summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rwxr-xr-xutil/harfbuzz/update-harfbuzz63
-rw-r--r--util/integrity/qt.bod111
-rw-r--r--util/lexgen/README16
-rw-r--r--util/lexgen/configfile.cpp99
-rw-r--r--util/lexgen/configfile.h81
-rw-r--r--util/lexgen/css2-simplified.lexgen93
-rw-r--r--util/lexgen/generator.cpp532
-rw-r--r--util/lexgen/generator.h221
-rw-r--r--util/lexgen/global.h113
-rw-r--r--util/lexgen/lexgen.lexgen24
-rw-r--r--util/lexgen/lexgen.pri3
-rw-r--r--util/lexgen/lexgen.pro6
-rw-r--r--util/lexgen/main.cpp323
-rw-r--r--util/lexgen/nfa.cpp508
-rw-r--r--util/lexgen/nfa.h127
-rw-r--r--util/lexgen/re2nfa.cpp547
-rw-r--r--util/lexgen/re2nfa.h116
-rw-r--r--util/lexgen/test.lexgen9
-rw-r--r--util/lexgen/tests/testdata/backtrack1/input1
-rw-r--r--util/lexgen/tests/testdata/backtrack1/output1
-rw-r--r--util/lexgen/tests/testdata/backtrack1/rules.lexgen3
-rw-r--r--util/lexgen/tests/testdata/backtrack2/input1
-rw-r--r--util/lexgen/tests/testdata/backtrack2/output2
-rw-r--r--util/lexgen/tests/testdata/backtrack2/rules.lexgen4
-rw-r--r--util/lexgen/tests/testdata/casesensitivity/input1
-rw-r--r--util/lexgen/tests/testdata/casesensitivity/output14
-rw-r--r--util/lexgen/tests/testdata/casesensitivity/rules.lexgen7
-rw-r--r--util/lexgen/tests/testdata/comments/input1
-rw-r--r--util/lexgen/tests/testdata/comments/output2
-rw-r--r--util/lexgen/tests/testdata/comments/rules.lexgen2
-rw-r--r--util/lexgen/tests/testdata/dot/input1
-rw-r--r--util/lexgen/tests/testdata/dot/output2
-rw-r--r--util/lexgen/tests/testdata/dot/rules.lexgen3
-rw-r--r--util/lexgen/tests/testdata/negation/input1
-rw-r--r--util/lexgen/tests/testdata/negation/output2
-rw-r--r--util/lexgen/tests/testdata/negation/rules.lexgen3
-rw-r--r--util/lexgen/tests/testdata/quoteinset/input1
-rw-r--r--util/lexgen/tests/testdata/quoteinset/output1
-rw-r--r--util/lexgen/tests/testdata/quoteinset/rules.lexgen2
-rw-r--r--util/lexgen/tests/testdata/quotes/input1
-rw-r--r--util/lexgen/tests/testdata/quotes/output1
-rw-r--r--util/lexgen/tests/testdata/quotes/rules.lexgen2
-rw-r--r--util/lexgen/tests/testdata/simple/input1
-rw-r--r--util/lexgen/tests/testdata/simple/output2
-rw-r--r--util/lexgen/tests/testdata/simple/rules.lexgen3
-rw-r--r--util/lexgen/tests/testdata/subsets1/input1
-rw-r--r--util/lexgen/tests/testdata/subsets1/output2
-rw-r--r--util/lexgen/tests/testdata/subsets1/rules.lexgen3
-rw-r--r--util/lexgen/tests/testdata/subsets2/input1
-rw-r--r--util/lexgen/tests/testdata/subsets2/output3
-rw-r--r--util/lexgen/tests/testdata/subsets2/rules.lexgen4
-rw-r--r--util/lexgen/tests/tests.pro6
-rw-r--r--util/lexgen/tests/tst_lexgen.cpp285
-rw-r--r--util/lexgen/tokenizer.cpp237
-rw-r--r--util/local_database/README1
-rwxr-xr-xutil/local_database/cldr2qlocalexml.py810
-rwxr-xr-xutil/local_database/dateconverter.py120
-rw-r--r--util/local_database/enumdata.py544
-rw-r--r--util/local_database/formattags.txt23
-rwxr-xr-xutil/local_database/qlocalexml2cpp.py877
-rw-r--r--util/local_database/testlocales/localemodel.cpp462
-rw-r--r--util/local_database/testlocales/localemodel.h69
-rw-r--r--util/local_database/testlocales/localewidget.cpp89
-rw-r--r--util/local_database/testlocales/localewidget.h59
-rw-r--r--util/local_database/testlocales/main.cpp51
-rw-r--r--util/local_database/testlocales/testlocales.pro4
-rw-r--r--util/local_database/xpathlite.py249
-rw-r--r--util/network/cookiejar-generateTLDs/cookiejar-generateTLDs.pro9
-rw-r--r--util/network/cookiejar-generateTLDs/main.cpp161
-rw-r--r--util/plugintest/README3
-rw-r--r--util/plugintest/main.cpp66
-rw-r--r--util/plugintest/plugintest.pro4
-rw-r--r--util/s60pixelmetrics/bld.inf45
-rw-r--r--util/s60pixelmetrics/pixel_metrics.cpp1255
-rw-r--r--util/s60pixelmetrics/pixel_metrics.h218
-rw-r--r--util/s60pixelmetrics/pm_mapper.hrh66
-rw-r--r--util/s60pixelmetrics/pm_mapper.mmp91
-rw-r--r--util/s60pixelmetrics/pm_mapper.pkg32
-rw-r--r--util/s60pixelmetrics/pm_mapper.rss160
-rw-r--r--util/s60pixelmetrics/pm_mapper_reg.rss57
-rw-r--r--util/s60pixelmetrics/pm_mapperapp.cpp959
-rw-r--r--util/s60pixelmetrics/pm_mapperapp.h190
-rw-r--r--util/s60pixelmetrics/pm_mapperview.cpp375
-rw-r--r--util/s60pixelmetrics/pm_mapperview.h228
-rw-r--r--util/s60theme/README31
-rw-r--r--util/s60theme/main.cpp78
-rw-r--r--util/s60theme/s60theme.pro12
-rw-r--r--util/s60theme/s60themeconvert.cpp312
-rw-r--r--util/s60theme/s60themeconvert.h54
-rwxr-xr-xutil/scripts/make_qfeatures_dot_h198
-rwxr-xr-xutil/scripts/unix_to_dos16
-rw-r--r--util/unicode/.gitattributes1
-rw-r--r--util/unicode/README1
-rw-r--r--util/unicode/codecs/big5/BIG514079
-rw-r--r--util/unicode/codecs/big5/big5.pro6
-rw-r--r--util/unicode/codecs/big5/big5.qrc6
-rw-r--r--util/unicode/codecs/big5/main.cpp158
-rw-r--r--util/unicode/data/ArabicShaping.txt338
-rw-r--r--util/unicode/data/BidiMirroring.txt582
-rw-r--r--util/unicode/data/Blocks.txt185
-rw-r--r--util/unicode/data/CaseFolding.txt1093
-rw-r--r--util/unicode/data/DerivedAge.txt867
-rw-r--r--util/unicode/data/DerivedNormalizationProps.txt2650
-rw-r--r--util/unicode/data/GraphemeBreakProperty.txt1039
-rw-r--r--util/unicode/data/LineBreak.txt18542
-rw-r--r--util/unicode/data/NormalizationCorrections.txt48
-rw-r--r--util/unicode/data/Scripts.txt1538
-rw-r--r--util/unicode/data/ScriptsCorrections.txt0
-rw-r--r--util/unicode/data/ScriptsInitial.txt0
-rw-r--r--util/unicode/data/SentenceBreakProperty.txt1664
-rw-r--r--util/unicode/data/SpecialCasing.txt264
-rw-r--r--util/unicode/data/UnicodeData.txt17720
-rw-r--r--util/unicode/data/WordBreakProperty.txt677
-rw-r--r--util/unicode/main.cpp2786
-rw-r--r--util/unicode/unicode.pro3
-rwxr-xr-xutil/unicode/writingSystems.sh60
-rw-r--r--util/unicode/x11/encodings.in71
-rwxr-xr-xutil/unicode/x11/makeencodings135
-rw-r--r--util/xkbdatagen/README1
-rw-r--r--util/xkbdatagen/main.cpp507
-rw-r--r--util/xkbdatagen/xkbdatagen.pro3
121 files changed, 76601 insertions, 0 deletions
diff --git a/util/harfbuzz/update-harfbuzz b/util/harfbuzz/update-harfbuzz
new file mode 100755
index 0000000000..29891b6fe7
--- /dev/null
+++ b/util/harfbuzz/update-harfbuzz
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+set -e
+
+require_clean_work_tree() {
+ # test if working tree is dirty
+ git rev-parse --verify HEAD > /dev/null &&
+ git update-index --refresh &&
+ git diff-files --quiet &&
+ git diff-index --cached --quiet HEAD ||
+ die "Working tree is dirty"
+}
+
+branch=master
+
+if [ $# = 1 ]; then
+ repo=$1
+elif [ $# = 2 ]; then
+ repo=$1
+ branch=$2
+else
+ echo "usage: $0 <path to local harfbuzz repository> [branch]"
+ exit 1
+fi
+
+if [ ! -r $repo/.git ]; then
+ echo "The provided path $repo does not point to a git repository."
+ exit 2
+fi
+
+test -z "$(git rev-parse --show-cdup)" || {
+ exit=$?
+ echo >&2 "You need to run this command from the toplevel of the working tree."
+ exit $exit
+}
+
+require_clean_work_tree
+
+url=`git --git-dir=$repo/.git config remote.origin.url`
+
+git ls-files src/3rdparty/harfbuzz | git update-index --force-remove --stdin
+
+git fetch $repo $branch
+
+commit=`git rev-parse FETCH_HEAD`
+tree=`git cat-file commit FETCH_HEAD|grep "^tree" | awk '{print $2}'`
+
+git read-tree --prefix=src/3rdparty/harfbuzz $tree
+
+git checkout src/3rdparty/harfbuzz
+
+git status
+
+cat >commitlog.txt <<EOT
+Updated Harfbuzz from $url to $commit
+EOT
+
+echo
+echo "Wrote commitlog.txt. Use with"
+echo
+echo " git commit -e -F commitlog.txt"
+echo
+echo "to commit your changes"
diff --git a/util/integrity/qt.bod b/util/integrity/qt.bod
new file mode 100644
index 0000000000..bdf50ce96a
--- /dev/null
+++ b/util/integrity/qt.bod
@@ -0,0 +1,111 @@
+CommandOptions {
+ MOCCommandOptions {
+ MOCOutput {
+ {
+ name="-o"
+ }
+ delimiter="Space"
+ merge="Replace"
+ #flags={"OUTPUTNAME"}
+ }
+ MOCDefines {
+ {
+ name="-D"
+ }
+ delimiter="Touching"
+ merge="Concat"
+ }
+ MOCIncludes {
+ {
+ name="-I"
+ }
+ delimiter="Touching"
+ merge="Concat"
+ flags={"RELATIVEPATH"}
+ }
+ }
+ UICommandOptions {
+ UIOutput {
+ {
+ name="-o"
+ }
+ delimiter="Space"
+ merge="Replace"
+ flags={"OUTPUTNAME"}
+ }
+ }
+ RCCCommandOptions {
+ RCCOutput {
+ {
+ name="-o"
+ }
+ delimiter="Space"
+ merge="Replace"
+ flags={"OUTPUTNAME"}
+ }
+ RCCName {
+ {
+ name="-name"
+ }
+ delimiter="Space"
+ merge="Replace"
+ }
+ }
+}
+
+Commands {
+ MOCPreprocessor {
+ name="MOCPreprocessor"
+ exec="${QT_BUILD_DIR}/bin/moc"
+ options={ "MOCCommandOptions", "SpecialOptions" }
+ }
+ UIPreprocessor {
+ name="UIPreprocessor"
+ exec="${QT_BUILD_DIR}/bin/uic"
+ options={ "UICommandOptions" }
+ }
+ RCCPreprocessor {
+ name="RCCPreprocessor"
+ exec="${QT_BUILD_DIR}/bin/rcc"
+ options={ "RCCCommandOptions" }
+ }
+}
+
+FileTypes {
+ MocCPP {
+ name="MOC/Qt Header"
+ outputExtension="time"
+ outputType="SourceFile"
+ command="MOCPreprocessor"
+ commandLine="${QT_BUILD_DIR}/bin/moc -nn $OPTIONS $INPUTFILE"
+ progress="MOCing"
+ extraFiles="$(OUTPUTDIR)/moc_$(OUTPUTNAMEBASE).cpp"
+ #postExecSafe={"${GHS_TOOLS_DIR}/filechanged work/$(OUTPUTNAME)"}
+ color="#0020a0"
+ grepable=true
+ }
+ RCC {
+ name="Qt Resource"
+ outputExtension="time"
+ #extensions={"qrc"}
+ outputType="SourceFile"
+ command="RCCPreprocessor"
+ commandLine="${QT_BUILD_DIR}/bin/rcc $OPTIONS $INPUTFILE"
+ extraFiles="$(OUTPUTDIR)/qrc_$(OUTPUTNAMEBASE).cpp"
+ progress="Generating Resource source from"
+ action="Generate Resource source for"
+ grepable=true
+ }
+ UI {
+ name="Qt Dialog"
+ outputExtension="time"
+ #extensions={"ui"}
+ outputType="SourceFile"
+ command="UIPreprocessor"
+ commandLine="${QT_BUILD_DIR}/bin/uic $OPTIONS $INPUTFILE"
+ extraFiles="$(OUTPUTDIR)/ui_$(OUTPUTNAMEBASE).cpp"
+ progress="Generating Dialog source from"
+ action="Generate Dialog source for"
+ grepable=true
+ }
+}
diff --git a/util/lexgen/README b/util/lexgen/README
new file mode 100644
index 0000000000..9feb18d1e3
--- /dev/null
+++ b/util/lexgen/README
@@ -0,0 +1,16 @@
+Lexgen
+------
+
+This is a little tool to generate lexical scanners from a rather simplistic
+configuration file. We use it internally in Qt to generate the scanner for the
+CSS parser that is built into the toolkit (used for the widget styling and the
+HTML import into QTextDocument).
+
+Beware, it's very slow (in generating the code) and it may not generate what
+you want. But I like that it generates code that operates on QChar and friends.
+
+Use at your own risk ;-)
+
+
+--
+Simon Hausmann <simon.hausmann@nokia.com>
diff --git a/util/lexgen/configfile.cpp b/util/lexgen/configfile.cpp
new file mode 100644
index 0000000000..dab2f61686
--- /dev/null
+++ b/util/lexgen/configfile.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "configfile.h"
+
+#include <QFile>
+
+ConfigFile::SectionMap ConfigFile::parse(const QString &fileName)
+{
+ QFile f(fileName);
+ if (!f.open(QIODevice::ReadOnly))
+ return ConfigFile::SectionMap();
+ return parse(&f);
+}
+
+ConfigFile::SectionMap ConfigFile::parse(QIODevice *dev)
+{
+ SectionMap sections;
+ SectionMap::Iterator currentSection = sections.end();
+
+ ConfigFile::SectionMap result;
+ int currentLineNumber = 0;
+ while (!dev->atEnd()) {
+ QString line = QString::fromUtf8(dev->readLine()).trimmed();
+ ++currentLineNumber;
+
+ if (line.isEmpty() || line.startsWith(QLatin1Char('#')))
+ continue;
+
+ if (line.startsWith(QLatin1Char('['))) {
+ if (!line.endsWith(']')) {
+ qWarning("Syntax error at line %d: Missing ']' at start of new section.", currentLineNumber);
+ return SectionMap();
+ }
+ line.remove(0, 1);
+ line.chop(1);
+ const QString sectionName = line;
+ currentSection = sections.insert(sectionName, Section());
+ continue;
+ }
+
+ if (currentSection == sections.end()) {
+ qWarning("Syntax error at line %d: Entry found outside of any section.", currentLineNumber);
+ return SectionMap();
+ }
+
+ Entry e;
+ e.lineNumber = currentLineNumber;
+
+ int equalPos = line.indexOf(QLatin1Char('='));
+ if (equalPos == -1) {
+ e.key = line;
+ } else {
+ e.key = line;
+ e.key.truncate(equalPos);
+ e.key = e.key.trimmed();
+ e.value = line.mid(equalPos + 1).trimmed();
+ }
+ currentSection->append(e);
+ }
+ return sections;
+}
diff --git a/util/lexgen/configfile.h b/util/lexgen/configfile.h
new file mode 100644
index 0000000000..b8d483b916
--- /dev/null
+++ b/util/lexgen/configfile.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef CONFIGFILE_H
+#define CONFIGFILE_H
+
+#include <QStringList>
+#include <QMap>
+#include <QVector>
+
+struct ConfigFile
+{
+ struct Entry
+ {
+ inline Entry() : lineNumber(-1) {}
+ int lineNumber;
+ QString key;
+ QString value;
+ };
+ struct Section : public QVector<Entry>
+ {
+ inline bool contains(const QString &key) const
+ {
+ for (int i = 0; i < count(); ++i)
+ if (at(i).key == key)
+ return true;
+ return false;
+ }
+ inline QString value(const QString &key, const QString &defaultValue = QString()) const
+ {
+ for (int i = 0; i < count(); ++i)
+ if (at(i).key == key)
+ return at(i).value;
+ return defaultValue;
+ }
+ };
+ typedef QMap<QString, Section> SectionMap;
+
+ static SectionMap parse(const QString &fileName);
+ static SectionMap parse(QIODevice *dev);
+};
+
+#endif // CONFIGFILE_H
+
diff --git a/util/lexgen/css2-simplified.lexgen b/util/lexgen/css2-simplified.lexgen
new file mode 100644
index 0000000000..53facb1d4a
--- /dev/null
+++ b/util/lexgen/css2-simplified.lexgen
@@ -0,0 +1,93 @@
+[Options]
+case-sensitive
+classname = QCssScanner_Generated
+
+[Code Generator Options]
+MapToCode[a-z] = (ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256
+TokenPrefix = QCss::
+FileHeader = ../moc/licenseheader.txt
+
+[Macros]
+escape = \\[^\r\n\f0-9a-f]
+nmstart = [_a-z]|{escape}
+nmchar = [_a-z0-9-]|{escape}
+nl = \n|\r\n|\r|\f
+string1 = \"([^\n\r\f\\"]|\\{nl}|{escape})*\"
+string2 = \'([^\n\r\f\\']|\\{nl}|{escape})*\'
+invalid1 = \"([^\n\r\f\\"]|\\{nl}|{escape})*
+invalid2 = \'([^\n\r\f\\']|\\{nl}|{escape})*
+
+ident = -?{nmstart}{nmchar}*
+name = {nmchar}+
+num = [0-9]+|[0-9]*"."[0-9]+
+string = {string1}|{string2}
+invalid = {invalid1}|{invalid2}
+url = ([!#$%&*-~]|{escape})*
+s = [ \t\r\n\f]
+w = {s}*
+
+[Tokens]
+
+S = {s}+
+
+handleCommentStart() = \/\*
+
+CDO = "<!--"
+CDC = "-->"
+INCLUDES = "~="
+DASHMATCH = "|="
+
+LBRACE = {w}"{"
+PLUS = {w}"+"
+GREATER = {w}">"
+COMMA = {w}","
+
+STRING = {string}
+INVALID = {invalid}
+
+IDENT = {ident}
+
+HASH = "#"{name}
+
+ATKEYWORD_SYM = "@"{ident}
+
+EXCLAMATION_SYM = "!"
+
+#EMS = {num}em
+#EXS = {num}ex
+#LENGTH = {num}px
+#LENGTH = {num}cm
+#LENGTH = {num}mm
+#LENGTH = {num}in
+#LENGTH = {num}pt
+#LENGTH = {num}pc
+#ANGLE = {num}deg
+#ANGLE = {num}rad
+#ANGLE = {num}grad
+#TIME = {num}ms
+#TIME = {num}s
+#FREQ = {num}hz
+#FREQ = {num}khz
+#DIMENSION = {num}{ident}
+LENGTH = {num}{ident}
+
+PERCENTAGE = {num}%
+NUMBER = {num}
+
+#URI = "url("{w}{string}{w}")"
+#URI = "url("{w}{url}{w}")"
+FUNCTION = {ident}"("
+
+COLON = :
+SEMICOLON = ;
+RBRACE = \}
+SLASH = /
+MINUS = -
+DOT = \.
+STAR = \*
+LBRACKET = \[
+RBRACKET = \]
+EQUAL = \=
+LPAREN = \(
+RPAREN = \)
+OR = \|
diff --git a/util/lexgen/generator.cpp b/util/lexgen/generator.cpp
new file mode 100644
index 0000000000..7998861dfe
--- /dev/null
+++ b/util/lexgen/generator.cpp
@@ -0,0 +1,532 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "generator.h"
+
+#include <QFile>
+
+void Function::printDeclaration(CodeBlock &block, const QString &funcNamePrefix) const
+{
+ block << (iline ? "inline " : "") << signature(funcNamePrefix) << (iline ? QLatin1String(" {") : QLatin1String(";"));
+ if (!iline)
+ return;
+
+ block.indent();
+ QString tmp = body;
+ if (tmp.endsWith(QLatin1Char('\n')))
+ tmp.chop(1);
+ foreach (QString line, tmp.split(QLatin1Char('\n')))
+ block << line;
+ block.outdent();
+ block << "}";
+}
+
+QString Function::signature(const QString &funcNamePrefix) const
+{
+ QString sig;
+ if (!rtype.isEmpty()) {
+ sig += rtype;
+ sig += QLatin1Char(' ');
+ }
+ sig += funcNamePrefix;
+ sig += fname;
+ if (cnst)
+ sig += " const";
+ return sig;
+}
+
+QString Function::definition() const
+{
+ if (iline)
+ return QString();
+
+ QString result;
+ result += signature();
+ result += QLatin1String("\n{\n");
+
+ QString tmp = body;
+
+ if (tmp.endsWith(QLatin1Char('\n')))
+ tmp.chop(1);
+ if (!tmp.startsWith(QLatin1Char('\n')))
+ tmp.prepend(" ");
+
+ tmp.replace(QLatin1Char('\n'), QLatin1String("\n "));
+
+ result += tmp;
+
+ result += QLatin1String("\n}\n");
+
+ return result;
+}
+
+void Class::Section::printDeclaration(const Class *klass, CodeBlock &block) const
+{
+ foreach (Function ctor, constructors)
+ ctor.printDeclaration(block, klass->name());
+
+ if (!constructors.isEmpty())
+ block.addNewLine();
+
+ foreach (Function func, functions)
+ func.printDeclaration(block);
+
+ if (!functions.isEmpty())
+ block.addNewLine();
+
+ foreach (QString var, variables)
+ block << var << ';';
+}
+
+void Class::addConstructor(Access access, const QString &body, const QString &_args)
+{
+ Function ctor;
+ QString args = _args;
+ if (!args.startsWith(QLatin1Char('('))
+ && !args.endsWith(QLatin1Char(')'))) {
+ args.prepend('(');
+ args.append(')');
+ }
+ ctor.setName(args);
+ ctor.addBody(body);
+ sections[access].constructors.append(ctor);
+}
+
+QString Class::Section::definition(const Class *klass) const
+{
+ QString result;
+
+ foreach (Function ctor, constructors) {
+ ctor.setName(klass->name() + "::" + klass->name() + ctor.name());
+ result += ctor.definition();
+ result += QLatin1Char('\n');
+ }
+
+ foreach (Function func, functions) {
+ if (!func.hasBody()) continue;
+ func.setName(klass->name() + "::" + func.name());
+ result += func.definition();
+ result += QLatin1Char('\n');
+ }
+
+ return result;
+}
+
+QString Class::declaration() const
+{
+ CodeBlock block;
+
+ block << QLatin1String("class ") << cname;
+ block << "{";
+
+ if (!sections[PublicMember].isEmpty()) {
+ block << "public:";
+ block.indent();
+ sections[PublicMember].printDeclaration(this, block);
+ block.outdent();
+ }
+
+ if (!sections[ProtectedMember].isEmpty()) {
+ block << "protected:";
+ block.indent();
+ sections[ProtectedMember].printDeclaration(this, block);
+ block.outdent();
+ }
+
+ if (!sections[PrivateMember].isEmpty()) {
+ block << "private:";
+ block.indent();
+ sections[PrivateMember].printDeclaration(this, block);
+ block.outdent();
+ }
+
+ block << "};";
+ block.addNewLine();
+
+ return block.toString();
+}
+
+QString Class::definition() const
+{
+ return sections[PrivateMember].definition(this)
+ + sections[ProtectedMember].definition(this)
+ + sections[PublicMember].definition(this);
+}
+
+Generator::Generator(const DFA &_dfa, const Config &config)
+ : dfa(_dfa), cfg(config)
+{
+ QList<InputType> lst = cfg.maxInputSet.toList();
+ qSort(lst);
+ minInput = lst.first();
+ maxInput = lst.last();
+
+ ConfigFile::Section section = config.configSections.value("Code Generator Options");
+
+ foreach (ConfigFile::Entry entry, section) {
+ if (!entry.key.startsWith(QLatin1String("MapToCode["))
+ || !entry.key.endsWith(QLatin1Char(']')))
+ continue;
+ QString range = entry.key;
+ range.remove(0, qstrlen("MapToCode["));
+ range.chop(1);
+ if (range.length() != 3
+ || range.at(1) != QLatin1Char('-')) {
+ qWarning("Invalid range for char mapping function: %s", qPrintable(range));
+ continue;
+ }
+ TransitionSequence seq;
+ seq.first = range.at(0).unicode();
+ seq.last = range.at(2).unicode();
+ seq.testFunction = entry.value;
+ charFunctionRanges.append(seq);
+ }
+
+ QString tokenPrefix = section.value("TokenPrefix");
+ if (!tokenPrefix.isEmpty()) {
+ for (int i = 0; i < dfa.count(); ++i)
+ if (!dfa.at(i).symbol.isEmpty()
+ && !dfa.at(i).symbol.endsWith(QLatin1String("()")))
+ dfa[i].symbol.prepend(tokenPrefix);
+ }
+
+ headerFileName = section.value("FileHeader");
+}
+
+static inline bool adjacentKeys(int left, int right) { return left + 1 == right; }
+//static inline bool adjacentKeys(const InputType &left, const InputType &right)
+//{ return left.val + 1 == right.val; }
+
+static QVector<Generator::TransitionSequence> convertToSequences(const TransitionMap &transitions)
+{
+ QVector<Generator::TransitionSequence> sequences;
+ if (transitions.isEmpty())
+ return sequences;
+
+ QList<InputType> keys = transitions.keys();
+ qSort(keys);
+ int i = 0;
+ Generator::TransitionSequence sequence;
+ sequence.first = keys.at(0);
+ ++i;
+ for (; i < keys.count(); ++i) {
+ if (adjacentKeys(keys.at(i - 1), keys.at(i))
+ && transitions.value(keys.at(i)) == transitions.value(keys.at(i - 1))) {
+ continue;
+ }
+ sequence.last = keys.at(i - 1);
+ sequence.transition = transitions.value(sequence.last);
+ sequences.append(sequence);
+
+ sequence.first = keys.at(i);
+ }
+ sequence.last = keys.at(i - 1);
+ sequence.transition = transitions.value(sequence.last);
+ sequences.append(sequence);
+
+ return sequences;
+}
+
+QDebug &operator<<(QDebug &debug, const Generator::TransitionSequence &seq)
+{
+ return debug << "[first:" << seq.first << "; last:" << seq.last << "; transition:" << seq.transition
+ << (seq.testFunction.isEmpty() ? QString() : QString(QString("; testfunction:" + seq.testFunction)))
+ << "]";
+}
+
+bool Generator::isSingleReferencedFinalState(int i) const
+{
+ return backReferenceMap.value(i) == 1
+ && dfa.at(i).transitions.isEmpty()
+ && !dfa.at(i).symbol.isEmpty();
+}
+
+void Generator::generateTransitions(CodeBlock &body, const TransitionMap &transitions)
+{
+ if (transitions.isEmpty())
+ return;
+
+ QVector<TransitionSequence> sequences = convertToSequences(transitions);
+
+ bool needsCharFunction = false;
+ if (!charFunctionRanges.isEmpty()) {
+ int i = 0;
+ while (i < sequences.count()) {
+ const TransitionSequence &seq = sequences.at(i);
+ if (!seq.testFunction.isEmpty()) {
+ ++i;
+ continue;
+ }
+
+ foreach (TransitionSequence range, charFunctionRanges)
+ if (range.first >= seq.first && range.last <= seq.last) {
+ needsCharFunction = true;
+
+ TransitionSequence left, middle, right;
+
+ left.first = seq.first;
+ left.last = range.first - 1;
+ left.transition = seq.transition;
+
+ middle = range;
+ middle.transition = seq.transition;
+
+ right.first = range.last + 1;
+ right.last = seq.last;
+ right.transition = seq.transition;
+
+ sequences.remove(i);
+ if (left.last >= left.first) {
+ sequences.insert(i, left);
+ ++i;
+ }
+ sequences.insert(i, middle);
+ ++i;
+ if (right.last >= right.first) {
+ sequences.insert(i, right);
+ ++i;
+ }
+
+ i = -1;
+ break;
+ }
+
+ ++i;
+ }
+ }
+
+ //qDebug() << "sequence count" << sequences.count();
+ //qDebug() << sequences;
+
+ if (sequences.count() < 10
+ || sequences.last().last == maxInput
+ || needsCharFunction) {
+ foreach (TransitionSequence seq, sequences) {
+ const bool embedFinalState = isSingleReferencedFinalState(seq.transition);
+
+ QString brace;
+ if (embedFinalState)
+ brace = " {";
+
+ if (!seq.testFunction.isEmpty()) {
+ body << "if (" << seq.testFunction << ")" << brace;
+ } else if (seq.first == seq.last) {
+ body << "if (ch.unicode() == " << seq.first << ")" << brace;
+ } else {
+ if (seq.last < maxInput)
+ body << "if (ch.unicode() >= " << seq.first
+ << " && ch.unicode() <= " << seq.last << ")" << brace;
+ else
+ body << "if (ch.unicode() >= " << seq.first << ")" << brace;
+ }
+ body.indent();
+ if (embedFinalState) {
+ body << "token = " << dfa.at(seq.transition).symbol << ";";
+ body << "goto found;";
+
+ body.outdent();
+ body << "}";
+ } else {
+ body << "goto state_" << seq.transition << ";";
+ body.outdent();
+ }
+ }
+ } else {
+ QList<InputType> keys = transitions.keys();
+ qSort(keys);
+
+ body << "switch (ch.unicode()) {";
+ body.indent();
+ for (int k = 0; k < keys.count(); ++k) {
+ const InputType key = keys.at(k);
+ const int trans = transitions.value(key);
+
+ QString keyStr;
+ if (key == '\\')
+ keyStr = QString("\'\\\\\'");
+ else if (key >= 48 && key < 127)
+ keyStr = QString('\'') + QChar::fromLatin1(char(key)) + QChar('\'');
+ else
+ keyStr = QString::number(key);
+
+ if (k < keys.count() - 1
+ && transitions.value(keys.at(k + 1)) == trans) {
+ body << "case " << keyStr << ":";
+ } else {
+ if (isSingleReferencedFinalState(trans)) {
+ body << "case " << keyStr << ": token = " << dfa.at(trans).symbol << "; goto found;";
+ } else {
+ body << "case " << keyStr << ": goto state_" << trans << ";";
+ }
+ }
+ }
+ body.outdent();
+ body << "}";
+ }
+}
+
+QString Generator::generate()
+{
+ Class klass(cfg.className);
+
+ klass.addMember(Class::PublicMember, "QString input");
+ klass.addMember(Class::PublicMember, "int pos");
+ klass.addMember(Class::PublicMember, "int lexemStart");
+ klass.addMember(Class::PublicMember, "int lexemLength");
+
+ {
+ CodeBlock body;
+ body << "input = inp;";
+ body << "pos = 0;";
+ body << "lexemStart = 0;";
+ body << "lexemLength = 0;";
+ klass.addConstructor(Class::PublicMember, body, "const QString &inp");
+ }
+
+ {
+ Function next("QChar", "next()");
+ next.setInline(true);
+ if (cfg.caseSensitivity == Qt::CaseSensitive)
+ next.addBody("return (pos < input.length()) ? input.at(pos++) : QChar();");
+ else
+ next.addBody("return (pos < input.length()) ? input.at(pos++).toLower() : QChar();");
+ klass.addMember(Class::PublicMember, next);
+ }
+
+ /*
+ {
+ Function lexem("QString", "lexem()");
+ lexem.setConst(true);
+ lexem.setInline(true);
+ lexem.addBody("return input.mid(lexemStart, lexemLength);");
+ klass.addMember(Class::PublicMember, lexem);
+ }
+ */
+
+ for (int i = 0; i < dfa.count(); ++i)
+ if (dfa.at(i).symbol.endsWith(QLatin1String("()"))) {
+ Function handlerFunc("int", dfa.at(i).symbol);
+ klass.addMember(Class::PublicMember, handlerFunc);
+ }
+
+ Function lexFunc;
+ lexFunc.setReturnType("int");
+ lexFunc.setName("lex()");
+
+ CodeBlock body;
+ body << "lexemStart = pos;";
+ body << "lexemLength = 0;";
+ body << "int lastAcceptingPos = -1;";
+ body << "int token = -1;";
+ body << "QChar ch;";
+ body.addNewLine();
+
+ backReferenceMap.clear();
+ foreach (State s, dfa)
+ foreach (int state, s.transitions)
+ backReferenceMap[state]++;
+
+ bool haveSingleReferencedFinalState = false;
+
+ for (int i = 0; i < dfa.count(); ++i) {
+ if (isSingleReferencedFinalState(i)) {
+ haveSingleReferencedFinalState = true;
+ continue;
+ }
+
+ if (i > 0)
+ body << "state_" << i << ":";
+ else
+ body << "// initial state";
+
+ body.indent();
+
+ if (!dfa.at(i).symbol.isEmpty()) {
+ body << "lastAcceptingPos = pos;";
+ body << "token = " << dfa.at(i).symbol << ";";
+ }
+
+ body.outdent();
+
+ body.indent();
+
+ if (!dfa.at(i).transitions.isEmpty()) {
+ body << "ch = next();";
+ generateTransitions(body, dfa.at(i).transitions);
+ }
+
+ body << "goto out;";
+
+ body.outdent();
+ }
+
+ if (haveSingleReferencedFinalState) {
+ body << "found:";
+ body << "lastAcceptingPos = pos;";
+ body.addNewLine();
+ }
+
+ body << "out:";
+ body << "if (lastAcceptingPos != -1) {";
+ body.indent();
+ body << "lexemLength = lastAcceptingPos - lexemStart;";
+ body << "pos = lastAcceptingPos;";
+ body.outdent();
+ body << "}";
+ body << "return token;";
+
+ lexFunc.addBody(body);
+
+ klass.addMember(Class::PublicMember, lexFunc);
+
+ QString header;
+ QFile headerFile(headerFileName);
+ if (!headerFileName.isEmpty()
+ && headerFile.exists()
+ && headerFile.open(QIODevice::ReadOnly)) {
+ header = QString::fromUtf8(headerFile.readAll());
+ }
+
+ header += QLatin1String("// auto generated. DO NOT EDIT.\n");
+
+ return header + klass.declaration() + klass.definition();
+}
+
diff --git a/util/lexgen/generator.h b/util/lexgen/generator.h
new file mode 100644
index 0000000000..b9df8d74fa
--- /dev/null
+++ b/util/lexgen/generator.h
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef GENERATOR_H
+#define GENERATOR_H
+
+#include <QTextStream>
+#include <QStringList>
+
+#include "nfa.h"
+
+class LineStream
+{
+private:
+ struct SharedStream
+ {
+ int ref;
+ QTextStream *stream;
+ };
+
+public:
+ LineStream(QTextStream *textStream)
+ {
+ shared = new SharedStream;
+ shared->ref = 1;
+ shared->stream = textStream;
+ }
+ LineStream(const LineStream &other)
+ {
+ shared = other.shared;
+ shared->ref++;
+ }
+ LineStream &operator=(const LineStream &other)
+ {
+ if (this == &other)
+ return *this;
+ LineStream copy(other); // keep refcount up
+ qSwap(*shared, *other.shared);
+ return *this;
+ }
+ ~LineStream()
+ {
+ if (!--shared->ref) {
+ (*shared->stream) << endl;
+ delete shared;
+ }
+ }
+
+ template <typename T>
+ LineStream &operator<<(const T &value)
+ { (*shared->stream) << value; return *this; }
+
+ SharedStream *shared;
+};
+
+class CodeBlock
+{
+public:
+ inline CodeBlock() { stream.setString(&output, QIODevice::WriteOnly); }
+
+ inline void indent() { indentStr += QLatin1String(" "); }
+ inline void outdent() { indentStr.remove(0, 4); }
+
+ template <typename T>
+ LineStream operator<<(const T &value)
+ { stream << indentStr; stream << value; return LineStream(&stream); }
+
+ inline void addNewLine() { stream << endl; }
+
+ inline QString toString() const { stream.flush(); return output; }
+
+private:
+ QString output;
+ mutable QTextStream stream;
+ QString indentStr;
+};
+
+class Function
+{
+public:
+ inline Function(const QString &returnType, const QString &name)
+ : rtype(returnType), fname(name), iline(false), cnst(false) {}
+ inline Function() : iline(false), cnst(false) {}
+
+ inline void setName(const QString &name) { fname = name; }
+ inline QString name() const { return fname; }
+
+ inline void setInline(bool i) { iline = i; }
+ inline bool isInline() const { return iline; }
+
+ inline void setReturnType(const QString &type) { rtype = type; }
+ inline QString returnType() const { return rtype; }
+
+ inline void addBody(const QString &_body) { body += _body; }
+ inline void addBody(const CodeBlock &block) { body += block.toString(); }
+ inline bool hasBody() const { return !body.isEmpty(); }
+
+ inline void setConst(bool konst) { cnst = konst; }
+ inline bool isConst() const { return cnst; }
+
+ void printDeclaration(CodeBlock &block, const QString &funcNamePrefix = QString()) const;
+ QString definition() const;
+
+private:
+ QString signature(const QString &funcNamePrefix = QString()) const;
+
+ QString rtype;
+ QString fname;
+ QString body;
+ bool iline;
+ bool cnst;
+};
+
+class Class
+{
+public:
+ enum Access { PublicMember, ProtectedMember, PrivateMember };
+
+ inline Class(const QString &name) : cname(name) {}
+
+ inline void setName(const QString &name) { cname = name; }
+ inline QString name() const { return cname; }
+
+ inline void addMember(Access access, const QString &name)
+ { sections[access].variables.append(name); }
+ inline void addMember(Access access, const Function &func)
+ { sections[access].functions.append(func); }
+
+ void addConstructor(Access access, const QString &body, const QString &args = QString());
+ inline void addConstructor(Access access, const CodeBlock &body, const QString &args = QString())
+ { addConstructor(access, body.toString(), args); }
+
+ QString declaration() const;
+ QString definition() const;
+
+private:
+ QString cname;
+ struct Section
+ {
+ QVector<Function> functions;
+ QStringList variables;
+ QVector<Function> constructors;
+
+ inline bool isEmpty() const
+ { return functions.isEmpty() && variables.isEmpty() && constructors.isEmpty(); }
+
+ void printDeclaration(const Class *klass, CodeBlock &block) const;
+ QString definition(const Class *klass) const;
+ };
+
+ Section sections[3];
+};
+
+class Generator
+{
+public:
+ Generator(const DFA &dfa, const Config &config);
+
+ QString generate();
+
+private:
+ void generateTransitions(CodeBlock &body, const TransitionMap &transitions);
+ bool isSingleReferencedFinalState(int i) const;
+
+ DFA dfa;
+ Config cfg;
+ InputType minInput;
+ InputType maxInput;
+ QHash<int, int> backReferenceMap;
+ QString headerFileName;
+public:
+ struct TransitionSequence
+ {
+ inline TransitionSequence() : first(-1), last(-1), transition(-1) {}
+ InputType first;
+ InputType last;
+ int transition;
+ QString testFunction;
+ };
+private:
+ QVector<TransitionSequence> charFunctionRanges;
+};
+
+#endif
diff --git a/util/lexgen/global.h b/util/lexgen/global.h
new file mode 100644
index 0000000000..49f993e8c6
--- /dev/null
+++ b/util/lexgen/global.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#include <QHash>
+#include <QDataStream>
+#include <QSet>
+
+#include "configfile.h"
+
+#if 1
+typedef int InputType;
+
+enum SpecialInputType {
+ DigitInput,
+ SpaceInput,
+ Letter
+};
+
+#else
+
+enum SpecialInputType {
+ NoSpecialInput = 0,
+ DigitInput,
+ SpaceInput,
+ LetterOrNumberInput
+};
+
+struct InputType
+{
+ inline InputType() : val(0), specialInput(NoSpecialInput) {}
+ inline InputType(const int &val) : val(val), specialInput(NoSpecialInput) {}
+
+ inline operator int() const { return val; }
+
+ inline bool operator==(const InputType &other) const
+ { return val == other.val; }
+ inline bool operator!=(const InputType &other) const
+ { return val != other.val; }
+
+ int val;
+ SpecialInputType specialInput;
+};
+
+inline int qHash(const InputType &t) { return qHash(t.val); }
+
+inline QDataStream &operator<<(QDataStream &stream, const InputType &i)
+{
+ return stream << i;
+}
+
+inline QDataStream &operator>>(QDataStream &stream, InputType &i)
+{
+ return stream >> i;
+}
+
+#endif
+
+const InputType Epsilon = -1;
+
+struct Config
+{
+ inline Config() : caseSensitivity(Qt::CaseSensitive), debug(false), cache(false) {}
+ QSet<InputType> maxInputSet;
+ Qt::CaseSensitivity caseSensitivity;
+ QString className;
+ bool debug;
+ bool cache;
+ QString ruleFile;
+ ConfigFile::SectionMap configSections;
+};
+
+#endif // GLOBAL_H
diff --git a/util/lexgen/lexgen.lexgen b/util/lexgen/lexgen.lexgen
new file mode 100644
index 0000000000..33efb8b39b
--- /dev/null
+++ b/util/lexgen/lexgen.lexgen
@@ -0,0 +1,24 @@
+[Options]
+case-sensitive
+classname = RegExpTokenizer
+
+[Code Generator Options]
+TokenPrefix = RE2NFA::
+
+[Macros]
+Escape = \\.{1}
+
+[Tokens]
+TOK_QUOTED_STRING = \"[^\"]*\"
+TOK_STRING = [^\{\}\(\)\,\*\|\?\.\+\[]|{Escape}
+TOK_SEQUENCE = \[([^\]]|(\\\]))*\]
+TOK_LBRACE = \{
+TOK_RBRACE = \}
+TOK_LPAREN = \(
+TOK_RPAREN = \)
+TOK_COMMA = \,
+TOK_STAR = \*
+TOK_OR = \|
+TOK_QUESTION = \?
+TOK_DOT = \.
+TOK_PLUS = \+
diff --git a/util/lexgen/lexgen.pri b/util/lexgen/lexgen.pri
new file mode 100644
index 0000000000..b36e00ea62
--- /dev/null
+++ b/util/lexgen/lexgen.pri
@@ -0,0 +1,3 @@
+VPATH += $$PWD
+SOURCES += nfa.cpp configfile.cpp re2nfa.cpp
+INCLUDEPATH += $$PWD
diff --git a/util/lexgen/lexgen.pro b/util/lexgen/lexgen.pro
new file mode 100644
index 0000000000..89ac84de06
--- /dev/null
+++ b/util/lexgen/lexgen.pro
@@ -0,0 +1,6 @@
+TEMPLATE = app
+TARGET = lexgen
+include(lexgen.pri)
+SOURCES += main.cpp \
+ generator.cpp
+QT = core
diff --git a/util/lexgen/main.cpp b/util/lexgen/main.cpp
new file mode 100644
index 0000000000..1cb5d902a6
--- /dev/null
+++ b/util/lexgen/main.cpp
@@ -0,0 +1,323 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nfa.h"
+#include "re2nfa.h"
+#include "configfile.h"
+#include "generator.h"
+
+#include <QFile>
+#include <QCoreApplication>
+#include <QFileInfo>
+#include <QDateTime>
+
+struct Symbol
+{
+ QString token;
+ QString lexem;
+};
+
+static QList<Symbol> tokenize(const DFA &dfa, const QString &input, Config *cfg, bool *ok = 0)
+{
+ QList<Symbol> symbols;
+ Symbol lastSymbol;
+ int state = 0;
+ int lastAcceptingState = -1;
+ QString lastAcceptingLexem;
+ int lastAcceptingPos = -1;
+ for (int i = 0; i < input.length(); ++i) {
+ QChar ch = input.at(i);
+ QChar chForInput = ch;
+ if (cfg->caseSensitivity == Qt::CaseInsensitive)
+ chForInput = chForInput.toLower();
+ int next = dfa.at(state).transitions.value(chForInput.unicode());
+ if (cfg->debug)
+ qDebug() << "input" << input.at(i) << "leads to state" << next;
+ if (next) {
+ lastSymbol.lexem.append(input.at(i));
+ lastSymbol.token = dfa.at(next).symbol;
+ if (!lastSymbol.token.isEmpty()) {
+ lastAcceptingState = next;
+ lastAcceptingLexem = lastSymbol.lexem;
+ lastAcceptingPos = i;
+ }
+ state = next;
+ } else {
+ if (lastAcceptingState != -1) {
+ if (cfg->debug)
+ qDebug() << "adding" << dfa.at(lastAcceptingState).symbol << "and backtracking to" << lastAcceptingPos;
+ Symbol s;
+ s.token = dfa.at(lastAcceptingState).symbol;
+ s.lexem = lastAcceptingLexem;
+ symbols << s;
+ lastSymbol = Symbol();
+ state = 0;
+ i = lastAcceptingPos;
+ lastAcceptingPos = -1;
+ lastAcceptingState = -1;
+ continue;
+ }
+ if (state == 0 || lastSymbol.token.isEmpty()) {
+ if (cfg->debug)
+ qDebug() << "invalid input";
+ if (ok)
+ *ok = false;
+ return symbols;
+ }
+ if (cfg->debug)
+ qDebug() << "appending symbol with token" << lastSymbol.token;
+ symbols << lastSymbol;
+ lastSymbol = Symbol();
+ state = 0;
+ lastAcceptingState = -1;
+ --i;
+ }
+ }
+ if (!lastSymbol.token.isEmpty()) {
+ if (cfg->debug)
+ qDebug() << "appending (last) symbol with token" << lastSymbol.token;
+ symbols << lastSymbol;
+ } else if (lastAcceptingState != -1) {
+ if (cfg->debug)
+ qDebug() << "appending last accepting state with token" << dfa.at(lastAcceptingState).symbol;
+ Symbol s;
+ s.lexem = lastAcceptingLexem;
+ s.token = dfa.at(lastAcceptingState).symbol;
+ symbols << s;
+ }
+ if (ok)
+ *ok = true;
+ return symbols;
+}
+
+static QSet<InputType> determineMaxInputSet(const ConfigFile::Section &section)
+{
+ QSet<InputType> set;
+
+ QString inputTypeName;
+
+ foreach (const ConfigFile::Entry &entry, section)
+ if (entry.key == QLatin1String("InputType")) {
+ if (!inputTypeName.isEmpty()) {
+ qWarning("Error: InputType field specified multiple times in config file");
+ return QSet<InputType>();
+ }
+ inputTypeName = entry.value;
+ }
+
+ if (inputTypeName.isEmpty())
+ inputTypeName = "quint8";
+
+ if (inputTypeName == "quint8") {
+ for (int i = 1; i < 256; ++i)
+ set.insert(i);
+ } /* else if ### */
+ else {
+ qWarning("Error: Unknown input type '%s'", qPrintable(inputTypeName));
+ return QSet<InputType>();
+ }
+
+ return set;
+}
+
+static bool loadConfig(const QString &ruleFile, Config *cfg)
+{
+ ConfigFile::SectionMap sections = ConfigFile::parse(ruleFile);
+ if (sections.isEmpty()) {
+ qWarning("Error parsing %s", qPrintable(ruleFile));
+ return false;
+ }
+
+ QSet<InputType> maxInputSet = determineMaxInputSet(sections.value("Options"));
+ if (maxInputSet.isEmpty())
+ return false;
+
+ Qt::CaseSensitivity cs = Qt::CaseInsensitive;
+ if (sections.value("Options").contains("case-sensitive"))
+ cs = Qt::CaseSensitive;
+
+ cfg->configSections = sections;
+ cfg->caseSensitivity = cs;
+ cfg->className = sections.value("Options").value("classname", "Scanner");
+ cfg->maxInputSet = maxInputSet;
+ cfg->ruleFile = ruleFile;
+ return true;
+}
+
+static DFA generateMachine(const Config &cfg)
+{
+ if (cfg.cache) {
+ QFileInfo ruleInfo(cfg.ruleFile);
+ QFileInfo cacheInfo(ruleInfo.baseName() + ".dfa");
+ if (cacheInfo.exists()
+ && cacheInfo.lastModified() > ruleInfo.lastModified()) {
+ QFile f(cacheInfo.absoluteFilePath());
+ f.open(QIODevice::ReadOnly);
+ QDataStream stream(&f);
+ DFA machine;
+ stream >> machine;
+ return machine;
+ }
+ }
+
+ QMap<QString, NFA> macros;
+ foreach (ConfigFile::Entry e, cfg.configSections.value("Macros")) {
+ int errCol = 0;
+ if (cfg.debug)
+ qDebug() << "parsing" << e.value;
+ NFA nfa = RE2NFA(macros, cfg.maxInputSet, cfg.caseSensitivity).parse(e.value, &errCol);
+ if (nfa.isEmpty()) {
+ qWarning("Parse error in line %d column %d", e.lineNumber, errCol);
+ return DFA();
+ }
+ macros.insert(e.key, nfa);
+ }
+
+ if (!cfg.configSections.contains("Tokens")) {
+ qWarning("Rule file does not contain a [Tokens] section!");
+ return DFA();
+ }
+
+ QVector<NFA> tokens;
+
+ foreach (ConfigFile::Entry e, cfg.configSections.value("Tokens")) {
+ int errCol = 0;
+ if (cfg.debug)
+ qDebug() << "parsing" << e.value;
+ NFA tok = RE2NFA(macros, cfg.maxInputSet, cfg.caseSensitivity).parse(e.value, &errCol);
+ if (tok.isEmpty()) {
+ qWarning("Parse error in line %d column %d while parsing token %s", e.lineNumber, errCol, e.key.toLocal8Bit().constData());
+ return DFA();
+ }
+ tok.setTerminationSymbol(e.key);
+ tokens.append(tok);
+ }
+
+ NFA giganticStateMachine;
+ foreach (NFA nfa, tokens)
+ if (giganticStateMachine.isEmpty())
+ giganticStateMachine = nfa;
+ else
+ giganticStateMachine = NFA::createAlternatingNFA(giganticStateMachine, nfa);
+
+ DFA result = giganticStateMachine.toDFA().minimize();
+ if (cfg.cache) {
+ QFileInfo ruleInfo(cfg.ruleFile);
+ QFileInfo cacheInfo(ruleInfo.baseName() + ".dfa");
+ QFile f(cacheInfo.absoluteFilePath());
+ f.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ QDataStream stream(&f);
+ stream << result;
+ }
+ return result;
+}
+
+#if !defined(AUTOTEST)
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ QString ruleFile;
+ Config cfg;
+
+ const QStringList arguments = app.arguments().mid(1);
+ cfg.debug = arguments.contains("-debug");
+ const bool testRules = arguments.contains("-test");
+ cfg.cache = arguments.contains("-cache");
+
+ foreach (const QString &arg, arguments)
+ if (!arg.startsWith(QLatin1Char('-'))) {
+ ruleFile = arg;
+ break;
+ }
+
+ if (ruleFile.isEmpty()) {
+ qWarning("usage: lexgen [-test rulefile");
+ qWarning(" ");
+ qWarning(" the -test option will cause lexgen to interpret standard input");
+ qWarning(" according to the specified rules and print out pairs of token and");
+ qWarning(" lexical element");
+ return 1;
+ }
+
+ if (!loadConfig(ruleFile, &cfg))
+ return 1;
+
+ DFA machine = generateMachine(cfg);
+ if (machine.isEmpty())
+ return 1;
+
+ if (testRules) {
+ qWarning("Testing:");
+ QString input = QTextStream(stdin).readAll();
+ /*
+ qDebug() << "NFA has" << machine.stateCount() << "states";
+ qDebug() << "Converting to DFA... (this may take a while)";
+ DFA dfa = machine.toDFA();
+ qDebug() << "DFA has" << dfa.count() << "states";
+ qDebug() << "Minimizing...";
+ dfa = dfa.minimize();
+ qDebug() << "Minimized DFA has" << dfa.count() << "states";
+ */
+ DFA dfa = machine;
+ if (cfg.debug)
+ qDebug() << "tokenizing" << input;
+ bool ok = false;
+ QList<Symbol> symbols = tokenize(dfa, input, &cfg, &ok);
+ if (symbols.isEmpty()) {
+ qWarning("No tokens produced!");
+ } else {
+ foreach (Symbol s, symbols)
+ qDebug() << s.token << ":" << s.lexem;
+ }
+ if (ok)
+ qDebug() << symbols.count() << "tokens produced.";
+ else
+ qDebug() << "Error while tokenizing!";
+ } else {
+ Generator gen(machine, cfg);
+ QTextStream(stdout)
+ << gen.generate();
+ }
+
+ return 0;
+}
+#endif
+
diff --git a/util/lexgen/nfa.cpp b/util/lexgen/nfa.cpp
new file mode 100644
index 0000000000..4adde3a5cf
--- /dev/null
+++ b/util/lexgen/nfa.cpp
@@ -0,0 +1,508 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "nfa.h"
+#include <QSet>
+#include <limits.h>
+
+NFA NFA::createSingleInputNFA(InputType input)
+{
+ NFA result;
+ result.initialize(2);
+ result.addTransition(result.initialState, input, result.finalState);
+ return result;
+}
+
+NFA NFA::createSymbolNFA(const QString &symbol)
+{
+ NFA result = NFA::createSingleInputNFA(Epsilon);
+ result.states[result.finalState].symbol = symbol;
+ return result;
+}
+
+void NFA::initialize(int size)
+{
+ states.resize(size);
+ states.fill(State());
+ initialState = 0;
+ finalState = size - 1;
+}
+
+void NFA::addTransition(int from, InputType input, int to)
+{
+ assertValidState(from);
+ assertValidState(to);
+
+ states[from].transitions.insertMulti(input, to);
+}
+
+void NFA::copyFrom(const NFA &other, int baseState)
+{
+ assertValidState(baseState);
+ assertValidState(baseState + other.states.count() - 1);
+
+ for (int i = 0; i < other.states.count(); ++i) {
+ State s = other.states.at(i);
+
+ for (TransitionMap::Iterator it = s.transitions.begin(),
+ end = s.transitions.end(); it != end; ++it)
+ *it += baseState;
+
+ states[baseState + i] = s;
+ }
+}
+
+void NFA::initializeFromPair(const NFA &a, const NFA &b,
+ int *initialA, int *finalA,
+ int *initialB, int *finalB)
+{
+ initialize(a.states.count() + b.states.count() + 2);
+
+ int baseIdxA = 1;
+ int baseIdxB = 1 + a.states.count();
+
+ *initialA = a.initialState + baseIdxA;
+ *finalA = a.finalState + baseIdxA;
+
+ *initialB = b.initialState + baseIdxB;
+ *finalB = b.finalState + baseIdxB;
+
+ copyFrom(a, baseIdxA);
+ copyFrom(b, baseIdxB);
+}
+
+NFA NFA::createAlternatingNFA(const NFA &a, const NFA &b)
+{
+ NFA result;
+
+ int newInitialA, newFinalA,
+ newInitialB, newFinalB;
+
+ result.initializeFromPair(a, b, &newInitialA, &newFinalA,
+ &newInitialB, &newFinalB);
+
+ result.addTransition(result.initialState, Epsilon, newInitialA);
+ result.addTransition(result.initialState, Epsilon, newInitialB);
+
+ result.addTransition(newFinalA, Epsilon, result.finalState);
+ result.addTransition(newFinalB, Epsilon, result.finalState);
+
+ return result;
+}
+
+NFA NFA::createConcatenatingNFA(const NFA &a, const NFA &b)
+{
+ NFA result;
+
+ int initialA, finalA,
+ initialB, finalB;
+
+ result.initializeFromPair(a, b, &initialA, &finalA, &initialB, &finalB);
+
+ result.addTransition(result.initialState, Epsilon, initialA);
+ result.addTransition(finalA, Epsilon, initialB);
+ result.addTransition(finalB, Epsilon, result.finalState);
+ return result;
+}
+
+NFA NFA::createOptionalNFA(const NFA &a)
+{
+ NFA result;
+
+ result.initialize(a.states.count() + 2);
+
+ int baseIdxA = 1;
+ int initialA = a.initialState + baseIdxA;
+ int finalA = a.finalState + baseIdxA;
+
+ result.copyFrom(a, baseIdxA);
+
+ result.addTransition(result.initialState, Epsilon, initialA);
+ result.addTransition(result.initialState, Epsilon, result.finalState);
+
+ result.addTransition(finalA, Epsilon, initialA);
+ result.addTransition(finalA, Epsilon, result.finalState);
+
+ return result;
+}
+
+NFA NFA::createStringNFA(const QByteArray &str)
+{
+ NFA result;
+ foreach (char c, str) {
+ NFA ch = NFA::createSingleInputNFA(c);
+ if (result.isEmpty())
+ result = ch;
+ else
+ result = NFA::createConcatenatingNFA(result, ch);
+ }
+ return result;
+}
+
+NFA NFA::createSetNFA(const QSet<InputType> &set)
+{
+ NFA result;
+ result.initialize(set.count() + 2);
+
+ int state = 1;
+ for (QSet<InputType>::ConstIterator it = set.constBegin(), end = set.constEnd();
+ it != end; ++it, ++state) {
+ result.addTransition(result.initialState, Epsilon, state);
+ result.addTransition(state, *it, result.finalState);
+ }
+
+ /*
+ foreach (InputType input, set) {
+ NFA ch = NFA::createSingleInputNFA(input);
+ if (result.isEmpty())
+ result = ch;
+ else
+ result = NFA::createAlternatingNFA(result, ch);
+ }
+ */
+ return result;
+}
+
+NFA NFA::createZeroOrOneNFA(const NFA &a)
+{
+ NFA epsilonNFA = createSingleInputNFA(Epsilon);
+ return NFA::createAlternatingNFA(a, epsilonNFA);
+}
+
+NFA NFA::applyQuantity(const NFA &a, int minOccurrences, int maxOccurrences)
+{
+ NFA result = a;
+ NFA epsilonNFA = createSingleInputNFA(Epsilon);
+
+ if (minOccurrences == 0) {
+ result = NFA::createAlternatingNFA(result, epsilonNFA);
+ } else {
+ minOccurrences--;
+ }
+ maxOccurrences--;
+
+ for (int i = 0; i < minOccurrences; ++i)
+ result = NFA::createConcatenatingNFA(result, a);
+
+ for (int i = minOccurrences; i < maxOccurrences; ++i)
+ result = NFA::createConcatenatingNFA(result, NFA::createAlternatingNFA(a, epsilonNFA));
+
+ return result;
+}
+
+void NFA::debug()
+{
+ qDebug() << "NFA has" << states.count() << "states";
+ qDebug() << "initial state is" << initialState;
+ qDebug() << "final state is" << finalState;
+
+ for (int i = 0; i < states.count(); ++i) {
+ const State &s = states.at(i);
+ for (TransitionMap::ConstIterator it = s.transitions.constBegin(),
+ end = s.transitions.constEnd(); it != end; ++it)
+ qDebug() << "transition from state" << i << "to" << it.value() << "through"
+ << (it.key() == Epsilon ? QString("Epsilon") : QString(char(it.key())));
+ if (!s.symbol.isEmpty())
+ qDebug() << "State" << i << "leads to symbol" << s.symbol;
+ }
+}
+
+// helper
+typedef QSet<int> DFAState;
+
+// that's a bad hash, but it's good enough for us
+// and it allows us to use the nice QHash API :)
+inline uint qHash(const DFAState &state)
+{
+ uint val = 0;
+ foreach (int s, state)
+ val |= qHash(s);
+ return val;
+}
+
+DFA NFA::toDFA() const
+{
+ DFA result;
+ result.reserve(states.count());
+
+ QHash<QString, int> symbolReferenceCounts;
+ {
+ QSet<int> symbolStates;
+ for (int i = 0; i < states.count(); ++i)
+ if (!states.at(i).symbol.isEmpty())
+ symbolStates.insert(i);
+
+ QHash<int, QString> epsilonStates;
+ for (int i = 0; i < states.count(); ++i) {
+ const State &s = states.at(i);
+ for (TransitionMap::ConstIterator transition = s.transitions.constBegin(), end = s.transitions.constEnd();
+ transition != end; ++transition)
+ if (transition.key() == Epsilon && symbolStates.contains(transition.value()))
+ epsilonStates.insert(i, states.at(transition.value()).symbol);
+ }
+
+ int lastCount;
+ do {
+ lastCount = epsilonStates.count();
+ for (int i = 0; i < states.count(); ++i) {
+ const State &s = states.at(i);
+ for (TransitionMap::ConstIterator transition = s.transitions.constBegin(), end = s.transitions.constEnd();
+ transition != end; ++transition)
+ if (transition.key() == Epsilon && epsilonStates.contains(transition.value()))
+ epsilonStates.insert(i, epsilonStates.value(transition.value()));
+ }
+
+ } while (lastCount != epsilonStates.count());
+
+ for (int i = 0; i < states.count(); ++i) {
+ const State &s = states.at(i);
+ for (TransitionMap::ConstIterator transition = s.transitions.constBegin(), end = s.transitions.constEnd();
+ transition != end; ++transition) {
+ if (transition.key() == Epsilon)
+ continue;
+ if (symbolStates.contains(transition.value())) {
+ const QString symbol = states.at(transition.value()).symbol;
+ symbolReferenceCounts[symbol]++;
+ } else if (epsilonStates.contains(transition.value())) {
+ const QString symbol = epsilonStates.value(transition.value());
+ symbolReferenceCounts[symbol]++;
+ }
+ }
+ }
+ /*
+ for (QHash<QString, int>::ConstIterator symIt = symbolReferenceCounts.constBegin(), symEnd = symbolReferenceCounts.constEnd();
+ symIt != symEnd; ++symIt)
+ qDebug() << "symbol" << symIt.key() << "is reached" << symIt.value() << "times";
+ */
+ }
+
+
+ QSet<InputType> validInput;
+ foreach (const State &s, states)
+ for (TransitionMap::ConstIterator it = s.transitions.constBegin(),
+ end = s.transitions.constEnd(); it != end; ++it)
+ if (it.key() != Epsilon)
+ validInput.insert(it.key());
+
+ // A DFA state can consist of multiple NFA states.
+ // the dfaStateMap maps from these to the actual
+ // state index within the resulting DFA vector
+ QHash<DFAState, int> dfaStateMap;
+ QStack<DFAState> pendingDFAStates;
+
+ DFAState startState = epsilonClosure(QSet<int>() << initialState);
+
+ result.resize(1);
+ dfaStateMap.insert(startState, 0);
+
+ pendingDFAStates.push(startState);
+
+ while (!pendingDFAStates.isEmpty()) {
+ DFAState state = pendingDFAStates.pop();
+// qDebug() << "processing" << state << "from the stack of pending states";
+
+ foreach (InputType input, validInput) {
+
+ QSet<int> reachableStates;
+
+ foreach (int nfaState, state) {
+ const TransitionMap &transitions = states.at(nfaState).transitions;
+ TransitionMap::ConstIterator it = transitions.find(input);
+ while (it != transitions.constEnd() && it.key() == input) {
+ reachableStates.insert(it.value());
+ ++it;
+ }
+ }
+
+ if (reachableStates.isEmpty())
+ continue;
+
+// qDebug() << "can reach" << reachableStates << "from input" << char(input);
+
+ QSet<int> closure = epsilonClosure(reachableStates);
+
+// qDebug() << "closure is" << closure;
+
+ if (!dfaStateMap.contains(closure)) {
+ int dfaState = result.count();
+ result.append(State());
+
+ QString symbol;
+ int refCount = INT_MAX;
+ foreach (int nfaState, closure)
+ if (!states.at(nfaState).symbol.isEmpty()) {
+// qDebug() << "closure also contains symbol" << states.at(nfaState).symbol;
+ QString candidate = states.at(nfaState).symbol;
+ int candidateRefCount =symbolReferenceCounts.value(candidate, INT_MAX);
+ if (candidateRefCount < refCount) {
+ refCount = candidateRefCount;
+ symbol = candidate;
+ }
+ }
+ if (!symbol.isEmpty())
+ result.last().symbol = symbol;
+
+ dfaStateMap.insert(closure, dfaState);
+
+ Q_ASSERT(!pendingDFAStates.contains(closure));
+ pendingDFAStates.prepend(closure);
+ }
+
+ result[dfaStateMap.value(state)].transitions.insert(input, dfaStateMap.value(closure));
+ }
+ }
+
+ return result;
+}
+
+QSet<int> NFA::epsilonClosure(const QSet<int> &initialClosure) const
+{
+ QSet<int> closure = initialClosure;
+ closure.reserve(closure.count() * 4);
+
+ QStack<int> stateStack;
+ stateStack.resize(closure.count());
+ qCopy(closure.constBegin(), closure.constEnd(), stateStack.begin());
+
+ while (!stateStack.isEmpty()) {
+ int t = stateStack.pop();
+ const TransitionMap &transitions = states.at(t).transitions;
+ TransitionMap::ConstIterator it = transitions.find(Epsilon);
+ while (it != transitions.constEnd() && it.key() == Epsilon) {
+ const int u = it.value();
+ if (!closure.contains(u)) {
+ closure.insert(u);
+ stateStack.push(u);
+ }
+ ++it;
+ }
+ }
+
+ return closure;
+}
+
+void NFA::setTerminationSymbol(const QString &symbol)
+{
+ states[finalState].symbol = symbol;
+}
+
+void DFA::debug() const
+{
+ qDebug() << "DFA has" << count() << "states";
+
+ for (int i = 0; i < count(); ++i) {
+ const State &s = at(i);
+ if (s.transitions.isEmpty()) {
+ qDebug() << "State" << i << "has no transitions";
+ } else {
+ for (TransitionMap::ConstIterator it = s.transitions.constBegin(),
+ end = s.transitions.constEnd(); it != end; ++it)
+ qDebug() << "transition from state" << i << "to" << it.value() << "through"
+ << (it.key() == Epsilon ? QString("Epsilon") : QString(char(it.key())));
+ }
+ if (!s.symbol.isEmpty())
+ qDebug() << "State" << i << "leads to symbol" << s.symbol;
+ }
+
+}
+
+DFA DFA::minimize() const
+{
+ QVector<bool> inequivalentStates(count() * count());
+ inequivalentStates.fill(false);
+
+ for (int i = 0; i < count(); ++i)
+ for (int j = 0; j < i; ++j) {
+ if (i != j && at(i).symbol != at(j).symbol)
+ inequivalentStates[i * count() + j] = true;
+ }
+
+ bool done;
+ do {
+ done = true;
+ for (int i = 0; i < count(); ++i)
+ for (int j = 0; j < count(); ++j) {
+ if (i == j)
+ continue;
+
+ if (inequivalentStates[i * count() + j])
+ continue;
+
+ if (at(i).transitions.keys() != at(j).transitions.keys()) {
+ inequivalentStates[i * count() + j] = true;
+ done = false;
+ continue;
+ }
+
+ foreach (InputType a, at(i).transitions.keys()) {
+ int r = at(i).transitions.value(a, -1);
+ if (r == -1)
+ continue;
+ int s = at(j).transitions.value(a, -1);
+ if (s == -1)
+ continue;
+
+ if (inequivalentStates[r * count() + s]
+ || r == s) {
+ inequivalentStates[i * count() + j] = true;
+ done = false;
+ break;
+ }
+ }
+ }
+ } while (!done);
+
+ QHash<int, int> statesToEliminate;
+ for (int i = 0; i < count(); ++i)
+ for (int j = 0; j < i; ++j)
+ if (!inequivalentStates[i * count() + j]) {
+ statesToEliminate.insertMulti(i, j);
+ }
+
+ /*
+ qDebug() << "states to eliminiate:" << statesToEliminate.count();;
+ qDebug() << "merging" << statesToEliminate;
+ debug();
+ */
+
+ return *this;
+}
+
+
diff --git a/util/lexgen/nfa.h b/util/lexgen/nfa.h
new file mode 100644
index 0000000000..02657b33eb
--- /dev/null
+++ b/util/lexgen/nfa.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NFA_H
+#define NFA_H
+
+#include <QMap>
+#include <QHash>
+#include <QString>
+#include <QVector>
+#include <QDebug>
+#include <QStack>
+#include <QByteArray>
+
+#include "global.h"
+
+typedef QHash<InputType, int> TransitionMap;
+
+struct State
+{
+ QString symbol;
+ TransitionMap transitions;
+};
+
+inline QDataStream &operator<<(QDataStream &stream, const State &state)
+{
+ return stream << state.symbol << state.transitions;
+}
+
+inline QDataStream &operator>>(QDataStream &stream, State &state)
+{
+ return stream >> state.symbol >> state.transitions;
+}
+
+struct DFA : public QVector<State>
+{
+ void debug() const;
+ DFA minimize() const;
+};
+
+class NFA
+{
+public:
+ static NFA createSingleInputNFA(InputType input);
+ static NFA createSymbolNFA(const QString &symbol);
+ static NFA createAlternatingNFA(const NFA &a, const NFA &b);
+ static NFA createConcatenatingNFA(const NFA &a, const NFA &b);
+ static NFA createOptionalNFA(const NFA &a);
+
+ // convenience
+ static NFA createStringNFA(const QByteArray &str);
+ static NFA createSetNFA(const QSet<InputType> &set);
+ static NFA createZeroOrOneNFA(const NFA &a);
+ static NFA applyQuantity(const NFA &a, int minOccurrences, int maxOccurrences);
+
+ void setTerminationSymbol(const QString &symbol);
+
+ DFA toDFA() const;
+
+ inline bool isEmpty() const { return states.isEmpty(); }
+ inline int stateCount() const { return states.count(); }
+
+ void debug();
+
+private:
+ void initialize(int size);
+ void addTransition(int from, InputType input, int to);
+ void copyFrom(const NFA &other, int baseState);
+
+ void initializeFromPair(const NFA &a, const NFA &b,
+ int *initialA, int *finalA,
+ int *initialB, int *finalB);
+
+ QSet<int> epsilonClosure(const QSet<int> &initialClosure) const;
+
+ inline void assertValidState(int state)
+ { Q_UNUSED(state); Q_ASSERT(state >= 0); Q_ASSERT(state < states.count()); }
+
+#if defined(AUTOTEST)
+public:
+#endif
+ int initialState;
+ int finalState;
+
+ QVector<State> states;
+};
+
+#endif // NFA_H
+
diff --git a/util/lexgen/re2nfa.cpp b/util/lexgen/re2nfa.cpp
new file mode 100644
index 0000000000..77cf5019fe
--- /dev/null
+++ b/util/lexgen/re2nfa.cpp
@@ -0,0 +1,547 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "re2nfa.h"
+#include "tokenizer.cpp"
+
+RE2NFA::RE2NFA(const QMap<QString, NFA> &macros, const QSet<InputType> &maxInputSet, Qt::CaseSensitivity cs)
+ : macros(macros), index(0), errorColumn(-1), maxInputSet(maxInputSet), caseSensitivity(cs)
+{
+}
+
+NFA RE2NFA::parse(const QString &expression, int *errCol)
+{
+ tokenize(expression);
+
+ if (symbols.isEmpty())
+ return NFA();
+
+ index = 0;
+
+ NFA result = parseExpr();
+ if (result.isEmpty()) {
+ if (errCol)
+ *errCol = errorColumn;
+ }
+ return result;
+}
+
+NFA RE2NFA::parseExpr()
+{
+ NFA value = parseBranch();
+ while (test(TOK_OR)) {
+ NFA rhs = parseBranch();
+ value = NFA::createAlternatingNFA(value, rhs);
+ }
+ return value;
+}
+
+NFA RE2NFA::parseBranch()
+{
+ NFA value = parsePiece();
+ if (!hasNext())
+ return value;
+ NFA next;
+ do {
+ next = parsePiece();
+ if (!next.isEmpty())
+ value = NFA::createConcatenatingNFA(value, next);
+ } while (!next.isEmpty() && hasNext());
+ return value;
+}
+
+NFA RE2NFA::parsePiece()
+{
+ NFA atom = parseAtom();
+ if (atom.isEmpty() || !hasNext())
+ return atom;
+ return parseMaybeQuantifier(atom);
+}
+
+NFA RE2NFA::parseAtom()
+{
+ // ####
+ switch (next()) {
+ case TOK_STRING:
+ return createCharNFA();
+ case TOK_LPAREN: {
+ NFA subExpr = parseExpr();
+ next(TOK_RPAREN);
+ return subExpr;
+ }
+ case TOK_LBRACE: {
+ QString macroName = lexemUntil(TOK_RBRACE);
+ QMap<QString, NFA>::ConstIterator macro = macros.find(macroName);
+ if (macro == macros.end()) {
+ qWarning("Unknown macro '%s' - probably used before defined", qPrintable(macroName));
+ return NFA();
+ }
+ return *macro;
+ }
+ case TOK_LBRACKET: {
+ NFA set = parseSet();
+ next(TOK_RBRACKET);
+ return set;
+ }
+ case TOK_SEQUENCE:
+ return parseSet2();
+ case TOK_DOT:
+ return NFA::createSetNFA(maxInputSet);
+ default:
+ prev();
+ return NFA();
+ }
+}
+
+NFA RE2NFA::parseMaybeQuantifier(const NFA &nfa)
+{
+ // ####
+ switch (next()) {
+ case TOK_STAR:
+ return NFA::createOptionalNFA(nfa);
+ case TOK_QUESTION:
+ return NFA::createZeroOrOneNFA(nfa);
+ case TOK_PLUS:
+ return NFA::createConcatenatingNFA(nfa, NFA::createOptionalNFA(nfa));
+ case TOK_LBRACE: {
+ const int rewind = index - 1;
+
+ QString lexemBeforeComma;
+ QString lexemAfterComma;
+ bool seenComma = false;
+ forever {
+ if (test(TOK_COMMA)) {
+ if (seenComma) {
+ errorColumn = symbol().column;
+ return NFA();
+ }
+ seenComma = true;
+ } else if (test(TOK_RBRACE)) {
+ break;
+ } else {
+ next(TOK_STRING);
+ if (seenComma)
+ lexemAfterComma += symbol().lexem;
+ else
+ lexemBeforeComma += symbol().lexem;
+ }
+ }
+ bool isNumber = false;
+ int min = lexemBeforeComma.toInt(&isNumber);
+ if (!isNumber) {
+ index = rewind;
+ return nfa;
+ }
+ int max = min;
+ if (seenComma) {
+ max = lexemAfterComma.toInt(&isNumber);
+ if (!isNumber) {
+ errorColumn = symbol().column;
+ return NFA();
+ }
+ }
+ return NFA::applyQuantity(nfa, min, max);
+ }
+ default:
+ prev();
+ return nfa;
+ }
+}
+
+NFA RE2NFA::parseSet()
+{
+ QSet<InputType> set;
+ bool negate = false;
+
+ next(TOK_STRING);
+
+ do {
+ Q_ASSERT(symbol().lexem.length() == 1);
+ // ###
+ QChar ch = symbol().lexem.at(0);
+ if (set.isEmpty() && ch == QLatin1Char('^')) {
+ negate = true;
+ continue;
+ }
+
+ // look ahead for ranges like a-z
+ bool rangeFound = false;
+ if (test(TOK_STRING)) {
+ if (symbol().lexem.length() == 1
+ && symbol().lexem.at(0) == QLatin1Char('-')) {
+ next(TOK_STRING);
+ Q_ASSERT(symbol().lexem.length() == 1);
+ QChar last = symbol().lexem.at(0);
+
+ if (ch.unicode() > last.unicode())
+ qSwap(ch, last);
+
+ for (ushort i = ch.unicode(); i <= last.unicode(); ++i) {
+ if (caseSensitivity == Qt::CaseInsensitive) {
+ set.insert(QChar(i).toLower().unicode());
+ } else {
+ set.insert(i);
+ }
+ }
+
+ rangeFound = true;
+ } else {
+ prev();
+ }
+ }
+
+ if (!rangeFound) {
+ if (caseSensitivity == Qt::CaseInsensitive) {
+ set.insert(ch.toLower().unicode());
+ } else {
+ set.insert(ch.unicode());
+ }
+ }
+ } while (test(TOK_STRING));
+
+ if (negate) {
+ QSet<InputType> negatedSet = maxInputSet;
+ negatedSet.subtract(set);
+ set = negatedSet;
+ }
+
+ return NFA::createSetNFA(set);
+}
+
+NFA RE2NFA::parseSet2()
+{
+ QSet<InputType> set;
+ bool negate = false;
+
+ QString str = symbol().lexem;
+ // strip off brackets
+ str.chop(1);
+ str.remove(0, 1);
+
+ int i = 0;
+ while (i < str.length()) {
+ // ###
+ QChar ch = str.at(i++);
+ if (set.isEmpty() && ch == QLatin1Char('^')) {
+ negate = true;
+ continue;
+ }
+
+ // look ahead for ranges like a-z
+ bool rangeFound = false;
+ if (i < str.length() - 1 && str.at(i) == QLatin1Char('-')) {
+ ++i;
+ QChar last = str.at(i++);
+
+ if (ch.unicode() > last.unicode())
+ qSwap(ch, last);
+
+ for (ushort i = ch.unicode(); i <= last.unicode(); ++i) {
+ if (caseSensitivity == Qt::CaseInsensitive) {
+ set.insert(QChar(i).toLower().unicode());
+ } else {
+ set.insert(i);
+ }
+ }
+
+ rangeFound = true;
+ }
+
+ if (!rangeFound) {
+ if (caseSensitivity == Qt::CaseInsensitive) {
+ set.insert(ch.toLower().unicode());
+ } else {
+ set.insert(ch.unicode());
+ }
+ }
+ }
+
+ if (negate) {
+ QSet<InputType> negatedSet = maxInputSet;
+ negatedSet.subtract(set);
+ set = negatedSet;
+ }
+
+ return NFA::createSetNFA(set);
+}
+NFA RE2NFA::createCharNFA()
+{
+ NFA nfa;
+ // ####
+ if (caseSensitivity == Qt::CaseInsensitive) {
+ nfa = NFA::createStringNFA(symbol().lexem.toLower().toLatin1());
+ } else {
+ nfa = NFA::createStringNFA(symbol().lexem.toLatin1());
+ }
+ return nfa;
+}
+
+static inline int skipQuote(const QString &str, int pos)
+{
+ while (pos < str.length()
+ && str.at(pos) != QLatin1Char('"')) {
+ if (str.at(pos) == QLatin1Char('\\')) {
+ ++pos;
+ if (pos >= str.length())
+ break;
+ }
+ ++pos;
+ }
+ if (pos < str.length())
+ ++pos;
+ return pos;
+}
+
+#if 0
+static const char*tokStr(Token t)
+{
+ switch (t) {
+ case TOK_INVALID: return "TOK_INVALID";
+ case TOK_STRING: return "TOK_STRING";
+ case TOK_LBRACE: return "TOK_LBRACE";
+ case TOK_RBRACE: return "TOK_RBRACE";
+ case TOK_LBRACKET: return "TOK_LBRACKET";
+ case TOK_RBRACKET: return "TOK_RBRACKET";
+ case TOK_LPAREN: return "TOK_LPAREN";
+ case TOK_RPAREN: return "TOK_RPAREN";
+ case TOK_COMMA: return "TOK_COMMA";
+ case TOK_STAR: return "TOK_STAR";
+ case TOK_OR: return "TOK_OR";
+ case TOK_QUESTION: return "TOK_QUESTION";
+ case TOK_DOT: return "TOK_DOT";
+ case TOK_PLUS: return "TOK_PLUS";
+ case TOK_SEQUENCE: return "TOK_SEQUENCE";
+ case TOK_QUOTED_STRING: return "TOK_QUOTED_STRING";
+ }
+ return "";
+}
+#endif
+
+void RE2NFA::tokenize(const QString &input)
+{
+ symbols.clear();
+#if 1
+ RegExpTokenizer tokenizer(input);
+ Symbol sym;
+ int tok = tokenizer.lex();
+ while (tok != -1) {
+ Symbol sym;
+ sym.token = static_cast<Token>(tok);
+ sym.lexem = input.mid(tokenizer.lexemStart, tokenizer.lexemLength);
+
+ if (sym.token == TOK_QUOTED_STRING) {
+ sym.lexem.chop(1);
+ sym.lexem.remove(0, 1);
+ sym.token = TOK_STRING;
+ }
+
+ if (sym.token == TOK_STRING || sym.token == TOK_SEQUENCE) {
+ for (int i = 0; i < sym.lexem.length(); ++i) {
+ if (sym.lexem.at(i) == '\\') {
+ if (i >= sym.lexem.length() - 1)
+ break;
+ QChar ch = sym.lexem.at(i + 1);
+ if (ch == QLatin1Char('n')) {
+ ch = '\n';
+ } else if (ch == QLatin1Char('r')) {
+ ch = '\r';
+ } else if (ch == QLatin1Char('t')) {
+ ch = '\t';
+ } else if (ch == QLatin1Char('f')) {
+ ch = '\f';
+ }
+ sym.lexem.replace(i, 2, ch);
+ }
+ }
+ }
+
+ /*
+ if (sym.token == TOK_SEQUENCE) {
+ Symbol s;
+ s.token = TOK_LBRACKET;
+ s.lexem = "[";
+ symbols.append(s);
+
+ for (int i = 1; i < sym.lexem.length() - 1; ++i) {
+ s.token = TOK_STRING;
+ s.lexem = sym.lexem.at(i);
+ symbols.append(s);
+ }
+
+ s.token = TOK_RBRACKET;
+ s.lexem = "]";
+ symbols.append(s);
+
+ tok = tokenizer.lex();
+ continue;
+ }
+ */
+
+ symbols.append(sym);
+ tok = tokenizer.lex();
+ }
+#else
+ int pos = 0;
+ bool insideSet = false;
+ while (pos < input.length()) {
+ QChar ch = input.at(pos);
+
+ Symbol sym;
+ sym.column = pos;
+ sym.token = TOK_INVALID;
+ sym.lexem = QString(ch);
+ switch (ch.toLatin1()) {
+ case '"': {
+ if (insideSet) {
+ sym.token = TOK_STRING;
+ sym.lexem = QString(ch);
+ symbols += sym;
+ ++pos;
+ continue;
+ }
+ if (pos + 1 >= input.length())
+ return;
+ int quoteEnd = skipQuote(input, pos + 1);
+ sym.token = TOK_STRING;
+ sym.lexem = input.mid(pos + 1, quoteEnd - pos - 2);
+ symbols += sym;
+ pos = quoteEnd;
+ continue;
+ }
+ case '{':
+ sym.token = (insideSet ? TOK_STRING : TOK_LBRACE);
+ break;
+ case '}':
+ sym.token = (insideSet ? TOK_STRING : TOK_RBRACE);
+ break;
+ case '[':
+ insideSet = true;
+ sym.token = TOK_LBRACKET;
+ break;
+ case ']':
+ insideSet = false;
+ sym.token = TOK_RBRACKET;
+ break;
+ case '(':
+ sym.token = (insideSet ? TOK_STRING : TOK_LPAREN);
+ break;
+ case ')':
+ sym.token = (insideSet ? TOK_STRING : TOK_RPAREN);
+ break;
+ case ',':
+ sym.token = (insideSet ? TOK_STRING : TOK_COMMA);
+ break;
+ case '*':
+ sym.token = (insideSet ? TOK_STRING : TOK_STAR);
+ break;
+ case '|':
+ sym.token = (insideSet ? TOK_STRING : TOK_OR);
+ break;
+ case '?':
+ sym.token = (insideSet ? TOK_STRING : TOK_QUESTION);
+ break;
+ case '.':
+ sym.token = (insideSet ? TOK_STRING : TOK_DOT);
+ break;
+ case '+':
+ sym.token = (insideSet ? TOK_STRING : TOK_PLUS);
+ break;
+ case '\\':
+ ++pos;
+ if (pos >= input.length())
+ return;
+ ch = input.at(pos);
+ if (ch == QLatin1Char('n')) {
+ ch = '\n';
+ } else if (ch == QLatin1Char('r')) {
+ ch = '\r';
+ } else if (ch == QLatin1Char('t')) {
+ ch = '\t';
+ } else if (ch == QLatin1Char('f')) {
+ ch = '\f';
+ }
+ // fall through
+ default:
+ sym.token = TOK_STRING;
+ sym.lexem = QString(ch);
+ symbols += sym;
+ ++pos;
+ continue;
+ }
+ symbols += sym;
+ ++pos;
+ }
+#endif
+#if 0
+ foreach (Symbol s, symbols) {
+ qDebug() << "Tok" << tokStr(s.token) << "lexem" << s.lexem;
+ }
+#endif
+}
+
+bool RE2NFA::next(Token t)
+{
+ if (hasNext() && next() == t)
+ return true;
+ errorColumn = symbol().column;
+ Q_ASSERT(false);
+ return false;
+}
+
+bool RE2NFA::test(Token t)
+{
+ if (index >= symbols.count())
+ return false;
+ if (symbols.at(index).token == t) {
+ ++index;
+ return true;
+ }
+ return false;
+}
+
+QString RE2NFA::lexemUntil(Token t)
+{
+ QString lexem;
+ while (hasNext() && next() != t)
+ lexem += symbol().lexem;
+ return lexem;
+}
+
diff --git a/util/lexgen/re2nfa.h b/util/lexgen/re2nfa.h
new file mode 100644
index 0000000000..57b8bde09e
--- /dev/null
+++ b/util/lexgen/re2nfa.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RE2NFA_H
+#define RE2NFA_H
+
+#include "nfa.h"
+#include <QSet>
+
+class RE2NFA
+{
+public:
+ RE2NFA(const QMap<QString, NFA> &macros, const QSet<InputType> &maxInputSet, Qt::CaseSensitivity cs);
+
+ NFA parse(const QString &expression, int *errorColumn = 0);
+
+private:
+ NFA parseExpr();
+ NFA parseBranch();
+ NFA parsePiece();
+ NFA parseAtom();
+ NFA parseMaybeQuantifier(const NFA &nfa);
+ NFA parseSet();
+ NFA parseSet2();
+
+ NFA createCharNFA();
+
+private:
+ friend class RegExpTokenizer;
+
+ enum Token {
+ TOK_INVALID,
+ TOK_STRING,
+ TOK_LBRACE, // {
+ TOK_RBRACE, // }
+ TOK_LBRACKET, // [
+ TOK_RBRACKET, // ]
+ TOK_LPAREN, // (
+ TOK_RPAREN, // )
+ TOK_COMMA,
+ TOK_STAR,
+ TOK_OR,
+ TOK_QUESTION,
+ TOK_DOT,
+ TOK_PLUS,
+ TOK_SEQUENCE,
+ TOK_QUOTED_STRING
+ };
+
+ struct Symbol
+ {
+ inline Symbol() : token(TOK_INVALID), column(-1) {}
+ inline Symbol(Token t, const QString &l = QString()) : token(t), lexem(l), column(-1) {}
+ Token token;
+ QString lexem;
+ int column;
+ };
+
+ inline bool hasNext() const { return index < symbols.count(); }
+ inline Token next() { return symbols.at(index++).token; }
+ bool next(Token t);
+ bool test(Token t);
+ inline void prev() { index--; }
+ inline const Symbol &symbol() const { return symbols.at(index - 1); }
+ QString lexemUntil(Token t);
+
+ void tokenize(const QString &input);
+
+ QMap<QString, NFA> macros;
+ QVector<Symbol> symbols;
+ int index;
+ int errorColumn;
+ const QSet<InputType> maxInputSet;
+ Qt::CaseSensitivity caseSensitivity;
+};
+
+#endif // RE2NFA_H
+
diff --git a/util/lexgen/test.lexgen b/util/lexgen/test.lexgen
new file mode 100644
index 0000000000..fd532fd549
--- /dev/null
+++ b/util/lexgen/test.lexgen
@@ -0,0 +1,9 @@
+[Options]
+case-insensitive
+classname = TestScanner
+
+[Tokens]
+TOK_C = [abcd]
+TOK_B = [bc]
+TOK_A = a
+
diff --git a/util/lexgen/tests/testdata/backtrack1/input b/util/lexgen/tests/testdata/backtrack1/input
new file mode 100644
index 0000000000..f5099b509d
--- /dev/null
+++ b/util/lexgen/tests/testdata/backtrack1/input
@@ -0,0 +1 @@
+LETX
diff --git a/util/lexgen/tests/testdata/backtrack1/output b/util/lexgen/tests/testdata/backtrack1/output
new file mode 100644
index 0000000000..6893deb014
--- /dev/null
+++ b/util/lexgen/tests/testdata/backtrack1/output
@@ -0,0 +1 @@
+TOK_LET|LET
diff --git a/util/lexgen/tests/testdata/backtrack1/rules.lexgen b/util/lexgen/tests/testdata/backtrack1/rules.lexgen
new file mode 100644
index 0000000000..ade8a15546
--- /dev/null
+++ b/util/lexgen/tests/testdata/backtrack1/rules.lexgen
@@ -0,0 +1,3 @@
+[Tokens]
+TOK_LET = LET
+TOK_LETXX = LETXX
diff --git a/util/lexgen/tests/testdata/backtrack2/input b/util/lexgen/tests/testdata/backtrack2/input
new file mode 100644
index 0000000000..59ff5b7301
--- /dev/null
+++ b/util/lexgen/tests/testdata/backtrack2/input
@@ -0,0 +1 @@
+LETXTRA
diff --git a/util/lexgen/tests/testdata/backtrack2/output b/util/lexgen/tests/testdata/backtrack2/output
new file mode 100644
index 0000000000..348b382818
--- /dev/null
+++ b/util/lexgen/tests/testdata/backtrack2/output
@@ -0,0 +1,2 @@
+TOK_LET|LET
+TOK_XTRA|XTRA
diff --git a/util/lexgen/tests/testdata/backtrack2/rules.lexgen b/util/lexgen/tests/testdata/backtrack2/rules.lexgen
new file mode 100644
index 0000000000..6f16986e83
--- /dev/null
+++ b/util/lexgen/tests/testdata/backtrack2/rules.lexgen
@@ -0,0 +1,4 @@
+[Tokens]
+TOK_LET = LET
+TOK_LETXX = LETXX
+TOK_XTRA = XTRA
diff --git a/util/lexgen/tests/testdata/casesensitivity/input b/util/lexgen/tests/testdata/casesensitivity/input
new file mode 100644
index 0000000000..72b7f4869c
--- /dev/null
+++ b/util/lexgen/tests/testdata/casesensitivity/input
@@ -0,0 +1 @@
+abcdAbcDABCDeFgEFGefgEfghiHIHihI
diff --git a/util/lexgen/tests/testdata/casesensitivity/output b/util/lexgen/tests/testdata/casesensitivity/output
new file mode 100644
index 0000000000..3a4e819060
--- /dev/null
+++ b/util/lexgen/tests/testdata/casesensitivity/output
@@ -0,0 +1,14 @@
+TOK_AB|ab
+TOK_CD|cd
+TOK_AB|Ab
+TOK_CD|cD
+TOK_AB|AB
+TOK_CD|CD
+TOK_EFG|eFg
+TOK_EFG|EFG
+TOK_EFG|efg
+TOK_EFG|Efg
+TOK_HI|hi
+TOK_HI|HI
+TOK_HI|Hi
+TOK_HI|hI
diff --git a/util/lexgen/tests/testdata/casesensitivity/rules.lexgen b/util/lexgen/tests/testdata/casesensitivity/rules.lexgen
new file mode 100644
index 0000000000..3347587ffe
--- /dev/null
+++ b/util/lexgen/tests/testdata/casesensitivity/rules.lexgen
@@ -0,0 +1,7 @@
+[Options]
+case-insensitive
+[Tokens]
+TOK_AB = ab
+TOK_CD = cd
+TOK_EFG = [e-g]{3}
+TOK_HI = [hi]{2}
diff --git a/util/lexgen/tests/testdata/comments/input b/util/lexgen/tests/testdata/comments/input
new file mode 100644
index 0000000000..03873e044a
--- /dev/null
+++ b/util/lexgen/tests/testdata/comments/input
@@ -0,0 +1 @@
+/* comment with stuff *//*another comment with * stars * inside*/
diff --git a/util/lexgen/tests/testdata/comments/output b/util/lexgen/tests/testdata/comments/output
new file mode 100644
index 0000000000..2395ad1873
--- /dev/null
+++ b/util/lexgen/tests/testdata/comments/output
@@ -0,0 +1,2 @@
+TOK_COMMENT|/* comment with stuff */
+TOK_COMMENT|/*another comment with * stars * inside*/
diff --git a/util/lexgen/tests/testdata/comments/rules.lexgen b/util/lexgen/tests/testdata/comments/rules.lexgen
new file mode 100644
index 0000000000..490c759cc5
--- /dev/null
+++ b/util/lexgen/tests/testdata/comments/rules.lexgen
@@ -0,0 +1,2 @@
+[Tokens]
+TOK_COMMENT = \/\*[^*]*\*+([^/*][^*]*\*+)*\/
diff --git a/util/lexgen/tests/testdata/dot/input b/util/lexgen/tests/testdata/dot/input
new file mode 100644
index 0000000000..e5b0ad6e91
--- /dev/null
+++ b/util/lexgen/tests/testdata/dot/input
@@ -0,0 +1 @@
+afbcxd
diff --git a/util/lexgen/tests/testdata/dot/output b/util/lexgen/tests/testdata/dot/output
new file mode 100644
index 0000000000..6a9afd4ced
--- /dev/null
+++ b/util/lexgen/tests/testdata/dot/output
@@ -0,0 +1,2 @@
+TOK_AB|afb
+TOK_CD|cxd
diff --git a/util/lexgen/tests/testdata/dot/rules.lexgen b/util/lexgen/tests/testdata/dot/rules.lexgen
new file mode 100644
index 0000000000..03873a71bf
--- /dev/null
+++ b/util/lexgen/tests/testdata/dot/rules.lexgen
@@ -0,0 +1,3 @@
+[Tokens]
+TOK_AB = a.b
+TOK_CD = c.d
diff --git a/util/lexgen/tests/testdata/negation/input b/util/lexgen/tests/testdata/negation/input
new file mode 100644
index 0000000000..9447b8005d
--- /dev/null
+++ b/util/lexgen/tests/testdata/negation/input
@@ -0,0 +1 @@
+aycabd
diff --git a/util/lexgen/tests/testdata/negation/output b/util/lexgen/tests/testdata/negation/output
new file mode 100644
index 0000000000..0b73263fb9
--- /dev/null
+++ b/util/lexgen/tests/testdata/negation/output
@@ -0,0 +1,2 @@
+TOK_A|ayc
+TOK_B|abd
diff --git a/util/lexgen/tests/testdata/negation/rules.lexgen b/util/lexgen/tests/testdata/negation/rules.lexgen
new file mode 100644
index 0000000000..179810b3a0
--- /dev/null
+++ b/util/lexgen/tests/testdata/negation/rules.lexgen
@@ -0,0 +1,3 @@
+[Tokens]
+TOK_A = a[^b]c
+TOK_B = abd
diff --git a/util/lexgen/tests/testdata/quoteinset/input b/util/lexgen/tests/testdata/quoteinset/input
new file mode 100644
index 0000000000..5a9b6804a9
--- /dev/null
+++ b/util/lexgen/tests/testdata/quoteinset/input
@@ -0,0 +1 @@
+"a
diff --git a/util/lexgen/tests/testdata/quoteinset/output b/util/lexgen/tests/testdata/quoteinset/output
new file mode 100644
index 0000000000..7ba8890d5d
--- /dev/null
+++ b/util/lexgen/tests/testdata/quoteinset/output
@@ -0,0 +1 @@
+TOK_QUOTEA|"a
diff --git a/util/lexgen/tests/testdata/quoteinset/rules.lexgen b/util/lexgen/tests/testdata/quoteinset/rules.lexgen
new file mode 100644
index 0000000000..9838276a7e
--- /dev/null
+++ b/util/lexgen/tests/testdata/quoteinset/rules.lexgen
@@ -0,0 +1,2 @@
+[Tokens]
+TOK_QUOTEA = ["]a
diff --git a/util/lexgen/tests/testdata/quotes/input b/util/lexgen/tests/testdata/quotes/input
new file mode 100644
index 0000000000..ac5445055d
--- /dev/null
+++ b/util/lexgen/tests/testdata/quotes/input
@@ -0,0 +1 @@
+quotedstring
diff --git a/util/lexgen/tests/testdata/quotes/output b/util/lexgen/tests/testdata/quotes/output
new file mode 100644
index 0000000000..c538e32d75
--- /dev/null
+++ b/util/lexgen/tests/testdata/quotes/output
@@ -0,0 +1 @@
+TOK_STR|quotedstring
diff --git a/util/lexgen/tests/testdata/quotes/rules.lexgen b/util/lexgen/tests/testdata/quotes/rules.lexgen
new file mode 100644
index 0000000000..d528cdd589
--- /dev/null
+++ b/util/lexgen/tests/testdata/quotes/rules.lexgen
@@ -0,0 +1,2 @@
+[Tokens]
+TOK_STR = "quotedstring"
diff --git a/util/lexgen/tests/testdata/simple/input b/util/lexgen/tests/testdata/simple/input
new file mode 100644
index 0000000000..acbe86c7c8
--- /dev/null
+++ b/util/lexgen/tests/testdata/simple/input
@@ -0,0 +1 @@
+abcd
diff --git a/util/lexgen/tests/testdata/simple/output b/util/lexgen/tests/testdata/simple/output
new file mode 100644
index 0000000000..a37a58ea31
--- /dev/null
+++ b/util/lexgen/tests/testdata/simple/output
@@ -0,0 +1,2 @@
+TOK_AB|ab
+TOK_CD|cd
diff --git a/util/lexgen/tests/testdata/simple/rules.lexgen b/util/lexgen/tests/testdata/simple/rules.lexgen
new file mode 100644
index 0000000000..5d958c429a
--- /dev/null
+++ b/util/lexgen/tests/testdata/simple/rules.lexgen
@@ -0,0 +1,3 @@
+[Tokens]
+TOK_AB = ab
+TOK_CD = cd
diff --git a/util/lexgen/tests/testdata/subsets1/input b/util/lexgen/tests/testdata/subsets1/input
new file mode 100644
index 0000000000..47f66d1c94
--- /dev/null
+++ b/util/lexgen/tests/testdata/subsets1/input
@@ -0,0 +1 @@
+abaf
diff --git a/util/lexgen/tests/testdata/subsets1/output b/util/lexgen/tests/testdata/subsets1/output
new file mode 100644
index 0000000000..75dd9361bc
--- /dev/null
+++ b/util/lexgen/tests/testdata/subsets1/output
@@ -0,0 +1,2 @@
+TOK_AB|ab
+TOK_AZ|af
diff --git a/util/lexgen/tests/testdata/subsets1/rules.lexgen b/util/lexgen/tests/testdata/subsets1/rules.lexgen
new file mode 100644
index 0000000000..94f51a91e2
--- /dev/null
+++ b/util/lexgen/tests/testdata/subsets1/rules.lexgen
@@ -0,0 +1,3 @@
+[Tokens]
+TOK_AB = ab
+TOK_AZ = a[a-z]
diff --git a/util/lexgen/tests/testdata/subsets2/input b/util/lexgen/tests/testdata/subsets2/input
new file mode 100644
index 0000000000..4d0dc3ad82
--- /dev/null
+++ b/util/lexgen/tests/testdata/subsets2/input
@@ -0,0 +1 @@
+abd
diff --git a/util/lexgen/tests/testdata/subsets2/output b/util/lexgen/tests/testdata/subsets2/output
new file mode 100644
index 0000000000..d5a7bc5bb7
--- /dev/null
+++ b/util/lexgen/tests/testdata/subsets2/output
@@ -0,0 +1,3 @@
+TOK_A|a
+TOK_B|b
+TOK_D|d
diff --git a/util/lexgen/tests/testdata/subsets2/rules.lexgen b/util/lexgen/tests/testdata/subsets2/rules.lexgen
new file mode 100644
index 0000000000..e0a76294bc
--- /dev/null
+++ b/util/lexgen/tests/testdata/subsets2/rules.lexgen
@@ -0,0 +1,4 @@
+[Tokens]
+TOK_D = [abcd]
+TOK_B = [bc]
+TOK_A = a
diff --git a/util/lexgen/tests/tests.pro b/util/lexgen/tests/tests.pro
new file mode 100644
index 0000000000..eb04439a13
--- /dev/null
+++ b/util/lexgen/tests/tests.pro
@@ -0,0 +1,6 @@
+CONFIG += qtestlib
+SOURCES += tst_lexgen.cpp
+TARGET = tst_lexgen
+include(../lexgen.pri)
+QT = core
+DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/util/lexgen/tests/tst_lexgen.cpp b/util/lexgen/tests/tst_lexgen.cpp
new file mode 100644
index 0000000000..c80de646d6
--- /dev/null
+++ b/util/lexgen/tests/tst_lexgen.cpp
@@ -0,0 +1,285 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#define AUTOTEST
+#include "../main.cpp"
+
+class tst_LexGen : public QObject
+{
+ Q_OBJECT
+private slots:
+ void nfa_singleInput();
+ void nfa_alternating();
+ void nfa_concatenating();
+ void nfa_optional();
+ void nfa_toDFA_data();
+ void nfa_toDFA();
+ void lexgen_data();
+ void lexgen();
+};
+
+void tst_LexGen::nfa_singleInput()
+{
+ NFA nfa = NFA::createSingleInputNFA('a');
+
+ QCOMPARE(nfa.initialState, 0);
+ QCOMPARE(nfa.finalState, 1);
+
+ QCOMPARE(nfa.states.count(), 2);
+
+ QCOMPARE(nfa.states.at(0).transitions.count(), 1);
+ QVERIFY(nfa.states.at(0).transitions.contains('a'));
+ QCOMPARE(nfa.states.at(0).transitions.values('a').count(), 1);
+ QCOMPARE(nfa.states.at(0).transitions.value('a'), nfa.finalState);
+
+ QVERIFY(nfa.states.at(1).transitions.isEmpty());
+}
+
+void tst_LexGen::nfa_alternating()
+{
+ NFA a = NFA::createSingleInputNFA('a');
+ NFA b = NFA::createSingleInputNFA('b');
+ NFA nfa = NFA::createAlternatingNFA(a, b);
+
+ const int initialA = 1;
+ const int finalA = 2;
+
+ const int initialB = 3;
+ const int finalB = 4;
+
+ QCOMPARE(nfa.states.count(), 6);
+
+ QCOMPARE(nfa.initialState, 0);
+ QCOMPARE(nfa.finalState, 5);
+
+ QList<int> initialTransitions = nfa.states.at(0).transitions.values(Epsilon);
+ QCOMPARE(initialTransitions.count(), 2);
+ QVERIFY(initialTransitions.contains(initialA));
+ QVERIFY(initialTransitions.contains(initialB));
+
+ // no need to test the individual a and b NFAs, the other
+ // autotest already takes care of that. Just check whether
+ // the epsilon transitions to the final state exist.
+
+ QCOMPARE(nfa.states.at(finalA).transitions.count(), 1);
+ QCOMPARE(nfa.states.at(finalA).transitions.values(Epsilon).count(), 1);
+ QCOMPARE(nfa.states.at(finalA).transitions.value(Epsilon), nfa.finalState);
+
+ QCOMPARE(nfa.states.at(finalB).transitions.count(), 1);
+ QCOMPARE(nfa.states.at(finalB).transitions.values(Epsilon).count(), 1);
+ QCOMPARE(nfa.states.at(finalB).transitions.value(Epsilon), nfa.finalState);
+}
+
+void tst_LexGen::nfa_concatenating()
+{
+ NFA a = NFA::createSingleInputNFA('a');
+ NFA b = NFA::createSingleInputNFA('b');
+ NFA nfa = NFA::createConcatenatingNFA(a, b);
+
+ const int initialA = 1;
+ const int finalA = 2;
+
+ const int initialB = 3;
+ const int finalB = 4;
+
+ QCOMPARE(nfa.states.count(), 6);
+
+ QCOMPARE(nfa.initialState, 0);
+ QCOMPARE(nfa.finalState, 5);
+
+ QCOMPARE(nfa.states.at(0).transitions.count(), 1);
+ QCOMPARE(nfa.states.at(0).transitions.values(Epsilon).count(), 1);
+ QCOMPARE(nfa.states.at(0).transitions.value(Epsilon), initialA);
+
+ QCOMPARE(nfa.states.at(finalA).transitions.values(Epsilon).count(), 1);
+ QCOMPARE(nfa.states.at(finalA).transitions.value(Epsilon), initialB);
+
+ QCOMPARE(nfa.states.at(finalB).transitions.values(Epsilon).count(), 1);
+ QCOMPARE(nfa.states.at(finalB).transitions.value(Epsilon), nfa.finalState);
+}
+
+void tst_LexGen::nfa_optional()
+{
+ NFA a = NFA::createSingleInputNFA('a');
+ NFA nfa = NFA::createOptionalNFA(a);
+
+ const int initialA = 1;
+ const int finalA = 2;
+
+ QCOMPARE(nfa.states.count(), 4);
+
+ QCOMPARE(nfa.initialState, 0);
+ QCOMPARE(nfa.finalState, 3);
+
+ QCOMPARE(nfa.states.at(0).transitions.count(), 2);
+ QList<int> initialTransitions = nfa.states.at(0).transitions.values(Epsilon);
+ QVERIFY(initialTransitions.contains(nfa.finalState));
+ QVERIFY(initialTransitions.contains(initialA));
+
+ QList<int> finalEpsilonATransitions = nfa.states.at(finalA).transitions.values(Epsilon);
+ QVERIFY(finalEpsilonATransitions.contains(initialA));
+ QVERIFY(finalEpsilonATransitions.contains(nfa.finalState));
+}
+
+Q_DECLARE_METATYPE(NFA);
+Q_DECLARE_METATYPE(DFA);
+
+void tst_LexGen::nfa_toDFA_data()
+{
+ QTest::addColumn<NFA>("nfa");
+ QTest::addColumn<DFA>("expectedDFA");
+
+ NFA a = NFA::createSingleInputNFA('a');
+ NFA b = NFA::createSingleInputNFA('b');
+ NFA c = NFA::createSingleInputNFA('c');
+
+ NFA nfa;
+ DFA dfa;
+
+ dfa.clear();
+ dfa.resize(3);
+ dfa[0].transitions.insert('a', 1);
+ dfa[1].transitions.insert('b', 2);
+
+ nfa = NFA::createConcatenatingNFA(a, b);
+
+ QTest::newRow("simple concat") << nfa << dfa;
+
+ dfa.clear();
+ dfa.resize(3);
+ dfa[0].transitions.insert('a', 1);
+ dfa[0].transitions.insert('b', 2);
+
+ nfa = NFA::createAlternatingNFA(a, b);
+
+ QTest::newRow("simple alternate") << nfa << dfa;
+
+}
+
+void tst_LexGen::nfa_toDFA()
+{
+ QFETCH(NFA, nfa);
+ QFETCH(DFA, expectedDFA);
+
+ DFA dfa = nfa.toDFA();
+
+ QCOMPARE(dfa.count(), expectedDFA.count());
+ for (int i = 0; i < dfa.count(); ++i) {
+ if (dfa.at(i).transitions != expectedDFA.at(i).transitions) {
+ qDebug() << "DFAs differ in state" << i;
+ qDebug() << "NFA:";
+ nfa.debug();
+ qDebug() << "Actual DFA:";
+ dfa.debug();
+ qDebug() << "Expected DFA:";
+ expectedDFA.debug();
+ QVERIFY(false);
+ }
+ }
+}
+
+void tst_LexGen::lexgen_data()
+{
+ QTest::addColumn<QString>("ruleFile");
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("expectedOutput");
+
+ QDir d(QString(SRCDIR));
+ d.cd("testdata");
+ foreach (QString test, d.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
+ QString dir = d.absoluteFilePath(test) + '/';
+ QTest::newRow(qPrintable(test))
+ << dir + "rules.lexgen"
+ << dir + "input"
+ << dir + "output"
+ ;
+ }
+}
+
+void tst_LexGen::lexgen()
+{
+ QFETCH(QString, ruleFile);
+ QFETCH(QString, input);
+ QFETCH(QString, expectedOutput);
+
+ Config conf;
+ QVERIFY(loadConfig(ruleFile, &conf));
+ DFA dfa = generateMachine(conf);
+ QVERIFY(!dfa.isEmpty());
+ conf.debug = true;
+
+ QFile f(input);
+ QVERIFY(f.open(QIODevice::ReadOnly));
+ input = QString::fromUtf8(f.readAll());
+ f.close();
+ if (input.endsWith(QLatin1Char('\n')))
+ input.chop(1);
+// machine.debug();
+ bool ok = false;
+ QList<Symbol> symbols = tokenize(dfa, input, &conf, &ok);
+ QVERIFY(ok);
+ f.setFileName(expectedOutput);
+ QVERIFY(f.open(QIODevice::ReadOnly));
+ QStringList lines;
+ while (!f.atEnd()) {
+ QString line = QString::fromUtf8(f.readLine());
+ if (line.endsWith(QLatin1Char('\n')))
+ line.chop(1);
+ lines << line;
+ }
+ f.close();
+
+// dfa.debug();
+ QCOMPARE(lines.count(), symbols.count());
+
+ for (int i = 0; i < lines.count(); ++i) {
+ QStringList l = lines.at(i).split(QChar::fromLatin1('|'));
+ QCOMPARE(l.count(), 2);
+ QString expectedToken = l.at(0);
+ QString expectedLexem = l.at(1);
+ QCOMPARE(symbols.at(i).token, expectedToken);
+ QCOMPARE(symbols.at(i).lexem, expectedLexem);
+ }
+}
+
+QTEST_MAIN(tst_LexGen)
+#include "tst_lexgen.moc"
diff --git a/util/lexgen/tokenizer.cpp b/util/lexgen/tokenizer.cpp
new file mode 100644
index 0000000000..39fc7ca1ef
--- /dev/null
+++ b/util/lexgen/tokenizer.cpp
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+// auto generated. DO NOT EDIT.
+class RegExpTokenizer
+{
+public:
+ RegExpTokenizer(const QString &inp);
+
+ inline QChar next() {
+ return (pos < input.length()) ? input.at(pos++) : QChar();
+ }
+ int lex();
+
+ QString input;
+ int pos;
+ int lexemStart;
+ int lexemLength;
+};
+
+RegExpTokenizer::RegExpTokenizer(const QString &inp)
+{
+ input = inp;
+ pos = 0;
+ lexemStart = 0;
+ lexemLength = 0;
+}
+
+
+int RegExpTokenizer::lex()
+{
+ lexemStart = pos;
+ lexemLength = 0;
+ int lastAcceptingPos = -1;
+ int token = -1;
+ QChar ch;
+
+ // initial state
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 33)
+ goto state_1;
+ if (ch.unicode() == 34)
+ goto state_2;
+ if (ch.unicode() >= 35 && ch.unicode() <= 39)
+ goto state_1;
+ if (ch.unicode() == 40) {
+ token = RE2NFA::TOK_LPAREN;
+ goto found;
+ }
+ if (ch.unicode() == 41) {
+ token = RE2NFA::TOK_RPAREN;
+ goto found;
+ }
+ if (ch.unicode() == 42) {
+ token = RE2NFA::TOK_STAR;
+ goto found;
+ }
+ if (ch.unicode() == 43) {
+ token = RE2NFA::TOK_PLUS;
+ goto found;
+ }
+ if (ch.unicode() == 44) {
+ token = RE2NFA::TOK_COMMA;
+ goto found;
+ }
+ if (ch.unicode() == 45)
+ goto state_1;
+ if (ch.unicode() == 46) {
+ token = RE2NFA::TOK_DOT;
+ goto found;
+ }
+ if (ch.unicode() >= 47 && ch.unicode() <= 62)
+ goto state_1;
+ if (ch.unicode() == 63) {
+ token = RE2NFA::TOK_QUESTION;
+ goto found;
+ }
+ if (ch.unicode() >= 64 && ch.unicode() <= 90)
+ goto state_1;
+ if (ch.unicode() == 91)
+ goto state_10;
+ if (ch.unicode() == 92)
+ goto state_11;
+ if (ch.unicode() >= 93 && ch.unicode() <= 122)
+ goto state_1;
+ if (ch.unicode() == 123) {
+ token = RE2NFA::TOK_LBRACE;
+ goto found;
+ }
+ if (ch.unicode() == 124) {
+ token = RE2NFA::TOK_OR;
+ goto found;
+ }
+ if (ch.unicode() == 125) {
+ token = RE2NFA::TOK_RBRACE;
+ goto found;
+ }
+ if (ch.unicode() >= 126)
+ goto state_1;
+ goto out;
+ state_1:
+ lastAcceptingPos = pos;
+ token = RE2NFA::TOK_STRING;
+ goto out;
+ state_2:
+ lastAcceptingPos = pos;
+ token = RE2NFA::TOK_STRING;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 33)
+ goto state_15;
+ if (ch.unicode() == 34)
+ goto state_16;
+ if (ch.unicode() >= 35)
+ goto state_15;
+ goto out;
+ state_10:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 91)
+ goto state_17;
+ if (ch.unicode() == 92)
+ goto state_18;
+ if (ch.unicode() == 93)
+ goto state_19;
+ if (ch.unicode() >= 94)
+ goto state_17;
+ goto out;
+ state_11:
+ lastAcceptingPos = pos;
+ token = RE2NFA::TOK_STRING;
+ ch = next();
+ if (ch.unicode() >= 1)
+ goto state_20;
+ goto out;
+ state_15:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 33)
+ goto state_15;
+ if (ch.unicode() == 34)
+ goto state_16;
+ if (ch.unicode() >= 35)
+ goto state_15;
+ goto out;
+ state_16:
+ lastAcceptingPos = pos;
+ token = RE2NFA::TOK_QUOTED_STRING;
+ goto out;
+ state_17:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 91)
+ goto state_17;
+ if (ch.unicode() == 92)
+ goto state_18;
+ if (ch.unicode() == 93)
+ goto state_19;
+ if (ch.unicode() >= 94)
+ goto state_17;
+ goto out;
+ state_18:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 91)
+ goto state_17;
+ if (ch.unicode() == 92)
+ goto state_18;
+ if (ch.unicode() == 93)
+ goto state_21;
+ if (ch.unicode() >= 94)
+ goto state_17;
+ goto out;
+ state_19:
+ lastAcceptingPos = pos;
+ token = RE2NFA::TOK_SEQUENCE;
+ goto out;
+ state_20:
+ lastAcceptingPos = pos;
+ token = RE2NFA::TOK_STRING;
+ goto out;
+ state_21:
+ lastAcceptingPos = pos;
+ token = RE2NFA::TOK_SEQUENCE;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 91)
+ goto state_17;
+ if (ch.unicode() == 92)
+ goto state_18;
+ if (ch.unicode() == 93)
+ goto state_19;
+ if (ch.unicode() >= 94)
+ goto state_17;
+ goto out;
+ found:
+ lastAcceptingPos = pos;
+
+ out:
+ if (lastAcceptingPos != -1) {
+ lexemLength = lastAcceptingPos - lexemStart;
+ pos = lastAcceptingPos;
+ }
+ return token;
+}
+
diff --git a/util/local_database/README b/util/local_database/README
new file mode 100644
index 0000000000..23b6a33ad8
--- /dev/null
+++ b/util/local_database/README
@@ -0,0 +1 @@
+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/cldr2qlocalexml.py b/util/local_database/cldr2qlocalexml.py
new file mode 100755
index 0000000000..f0f9cb1ead
--- /dev/null
+++ b/util/local_database/cldr2qlocalexml.py
@@ -0,0 +1,810 @@
+#!/usr/bin/env python
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## No Commercial Usage
+## This file contains pre-release code and may not be distributed.
+## You may use this file in accordance with the terms and conditions
+## contained in the Technology Preview License Agreement accompanying
+## this package.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Nokia gives you certain additional
+## rights. These rights are described in the Nokia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import os
+import sys
+import enumdata
+import xpathlite
+from xpathlite import DraftResolution
+from dateconverter import convert_date
+import re
+
+findEntry = xpathlite.findEntry
+findEntryInFile = xpathlite._findEntryInFile
+findTagsInFile = xpathlite.findTagsInFile
+
+def parse_number_format(patterns, data):
+ # this is a very limited parsing of the number format for currency only.
+ def skip_repeating_pattern(x):
+ p = x.replace('0', '#').replace(',', '').replace('.', '')
+ seen = False
+ result = ''
+ for c in p:
+ if c == '#':
+ if seen:
+ continue
+ seen = True
+ else:
+ seen = False
+ result = result + c
+ return result
+ patterns = patterns.split(';')
+ result = []
+ for pattern in patterns:
+ pattern = skip_repeating_pattern(pattern)
+ pattern = pattern.replace('#', "%1")
+ # according to http://www.unicode.org/reports/tr35/#Number_Format_Patterns
+ # there can be doubled or trippled currency sign, however none of the
+ # locales use that.
+ pattern = pattern.replace(u'\xa4', "%2")
+ pattern = pattern.replace("''", "###").replace("'", '').replace("###", "'")
+ pattern = pattern.replace('-', data['minus'])
+ pattern = pattern.replace('+', data['plus'])
+ result.append(pattern)
+ return result
+
+def parse_list_pattern_part_format(pattern):
+ # this is a very limited parsing of the format for list pattern part only.
+ result = ""
+ result = pattern.replace("{0}", "%1")
+ result = result.replace("{1}", "%2")
+ result = result.replace("{2}", "%3")
+ return result
+
+def ordStr(c):
+ if len(c) == 1:
+ return str(ord(c))
+ return "##########"
+
+# the following functions are supposed to fix the problem with QLocale
+# returning a character instead of strings for QLocale::exponential()
+# and others. So we fallback to default values in these cases.
+def fixOrdStrExp(c):
+ if len(c) == 1:
+ return str(ord(c))
+ return str(ord('e'))
+def fixOrdStrPercent(c):
+ if len(c) == 1:
+ return str(ord(c))
+ return str(ord('%'))
+def fixOrdStrList(c):
+ if len(c) == 1:
+ return str(ord(c))
+ return str(ord(';'))
+
+def generateLocaleInfo(path):
+ (dir_name, file_name) = os.path.split(path)
+
+ if not path.endswith(".xml"):
+ return {}
+ language_code = findEntryInFile(path, "identity/language", attribute="type")[0]
+ if language_code == 'root':
+ # just skip it
+ return {}
+ country_code = findEntryInFile(path, "identity/territory", attribute="type")[0]
+ script_code = findEntryInFile(path, "identity/script", attribute="type")[0]
+ variant_code = findEntryInFile(path, "identity/variant", attribute="type")[0]
+
+ # we should handle fully qualified names with the territory
+ if not country_code:
+ return {}
+
+ # we do not support variants
+ # ### actually there is only one locale with variant: en_US_POSIX
+ # does anybody care about it at all?
+ if variant_code:
+ return {}
+
+ language_id = enumdata.languageCodeToId(language_code)
+ if language_id == -1:
+ sys.stderr.write("unnknown language code \"" + language_code + "\"\n")
+ return {}
+ language = enumdata.language_list[language_id][0]
+
+ script_id = enumdata.scriptCodeToId(script_code)
+ if script_code == -1:
+ sys.stderr.write("unnknown script code \"" + script_code + "\"\n")
+ return {}
+ script = "AnyScript"
+ if script_id != -1:
+ script = enumdata.script_list[script_id][0]
+
+ country_id = enumdata.countryCodeToId(country_code)
+ country = ""
+ if country_id != -1:
+ country = enumdata.country_list[country_id][0]
+ if country == "":
+ sys.stderr.write("unnknown country code \"" + country_code + "\"\n")
+ return {}
+
+ # So we say we accept only those values that have "contributed" or
+ # "approved" resolution. see http://www.unicode.org/cldr/process.html
+ # But we only respect the resolution for new datas for backward
+ # compatibility.
+ draft = DraftResolution.contributed
+
+ result = {}
+ result['language'] = language
+ result['script'] = script
+ result['country'] = country
+ result['language_code'] = language_code
+ result['country_code'] = country_code
+ result['script_code'] = script_code
+ result['variant_code'] = variant_code
+ result['language_id'] = language_id
+ result['script_id'] = script_id
+ result['country_id'] = country_id
+
+ supplementalPath = dir_name + "/../supplemental/supplementalData.xml"
+ currencies = findTagsInFile(supplementalPath, "currencyData/region[iso3166=%s]"%country_code);
+ result['currencyIsoCode'] = ''
+ result['currencyDigits'] = 2
+ result['currencyRounding'] = 1
+ if currencies:
+ for e in currencies:
+ if e[0] == 'currency':
+ tender = True
+ t = filter(lambda x: x[0] == 'tender', e[1])
+ if t and t[0][1] == 'false':
+ tender = False;
+ if tender and not filter(lambda x: x[0] == 'to', e[1]):
+ result['currencyIsoCode'] = filter(lambda x: x[0] == 'iso4217', e[1])[0][1]
+ break
+ if result['currencyIsoCode']:
+ t = findTagsInFile(supplementalPath, "currencyData/fractions/info[iso4217=%s]"%result['currencyIsoCode']);
+ if t and t[0][0] == 'info':
+ result['currencyDigits'] = int(filter(lambda x: x[0] == 'digits', t[0][1])[0][1])
+ result['currencyRounding'] = int(filter(lambda x: x[0] == 'rounding', t[0][1])[0][1])
+ numbering_system = None
+ try:
+ numbering_system = findEntry(path, "numbers/defaultNumberingSystem")
+ except:
+ pass
+ def findEntryDef(path, xpath, value=''):
+ try:
+ return findEntry(path, xpath)
+ except xpathlite.Error:
+ return value
+ def get_number_in_system(path, xpath, numbering_system):
+ if numbering_system:
+ try:
+ return findEntry(path, xpath + "[numberSystem=" + numbering_system + "]")
+ except xpathlite.Error:
+ pass
+ return findEntry(path, xpath)
+ result['decimal'] = get_number_in_system(path, "numbers/symbols/decimal", numbering_system)
+ result['group'] = get_number_in_system(path, "numbers/symbols/group", numbering_system)
+ result['list'] = get_number_in_system(path, "numbers/symbols/list", numbering_system)
+ result['percent'] = get_number_in_system(path, "numbers/symbols/percentSign", numbering_system)
+ result['zero'] = get_number_in_system(path, "numbers/symbols/nativeZeroDigit", numbering_system)
+ result['minus'] = get_number_in_system(path, "numbers/symbols/minusSign", numbering_system)
+ result['plus'] = get_number_in_system(path, "numbers/symbols/plusSign", numbering_system)
+ result['exp'] = get_number_in_system(path, "numbers/symbols/exponential", numbering_system).lower()
+ result['quotationStart'] = findEntry(path, "delimiters/quotationStart")
+ result['quotationEnd'] = findEntry(path, "delimiters/quotationEnd")
+ result['alternateQuotationStart'] = findEntry(path, "delimiters/alternateQuotationStart")
+ result['alternateQuotationEnd'] = findEntry(path, "delimiters/alternateQuotationEnd")
+ result['listPatternPartStart'] = parse_list_pattern_part_format(findEntry(path, "listPatterns/listPattern/listPatternPart[start]"))
+ result['listPatternPartMiddle'] = parse_list_pattern_part_format(findEntry(path, "listPatterns/listPattern/listPatternPart[middle]"))
+ result['listPatternPartEnd'] = parse_list_pattern_part_format(findEntry(path, "listPatterns/listPattern/listPatternPart[end]"))
+ result['listPatternPartTwo'] = parse_list_pattern_part_format(findEntry(path, "listPatterns/listPattern/listPatternPart[2]"))
+ result['am'] = findEntry(path, "dates/calendars/calendar[gregorian]/dayPeriods/dayPeriodContext[format]/dayPeriodWidth[wide]/dayPeriod[am]", draft)
+ result['pm'] = findEntry(path, "dates/calendars/calendar[gregorian]/dayPeriods/dayPeriodContext[format]/dayPeriodWidth[wide]/dayPeriod[pm]", draft)
+ result['longDateFormat'] = convert_date(findEntry(path, "dates/calendars/calendar[gregorian]/dateFormats/dateFormatLength[full]/dateFormat/pattern"))
+ result['shortDateFormat'] = convert_date(findEntry(path, "dates/calendars/calendar[gregorian]/dateFormats/dateFormatLength[short]/dateFormat/pattern"))
+ result['longTimeFormat'] = convert_date(findEntry(path, "dates/calendars/calendar[gregorian]/timeFormats/timeFormatLength[full]/timeFormat/pattern"))
+ result['shortTimeFormat'] = convert_date(findEntry(path, "dates/calendars/calendar[gregorian]/timeFormats/timeFormatLength[short]/timeFormat/pattern"))
+
+ endonym = None
+ if country_code and script_code:
+ endonym = findEntryDef(path, "localeDisplayNames/languages/language[type=%s_%s_%s]" % (language_code, script_code, country_code))
+ if not endonym and script_code:
+ endonym = findEntryDef(path, "localeDisplayNames/languages/language[type=%s_%s]" % (language_code, script_code))
+ if not endonym and country_code:
+ endonym = findEntryDef(path, "localeDisplayNames/languages/language[type=%s_%s]" % (language_code, country_code))
+ if not endonym:
+ endonym = findEntryDef(path, "localeDisplayNames/languages/language[type=%s]" % (language_code))
+ result['language_endonym'] = endonym
+ result['country_endonym'] = findEntryDef(path, "localeDisplayNames/territories/territory[type=%s]" % (country_code))
+
+ currency_format = get_number_in_system(path, "numbers/currencyFormats/currencyFormatLength/currencyFormat/pattern", numbering_system)
+ currency_format = parse_number_format(currency_format, result)
+ result['currencyFormat'] = currency_format[0]
+ result['currencyNegativeFormat'] = ''
+ if len(currency_format) > 1:
+ result['currencyNegativeFormat'] = currency_format[1]
+
+ result['currencySymbol'] = ''
+ result['currencyDisplayName'] = ''
+ if result['currencyIsoCode']:
+ result['currencySymbol'] = findEntryDef(path, "numbers/currencies/currency[%s]/symbol" % result['currencyIsoCode'])
+ display_name_path = "numbers/currencies/currency[%s]/displayName" % result['currencyIsoCode']
+ result['currencyDisplayName'] \
+ = findEntryDef(path, display_name_path) + ";" \
+ + findEntryDef(path, display_name_path + "[count=zero]") + ";" \
+ + findEntryDef(path, display_name_path + "[count=one]") + ";" \
+ + findEntryDef(path, display_name_path + "[count=two]") + ";" \
+ + findEntryDef(path, display_name_path + "[count=few]") + ";" \
+ + findEntryDef(path, display_name_path + "[count=many]") + ";" \
+ + findEntryDef(path, display_name_path + "[count=other]") + ";"
+
+ standalone_long_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[stand-alone]/monthWidth[wide]/month"
+ result['standaloneLongMonths'] \
+ = findEntry(path, standalone_long_month_path + "[1]") + ";" \
+ + findEntry(path, standalone_long_month_path + "[2]") + ";" \
+ + findEntry(path, standalone_long_month_path + "[3]") + ";" \
+ + findEntry(path, standalone_long_month_path + "[4]") + ";" \
+ + findEntry(path, standalone_long_month_path + "[5]") + ";" \
+ + findEntry(path, standalone_long_month_path + "[6]") + ";" \
+ + findEntry(path, standalone_long_month_path + "[7]") + ";" \
+ + findEntry(path, standalone_long_month_path + "[8]") + ";" \
+ + findEntry(path, standalone_long_month_path + "[9]") + ";" \
+ + findEntry(path, standalone_long_month_path + "[10]") + ";" \
+ + findEntry(path, standalone_long_month_path + "[11]") + ";" \
+ + findEntry(path, standalone_long_month_path + "[12]") + ";"
+
+ standalone_short_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[stand-alone]/monthWidth[abbreviated]/month"
+ result['standaloneShortMonths'] \
+ = findEntry(path, standalone_short_month_path + "[1]") + ";" \
+ + findEntry(path, standalone_short_month_path + "[2]") + ";" \
+ + findEntry(path, standalone_short_month_path + "[3]") + ";" \
+ + findEntry(path, standalone_short_month_path + "[4]") + ";" \
+ + findEntry(path, standalone_short_month_path + "[5]") + ";" \
+ + findEntry(path, standalone_short_month_path + "[6]") + ";" \
+ + findEntry(path, standalone_short_month_path + "[7]") + ";" \
+ + findEntry(path, standalone_short_month_path + "[8]") + ";" \
+ + findEntry(path, standalone_short_month_path + "[9]") + ";" \
+ + findEntry(path, standalone_short_month_path + "[10]") + ";" \
+ + findEntry(path, standalone_short_month_path + "[11]") + ";" \
+ + findEntry(path, standalone_short_month_path + "[12]") + ";"
+
+ standalone_narrow_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[stand-alone]/monthWidth[narrow]/month"
+ result['standaloneNarrowMonths'] \
+ = findEntry(path, standalone_narrow_month_path + "[1]") + ";" \
+ + findEntry(path, standalone_narrow_month_path + "[2]") + ";" \
+ + findEntry(path, standalone_narrow_month_path + "[3]") + ";" \
+ + findEntry(path, standalone_narrow_month_path + "[4]") + ";" \
+ + findEntry(path, standalone_narrow_month_path + "[5]") + ";" \
+ + findEntry(path, standalone_narrow_month_path + "[6]") + ";" \
+ + findEntry(path, standalone_narrow_month_path + "[7]") + ";" \
+ + findEntry(path, standalone_narrow_month_path + "[8]") + ";" \
+ + findEntry(path, standalone_narrow_month_path + "[9]") + ";" \
+ + findEntry(path, standalone_narrow_month_path + "[10]") + ";" \
+ + findEntry(path, standalone_narrow_month_path + "[11]") + ";" \
+ + findEntry(path, standalone_narrow_month_path + "[12]") + ";"
+
+ long_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[format]/monthWidth[wide]/month"
+ result['longMonths'] \
+ = findEntry(path, long_month_path + "[1]") + ";" \
+ + findEntry(path, long_month_path + "[2]") + ";" \
+ + findEntry(path, long_month_path + "[3]") + ";" \
+ + findEntry(path, long_month_path + "[4]") + ";" \
+ + findEntry(path, long_month_path + "[5]") + ";" \
+ + findEntry(path, long_month_path + "[6]") + ";" \
+ + findEntry(path, long_month_path + "[7]") + ";" \
+ + findEntry(path, long_month_path + "[8]") + ";" \
+ + findEntry(path, long_month_path + "[9]") + ";" \
+ + findEntry(path, long_month_path + "[10]") + ";" \
+ + findEntry(path, long_month_path + "[11]") + ";" \
+ + findEntry(path, long_month_path + "[12]") + ";"
+
+ short_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[format]/monthWidth[abbreviated]/month"
+ result['shortMonths'] \
+ = findEntry(path, short_month_path + "[1]") + ";" \
+ + findEntry(path, short_month_path + "[2]") + ";" \
+ + findEntry(path, short_month_path + "[3]") + ";" \
+ + findEntry(path, short_month_path + "[4]") + ";" \
+ + findEntry(path, short_month_path + "[5]") + ";" \
+ + findEntry(path, short_month_path + "[6]") + ";" \
+ + findEntry(path, short_month_path + "[7]") + ";" \
+ + findEntry(path, short_month_path + "[8]") + ";" \
+ + findEntry(path, short_month_path + "[9]") + ";" \
+ + findEntry(path, short_month_path + "[10]") + ";" \
+ + findEntry(path, short_month_path + "[11]") + ";" \
+ + findEntry(path, short_month_path + "[12]") + ";"
+
+ narrow_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[format]/monthWidth[narrow]/month"
+ result['narrowMonths'] \
+ = findEntry(path, narrow_month_path + "[1]") + ";" \
+ + findEntry(path, narrow_month_path + "[2]") + ";" \
+ + findEntry(path, narrow_month_path + "[3]") + ";" \
+ + findEntry(path, narrow_month_path + "[4]") + ";" \
+ + findEntry(path, narrow_month_path + "[5]") + ";" \
+ + findEntry(path, narrow_month_path + "[6]") + ";" \
+ + findEntry(path, narrow_month_path + "[7]") + ";" \
+ + findEntry(path, narrow_month_path + "[8]") + ";" \
+ + findEntry(path, narrow_month_path + "[9]") + ";" \
+ + findEntry(path, narrow_month_path + "[10]") + ";" \
+ + findEntry(path, narrow_month_path + "[11]") + ";" \
+ + findEntry(path, narrow_month_path + "[12]") + ";"
+
+ long_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[format]/dayWidth[wide]/day"
+ result['longDays'] \
+ = findEntry(path, long_day_path + "[sun]") + ";" \
+ + findEntry(path, long_day_path + "[mon]") + ";" \
+ + findEntry(path, long_day_path + "[tue]") + ";" \
+ + findEntry(path, long_day_path + "[wed]") + ";" \
+ + findEntry(path, long_day_path + "[thu]") + ";" \
+ + findEntry(path, long_day_path + "[fri]") + ";" \
+ + findEntry(path, long_day_path + "[sat]") + ";"
+
+ short_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[format]/dayWidth[abbreviated]/day"
+ result['shortDays'] \
+ = findEntry(path, short_day_path + "[sun]") + ";" \
+ + findEntry(path, short_day_path + "[mon]") + ";" \
+ + findEntry(path, short_day_path + "[tue]") + ";" \
+ + findEntry(path, short_day_path + "[wed]") + ";" \
+ + findEntry(path, short_day_path + "[thu]") + ";" \
+ + findEntry(path, short_day_path + "[fri]") + ";" \
+ + findEntry(path, short_day_path + "[sat]") + ";"
+
+ narrow_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[format]/dayWidth[narrow]/day"
+ result['narrowDays'] \
+ = findEntry(path, narrow_day_path + "[sun]") + ";" \
+ + findEntry(path, narrow_day_path + "[mon]") + ";" \
+ + findEntry(path, narrow_day_path + "[tue]") + ";" \
+ + findEntry(path, narrow_day_path + "[wed]") + ";" \
+ + findEntry(path, narrow_day_path + "[thu]") + ";" \
+ + findEntry(path, narrow_day_path + "[fri]") + ";" \
+ + findEntry(path, narrow_day_path + "[sat]") + ";"
+
+ standalone_long_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[stand-alone]/dayWidth[wide]/day"
+ result['standaloneLongDays'] \
+ = findEntry(path, standalone_long_day_path + "[sun]") + ";" \
+ + findEntry(path, standalone_long_day_path + "[mon]") + ";" \
+ + findEntry(path, standalone_long_day_path + "[tue]") + ";" \
+ + findEntry(path, standalone_long_day_path + "[wed]") + ";" \
+ + findEntry(path, standalone_long_day_path + "[thu]") + ";" \
+ + findEntry(path, standalone_long_day_path + "[fri]") + ";" \
+ + findEntry(path, standalone_long_day_path + "[sat]") + ";"
+
+ standalone_short_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[stand-alone]/dayWidth[abbreviated]/day"
+ result['standaloneShortDays'] \
+ = findEntry(path, standalone_short_day_path + "[sun]") + ";" \
+ + findEntry(path, standalone_short_day_path + "[mon]") + ";" \
+ + findEntry(path, standalone_short_day_path + "[tue]") + ";" \
+ + findEntry(path, standalone_short_day_path + "[wed]") + ";" \
+ + findEntry(path, standalone_short_day_path + "[thu]") + ";" \
+ + findEntry(path, standalone_short_day_path + "[fri]") + ";" \
+ + findEntry(path, standalone_short_day_path + "[sat]") + ";"
+
+ standalone_narrow_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[stand-alone]/dayWidth[narrow]/day"
+ result['standaloneNarrowDays'] \
+ = findEntry(path, standalone_narrow_day_path + "[sun]") + ";" \
+ + findEntry(path, standalone_narrow_day_path + "[mon]") + ";" \
+ + findEntry(path, standalone_narrow_day_path + "[tue]") + ";" \
+ + findEntry(path, standalone_narrow_day_path + "[wed]") + ";" \
+ + findEntry(path, standalone_narrow_day_path + "[thu]") + ";" \
+ + findEntry(path, standalone_narrow_day_path + "[fri]") + ";" \
+ + findEntry(path, standalone_narrow_day_path + "[sat]") + ";"
+
+ return result
+
+def addEscapes(s):
+ result = ''
+ for c in s:
+ n = ord(c)
+ if n < 128:
+ result += c
+ else:
+ result += "\\x"
+ result += "%02x" % (n)
+ return result
+
+def unicodeStr(s):
+ utf8 = s.encode('utf-8')
+ return "<size>" + str(len(utf8)) + "</size><data>" + addEscapes(utf8) + "</data>"
+
+def usage():
+ print "Usage: cldr2qlocalexml.py <path-to-cldr-main>"
+ sys.exit()
+
+def integrateWeekData(filePath):
+ if not filePath.endswith(".xml"):
+ return {}
+ monFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=mon]", attribute="territories")[0].split(" ")
+ tueFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=tue]", attribute="territories")[0].split(" ")
+ wedFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=wed]", attribute="territories")[0].split(" ")
+ thuFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=thu]", attribute="territories")[0].split(" ")
+ friFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=fri]", attribute="territories")[0].split(" ")
+ satFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=sat]", attribute="territories")[0].split(" ")
+ sunFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=sun]", attribute="territories")[0].split(" ")
+
+ monWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=mon]", attribute="territories")[0].split(" ")
+ tueWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=tue]", attribute="territories")[0].split(" ")
+ wedWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=wed]", attribute="territories")[0].split(" ")
+ thuWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=thu]", attribute="territories")[0].split(" ")
+ friWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=fri]", attribute="territories")[0].split(" ")
+ satWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=sat]", attribute="territories")[0].split(" ")
+ sunWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=sun]", attribute="territories")[0].split(" ")
+
+ monWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=mon]", attribute="territories")[0].split(" ")
+ tueWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=tue]", attribute="territories")[0].split(" ")
+ wedWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=wed]", attribute="territories")[0].split(" ")
+ thuWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=thu]", attribute="territories")[0].split(" ")
+ friWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=fri]", attribute="territories")[0].split(" ")
+ satWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=sat]", attribute="territories")[0].split(" ")
+ sunWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=sun]", attribute="territories")[0].split(" ")
+
+ firstDayByCountryCode = {}
+ for countryCode in monFirstDayIn:
+ firstDayByCountryCode[countryCode] = "mon"
+ for countryCode in tueFirstDayIn:
+ firstDayByCountryCode[countryCode] = "tue"
+ for countryCode in wedFirstDayIn:
+ firstDayByCountryCode[countryCode] = "wed"
+ for countryCode in thuFirstDayIn:
+ firstDayByCountryCode[countryCode] = "thu"
+ for countryCode in friFirstDayIn:
+ firstDayByCountryCode[countryCode] = "fri"
+ for countryCode in satFirstDayIn:
+ firstDayByCountryCode[countryCode] = "sat"
+ for countryCode in sunFirstDayIn:
+ firstDayByCountryCode[countryCode] = "sun"
+
+ weekendStartByCountryCode = {}
+ for countryCode in monWeekendStart:
+ weekendStartByCountryCode[countryCode] = "mon"
+ for countryCode in tueWeekendStart:
+ weekendStartByCountryCode[countryCode] = "tue"
+ for countryCode in wedWeekendStart:
+ weekendStartByCountryCode[countryCode] = "wed"
+ for countryCode in thuWeekendStart:
+ weekendStartByCountryCode[countryCode] = "thu"
+ for countryCode in friWeekendStart:
+ weekendStartByCountryCode[countryCode] = "fri"
+ for countryCode in satWeekendStart:
+ weekendStartByCountryCode[countryCode] = "sat"
+ for countryCode in sunWeekendStart:
+ weekendStartByCountryCode[countryCode] = "sun"
+
+ weekendEndByCountryCode = {}
+ for countryCode in monWeekendEnd:
+ weekendEndByCountryCode[countryCode] = "mon"
+ for countryCode in tueWeekendEnd:
+ weekendEndByCountryCode[countryCode] = "tue"
+ for countryCode in wedWeekendEnd:
+ weekendEndByCountryCode[countryCode] = "wed"
+ for countryCode in thuWeekendEnd:
+ weekendEndByCountryCode[countryCode] = "thu"
+ for countryCode in friWeekendEnd:
+ weekendEndByCountryCode[countryCode] = "fri"
+ for countryCode in satWeekendEnd:
+ weekendEndByCountryCode[countryCode] = "sat"
+ for countryCode in sunWeekendEnd:
+ weekendEndByCountryCode[countryCode] = "sun"
+
+ for (key,locale) in locale_database.iteritems():
+ countryCode = locale['country_code']
+ if countryCode in firstDayByCountryCode:
+ locale_database[key]['firstDayOfWeek'] = firstDayByCountryCode[countryCode]
+ else:
+ locale_database[key]['firstDayOfWeek'] = firstDayByCountryCode["001"]
+
+ if countryCode in weekendStartByCountryCode:
+ locale_database[key]['weekendStart'] = weekendStartByCountryCode[countryCode]
+ else:
+ locale_database[key]['weekendStart'] = weekendStartByCountryCode["001"]
+
+ if countryCode in weekendEndByCountryCode:
+ locale_database[key]['weekendEnd'] = weekendEndByCountryCode[countryCode]
+ else:
+ locale_database[key]['weekendEnd'] = weekendEndByCountryCode["001"]
+
+if len(sys.argv) != 2:
+ usage()
+
+cldr_dir = sys.argv[1]
+
+if not os.path.isdir(cldr_dir):
+ usage()
+
+cldr_files = os.listdir(cldr_dir)
+
+locale_database = {}
+for file in cldr_files:
+ l = generateLocaleInfo(cldr_dir + "/" + file)
+ if not l:
+ sys.stderr.write("skipping file \"" + file + "\"\n")
+ continue
+
+ locale_database[(l['language_id'], l['script_id'], l['country_id'], l['variant_code'])] = l
+
+integrateWeekData(cldr_dir+"/../supplemental/supplementalData.xml")
+locale_keys = locale_database.keys()
+locale_keys.sort()
+
+cldr_version = 'unknown'
+ldml = open(cldr_dir+"/../dtd/ldml.dtd", "r")
+for line in ldml:
+ if 'version cldrVersion CDATA #FIXED' in line:
+ cldr_version = line.split('"')[1]
+
+print "<localeDatabase>"
+print " <version>" + cldr_version + "</version>"
+print " <languageList>"
+for id in enumdata.language_list:
+ l = enumdata.language_list[id]
+ print " <language>"
+ print " <name>" + l[0] + "</name>"
+ print " <id>" + str(id) + "</id>"
+ print " <code>" + l[1] + "</code>"
+ print " </language>"
+print " </languageList>"
+
+print " <scriptList>"
+for id in enumdata.script_list:
+ l = enumdata.script_list[id]
+ print " <script>"
+ print " <name>" + l[0] + "</name>"
+ print " <id>" + str(id) + "</id>"
+ print " <code>" + l[1] + "</code>"
+ print " </script>"
+print " </scriptList>"
+
+print " <countryList>"
+for id in enumdata.country_list:
+ l = enumdata.country_list[id]
+ print " <country>"
+ print " <name>" + l[0] + "</name>"
+ print " <id>" + str(id) + "</id>"
+ print " <code>" + l[1] + "</code>"
+ print " </country>"
+print " </countryList>"
+
+print \
+" <defaultCountryList>\n\
+ <defaultCountry>\n\
+ <language>Afrikaans</language>\n\
+ <country>SouthAfrica</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Afan</language>\n\
+ <country>Ethiopia</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Afar</language>\n\
+ <country>Djibouti</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Arabic</language>\n\
+ <country>SaudiArabia</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Chinese</language>\n\
+ <country>China</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Dutch</language>\n\
+ <country>Netherlands</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>English</language>\n\
+ <country>UnitedStates</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>French</language>\n\
+ <country>France</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>German</language>\n\
+ <country>Germany</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Greek</language>\n\
+ <country>Greece</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Italian</language>\n\
+ <country>Italy</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Malay</language>\n\
+ <country>Malaysia</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Portuguese</language>\n\
+ <country>Portugal</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Russian</language>\n\
+ <country>RussianFederation</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Serbian</language>\n\
+ <country>SerbiaAndMontenegro</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>SerboCroatian</language>\n\
+ <country>SerbiaAndMontenegro</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Somali</language>\n\
+ <country>Somalia</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Spanish</language>\n\
+ <country>Spain</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Swahili</language>\n\
+ <country>Kenya</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Swedish</language>\n\
+ <country>Sweden</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Tigrinya</language>\n\
+ <country>Eritrea</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Uzbek</language>\n\
+ <country>Uzbekistan</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Persian</language>\n\
+ <country>Iran</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Mongolian</language>\n\
+ <country>Mongolia</country>\n\
+ </defaultCountry>\n\
+ <defaultCountry>\n\
+ <language>Nepali</language>\n\
+ <country>Nepal</country>\n\
+ </defaultCountry>\n\
+ </defaultCountryList>"
+
+print " <localeList>"
+print \
+" <locale>\n\
+ <language>C</language>\n\
+ <languageEndonym></languageEndonym>\n\
+ <script>AnyScript</script>\n\
+ <country>AnyCountry</country>\n\
+ <countryEndonym></countryEndonym>\n\
+ <decimal>46</decimal>\n\
+ <group>44</group>\n\
+ <list>59</list>\n\
+ <percent>37</percent>\n\
+ <zero>48</zero>\n\
+ <minus>45</minus>\n\
+ <plus>43</plus>\n\
+ <exp>101</exp>\n\
+ <quotationStart>\"</quotationStart>\n\
+ <quotationEnd>\"</quotationEnd>\n\
+ <alternateQuotationStart>\'</alternateQuotationStart>\n\
+ <alternateQuotationEnd>\'</alternateQuotationEnd>\n\
+ <listPatternPartStart>%1, %2</listPatternPartStart>\n\
+ <listPatternPartMiddle>%1, %2</listPatternPartMiddle>\n\
+ <listPatternPartEnd>%1, %2</listPatternPartEnd>\n\
+ <listPatternPartTwo>%1, %2</listPatternPartTwo>\n\
+ <am>AM</am>\n\
+ <pm>PM</pm>\n\
+ <firstDayOfWeek>mon</firstDayOfWeek>\n\
+ <weekendStart>sat</weekendStart>\n\
+ <weekendEnd>sun</weekendEnd>\n\
+ <longDateFormat>EEEE, d MMMM yyyy</longDateFormat>\n\
+ <shortDateFormat>d MMM yyyy</shortDateFormat>\n\
+ <longTimeFormat>HH:mm:ss z</longTimeFormat>\n\
+ <shortTimeFormat>HH:mm:ss</shortTimeFormat>\n\
+ <standaloneLongMonths>January;February;March;April;May;June;July;August;September;October;November;December;</standaloneLongMonths>\n\
+ <standaloneShortMonths>Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec;</standaloneShortMonths>\n\
+ <standaloneNarrowMonths>J;F;M;A;M;J;J;A;S;O;N;D;</standaloneNarrowMonths>\n\
+ <longMonths>January;February;March;April;May;June;July;August;September;October;November;December;</longMonths>\n\
+ <shortMonths>Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec;</shortMonths>\n\
+ <narrowMonths>1;2;3;4;5;6;7;8;9;10;11;12;</narrowMonths>\n\
+ <longDays>Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday;</longDays>\n\
+ <shortDays>Sun;Mon;Tue;Wed;Thu;Fri;Sat;</shortDays>\n\
+ <narrowDays>7;1;2;3;4;5;6;</narrowDays>\n\
+ <standaloneLongDays>Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday;</standaloneLongDays>\n\
+ <standaloneShortDays>Sun;Mon;Tue;Wed;Thu;Fri;Sat;</standaloneShortDays>\n\
+ <standaloneNarrowDays>S;M;T;W;T;F;S;</standaloneNarrowDays>\n\
+ <currencyIsoCode></currencyIsoCode>\n\
+ <currencySymbol></currencySymbol>\n\
+ <currencyDisplayName>;;;;;;;</currencyDisplayName>\n\
+ <currencyDigits>2</currencyDigits>\n\
+ <currencyRounding>1</currencyRounding>\n\
+ <currencyFormat>%1%2</currencyFormat>\n\
+ <currencyNegativeFormat></currencyNegativeFormat>\n\
+ </locale>"
+
+for key in locale_keys:
+ l = locale_database[key]
+
+ print " <locale>"
+ print " <language>" + l['language'] + "</language>"
+ print " <languageEndonym>" + l['language_endonym'].encode('utf-8') + "</languageEndonym>"
+ print " <script>" + l['script'] + "</script>"
+ print " <country>" + l['country'] + "</country>"
+ print " <countryEndonym>" + l['country_endonym'].encode('utf-8') + "</countryEndonym>"
+ print " <languagecode>" + l['language_code'] + "</languagecode>"
+ print " <scriptcode>" + l['script_code'] + "</scriptcode>"
+ print " <countrycode>" + l['country_code'] + "</countrycode>"
+ print " <decimal>" + ordStr(l['decimal']) + "</decimal>"
+ print " <group>" + ordStr(l['group']) + "</group>"
+ print " <list>" + fixOrdStrList(l['list']) + "</list>"
+ print " <percent>" + fixOrdStrPercent(l['percent']) + "</percent>"
+ print " <zero>" + ordStr(l['zero']) + "</zero>"
+ print " <minus>" + ordStr(l['minus']) + "</minus>"
+ print " <plus>" + ordStr(l['plus']) + "</plus>"
+ print " <exp>" + fixOrdStrExp(l['exp']) + "</exp>"
+ print " <quotationStart>" + l['quotationStart'].encode('utf-8') + "</quotationStart>"
+ print " <quotationEnd>" + l['quotationEnd'].encode('utf-8') + "</quotationEnd>"
+ print " <alternateQuotationStart>" + l['alternateQuotationStart'].encode('utf-8') + "</alternateQuotationStart>"
+ print " <alternateQuotationEnd>" + l['alternateQuotationEnd'].encode('utf-8') + "</alternateQuotationEnd>"
+ print " <listPatternPartStart>" + l['listPatternPartStart'].encode('utf-8') + "</listPatternPartStart>"
+ print " <listPatternPartMiddle>" + l['listPatternPartMiddle'].encode('utf-8') + "</listPatternPartMiddle>"
+ print " <listPatternPartEnd>" + l['listPatternPartEnd'].encode('utf-8') + "</listPatternPartEnd>"
+ print " <listPatternPartTwo>" + l['listPatternPartTwo'].encode('utf-8') + "</listPatternPartTwo>"
+ print " <am>" + l['am'].encode('utf-8') + "</am>"
+ print " <pm>" + l['pm'].encode('utf-8') + "</pm>"
+ print " <firstDayOfWeek>" + l['firstDayOfWeek'].encode('utf-8') + "</firstDayOfWeek>"
+ print " <weekendStart>" + l['weekendStart'].encode('utf-8') + "</weekendStart>"
+ print " <weekendEnd>" + l['weekendEnd'].encode('utf-8') + "</weekendEnd>"
+ print " <longDateFormat>" + l['longDateFormat'].encode('utf-8') + "</longDateFormat>"
+ print " <shortDateFormat>" + l['shortDateFormat'].encode('utf-8') + "</shortDateFormat>"
+ print " <longTimeFormat>" + l['longTimeFormat'].encode('utf-8') + "</longTimeFormat>"
+ print " <shortTimeFormat>" + l['shortTimeFormat'].encode('utf-8') + "</shortTimeFormat>"
+ print " <standaloneLongMonths>" + l['standaloneLongMonths'].encode('utf-8') + "</standaloneLongMonths>"
+ print " <standaloneShortMonths>"+ l['standaloneShortMonths'].encode('utf-8') + "</standaloneShortMonths>"
+ print " <standaloneNarrowMonths>"+ l['standaloneNarrowMonths'].encode('utf-8') + "</standaloneNarrowMonths>"
+ print " <longMonths>" + l['longMonths'].encode('utf-8') + "</longMonths>"
+ print " <shortMonths>" + l['shortMonths'].encode('utf-8') + "</shortMonths>"
+ print " <narrowMonths>" + l['narrowMonths'].encode('utf-8') + "</narrowMonths>"
+ print " <longDays>" + l['longDays'].encode('utf-8') + "</longDays>"
+ print " <shortDays>" + l['shortDays'].encode('utf-8') + "</shortDays>"
+ print " <narrowDays>" + l['narrowDays'].encode('utf-8') + "</narrowDays>"
+ print " <standaloneLongDays>" + l['standaloneLongDays'].encode('utf-8') + "</standaloneLongDays>"
+ print " <standaloneShortDays>" + l['standaloneShortDays'].encode('utf-8') + "</standaloneShortDays>"
+ print " <standaloneNarrowDays>" + l['standaloneNarrowDays'].encode('utf-8') + "</standaloneNarrowDays>"
+ print " <currencyIsoCode>" + l['currencyIsoCode'].encode('utf-8') + "</currencyIsoCode>"
+ print " <currencySymbol>" + l['currencySymbol'].encode('utf-8') + "</currencySymbol>"
+ print " <currencyDisplayName>" + l['currencyDisplayName'].encode('utf-8') + "</currencyDisplayName>"
+ print " <currencyDigits>" + str(l['currencyDigits']) + "</currencyDigits>"
+ print " <currencyRounding>" + str(l['currencyRounding']) + "</currencyRounding>"
+ print " <currencyFormat>" + l['currencyFormat'].encode('utf-8') + "</currencyFormat>"
+ print " <currencyNegativeFormat>" + l['currencyNegativeFormat'].encode('utf-8') + "</currencyNegativeFormat>"
+ print " </locale>"
+print " </localeList>"
+print "</localeDatabase>"
diff --git a/util/local_database/dateconverter.py b/util/local_database/dateconverter.py
new file mode 100755
index 0000000000..1b3db58196
--- /dev/null
+++ b/util/local_database/dateconverter.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## No Commercial Usage
+## This file contains pre-release code and may not be distributed.
+## You may use this file in accordance with the terms and conditions
+## contained in the Technology Preview License Agreement accompanying
+## this package.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Nokia gives you certain additional
+## rights. These rights are described in the Nokia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import re
+
+def _convert_pattern(pattern):
+ # patterns from http://www.unicode.org/reports/tr35/#Date_Format_Patterns
+ qt_regexps = {
+ r"yyy{3,}" : "yyyy", # more that three digits hence convert to four-digit year
+ r"L" : "M", # stand-alone month names. not supported.
+ r"g{1,}": "", # modified julian day. not supported.
+ r"S{1,}" : "", # fractional seconds. not supported.
+ r"A{1,}" : "" # milliseconds in day. not supported.
+ }
+ qt_patterns = {
+ "G" : "", "GG" : "", "GGG" : "", "GGGG" : "", "GGGGG" : "", # Era. not supported.
+ "y" : "yyyy", # four-digit year without leading zeroes
+ "Q" : "", "QQ" : "", "QQQ" : "", "QQQQ" : "", # quarter. not supported.
+ "q" : "", "qq" : "", "qqq" : "", "qqqq" : "", # quarter. not supported.
+ "MMMMM" : "MMM", # narrow month name.
+ "LLLLL" : "MMM", # stand-alone narrow month name.
+ "l" : "", # special symbol for chinese leap month. not supported.
+ "w" : "", "W" : "", # week of year/month. not supported.
+ "D" : "", "DD" : "", "DDD" : "", # day of year. not supported.
+ "F" : "", # day of week in month. not supported.
+ "E" : "ddd", "EE" : "ddd", "EEE" : "ddd", "EEEEE" : "ddd", "EEEE" : "dddd", # day of week
+ "e" : "ddd", "ee" : "ddd", "eee" : "ddd", "eeeee" : "ddd", "eeee" : "dddd", # local day of week
+ "c" : "ddd", "cc" : "ddd", "ccc" : "ddd", "ccccc" : "ddd", "cccc" : "dddd", # stand-alone local day of week
+ "a" : "AP", # AM/PM
+ "K" : "h", # Hour 0-11
+ "k" : "H", # Hour 1-24
+ "j" : "", # special reserved symbol.
+ "z" : "t", "zz" : "t", "zzz" : "t", "zzzz" : "t", # timezone
+ "Z" : "t", "ZZ" : "t", "ZZZ" : "t", "ZZZZ" : "t", # timezone
+ "v" : "t", "vv" : "t", "vvv" : "t", "vvvv" : "t", # timezone
+ "V" : "t", "VV" : "t", "VVV" : "t", "VVVV" : "t" # timezone
+ }
+ if qt_patterns.has_key(pattern):
+ return qt_patterns[pattern]
+ for r,v in qt_regexps.items():
+ pattern = re.sub(r, v, pattern)
+ return pattern
+
+def convert_date(input):
+ result = ""
+ patterns = "GyYuQqMLlwWdDFgEecahHKkjmsSAzZvV"
+ last = ""
+ inquote = 0
+ chars_to_strip = " -"
+ for c in input:
+ if c == "'":
+ inquote = inquote + 1
+ if inquote % 2 == 0:
+ if c in patterns:
+ if not last:
+ last = c
+ else:
+ if c in last:
+ last += c
+ else:
+ # pattern changed
+ converted = _convert_pattern(last)
+ result += converted
+ if not converted:
+ result = result.rstrip(chars_to_strip)
+ last = c
+ continue
+ if last:
+ # pattern ended
+ converted = _convert_pattern(last)
+ result += converted
+ if not converted:
+ result = result.rstrip(chars_to_strip)
+ last = ""
+ result += c
+ if last:
+ converted = _convert_pattern(last)
+ result += converted
+ if not converted:
+ result = result.rstrip(chars_to_strip)
+ return result.lstrip(chars_to_strip)
diff --git a/util/local_database/enumdata.py b/util/local_database/enumdata.py
new file mode 100644
index 0000000000..9e0d7d8ddd
--- /dev/null
+++ b/util/local_database/enumdata.py
@@ -0,0 +1,544 @@
+#!/usr/bin/env python
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## No Commercial Usage
+## This file contains pre-release code and may not be distributed.
+## You may use this file in accordance with the terms and conditions
+## contained in the Technology Preview License Agreement accompanying
+## this package.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Nokia gives you certain additional
+## rights. These rights are described in the Nokia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+# langugae_list and country_list reflect the current values of enums in qlocale.h
+# If new xml language files are available in CLDR, these languages and countries
+# need to be *appended* to this list.
+
+language_list = {
+ 0 : [ "AnyLanguage", " " ],
+ 1 : [ "C", " " ],
+ 2 : [ "Abkhazian", "ab" ],
+ 3 : [ "Afan", "om" ],
+ 4 : [ "Afar", "aa" ],
+ 5 : [ "Afrikaans", "af" ],
+ 6 : [ "Albanian", "sq" ],
+ 7 : [ "Amharic", "am" ],
+ 8 : [ "Arabic", "ar" ],
+ 9 : [ "Armenian", "hy" ],
+ 10 : [ "Assamese", "as" ],
+ 11 : [ "Aymara", "ay" ],
+ 12 : [ "Azerbaijani", "az" ],
+ 13 : [ "Bashkir", "ba" ],
+ 14 : [ "Basque", "eu" ],
+ 15 : [ "Bengali", "bn" ],
+ 16 : [ "Bhutani", "dz" ],
+ 17 : [ "Bihari", "bh" ],
+ 18 : [ "Bislama", "bi" ],
+ 19 : [ "Breton", "br" ],
+ 20 : [ "Bulgarian", "bg" ],
+ 21 : [ "Burmese", "my" ],
+ 22 : [ "Byelorussian", "be" ],
+ 23 : [ "Cambodian", "km" ],
+ 24 : [ "Catalan", "ca" ],
+ 25 : [ "Chinese", "zh" ],
+ 26 : [ "Corsican", "co" ],
+ 27 : [ "Croatian", "hr" ],
+ 28 : [ "Czech", "cs" ],
+ 29 : [ "Danish", "da" ],
+ 30 : [ "Dutch", "nl" ],
+ 31 : [ "English", "en" ],
+ 32 : [ "Esperanto", "eo" ],
+ 33 : [ "Estonian", "et" ],
+ 34 : [ "Faroese", "fo" ],
+ 35 : [ "Fiji", "fj" ],
+ 36 : [ "Finnish", "fi" ],
+ 37 : [ "French", "fr" ],
+ 38 : [ "Frisian", "fy" ],
+ 39 : [ "Gaelic", "gd" ],
+ 40 : [ "Galician", "gl" ],
+ 41 : [ "Georgian", "ka" ],
+ 42 : [ "German", "de" ],
+ 43 : [ "Greek", "el" ],
+ 44 : [ "Greenlandic", "kl" ],
+ 45 : [ "Guarani", "gn" ],
+ 46 : [ "Gujarati", "gu" ],
+ 47 : [ "Hausa", "ha" ],
+ 48 : [ "Hebrew", "he" ],
+ 49 : [ "Hindi", "hi" ],
+ 50 : [ "Hungarian", "hu" ],
+ 51 : [ "Icelandic", "is" ],
+ 52 : [ "Indonesian", "id" ],
+ 53 : [ "Interlingua", "ia" ],
+ 54 : [ "Interlingue", "ie" ],
+ 55 : [ "Inuktitut", "iu" ],
+ 56 : [ "Inupiak", "ik" ],
+ 57 : [ "Irish", "ga" ],
+ 58 : [ "Italian", "it" ],
+ 59 : [ "Japanese", "ja" ],
+ 60 : [ "Javanese", "jv" ],
+ 61 : [ "Kannada", "kn" ],
+ 62 : [ "Kashmiri", "ks" ],
+ 63 : [ "Kazakh", "kk" ],
+ 64 : [ "Kinyarwanda", "rw" ],
+ 65 : [ "Kirghiz", "ky" ],
+ 66 : [ "Korean", "ko" ],
+ 67 : [ "Kurdish", "ku" ],
+ 68 : [ "Kurundi", "rn" ],
+ 69 : [ "Laothian", "lo" ],
+ 70 : [ "Latin", "la" ],
+ 71 : [ "Latvian", "lv" ],
+ 72 : [ "Lingala", "ln" ],
+ 73 : [ "Lithuanian", "lt" ],
+ 74 : [ "Macedonian", "mk" ],
+ 75 : [ "Malagasy", "mg" ],
+ 76 : [ "Malay", "ms" ],
+ 77 : [ "Malayalam", "ml" ],
+ 78 : [ "Maltese", "mt" ],
+ 79 : [ "Maori", "mi" ],
+ 80 : [ "Marathi", "mr" ],
+ 81 : [ "Moldavian", "mo" ],
+ 82 : [ "Mongolian", "mn" ],
+ 83 : [ "Nauru", "na" ],
+ 84 : [ "Nepali", "ne" ],
+ 85 : [ "Norwegian", "nb" ],
+ 86 : [ "Occitan", "oc" ],
+ 87 : [ "Oriya", "or" ],
+ 88 : [ "Pashto", "ps" ],
+ 89 : [ "Persian", "fa" ],
+ 90 : [ "Polish", "pl" ],
+ 91 : [ "Portuguese", "pt" ],
+ 92 : [ "Punjabi", "pa" ],
+ 93 : [ "Quechua", "qu" ],
+ 94 : [ "RhaetoRomance", "rm" ],
+ 95 : [ "Romanian", "ro" ],
+ 96 : [ "Russian", "ru" ],
+ 97 : [ "Samoan", "sm" ],
+ 98 : [ "Sangho", "sg" ],
+ 99 : [ "Sanskrit", "sa" ],
+ 100 : [ "Serbian", "sr" ],
+ 101 : [ "SerboCroatian", "sh" ],
+ 102 : [ "Sesotho", "st" ],
+ 103 : [ "Setswana", "tn" ],
+ 104 : [ "Shona", "sn" ],
+ 105 : [ "Sindhi", "sd" ],
+ 106 : [ "Singhalese", "si" ],
+ 107 : [ "Siswati", "ss" ],
+ 108 : [ "Slovak", "sk" ],
+ 109 : [ "Slovenian", "sl" ],
+ 110 : [ "Somali", "so" ],
+ 111 : [ "Spanish", "es" ],
+ 112 : [ "Sundanese", "su" ],
+ 113 : [ "Swahili", "sw" ],
+ 114 : [ "Swedish", "sv" ],
+ 115 : [ "Tagalog", "tl" ],
+ 116 : [ "Tajik", "tg" ],
+ 117 : [ "Tamil", "ta" ],
+ 118 : [ "Tatar", "tt" ],
+ 119 : [ "Telugu", "te" ],
+ 120 : [ "Thai", "th" ],
+ 121 : [ "Tibetan", "bo" ],
+ 122 : [ "Tigrinya", "ti" ],
+ 123 : [ "Tonga", "to" ],
+ 124 : [ "Tsonga", "ts" ],
+ 125 : [ "Turkish", "tr" ],
+ 126 : [ "Turkmen", "tk" ],
+ 127 : [ "Twi", "tw" ],
+ 128 : [ "Uigur", "ug" ],
+ 129 : [ "Ukrainian", "uk" ],
+ 130 : [ "Urdu", "ur" ],
+ 131 : [ "Uzbek", "uz" ],
+ 132 : [ "Vietnamese", "vi" ],
+ 133 : [ "Volapuk", "vo" ],
+ 134 : [ "Welsh", "cy" ],
+ 135 : [ "Wolof", "wo" ],
+ 136 : [ "Xhosa", "xh" ],
+ 137 : [ "Yiddish", "yi" ],
+ 138 : [ "Yoruba", "yo" ],
+ 139 : [ "Zhuang", "za" ],
+ 140 : [ "Zulu", "zu" ],
+ 141 : [ "Nynorsk", "nn" ],
+ 142 : [ "Bosnian", "bs" ],
+ 143 : [ "Divehi", "dv" ],
+ 144 : [ "Manx", "gv" ],
+ 145 : [ "Cornish", "kw" ],
+ 146 : [ "Akan", "ak" ],
+ 147 : [ "Konkani", "kok" ],
+ 148 : [ "Ga", "gaa" ],
+ 149 : [ "Igbo", "ig" ],
+ 150 : [ "Kamba", "kam" ],
+ 151 : [ "Syriac", "syr" ],
+ 152 : [ "Blin", "byn" ],
+ 153 : [ "Geez", "gez" ],
+ 154 : [ "Koro", "kfo" ],
+ 155 : [ "Sidamo", "sid" ],
+ 156 : [ "Atsam", "cch" ],
+ 157 : [ "Tigre", "tig" ],
+ 158 : [ "Jju", "kaj" ],
+ 159 : [ "Friulian", "fur" ],
+ 160 : [ "Venda", "ve" ],
+ 161 : [ "Ewe", "ee" ],
+ 162 : [ "Walamo", "wal" ],
+ 163 : [ "Hawaiian", "haw" ],
+ 164 : [ "Tyap", "kcg" ],
+ 165 : [ "Chewa", "ny" ],
+ 166 : [ "Filipino", "fil" ],
+ 167 : [ "Swiss German", "gsw" ],
+ 168 : [ "Sichuan Yi", "ii" ],
+ 169 : [ "Kpelle", "kpe" ],
+ 170 : [ "Low German", "nds" ],
+ 171 : [ "South Ndebele", "nr" ],
+ 172 : [ "Northern Sotho", "nso" ],
+ 173 : [ "Northern Sami", "se" ],
+ 174 : [ "Taroko", "trv" ],
+ 175 : [ "Gusii", "guz" ],
+ 176 : [ "Taita", "dav" ],
+ 177 : [ "Fulah", "ff" ],
+ 178 : [ "Kikuyu", "ki" ],
+ 179 : [ "Samburu", "saq" ],
+ 180 : [ "Sena", "seh" ],
+ 181 : [ "North Ndebele", "nd" ],
+ 182 : [ "Rombo", "rof" ],
+ 183 : [ "Tachelhit", "shi" ],
+ 184 : [ "Kabyle", "kab" ],
+ 185 : [ "Nyankole", "nyn" ],
+ 186 : [ "Bena", "bez" ],
+ 187 : [ "Vunjo", "vun" ],
+ 188 : [ "Bambara", "bm" ],
+ 189 : [ "Embu", "ebu" ],
+ 190 : [ "Cherokee", "chr" ],
+ 191 : [ "Morisyen", "mfe" ],
+ 192 : [ "Makonde", "kde" ],
+ 193 : [ "Langi", "lag" ],
+ 194 : [ "Ganda", "lg" ],
+ 195 : [ "Bemba", "bem" ],
+ 196 : [ "Kabuverdianu", "kea" ],
+ 197 : [ "Meru", "mer" ],
+ 198 : [ "Kalenjin", "kln" ],
+ 199 : [ "Nama", "naq" ],
+ 200 : [ "Machame", "jmc" ],
+ 201 : [ "Colognian", "ksh" ],
+ 202 : [ "Masai", "mas" ],
+ 203 : [ "Soga", "xog" ],
+ 204 : [ "Luyia", "luy" ],
+ 205 : [ "Asu", "asa" ],
+ 206 : [ "Teso", "teo" ],
+ 207 : [ "Saho", "ssy" ],
+ 208 : [ "Koyra Chiini", "khq" ],
+ 209 : [ "Rwa", "rwk" ],
+ 210 : [ "Luo", "luo" ],
+ 211 : [ "Chiga", "cgg" ],
+ 212 : [ "Central Morocco Tamazight", "tzm" ],
+ 213 : [ "Koyraboro Senni", "ses" ],
+ 214 : [ "Shambala", "ksb" ]
+}
+
+country_list = {
+ 0 : [ "AnyCountry", " " ],
+ 1 : [ "Afghanistan", "AF" ],
+ 2 : [ "Albania", "AL" ],
+ 3 : [ "Algeria", "DZ" ],
+ 4 : [ "AmericanSamoa", "AS" ],
+ 5 : [ "Andorra", "AD" ],
+ 6 : [ "Angola", "AO" ],
+ 7 : [ "Anguilla", "AI" ],
+ 8 : [ "Antarctica", "AQ" ],
+ 9 : [ "AntiguaAndBarbuda", "AG" ],
+ 10 : [ "Argentina", "AR" ],
+ 11 : [ "Armenia", "AM" ],
+ 12 : [ "Aruba", "AW" ],
+ 13 : [ "Australia", "AU" ],
+ 14 : [ "Austria", "AT" ],
+ 15 : [ "Azerbaijan", "AZ" ],
+ 16 : [ "Bahamas", "BS" ],
+ 17 : [ "Bahrain", "BH" ],
+ 18 : [ "Bangladesh", "BD" ],
+ 19 : [ "Barbados", "BB" ],
+ 20 : [ "Belarus", "BY" ],
+ 21 : [ "Belgium", "BE" ],
+ 22 : [ "Belize", "BZ" ],
+ 23 : [ "Benin", "BJ" ],
+ 24 : [ "Bermuda", "BM" ],
+ 25 : [ "Bhutan", "BT" ],
+ 26 : [ "Bolivia", "BO" ],
+ 27 : [ "BosniaAndHerzegowina", "BA" ],
+ 28 : [ "Botswana", "BW" ],
+ 29 : [ "BouvetIsland", "BV" ],
+ 30 : [ "Brazil", "BR" ],
+ 31 : [ "BritishIndianOceanTerritory", "IO" ],
+ 32 : [ "BruneiDarussalam", "BN" ],
+ 33 : [ "Bulgaria", "BG" ],
+ 34 : [ "BurkinaFaso", "BF" ],
+ 35 : [ "Burundi", "BI" ],
+ 36 : [ "Cambodia", "KH" ],
+ 37 : [ "Cameroon", "CM" ],
+ 38 : [ "Canada", "CA" ],
+ 39 : [ "CapeVerde", "CV" ],
+ 40 : [ "CaymanIslands", "KY" ],
+ 41 : [ "CentralAfricanRepublic", "CF" ],
+ 42 : [ "Chad", "TD" ],
+ 43 : [ "Chile", "CL" ],
+ 44 : [ "China", "CN" ],
+ 45 : [ "ChristmasIsland", "CX" ],
+ 46 : [ "CocosIslands", "CC" ],
+ 47 : [ "Colombia", "CO" ],
+ 48 : [ "Comoros", "KM" ],
+ 49 : [ "DemocraticRepublicOfCongo", "CD" ],
+ 50 : [ "PeoplesRepublicOfCongo", "CG" ],
+ 51 : [ "CookIslands", "CK" ],
+ 52 : [ "CostaRica", "CR" ],
+ 53 : [ "IvoryCoast", "CI" ],
+ 54 : [ "Croatia", "HR" ],
+ 55 : [ "Cuba", "CU" ],
+ 56 : [ "Cyprus", "CY" ],
+ 57 : [ "CzechRepublic", "CZ" ],
+ 58 : [ "Denmark", "DK" ],
+ 59 : [ "Djibouti", "DJ" ],
+ 60 : [ "Dominica", "DM" ],
+ 61 : [ "DominicanRepublic", "DO" ],
+ 62 : [ "EastTimor", "TL" ],
+ 63 : [ "Ecuador", "EC" ],
+ 64 : [ "Egypt", "EG" ],
+ 65 : [ "ElSalvador", "SV" ],
+ 66 : [ "EquatorialGuinea", "GQ" ],
+ 67 : [ "Eritrea", "ER" ],
+ 68 : [ "Estonia", "EE" ],
+ 69 : [ "Ethiopia", "ET" ],
+ 70 : [ "FalklandIslands", "FK" ],
+ 71 : [ "FaroeIslands", "FO" ],
+ 72 : [ "Fiji", "FJ" ],
+ 73 : [ "Finland", "FI" ],
+ 74 : [ "France", "FR" ],
+ 75 : [ "MetropolitanFrance", "FX" ],
+ 76 : [ "FrenchGuiana", "GF" ],
+ 77 : [ "FrenchPolynesia", "PF" ],
+ 78 : [ "FrenchSouthernTerritories", "TF" ],
+ 79 : [ "Gabon", "GA" ],
+ 80 : [ "Gambia", "GM" ],
+ 81 : [ "Georgia", "GE" ],
+ 82 : [ "Germany", "DE" ],
+ 83 : [ "Ghana", "GH" ],
+ 84 : [ "Gibraltar", "GI" ],
+ 85 : [ "Greece", "GR" ],
+ 86 : [ "Greenland", "GL" ],
+ 87 : [ "Grenada", "GD" ],
+ 88 : [ "Guadeloupe", "GP" ],
+ 89 : [ "Guam", "GU" ],
+ 90 : [ "Guatemala", "GT" ],
+ 91 : [ "Guinea", "GN" ],
+ 92 : [ "GuineaBissau", "GW" ],
+ 93 : [ "Guyana", "GY" ],
+ 94 : [ "Haiti", "HT" ],
+ 95 : [ "HeardAndMcDonaldIslands", "HM" ],
+ 96 : [ "Honduras", "HN" ],
+ 97 : [ "HongKong", "HK" ],
+ 98 : [ "Hungary", "HU" ],
+ 99 : [ "Iceland", "IS" ],
+ 100 : [ "India", "IN" ],
+ 101 : [ "Indonesia", "ID" ],
+ 102 : [ "Iran", "IR" ],
+ 103 : [ "Iraq", "IQ" ],
+ 104 : [ "Ireland", "IE" ],
+ 105 : [ "Israel", "IL" ],
+ 106 : [ "Italy", "IT" ],
+ 107 : [ "Jamaica", "JM" ],
+ 108 : [ "Japan", "JP" ],
+ 109 : [ "Jordan", "JO" ],
+ 110 : [ "Kazakhstan", "KZ" ],
+ 111 : [ "Kenya", "KE" ],
+ 112 : [ "Kiribati", "KI" ],
+ 113 : [ "DemocraticRepublicOfKorea", "KP" ],
+ 114 : [ "RepublicOfKorea", "KR" ],
+ 115 : [ "Kuwait", "KW" ],
+ 116 : [ "Kyrgyzstan", "KG" ],
+ 117 : [ "Lao", "LA" ],
+ 118 : [ "Latvia", "LV" ],
+ 119 : [ "Lebanon", "LB" ],
+ 120 : [ "Lesotho", "LS" ],
+ 121 : [ "Liberia", "LR" ],
+ 122 : [ "LibyanArabJamahiriya", "LY" ],
+ 123 : [ "Liechtenstein", "LI" ],
+ 124 : [ "Lithuania", "LT" ],
+ 125 : [ "Luxembourg", "LU" ],
+ 126 : [ "Macau", "MO" ],
+ 127 : [ "Macedonia", "MK" ],
+ 128 : [ "Madagascar", "MG" ],
+ 129 : [ "Malawi", "MW" ],
+ 130 : [ "Malaysia", "MY" ],
+ 131 : [ "Maldives", "MV" ],
+ 132 : [ "Mali", "ML" ],
+ 133 : [ "Malta", "MT" ],
+ 134 : [ "MarshallIslands", "MH" ],
+ 135 : [ "Martinique", "MQ" ],
+ 136 : [ "Mauritania", "MR" ],
+ 137 : [ "Mauritius", "MU" ],
+ 138 : [ "Mayotte", "YT" ],
+ 139 : [ "Mexico", "MX" ],
+ 140 : [ "Micronesia", "FM" ],
+ 141 : [ "Moldova", "MD" ],
+ 142 : [ "Monaco", "MC" ],
+ 143 : [ "Mongolia", "MN" ],
+ 144 : [ "Montserrat", "MS" ],
+ 145 : [ "Morocco", "MA" ],
+ 146 : [ "Mozambique", "MZ" ],
+ 147 : [ "Myanmar", "MM" ],
+ 148 : [ "Namibia", "NA" ],
+ 149 : [ "Nauru", "NR" ],
+ 150 : [ "Nepal", "NP" ],
+ 151 : [ "Netherlands", "NL" ],
+ 152 : [ "NetherlandsAntilles", "AN" ],
+ 153 : [ "NewCaledonia", "NC" ],
+ 154 : [ "NewZealand", "NZ" ],
+ 155 : [ "Nicaragua", "NI" ],
+ 156 : [ "Niger", "NE" ],
+ 157 : [ "Nigeria", "NG" ],
+ 158 : [ "Niue", "NU" ],
+ 159 : [ "NorfolkIsland", "NF" ],
+ 160 : [ "NorthernMarianaIslands", "MP" ],
+ 161 : [ "Norway", "NO" ],
+ 162 : [ "Oman", "OM" ],
+ 163 : [ "Pakistan", "PK" ],
+ 164 : [ "Palau", "PW" ],
+ 165 : [ "PalestinianTerritory", "PS" ],
+ 166 : [ "Panama", "PA" ],
+ 167 : [ "PapuaNewGuinea", "PG" ],
+ 168 : [ "Paraguay", "PY" ],
+ 169 : [ "Peru", "PE" ],
+ 170 : [ "Philippines", "PH" ],
+ 171 : [ "Pitcairn", "PN" ],
+ 172 : [ "Poland", "PL" ],
+ 173 : [ "Portugal", "PT" ],
+ 174 : [ "PuertoRico", "PR" ],
+ 175 : [ "Qatar", "QA" ],
+ 176 : [ "Reunion", "RE" ],
+ 177 : [ "Romania", "RO" ],
+ 178 : [ "RussianFederation", "RU" ],
+ 179 : [ "Rwanda", "RW" ],
+ 180 : [ "SaintKittsAndNevis", "KN" ],
+ 181 : [ "StLucia", "LC" ],
+ 182 : [ "StVincentAndTheGrenadines", "VC" ],
+ 183 : [ "Samoa", "WS" ],
+ 184 : [ "SanMarino", "SM" ],
+ 185 : [ "SaoTomeAndPrincipe", "ST" ],
+ 186 : [ "SaudiArabia", "SA" ],
+ 187 : [ "Senegal", "SN" ],
+ 188 : [ "Seychelles", "SC" ],
+ 189 : [ "SierraLeone", "SL" ],
+ 190 : [ "Singapore", "SG" ],
+ 191 : [ "Slovakia", "SK" ],
+ 192 : [ "Slovenia", "SI" ],
+ 193 : [ "SolomonIslands", "SB" ],
+ 194 : [ "Somalia", "SO" ],
+ 195 : [ "SouthAfrica", "ZA" ],
+ 196 : [ "SouthGeorgiaAndTheSouthSandwichIslands", "GS" ],
+ 197 : [ "Spain", "ES" ],
+ 198 : [ "SriLanka", "LK" ],
+ 199 : [ "StHelena", "SH" ],
+ 200 : [ "StPierreAndMiquelon", "PM" ],
+ 201 : [ "Sudan", "SD" ],
+ 202 : [ "Suriname", "SR" ],
+ 203 : [ "SvalbardAndJanMayenIslands", "SJ" ],
+ 204 : [ "Swaziland", "SZ" ],
+ 205 : [ "Sweden", "SE" ],
+ 206 : [ "Switzerland", "CH" ],
+ 207 : [ "SyrianArabRepublic", "SY" ],
+ 208 : [ "Taiwan", "TW" ],
+ 209 : [ "Tajikistan", "TJ" ],
+ 210 : [ "Tanzania", "TZ" ],
+ 211 : [ "Thailand", "TH" ],
+ 212 : [ "Togo", "TG" ],
+ 213 : [ "Tokelau", "TK" ],
+ 214 : [ "Tonga", "TO" ],
+ 215 : [ "TrinidadAndTobago", "TT" ],
+ 216 : [ "Tunisia", "TN" ],
+ 217 : [ "Turkey", "TR" ],
+ 218 : [ "Turkmenistan", "TM" ],
+ 219 : [ "TurksAndCaicosIslands", "TC" ],
+ 220 : [ "Tuvalu", "TV" ],
+ 221 : [ "Uganda", "UG" ],
+ 222 : [ "Ukraine", "UA" ],
+ 223 : [ "UnitedArabEmirates", "AE" ],
+ 224 : [ "UnitedKingdom", "GB" ],
+ 225 : [ "UnitedStates", "US" ],
+ 226 : [ "UnitedStatesMinorOutlyingIslands", "UM" ],
+ 227 : [ "Uruguay", "UY" ],
+ 228 : [ "Uzbekistan", "UZ" ],
+ 229 : [ "Vanuatu", "VU" ],
+ 230 : [ "VaticanCityState", "VA" ],
+ 231 : [ "Venezuela", "VE" ],
+ 232 : [ "VietNam", "VN" ],
+ 233 : [ "BritishVirginIslands", "VG" ],
+ 234 : [ "USVirginIslands", "VI" ],
+ 235 : [ "WallisAndFutunaIslands", "WF" ],
+ 236 : [ "WesternSahara", "EH" ],
+ 237 : [ "Yemen", "YE" ],
+ 238 : [ "Yugoslavia", "YU" ],
+ 239 : [ "Zambia", "ZM" ],
+ 240 : [ "Zimbabwe", "ZW" ],
+ 241 : [ "SerbiaAndMontenegro", "CS" ],
+ 242 : [ "Montenegro", "ME" ],
+ 243 : [ "Serbia", "RS" ],
+ 244 : [ "Saint Barthelemy", "BL" ],
+ 245 : [ "Saint Martin", "MF" ],
+ 246 : [ "LatinAmericaAndTheCaribbean", "419" ]
+}
+
+script_list = {
+ 0 : [ "AnyScript", "" ],
+ 1 : [ "Arabic", "Arab" ],
+ 2 : [ "Cyrillic", "Cyrl" ],
+ 3 : [ "Deseret", "Dsrt" ],
+ 4 : [ "Gurmukhi", "Guru" ],
+ 5 : [ "Simplified Han", "Hans" ],
+ 6 : [ "Traditional Han", "Hant" ],
+ 7 : [ "Latin", "Latn" ],
+ 8 : [ "Mongolian", "Mong" ],
+ 9 : [ "Tifinagh", "Tfng" ]
+}
+
+def countryCodeToId(code):
+ for country_id in country_list:
+ if country_list[country_id][1] == code:
+ return country_id
+ return -1
+
+def languageCodeToId(code):
+ for language_id in language_list:
+ if language_list[language_id][1] == code:
+ return language_id
+ return -1
+
+def scriptCodeToId(code):
+ for script_id in script_list:
+ if script_list[script_id][1] == code:
+ return script_id
+ return -1
diff --git a/util/local_database/formattags.txt b/util/local_database/formattags.txt
new file mode 100644
index 0000000000..5138c37a81
--- /dev/null
+++ b/util/local_database/formattags.txt
@@ -0,0 +1,23 @@
+d
+dd
+ddd
+dddd
+M
+MM
+MMM
+MMMM
+yy
+yyyy
+h the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+hh the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+H the hour without a leading zero (0 to 23, even with AM/PM display)
+HH the hour with a leading zero (00 to 23, even with AM/PM display)
+m
+mm
+s
+ss
+z the milliseconds without leading zeroes (0 to 999)
+zzz the milliseconds with leading zeroes (000 to 999)
+AP or A interpret as an AM/PM time. AP must be either "AM" or "PM"
+ap or a Interpret as an AM/PM time. ap must be either "am" or "pm"
+t time zone
diff --git a/util/local_database/qlocalexml2cpp.py b/util/local_database/qlocalexml2cpp.py
new file mode 100755
index 0000000000..89074351e9
--- /dev/null
+++ b/util/local_database/qlocalexml2cpp.py
@@ -0,0 +1,877 @@
+#!/usr/bin/env python
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## No Commercial Usage
+## This file contains pre-release code and may not be distributed.
+## You may use this file in accordance with the terms and conditions
+## contained in the Technology Preview License Agreement accompanying
+## this package.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Nokia gives you certain additional
+## rights. These rights are described in the Nokia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import os
+import sys
+import tempfile
+import datetime
+import xml.dom.minidom
+
+class Error:
+ def __init__(self, msg):
+ self.msg = msg
+ def __str__(self):
+ return self.msg
+
+def check_static_char_array_length(name, array):
+ # some compilers like VC6 doesn't allow static arrays more than 64K bytes size.
+ size = reduce(lambda x, y: x+len(escapedString(y)), array, 0)
+ if size > 65535:
+ print "\n\n\n#error Array %s is too long! " % name
+ sys.stderr.write("\n\n\nERROR: the content of the array '%s' is too long: %d > 65535 " % (name, size))
+ sys.exit(1)
+
+def wrap_list(lst):
+ def split(lst, size):
+ for i in range(len(lst)/size+1):
+ yield lst[i*size:(i+1)*size]
+ return ",\n".join(map(lambda x: ", ".join(x), split(lst, 20)))
+
+def firstChildElt(parent, name):
+ child = parent.firstChild
+ while child:
+ if child.nodeType == parent.ELEMENT_NODE \
+ and (not name or child.nodeName == name):
+ return child
+ child = child.nextSibling
+ return False
+
+def nextSiblingElt(sibling, name):
+ sib = sibling.nextSibling
+ while sib:
+ if sib.nodeType == sibling.ELEMENT_NODE \
+ and (not name or sib.nodeName == name):
+ return sib
+ sib = sib.nextSibling
+ return False
+
+def eltText(elt):
+ result = ""
+ child = elt.firstChild
+ while child:
+ if child.nodeType == elt.TEXT_NODE:
+ if result:
+ result += " "
+ result += child.nodeValue
+ child = child.nextSibling
+ return result
+
+def loadLanguageMap(doc):
+ result = {}
+
+ language_list_elt = firstChildElt(doc.documentElement, "languageList")
+ language_elt = firstChildElt(language_list_elt, "language")
+ while language_elt:
+ language_id = int(eltText(firstChildElt(language_elt, "id")))
+ language_name = eltText(firstChildElt(language_elt, "name"))
+ language_code = eltText(firstChildElt(language_elt, "code"))
+ result[language_id] = (language_name, language_code)
+ language_elt = nextSiblingElt(language_elt, "language")
+
+ return result
+
+def loadScriptMap(doc):
+ result = {}
+
+ script_list_elt = firstChildElt(doc.documentElement, "scriptList")
+ script_elt = firstChildElt(script_list_elt, "script")
+ while script_elt:
+ script_id = int(eltText(firstChildElt(script_elt, "id")))
+ script_name = eltText(firstChildElt(script_elt, "name"))
+ script_code = eltText(firstChildElt(script_elt, "code"))
+ result[script_id] = (script_name, script_code)
+ script_elt = nextSiblingElt(script_elt, "script")
+
+ return result
+
+def loadCountryMap(doc):
+ result = {}
+
+ country_list_elt = firstChildElt(doc.documentElement, "countryList")
+ country_elt = firstChildElt(country_list_elt, "country")
+ while country_elt:
+ country_id = int(eltText(firstChildElt(country_elt, "id")))
+ country_name = eltText(firstChildElt(country_elt, "name"))
+ country_code = eltText(firstChildElt(country_elt, "code"))
+ result[country_id] = (country_name, country_code)
+ country_elt = nextSiblingElt(country_elt, "country")
+
+ return result
+
+def loadDefaultMap(doc):
+ result = {}
+
+ list_elt = firstChildElt(doc.documentElement, "defaultCountryList")
+ elt = firstChildElt(list_elt, "defaultCountry")
+ while elt:
+ country = eltText(firstChildElt(elt, "country"));
+ language = eltText(firstChildElt(elt, "language"));
+ result[language] = country;
+ elt = nextSiblingElt(elt, "defaultCountry");
+ return result
+
+def fixedScriptName(name, dupes):
+ name = name.replace(" ", "")
+ if name[-6:] != "Script":
+ name = name + "Script";
+ if name in dupes:
+ sys.stderr.write("\n\n\nERROR: The script name '%s' is messy" % name)
+ sys.exit(1);
+ return name
+
+def fixedCountryName(name, dupes):
+ if name in dupes:
+ return name.replace(" ", "") + "Country"
+ return name.replace(" ", "")
+
+def fixedLanguageName(name, dupes):
+ if name in dupes:
+ return name.replace(" ", "") + "Language"
+ return name.replace(" ", "")
+
+def findDupes(country_map, language_map):
+ country_set = set([ v[0] for a, v in country_map.iteritems() ])
+ language_set = set([ v[0] for a, v in language_map.iteritems() ])
+ return country_set & language_set
+
+def languageNameToId(name, language_map):
+ for key in language_map.keys():
+ if language_map[key][0] == name:
+ return key
+ return -1
+
+def scriptNameToId(name, script_map):
+ for key in script_map.keys():
+ if script_map[key][0] == name:
+ return key
+ return -1
+
+def countryNameToId(name, country_map):
+ for key in country_map.keys():
+ if country_map[key][0] == name:
+ return key
+ return -1
+
+def convertFormat(format):
+ result = ""
+ i = 0
+ while i < len(format):
+ if format[i] == "'":
+ result += "'"
+ i += 1
+ while i < len(format) and format[i] != "'":
+ result += format[i]
+ i += 1
+ if i < len(format):
+ result += "'"
+ i += 1
+ else:
+ s = format[i:]
+ if s.startswith("EEEE"):
+ result += "dddd"
+ i += 4
+ elif s.startswith("EEE"):
+ result += "ddd"
+ i += 3
+ elif s.startswith("a"):
+ result += "AP"
+ i += 1
+ elif s.startswith("z"):
+ result += "t"
+ i += 1
+ elif s.startswith("v"):
+ i += 1
+ else:
+ result += format[i]
+ i += 1
+
+ return result
+
+def convertToQtDayOfWeek(firstDay):
+ qtDayOfWeek = {"mon":1, "tue":2, "wed":3, "thu":4, "fri":5, "sat":6, "sun":7}
+ return qtDayOfWeek[firstDay]
+
+def assertSingleChar(string):
+ assert len(string) == 1, "This string is not allowed to be longer than 1 character"
+ return string
+
+class Locale:
+ def __init__(self, elt):
+ self.language = eltText(firstChildElt(elt, "language"))
+ self.languageEndonym = eltText(firstChildElt(elt, "languageEndonym"))
+ self.script = eltText(firstChildElt(elt, "script"))
+ self.country = eltText(firstChildElt(elt, "country"))
+ self.countryEndonym = eltText(firstChildElt(elt, "countryEndonym"))
+ self.decimal = int(eltText(firstChildElt(elt, "decimal")))
+ self.group = int(eltText(firstChildElt(elt, "group")))
+ self.listDelim = int(eltText(firstChildElt(elt, "list")))
+ self.percent = int(eltText(firstChildElt(elt, "percent")))
+ self.zero = int(eltText(firstChildElt(elt, "zero")))
+ self.minus = int(eltText(firstChildElt(elt, "minus")))
+ self.plus = int(eltText(firstChildElt(elt, "plus")))
+ self.exp = int(eltText(firstChildElt(elt, "exp")))
+ self.quotationStart = ord(assertSingleChar(eltText(firstChildElt(elt, "quotationStart"))))
+ self.quotationEnd = ord(assertSingleChar(eltText(firstChildElt(elt, "quotationEnd"))))
+ self.alternateQuotationStart = ord(assertSingleChar(eltText(firstChildElt(elt, "alternateQuotationStart"))))
+ self.alternateQuotationEnd = ord(assertSingleChar(eltText(firstChildElt(elt, "alternateQuotationEnd"))))
+ self.listPatternPartStart = eltText(firstChildElt(elt, "listPatternPartStart"))
+ self.listPatternPartMiddle = eltText(firstChildElt(elt, "listPatternPartMiddle"))
+ self.listPatternPartEnd = eltText(firstChildElt(elt, "listPatternPartEnd"))
+ self.listPatternPartTwo = eltText(firstChildElt(elt, "listPatternPartTwo"))
+ self.am = eltText(firstChildElt(elt, "am"))
+ self.pm = eltText(firstChildElt(elt, "pm"))
+ self.firstDayOfWeek = convertToQtDayOfWeek(eltText(firstChildElt(elt, "firstDayOfWeek")))
+ self.weekendStart = convertToQtDayOfWeek(eltText(firstChildElt(elt, "weekendStart")))
+ self.weekendEnd = convertToQtDayOfWeek(eltText(firstChildElt(elt, "weekendEnd")))
+ self.longDateFormat = convertFormat(eltText(firstChildElt(elt, "longDateFormat")))
+ self.shortDateFormat = convertFormat(eltText(firstChildElt(elt, "shortDateFormat")))
+ self.longTimeFormat = convertFormat(eltText(firstChildElt(elt, "longTimeFormat")))
+ self.shortTimeFormat = convertFormat(eltText(firstChildElt(elt, "shortTimeFormat")))
+ self.standaloneLongMonths = eltText(firstChildElt(elt, "standaloneLongMonths"))
+ self.standaloneShortMonths = eltText(firstChildElt(elt, "standaloneShortMonths"))
+ self.standaloneNarrowMonths = eltText(firstChildElt(elt, "standaloneNarrowMonths"))
+ self.longMonths = eltText(firstChildElt(elt, "longMonths"))
+ self.shortMonths = eltText(firstChildElt(elt, "shortMonths"))
+ self.narrowMonths = eltText(firstChildElt(elt, "narrowMonths"))
+ self.standaloneLongDays = eltText(firstChildElt(elt, "standaloneLongDays"))
+ self.standaloneShortDays = eltText(firstChildElt(elt, "standaloneShortDays"))
+ self.standaloneNarrowDays = eltText(firstChildElt(elt, "standaloneNarrowDays"))
+ self.longDays = eltText(firstChildElt(elt, "longDays"))
+ self.shortDays = eltText(firstChildElt(elt, "shortDays"))
+ self.narrowDays = eltText(firstChildElt(elt, "narrowDays"))
+ self.currencyIsoCode = eltText(firstChildElt(elt, "currencyIsoCode"))
+ self.currencySymbol = eltText(firstChildElt(elt, "currencySymbol"))
+ self.currencyDisplayName = eltText(firstChildElt(elt, "currencyDisplayName"))
+ self.currencyDigits = int(eltText(firstChildElt(elt, "currencyDigits")))
+ self.currencyRounding = int(eltText(firstChildElt(elt, "currencyRounding")))
+ self.currencyFormat = eltText(firstChildElt(elt, "currencyFormat"))
+ self.currencyNegativeFormat = eltText(firstChildElt(elt, "currencyNegativeFormat"))
+
+def loadLocaleMap(doc, language_map, script_map, country_map):
+ result = {}
+
+ locale_list_elt = firstChildElt(doc.documentElement, "localeList")
+ locale_elt = firstChildElt(locale_list_elt, "locale")
+ while locale_elt:
+ locale = Locale(locale_elt)
+ language_id = languageNameToId(locale.language, language_map)
+ if language_id == -1:
+ sys.stderr.write("Cannot find a language id for '%s'\n" % locale.language)
+ script_id = scriptNameToId(locale.script, script_map)
+ if script_id == -1:
+ sys.stderr.write("Cannot find a script id for '%s'\n" % locale.script)
+ country_id = countryNameToId(locale.country, country_map)
+ if country_id == -1:
+ sys.stderr.write("Cannot find a country id for '%s'\n" % locale.country)
+ result[(language_id, script_id, country_id)] = locale
+
+ locale_elt = nextSiblingElt(locale_elt, "locale")
+
+ return result
+
+def compareLocaleKeys(key1, key2):
+ if key1 == key2:
+ return 0
+
+ if key1[0] == key2[0]:
+ l1 = compareLocaleKeys.locale_map[key1]
+ l2 = compareLocaleKeys.locale_map[key2]
+
+ if l1.language in compareLocaleKeys.default_map:
+ default = compareLocaleKeys.default_map[l1.language]
+ if l1.country == default and key1[1] == 0:
+ return -1
+ if l2.country == default and key2[1] == 0:
+ return 1
+
+ if key1[1] != key2[1]:
+ return key1[1] - key2[1]
+ else:
+ return key1[0] - key2[0]
+
+ return key1[2] - key2[2]
+
+
+def languageCount(language_id, locale_map):
+ result = 0
+ for key in locale_map.keys():
+ if key[0] == language_id:
+ result += 1
+ return result
+
+def unicode2hex(s):
+ lst = []
+ for x in s:
+ v = ord(x)
+ if v > 0xFFFF:
+ # make a surrogate pair
+ # copied from qchar.h
+ high = (v >> 10) + 0xd7c0
+ low = (v % 0x400 + 0xdc00)
+ lst.append(hex(high))
+ lst.append(hex(low))
+ else:
+ lst.append(hex(v))
+ return lst
+
+class StringDataToken:
+ def __init__(self, index, length):
+ if index > 0xFFFF or length > 0xFFFF:
+ raise Error("Position exceeds ushort range: %d,%d " % (index, length))
+ self.index = index
+ self.length = length
+ def __str__(self):
+ return " %d,%d " % (self.index, self.length)
+
+class StringData:
+ def __init__(self):
+ self.data = []
+ self.hash = {}
+ def append(self, s):
+ 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)
+ size = len(lst)
+ if size >= 65535:
+ print "\n\n\n#error Data is too big!"
+ sys.stderr.write ("\n\n\nERROR: data size exceeds the uint16 range! size = %d\n" % size)
+ sys.exit(1)
+ token = None
+ try:
+ token = StringDataToken(index, size)
+ except Error as e:
+ sys.stderr.write("\n\n\nERROR: %s: on data '%s'" % (e, s))
+ sys.exit(1)
+ self.hash[s] = token
+ self.data += lst
+ return token
+
+def escapedString(s):
+ result = ""
+ i = 0
+ while i < len(s):
+ if s[i] == '"':
+ result += '\\"'
+ i += 1
+ else:
+ result += s[i]
+ i += 1
+ s = result
+
+ line = ""
+ need_escape = False
+ result = ""
+ for c in s:
+ if ord(c) < 128 and (not need_escape or ord(c.lower()) < ord('a') or ord(c.lower()) > ord('f')):
+ line += c
+ need_escape = False
+ else:
+ line += "\\x%02x" % (ord(c))
+ need_escape = True
+ if len(line) > 80:
+ result = result + "\n" + "\"" + line + "\""
+ line = ""
+ line += "\\0"
+ result = result + "\n" + "\"" + line + "\""
+ if result[0] == "\n":
+ result = result[1:]
+ return result
+
+def printEscapedString(s):
+ print escapedString(s);
+
+
+def currencyIsoCodeData(s):
+ if s:
+ return ",".join(map(lambda x: str(ord(x)), s))
+ return "0,0,0"
+
+def usage():
+ print "Usage: qlocalexml2cpp.py <path-to-locale.xml> <path-to-qt-src-tree>"
+ sys.exit(1)
+
+GENERATED_BLOCK_START = "// GENERATED PART STARTS HERE\n"
+GENERATED_BLOCK_END = "// GENERATED PART ENDS HERE\n"
+
+def main():
+ if len(sys.argv) != 3:
+ usage()
+
+ localexml = sys.argv[1]
+ qtsrcdir = sys.argv[2]
+
+ if not os.path.exists(qtsrcdir) or not os.path.exists(qtsrcdir):
+ usage()
+ if not os.path.isfile(qtsrcdir + "/src/corelib/tools/qlocale_data_p.h"):
+ usage()
+ if not os.path.isfile(qtsrcdir + "/src/corelib/tools/qlocale.h"):
+ usage()
+ if not os.path.isfile(qtsrcdir + "/src/corelib/tools/qlocale.qdoc"):
+ usage()
+
+ (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")
+ s = qlocaledata_file.readline()
+ while s and s != GENERATED_BLOCK_START:
+ data_temp_file.write(s)
+ s = qlocaledata_file.readline()
+ data_temp_file.write(GENERATED_BLOCK_START)
+
+ doc = xml.dom.minidom.parse(localexml)
+ language_map = loadLanguageMap(doc)
+ script_map = loadScriptMap(doc)
+ country_map = loadCountryMap(doc)
+ default_map = loadDefaultMap(doc)
+ locale_map = loadLocaleMap(doc, language_map, script_map, country_map)
+ dupes = findDupes(language_map, country_map)
+
+ cldr_version = eltText(firstChildElt(doc.documentElement, "version"))
+
+ data_temp_file.write("\n\
+/*\n\
+ This part of the file was generated on %s from the\n\
+ Common Locale Data Repository v%s\n\
+\n\
+ http://www.unicode.org/cldr/\n\
+\n\
+ Do not change it, instead edit CLDR data and regenerate this file using\n\
+ cldr2qlocalexml.py and qlocalexml2cpp.py.\n\
+*/\n\n\n\
+" % (str(datetime.date.today()), cldr_version) )
+
+ # Locale index
+ data_temp_file.write("static const quint16 locale_index[] = {\n")
+ index = 0
+ for key in language_map.keys():
+ i = 0
+ count = languageCount(key, locale_map)
+ if count > 0:
+ i = index
+ index += count
+ data_temp_file.write("%6d, // %s\n" % (i, language_map[key][0]))
+ data_temp_file.write(" 0 // trailing 0\n")
+ data_temp_file.write("};\n")
+
+ data_temp_file.write("\n")
+
+ list_pattern_part_data = StringData()
+ date_format_data = StringData()
+ time_format_data = StringData()
+ months_data = StringData()
+ standalone_months_data = StringData()
+ days_data = StringData()
+ am_data = StringData()
+ pm_data = StringData()
+ currency_symbol_data = StringData()
+ currency_display_name_data = StringData()
+ currency_format_data = StringData()
+ endonyms_data = StringData()
+
+ # Locale data
+ data_temp_file.write("static const QLocalePrivate locale_data[] = {\n")
+ data_temp_file.write("// lang script terr dec group list prcnt zero minus plus exp quotStart quotEnd altQuotStart altQuotEnd lpStart lpMid lpEnd lpTwo sDtFmt lDtFmt sTmFmt lTmFmt ssMonth slMonth sMonth lMonth sDays lDays am,len pm,len\n")
+
+ locale_keys = locale_map.keys()
+ compareLocaleKeys.default_map = default_map
+ compareLocaleKeys.locale_map = locale_map
+ locale_keys.sort(compareLocaleKeys)
+
+ for key in locale_keys:
+ l = locale_map[key]
+ data_temp_file.write(" { %6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s, {%s}, %s,%s,%s,%s,%s,%s,%6d,%6d,%6d,%6d,%6d }, // %s/%s/%s\n" \
+ % (key[0], key[1], key[2],
+ l.decimal,
+ l.group,
+ l.listDelim,
+ l.percent,
+ l.zero,
+ l.minus,
+ l.plus,
+ l.exp,
+ l.quotationStart,
+ l.quotationEnd,
+ l.alternateQuotationStart,
+ l.alternateQuotationEnd,
+ list_pattern_part_data.append(l.listPatternPartStart),
+ list_pattern_part_data.append(l.listPatternPartMiddle),
+ list_pattern_part_data.append(l.listPatternPartEnd),
+ list_pattern_part_data.append(l.listPatternPartTwo),
+ date_format_data.append(l.shortDateFormat),
+ date_format_data.append(l.longDateFormat),
+ time_format_data.append(l.shortTimeFormat),
+ time_format_data.append(l.longTimeFormat),
+ standalone_months_data.append(l.standaloneShortMonths),
+ standalone_months_data.append(l.standaloneLongMonths),
+ standalone_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),
+ days_data.append(l.shortDays),
+ days_data.append(l.longDays),
+ days_data.append(l.narrowDays),
+ am_data.append(l.am),
+ pm_data.append(l.pm),
+ currencyIsoCodeData(l.currencyIsoCode),
+ currency_symbol_data.append(l.currencySymbol),
+ currency_display_name_data.append(l.currencyDisplayName),
+ currency_format_data.append(l.currencyFormat),
+ currency_format_data.append(l.currencyNegativeFormat),
+ endonyms_data.append(l.languageEndonym),
+ endonyms_data.append(l.countryEndonym),
+ l.currencyDigits,
+ l.currencyRounding,
+ l.firstDayOfWeek,
+ l.weekendStart,
+ l.weekendEnd,
+ l.language,
+ l.script,
+ l.country))
+ data_temp_file.write(" { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, {0,0,0}, 0,0, 0,0, 0,0, 0,0, 0, 0, 0, 0, 0, 0,0, 0,0 } // trailing 0s\n")
+ data_temp_file.write("};\n")
+
+ data_temp_file.write("\n")
+
+ # List patterns data
+ #check_static_char_array_length("list_pattern_part", list_pattern_part_data.data)
+ data_temp_file.write("static const ushort list_pattern_part_data[] = {\n")
+ data_temp_file.write(wrap_list(list_pattern_part_data.data))
+ data_temp_file.write("\n};\n")
+
+ data_temp_file.write("\n")
+
+ # Date format data
+ #check_static_char_array_length("date_format", date_format_data.data)
+ data_temp_file.write("static const ushort date_format_data[] = {\n")
+ data_temp_file.write(wrap_list(date_format_data.data))
+ data_temp_file.write("\n};\n")
+
+ data_temp_file.write("\n")
+
+ # Time format data
+ #check_static_char_array_length("time_format", time_format_data.data)
+ data_temp_file.write("static const ushort time_format_data[] = {\n")
+ data_temp_file.write(wrap_list(time_format_data.data))
+ data_temp_file.write("\n};\n")
+
+ data_temp_file.write("\n")
+
+ # Months data
+ #check_static_char_array_length("months", months_data.data)
+ data_temp_file.write("static const ushort months_data[] = {\n")
+ data_temp_file.write(wrap_list(months_data.data))
+ data_temp_file.write("\n};\n")
+
+ data_temp_file.write("\n")
+
+ # Standalone months data
+ #check_static_char_array_length("standalone_months", standalone_months_data.data)
+ data_temp_file.write("static const ushort standalone_months_data[] = {\n")
+ data_temp_file.write(wrap_list(standalone_months_data.data))
+ data_temp_file.write("\n};\n")
+
+ data_temp_file.write("\n")
+
+ # Days data
+ #check_static_char_array_length("days", days_data.data)
+ data_temp_file.write("static const ushort days_data[] = {\n")
+ data_temp_file.write(wrap_list(days_data.data))
+ data_temp_file.write("\n};\n")
+
+ data_temp_file.write("\n")
+
+ # AM data
+ #check_static_char_array_length("am", am_data.data)
+ data_temp_file.write("static const ushort am_data[] = {\n")
+ data_temp_file.write(wrap_list(am_data.data))
+ data_temp_file.write("\n};\n")
+
+ data_temp_file.write("\n")
+
+ # PM data
+ #check_static_char_array_length("pm", am_data.data)
+ data_temp_file.write("static const ushort pm_data[] = {\n")
+ data_temp_file.write(wrap_list(pm_data.data))
+ data_temp_file.write("\n};\n")
+
+ data_temp_file.write("\n")
+
+ # Currency symbol data
+ #check_static_char_array_length("currency_symbol", currency_symbol_data.data)
+ data_temp_file.write("static const ushort currency_symbol_data[] = {\n")
+ data_temp_file.write(wrap_list(currency_symbol_data.data))
+ data_temp_file.write("\n};\n")
+
+ data_temp_file.write("\n")
+
+ # Currency display name data
+ #check_static_char_array_length("currency_display_name", currency_display_name_data.data)
+ data_temp_file.write("static const ushort currency_display_name_data[] = {\n")
+ data_temp_file.write(wrap_list(currency_display_name_data.data))
+ data_temp_file.write("\n};\n")
+
+ data_temp_file.write("\n")
+
+ # Currency format data
+ #check_static_char_array_length("currency_format", currency_format_data.data)
+ data_temp_file.write("static const ushort currency_format_data[] = {\n")
+ data_temp_file.write(wrap_list(currency_format_data.data))
+ data_temp_file.write("\n};\n")
+
+ # Endonyms data
+ #check_static_char_array_length("endonyms", endonyms_data.data)
+ data_temp_file.write("static const ushort endonyms_data[] = {\n")
+ data_temp_file.write(wrap_list(endonyms_data.data))
+ data_temp_file.write("\n};\n")
+
+ data_temp_file.write("\n")
+
+ # Language name list
+ data_temp_file.write("static const char language_name_list[] =\n")
+ data_temp_file.write("\"Default\\0\"\n")
+ for key in language_map.keys():
+ if key == 0:
+ continue
+ data_temp_file.write("\"" + language_map[key][0] + "\\0\"\n")
+ data_temp_file.write(";\n")
+
+ data_temp_file.write("\n")
+
+ # Language name index
+ data_temp_file.write("static const quint16 language_name_index[] = {\n")
+ data_temp_file.write(" 0, // AnyLanguage\n")
+ index = 8
+ for key in language_map.keys():
+ if key == 0:
+ continue
+ language = language_map[key][0]
+ data_temp_file.write("%6d, // %s\n" % (index, language))
+ index += len(language) + 1
+ data_temp_file.write("};\n")
+
+ data_temp_file.write("\n")
+
+ # Script name list
+ data_temp_file.write("static const char script_name_list[] =\n")
+ data_temp_file.write("\"Default\\0\"\n")
+ for key in script_map.keys():
+ if key == 0:
+ continue
+ data_temp_file.write("\"" + script_map[key][0] + "\\0\"\n")
+ data_temp_file.write(";\n")
+
+ data_temp_file.write("\n")
+
+ # Script name index
+ data_temp_file.write("static const quint16 script_name_index[] = {\n")
+ data_temp_file.write(" 0, // AnyScript\n")
+ index = 8
+ for key in script_map.keys():
+ if key == 0:
+ continue
+ script = script_map[key][0]
+ data_temp_file.write("%6d, // %s\n" % (index, script))
+ index += len(script) + 1
+ data_temp_file.write("};\n")
+
+ data_temp_file.write("\n")
+
+ # Country name list
+ data_temp_file.write("static const char country_name_list[] =\n")
+ data_temp_file.write("\"Default\\0\"\n")
+ for key in country_map.keys():
+ if key == 0:
+ continue
+ data_temp_file.write("\"" + country_map[key][0] + "\\0\"\n")
+ data_temp_file.write(";\n")
+
+ data_temp_file.write("\n")
+
+ # Country name index
+ data_temp_file.write("static const quint16 country_name_index[] = {\n")
+ data_temp_file.write(" 0, // AnyCountry\n")
+ index = 8
+ for key in country_map.keys():
+ if key == 0:
+ continue
+ country = country_map[key][0]
+ data_temp_file.write("%6d, // %s\n" % (index, country))
+ index += len(country) + 1
+ data_temp_file.write("};\n")
+
+ data_temp_file.write("\n")
+
+ # Language code list
+ data_temp_file.write("static const unsigned char language_code_list[] =\n")
+ for key in language_map.keys():
+ code = language_map[key][1]
+ if len(code) == 2:
+ code += r"\0"
+ data_temp_file.write("\"%2s\" // %s\n" % (code, language_map[key][0]))
+ data_temp_file.write(";\n")
+
+ data_temp_file.write("\n")
+
+ # Script code list
+ data_temp_file.write("static const unsigned char script_code_list[] =\n")
+ for key in script_map.keys():
+ code = script_map[key][1]
+ for i in range(4 - len(code)):
+ code += "\\0"
+ data_temp_file.write("\"%2s\" // %s\n" % (code, script_map[key][0]))
+ data_temp_file.write(";\n")
+
+ # Country code list
+ data_temp_file.write("static const unsigned char country_code_list[] =\n")
+ for key in country_map.keys():
+ code = country_map[key][1]
+ if len(code) == 2:
+ code += "\\0"
+ data_temp_file.write("\"%2s\" // %s\n" % (code, country_map[key][0]))
+ data_temp_file.write(";\n")
+
+ data_temp_file.write("\n")
+ data_temp_file.write(GENERATED_BLOCK_END)
+ s = qlocaledata_file.readline()
+ # skip until end of the block
+ while s and s != GENERATED_BLOCK_END:
+ s = qlocaledata_file.readline()
+
+ s = qlocaledata_file.readline()
+ while s:
+ data_temp_file.write(s)
+ s = qlocaledata_file.readline()
+ data_temp_file.close()
+ qlocaledata_file.close()
+
+ os.rename(data_temp_file_path, qtsrcdir + "/src/corelib/tools/qlocale_data_p.h")
+
+ # 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")
+ s = qlocaleh_file.readline()
+ while s and s != GENERATED_BLOCK_START:
+ qlocaleh_temp_file.write(s)
+ s = qlocaleh_file.readline()
+ qlocaleh_temp_file.write(GENERATED_BLOCK_START)
+ qlocaleh_temp_file.write("// see qlocale_data_p.h for more info on generated data\n")
+
+ # Language enum
+ qlocaleh_temp_file.write(" enum Language {\n")
+ language = ""
+ for key in language_map.keys():
+ language = fixedLanguageName(language_map[key][0], dupes)
+ qlocaleh_temp_file.write(" " + language + " = " + str(key) + ",\n")
+ # special cases for norwegian. we really need to make it right at some point.
+ qlocaleh_temp_file.write(" NorwegianBokmal = Norwegian,\n")
+ qlocaleh_temp_file.write(" NorwegianNynorsk = Nynorsk,\n")
+ qlocaleh_temp_file.write(" LastLanguage = " + language + "\n")
+ qlocaleh_temp_file.write(" };\n")
+
+ qlocaleh_temp_file.write("\n")
+
+ # Script enum
+ qlocaleh_temp_file.write(" enum Script {\n")
+ script = ""
+ for key in script_map.keys():
+ script = fixedScriptName(script_map[key][0], dupes)
+ qlocaleh_temp_file.write(" " + script + " = " + str(key) + ",\n")
+ qlocaleh_temp_file.write(" SimplifiedChineseScript = SimplifiedHanScript,\n")
+ qlocaleh_temp_file.write(" TraditionalChineseScript = TraditionalHanScript,\n")
+ qlocaleh_temp_file.write(" LastScript = " + script + "\n")
+ qlocaleh_temp_file.write(" };\n")
+
+ # Country enum
+ qlocaleh_temp_file.write(" enum Country {\n")
+ country = ""
+ for key in country_map.keys():
+ country = fixedCountryName(country_map[key][0], dupes)
+ qlocaleh_temp_file.write(" " + country + " = " + str(key) + ",\n")
+ qlocaleh_temp_file.write(" LastCountry = " + country + "\n")
+ qlocaleh_temp_file.write(" };\n")
+
+ qlocaleh_temp_file.write(GENERATED_BLOCK_END)
+ s = qlocaleh_file.readline()
+ # skip until end of the block
+ while s and s != GENERATED_BLOCK_END:
+ s = qlocaleh_file.readline()
+
+ s = qlocaleh_file.readline()
+ while s:
+ qlocaleh_temp_file.write(s)
+ s = qlocaleh_file.readline()
+ qlocaleh_temp_file.close()
+ qlocaleh_file.close()
+
+ os.rename(qlocaleh_temp_file_path, qtsrcdir + "/src/corelib/tools/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")
+ s = qlocaleqdoc_file.readline()
+ DOCSTRING=" QLocale's data is based on Common Locale Data Repository "
+ while s:
+ if DOCSTRING in s:
+ qlocaleqdoc_temp_file.write(DOCSTRING + "v" + cldr_version + ".\n")
+ else:
+ qlocaleqdoc_temp_file.write(s)
+ s = qlocaleqdoc_file.readline()
+ qlocaleqdoc_temp_file.close()
+ qlocaleqdoc_file.close()
+
+ os.rename(qlocaleqdoc_temp_file_path, qtsrcdir + "/src/corelib/tools/qlocale.qdoc")
+
+if __name__ == "__main__":
+ main()
diff --git a/util/local_database/testlocales/localemodel.cpp b/util/local_database/testlocales/localemodel.cpp
new file mode 100644
index 0000000000..c1916fc11e
--- /dev/null
+++ b/util/local_database/testlocales/localemodel.cpp
@@ -0,0 +1,462 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "localemodel.h"
+
+#include <QLocale>
+#include <QDate>
+#include <qdebug.h>
+
+static const int g_model_cols = 6;
+
+struct LocaleListItem
+{
+ int language;
+ int country;
+};
+
+const LocaleListItem g_locale_list[] = {
+ { 1, 0 }, // C/AnyCountry
+ { 3, 69 }, // Afan/Ethiopia
+ { 3, 111 }, // Afan/Kenya
+ { 4, 59 }, // Afar/Djibouti
+ { 4, 67 }, // Afar/Eritrea
+ { 4, 69 }, // Afar/Ethiopia
+ { 5, 195 }, // Afrikaans/SouthAfrica
+ { 5, 148 }, // Afrikaans/Namibia
+ { 6, 2 }, // Albanian/Albania
+ { 7, 69 }, // Amharic/Ethiopia
+ { 8, 186 }, // Arabic/SaudiArabia
+ { 8, 3 }, // Arabic/Algeria
+ { 8, 17 }, // Arabic/Bahrain
+ { 8, 64 }, // Arabic/Egypt
+ { 8, 103 }, // Arabic/Iraq
+ { 8, 109 }, // Arabic/Jordan
+ { 8, 115 }, // Arabic/Kuwait
+ { 8, 119 }, // Arabic/Lebanon
+ { 8, 122 }, // Arabic/LibyanArabJamahiriya
+ { 8, 145 }, // Arabic/Morocco
+ { 8, 162 }, // Arabic/Oman
+ { 8, 175 }, // Arabic/Qatar
+ { 8, 201 }, // Arabic/Sudan
+ { 8, 207 }, // Arabic/SyrianArabRepublic
+ { 8, 216 }, // Arabic/Tunisia
+ { 8, 223 }, // Arabic/UnitedArabEmirates
+ { 8, 237 }, // Arabic/Yemen
+ { 9, 11 }, // Armenian/Armenia
+ { 10, 100 }, // Assamese/India
+ { 12, 15 }, // Azerbaijani/Azerbaijan
+ { 14, 197 }, // Basque/Spain
+ { 15, 18 }, // Bengali/Bangladesh
+ { 15, 100 }, // Bengali/India
+ { 16, 25 }, // Bhutani/Bhutan
+ { 20, 33 }, // Bulgarian/Bulgaria
+ { 22, 20 }, // Byelorussian/Belarus
+ { 23, 36 }, // Cambodian/Cambodia
+ { 24, 197 }, // Catalan/Spain
+ { 25, 44 }, // Chinese/China
+ { 25, 97 }, // Chinese/HongKong
+ { 25, 126 }, // Chinese/Macau
+ { 25, 190 }, // Chinese/Singapore
+ { 25, 208 }, // Chinese/Taiwan
+ { 27, 54 }, // Croatian/Croatia
+ { 28, 57 }, // Czech/CzechRepublic
+ { 29, 58 }, // Danish/Denmark
+ { 30, 151 }, // Dutch/Netherlands
+ { 30, 21 }, // Dutch/Belgium
+ { 31, 225 }, // English/UnitedStates
+ { 31, 4 }, // English/AmericanSamoa
+ { 31, 13 }, // English/Australia
+ { 31, 21 }, // English/Belgium
+ { 31, 22 }, // English/Belize
+ { 31, 28 }, // English/Botswana
+ { 31, 38 }, // English/Canada
+ { 31, 89 }, // English/Guam
+ { 31, 97 }, // English/HongKong
+ { 31, 100 }, // English/India
+ { 31, 104 }, // English/Ireland
+ { 31, 107 }, // English/Jamaica
+ { 31, 133 }, // English/Malta
+ { 31, 134 }, // English/MarshallIslands
+ { 31, 148 }, // English/Namibia
+ { 31, 154 }, // English/NewZealand
+ { 31, 160 }, // English/NorthernMarianaIslands
+ { 31, 163 }, // English/Pakistan
+ { 31, 170 }, // English/Philippines
+ { 31, 190 }, // English/Singapore
+ { 31, 195 }, // English/SouthAfrica
+ { 31, 215 }, // English/TrinidadAndTobago
+ { 31, 224 }, // English/UnitedKingdom
+ { 31, 226 }, // English/UnitedStatesMinorOutlyingIslands
+ { 31, 234 }, // English/USVirginIslands
+ { 31, 240 }, // English/Zimbabwe
+ { 33, 68 }, // Estonian/Estonia
+ { 34, 71 }, // Faroese/FaroeIslands
+ { 36, 73 }, // Finnish/Finland
+ { 37, 74 }, // French/France
+ { 37, 21 }, // French/Belgium
+ { 37, 38 }, // French/Canada
+ { 37, 125 }, // French/Luxembourg
+ { 37, 142 }, // French/Monaco
+ { 37, 206 }, // French/Switzerland
+ { 40, 197 }, // Galician/Spain
+ { 41, 81 }, // Georgian/Georgia
+ { 42, 82 }, // German/Germany
+ { 42, 14 }, // German/Austria
+ { 42, 21 }, // German/Belgium
+ { 42, 123 }, // German/Liechtenstein
+ { 42, 125 }, // German/Luxembourg
+ { 42, 206 }, // German/Switzerland
+ { 43, 85 }, // Greek/Greece
+ { 43, 56 }, // Greek/Cyprus
+ { 44, 86 }, // Greenlandic/Greenland
+ { 46, 100 }, // Gujarati/India
+ { 47, 83 }, // Hausa/Ghana
+ { 47, 156 }, // Hausa/Niger
+ { 47, 157 }, // Hausa/Nigeria
+ { 48, 105 }, // Hebrew/Israel
+ { 49, 100 }, // Hindi/India
+ { 50, 98 }, // Hungarian/Hungary
+ { 51, 99 }, // Icelandic/Iceland
+ { 52, 101 }, // Indonesian/Indonesia
+ { 57, 104 }, // Irish/Ireland
+ { 58, 106 }, // Italian/Italy
+ { 58, 206 }, // Italian/Switzerland
+ { 59, 108 }, // Japanese/Japan
+ { 61, 100 }, // Kannada/India
+ { 63, 110 }, // Kazakh/Kazakhstan
+ { 64, 179 }, // Kinyarwanda/Rwanda
+ { 65, 116 }, // Kirghiz/Kyrgyzstan
+ { 66, 114 }, // Korean/RepublicOfKorea
+ { 67, 102 }, // Kurdish/Iran
+ { 67, 103 }, // Kurdish/Iraq
+ { 67, 207 }, // Kurdish/SyrianArabRepublic
+ { 67, 217 }, // Kurdish/Turkey
+ { 69, 117 }, // Laothian/Lao
+ { 71, 118 }, // Latvian/Latvia
+ { 72, 49 }, // Lingala/DemocraticRepublicOfCongo
+ { 72, 50 }, // Lingala/PeoplesRepublicOfCongo
+ { 73, 124 }, // Lithuanian/Lithuania
+ { 74, 127 }, // Macedonian/Macedonia
+ { 76, 130 }, // Malay/Malaysia
+ { 76, 32 }, // Malay/BruneiDarussalam
+ { 77, 100 }, // Malayalam/India
+ { 78, 133 }, // Maltese/Malta
+ { 80, 100 }, // Marathi/India
+ { 82, 143 }, // Mongolian/Mongolia
+ { 84, 150 }, // Nepali/Nepal
+ { 85, 161 }, // Norwegian/Norway
+ { 87, 100 }, // Oriya/India
+ { 88, 1 }, // Pashto/Afghanistan
+ { 89, 102 }, // Persian/Iran
+ { 89, 1 }, // Persian/Afghanistan
+ { 90, 172 }, // Polish/Poland
+ { 91, 173 }, // Portuguese/Portugal
+ { 91, 30 }, // Portuguese/Brazil
+ { 92, 100 }, // Punjabi/India
+ { 92, 163 }, // Punjabi/Pakistan
+ { 95, 177 }, // Romanian/Romania
+ { 96, 178 }, // Russian/RussianFederation
+ { 96, 222 }, // Russian/Ukraine
+ { 99, 100 }, // Sanskrit/India
+ { 100, 241 }, // Serbian/SerbiaAndMontenegro
+ { 100, 27 }, // Serbian/BosniaAndHerzegowina
+ { 100, 238 }, // Serbian/Yugoslavia
+ { 101, 241 }, // SerboCroatian/SerbiaAndMontenegro
+ { 101, 27 }, // SerboCroatian/BosniaAndHerzegowina
+ { 101, 238 }, // SerboCroatian/Yugoslavia
+ { 102, 195 }, // Sesotho/SouthAfrica
+ { 103, 195 }, // Setswana/SouthAfrica
+ { 107, 195 }, // Siswati/SouthAfrica
+ { 108, 191 }, // Slovak/Slovakia
+ { 109, 192 }, // Slovenian/Slovenia
+ { 110, 194 }, // Somali/Somalia
+ { 110, 59 }, // Somali/Djibouti
+ { 110, 69 }, // Somali/Ethiopia
+ { 110, 111 }, // Somali/Kenya
+ { 111, 197 }, // Spanish/Spain
+ { 111, 10 }, // Spanish/Argentina
+ { 111, 26 }, // Spanish/Bolivia
+ { 111, 43 }, // Spanish/Chile
+ { 111, 47 }, // Spanish/Colombia
+ { 111, 52 }, // Spanish/CostaRica
+ { 111, 61 }, // Spanish/DominicanRepublic
+ { 111, 63 }, // Spanish/Ecuador
+ { 111, 65 }, // Spanish/ElSalvador
+ { 111, 90 }, // Spanish/Guatemala
+ { 111, 96 }, // Spanish/Honduras
+ { 111, 139 }, // Spanish/Mexico
+ { 111, 155 }, // Spanish/Nicaragua
+ { 111, 166 }, // Spanish/Panama
+ { 111, 168 }, // Spanish/Paraguay
+ { 111, 169 }, // Spanish/Peru
+ { 111, 174 }, // Spanish/PuertoRico
+ { 111, 225 }, // Spanish/UnitedStates
+ { 111, 227 }, // Spanish/Uruguay
+ { 111, 231 }, // Spanish/Venezuela
+ { 113, 111 }, // Swahili/Kenya
+ { 113, 210 }, // Swahili/Tanzania
+ { 114, 205 }, // Swedish/Sweden
+ { 114, 73 }, // Swedish/Finland
+ { 116, 209 }, // Tajik/Tajikistan
+ { 117, 100 }, // Tamil/India
+ { 118, 178 }, // Tatar/RussianFederation
+ { 119, 100 }, // Telugu/India
+ { 120, 211 }, // Thai/Thailand
+ { 122, 67 }, // Tigrinya/Eritrea
+ { 122, 69 }, // Tigrinya/Ethiopia
+ { 124, 195 }, // Tsonga/SouthAfrica
+ { 125, 217 }, // Turkish/Turkey
+ { 129, 222 }, // Ukrainian/Ukraine
+ { 130, 100 }, // Urdu/India
+ { 130, 163 }, // Urdu/Pakistan
+ { 131, 228 }, // Uzbek/Uzbekistan
+ { 131, 1 }, // Uzbek/Afghanistan
+ { 132, 232 }, // Vietnamese/VietNam
+ { 134, 224 }, // Welsh/UnitedKingdom
+ { 136, 195 }, // Xhosa/SouthAfrica
+ { 138, 157 }, // Yoruba/Nigeria
+ { 140, 195 }, // Zulu/SouthAfrica
+ { 141, 161 }, // Nynorsk/Norway
+ { 142, 27 }, // Bosnian/BosniaAndHerzegowina
+ { 143, 131 }, // Divehi/Maldives
+ { 144, 224 }, // Manx/UnitedKingdom
+ { 145, 224 }, // Cornish/UnitedKingdom
+ { 146, 83 }, // Akan/Ghana
+ { 147, 100 }, // Konkani/India
+ { 148, 83 }, // Ga/Ghana
+ { 149, 157 }, // Igbo/Nigeria
+ { 150, 111 }, // Kamba/Kenya
+ { 151, 207 }, // Syriac/SyrianArabRepublic
+ { 152, 67 }, // Blin/Eritrea
+ { 153, 67 }, // Geez/Eritrea
+ { 153, 69 }, // Geez/Ethiopia
+ { 154, 157 }, // Koro/Nigeria
+ { 155, 69 }, // Sidamo/Ethiopia
+ { 156, 157 }, // Atsam/Nigeria
+ { 157, 67 }, // Tigre/Eritrea
+ { 158, 157 }, // Jju/Nigeria
+ { 159, 106 }, // Friulian/Italy
+ { 160, 195 }, // Venda/SouthAfrica
+ { 161, 83 }, // Ewe/Ghana
+ { 161, 212 }, // Ewe/Togo
+ { 163, 225 }, // Hawaiian/UnitedStates
+ { 164, 157 }, // Tyap/Nigeria
+ { 165, 129 }, // Chewa/Malawi
+};
+static const int g_locale_list_count = sizeof(g_locale_list)/sizeof(g_locale_list[0]);
+
+LocaleModel::LocaleModel(QObject *parent)
+ : QAbstractItemModel(parent)
+{
+ m_data_list.append(1234.5678);
+ m_data_list.append(QDate::currentDate());
+ m_data_list.append(QDate::currentDate());
+ m_data_list.append(QTime::currentTime());
+ m_data_list.append(QTime::currentTime());
+}
+
+QVariant LocaleModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid()
+ || role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::ToolTipRole
+ || index.column() >= g_model_cols
+ || index.row() >= g_locale_list_count + 2)
+ return QVariant();
+
+ QVariant data;
+ if (index.column() < g_model_cols - 1)
+ data = m_data_list.at(index.column());
+
+ if (index.row() == 0) {
+ if (role == Qt::ToolTipRole)
+ return QVariant();
+ switch (index.column()) {
+ case 0:
+ return data.toDouble();
+ case 1:
+ return data.toDate();
+ case 2:
+ return data.toDate();
+ case 3:
+ return data.toTime();
+ case 4:
+ return data.toTime();
+ case 5:
+ return QVariant();
+ default:
+ break;
+ }
+ } else {
+ QLocale locale;
+ if (index.row() == 1) {
+ locale = QLocale::system();
+ } else {
+ LocaleListItem item = g_locale_list[index.row() - 2];
+ locale = QLocale((QLocale::Language)item.language, (QLocale::Country)item.country);
+ }
+
+ switch (index.column()) {
+ case 0:
+ if (role == Qt::ToolTipRole)
+ return QVariant();
+ return locale.toString(data.toDouble());
+ case 1:
+ if (role == Qt::ToolTipRole)
+ return locale.dateFormat(QLocale::LongFormat);
+ return locale.toString(data.toDate(), QLocale::LongFormat);
+ case 2:
+ if (role == Qt::ToolTipRole)
+ return locale.dateFormat(QLocale::ShortFormat);
+ return locale.toString(data.toDate(), QLocale::ShortFormat);
+ case 3:
+ if (role == Qt::ToolTipRole)
+ return locale.timeFormat(QLocale::LongFormat);
+ return locale.toString(data.toTime(), QLocale::LongFormat);
+ case 4:
+ if (role == Qt::ToolTipRole)
+ return locale.timeFormat(QLocale::ShortFormat);
+ return locale.toString(data.toTime(), QLocale::ShortFormat);
+ case 5:
+ if (role == Qt::ToolTipRole)
+ return QVariant();
+ return locale.name();
+ default:
+ break;
+ }
+ }
+
+ return QVariant();
+}
+
+QVariant LocaleModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ if (orientation == Qt::Horizontal) {
+ switch (section) {
+ case 0:
+ return QLatin1String("Double");
+ case 1:
+ return QLatin1String("Long Date");
+ case 2:
+ return QLatin1String("Short Date");
+ case 3:
+ return QLatin1String("Long Time");
+ case 4:
+ return QLatin1String("Short Time");
+ case 5:
+ return QLatin1String("Name");
+ default:
+ break;
+ }
+ } else {
+ if (section >= g_locale_list_count + 2)
+ return QVariant();
+ if (section == 0) {
+ return QLatin1String("Input");
+ } else if (section == 1) {
+ return QLatin1String("System");
+ } else {
+ LocaleListItem item = g_locale_list[section - 2];
+ return QLocale::languageToString((QLocale::Language)item.language)
+ + QLatin1Char('/')
+ + QLocale::countryToString((QLocale::Country)item.country);
+ }
+ }
+
+ return QVariant();
+}
+
+QModelIndex LocaleModel::index(int row, int column,
+ const QModelIndex &parent) const
+{
+ if (parent.isValid()
+ || row >= g_locale_list_count + 2
+ || column >= g_model_cols)
+ return QModelIndex();
+
+ return createIndex(row, column);
+}
+
+QModelIndex LocaleModel::parent(const QModelIndex&) const
+{
+ return QModelIndex();
+}
+
+int LocaleModel::columnCount(const QModelIndex&) const
+{
+ return g_model_cols;
+}
+
+int LocaleModel::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
+ return g_locale_list_count + 2;
+}
+
+Qt::ItemFlags LocaleModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return 0;
+ if (index.row() == 0 && index.column() == g_model_cols - 1)
+ return 0;
+ if (index.row() == 0)
+ return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
+ return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+}
+
+bool LocaleModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (!index.isValid()
+ || index.row() != 0
+ || index.column() >= g_model_cols - 1
+ || role != Qt::EditRole
+ || m_data_list.at(index.column()).type() != value.type())
+ return false;
+
+ m_data_list[index.column()] = value;
+ emit dataChanged(createIndex(1, index.column()),
+ createIndex(g_locale_list_count, index.column()));
+
+ return true;
+}
diff --git a/util/local_database/testlocales/localemodel.h b/util/local_database/testlocales/localemodel.h
new file mode 100644
index 0000000000..9e569f7f09
--- /dev/null
+++ b/util/local_database/testlocales/localemodel.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef LOCALEMODEL_H
+#define LOCALEMODEL_H
+
+#include <QAbstractItemModel>
+#include <QList>
+#include <QVariant>
+
+class LocaleModel : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ LocaleModel(QObject *parent = 0);
+
+ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ virtual QModelIndex index(int row, int column,
+ const QModelIndex &parent = QModelIndex()) const;
+ virtual QModelIndex parent(const QModelIndex &index) const;
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole ) const;
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
+ virtual bool setData(const QModelIndex &index, const QVariant &value,
+ int role = Qt::EditRole);
+private:
+ QList<QVariant> m_data_list;
+};
+
+#endif // LOCALEMODEL_H
diff --git a/util/local_database/testlocales/localewidget.cpp b/util/local_database/testlocales/localewidget.cpp
new file mode 100644
index 0000000000..d20868f51b
--- /dev/null
+++ b/util/local_database/testlocales/localewidget.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QTableView>
+#include <QVBoxLayout>
+#include <QItemDelegate>
+#include <QItemEditorFactory>
+#include <QDoubleSpinBox>
+
+#include "localewidget.h"
+#include "localemodel.h"
+
+class DoubleEditorCreator : public QItemEditorCreatorBase
+{
+public:
+ QWidget *createWidget(QWidget *parent) const {
+ QDoubleSpinBox *w = new QDoubleSpinBox(parent);
+ w->setDecimals(4);
+ w->setRange(-10000.0, 10000.0);
+ return w;
+ }
+ virtual QByteArray valuePropertyName() const {
+ return QByteArray("value");
+ }
+};
+
+class EditorFactory : public QItemEditorFactory
+{
+public:
+ EditorFactory() {
+ static DoubleEditorCreator double_editor_creator;
+ registerEditor(QVariant::Double, &double_editor_creator);
+ }
+};
+
+LocaleWidget::LocaleWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ m_model = new LocaleModel(this);
+ m_view = new QTableView(this);
+
+ QItemDelegate *delegate = qobject_cast<QItemDelegate*>(m_view->itemDelegate());
+ Q_ASSERT(delegate != 0);
+ static EditorFactory editor_factory;
+ delegate->setItemEditorFactory(&editor_factory);
+
+ m_view->setModel(m_model);
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->setMargin(0);
+ layout->addWidget(m_view);
+}
diff --git a/util/local_database/testlocales/localewidget.h b/util/local_database/testlocales/localewidget.h
new file mode 100644
index 0000000000..b119db043c
--- /dev/null
+++ b/util/local_database/testlocales/localewidget.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef LOCALEWIDGET_H
+#define LOCALEWIDGET_H
+
+#include <QWidget>
+
+class LocaleModel;
+class QTableView;
+
+class LocaleWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ LocaleWidget(QWidget *parent = 0);
+private:
+ LocaleModel *m_model;
+ QTableView *m_view;
+};
+
+#endif // LOCALEWIDGET_H
diff --git a/util/local_database/testlocales/main.cpp b/util/local_database/testlocales/main.cpp
new file mode 100644
index 0000000000..08aacd549f
--- /dev/null
+++ b/util/local_database/testlocales/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QApplication>
+
+#include "localewidget.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ LocaleWidget wgt;
+ wgt.show();
+ return app.exec();
+}
diff --git a/util/local_database/testlocales/testlocales.pro b/util/local_database/testlocales/testlocales.pro
new file mode 100644
index 0000000000..a9a6247f96
--- /dev/null
+++ b/util/local_database/testlocales/testlocales.pro
@@ -0,0 +1,4 @@
+TARGET = testlocales
+CONFIG += debug
+SOURCES += localemodel.cpp localewidget.cpp main.cpp
+HEADERS += localemodel.h localewidget.h \ No newline at end of file
diff --git a/util/local_database/xpathlite.py b/util/local_database/xpathlite.py
new file mode 100644
index 0000000000..502d85d33a
--- /dev/null
+++ b/util/local_database/xpathlite.py
@@ -0,0 +1,249 @@
+#!/usr/bin/env python
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## No Commercial Usage
+## This file contains pre-release code and may not be distributed.
+## You may use this file in accordance with the terms and conditions
+## contained in the Technology Preview License Agreement accompanying
+## this package.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Nokia gives you certain additional
+## rights. These rights are described in the Nokia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import sys
+import os
+import xml.dom.minidom
+
+doc_cache = {}
+
+class DraftResolution:
+ # See http://www.unicode.org/cldr/process.html for description
+ unconfirmed = 'unconfirmed'
+ provisional = 'provisional'
+ contributed = 'contributed'
+ approved = 'approved'
+ _values = { unconfirmed : 1, provisional : 2, contributed : 3, approved : 4 }
+ def __init__(self, resolution):
+ self.resolution = resolution
+ def toInt(self):
+ return DraftResolution._values[self.resolution]
+
+class Error:
+ def __init__(self, msg):
+ self.msg = msg
+ def __str__(self):
+ return self.msg
+
+def findChild(parent, tag_name, arg_name=None, arg_value=None, draft=None):
+ for node in parent.childNodes:
+ if node.nodeType != node.ELEMENT_NODE:
+ continue
+ if node.nodeName != tag_name:
+ continue
+ if arg_value:
+ if not node.attributes.has_key(arg_name):
+ continue
+ if node.attributes[arg_name].nodeValue != arg_value:
+ continue
+ if draft:
+ if not node.attributes.has_key('draft'):
+ # if draft is not specified then it's approved
+ return node
+ value = node.attributes['draft'].nodeValue
+ value = DraftResolution(value).toInt()
+ exemplar = DraftResolution(draft).toInt()
+ if exemplar > value:
+ continue
+ return node
+ return False
+
+def findTagsInFile(file, path):
+ doc = False
+ if doc_cache.has_key(file):
+ doc = doc_cache[file]
+ else:
+ doc = xml.dom.minidom.parse(file)
+ doc_cache[file] = doc
+
+ 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]
+ tag_name = tag_spec
+ arg_name = 'type'
+ arg_value = ''
+ left_bracket = tag_spec.find('[')
+ if left_bracket != -1:
+ tag_name = tag_spec[:left_bracket]
+ arg_value = tag_spec[left_bracket+1:-1].split("=")
+ if len(arg_value) == 2:
+ arg_name = arg_value[0]
+ arg_value = arg_value[1]
+ else:
+ arg_value = arg_value[0]
+ elt = findChild(elt, tag_name, arg_name, arg_value)
+ if not elt:
+ return None
+ ret = []
+ if elt.childNodes:
+ for node in elt.childNodes:
+ if node.attributes:
+ element = [node.nodeName, None]
+ element[1] = node.attributes.items()
+ ret.append(element)
+ else:
+ if elt.attributes:
+ element = [elt.nodeName, None]
+ element[1] = elt.attributes.items()
+ ret.append(element)
+ return ret
+
+def _findEntryInFile(file, path, draft=None, attribute=None):
+ doc = False
+ if doc_cache.has_key(file):
+ doc = doc_cache[file]
+ else:
+ doc = xml.dom.minidom.parse(file)
+ doc_cache[file] = doc
+
+ 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]
+ tag_name = tag_spec
+ arg_name = 'type'
+ arg_value = ''
+ left_bracket = tag_spec.find('[')
+ if left_bracket != -1:
+ tag_name = tag_spec[:left_bracket]
+ arg_value = tag_spec[left_bracket+1:-1].split("=")
+ if len(arg_value) == 2:
+ arg_name = arg_value[0]
+ arg_value = arg_value[1]
+ else:
+ arg_value = arg_value[0]
+ alias = findChild(elt, 'alias')
+ if alias and alias.attributes['source'].nodeValue == 'locale':
+ path = alias.attributes['path'].nodeValue
+ aliaspath = tag_spec_list[:i] + path.split("/")
+ def resolve(x, y):
+ if y == '..':
+ return x[:-1]
+ return x + [y]
+ # resolve all dot-dot parts of the path
+ aliaspath = reduce(resolve, aliaspath, [])
+ # remove attribute specification that our xpathlite doesnt support
+ aliaspath = map(lambda x: x.replace("@type=", "").replace("'", ""), aliaspath)
+ # append the remaining path
+ aliaspath = aliaspath + tag_spec_list[i:]
+ aliaspath = "/".join(aliaspath)
+ # "locale" aliases are special - we need to start lookup from scratch
+ return (None, aliaspath)
+ elt = findChild(elt, tag_name, arg_name, arg_value, draft)
+ if not elt:
+ return ("", None)
+ if attribute is not None:
+ if elt.attributes.has_key(attribute):
+ return (elt.attributes[attribute].nodeValue, None)
+ return (None, None)
+ return (elt.firstChild.nodeValue, None)
+
+def findAlias(file):
+ if not doc_cache.has_key(file):
+ return False
+ doc = doc_cache[file]
+ alias_elt = findChild(doc.documentElement, "alias")
+ if not alias_elt:
+ return False
+ if not alias_elt.attributes.has_key('source'):
+ return False
+ return alias_elt.attributes['source'].nodeValue
+
+def _findEntry(base, path, draft=None, attribute=None):
+ file = base
+ if base.endswith(".xml"):
+ filename = base
+ base = base[:-4]
+ else:
+ file = base + ".xml"
+ (dirname, filename) = os.path.split(base)
+ items = filename.split("_")
+ # split locale name into items and iterate through them from back to front
+ # example: az_Latn_AZ => [az_Latn_AZ, az_Latn, az]
+ items = reversed(map(lambda x: "_".join(items[:x+1]), range(len(items))))
+ for item in items:
+ file = dirname + "/" + item + ".xml"
+ if os.path.isfile(file):
+ alias = findAlias(file)
+ if alias:
+ # if alias is found we should follow it and stop processing current file
+ # see http://www.unicode.org/reports/tr35/#Common_Elements
+ aliasfile = os.path.dirname(file) + "/" + alias + ".xml"
+ if not os.path.isfile(aliasfile):
+ raise Error("findEntry: fatal error: found an alias '%s' to '%s', but the alias file couldnt be found" % (filename, alias))
+ # found an alias, recurse into parsing it
+ result = _findEntry(aliasfile, path, draft, attribute)
+ return result
+ (result, aliaspath) = _findEntryInFile(file, path, draft, attribute)
+ if aliaspath:
+ # start lookup again because of the alias source="locale"
+ return _findEntry(base, aliaspath, draft, attribute)
+ if result:
+ return result
+ return None
+
+def findEntry(base, path, draft=None, attribute=None):
+ file = base
+ if base.endswith(".xml"):
+ file = base
+ base = base[:-4]
+ else:
+ file = base + ".xml"
+ (dirname, filename) = os.path.split(base)
+
+ result = None
+ while path:
+ result = _findEntry(base, path, draft, attribute)
+ if result:
+ return result
+ (result, aliaspath) = _findEntryInFile(dirname + "/root.xml", path, draft, attribute)
+ if result:
+ return result
+ if not aliaspath:
+ raise Error("findEntry: fatal error: %s: did not found key %s" % (filename, path))
+ path = aliaspath
+
+ return result
+
diff --git a/util/network/cookiejar-generateTLDs/cookiejar-generateTLDs.pro b/util/network/cookiejar-generateTLDs/cookiejar-generateTLDs.pro
new file mode 100644
index 0000000000..9d5f1cf7f9
--- /dev/null
+++ b/util/network/cookiejar-generateTLDs/cookiejar-generateTLDs.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+TARGET =
+DEPENDPATH += .
+INCLUDEPATH += .
+
+QT = core
+
+# Input
+SOURCES += main.cpp
diff --git a/util/network/cookiejar-generateTLDs/main.cpp b/util/network/cookiejar-generateTLDs/main.cpp
new file mode 100644
index 0000000000..5cdc97cd0c
--- /dev/null
+++ b/util/network/cookiejar-generateTLDs/main.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+
+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);
+ 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);
+ } 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 += "\"\"";
+ result += c;
+ }
+ }
+ return result;
+}
+
+int main(int argc, char **argv) {
+
+ QCoreApplication app(argc, argv);
+ if (argc < 3) {
+ printf("\nusage: %s inputFile outputFile\n\n", argv[0]);
+ printf("'inputFile' should be a list of effective TLDs, one per line,\n");
+ printf("as obtained from http://publicsuffix.org . To create indices and data file\n");
+ printf("file, do the following:\n\n");
+ printf(" wget http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1 -O effective_tld_names.dat\n");
+ printf(" grep '^[^\\/\\/]' effective_tld_names.dat > effective_tld_names.dat.trimmed\n");
+ printf(" %s effective_tld_names.dat.trimmed effective_tld_names.dat.qt\n\n", argv[0]);
+ printf("Now copy the data from effective_tld_names.dat.qt to the file src/network/access/qnetworkcookiejartlds_p.h in your Qt repo\n\n");
+ exit(1);
+ }
+ QFile file(argv[1]);
+ QFile outFile(argv[2]);
+ file.open(QIODevice::ReadOnly);
+ outFile.open(QIODevice::WriteOnly);
+
+ QByteArray outIndicesBufferBA;
+ QBuffer outIndicesBuffer(&outIndicesBufferBA);
+ outIndicesBuffer.open(QIODevice::WriteOnly);
+
+ QByteArray outDataBufferBA;
+ QBuffer outDataBuffer(&outDataBufferBA);
+ outDataBuffer.open(QIODevice::WriteOnly);
+
+ int lineCount = 0;
+ while (!file.atEnd()) {
+ file.readLine();
+ lineCount++;
+ }
+ file.reset();
+ QVector<QString> strings(lineCount);
+ while (!file.atEnd()) {
+ QString s = QString::fromUtf8(file.readLine());
+ QString st = s.trimmed();
+ int num = qHash(st) % lineCount;
+
+ 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("\"\"");
+
+ strings[num].append(utf8String);
+ strings[num].append("\\0");
+ }
+
+ outIndicesBuffer.write("static const quint16 tldCount = ");
+ outIndicesBuffer.write(QByteArray::number(lineCount));
+ outIndicesBuffer.write(";\n");
+ outIndicesBuffer.write("static const quint16 tldIndices[");
+// outIndicesBuffer.write(QByteArray::number(lineCount+1)); // not needed
+ outIndicesBuffer.write("] = {\n");
+
+ int utf8Size = 0;
+// int charSize = 0;
+ 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('"');
+ outDataBuffer.write(strings.at(a).toUtf8());
+ if (!lineIsEmpty)
+ outDataBuffer.write("\n");
+ outIndicesBuffer.write(QByteArray::number(utf8Size));
+ outIndicesBuffer.write(",\n");
+ utf8Size += strings.at(a).count() - (zeroCount + quoteCount + utf8CharsCount * 3);
+// charSize += strings.at(a).count();
+ }
+ outIndicesBuffer.write(QByteArray::number(utf8Size));
+ outIndicesBuffer.write("};\n");
+ outIndicesBuffer.close();
+ outFile.write(outIndicesBufferBA);
+
+ outDataBuffer.close();
+ outFile.write("\nstatic const char tldData[");
+// outFile.write(QByteArray::number(charSize)); // not needed
+ outFile.write("] = {\n");
+ outFile.write(outDataBufferBA);
+ outFile.write("};\n");
+ outFile.close();
+ printf("data generated to %s . Now copy the data from this file to src/network/access/qnetworkcookiejartlds_p.h in your Qt repo\n", argv[2]);
+ exit(0);
+}
diff --git a/util/plugintest/README b/util/plugintest/README
new file mode 100644
index 0000000000..2cd9c35927
--- /dev/null
+++ b/util/plugintest/README
@@ -0,0 +1,3 @@
+Attempts to load a Qt plugin, and shows the error message if the plugin could not be loaded.
+
+Use this tool to check why your database driver is not there, or why that style doesn't show.
diff --git a/util/plugintest/main.cpp b/util/plugintest/main.cpp
new file mode 100644
index 0000000000..dab9471115
--- /dev/null
+++ b/util/plugintest/main.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtCore/QtCore>
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ const QStringList args = app.arguments().mid(1);
+ if (args.isEmpty()) {
+ printf("Usage: ./plugintest libplugin.so...\nThis tool loads a plugin and displays whether QPluginLoader could load it or not.\nIf the plugin could not be loaded, it'll display the error string.\n");
+ return 1;
+ }
+
+ foreach (QString plugin, args) {
+ printf("%s: ", qPrintable(plugin));
+ QPluginLoader loader(plugin);
+ if (loader.load())
+ printf("success!\n");
+ else
+ printf("failure: %s\n", qPrintable(loader.errorString()));
+ }
+
+ return 0;
+}
+
diff --git a/util/plugintest/plugintest.pro b/util/plugintest/plugintest.pro
new file mode 100644
index 0000000000..94faf0387a
--- /dev/null
+++ b/util/plugintest/plugintest.pro
@@ -0,0 +1,4 @@
+TEMPLATE = app
+TARGET = plugintest
+SOURCES += main.cpp
+QT = core
diff --git a/util/s60pixelmetrics/bld.inf b/util/s60pixelmetrics/bld.inf
new file mode 100644
index 0000000000..90fe0818af
--- /dev/null
+++ b/util/s60pixelmetrics/bld.inf
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utility applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+PRJ_MMPFILES
+pm_mapper.mmp
+
+// End of File
diff --git a/util/s60pixelmetrics/pixel_metrics.cpp b/util/s60pixelmetrics/pixel_metrics.cpp
new file mode 100644
index 0000000000..bc05fd28aa
--- /dev/null
+++ b/util/s60pixelmetrics/pixel_metrics.cpp
@@ -0,0 +1,1255 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utility applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "pixel_metrics.h"
+
+#include <AknLayout2ScalableDef.h>
+#include <AknLayoutScalable_Avkon.cdl.h>
+#include <AknLayoutScalable_Apps.cdl.h>
+#include <AknUtils.h>
+
+// Version number for dynamic calculations. These are to be exported to static data,
+// so that we can keep dynamic and static values inline.
+// Please adjust version data if correcting dynamic PM calculations.
+const TInt KPMMajorVersion = 1;
+const TInt KPMMinorVersion = 19;
+
+TPixelMetricsVersion PixelMetrics::Version()
+ {
+ TPixelMetricsVersion version;
+ version.majorVersion = KPMMajorVersion;
+ version.minorVersion = KPMMinorVersion;
+ return version;
+ }
+
+TInt PixelMetrics::PixelMetricValue(QStyle::PixelMetric metric)
+ {
+ TInt value = -909;
+ // Main pane
+ TRect mainPaneRect;
+ AknLayoutUtils::LayoutMetricsRect(
+ AknLayoutUtils::EMainPane,
+ mainPaneRect );
+ // Screen
+ TRect screenRect;
+ AknLayoutUtils::LayoutMetricsRect(
+ AknLayoutUtils::EApplicationWindow,
+ screenRect );
+ // Navi pane
+ TRect naviPaneRect;
+ AknLayoutUtils::LayoutMetricsRect(
+ AknLayoutUtils::ENaviPane,
+ naviPaneRect );
+
+ TAknLayoutRect appWindow;
+ appWindow.LayoutRect( screenRect, AknLayoutScalable_Avkon::application_window(0) );
+
+ TInt variety = 0;
+ TBool landscape = EFalse;
+ if ( screenRect.iBr.iX > screenRect.iBr.iY )
+ {
+ // in landscape another variety is used
+ landscape = ETrue;
+ }
+ switch (metric)
+ {
+ case QStyle::PM_DockWidgetHandleExtent:
+ // what's this??? Not in S60
+ break;
+ case QStyle::PM_CheckListControllerSize:
+ case QStyle::PM_CheckListButtonSize:
+ {
+ // hierarchical menu - checkbox / radiobutton
+ // Area (width/height) of the checkbox/radio button in a Q3CheckListItem.
+ TAknLayoutRect listScrollPane;
+ listScrollPane.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::listscroll_gen_pane(0));
+ TAknLayoutRect listGenPane;
+ listGenPane.LayoutRect( listScrollPane.Rect(), AknLayoutScalable_Avkon::list_gen_pane(0));
+ TAknLayoutRect listHierarchyPane;
+ listHierarchyPane.LayoutRect( listGenPane.Rect(), AknLayoutScalable_Avkon::list_single_graphic_hl_pane(0));
+
+ TAknLayoutRect listHierarchyControllerPane;
+ listHierarchyPane.LayoutRect( listHierarchyPane.Rect(), AknLayoutScalable_Avkon::list_single_graphic_hl_pane_g3(0));
+ TAknLayoutRect listHierarchyPropertyPane;
+ listHierarchyPropertyPane.LayoutRect( listHierarchyPane.Rect(), AknLayoutScalable_Avkon::list_single_graphic_hl_pane_g2(0));
+
+ if (metric==QStyle::PM_CheckListControllerSize)value = Max( listHierarchyPane.Rect().Width(), listHierarchyPane.Rect().Width());
+ else value = Max( listHierarchyPropertyPane.Rect().Width(), listHierarchyPropertyPane.Rect().Width());
+ }
+ break;
+ case QStyle::PM_DialogButtonsSeparator: //Distance between buttons in a dialog buttons widget.
+ case QStyle::PM_DialogButtonsButtonWidth: // Minimum width of a button in a dialog buttons widget.
+ case QStyle::PM_DialogButtonsButtonHeight:// Minimum height of a button in a dialog buttons widget.
+ {
+ TAknLayoutRect appWindow;
+ appWindow.LayoutRect( screenRect, AknLayoutScalable_Avkon::application_window(0) );
+ variety = 0;
+ if ( landscape )
+ {
+ variety = 2;
+ }
+ TAknLayoutRect areaBottomRect;
+ areaBottomRect.LayoutRect( appWindow.Rect(), AknLayoutScalable_Avkon::area_bottom_pane(variety) );
+
+ TAknLayoutRect controlPaneRect;
+ controlPaneRect.LayoutRect( areaBottomRect.Rect(), AknLayoutScalable_Avkon::control_pane() );
+ TAknLayoutText controlPaneLSKText;
+ TAknLayoutText controlPaneRSKText;
+ TAknLayoutText controlPaneMSKText;
+ variety = 0;
+ if (AknLayoutUtils::MSKEnabled())
+ {
+ variety = 3;
+ controlPaneMSKText.LayoutText( controlPaneRect.Rect(), AknLayoutScalable_Avkon::control_pane_t3(variety)); //MSK text area
+ }
+ controlPaneLSKText.LayoutText( controlPaneRect.Rect(), AknLayoutScalable_Avkon::control_pane_t1(variety)); //LSK text area
+ controlPaneRSKText.LayoutText( controlPaneRect.Rect(), AknLayoutScalable_Avkon::control_pane_t2(variety)); //RSK text area
+
+ /*
+ *
+ ==================================================================================
+ | A | LSK_rect | B | MSK_rect | C | RSK_rect | D |
+ ==================================================================================
+ where A is left padding (between control pane and LSK rect)
+ B is mid-left padding (between LSK and MSK rects)
+ C is mid-right padding (between MSK and RSK rects)
+ D is right padding (between RSK and control pane)
+
+ ==> Since all these can be separate, lets take Max of {A..D} for PM value
+ */
+
+ TInt itemSpacingA = 0;
+ TInt itemSpacingB = 0;
+ TInt itemSpacingC = 0;
+ TInt itemSpacingMax = 0;
+ if ( !AknLayoutUtils::MSKEnabled() )
+ {
+ itemSpacingA = controlPaneRect.Rect().iBr.iX - controlPaneRSKText.TextRect().iBr.iX;
+ itemSpacingB = controlPaneLSKText.TextRect().iTl.iX - controlPaneRect.Rect().iTl.iX;
+ if (!landscape)
+ {
+ // use mid-gap only in portrait
+ itemSpacingC = controlPaneRSKText.TextRect().iTl.iX - controlPaneLSKText.TextRect().iBr.iX;
+ }
+ itemSpacingMax = Max(itemSpacingA, Max( itemSpacingB, itemSpacingC));
+ // no itemspacing4 if no MSK
+ }
+ else
+ {
+ TInt itemSpacingD = 0;
+ itemSpacingA = controlPaneRect.Rect().iBr.iX - controlPaneRSKText.TextRect().iBr.iX;
+ itemSpacingB = controlPaneLSKText.TextRect().iTl.iX - controlPaneRect.Rect().iTl.iX;
+ if ( !(AknLayoutUtils::PenEnabled() || landscape) ) // no MSK in touch, nor in landscape
+ {
+ itemSpacingC = controlPaneRSKText.TextRect().iTl.iX - controlPaneMSKText.TextRect().iBr.iX;
+ itemSpacingD = controlPaneMSKText.TextRect().iTl.iX - controlPaneLSKText.TextRect().iBr.iX;
+ }
+ itemSpacingMax = Max(itemSpacingA, Max( itemSpacingB, Max( itemSpacingC, itemSpacingD )));
+ }
+ if (metric==QStyle::PM_DialogButtonsSeparator) value = itemSpacingMax;
+ else if (metric==QStyle::PM_DialogButtonsButtonWidth)
+ {
+ value = Max( controlPaneLSKText.TextRect().Width(), controlPaneRSKText.TextRect().Width());
+ if (AknLayoutUtils::MSKEnabled())
+ {
+ value = Max(value, controlPaneMSKText.TextRect().Width());
+ }
+ }
+ else if (metric==QStyle::PM_DialogButtonsButtonHeight)
+ {
+ value = Max( controlPaneLSKText.TextRect().Height(), controlPaneRSKText.TextRect().Height());
+ if (AknLayoutUtils::MSKEnabled())
+ {
+ value = Max(value, controlPaneMSKText.TextRect().Height());
+ }
+ }
+ }
+ break;
+ case QStyle::PM_DockWidgetTitleMargin: // not in S60, lets use the same margin as in button
+ case QStyle::PM_DockWidgetTitleBarButtonMargin: // not in S60, lets use the same margin as in button
+ case QStyle::PM_ButtonMargin:
+ {
+ TRect myRect(TSize( 80, 20)); // this arbitrary size - user can set it - button border does not seem to have any scalability in it
+ TAknLayoutRect buttonRect;
+ TAknLayoutRect buttonBordersRect;
+ TAknLayoutText buttonText;
+
+ buttonRect.LayoutRect( myRect, AknLayoutScalable_Avkon::eswt_ctrl_button_pane());
+ buttonBordersRect.LayoutRect( buttonRect.Rect(), AknLayoutScalable_Avkon::common_borders_pane_copy2(0)); //with text
+ buttonText.LayoutText( buttonRect.Rect(), AknLayoutScalable_Avkon::control_button_pane_t1() );
+
+ // Its better to use left-right margins, since font deployment can create funny top / bottom margins
+ TInt leftMargin = buttonText.TextRect().iTl.iX - buttonBordersRect.Rect().iTl.iX;
+ TInt rightMargin = buttonBordersRect.Rect().iBr.iX - buttonText.TextRect().iBr.iX;
+ value = (TInt) ((leftMargin+rightMargin)/2);
+ }
+ break;
+ case QStyle::PM_ButtonDefaultIndicator:
+ {
+ // no default button indicators in S60
+ value = 0;
+ }
+ break;
+ case QStyle::PM_MdiSubWindowFrameWidth:
+ case QStyle::PM_ComboBoxFrameWidth:
+ case QStyle::PM_SpinBoxFrameWidth:
+ value = 0;
+ break;
+ case QStyle::PM_ToolBarFrameWidth:
+ case QStyle::PM_DefaultFrameWidth:
+ {
+ TAknLayoutRect highLightPaneRect;
+ TAknLayoutRect centerPaneRect;
+ TRect rectParent( mainPaneRect );
+ highLightPaneRect.LayoutRect( rectParent, AknLayoutScalable_Avkon::toolbar_button_pane(0).LayoutLine());
+ centerPaneRect.LayoutRect(rectParent, AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine());
+
+ value = highLightPaneRect.Rect().iBr.iX - centerPaneRect.Rect().iBr.iX;
+ }
+ break;
+ case QStyle::PM_RadioButtonLabelSpacing:
+ {
+ /*
+ *
+ ===================================================================================
+ | A | iconLayoutRect |B| itemText | C |
+ ===================================================================================
+ mirrored:
+ ===================================================================================
+ | C | itemText |B| iconLayoutRect | A |
+ ===================================================================================
+ where A is left padding
+ B is gap between icon and text
+ C is right padding
+ */
+
+ TRect rectParent( mainPaneRect );
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( rectParent,AknLayoutScalable_Avkon::list_choice_list_pane(1).LayoutLine() ); // w/ scrollbar
+ TAknLayoutText itemText;
+ itemText.LayoutText( layoutRect.Rect(), AknLayoutScalable_Avkon::list_single_choice_list_pane_t1(1) );
+ TAknLayoutRect iconLayoutRect;
+ iconLayoutRect.LayoutRect( layoutRect.Rect(), AknLayoutScalable_Avkon::list_single_choice_list_pane_g1().LayoutLine() );
+
+ if ( !AknLayoutUtils::LayoutMirrored() )
+ {
+ value = itemText.TextRect().iTl.iX - iconLayoutRect.Rect().iBr.iX;
+ }
+ else
+ {
+ value = iconLayoutRect.Rect().iTl.iX - itemText.TextRect().iBr.iX;
+ }
+ }
+
+ break;
+ case QStyle::PM_CheckBoxLabelSpacing:
+ {
+ /*
+ *
+ ===================================================================================
+ | A | iconLayoutRect |B| itemText | C |
+ ===================================================================================
+ mirrored:
+ ===================================================================================
+ | C | itemText |B| iconLayoutRect | A |
+ ===================================================================================
+ where A is left padding
+ B is gap between icon and text
+ C is right padding
+ */
+
+ TRect rectParent( mainPaneRect );
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( rectParent, AknLayoutScalable_Avkon::listscroll_gen_pane(0).LayoutLine() );
+
+ TAknLayoutRect layoutRect2;
+ layoutRect2.LayoutRect( layoutRect.Rect(), AknLayoutScalable_Avkon::list_gen_pane(0).LayoutLine() );
+ TAknLayoutRect layoutRect3;
+ layoutRect3.LayoutRect( layoutRect2.Rect(), AknLayoutScalable_Avkon::list_single_graphic_pane(0).LayoutLine() );
+
+ TAknLayoutText itemText;
+ itemText.LayoutText( layoutRect3.Rect(), AknLayoutScalable_Avkon::list_single_graphic_pane_t1(0) );
+ TAknLayoutRect iconLayoutRect;
+ iconLayoutRect.LayoutRect( layoutRect3.Rect(), AknLayoutScalable_Avkon::list_single_graphic_pane_g1(0).LayoutLine() );
+
+ if ( !AknLayoutUtils::LayoutMirrored() )
+ {
+ value = itemText.TextRect().iTl.iX - iconLayoutRect.Rect().iBr.iX;
+ }
+ else
+ {
+ value = iconLayoutRect.Rect().iTl.iX - itemText.TextRect().iBr.iX;
+ }
+ }
+ break;
+ case QStyle::PM_ToolTipLabelFrameWidth:
+ {
+ /*
+ *
+ |===================================================================================|
+ | info popup note B |
+ | ============================================================================== |
+ | A | hintText | D|
+ | ============================================================================== |
+ | C |
+ |===================================================================================|
+ where A is left padding
+ B is top padding
+ C is bottom padding
+ D is right padding
+ we'll provide the average of top and bottom padding as PM_ToolTipLabelFrameWidth
+ */
+
+ // Set pop-up to contain only one line of text
+ TInt index = 0;
+ if ( landscape )
+ {
+ // in landscape another variety is used
+ index += 5;
+ }
+ // Get parameter and table limits for popup preview text window
+ TAknLayoutScalableParameterLimits limits =
+ AknLayoutScalable_Avkon::popup_preview_text_window_ParamLimits();
+
+ TAknLayoutScalableTableLimits tableLimits =
+ AknLayoutScalable_Avkon::popup_preview_text_window_t_Limits();
+
+ TInt windowVariety = Min( Max( index, limits.FirstVariety() ), limits.LastVariety() );
+
+ TAknLayoutScalableParameterLimits tParamLimits =
+ AknLayoutScalable_Avkon:: popup_preview_text_window_t_ParamLimits(
+ tableLimits.FirstIndex() );
+
+ TInt lineVariety = Min( Max( index, tParamLimits.FirstVariety() ), tParamLimits.LastVariety() );
+
+ TAknWindowLineLayout lineLayout = AknLayoutScalable_Avkon::popup_preview_text_window(windowVariety).LayoutLine();
+
+ // rect for the whole info popup
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect(screenRect, lineLayout);
+ TRect rectPopupWindow = layoutRect.Rect();
+
+ TAknTextComponentLayout popupTextLayout =
+ AknLayoutScalable_Avkon::popup_preview_text_window_t(
+ tableLimits.FirstIndex(), lineVariety );
+
+ // rect for the whole the text inside the popup
+ TAknLayoutText layoutText;
+ layoutText.LayoutText( rectPopupWindow, popupTextLayout );
+
+ // Each margin has different value in S60 - let's take average of top & bottom
+ TInt topMargin = layoutText.TextRect().iTl.iY - layoutRect.Rect().iTl.iY;
+ TInt bottomMargin = layoutRect.Rect().iBr.iY - layoutText.TextRect().iBr.iY;
+ TInt averageMargin = (TInt)(topMargin+bottomMargin)/2;
+ value = averageMargin;
+ }
+ break;
+ case QStyle::PM_ListViewIconSize:
+ {
+ // todo: there are lots and lots of views with different sized icons - which one to use?
+ // todo: this is probably not a good default icon size, as this fetches A column icon size
+ // todo: preferably use settings item with graphic instead
+ TAknLayoutRect iconRect;
+ iconRect.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::list_double_graphic_pane_g1_cp2(0).LayoutLine());
+ //icon areas are usually squares - lets take bigger of two dimensions
+ value = Max( iconRect.Rect().Width(), iconRect.Rect().Height() );
+ }
+ break;
+
+ case QStyle::PM_LargeIconSize: // lets use AS icon as a base for large icon
+ case QStyle::PM_IconViewIconSize:
+ {
+ // Lets assume that we'd take these from grid (3x4) layout
+ TAknLayoutRect appPaneRect;
+ TAknLayoutRect gridAppRect;
+ TAknLayoutRect cellAppRect;
+ TInt varietyGrid = 2; //Let's use the 3x4 grid as a base.
+ TInt varietyCell = 1; //Let's use the 3x4 grid as a base.
+ if ( landscape )
+ {
+ varietyGrid = 3;
+ varietyCell = 2;
+ }
+ appPaneRect.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::listscroll_app_pane(1).LayoutLine()); //3x4 grid
+ gridAppRect.LayoutRect( appPaneRect.Rect(), AknLayoutScalable_Avkon::grid_app_pane(varietyGrid).LayoutLine());
+ cellAppRect.LayoutRect( gridAppRect.Rect(), AknLayoutScalable_Avkon::cell_app_pane(varietyCell, 0, 0).LayoutLine());
+ TAknLayoutRect cellGraphRect;
+ TAknWindowComponentLayout appIcon = AknLayoutScalable_Avkon::cell_app_pane_g1(0); // no mark, no highlight
+ cellGraphRect.LayoutRect( gridAppRect.Rect(), appIcon);
+ //icon areas are usually squares - if not, lets take larger
+ value = Max( cellGraphRect.Rect().Width(), cellGraphRect.Rect().Height());
+ }
+ break;
+ case QStyle::PM_TabBarIconSize:
+ {
+ TAknLayoutRect naviNaviRect;
+ naviNaviRect.LayoutRect( naviPaneRect, AknLayoutScalable_Avkon::navi_navi_tabs_pane().LayoutLine()); // two tabs
+ TAknLayoutRect tabRect;
+ tabRect.LayoutRect( naviNaviRect.Rect(), AknLayoutScalable_Avkon::navi_tabs_3_pane().LayoutLine()); //active tab on left
+ TAknLayoutRect activeTabRect;
+ activeTabRect.LayoutRect( tabRect.Rect(), AknLayoutScalable_Avkon::tabs_3_active_pane(0).LayoutLine()); //active tab
+ TAknLayoutRect activeTabGraphicRect;
+
+ activeTabGraphicRect.LayoutRect( activeTabRect.Rect(), AknLayoutScalable_Avkon::tabs_3_active_pane_g1().LayoutLine()); //active tab graphic
+ value = Min(activeTabGraphicRect.Rect().Width(), activeTabGraphicRect.Rect().Height());
+ }
+ break;
+ case QStyle::PM_MessageBoxIconSize:
+ {
+ TAknLayoutRect noteRect;
+ noteRect.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::popup_note_image_window(0).LayoutLine()); //note with image
+ TAknLayoutRect noteImageRect;
+ noteImageRect.LayoutRect( noteRect.Rect(), AknLayoutScalable_Avkon::popup_note_image_window_g2(2).LayoutLine()); //note with image
+ value = noteImageRect.Rect().Width();
+ }
+ break;
+ case QStyle::PM_TextCursorWidth:
+ {
+ TAknLayoutRect miscGraphicsRect;
+ miscGraphicsRect.LayoutRect( screenRect, AknLayoutScalable_Avkon::misc_graphics());
+ miscGraphicsRect.LayoutRect( miscGraphicsRect.Rect(), AknLayoutScalable_Avkon::misc_graphics());
+ TAknLayoutRect textsGraphicsRect;
+ textsGraphicsRect.LayoutRect( miscGraphicsRect.Rect(), AknLayoutScalable_Avkon::texts_graphics());
+ TAknLayoutRect cursorGraphicsRect;
+ cursorGraphicsRect.LayoutRect( textsGraphicsRect.Rect(), AknLayoutScalable_Avkon::cursor_graphics_pane());
+ TAknLayoutRect cursorPrimaryRect;
+ cursorPrimaryRect.LayoutRect( cursorGraphicsRect.Rect(), AknLayoutScalable_Avkon::cursor_primary_pane());
+ TAknLayoutRect cursorRect;
+ cursorRect.LayoutRect( cursorPrimaryRect.Rect(), AknLayoutScalable_Avkon::cursor_digital_pane_g1());
+ value = cursorRect.Rect().Width();
+ }
+ break;
+ case QStyle::PM_SliderLength:
+ {
+ TAknLayoutRect settingRect;
+ settingRect.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::listscroll_set_pane() );
+ TAknLayoutRect settingContentRect;
+ settingContentRect.LayoutRect( settingRect.Rect(), AknLayoutScalable_Avkon::set_content_pane() );
+ TAknLayoutRect sliderRect;
+ sliderRect.LayoutRect( settingContentRect.Rect(), AknLayoutScalable_Avkon::setting_slider_graphic_pane() );
+ TAknLayoutRect sliderSettingRect;
+ sliderSettingRect.LayoutRect( sliderRect.Rect(), AknLayoutScalable_Avkon::slider_set_pane_cp() );
+ TAknLayoutRect sliderGraph2Rect;
+ sliderGraph2Rect.LayoutRect( sliderSettingRect.Rect(), AknLayoutScalable_Avkon::slider_set_pane_g6() );
+ value = sliderGraph2Rect.Rect().Width();
+ }
+ break;
+ case QStyle::PM_SliderThickness:
+ {
+ TAknLayoutRect settingRect;
+ settingRect.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::listscroll_set_pane() );
+ TAknLayoutRect settingContentRect;
+ settingContentRect.LayoutRect( settingRect.Rect(), AknLayoutScalable_Avkon::set_content_pane() );
+ TAknLayoutRect sliderRect;
+ sliderRect.LayoutRect( settingContentRect.Rect(), AknLayoutScalable_Avkon::setting_slider_graphic_pane() );
+ TAknLayoutRect sliderSettingRect;
+ sliderSettingRect.LayoutRect( sliderRect.Rect(), AknLayoutScalable_Avkon::slider_set_pane_cp() );
+ TAknLayoutRect sliderGraph2Rect;
+ sliderGraph2Rect.LayoutRect( sliderSettingRect.Rect(), AknLayoutScalable_Avkon::slider_set_pane_g6() );
+ //todo: make a proper calculation for tick marks
+ value = (TInt)(sliderGraph2Rect.Rect().Height()*1.5); // add assumed tickmark height
+ }
+ break;
+ case QStyle::PM_SliderTickmarkOffset:
+ {
+ TAknLayoutRect settingRect;
+ settingRect.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::listscroll_set_pane() );
+ TAknLayoutRect settingContentRect;
+ settingContentRect.LayoutRect( settingRect.Rect(), AknLayoutScalable_Avkon::set_content_pane() );
+ TAknLayoutRect sliderRect;
+ sliderRect.LayoutRect( settingContentRect.Rect(), AknLayoutScalable_Avkon::setting_slider_graphic_pane() );
+ TAknLayoutRect sliderSettingRect;
+ sliderSettingRect.LayoutRect( sliderRect.Rect(), AknLayoutScalable_Avkon::slider_set_pane_cp() );
+ TAknLayoutRect sliderGraph2Rect;
+ sliderGraph2Rect.LayoutRect( sliderSettingRect.Rect(), AknLayoutScalable_Avkon::slider_set_pane_g6() );
+ //todo: make a proper calculation for tick marks
+ value = (TInt)(sliderGraph2Rect.Rect().Height()*0.5); // no tickmarks in S60, lets assume they are half the size of slider indicator
+ }
+ break;
+ case QStyle::PM_SliderControlThickness:
+ {
+ TAknLayoutRect settingRect;
+ settingRect.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::listscroll_set_pane() );
+ TAknLayoutRect settingContentRect;
+ settingContentRect.LayoutRect( settingRect.Rect(), AknLayoutScalable_Avkon::set_content_pane() );
+ TAknLayoutRect sliderRect;
+ sliderRect.LayoutRect( settingContentRect.Rect(), AknLayoutScalable_Avkon::setting_slider_graphic_pane() );
+ TAknLayoutRect sliderSettingRect;
+ sliderSettingRect.LayoutRect( sliderRect.Rect(), AknLayoutScalable_Avkon::slider_set_pane_cp() );
+ TAknLayoutRect sliderGraph2Rect;
+ sliderGraph2Rect.LayoutRect( sliderSettingRect.Rect(), AknLayoutScalable_Avkon::slider_set_pane_g6() );
+ value = sliderGraph2Rect.Rect().Height();
+ }
+ break;
+ case QStyle::PM_SliderSpaceAvailable:
+ {
+ TAknLayoutRect settingRect;
+ settingRect.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::listscroll_set_pane() );
+ TAknLayoutRect settingContentRect;
+ settingContentRect.LayoutRect( settingRect.Rect(), AknLayoutScalable_Avkon::set_content_pane() );
+ TAknLayoutRect sliderRect;
+ sliderRect.LayoutRect( settingContentRect.Rect(), AknLayoutScalable_Avkon::setting_slider_graphic_pane() );
+ TAknLayoutRect sliderSettingRect;
+ sliderSettingRect.LayoutRect( sliderRect.Rect(), AknLayoutScalable_Avkon::slider_set_pane_cp() );
+ value = sliderSettingRect.Rect().Width();
+ }
+ break;
+ case QStyle::PM_MenuBarItemSpacing:
+ {
+ TAknLayoutRect appWindow;
+ appWindow.LayoutRect( screenRect, AknLayoutScalable_Avkon::application_window(0) );
+
+ variety = 0;
+ if ( landscape )
+ {
+ variety = 2;
+ }
+ TAknLayoutRect areaBottomRect;
+ areaBottomRect.LayoutRect( appWindow.Rect(), AknLayoutScalable_Avkon::area_bottom_pane(variety) );
+
+ TAknLayoutRect controlPaneRect;
+ controlPaneRect.LayoutRect( areaBottomRect.Rect(), AknLayoutScalable_Avkon::control_pane() );
+ TAknLayoutText controlPaneLSKText;
+ TAknLayoutText controlPaneRSKText;
+ TAknLayoutText controlPaneMSKText;
+ variety = 0;
+ if (AknLayoutUtils::MSKEnabled())
+ {
+ variety = 3;
+ controlPaneMSKText.LayoutText( controlPaneRect.Rect(), AknLayoutScalable_Avkon::control_pane_t3(variety)); //MSK text area
+ }
+ controlPaneLSKText.LayoutText( controlPaneRect.Rect(), AknLayoutScalable_Avkon::control_pane_t1(variety)); //LSK text area
+ controlPaneRSKText.LayoutText( controlPaneRect.Rect(), AknLayoutScalable_Avkon::control_pane_t2(variety)); //RSK text area
+
+ /*
+ *
+ ==================================================================================
+ | A | LSK_rect | B | MSK_rect | C | RSK_rect | D |
+ ==================================================================================
+ where A is left padding (between control pane and LSK rect)
+ B is mid-left padding (between LSK and MSK rects)
+ C is mid-right padding (between MSK and RSK rects)
+ D is right padding (between RSK and control pane)
+
+ ==> Since all these can be separate, lets take Max of {A..D} for PM value
+ */
+
+ TInt itemSpacing1 = 0;
+ TInt itemSpacing2 = 0;
+ TInt itemSpacing3 = 0;
+ TInt itemSpacing4 = 0;
+ TInt itemSpacingMax = 0;
+ if ( !AknLayoutUtils::MSKEnabled() )
+ {
+ itemSpacing1 = controlPaneRect.Rect().iBr.iX - controlPaneRSKText.TextRect().iBr.iX;
+ itemSpacing2 = controlPaneLSKText.TextRect().iTl.iX - controlPaneRect.Rect().iTl.iX;
+ if ( !landscape )
+ {
+ // use mid gap only in portrait
+ itemSpacing3 = controlPaneRSKText.TextRect().iTl.iX - controlPaneLSKText.TextRect().iBr.iX;
+ }
+ itemSpacingMax = Max(itemSpacing1, Max( itemSpacing2, itemSpacing3));
+ // no itemspacing4 if no MSK
+ }
+ else
+ {
+ itemSpacing1 = controlPaneRect.Rect().iBr.iX - controlPaneRSKText.TextRect().iBr.iX;
+ itemSpacing2 = controlPaneLSKText.TextRect().iTl.iX - controlPaneRect.Rect().iTl.iX;
+ if ( !(AknLayoutUtils::PenEnabled() || landscape) ) // no MSK in touch, nor in landscape
+ {
+ itemSpacing3 = controlPaneRSKText.TextRect().iTl.iX - controlPaneMSKText.TextRect().iBr.iX;
+ itemSpacing4 = controlPaneMSKText.TextRect().iTl.iX - controlPaneLSKText.TextRect().iBr.iX;
+ }
+ itemSpacingMax = Max(itemSpacing1, Max( itemSpacing2, Max( itemSpacing3, itemSpacing4 )));
+ }
+ value = itemSpacingMax;
+ }
+ break;
+ case QStyle::PM_MenuBarHMargin:
+ {
+ TAknLayoutRect appWindow;
+ appWindow.LayoutRect( screenRect, AknLayoutScalable_Avkon::application_window(0) );
+
+ variety = 0;
+ if ( landscape )
+ {
+ variety = 6;
+ }
+ TAknLayoutRect areaBottomRect;
+ areaBottomRect.LayoutRect( appWindow.Rect(), AknLayoutScalable_Avkon::area_bottom_pane(variety) );
+
+ // variety 7 if thin status pane, 1 if no status pane, 3 if small status pane and with main pane, 4 otherwise (idle has bunch of own varieties)
+ TAknLayoutRect controlPaneRect;
+ controlPaneRect.LayoutRect( areaBottomRect.Rect(), AknLayoutScalable_Avkon::control_pane() );
+ value = areaBottomRect.Rect().Height() - controlPaneRect.Rect().Height();
+ }
+ break;
+ case QStyle::PM_MenuBarVMargin:
+ {
+ TAknLayoutRect appWindow;
+ appWindow.LayoutRect( screenRect, AknLayoutScalable_Avkon::application_window(0) );
+
+ variety = 0;
+ if ( landscape )
+ {
+ variety = 6;
+ }
+ TAknLayoutText controlPaneLSKText;
+ TAknLayoutRect areaBottomRect;
+ areaBottomRect.LayoutRect( appWindow.Rect(), AknLayoutScalable_Avkon::area_bottom_pane(variety) );
+ // variety 7 if thin status pane, 1 if no status pane, 3 if small status pane and with main pane, 4 otherwise (idle has bunch of own varieties)
+ TAknLayoutRect controlPaneRect;
+ controlPaneRect.LayoutRect( areaBottomRect.Rect(), AknLayoutScalable_Avkon::control_pane() );
+
+ variety = 0;
+ if (AknLayoutUtils::MSKEnabled())
+ {
+ variety = 3;
+ }
+ controlPaneLSKText.LayoutText( controlPaneRect.Rect(), AknLayoutScalable_Avkon::control_pane_t1(variety)); //LSK text area
+
+ value = controlPaneRect.Rect().Height() - controlPaneLSKText.TextRect().Height();
+ }
+ break;
+ case QStyle::PM_ToolBarItemSpacing:
+ {
+ TAknLayoutRect popupToolBarWindow;
+ variety = 4;
+ popupToolBarWindow.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::popup_toolbar_window(variety) );
+ TAknLayoutRect gridToolBarRect;
+ gridToolBarRect.LayoutRect( popupToolBarWindow.Rect(), AknLayoutScalable_Avkon::grid_toobar_pane() );
+ TAknLayoutRect cellToolBarRect1;
+ TAknLayoutRect cellToolBarRect2;
+ cellToolBarRect1.LayoutRect( gridToolBarRect.Rect(), AknLayoutScalable_Avkon::cell_toolbar_pane(0).LayoutLine() ); //first item
+ cellToolBarRect2.LayoutRect( gridToolBarRect.Rect(), AknLayoutScalable_Avkon::cell_toolbar_pane(1).LayoutLine() ); //second item
+ value = cellToolBarRect1.Rect().iBr.iX - cellToolBarRect2.Rect().iTl.iX;
+ }
+ break;
+ case QStyle::PM_ToolBarItemMargin:
+ {
+ variety = 4;
+ TAknLayoutRect popupToolBarWindow;
+ popupToolBarWindow.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::popup_toolbar_window(variety) );
+ TAknLayoutRect gridToolBarRect;
+ gridToolBarRect.LayoutRect( popupToolBarWindow.Rect(), AknLayoutScalable_Avkon::grid_toobar_pane() );
+ TAknLayoutRect cellToolBarRect1;
+ cellToolBarRect1.LayoutRect( gridToolBarRect.Rect(), AknLayoutScalable_Avkon::cell_toolbar_pane(0).LayoutLine() ); //first item
+ value = gridToolBarRect.Rect().iTl.iX - cellToolBarRect1.Rect().iTl.iX;
+ }
+ break;
+ case QStyle::PM_LayoutLeftMargin: // there really isn't a default layoutting on s60, but lets use AppShell icon deployment as base
+ case QStyle::PM_LayoutRightMargin:
+ case QStyle::PM_LayoutTopMargin:
+ case QStyle::PM_LayoutBottomMargin:
+ case QStyle::PM_LayoutHorizontalSpacing:
+ case QStyle::PM_LayoutVerticalSpacing:
+ {
+ //since spacing and margins should be globally same, lets use same easy component as base - such as find popup
+ TAknLayoutRect popup_find_windowRect;
+ TAknLayoutRect bg_popup_window_pane_cp12Rect;
+ TAknLayoutRect find_popup_paneRect;
+ popup_find_windowRect.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::popup_find_window(0).LayoutLine());
+ bg_popup_window_pane_cp12Rect.LayoutRect( popup_find_windowRect.Rect(), AknLayoutScalable_Avkon::bg_popup_window_pane_cp12().LayoutLine());
+ find_popup_paneRect.LayoutRect( bg_popup_window_pane_cp12Rect.Rect(), AknLayoutScalable_Avkon::find_popup_pane().LayoutLine());
+
+ const TBool mirrored = AknLayoutUtils::LayoutMirrored();
+ if ((metric==QStyle::PM_LayoutVerticalSpacing && !mirrored) || metric==QStyle::PM_LayoutLeftMargin)
+ {
+ if (mirrored)
+ {
+ value = find_popup_paneRect.Rect().iTl.iX - bg_popup_window_pane_cp12Rect.Rect().iTl.iX;
+ }
+ else
+ {
+ value = find_popup_paneRect.Rect().iTl.iX - bg_popup_window_pane_cp12Rect.Rect().iTl.iX;
+ }
+ }
+ else if (metric==QStyle::PM_LayoutRightMargin || (metric==QStyle::PM_LayoutVerticalSpacing && mirrored))
+ {
+ if (mirrored)
+ {
+ value = bg_popup_window_pane_cp12Rect.Rect().iBr.iX - find_popup_paneRect.Rect().iBr.iX;
+ }
+ else
+ {
+ value = bg_popup_window_pane_cp12Rect.Rect().iBr.iX - find_popup_paneRect.Rect().iBr.iX;
+ }
+ }
+ else if (metric==QStyle::PM_LayoutTopMargin || metric==QStyle::PM_LayoutHorizontalSpacing)
+ {
+ value = find_popup_paneRect.Rect().iTl.iY - bg_popup_window_pane_cp12Rect.Rect().iTl.iY;
+ }
+ else if (metric==QStyle::PM_LayoutBottomMargin)
+ {
+ value = bg_popup_window_pane_cp12Rect.Rect().iBr.iY - find_popup_paneRect.Rect().iBr.iY;
+ }
+ }
+ break;
+ case QStyle::PM_MaximumDragDistance:
+ {
+ value = -1; //disable - not in S60
+ }
+ break;
+ case QStyle::PM_SplitterWidth:
+ case QStyle::PM_ScrollBarExtent:
+ {
+ TAknLayoutRect miscGraphicsRect;
+ miscGraphicsRect.LayoutRect( screenRect, AknLayoutScalable_Avkon::misc_graphics());
+ miscGraphicsRect.LayoutRect( miscGraphicsRect.Rect(), AknLayoutScalable_Avkon::misc_graphics());
+ TAknLayoutRect textsGraphicsRect;
+ textsGraphicsRect.LayoutRect( miscGraphicsRect.Rect(), AknLayoutScalable_Avkon::texts_graphics());
+ TAknLayoutRect editorScrollRect;
+ editorScrollRect.LayoutRect( textsGraphicsRect.Rect(), AknLayoutScalable_Avkon::editor_scroll_pane());
+ TAknLayoutRect scrollPaneRect;
+ scrollPaneRect.LayoutRect( editorScrollRect.Rect(), AknLayoutScalable_Avkon::scroll_pane_cp13());
+ value = scrollPaneRect.Rect().Width(); // width of editor's scroll bar
+ }
+ break;
+ case QStyle::PM_ScrollBarSliderMin:
+ {
+ TAknLayoutRect listScrollPane;
+ listScrollPane.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::listscroll_gen_pane(0));
+ TAknLayoutRect scrollPane;
+ scrollPane.LayoutRect( listScrollPane.Rect(), AknLayoutScalable_Avkon::scroll_pane());
+ TAknLayoutRect scrollHandlePane;
+ scrollHandlePane.LayoutRect( scrollPane.Rect(), AknLayoutScalable_Avkon::scroll_handle_pane());
+ TAknLayoutRect aidMinSizePane;
+ aidMinSizePane.LayoutRect( scrollHandlePane.Rect(), AknLayoutScalable_Avkon::aid_size_min_handle()); // this gives min width size for horizontal scroll bar - same can be used for vertical height minimum
+ value = aidMinSizePane.Rect().Height();
+ }
+ break;
+ case QStyle::PM_MenuBarPanelWidth:
+ {
+ TAknLayoutRect appWindow;
+ appWindow.LayoutRect( screenRect, AknLayoutScalable_Avkon::application_window(0) );
+
+ variety = 0;
+ if ( landscape )
+ {
+ variety = 2;
+ }
+ TAknLayoutRect areaBottomRect;
+ areaBottomRect.LayoutRect( appWindow.Rect(), AknLayoutScalable_Avkon::area_bottom_pane(variety) );
+
+ // todo: prt: variety 7 if thin status pane, 1 if no status pane, 3 if small status pane and with main pane, 4 otherwise (idle has bunch of own varieties)
+ // todo: lsc: variety 6 if thin status pane
+ // todo: should stacon be considered?
+ TAknLayoutRect controlPaneRect;
+ controlPaneRect.LayoutRect( areaBottomRect.Rect(), AknLayoutScalable_Avkon::control_pane() );
+ value = areaBottomRect.Rect().Height() - controlPaneRect.Rect().Height(); //usually zero
+ }
+ break;
+ case QStyle::PM_ProgressBarChunkWidth:
+ {
+ // This is either deduced or skinned (for Java) in S60
+ // Layout data does not know it. It would require parameters from the
+ // actual progress dialog to be able to calc this (max. value and increment)
+ // So we need to set up some values - lets take one tenth of progress dialog area:
+ TAknLayoutRect appWindow;
+ appWindow.LayoutRect( screenRect, AknLayoutScalable_Avkon::application_window(variety) );
+ if (landscape)
+ {
+ variety = 6;
+ }
+ TAknLayoutRect popupWaitWindowRect;
+ popupWaitWindowRect.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::popup_note_wait_window(variety) );
+ TAknLayoutRect waitbarPaneRect;
+ waitbarPaneRect.LayoutRect( popupWaitWindowRect.Rect(), AknLayoutScalable_Avkon::wait_bar_pane(0) );
+ TAknLayoutRect waitAnimRect;
+ waitAnimRect.LayoutRect( waitbarPaneRect.Rect(), AknLayoutScalable_Avkon::wait_anim_pane() );
+ value = (TInt) (waitAnimRect.Rect().Width() / 10);
+ }
+ break;
+ case QStyle::PM_TabBarTabOverlap:
+ case QStyle::PM_TabBarTabHSpace:
+ case QStyle::PM_TabBarTabVSpace:
+ case QStyle::PM_TabBarBaseHeight:
+ case QStyle::PM_TabBarBaseOverlap:
+ case QStyle::PM_TabBarScrollButtonWidth:
+ case QStyle::PM_TabBarTabShiftHorizontal:
+ case QStyle::PM_TabBarTabShiftVertical:
+ value = PixelMetricTabValue(metric, appWindow.Rect(), landscape);
+ break;
+ case QStyle::PM_MenuPanelWidth:
+ case QStyle::PM_MenuHMargin:
+ case QStyle::PM_MenuVMargin:
+ value = PixelMetricMenuValue(metric, mainPaneRect);
+ break;
+ case QStyle::PM_ButtonIconSize:
+ {
+ //lets use voice recorder icons as a base
+ //Unfortunately S60 graphics don't separate button bevel graphics from the actual icon.
+ //Se we have no means to query the margin from bevel border to "central icon" border.
+ //So, we need to make a estimate...
+
+ TAknLayoutRect vRMainRect;
+ vRMainRect.LayoutRect( mainPaneRect, AknLayoutScalable_Apps::main_vorec_pane() );
+
+ TAknLayoutRect vRButtonGridRect;
+ vRButtonGridRect.LayoutRect( vRMainRect.Rect(), AknLayoutScalable_Apps::grid_vorec_pane() );
+
+ TAknLayoutRect vRButtonCellRect;
+ vRButtonCellRect.LayoutRect( vRButtonGridRect.Rect(), AknLayoutScalable_Apps::cell_vorec_pane(0) );
+
+ TAknLayoutRect vRButtonCellGraphicsRect;
+ vRButtonCellGraphicsRect.LayoutRect( vRButtonCellRect.Rect(), AknLayoutScalable_Apps::cell_vorec_pane_g1() );
+
+ // 0.32 is the estimate how much the icon occupies of the button bevel area
+ value = vRButtonCellGraphicsRect.Rect().Width() * 0.32;
+ }
+ break;
+ case QStyle::PM_SmallIconSize:
+ {
+ // lets use AI2 icon as a base
+ TAknLayoutRect idlePaneRect;
+ idlePaneRect.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::main_idle_act2_pane() );
+ TAknLayoutRect idleDataRect;
+ idleDataRect.LayoutRect( idlePaneRect.Rect(), AknLayoutScalable_Avkon::popup_ai2_data_window(1) );
+ TAknLayoutRect ai2GridRect;
+ ai2GridRect.LayoutRect( idleDataRect.Rect(), AknLayoutScalable_Avkon::grid_ai2_button_pane() );
+ TAknLayoutRect ai2MpRect;
+ ai2MpRect.LayoutRect( ai2GridRect.Rect(), AknLayoutScalable_Avkon::ai2_mp_button_pane() );
+ TAknLayoutRect ai2CellPaneRect;
+ ai2CellPaneRect.LayoutRect( ai2MpRect.Rect(), AknLayoutScalable_Avkon::cell_ai2_button_pane(1).LayoutLine() );
+ TAknLayoutRect ai2CellButtonRect;
+ ai2CellButtonRect.LayoutRect( ai2CellPaneRect.Rect(), AknLayoutScalable_Avkon::cell_ai2_button_pane_g1());
+ value = Min( ai2CellButtonRect.Rect().Width(), ai2CellButtonRect.Rect().Height());
+ }
+ break;
+ case QStyle::PM_FocusFrameHMargin:
+ case QStyle::PM_FocusFrameVMargin:
+ {
+ TAknLayoutRect listScrollPane;
+ listScrollPane.LayoutRect(mainPaneRect, AknLayoutScalable_Avkon::listscroll_gen_pane(0));
+ TAknLayoutRect listGenPane;
+ listGenPane.LayoutRect(listScrollPane.Rect(), AknLayoutScalable_Avkon::list_gen_pane(0));
+ TAknLayoutRect listSinglePane;
+ listSinglePane.LayoutRect(listGenPane.Rect(), AknLayoutScalable_Avkon::list_single_pane(0));
+ TAknLayoutText listSinglePaneText;
+ listSinglePaneText.LayoutText(listSinglePane.Rect(), AknLayoutScalable_Avkon::list_single_pane_t1(0));
+ TAknLayoutRect highlightRect;
+ highlightRect.LayoutRect(listSinglePane.Rect(), AknLayoutScalable_Avkon::list_highlight_pane_cp1().LayoutLine());
+
+ // The difference of center piece from border tell the frame width.
+ if ( value == QStyle::PM_FocusFrameHMargin)
+ {
+ //use topleft for horizontal as S60 uses different values for right and left borders
+ value = listSinglePaneText.TextRect().iTl.iX - highlightRect.Rect().iTl.iX;
+ }
+ else
+ {
+ value = highlightRect.Rect().iBr.iY - listSinglePaneText.TextRect().iBr.iY;
+ }
+ }
+ break;
+ case QStyle::PM_ToolBarIconSize:
+ {
+ TAknLayoutRect popupToolBarWindow;
+ variety = 4;
+ popupToolBarWindow.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::popup_toolbar_window(variety) );
+ TAknLayoutRect gridToolBarRect;
+ gridToolBarRect.LayoutRect( popupToolBarWindow.Rect(), AknLayoutScalable_Avkon::grid_toobar_pane() );
+ TAknLayoutRect cellToolBarRect1;
+ TAknLayoutRect cellToolBarRect2;
+ cellToolBarRect1.LayoutRect( gridToolBarRect.Rect(), AknLayoutScalable_Avkon::cell_toolbar_pane(0).LayoutLine() ); //first item
+ value = Min( cellToolBarRect1.Rect().Height(), cellToolBarRect1.Rect().Width() );
+ }
+ break;
+
+ case QStyle::PM_TitleBarHeight: // use titlepane height
+ {
+ TAknLayoutRect statusPaneRect;
+ TAknLayoutRect titlePane;
+ TAknLayoutRect areaTopRect;
+ if (landscape)
+ {
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ // Top area - 0 is for classic landscape (used in touch landscape as well)
+ areaTopRect.LayoutRect( appWindow.Rect(), AknLayoutScalable_Avkon::area_top_pane(2) );
+ // Status pane - 0 softkeys on right
+ statusPaneRect.LayoutRect( areaTopRect.Rect(), AknLayoutScalable_Avkon::stacon_top_pane() );
+ }
+ else
+ {
+ // Top area - 2 is for classic landscape.
+ areaTopRect.LayoutRect( appWindow.Rect(), AknLayoutScalable_Avkon::area_bottom_pane(2) );
+ // Stacon top pane (default ok)
+ statusPaneRect.LayoutRect( areaTopRect.Rect(), AknLayoutScalable_Avkon::stacon_bottom_pane() );
+ }
+ titlePane.LayoutRect( areaTopRect.Rect(), AknLayoutScalable_Avkon::title_pane_stacon(0) ); //softkeys on right
+ }
+ else
+ {
+ // Top area - 0 is for classic portrait
+ areaTopRect.LayoutRect( appWindow.Rect(), AknLayoutScalable_Avkon::area_top_pane(0) );
+ // Status pane - 0 is for classic portrait
+ statusPaneRect.LayoutRect( areaTopRect.Rect(), AknLayoutScalable_Avkon::status_pane(0) );
+ titlePane.LayoutRect( statusPaneRect.Rect(), AknLayoutScalable_Avkon::title_pane(0) );
+ }
+ value = titlePane.Rect().Height();
+ }
+ break;
+ case QStyle::PM_IndicatorWidth:
+ case QStyle::PM_IndicatorHeight:
+ {
+ TRect rectParent( mainPaneRect );
+
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( rectParent,AknLayoutScalable_Avkon::set_content_pane().LayoutLine() );
+ TAknLayoutRect layoutRect2;
+ layoutRect2.LayoutRect( layoutRect.Rect(),AknLayoutScalable_Avkon::list_set_graphic_pane(0).LayoutLine() );
+
+ TAknLayoutRect iconLayoutRect;
+ iconLayoutRect.LayoutRect( layoutRect2.Rect(), AknLayoutScalable_Avkon::list_set_graphic_pane_g1(0).LayoutLine() );
+ if (metric==QStyle::PM_IndicatorWidth)
+ {
+ value = iconLayoutRect.Rect().Width();
+ }
+ else
+ {
+ value = iconLayoutRect.Rect().Height();
+ }
+ }
+ break;
+ case QStyle::PM_ExclusiveIndicatorHeight:
+ case QStyle::PM_ExclusiveIndicatorWidth:
+ {
+ TRect rectParent( mainPaneRect );
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( rectParent,AknLayoutScalable_Avkon::list_choice_list_pane(1).LayoutLine() ); // w/ scrollbar
+ TAknLayoutText itemText;
+ itemText.LayoutText( layoutRect.Rect(), AknLayoutScalable_Avkon::list_single_choice_list_pane_t1(1) );
+ TAknLayoutRect iconLayoutRect;
+ iconLayoutRect.LayoutRect( layoutRect.Rect(), AknLayoutScalable_Avkon::list_single_choice_list_pane_g1().LayoutLine() );
+
+ if (metric==QStyle::PM_ExclusiveIndicatorHeight)
+ {
+ value = iconLayoutRect.Rect().Height();
+ }
+ else
+ {
+ value = iconLayoutRect.Rect().Width();
+ }
+ }
+ break;
+
+ // These are obsolete.
+ case QStyle::PM_DefaultTopLevelMargin:
+ case QStyle::PM_DefaultChildMargin:
+ case QStyle::PM_DefaultLayoutSpacing:
+ break;
+
+ case QStyle::PM_Custom_FrameCornerWidth:
+ {
+ TAknLayoutRect inputFocusRect;
+ inputFocusRect.LayoutRect(mainPaneRect, AknLayoutScalable_Avkon::input_focus_pane(0));
+ TAknLayoutRect inputFocusInnerRect;
+ inputFocusInnerRect.LayoutRect(mainPaneRect, AknLayoutScalable_Avkon::input_focus_pane_g1());
+
+ value = inputFocusRect.Rect().iBr.iX - inputFocusInnerRect.Rect().iBr.iX;
+ value+= 2; //visually better value for generic cases
+ }
+ break;
+ case QStyle::PM_Custom_FrameCornerHeight:
+ {
+ TAknLayoutRect inputFocusRect;
+ inputFocusRect.LayoutRect(mainPaneRect, AknLayoutScalable_Avkon::input_focus_pane(0));
+ TAknLayoutRect inputFocusInnerRect;
+ inputFocusInnerRect.LayoutRect(mainPaneRect, AknLayoutScalable_Avkon::input_focus_pane_g1());
+ value = inputFocusRect.Rect().iBr.iY - inputFocusInnerRect.Rect().iBr.iY;
+ value+= 2; //visually better value for generic cases
+ }
+ break;
+ case QStyle::PM_Custom_BoldLineWidth:
+ value = 3;
+ break;
+ case QStyle::PM_Custom_ThinLineWidth:
+ value = 1;
+ break;
+ case QStyle::PM_Custom_MessageBoxHeight:
+ {
+ TAknLayoutRect popupRect;
+ popupRect.LayoutRect(mainPaneRect, AknLayoutScalable_Avkon::popup_window_general(0));
+ value = popupRect.Rect().Height();
+ }
+ break;
+ case QStyle::PM_ButtonShiftHorizontal:
+ case QStyle::PM_ButtonShiftVertical:
+ value = 0;
+ break;
+
+ case QStyle::PM_ToolBarExtensionExtent:
+ value = PixelMetricTabValue(QStyle::PM_TabBarScrollButtonWidth, appWindow.Rect(), landscape);
+ break;
+
+ case QStyle::PM_MenuScrollerHeight:
+ {
+ TRect rectParent( mainPaneRect );
+ TAknLayoutRect listWidthScrollBarsRect;
+ listWidthScrollBarsRect.LayoutRect( rectParent, AknLayoutScalable_Avkon::listscroll_gen_pane(0).LayoutLine() );
+
+ TAknLayoutRect listWidgetRect;
+ listWidgetRect.LayoutRect( listWidthScrollBarsRect.Rect(), AknLayoutScalable_Avkon::list_gen_pane(0).LayoutLine() );
+ TAknLayoutRect singleLineListWidgetRect;
+ singleLineListWidgetRect.LayoutRect( listWidgetRect.Rect(), AknLayoutScalable_Avkon::list_single_pane(0).LayoutLine() );
+
+ TAknLayoutRect listHighlightRect;
+ listHighlightRect.LayoutRect( singleLineListWidgetRect.Rect(), AknLayoutScalable_Avkon::list_highlight_pane_cp1(0).LayoutLine() );
+
+ value = listHighlightRect.Rect().Height();
+ }
+ break;
+
+// todo: re-check if these really are not available in s60
+ case QStyle::PM_MenuDesktopFrameWidth: // not needed in S60 - dislocates Menu both horizontally and vertically
+ case QStyle::PM_HeaderMarkSize: // The size of the sort indicator in a header. Not in S60
+ case QStyle::PM_SpinBoxSliderHeight: // The height of the optional spin box slider. Not in S60
+ case QStyle::PM_HeaderMargin: // not in S60
+ case QStyle::PM_MenuTearoffHeight: // not in S60
+ case QStyle::PM_DockWidgetFrameWidth: // not in S60
+ case QStyle::PM_DockWidgetSeparatorExtent: // not in S60
+ case QStyle::PM_MdiSubWindowMinimizedWidth: //no such thing in S60
+ case QStyle::PM_HeaderGripMargin: // not in S60
+ case QStyle::PM_ToolBarSeparatorExtent: // not in S60
+ case QStyle::PM_ToolBarHandleExtent: // not in s60
+ case QStyle::PM_MenuButtonIndicator: // none???
+ case QStyle::PM_TabBar_ScrollButtonOverlap: // not used in S60 - tab arrows are on left and right side of tab group - not together
+ case QStyle::PM_SizeGripSize: // use default
+ case QStyle::PM_TabCloseIndicatorWidth:
+ case QStyle::PM_TabCloseIndicatorHeight:
+ case QStyle::PM_ScrollView_ScrollBarSpacing:
+ case QStyle::PM_SubMenuOverlap:
+ default:
+ break;
+ }
+ return value;
+ }
+
+TInt PixelMetrics::PixelMetricTabValue(QStyle::PixelMetric tabMetric, TRect appWindow, TBool landscape)
+ {
+ TInt tabValue = 0;
+ // common ones
+ TAknLayoutRect mainAreaRect;
+ TAknLayoutRect rightIndicationRect;
+ TAknLayoutRect leftIndicationRect;
+ TAknLayoutRect activeTabRect;
+ TAknLayoutText activeTabTextRect;
+ TAknLayoutRect passiveTabRect;
+ TAknLayoutText passiveTabTextRect;
+ TAknLayoutRect tabsPaneRect;
+ if ( landscape )
+ {
+ TAknLayoutRect statusPaneRect;
+ TAknLayoutRect areaTopRect;
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ // Top area - 0 is for classic landscape (used in touch landscape as well)
+ areaTopRect.LayoutRect( appWindow, AknLayoutScalable_Avkon::area_top_pane(2) );
+ // Status pane - 0 softkeys on right
+ statusPaneRect.LayoutRect( areaTopRect.Rect(), AknLayoutScalable_Avkon::stacon_top_pane() );
+ }
+ else
+ {
+ // Top area - 2 is for classic landscape.
+ areaTopRect.LayoutRect( appWindow, AknLayoutScalable_Avkon::area_bottom_pane(2) );
+ // Stacon top pane (default ok)
+ statusPaneRect.LayoutRect( areaTopRect.Rect(), AknLayoutScalable_Avkon::stacon_bottom_pane() );
+ }
+ // main pane for landscape
+ mainAreaRect.LayoutRect( appWindow, AknLayoutScalable_Avkon::main_pane(4) );
+
+ // navi pane
+ TAknLayoutRect naviPaneRect;
+ naviPaneRect.LayoutRect( statusPaneRect.Rect(), AknLayoutScalable_Avkon::navi_pane_stacon(0) ); // softkeys on right
+ // navi-navi pane
+ tabsPaneRect.LayoutRect( naviPaneRect.Rect(), AknLayoutScalable_Avkon::navi_navi_pane_stacon(0) ); // softkeys on right
+ // Passive tab item - lets use layout where active is on left side of passive
+ passiveTabRect.LayoutRect( tabsPaneRect.Rect(), AknLayoutScalable_Avkon::tabs_3_passive_pane(0) );
+ // Active tab item
+ activeTabRect.LayoutRect( tabsPaneRect.Rect(), AknLayoutScalable_Avkon::tabs_3_active_pane(0) );
+ // Left indication
+ leftIndicationRect.LayoutRect( tabsPaneRect.Rect(), AknLayoutScalable_Avkon::navi_navi_pane_g1(0) );
+ // Right indication
+ rightIndicationRect.LayoutRect( tabsPaneRect.Rect(), AknLayoutScalable_Avkon::navi_navi_pane_g2(0) );
+ // active tab text rect
+ activeTabTextRect.LayoutText( activeTabRect.Rect(), AknLayoutScalable_Avkon::tabs_3_active_pane_t1(1) );
+ // passive tab text rect
+ passiveTabTextRect.LayoutText( passiveTabRect.Rect(), AknLayoutScalable_Avkon::tabs_3_passive_pane_t1(1) );
+ }
+ else
+ {
+ // main pane for portait
+ mainAreaRect.LayoutRect( appWindow, AknLayoutScalable_Avkon::main_pane(3) );
+ // Top area - 0 is for classic portrait
+ TAknLayoutRect areaTopRect;
+ areaTopRect.LayoutRect( appWindow, AknLayoutScalable_Avkon::area_top_pane(0) );
+ // Status pane - 0 is for classic portrait
+ TAknLayoutRect statusPaneRect;
+ statusPaneRect.LayoutRect( areaTopRect.Rect(), AknLayoutScalable_Avkon::status_pane(0) );
+
+ // Navi pane
+ TAknLayoutRect naviPaneRect;
+ naviPaneRect.LayoutRect( statusPaneRect.Rect(), AknLayoutScalable_Avkon::navi_pane(0) );
+ // Navi-navi pane for tabs (0)
+ TAknLayoutRect navi2PaneRect;
+ navi2PaneRect.LayoutRect( naviPaneRect.Rect(), AknLayoutScalable_Avkon::navi_navi_pane() );
+ // Short tab pane
+ tabsPaneRect.LayoutRect( navi2PaneRect.Rect(), AknLayoutScalable_Avkon::navi_navi_tabs_pane() );
+ // Tab pane for 2 items
+ TAknLayoutRect tab2PaneRect;
+ tab2PaneRect.LayoutRect( tabsPaneRect.Rect(), AknLayoutScalable_Avkon::navi_tabs_3_pane() );
+ // Passive tab item - lets use layout where active is on left side of passive
+ passiveTabRect.LayoutRect( tab2PaneRect.Rect(), AknLayoutScalable_Avkon::tabs_3_passive_pane(0) );
+ // Active tab item
+ activeTabRect.LayoutRect( tab2PaneRect.Rect(), AknLayoutScalable_Avkon::tabs_3_active_pane(0) );
+ // Left indication
+ leftIndicationRect.LayoutRect( tabsPaneRect.Rect(), AknLayoutScalable_Avkon::navi_navi_pane_g1(0) );
+ // Right indication
+ rightIndicationRect.LayoutRect( tabsPaneRect.Rect(), AknLayoutScalable_Avkon::navi_navi_pane_g2(0) );
+ // active tab text rect
+ activeTabTextRect.LayoutText( activeTabRect.Rect(), AknLayoutScalable_Avkon::tabs_3_active_pane_t1(0) );
+ // passive tab text rect
+ passiveTabTextRect.LayoutText( passiveTabRect.Rect(), AknLayoutScalable_Avkon::tabs_3_passive_pane_t1(0) );
+ }
+
+ // active tab on left, passive on rightside
+ TInt tabOverlap = activeTabRect.Rect().iBr.iX - passiveTabRect.Rect().iTl.iX;
+ TInt tabHSpace = (TInt) ((activeTabTextRect.TextRect().iTl.iX - activeTabRect.Rect().iTl.iX + activeTabRect.Rect().iBr.iX - activeTabTextRect.TextRect().iBr.iX)/2);
+ TInt tabVSpace = (TInt) ((activeTabTextRect.TextRect().iTl.iY - activeTabRect.Rect().iTl.iY + activeTabRect.Rect().iBr.iY - activeTabTextRect.TextRect().iBr.iY)/2);
+ TInt tabBaseHeight = 0;
+ if ( landscape && !AknLayoutUtils::PenEnabled())
+ {
+ // In landscape tab is below mainpane
+ tabBaseHeight = mainAreaRect.Rect().iBr.iY - tabsPaneRect.Rect().iTl.iY;
+ }
+ else
+ {
+ // In portrait (and in landscape touch) tab is above mainpane
+ tabBaseHeight = tabsPaneRect.Rect().iBr.iY - mainAreaRect.Rect().iTl.iY;
+ }
+ TInt tabBaseOverlap = 0;
+ if ( landscape && !AknLayoutUtils::PenEnabled())
+ {
+ // In landscape tab is below mainpane
+ tabBaseOverlap = Max( 0, mainAreaRect.Rect().iBr.iY - tabsPaneRect.Rect().iTl.iY);
+ }
+ else
+ {
+ // In portrait tab is above mainpane
+ tabBaseOverlap = Max( 0, mainAreaRect.Rect().iTl.iY - tabsPaneRect.Rect().iBr.iY);
+ }
+ TInt tabButtonWidth = Max(leftIndicationRect.Rect().Width(), rightIndicationRect.Rect().Width());
+ TInt tabVShift = Max( Abs(activeTabTextRect.TextRect().iBr.iY - passiveTabTextRect.TextRect().iBr.iY), Abs(activeTabTextRect.TextRect().iTl.iY - passiveTabTextRect.TextRect().iTl.iY) );
+ TInt tabHShift = Max( Abs(activeTabTextRect.TextRect().iBr.iX - passiveTabTextRect.TextRect().iBr.iX), Abs(activeTabTextRect.TextRect().iTl.iX - passiveTabTextRect.TextRect().iTl.iX) );
+ tabHShift -= (passiveTabRect.Rect().Width() - tabOverlap); // remove tab change and add overlapping area
+
+ switch( tabMetric )
+ {
+ case QStyle::PM_TabBarTabOverlap:
+ tabValue = tabOverlap;
+ break;
+ case QStyle::PM_TabBarTabHSpace:
+ tabValue = tabHSpace;
+ break;
+ case QStyle::PM_TabBarTabVSpace:
+ tabValue = tabVSpace;
+ break;
+ case QStyle::PM_TabBarBaseHeight:
+ tabValue = tabBaseHeight;
+ break;
+ case QStyle::PM_TabBarBaseOverlap:
+ tabValue = tabBaseOverlap;
+ break;
+ case QStyle::PM_TabBarScrollButtonWidth:
+ // Since in Qt the scroll indicator is shown within a button, we need to add button margins to this value
+ {
+ tabValue = tabButtonWidth + 2*PixelMetricValue(QStyle::PM_ButtonMargin);
+ }
+ break;
+ case QStyle::PM_TabBarTabShiftHorizontal:
+ tabValue = tabHShift;
+ break;
+ case QStyle::PM_TabBarTabShiftVertical:
+ tabValue = tabVShift;
+ break;
+ default:
+ break;
+ }
+ return tabValue;
+ }
+
+TInt PixelMetrics::PixelMetricMenuValue(QStyle::PixelMetric tabMetric, TRect mainPaneRect )
+ {
+ TInt menuValue = 0;
+ TAknLayoutRect popupMenuRect;
+ popupMenuRect.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::popup_menu_window(0) );
+ TAknLayoutRect listScrollPaneRect;
+ listScrollPaneRect.LayoutRect( popupMenuRect.Rect(), AknLayoutScalable_Avkon::listscroll_menu_pane(0) );
+ TAknLayoutRect listMenuPaneRect;
+ listMenuPaneRect.LayoutRect( listScrollPaneRect.Rect(), AknLayoutScalable_Avkon::list_menu_pane(0) );
+ TAknLayoutRect listMenuRow1Rect;
+ listMenuRow1Rect.LayoutRect( listScrollPaneRect.Rect(), AknLayoutScalable_Avkon::list_single_pane_cp2(0));
+
+ switch (tabMetric)
+ {
+ case QStyle::PM_MenuPanelWidth:
+ menuValue = listMenuPaneRect.Rect().iTl.iX - listScrollPaneRect.Rect().iTl.iX;
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ menuValue = listScrollPaneRect.Rect().iBr.iX - listMenuPaneRect.Rect().iBr.iX;
+ }
+ break;
+ case QStyle::PM_MenuHMargin:
+ menuValue = listMenuRow1Rect.Rect().iTl.iX - popupMenuRect.Rect().iTl.iX;
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ menuValue = popupMenuRect.Rect().iBr.iX - listMenuRow1Rect.Rect().iBr.iX;
+ }
+ break;
+ case QStyle::PM_MenuVMargin:
+ menuValue = listMenuRow1Rect.Rect().iTl.iY - popupMenuRect.Rect().iTl.iY;
+ break;
+ default:
+ break;
+ }
+ return menuValue;
+ }
diff --git a/util/s60pixelmetrics/pixel_metrics.h b/util/s60pixelmetrics/pixel_metrics.h
new file mode 100644
index 0000000000..ba952cc955
--- /dev/null
+++ b/util/s60pixelmetrics/pixel_metrics.h
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utility applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PIXELMETRICS_H
+#define PIXELMETRICS_H
+
+#include <e32base.h>
+#define S60_Rnd_Env
+
+#ifdef S60_Rnd_Env
+#pragma message ("Building in supported environment")
+
+const TInt KUnknownBase = -5000;
+
+NONSHARABLE_CLASS( QStyle )
+ {
+ public:
+ enum PixelMetric {
+ PM_ButtonMargin,
+ PM_ButtonDefaultIndicator,
+ PM_MenuButtonIndicator,
+ PM_ButtonShiftHorizontal,
+ PM_ButtonShiftVertical,
+
+ PM_DefaultFrameWidth,
+ PM_SpinBoxFrameWidth,
+ PM_ComboBoxFrameWidth,
+
+ PM_MaximumDragDistance,
+
+ PM_ScrollBarExtent,
+ PM_ScrollBarSliderMin,
+
+ PM_SliderThickness, // total slider thickness
+ PM_SliderControlThickness, // thickness of the business part
+ PM_SliderLength, // total length of slider
+ PM_SliderTickmarkOffset, //
+ PM_SliderSpaceAvailable, // available space for slider to move
+
+ PM_DockWidgetSeparatorExtent,
+ PM_DockWidgetHandleExtent,
+ PM_DockWidgetFrameWidth,
+
+ PM_TabBarTabOverlap,
+ PM_TabBarTabHSpace,
+ PM_TabBarTabVSpace,
+ PM_TabBarBaseHeight,
+ PM_TabBarBaseOverlap,
+
+ PM_ProgressBarChunkWidth,
+
+ PM_SplitterWidth,
+ PM_TitleBarHeight,
+
+ PM_MenuScrollerHeight,
+ PM_MenuHMargin,
+ PM_MenuVMargin,
+ PM_MenuPanelWidth,
+ PM_MenuTearoffHeight,
+ PM_MenuDesktopFrameWidth,
+
+ PM_MenuBarPanelWidth,
+ PM_MenuBarItemSpacing,
+ PM_MenuBarVMargin,
+ PM_MenuBarHMargin,
+
+ PM_IndicatorWidth,
+ PM_IndicatorHeight,
+ PM_ExclusiveIndicatorWidth,
+ PM_ExclusiveIndicatorHeight,
+ PM_CheckListButtonSize,
+ PM_CheckListControllerSize,
+
+ PM_DialogButtonsSeparator,
+ PM_DialogButtonsButtonWidth,
+ PM_DialogButtonsButtonHeight,
+
+ PM_MdiSubWindowFrameWidth,
+ PM_MDIFrameWidth = PM_MdiSubWindowFrameWidth, //obsolete
+ PM_MdiSubWindowMinimizedWidth,
+ PM_MDIMinimizedWidth = PM_MdiSubWindowMinimizedWidth, //obsolete
+
+ PM_HeaderMargin,
+ PM_HeaderMarkSize,
+ PM_HeaderGripMargin,
+ PM_TabBarTabShiftHorizontal,
+ PM_TabBarTabShiftVertical,
+ PM_TabBarScrollButtonWidth,
+
+ PM_ToolBarFrameWidth,
+ PM_ToolBarHandleExtent,
+ PM_ToolBarItemSpacing,
+ PM_ToolBarItemMargin,
+ PM_ToolBarSeparatorExtent,
+ PM_ToolBarExtensionExtent,
+
+ PM_SpinBoxSliderHeight,
+
+ PM_DefaultTopLevelMargin,
+ PM_DefaultChildMargin,
+ PM_DefaultLayoutSpacing,
+
+ PM_ToolBarIconSize,
+ PM_ListViewIconSize,
+ PM_IconViewIconSize,
+ PM_SmallIconSize,
+ PM_LargeIconSize,
+
+ PM_FocusFrameVMargin,
+ PM_FocusFrameHMargin,
+
+ PM_ToolTipLabelFrameWidth,
+ PM_CheckBoxLabelSpacing,
+ PM_TabBarIconSize,
+ PM_SizeGripSize,
+ PM_DockWidgetTitleMargin,
+ PM_MessageBoxIconSize,
+ PM_ButtonIconSize,
+
+ PM_DockWidgetTitleBarButtonMargin,
+
+ PM_RadioButtonLabelSpacing,
+ PM_LayoutLeftMargin,
+ PM_LayoutTopMargin,
+ PM_LayoutRightMargin,
+ PM_LayoutBottomMargin,
+ PM_LayoutHorizontalSpacing,
+ PM_LayoutVerticalSpacing,
+ PM_TabBar_ScrollButtonOverlap,
+
+ PM_TextCursorWidth,
+
+ PM_TabCloseIndicatorWidth,
+ PM_TabCloseIndicatorHeight,
+
+ PM_ScrollView_ScrollBarSpacing,
+ PM_SubMenuOverlap,
+
+ // do not add any values below/greater than this
+ PM_CustomBase = 0xf0000000,
+
+ // The following are custom values needed to draw the S60Style according scalable UIs.
+ // Width of 9-part frame-corner
+ PM_Custom_FrameCornerWidth,
+ // Height of 9-part frame corner
+ PM_Custom_FrameCornerHeight,
+ // Bold line width
+ PM_Custom_BoldLineWidth,
+ // Thin line width
+ PM_Custom_ThinLineWidth,
+ // Height of a popup info messagebox
+ PM_Custom_MessageBoxHeight
+ };
+
+ };
+#else
+#pragma message ("Building in non-supported environment, this probably fails")
+#endif
+
+
+// Pixel metrics version information.
+class TPixelMetricsVersion
+ {
+ public:
+ TInt majorVersion;
+ TInt minorVersion;
+ };
+
+NONSHARABLE_CLASS(PixelMetrics)
+{
+ public:
+ static TPixelMetricsVersion Version();
+ static TInt PixelMetricValue(QStyle::PixelMetric);
+
+ private:
+ static TInt PixelMetricMenuValue( QStyle::PixelMetric menuValue, TRect mainPaneRect );
+ static TInt PixelMetricTabValue( QStyle::PixelMetric tabValue, TRect appWindow, TBool landscape );
+};
+
+#endif // PIXELMETRICS_H
diff --git a/util/s60pixelmetrics/pm_mapper.hrh b/util/s60pixelmetrics/pm_mapper.hrh
new file mode 100644
index 0000000000..c1b70c36b4
--- /dev/null
+++ b/util/s60pixelmetrics/pm_mapper.hrh
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utility applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PMMAPPER_HRH
+#define PMMAPPER_HRH
+
+// DATA TYPES
+
+// View IDs.
+enum
+ {
+ EPMMapperViewId = 1 // Base view.
+ };
+
+// Menu items (commands)
+enum
+ {
+ ECmdStartCalculations = 8500,
+ ECmdSwitchOrientation,
+ ECmdStatus,
+ ECmdSwitchOutput,
+ ECmdCreateHeaderFile
+ };
+
+#endif // PMMAPPER_HRH
+
+
+// End of File
diff --git a/util/s60pixelmetrics/pm_mapper.mmp b/util/s60pixelmetrics/pm_mapper.mmp
new file mode 100644
index 0000000000..ddbbc65efd
--- /dev/null
+++ b/util/s60pixelmetrics/pm_mapper.mmp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utility applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <data_caging_paths.hrh>
+#include <platform_paths.hrh>
+
+TARGET pm_mapper.exe
+TARGETTYPE exe
+UID 0x100039CE 0x2002121F
+
+CAPABILITY CAP_APPLICATION
+VENDORID VID_DEFAULT
+
+SOURCEPATH .
+SOURCE pm_mapperview.cpp
+SOURCE pm_mapperapp.cpp
+SOURCE pixel_metrics.cpp
+
+START RESOURCE pm_mapper.rss
+HEADER
+TARGETPATH APP_RESOURCE_DIR
+END
+
+START RESOURCE pm_mapper_reg.rss
+TARGETPATH \private\10003a3f\apps
+END
+
+APP_LAYER_SYSTEMINCLUDE
+USERINCLUDE .
+
+LIBRARY eikcoctl.lib
+LIBRARY avkon.lib
+LIBRARY euser.lib
+LIBRARY apparc.lib
+LIBRARY cone.lib
+LIBRARY eikcore.lib
+LIBRARY bafl.lib
+LIBRARY eikctl.lib
+LIBRARY apgrfx.lib
+LIBRARY aknnotify.lib
+LIBRARY ws32.lib
+LIBRARY commonengine.lib
+LIBRARY fbscli.lib
+LIBRARY eikdlg.lib
+LIBRARY aknskins.lib
+LIBRARY gdi.lib
+LIBRARY CentralRepository.lib
+LIBRARY efsrv.lib
+LIBRARY cdlengine.lib
+LIBRARY AknLayout2.lib
+LIBRARY AknLayout2Scalable.lib
+
+// End of File
diff --git a/util/s60pixelmetrics/pm_mapper.pkg b/util/s60pixelmetrics/pm_mapper.pkg
new file mode 100644
index 0000000000..f5a2a9ba74
--- /dev/null
+++ b/util/s60pixelmetrics/pm_mapper.pkg
@@ -0,0 +1,32 @@
+; ==============================================================================
+; Name : PMMapper.pkg
+; Part of : Pixel Metrics Mapper
+; Description : Package file for pixel metrics mapper
+; SIS creation.
+; Version :
+;
+; Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+; This material, including documentation and any related
+; computer programs, is protected by copyright controlled by
+; Nokia Corporation. All rights are reserved. Copying,
+; including reproducing, storing, adapting or translating, any
+; or all of this material requires the prior written consent of
+; Nokia Corporation. This material also contains confidential
+; information which may not be disclosed to others without the
+; prior written consent of Nokia Corporation.
+; ==============================================================================
+
+
+;Header
+#{"PMMapper"},(0x2002121F),1,0,0
+
+;Localised Vendor name
+%{"Nokia Test EN"}
+
+;Unique Vendor name
+:"Vendor"
+
+;Files to install
+"\Epoc32\release\armv5\urel\pm_mapper.exe" -"!:\sys\bin\pm_mapper.exe"
+"\epoc32\data\z\private\10003a3f\apps\pm_mapper_reg.rsc" -"!:\private\10003a3f\import\apps\pm_mapper_reg.rsc"
+"\epoc32\data\Z\Resource\Apps\pm_mapper.RSC" -"!:\resource\apps\pm_mapper.rsc"
diff --git a/util/s60pixelmetrics/pm_mapper.rss b/util/s60pixelmetrics/pm_mapper.rss
new file mode 100644
index 0000000000..b7e6d3d6d1
--- /dev/null
+++ b/util/s60pixelmetrics/pm_mapper.rss
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utility applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+// RESOURCE IDENTIFIER
+NAME TATR
+
+
+// INCLUDES
+#include <eikon.rh>
+#include <avkon.rh>
+#include <avkon.mbg>
+#include <avkon.rsg>
+#include <avkon.hrh>
+#include <uikon.hrh>
+#include <avkonIcons.hrh>
+#include <data_caging_paths_strings.hrh>
+#include <appinfo.rh>
+
+#include "pm_mapper.hrh"
+
+
+// RESOURCE DEFINITIONS
+
+// -----------------------------------------------------------------------------
+//
+// RSS_SIGNATURE
+//
+//
+// -----------------------------------------------------------------------------
+//
+RESOURCE RSS_SIGNATURE { }
+
+
+// -----------------------------------------------------------------------------
+//
+// TBUF
+//
+//
+// -----------------------------------------------------------------------------
+//
+RESOURCE TBUF { buf = "pm_mapper"; }
+
+
+// -----------------------------------------------------------------------------
+//
+// EIK_APP_INFO
+//
+//
+// -----------------------------------------------------------------------------
+//
+RESOURCE EIK_APP_INFO
+ {
+ }
+
+// -----------------------------------------------------------------------------
+//
+// r_pmmapper_localisable_app_info
+// Captions for this application.
+//
+// -----------------------------------------------------------------------------
+//
+RESOURCE LOCALISABLE_APP_INFO r_pmmapper_localisable_app_info
+ {
+ short_caption = "pm_mapper";
+ caption_and_icon =
+ CAPTION_AND_ICON_INFO
+ {
+ caption = "PixelMetricsMapper";
+ };
+ }
+
+// -----------------------------------------------------------------------------
+//
+// r_pmmapper_view
+//
+//
+// -----------------------------------------------------------------------------
+//
+RESOURCE AVKON_VIEW r_pmmapper_view
+ {
+ menubar = r_pmmapper_view_menu;
+ cba = R_AVKON_SOFTKEYS_OPTIONS_EXIT;
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// r_pmmapper_view_menu
+//
+//
+// -----------------------------------------------------------------------------
+//
+RESOURCE MENU_BAR r_pmmapper_view_menu
+ {
+ titles=
+ {
+ MENU_TITLE { txt = "A"; menu_pane = r_pmmapper_system_menu; }
+ };
+ }
+
+// -----------------------------------------------------------------------------
+//
+// r_pmmapper_system_menu
+//
+//
+// -----------------------------------------------------------------------------
+//
+RESOURCE MENU_PANE r_pmmapper_system_menu
+ {
+ items =
+ {
+ MENU_ITEM { command = ECmdStartCalculations; txt = "Start calculations"; },
+ MENU_ITEM { command = ECmdSwitchOrientation; txt = "Switch orientation"; },
+ MENU_ITEM { command = ECmdStatus; txt = "Status"; },
+ MENU_ITEM { command = ECmdSwitchOutput; txt = "Switch output (file/screen)"; },
+ MENU_ITEM { command = ECmdCreateHeaderFile; txt = "Create header file"; }
+ };
+ }
+
+
+// End of File
diff --git a/util/s60pixelmetrics/pm_mapper_reg.rss b/util/s60pixelmetrics/pm_mapper_reg.rss
new file mode 100644
index 0000000000..42236e9ca0
--- /dev/null
+++ b/util/s60pixelmetrics/pm_mapper_reg.rss
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utility applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <appinfo.rh>
+#include <pm_mapper.rsg>
+#include <data_caging_paths_strings.hrh>
+
+UID2 KUidAppRegistrationResourceFile
+UID3 0x2002121F // application UID
+
+RESOURCE APP_REGISTRATION_INFO
+ {
+ app_file = "pm_mapper";
+ localisable_resource_file =
+ APP_RESOURCE_DIR"\\pm_mapper";
+ localisable_resource_id = R_PMMAPPER_LOCALISABLE_APP_INFO;
+ }
+
+// End of File
diff --git a/util/s60pixelmetrics/pm_mapperapp.cpp b/util/s60pixelmetrics/pm_mapperapp.cpp
new file mode 100644
index 0000000000..d905ccef74
--- /dev/null
+++ b/util/s60pixelmetrics/pm_mapperapp.cpp
@@ -0,0 +1,959 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utility applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// INCLUDE FILES
+
+#include <avkon.rsg>
+#include <avkon.hrh>
+#include "pm_mapper.hrh"
+#include "pm_mapperapp.h"
+#include "pm_mapperview.h"
+#include <pm_mapper.rsg>
+
+#include <BldVariant.hrh>
+
+#include <w32std.h>
+#include <apgwgnam.h>
+#include <eikstart.h>
+#include <eikenv.h>
+#include <f32file.h>
+
+#include <avkon.hrh>
+#include <aknenv.h>
+
+#include <aknnotedialog.h>
+#include <stringloader.h>
+#include <coneresloader.h>
+#include <aknglobalnote.h>
+
+#include <CentralRepository.h>
+
+#include <Aknsutils.h>
+#include <AknUtils.h>
+#include "pixel_metrics.h"
+
+#include <avkon.mbg>
+
+#include <AknLayoutConfig.h>
+#include <aknsgcc.h>
+
+typedef TBuf<2048> TMySmallBuffer;
+typedef TBuf<8192> TMyBigBuffer;
+
+_LIT(KLayoutSourceFileAndPath, "\\private\\2002121f\\pm_layout.cpp");
+_LIT(KPixelMetricsDataFiles, "\\private\\2002121f\\*.txt");
+_LIT(KOpenBrace, "{");
+_LIT(KComma, ",");
+_LIT(KColon, ":");
+_LIT(KTab, "\t");
+_LIT(KEndBraceWithCommaAndCRLF, "},\n");
+_LIT(KCRLF, "\n");
+
+// Number of header lines in layout data.
+const TInt KHeaderValues = 4;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// C++ constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CPixelMetricsMapperAppUi::CPixelMetricsMapperAppUi() : iFileOutputOn(EFalse)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CPixelMetricsMapperAppUi::~CPixelMetricsMapperAppUi()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperAppUi::ConstructL()
+ {
+ BaseConstructL();
+
+ CEikonEnv& eikEnv = *CEikonEnv::Static();
+
+ eikEnv.WsSession().ComputeMode(
+ RWsSession::EPriorityControlDisabled );
+ RThread().SetProcessPriority( EPriorityHigh );
+
+ CPixelMetricsMapperView* view = new( ELeave ) CPixelMetricsMapperView;
+ CleanupStack::PushL( view );
+ view->ConstructL();
+ CleanupStack::Pop(); // view
+ AddViewL(view); // transfer ownership to CAknViewAppUi
+ iView = view;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CPixelMetricsMapperAppUi::HandleKeyEventL(
+ const TKeyEvent& /*aKeyEvent*/,
+ TEventCode /*aType*/ )
+ {
+ return EKeyWasNotConsumed;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperAppUi::HandleCommandL( TInt aCommand )
+ {
+ switch ( aCommand )
+ {
+ case EAknSoftkeyExit:
+ case EEikCmdExit:
+ Exit();
+ break;
+ case ECmdSwitchOutput:
+ {
+ HBufC* buffer = HBufC::NewLC( 100 );
+ TPtr bufferPtr = buffer->Des();
+ TBool last = ETrue;
+ bufferPtr.Append(_L("Output switched to "));
+ iFileOutputOn = !iFileOutputOn;
+ if (iFileOutputOn)
+ bufferPtr.Append(_L("file."));
+ else
+ bufferPtr.Append(_L("screen."));
+ ShowL( *buffer, last );
+ CleanupStack::PopAndDestroy( buffer );
+ }
+ break;
+ case ECmdStatus:
+ {
+ ClearL();
+
+ // layout
+ HBufC* buffer = HBufC::NewLC( 100 );
+ TPtr bufferPtr = buffer->Des();
+ TBool last = ETrue;
+
+ // Orientation
+ bufferPtr.Append(_L("Orientation: "));
+ bufferPtr.AppendNum((TInt)iAvkonAppUi->Orientation());
+ ShowL( *buffer, last );
+ bufferPtr.Zero();
+
+ // Output
+ bufferPtr.Append(_L("Output: "));
+ if (iFileOutputOn) bufferPtr.Append(_L("File"));
+ else bufferPtr.Append(_L("Screen"));
+ ShowL( *buffer, last );
+ bufferPtr.Zero();
+
+ CAknLayoutConfig::TScreenMode localAppScreenMode = CAknSgcClient::ScreenMode();
+ TInt hashValue = localAppScreenMode.ScreenStyleHash();
+ TPixelsTwipsAndRotation pixels = CAknSgcClient::PixelsAndRotation();
+ TSize pixelSize = pixels.iPixelSize;
+
+ bufferPtr.Append(_L("LayoutName: "));
+
+ if ( (pixelSize.iWidth == 320 || pixelSize.iWidth == 240 )&&
+ (pixelSize.iHeight == 320 || pixelSize.iHeight == 240 ))
+ {
+ if (hashValue==0x996F7AA7)
+ bufferPtr.Append(_L("QVGA2"));
+ else
+ bufferPtr.Append(_L("QVGA1"));
+ }
+ else if ((pixelSize.iWidth == 640 || pixelSize.iWidth == 360 )&&
+ (pixelSize.iHeight == 360 || pixelSize.iHeight == 640 ))
+ {
+ bufferPtr.Append(_L("nHD"));
+ }
+ else if ((pixelSize.iWidth == 640 || pixelSize.iWidth == 480 )&&
+ (pixelSize.iHeight == 480 || pixelSize.iHeight == 640 ))
+ {
+ bufferPtr.Append(_L("VGA"));
+ }
+ else if ((pixelSize.iWidth == 352 || pixelSize.iWidth == 800 )&&
+ (pixelSize.iHeight == 800 || pixelSize.iHeight == 352 ))
+ {
+ bufferPtr.Append(_L("E90"));
+ }
+ else if ((pixelSize.iWidth == 320 || pixelSize.iWidth == 480 ||
+ pixelSize.iWidth == 240 || pixelSize.iWidth == 640 )&&
+ (pixelSize.iHeight == 320 || pixelSize.iHeight == 480 ||
+ pixelSize.iHeight == 240 || pixelSize.iHeight == 640))
+ {
+ bufferPtr.Append(_L("HVGA"));
+ }
+ else if ((pixelSize.iWidth == 480 || pixelSize.iWidth == 854 ||
+ pixelSize.iWidth == 848 || pixelSize.iWidth == 800 )&&
+ (pixelSize.iHeight == 800 || pixelSize.iHeight == 480 ||
+ pixelSize.iHeight == 848 || pixelSize.iHeight == 854))
+ {
+ bufferPtr.Append(_L("WVGA"));
+ }
+ else
+ {
+ bufferPtr.Append(_L("Unknown"));
+ }
+
+ ShowL( *buffer, last );
+ bufferPtr.Zero();
+ CleanupStack::PopAndDestroy( buffer );
+ }
+ break;
+ case ECmdSwitchOrientation:
+ {
+ ClearL();
+ HBufC* buffer = HBufC::NewLC( 100 );
+ TPtr bufferPtr = buffer->Des();
+ TBool last = ETrue;
+
+ #ifndef __SERIES60_31__
+ if (!iAvkonAppUi->OrientationCanBeChanged())
+ {
+ bufferPtr.Append(_L("Orientation cannot be changed."));
+ ShowL( *buffer, last );
+ bufferPtr.Zero();
+ CleanupStack::PopAndDestroy( buffer );
+ break;
+ }
+ #endif //__SERIES60_31__
+
+ if ( iAvkonAppUi->Orientation() == CAknAppUiBase::EAppUiOrientationPortrait)
+ {
+ iAvkonAppUi->SetOrientationL(CAknAppUiBase::EAppUiOrientationLandscape);
+ }
+ else if (iAvkonAppUi->Orientation() == CAknAppUiBase::EAppUiOrientationLandscape)
+ {
+ iAvkonAppUi->SetOrientationL(CAknAppUiBase::EAppUiOrientationPortrait);
+ }
+ else
+ {
+ // unspecified
+ iAvkonAppUi->SetOrientationL(CAknAppUiBase::EAppUiOrientationLandscape);
+ }
+ bufferPtr.Append(_L("Orientation changed."));
+ ShowL( *buffer, last );
+ bufferPtr.Zero();
+ CleanupStack::PopAndDestroy( buffer );
+ break;
+ }
+ case ECmdStartCalculations:
+ {
+ ClearL();
+ // Get known values
+ TInt index = 0;
+ TBool last = EFalse;
+ if (iFileOutputOn)
+ {
+ TRect screenRect;
+ AknLayoutUtils::LayoutMetricsRect(
+ AknLayoutUtils::EApplicationWindow,
+ screenRect );
+
+ // Add screen dimensions
+ TInt height = screenRect.Height();
+ TInt width = screenRect.Width();
+ TBuf16<32> tgt;
+ // HEIGHT
+ tgt.Append(_L("height: \t"));
+ tgt.AppendNum(height, EDecimal); // put max height into text file
+ ShowL( tgt, last );
+ tgt.Zero();
+ // WIDTH
+ tgt.Append(_L("width: \t"));
+ tgt.AppendNum(width, EDecimal); // put max width into text file
+ ShowL( tgt, last );
+ tgt.Zero();
+ // VERSION
+ TPixelMetricsVersion version = PixelMetrics::Version();
+ tgt.Append(_L("major_version: \t"));
+ tgt.AppendNum(version.majorVersion, EDecimal); // put major version into text file
+ ShowL( tgt, last );
+ tgt.Zero();
+ tgt.Append(_L("minor_version: \t"));
+ tgt.AppendNum(version.minorVersion, EDecimal); // put minor version into text file
+ ShowL( tgt, last );
+ tgt.Zero();
+ }
+
+ TInt myValue = KErrNotFound;
+ for (;;)
+ {
+ if (index==QStyle::PM_Custom_MessageBoxHeight)
+ {
+ last = ETrue;
+ }
+ myValue = PixelMetrics::PixelMetricValue(static_cast<QStyle::PixelMetric>(index));
+ ShowSingleValueL( index, myValue, last );
+
+ if (last) break;
+ // if last before custom values, "jump" to custom base
+ if (index==QStyle::PM_SubMenuOverlap) index = QStyle::PM_CustomBase;
+ index++;
+ }
+ }
+ break;
+ case ECmdCreateHeaderFile:
+ CreateHeaderFileL();
+ break;
+ default:
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperAppUi::ShowL( const TDesC& aText, TBool& aLast, const TBool& aFileOutput )
+ {
+ _LIT( KTestPrefix, "\t" );
+
+ HBufC* buffer = HBufC::NewLC( aText.Length() + KTestPrefix().Length() );
+ TPtr ptr = buffer->Des();
+ ptr.Append( KTestPrefix );
+ ptr.Append( aText );
+ iView->ShowL( *buffer, aLast, aFileOutput );
+ CleanupStack::PopAndDestroy( buffer );
+ }
+
+void CPixelMetricsMapperAppUi::ShowSingleValueL(TInt& aPixelMetric, TInt& aValue, TBool& aLast )
+ {
+ HBufC* buffer = HBufC::NewLC( 100 );
+ TPtr bufferPtr = buffer->Des();
+
+ switch (aPixelMetric)
+ {
+ case QStyle::PM_DockWidgetTitleMargin:
+ bufferPtr.Append(_L("DockTitleMargin: "));
+ break;
+ case QStyle::PM_DockWidgetTitleBarButtonMargin:
+ bufferPtr.Append(_L("DockTitleBtnMargin: "));
+ break;
+ case QStyle::PM_ButtonMargin:
+ bufferPtr.Append(_L("ButtonMargin: "));
+ break;
+ case QStyle::PM_ButtonDefaultIndicator:
+ bufferPtr.Append(_L("ButtonDefaultIndicator: "));
+ break;
+ case QStyle::PM_MdiSubWindowFrameWidth:
+ bufferPtr.Append(_L("MdiSubWndFrameW: "));
+ break;
+ case QStyle::PM_ComboBoxFrameWidth:
+ bufferPtr.Append(_L("ComboBoxFrameWidth: "));
+ break;
+ case QStyle::PM_SpinBoxFrameWidth:
+ bufferPtr.Append(_L("SpinBoxFrameWidth: "));
+ break;
+ case QStyle::PM_DefaultFrameWidth:
+ bufferPtr.Append(_L("DefaultFrameWidth: "));
+ break;
+ case QStyle::PM_RadioButtonLabelSpacing:
+ bufferPtr.Append(_L("RadioButtonLabelSpc: "));
+ break;
+ case QStyle::PM_CheckBoxLabelSpacing:
+ bufferPtr.Append(_L("CheckBoxLabelSpacing: "));
+ break;
+ case QStyle::PM_ToolTipLabelFrameWidth:
+ bufferPtr.Append(_L("ToolTipLabelFrameW: "));
+ break;
+ case QStyle::PM_ListViewIconSize:
+ bufferPtr.Append(_L("ListViewIconSize: "));
+ break;
+ case QStyle::PM_LargeIconSize:
+ bufferPtr.Append(_L("LargeIconSize: "));
+ break;
+ case QStyle::PM_IconViewIconSize:
+ bufferPtr.Append(_L("IconViewIconSize: "));
+ break;
+ case QStyle::PM_TabBarIconSize:
+ bufferPtr.Append(_L("TabBarIconSize: "));
+ break;
+ case QStyle::PM_MessageBoxIconSize:
+ bufferPtr.Append(_L("MessageBoxIconSize: "));
+ break;
+ case QStyle::PM_ButtonIconSize:
+ bufferPtr.Append(_L("ButtonIconSize: "));
+ break;
+ case QStyle::PM_TextCursorWidth:
+ bufferPtr.Append(_L("TextCursorWidth: "));
+ break;
+ case QStyle::PM_SliderLength:
+ bufferPtr.Append(_L("SliderLength: "));
+ break;
+ case QStyle::PM_SliderThickness:
+ bufferPtr.Append(_L("SliderThickness: "));
+ break;
+ case QStyle::PM_SliderTickmarkOffset:
+ bufferPtr.Append(_L("SliderTickmarkOffset: "));
+ break;
+ case QStyle::PM_SliderControlThickness:
+ bufferPtr.Append(_L("SliderCntrlThickness: "));
+ break;
+ case QStyle::PM_SliderSpaceAvailable:
+ bufferPtr.Append(_L("SliderSpaceAvailable: "));
+ break;
+ case QStyle::PM_MenuBarItemSpacing:
+ bufferPtr.Append(_L("MenuBarItemSpacing: "));
+ break;
+ case QStyle::PM_MenuBarHMargin:
+ bufferPtr.Append(_L("MenuBarHMargin: "));
+ break;
+ case QStyle::PM_MenuBarVMargin:
+ bufferPtr.Append(_L("MenuBarVMargin: "));
+ break;
+ case QStyle::PM_ToolBarItemSpacing:
+ bufferPtr.Append(_L("ToolBarItemSpacing: "));
+ break;
+ case QStyle::PM_ToolBarFrameWidth:
+ bufferPtr.Append(_L("ToolBarFrameWidth: "));
+ break;
+ case QStyle::PM_ToolBarItemMargin:
+ bufferPtr.Append(_L("ToolBarItemMargin: "));
+ break;
+ case QStyle::PM_LayoutLeftMargin:
+ bufferPtr.Append(_L("LayoutLeftMargin: "));
+ break;
+ case QStyle::PM_LayoutRightMargin:
+ bufferPtr.Append(_L("LayoutRightMargin: "));
+ break;
+ case QStyle::PM_LayoutTopMargin:
+ bufferPtr.Append(_L("LayoutTopMargin: "));
+ break;
+ case QStyle::PM_LayoutBottomMargin:
+ bufferPtr.Append(_L("LayoutBottomMargin: "));
+ break;
+ case QStyle::PM_LayoutHorizontalSpacing:
+ bufferPtr.Append(_L("LayoutHSpacing: "));
+ break;
+ case QStyle::PM_LayoutVerticalSpacing:
+ bufferPtr.Append(_L("LayoutVSpacing: "));
+ break;
+ case QStyle::PM_MaximumDragDistance:
+ bufferPtr.Append(_L("MaxDragDistance: "));
+ break;
+ case QStyle::PM_ScrollBarExtent:
+ bufferPtr.Append(_L("ScrollBarExtent: "));
+ break;
+ case QStyle::PM_ScrollBarSliderMin:
+ bufferPtr.Append(_L("ScrollBarSliderMin: "));
+ break;
+ case QStyle::PM_MenuBarPanelWidth:
+ bufferPtr.Append(_L("MenuBarPanelWidth: "));
+ break;
+ case QStyle::PM_ProgressBarChunkWidth:
+ bufferPtr.Append(_L("ProgBarChunkWidth: "));
+ break;
+ case QStyle::PM_TabBarTabOverlap:
+ bufferPtr.Append(_L("TabBarTabOverlap: "));
+ break;
+ case QStyle::PM_TabBarTabHSpace:
+ bufferPtr.Append(_L("TabBarTabHSpace: "));
+ break;
+ case QStyle::PM_TabBarTabVSpace:
+ bufferPtr.Append(_L("TabBarTabVSpace: "));
+ break;
+ case QStyle::PM_TabBarBaseHeight:
+ bufferPtr.Append(_L("TabBarBaseHeight: "));
+ break;
+ case QStyle::PM_TabBarBaseOverlap:
+ bufferPtr.Append(_L("TabBarBaseOverlap: "));
+ break;
+ case QStyle::PM_TabBarScrollButtonWidth:
+ bufferPtr.Append(_L("TabBarScrollBtnWidth: "));
+ break;
+ case QStyle::PM_TabBarTabShiftHorizontal:
+ bufferPtr.Append(_L("TabBarTabShiftH: "));
+ break;
+ case QStyle::PM_TabBarTabShiftVertical:
+ bufferPtr.Append(_L("TabBarTabShiftV: "));
+ break;
+ case QStyle::PM_MenuPanelWidth:
+ bufferPtr.Append(_L("MenuPanelWidth: "));
+ break;
+ case QStyle::PM_MenuHMargin:
+ bufferPtr.Append(_L("MenuHMargin: "));
+ break;
+ case QStyle::PM_MenuVMargin:
+ bufferPtr.Append(_L("MenuVMargin: "));
+ break;
+ case QStyle::PM_MenuDesktopFrameWidth:
+ bufferPtr.Append(_L("MenuFrameWidth: "));
+ break;
+ case QStyle::PM_SmallIconSize:
+ bufferPtr.Append(_L("SmallIconSize: "));
+ break;
+ case QStyle::PM_FocusFrameHMargin:
+ bufferPtr.Append(_L("FocusFrameHMargin: "));
+ break;
+ case QStyle::PM_FocusFrameVMargin:
+ bufferPtr.Append(_L("FocusFrameVMargin: "));
+ break;
+ case QStyle::PM_ToolBarIconSize:
+ bufferPtr.Append(_L("ToolBarIconSize: "));
+ break;
+ case QStyle::PM_TitleBarHeight: // use titlepane height
+ bufferPtr.Append(_L("TitleBarHeight: "));
+ break;
+ case QStyle::PM_IndicatorWidth:
+ bufferPtr.Append(_L("IndicatorWidth: "));
+ break;
+ case QStyle::PM_IndicatorHeight:
+ bufferPtr.Append(_L("IndicatorHeight: "));
+ break;
+ case QStyle::PM_ExclusiveIndicatorHeight:
+ bufferPtr.Append(_L("ExclusiveIndHeight: "));
+ break;
+ case QStyle::PM_ExclusiveIndicatorWidth:
+ bufferPtr.Append(_L("ExclusiveIndWidth: "));
+ break;
+ case QStyle::PM_HeaderMargin: // not in S60
+ bufferPtr.Append(_L("HeaderMargin: "));
+ break;
+ case QStyle::PM_MenuScrollerHeight: // not in S60
+ bufferPtr.Append(_L("MenuScrollerHeight: "));
+ break;
+ case QStyle::PM_MenuTearoffHeight: // not in S60
+ bufferPtr.Append(_L("MenuTearoffHeight: "));
+ break;
+ case QStyle::PM_DockWidgetFrameWidth: // not in S60
+ bufferPtr.Append(_L("DockFrameWidth: "));
+ break;
+ case QStyle::PM_DockWidgetSeparatorExtent: // not in S60
+ bufferPtr.Append(_L("DockSepExtent: "));
+ break;
+ case QStyle::PM_MdiSubWindowMinimizedWidth: //no such thing in S60
+ bufferPtr.Append(_L("MdiSubWndMinWidth: "));
+ break;
+ case QStyle::PM_HeaderGripMargin: // not in S60
+ bufferPtr.Append(_L("HeaderGripMargin: "));
+ break;
+ case QStyle::PM_SplitterWidth: // not in S60
+ bufferPtr.Append(_L("SplitterWidth: "));
+ break;
+ case QStyle::PM_ToolBarExtensionExtent: // not in S60
+ bufferPtr.Append(_L("ToolBarExtExtent: "));
+ break;
+ case QStyle::PM_ToolBarSeparatorExtent: // not in S60
+ bufferPtr.Append(_L("ToolBarSepExtent: "));
+ break;
+ case QStyle::PM_ToolBarHandleExtent: // not in s60
+ bufferPtr.Append(_L("ToolBarHandleExtent: "));
+ break;
+ case QStyle::PM_MenuButtonIndicator: // none???
+ bufferPtr.Append(_L("MenuButtonIndicator: "));
+ break;
+ case QStyle::PM_ButtonShiftHorizontal: //none in 3.x
+ bufferPtr.Append(_L("ButtonShiftHorizontal: "));
+ break;
+ case QStyle::PM_ButtonShiftVertical: // none in 3.x
+ bufferPtr.Append(_L("ButtonShiftVertical: "));
+ break;
+ case QStyle::PM_TabBar_ScrollButtonOverlap: // not used in S60 - tab arrows are on left and right side of tab group - not together
+ bufferPtr.Append(_L("TabScrollBtnOverlap: "));
+ break;
+ case QStyle::PM_SizeGripSize: // use default
+ bufferPtr.Append(_L("SizeGripSize: "));
+ break;
+ case QStyle::PM_DockWidgetHandleExtent:
+ bufferPtr.Append(_L("DockWdgtHandleExt: "));
+ break;
+ case QStyle::PM_CheckListButtonSize:
+ bufferPtr.Append(_L("CheckListButtonSize: "));
+ break;
+ case QStyle::PM_CheckListControllerSize:
+ bufferPtr.Append(_L("CheckListCntlerSize: "));
+ break;
+ case QStyle::PM_DialogButtonsSeparator:
+ bufferPtr.Append(_L("DialogBtnSeparator: "));
+ break;
+ case QStyle::PM_DialogButtonsButtonWidth:
+ bufferPtr.Append(_L("DialogBtnWidth: "));
+ break;
+ case QStyle::PM_DialogButtonsButtonHeight:
+ bufferPtr.Append(_L("DialogBtnHeight: "));
+ break;
+ case QStyle::PM_HeaderMarkSize:
+ bufferPtr.Append(_L("HeaderMarkSize: "));
+ break;
+ case QStyle::PM_SpinBoxSliderHeight:
+ bufferPtr.Append(_L("SpinBoxSliderHeight: "));
+ break;
+ case QStyle::PM_DefaultTopLevelMargin:
+ bufferPtr.Append(_L("DefaultTopLvlMrg: "));
+ break;
+ case QStyle::PM_DefaultChildMargin:
+ bufferPtr.Append(_L("DefaultChildMrg: "));
+ break;
+ case QStyle::PM_DefaultLayoutSpacing:
+ bufferPtr.Append(_L("DefaultlayoutSpc: "));
+ break;
+ case QStyle::PM_TabCloseIndicatorWidth:
+ bufferPtr.Append(_L("TabCloseIndWidth: "));
+ break;
+ case QStyle::PM_TabCloseIndicatorHeight:
+ bufferPtr.Append(_L("TabCloseIndHeight: "));
+ break;
+ case QStyle::PM_ScrollView_ScrollBarSpacing:
+ bufferPtr.Append(_L("ScrollViewBarSpc: "));
+ break;
+ case QStyle::PM_SubMenuOverlap:
+ bufferPtr.Append(_L("SubMenuOverlap: "));
+ break;
+ case QStyle::PM_Custom_FrameCornerHeight:
+ bufferPtr.Append(_L("C_FrCornerHeight: "));
+ break;
+ case QStyle::PM_Custom_FrameCornerWidth:
+ bufferPtr.Append(_L("C_FrCornerWidth: "));
+ break;
+ case QStyle::PM_Custom_ThinLineWidth:
+ bufferPtr.Append(_L("C_ThinLineWidth: "));
+ break;
+ case QStyle::PM_Custom_BoldLineWidth:
+ bufferPtr.Append(_L("C_BoldLineWidth: "));
+ break;
+ case QStyle::PM_Custom_MessageBoxHeight:
+ bufferPtr.Append(_L("C_MsgBoxHeight: "));
+ break;
+ default:
+ bufferPtr.Append(_L("Default: "));
+ break;
+ }
+
+ if (iFileOutputOn)
+ {
+ bufferPtr.Append('\t');
+ }
+ bufferPtr.AppendNum(aValue);
+ bufferPtr.Append(_L(" "));
+ ShowL( *buffer, aLast, iFileOutputOn );
+ CleanupStack::PopAndDestroy( buffer );
+ }
+
+void CPixelMetricsMapperAppUi::ClearL()
+ {
+ iView->ClearL();
+ }
+
+void CPixelMetricsMapperAppUi::CreateHeaderFileL() const
+ {
+ // Open/create resulting file.
+ RFile file;
+ HBufC* layoutFile = HBufC::NewLC( KMaxFileName );
+ *layoutFile = KLayoutSourceFileAndPath;
+ TFileName fileName = *layoutFile;
+ CleanupStack::PopAndDestroy(layoutFile);
+ RFs& fs = CEikonEnv::Static()->FsSession();
+ TInt error = file.Open(fs,fileName, EFileWrite|EFileShareAny|EFileStreamText );
+ if (error==KErrNotFound)
+ {
+ file.Create(fs,fileName, EFileWrite|EFileShareAny|EFileStreamText);
+ }
+ CleanupClosePushL( file );
+ file.SetSize( 0 );
+
+ // Make all writes as from textfile.
+ TFileText textFile;
+ textFile.Set( file );
+ textFile.Seek( ESeekStart );
+
+ // Take all layout files from private folder.
+ CDir* dirList;
+ User::LeaveIfError(fs.GetDir(
+ KPixelMetricsDataFiles,
+ KEntryAttMaskSupported,
+ ESortByName,
+ dirList));
+
+ TMySmallBuffer bufferLayoutHdr;
+ TMyBigBuffer bufferPMData;
+ TInt fileCount = dirList->Count();
+ for (TInt i=0;i<fileCount;i++)
+ {
+ // open sourcefile
+ RFile sourceFile;
+ TFileName layoutFile = (*dirList)[i].iName;
+ User::LeaveIfError( sourceFile.Open(
+ fs,layoutFile, EFileRead|EFileShareAny|EFileStreamText ));
+ CleanupClosePushL( sourceFile );
+
+ // Make all reads as from textfile.
+ TFileText textSourceFile;
+ textSourceFile.Set( sourceFile );
+ TFileName layoutName = CreateLayoutNameL( textSourceFile );
+
+ // rewind - just in case.
+ textSourceFile.Seek( ESeekStart );
+ TFileName oneline;
+ bufferLayoutHdr.Append(KOpenBrace);
+ bufferPMData.Append(KOpenBrace);
+ TInt loop = 0;
+ FOREVER
+ {
+ if( textSourceFile.Read(oneline) != KErrNone )
+ {
+ break;
+ }
+ // Add commas for all but first line
+ if (loop != 0)
+ {
+ if ( loop <= KHeaderValues-1)
+ {
+ bufferLayoutHdr.Append(KComma);
+ }
+ else
+ {
+ if (loop != KHeaderValues)
+ {
+ bufferPMData.Append(KComma);
+ }
+ }
+ if (loop==KHeaderValues)
+ {
+ bufferLayoutHdr.Append(_L(",QLatin1String(\""));
+ bufferLayoutHdr.Append(layoutName);
+ bufferLayoutHdr.Append(_L("\")"));
+ }
+ }
+ // Remove pixel metrics name and ":"
+ oneline = oneline.Mid(oneline.Find(KColon)+1);
+ // Remove tab
+ oneline = oneline.Mid(oneline.Find(KTab)+1);
+ // remove crap from the end of line
+ TLex lex(oneline);
+ TInt nextValue = -666;
+ User::LeaveIfError( lex.Val(nextValue) );
+ if ( loop <= KHeaderValues-1)
+ {
+ bufferLayoutHdr.AppendNum(nextValue);
+ }
+ else
+ {
+ if (nextValue == -909)
+ bufferPMData.Append(_L("ECommonStyleValue"));
+ else
+ bufferPMData.AppendNum(nextValue);
+ }
+ oneline.Zero();
+ loop++;
+ }
+ file.Flush();
+ bufferLayoutHdr.Append(KEndBraceWithCommaAndCRLF);
+ bufferPMData.Append(KEndBraceWithCommaAndCRLF);
+ CleanupStack::PopAndDestroy(); //sourceFile
+ }
+
+ if (fileCount > 0)
+ {
+ bufferLayoutHdr = bufferLayoutHdr.Left(bufferLayoutHdr.Length()-2);
+ bufferPMData = bufferPMData.Left(bufferPMData.Length()-2);
+ textFile.Write(bufferLayoutHdr);
+ textFile.Write(KCRLF);
+ textFile.Write(bufferPMData);
+ }
+ delete dirList;
+
+ CleanupStack::PopAndDestroy(); //file
+ }
+
+TFileName CPixelMetricsMapperAppUi::CreateLayoutNameL(TFileText& aFileHandle) const
+{
+ aFileHandle.Seek(ESeekStart);
+ // Layout data is deployed like this:
+ // first line - height
+ // second line - width
+ TFileName lines;
+ TFileName layoutName;
+
+ TInt height = -666;
+ TInt width = -666;
+ // Collect name information.
+ for (TInt i=0; i<6; i++)
+ {
+ User::LeaveIfError(aFileHandle.Read(lines));
+ // Remove pixel metrics name and ":"
+ lines = lines.Mid(lines.Find(KColon)+1);
+ // Remove tab
+ lines = lines.Mid(lines.Find(KTab)+1);
+ TLex myLexer(lines);
+ TInt error = KErrNone;
+ if (i==0) //height is first
+ {
+ error = myLexer.Val(height);
+ }
+ if (i==1) //width is second
+ {
+ error = myLexer.Val(width);
+ }
+ User::LeaveIfError(error);
+ }
+
+ // Interpret results and write name to buffer.
+ if ( (width == 240 && height == 320) ||
+ (width == 320 && height == 240))
+ {
+ layoutName.Append(_L("QVGA "));
+ }
+ else if ( (width == 360 && height == 640) ||
+ (width == 640 && height == 360))
+ {
+ layoutName.Append(_L("NHD "));
+ }
+ else if ( (width == 480 && height == 640) ||
+ (width == 640 && height == 480))
+ {
+ layoutName.Append(_L("VGA "));
+ }
+ else if ( (width == 800 && height == 352) ||
+ (width == 352 && height == 800))
+ {
+ layoutName.Append(_L("E90 "));
+ }
+ else if ( (width == 800 && height == 480) ||
+ (width == 480 && height == 800) ||
+ (width == 848 && height == 480) ||
+ (width == 480 && height == 848) ||
+ (width == 854 && height == 480) ||
+ (width == 480 && height == 854))
+ {
+ layoutName.Append(_L("WVGA "));
+ }
+ else if ( (width == 480 && height == 320) ||
+ (width == 320 && height == 480) ||
+ (width == 640 && height == 240) ||
+ (width == 240 && height == 640))
+ {
+ layoutName.Append(_L("HVGA "));
+ }
+ else
+ {
+ layoutName.Append(_L("Unknown "));
+ layoutName.AppendNum(height);
+ layoutName.Append(_L("x"));
+ layoutName.AppendNum(width);
+ }
+ if (width > height)
+ {
+ layoutName.Append(_L("Landscape"));
+ }
+ else
+ {
+ layoutName.Append(_L("Portrait"));
+ }
+ return layoutName;
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CEikAppUi* CPixelMetricsMapperDocument::CreateAppUiL()
+ {
+ return( new ( ELeave ) CPixelMetricsMapperAppUi );
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperDocument::ConstructL()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TUid CPixelMetricsMapperApplication::AppDllUid() const
+ {
+ return KUidPMMapperApplication;
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+CApaDocument* CPixelMetricsMapperApplication::CreateDocumentL()
+ {
+ CPixelMetricsMapperDocument* document =
+ new( ELeave ) CPixelMetricsMapperDocument( *this );
+ CleanupStack::PushL( document );
+ document->ConstructL();
+ CleanupStack::Pop();
+ return( document );
+ }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+// ---------------------------------------------------------
+// NewApplication implements
+//
+// Creates an instance of application.
+//
+// Returns: an instance of CVtUiApp
+// ---------------------------------------------------------
+//
+LOCAL_C CApaApplication* NewApplication()
+ {
+ return new CPixelMetricsMapperApplication;
+ }
+
+// ---------------------------------------------------------
+// E32Main implements
+//
+// It is called when executable is started.
+//
+// Returns: error code.
+// ---------------------------------------------------------
+//
+GLDEF_C TInt E32Main()
+ {
+ return EikStart::RunApplication( NewApplication );
+ }
+
+// End of File
diff --git a/util/s60pixelmetrics/pm_mapperapp.h b/util/s60pixelmetrics/pm_mapperapp.h
new file mode 100644
index 0000000000..15305c5c13
--- /dev/null
+++ b/util/s60pixelmetrics/pm_mapperapp.h
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utility applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PMMAPPERAPP_H
+#define PMMAPPERAPP_H
+
+// INCLUDES
+#include <eikapp.h>
+#include <eikdoc.h>
+#include <e32std.h>
+#include <aknViewAppUi.h>
+
+// CONSTANTS
+const TUid KUidPMMapperApplication = { 0x2002121F };
+
+
+// FORWARD DECLARATIONS
+class CPixelMetricsMapperView;
+class MAknsSkinInstance;
+
+// CLASS DECLARATION
+/**
+* CPixelMetricsMapperDocument
+*/
+class CPixelMetricsMapperDocument : public CEikDocument
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Symbian 2nd phase constructor.
+ */
+ void ConstructL();
+
+ /**
+ * Constructor.
+ */
+ CPixelMetricsMapperDocument( CEikApplication& aApp )
+ : CEikDocument( aApp ) {}
+
+ /**
+ * Destructor.
+ */
+ ~CPixelMetricsMapperDocument(){}
+
+ public: // Functions from base classes
+
+ /**
+ * From CEikDocument.
+ */
+ CFileStore* OpenFileL(
+ TBool /*aDoOpen*/,
+ const TDesC& /*aFilename*/,
+ RFs& /*aFs*/ )
+ {
+ return NULL;
+ }
+
+ private: // Functions from base classes
+
+ /**
+ * From CEikDocument.
+ */
+ CEikAppUi* CreateAppUiL();
+ };
+
+/**
+* CPixelMetricsMapperAppUi
+*/
+class CPixelMetricsMapperAppUi : public CAknViewAppUi
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Constructor.
+ */
+ CPixelMetricsMapperAppUi();
+
+ /**
+ * Symbian 2nd phase constructor.
+ */
+ void ConstructL();
+
+ /**
+ * Destructor.
+ */
+ ~CPixelMetricsMapperAppUi();
+
+ private: // Functions from base classes
+
+ /**
+ * From CEikAppUi.
+ */
+ void HandleCommandL(TInt aCommand);
+
+ /**
+ * From CEikAppUi.
+ */
+ virtual TKeyResponse HandleKeyEventL(
+ const TKeyEvent& aKeyEvent,
+ TEventCode aType );
+
+ private:
+
+ /**
+ * Shows text given.
+ */
+ void ShowL( const TDesC& aText, TBool& aLast, const TBool& aFileOutput = EFalse );
+ void ShowSingleValueL(TInt& aPixelMetric, TInt& aValue, TBool& aLast);
+ void ClearL();
+ void CreateHeaderFileL() const;
+
+ TFileName CreateLayoutNameL(TFileText& aFileHandle) const;
+
+ private: // Data
+
+ // Test view.
+ CPixelMetricsMapperView* iView;
+
+ CEikDialog* iDialog;
+
+ TBool iFileOutputOn;
+ TBool iMode;
+
+ CFbsBitmap* icon;
+ CFbsBitmap* iconMask;
+
+ };
+
+
+/**
+* CPixelMetricsMapperApplication
+*/
+class CPixelMetricsMapperApplication : public CEikApplication
+ {
+ private: // Functions from base classes
+
+ /**
+ * From CApaApplication.
+ */
+ CApaDocument* CreateDocumentL();
+
+ /**
+ * From CApaApplication.
+ */
+ TUid AppDllUid() const;
+ };
+
+
+#endif // PMMAPPERAPP_H
+
+
+// End of File
diff --git a/util/s60pixelmetrics/pm_mapperview.cpp b/util/s60pixelmetrics/pm_mapperview.cpp
new file mode 100644
index 0000000000..fe84751409
--- /dev/null
+++ b/util/s60pixelmetrics/pm_mapperview.cpp
@@ -0,0 +1,375 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utility applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// INCLUDE FILES
+
+#include <eiklabel.h>
+#include <avkon.rsg>
+#include <aknviewappui.h>
+#include <aknconsts.h>
+
+#include "pm_mapper.hrh"
+#include <pm_mapper.rsg>
+#include "pm_mapperView.h"
+#include "pm_mapperApp.h"
+
+#include <aknlists.h>
+#include <avkon.hrh>
+#include <AknUtils.h>
+
+// -----------------------------------------------------------------------------
+// C++ constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CPixelMetricsMapperViewContainer::CPixelMetricsMapperViewContainer(): iCount( 1 )
+ {
+ }
+
+
+// -----------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperViewContainer::ConstructL( const TRect& aRect )
+ {
+ CreateWindowL();
+ SetCanDrawOutsideRect();
+
+ iTexts = new( ELeave ) CDesCArrayFlat( 10 );
+ iTexts->AppendL( _L( "\tStarted." ) );
+
+ iListbox = new( ELeave ) CAknSingleStyleListBox;
+ iListbox->SetContainerWindowL( *this );
+ iListbox->ConstructL( this, EAknListBoxViewerFlags );
+
+ iListbox->Model()->SetItemTextArray( iTexts );
+ iListbox->SetRect( TRect( aRect.Size() ) );
+
+ iListbox->CreateScrollBarFrameL( ETrue );
+ iListbox->ScrollBarFrame()->SetScrollBarVisibilityL(
+ CEikScrollBarFrame::EOn,
+ CEikScrollBarFrame::EOn );
+
+ SetRect( aRect );
+ iListbox->ActivateL();
+ ActivateL();
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperViewContainer::ShowL( const TDesC& aString, TBool& aLast, const TBool& aFileOutput )
+ {
+ MDesCArray* itemList = iListbox->Model()->ItemTextArray();
+ CDesCArray* itemArray = ( CDesCArray* ) itemList;
+
+ itemArray->AppendL( aString );
+
+ iListbox->HandleItemAdditionL();
+ iListbox->SetCurrentItemIndex( iCount );
+ iCount++;
+ if ( aLast )
+ {
+ if (aFileOutput)
+ {
+ RFile file;
+ RFs& fs = CEikonEnv::Static()->FsSession();
+ TFileName fileName =_L("Layout_");
+
+ TRect screenRect;
+ AknLayoutUtils::LayoutMetricsRect(
+ AknLayoutUtils::EApplicationWindow,
+ screenRect );
+
+ // Add screen dimensions
+ TInt height = screenRect.Height();
+ TInt width = screenRect.Width();
+ fileName.AppendNum(height);
+ fileName.Append('_');
+ fileName.AppendNum(width);
+
+ fileName.Append(_L(".txt"));
+
+ TInt err=file.Open(fs,fileName,EFileStreamText|EFileWrite|EFileShareAny);
+ if (err==KErrNotFound) // file does not exist - create it
+ err=file.Create(fs,fileName,EFileStreamText|EFileWrite|EFileShareAny);
+ else
+ file.SetSize(0); //sweep the file
+ TFileText textFile;
+ textFile.Set(file);
+ err = textFile.Seek(ESeekStart);
+ if (err) User::InfoPrint(_L("File corrupted"));
+
+ // Finally loop through all the entries:
+ TInt idx = 0;
+ for(;idx!=itemList->MdcaCount();idx++)
+ {
+ err = textFile.Write(itemList->MdcaPoint(idx));
+ if (err) User::InfoPrint(_L("File corrupted"));
+ }
+ file.Close();
+ }
+ DrawNow();
+ }
+ }
+
+void CPixelMetricsMapperViewContainer::ClearL()
+ {
+ MDesCArray* itemList = iListbox->Model()->ItemTextArray();
+ CDesCArray* itemArray = ( CDesCArray* ) itemList;
+
+ itemArray->Reset();
+
+ iListbox->HandleItemAdditionL();
+ iCount = 0;
+ DrawNow();
+ }
+
+
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CPixelMetricsMapperViewContainer::~CPixelMetricsMapperViewContainer()
+ {
+ delete iListbox;
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperViewContainer::SizeChanged()
+ {
+ CCoeControl::SizeChanged();
+ if ( iListbox )
+ {
+ iListbox->SetRect( Rect() );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TInt CPixelMetricsMapperViewContainer::CountComponentControls() const
+ {
+ return 1;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CTestAppViewContainer::ComponentControl
+//
+//
+// -----------------------------------------------------------------------------
+//
+CCoeControl* CPixelMetricsMapperViewContainer::ComponentControl(
+ TInt /*aIndex*/ ) const
+ {
+ return iListbox;
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperViewContainer::Draw( const TRect& /*aRect*/ ) const
+ {
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperViewContainer::HandleControlEventL(
+ CCoeControl* /*aControl*/,
+ TCoeEvent /*aEventType*/ )
+ {
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CPixelMetricsMapperViewContainer::OfferKeyEventL(
+ const TKeyEvent& aKeyEvent,
+ TEventCode aType )
+ {
+ if (aKeyEvent.iCode == EKeyUpArrow ||
+ aKeyEvent.iCode == EKeyDownArrow )
+ {
+ return iListbox->OfferKeyEventL( aKeyEvent, aType );
+ }
+ return EKeyWasNotConsumed;
+ }
+
+void CPixelMetricsMapperViewContainer::HandleResourceChange(TInt aType)
+ {
+ CCoeControl::HandleResourceChange( aType );
+ if ( aType == KEikDynamicLayoutVariantSwitch )
+ {
+ TRect mainPaneRect;
+ AknLayoutUtils::LayoutMetricsRect(
+ AknLayoutUtils::EMainPane,
+ mainPaneRect );
+ SetRect( mainPaneRect );
+
+ }
+ if (iListbox)
+ iListbox->HandleResourceChange(aType);
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperView::ShowL( const TDesC& aString, TBool& aLast, const TBool& aFileOutput )
+ {
+ iView->ShowL( aString, aLast, aFileOutput );
+ }
+
+void CPixelMetricsMapperView::ClearL()
+ {
+ iView->ClearL();
+ }
+
+
+// -----------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperView::ConstructL()
+ {
+ BaseConstructL( R_PMMAPPER_VIEW );
+ }
+
+
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CPixelMetricsMapperView::~CPixelMetricsMapperView()
+ {
+ if ( iView )
+ {
+ AppUi()->RemoveFromViewStack( *this, iView );
+ }
+ delete iView;
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+TUid CPixelMetricsMapperView::Id() const
+ {
+ return TUid::Uid( EPMMapperViewId );
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperView::HandleCommandL( TInt aCommand )
+ {
+ AppUi()->HandleCommandL( aCommand );
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperView::HandleStatusPaneSizeChange()
+ {
+ if ( iView )
+ {
+ TRect cr = ClientRect();
+ iView->SetRect( cr );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperView::DoActivateL(
+ const TVwsViewId& /*aPrevViewId*/,
+ TUid /*aCustomMessageId*/,
+ const TDesC8& /*aCustomMessage*/ )
+ {
+ iView = new( ELeave ) CPixelMetricsMapperViewContainer;
+
+ TRect cr = ClientRect();
+ iView->ConstructL( cr );
+ AppUi()->AddToViewStackL( *this, iView );
+ }
+
+
+// -----------------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------------
+//
+void CPixelMetricsMapperView::DoDeactivate()
+ {
+ if (iView)
+ {
+ AppUi()->RemoveFromViewStack( *this, iView );
+ }
+ delete iView;
+ iView = NULL;
+ }
+
+
+// End of File
diff --git a/util/s60pixelmetrics/pm_mapperview.h b/util/s60pixelmetrics/pm_mapperview.h
new file mode 100644
index 0000000000..6d43396135
--- /dev/null
+++ b/util/s60pixelmetrics/pm_mapperview.h
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the utility applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PMMAPPERVIEW_H
+#define PMMAPPERVIEW_H
+
+
+// INCLUDES
+#include <aknview.h>
+#include <EIKLBO.H>
+
+// CONSTANTS
+// FORWARD DECLARATIONS
+class CAknSingleStyleListBox;
+class CAknSettingStyleListBox;
+
+// CLASS DECLARATION
+
+/**
+* CPixelMetricsMapperViewContainer
+*
+*/
+class CPixelMetricsMapperViewContainer
+: public CCoeControl,
+ public MCoeControlObserver
+ {
+ public: // Constructors and destructor
+
+ /**
+ * C++ constructor.
+ */
+ CPixelMetricsMapperViewContainer();
+
+ /**
+ * Symbian 2nd phase constructor.
+ *
+ * @param aRect Rectangle.
+ */
+ void ConstructL( const TRect& aRect );
+
+ /**
+ * Destructor.
+ */
+ ~CPixelMetricsMapperViewContainer();
+
+
+ public: // New functions
+
+ /**
+ * Show the given string.
+ *
+ * @param aString The string to be shown.
+ */
+ void ShowL( const TDesC& aString, TBool& aLast, const TBool& aFileOutput = EFalse );
+
+ void ClearL();
+
+
+ public: // Functions from base classes
+
+ /**
+ * From CCoeControl.
+ */
+ TKeyResponse OfferKeyEventL(
+ const TKeyEvent& aKeyEvent,
+ TEventCode aType );
+
+
+ void HandleResourceChange(TInt aType);
+
+
+ private: // Functions from base classes
+
+ /**
+ * From CCoeControl.
+ */
+ void SizeChanged();
+
+ /**
+ * From CCoeControl.
+ */
+ TInt CountComponentControls() const;
+
+ /**
+ * From CCoeControl.
+ */
+ CCoeControl* ComponentControl( TInt aIndex ) const;
+
+ /**
+ * From CCoeControl.
+ */
+ void Draw( const TRect& aRect ) const;
+
+
+ private: // Functions from base classes
+
+ /**
+ * From MCoeControlObserver.
+ */
+ void HandleControlEventL(
+ CCoeControl* aControl,
+ TCoeEvent aEventType );
+
+
+ private: // Data
+
+ // Texts.
+ CDesCArray* iTexts;
+
+ // Count.
+ TInt iCount;
+
+ // Listbox.
+ CAknSingleStyleListBox* iListbox;
+
+ };
+
+
+
+/**
+* CPixelMetricsMapperView
+*
+*
+* @since 1.0
+*/
+class CPixelMetricsMapperView : public CAknView
+ {
+ public: // Constructors and destructor
+
+ /**
+ * Symbian 2nd phase constructor.
+ */
+ void ConstructL();
+
+ /**
+ * Destructor.
+ */
+ ~CPixelMetricsMapperView();
+
+
+ public: // Functions from base classes
+
+ /**
+ * From CAknView.
+ */
+ TUid Id() const;
+
+ /**
+ * From CAknView.
+ */
+ void HandleCommandL( TInt aCommand );
+
+ /**
+ * From CAknView.
+ */
+ void HandleStatusPaneSizeChange();
+
+ /**
+ * From CAknView.
+ */
+ void ShowL( const TDesC& aString, TBool& aLast, const TBool& aFileOutput =EFalse );
+ void ClearL();
+
+
+ private: // from CAknView
+
+ /**
+ * From CAknView.
+ */
+ void DoActivateL(
+ const TVwsViewId& aPrevViewId,
+ TUid aCustomMessageId,
+ const TDesC8& aCustomMessage );
+
+ /**
+ * From CAknView.
+ */
+ void DoDeactivate();
+
+
+ private: // Data
+
+ // The view container.
+ CPixelMetricsMapperViewContainer* iView;
+
+ };
+
+#endif // PMMAPPERVIEW_H
+
+// End of File
diff --git a/util/s60theme/README b/util/s60theme/README
new file mode 100644
index 0000000000..da4e81a6a9
--- /dev/null
+++ b/util/s60theme/README
@@ -0,0 +1,31 @@
+'s60theme' is a commandline tool which converts Carbide.ui themes into
+an intermediate binary format that can be read by the simulated
+QS60Style. So, for example Designer (standalone or in Carbide) will
+be able to display a realistic S60 Ui.
+
+The intermediate binary format consists of hashes of QPictures and
+QColors, streamed to a QByteArray and compressed. QS60Style could not load
+the Carbide.ui theme directly because SVG handling is unfortunately
+not part of QtGui, and would require a dependency on the QtSvg module.
+
+Also, 's60theme' uses QWebkit to parse the SVG graphics (inspired by
+Ariya's 'WebKit-based SVG rasterizer' labs post). QtSvg had some issues
+with the SVGs that come with Carbide.ui.
+
+Usage examples:
+> s60theme "com.nokia.tools.theme.s60.50_3.4.0.0\config\model" Default.blob
+ (Reads the default 's60.50' theme and saves it as 'Default.blob')
+
+> s60theme "Eclipse\Examples\Haze\Haze.tdf" Haze.blob
+ (Reads the Haze theme and saves it as 'Haze.blob')
+
+To use the blob in a Qt application, get an instance of a QS60Style and call
+ style->loadS60ThemeFromBlob("Theme.blob");
+
+The simulated QS60Style will, in its constructor by default, try to load a
+":/s60Stylethemes/Default.blob". If your application has that a resource with
+exactly that filename, it will be used by default.
+'Default.blob' is not included in the current Qt source package. But it can
+easily be created with 's60theme' and a fresh install of Carbide.ui
+
+Visit http://www.forum.nokia.com for details about Carbide.ui
diff --git a/util/s60theme/main.cpp b/util/s60theme/main.cpp
new file mode 100644
index 0000000000..0e54582c88
--- /dev/null
+++ b/util/s60theme/main.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include "s60themeconvert.h"
+
+int help()
+{
+ qDebug() << "Usage: s60theme [modeldir|theme.tdf] output.blob";
+ qDebug() << "";
+ qDebug() << "Options:";
+ qDebug() << " modeldir: Theme 'model' directory in Carbide.ui tree";
+ qDebug() << " theme.tdf: Theme .tdf file";
+ qDebug() << " output.blob: Theme blob output filename";
+ qDebug() << "";
+ qDebug() << "s60theme takes an S60 theme from Carbide.ui and converts";
+ qDebug() << "it into a compact, binary format, that can be directly loaded by";
+ qDebug() << "the QtS60Style.";
+ qDebug() << "";
+ qDebug() << "Visit http://www.forum.nokia.com for details about Carbide.ui";
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc != 3)
+ return help();
+
+ QApplication app(argc, argv);
+
+ const QString input = QString::fromLatin1(argv[1]);
+ const QFileInfo inputInfo(input);
+ const QString output = QString::fromLatin1(argv[2]);
+ if (inputInfo.isDir())
+ return S60ThemeConvert::convertDefaultThemeToBlob(input, output) ? 0 : 1;
+ else if (inputInfo.suffix().compare(QString::fromLatin1("tdf"), Qt::CaseInsensitive) == 0)
+ return S60ThemeConvert::convertTdfToBlob(input, output) ? 0 : 1;
+
+ return help();
+}
diff --git a/util/s60theme/s60theme.pro b/util/s60theme/s60theme.pro
new file mode 100644
index 0000000000..83c0cf2357
--- /dev/null
+++ b/util/s60theme/s60theme.pro
@@ -0,0 +1,12 @@
+SOURCES += \
+ s60themeconvert.cpp \
+ main.cpp
+
+HEADERS += \
+ s60themeconvert.h
+
+QT += \
+ webkit
+
+CONFIG += \
+ console
diff --git a/util/s60theme/s60themeconvert.cpp b/util/s60theme/s60themeconvert.cpp
new file mode 100644
index 0000000000..8fe37fe970
--- /dev/null
+++ b/util/s60theme/s60themeconvert.cpp
@@ -0,0 +1,312 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60themeconvert.h"
+
+#include <QtGui>
+#include <QtWebKit>
+
+static const int pictureSize = 256;
+static const char* const msgPartNotInTdf = " Warning: The .tdf file does not have a part for ";
+static const char* const msgSvgNotFound = " Fatal: Could not find part .svg ";
+
+void dumpPartPictures(const QHash<QString, QPicture> &partPictures) {
+ foreach (const QString &partKey, partPictures.keys()) {
+ QPicture partPicture = partPictures.value(partKey);
+ qDebug() << partKey << partPicture.boundingRect();
+ QImage image(partPicture.boundingRect().size(), QImage::Format_ARGB32);
+ image.fill(Qt::transparent);
+ QPainter p(&image);
+ partPicture.play(&p);
+ image.save(partKey + QString::fromLatin1(".png"));
+ }
+}
+
+void dumpColors(const QHash<QPair<QString, int>, QColor> &colors) {
+ foreach (const QColor &color, colors.values()) {
+ const QPair<QString, int> key = colors.key(color);
+ qDebug() << key << color;
+ }
+}
+
+class WebKitSVGRenderer : public QWebView
+{
+ Q_OBJECT
+
+public:
+ WebKitSVGRenderer(QWidget *parent = 0);
+ QPicture svgToQPicture(const QString &svgFileName);
+
+private slots:
+ void loadFinishedSlot(bool ok);
+
+private:
+ QEventLoop m_loop;
+ QPicture m_result;
+};
+
+WebKitSVGRenderer::WebKitSVGRenderer(QWidget *parent)
+ : QWebView(parent)
+{
+
+ connect(this, SIGNAL(loadFinished(bool)), SLOT(loadFinishedSlot(bool)));
+ setFixedSize(pictureSize, pictureSize);
+ QPalette pal = palette();
+ pal.setColor(QPalette::Base, Qt::transparent);
+ setPalette(pal);
+}
+
+QPicture WebKitSVGRenderer::svgToQPicture(const QString &svgFileName)
+{
+ load(QUrl::fromLocalFile(svgFileName));
+ m_loop.exec();
+ return m_result;
+}
+
+void WebKitSVGRenderer::loadFinishedSlot(bool ok)
+{
+ // crude error-checking
+ if (!ok)
+ qDebug() << "Failed loading " << qPrintable(url().toString());
+
+ page()->mainFrame()->evaluateJavaScript(QString::fromLatin1(
+ "document.rootElement.preserveAspectRatio.baseVal.align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE;"
+ "document.rootElement.style.width = '100%';"
+ "document.rootElement.style.height = '100%';"
+ "document.rootElement.width.baseVal.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 100);"
+ "document.rootElement.height.baseVal.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 100);"
+ ));
+
+ m_result = QPicture(); // "Clear"
+ QPainter p(&m_result);
+ page()->mainFrame()->render(&p);
+ p.end();
+ m_result.setBoundingRect(QRect(0, 0, pictureSize, pictureSize));
+
+ m_loop.exit();
+}
+
+QPair<QString, int> colorIdPair(const QString &colorID)
+{
+ QPair<QString, int> result;
+ QString idText = colorID;
+ idText.remove(QRegExp(QString::fromLatin1("[0-9]")));
+ if (QS60Style::colorListKeys().contains(idText)) {
+ QString idNumber = colorID;
+ idNumber.remove(QRegExp(QString::fromLatin1("[a-zA-Z]")));
+ result.first = idText;
+ result.second = idNumber.toInt();
+ }
+ return result;
+}
+
+bool parseTdfFile(const QString &tdfFile,
+ QHash<QString, QString> &partSvgs,
+ QHash<QPair<QString, int>, QColor> &colors)
+{
+ QFile file(tdfFile);
+ if (!file.open(QIODevice::ReadOnly))
+ return false;
+
+ const QLatin1String elementKey("element");
+ const QLatin1String partKey("part");
+ const QLatin1String elementIdKey("id");
+ const QLatin1String layerKey("layer");
+ const QLatin1String layerFileNameKey("filename");
+ const QLatin1String layerColourrgbKey("colourrgb");
+ const QString annoyingPrefix = QString::fromLatin1("S60_2_6%");
+
+ QXmlStreamReader reader(&file);
+ QString partId;
+ QPair<QString, int> colorId;
+ // Somebody with a sense of aesthetics may implement proper XML parsing, here.
+ while (!reader.atEnd()) {
+ const QXmlStreamReader::TokenType token = reader.readNext();
+ switch (token) {
+ case QXmlStreamReader::StartElement:
+ if (reader.name() == elementKey || reader.name() == partKey) {
+ QString id = reader.attributes().value(elementIdKey).toString();
+ if (QS60Style::partKeys().contains(id))
+ partId = id;
+ else if (!id.isEmpty() && id.at(id.length()-1).isDigit())
+ colorId = colorIdPair(id);
+ else if (QS60Style::partKeys().contains(id.mid(annoyingPrefix.length())))
+ partId = id.mid(annoyingPrefix.length());
+ } else if(reader.name() == layerKey) {
+ if (!partId.isEmpty()) {
+ const QString svgFile = reader.attributes().value(layerFileNameKey).toString();
+ partSvgs.insert(partId, svgFile);
+ partId.clear();
+ } else if (!colorId.first.isEmpty()) {
+ const QColor colorValue(reader.attributes().value(layerColourrgbKey).toString().toInt(NULL, 16));
+ colors.insert(colorId, colorValue);
+ colorId.first.clear();
+ }
+ }
+ break;
+ case QXmlStreamReader::EndElement:
+ if (reader.tokenString() == elementKey || reader.name() == partKey)
+ partId.clear();
+ break;
+ default:
+ break;
+ }
+ }
+ return true;
+}
+
+bool loadThemeFromTdf(const QString &tdfFile,
+ QHash<QString, QPicture> &partPictures,
+ QHash<QPair<QString, int>, QColor> &colors)
+{
+ QHash<QString, QString> parsedPartSvgs;
+ QHash<QString, QPicture> parsedPartPictures;
+ QHash<QPair<QString, int>, QColor> parsedColors;
+ bool success = parseTdfFile(tdfFile, parsedPartSvgs, parsedColors);
+ if (!success)
+ return false;
+ const QString tdfBasePath = QFileInfo(tdfFile).absolutePath();
+ WebKitSVGRenderer renderer;
+ foreach (const QString &partKey, QS60Style::partKeys()) {
+ qDebug() << partKey;
+ QString tdfFullName;
+ if (parsedPartSvgs.contains(partKey)) {
+ tdfFullName = tdfBasePath + QDir::separator() + parsedPartSvgs.value(partKey);
+ } else {
+ qWarning() << msgPartNotInTdf << partKey;
+ tdfFullName = tdfBasePath + QDir::separator() + partKey + QLatin1String(".svg");
+ }
+ if (!QFile(tdfFullName).exists()) {
+ qWarning() << msgSvgNotFound << QDir::toNativeSeparators(tdfFullName);
+ return false;
+ }
+ const QPicture partPicture = renderer.svgToQPicture(tdfFullName);
+ parsedPartPictures.insert(partKey, partPicture);
+ }
+// dumpPartPictures(parsedPartPictures);
+// dumpColors(colors);
+ partPictures = parsedPartPictures;
+ colors = parsedColors;
+ return true;
+}
+
+bool S60ThemeConvert::convertTdfToBlob(const QString &themeTdf, const QString &themeBlob)
+{
+ QHash<QString, QPicture> partPictures;
+ QHash<QPair<QString, int>, QColor> colors;
+
+ if (!::loadThemeFromTdf(themeTdf, partPictures, colors))
+ return false;
+
+ QS60Style style;
+ style.setS60Theme(partPictures, colors);
+ return style.saveS60ThemeToBlob(themeBlob);
+}
+
+bool parseDesignFile(const QString &designFile,
+ QHash<QPair<QString, int>, QColor> &colors)
+{
+ const QLatin1String elementKey("element");
+ const QLatin1String elementIdKey("id");
+ const QLatin1String colorKey("defaultcolour_rgb");
+ QFile file(designFile);
+ if (!file.open(QIODevice::ReadOnly))
+ return false;
+ QXmlStreamReader reader(&file);
+ QPair<QString, int> colorId;
+ // Somebody with a sense of aesthetics may implement proper XML parsing, here.
+ while (!reader.atEnd()) {
+ const QXmlStreamReader::TokenType token = reader.readNext();
+ switch (token) {
+ case QXmlStreamReader::StartElement:
+ if (reader.name() == elementKey) {
+ const QString colorString = reader.attributes().value(colorKey).toString();
+ if (!colorString.isEmpty()) {
+ const QString colorId = reader.attributes().value(elementIdKey).toString();
+ colors.insert(colorIdPair(colorId), colorString.toInt(NULL, 16));
+ }
+ }
+ default:
+ break;
+ }
+ }
+ return true;
+}
+
+bool loadDefaultTheme(const QString &themePath,
+ QHash<QString, QPicture> &partPictures,
+ QHash<QPair<QString, int>, QColor> &colors)
+{
+ const QDir dir(themePath);
+ if (!dir.exists())
+ return false;
+
+ if (!parseDesignFile(themePath + QDir::separator() + QString::fromLatin1("defaultdesign.xml"), colors))
+ return false;
+
+ WebKitSVGRenderer renderer;
+ foreach (const QString &partKey, QS60Style::partKeys()) {
+ const QString partFileName = partKey + QLatin1String(".svg");
+ const QString partFile(dir.absolutePath() + QDir::separator() + partFileName);
+ if (!QFile::exists(partFile)) {
+ qWarning() << msgSvgNotFound << partFileName;
+ return false;
+ }
+ const QPicture partPicture = renderer.svgToQPicture(partFile);
+ partPictures.insert(partKey, partPicture);
+ }
+ return true;
+}
+
+bool S60ThemeConvert::convertDefaultThemeToBlob(const QString &themePath, const QString &themeBlob)
+{
+ QHash<QString, QPicture> partPictures;
+ QHash<QPair<QString, int>, QColor> colors;
+
+ if (!::loadDefaultTheme(themePath, partPictures, colors))
+ return false;
+
+ QS60Style style;
+ style.setS60Theme(partPictures, colors);
+ return style.saveS60ThemeToBlob(themeBlob);
+}
+
+#include "s60themeconvert.moc"
diff --git a/util/s60theme/s60themeconvert.h b/util/s60theme/s60themeconvert.h
new file mode 100644
index 0000000000..123e094a15
--- /dev/null
+++ b/util/s60theme/s60themeconvert.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60THEMECONVERT_H
+#define S60THEMECONVERT_H
+
+#include <QString>
+
+class S60ThemeConvert
+{
+public:
+ static bool convertTdfToBlob(const QString &themeTdf, const QString &themeBlob);
+ static bool convertDefaultThemeToBlob(const QString &themePath, const QString &themeBlob);
+};
+
+#endif // S60THEMECONVERT_H
diff --git a/util/scripts/make_qfeatures_dot_h b/util/scripts/make_qfeatures_dot_h
new file mode 100755
index 0000000000..bacb0e759a
--- /dev/null
+++ b/util/scripts/make_qfeatures_dot_h
@@ -0,0 +1,198 @@
+#!/usr/bin/perl
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is part of the test suite of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## No Commercial Usage
+## This file contains pre-release code and may not be distributed.
+## You may use this file in accordance with the terms and conditions
+## contained in the Technology Preview License Agreement accompanying
+## this package.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Nokia gives you certain additional
+## rights. These rights are described in the Nokia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+#
+# Usage: make_qfeatures_dot_h
+#
+# Generates src/corelib/global/qfeatures.h from src/corelib/global/qfeatures.txt.
+#
+# The qfeatures.txt file can contain redundancies, and this program
+# will show them.
+#
+
+if ($ENV{QTSRCDIR} ne '') {
+ $qtbase=$ENV{QTSRCDIR};
+} else {
+ $qtbase=$ENV{QTDIR};
+}
+
+open FL, "$qtbase/src/corelib/global/qfeatures.txt"
+ or die "Cannot open $qtbase/src/corelib/global/qfeatures.txt";
+
+while (<FL>) {
+ if ( /^Feature: (\S*)/ ) {
+ print STDERR "Duplicate: $1\n" if $macro{$1};
+ $macro{$macro=$1}=1;
+ } elsif ( /^Requires: (.*?)\s*$/ ) {
+ $deps{$macro}=$1;
+ map { $dep{"$macro $_"}=1 } split /\s+/, $1;
+ } elsif ( /^Name: (.*?)\s*$/ ) {
+ $label{$macro}=$1;
+ }
+}
+
+close FL;
+
+sub depends {
+ my($x,$y) = @_;
+ return 1 if $dep{"$x $y"};
+ return 0 if $dep{"$y $x"};
+ return 0 if $x eq $y;
+ my $d;
+ for $d (split /\s+/, $deps{$x}) {
+ return 1 if depends($d,$y);
+ }
+ return 0;
+}
+sub dependants_rec {
+ my($x) = @_;
+ my $n = 0;
+ my $d = 0;
+ $dependants_rec_count++;
+ if ( $dependants_rec_count > $dependants_rec_limit ) {
+ if ( $circularity_start eq $x ) {
+ print STDERR "Circular dependency: $circularity\n";
+ exit;
+ }
+ $circularity_start=$x if !$circularity_start;
+ $circularity="$x $circularity";
+ }
+ for $d (split /\s+/, $deps{$x}) {
+ $n += 1 + dependants_rec($d);
+ }
+ $dependants_rec_count--;
+ return $n;
+}
+sub dependants {
+ $dependants_rec_limit=keys %macro if !$dependants_rec_limit;
+ $dependants_rec_count=0;
+ return dependants_rec @_;
+}
+sub dependencysort {
+ my($x, $y) = @_;
+ my $xd = dependants($x);
+ my $yd = dependants($y);
+ return $xd-$yd if $xd != $yd;
+ return $x cmp $y;
+}
+
+@macros = sort { dependencysort($a,$b) } keys %macro;
+
+for $macro ( @macros ) {
+ for $d1 (split /\s+/, $deps{$macro} ) {
+ for $d2 (split /\s+/, $deps{$macro} ) {
+ print STDERR "Redundancy in $macro - $d1 depends on $d2\n" if depends($d1,$d2);
+ }
+ print STDERR "Unknown in $macro - $d1\n" if !$macro{$d1};
+ }
+}
+
+open OUT, ">$qtbase/src/corelib/global/qfeatures.h"
+ or die "Cannot open $qtbase/src/corelib/global/qfeatures.h for writing";
+
+print OUT
+'/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ * All features and their dependencies.
+ *
+ * This list is generated from $QTDIR/src/corelib/global/qfeatures.txt
+ * by $QTSRCDIR/util/scripts/make_qfeatures_dot_h
+ */
+
+';
+
+
+for $macro ( @macros ) {
+ print OUT "// $label{$macro}\n";
+ if ( $deps{$macro} ) {
+ print OUT "#if !defined(QT_NO_$macro)";
+ print OUT " && (", (join " || ", map { "defined(QT_NO_$_)" } split /\s+/, $deps{$macro}), ")";
+ print OUT "\n";
+ print OUT "#define QT_NO_$macro\n";
+ print OUT "#endif\n";
+ } else {
+ print OUT "//#define QT_NO_$macro\n";
+ }
+ print OUT "\n";
+}
+
+close OUT;
diff --git a/util/scripts/unix_to_dos b/util/scripts/unix_to_dos
new file mode 100755
index 0000000000..510037c2f7
--- /dev/null
+++ b/util/scripts/unix_to_dos
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+
+undef $/;
+
+foreach $f ( @ARGV ) {
+ if ( open( F, "< $f" ) ) {
+ $i = <F>;
+ close F;
+ $i =~ s/\n/\r\n/g;
+ $i =~ s/\r+/\r/g;
+ if ( open( F, "> $f" ) ) {
+ print F $i;
+ close F;
+ }
+ }
+}
diff --git a/util/unicode/.gitattributes b/util/unicode/.gitattributes
new file mode 100644
index 0000000000..772b88fc2f
--- /dev/null
+++ b/util/unicode/.gitattributes
@@ -0,0 +1 @@
+data/*.txt -crlf
diff --git a/util/unicode/README b/util/unicode/README
new file mode 100644
index 0000000000..ca34266a36
--- /dev/null
+++ b/util/unicode/README
@@ -0,0 +1 @@
+Unicode is used to generate the unicode data in src/corelib/tools.
diff --git a/util/unicode/codecs/big5/BIG5 b/util/unicode/codecs/big5/BIG5
new file mode 100644
index 0000000000..1a0a66fc4b
--- /dev/null
+++ b/util/unicode/codecs/big5/BIG5
@@ -0,0 +1,14079 @@
+<code_set_name> BIG5
+<mb_cur_max> 2
+<mb_cur_min> 1
+<comment_char> %
+<escape_char> /
+%
+% Chinese charmap for BIG5 (CP950)
+% version: 0.92
+% Contact: Tung-Han Hsieh <thhsieh@linux.org.tw>
+% Yuan-Chung Cheng <platin@ms31.hinet.net>
+% Distribution and use is free, even for comercial purpose.
+%
+% This charmap is converted from:
+% ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT
+% and also merged several characters (/xc6/xa1-/xc7/xfc) from:
+% Aprhic Tech. CO., LTD. Big5 <==> Unicode mapping table.
+%
+% Irrevsible mapping Big5 characters (using %IRREVERSIBLE% notation):
+% /xa2/xcc, /xa2/xce, /xf9/xe9, /xf9/xea, /xf9/xeb,
+% /xf9/xf9, /xf9/xfa, /xf9/xfb, /xf9/xfc, /xf9/xfd
+%
+% alias BIG5-CP950
+
+CHARMAP
+<U0000> /x00 NULL (NUL)
+<U0001> /x01 START OF HEADING (SOH)
+<U0002> /x02 START OF TEXT (STX)
+<U0003> /x03 END OF TEXT (ETX)
+<U0004> /x04 END OF TRANSMISSION (EOT)
+<U0005> /x05 ENQUIRY (ENQ)
+<U0006> /x06 ACKNOWLEDGE (ACK)
+<U0007> /x07 BELL (BEL)
+<U0008> /x08 BACKSPACE (BS)
+<U0009> /x09 CHARACTER TABULATION (HT)
+<U000A> /x0a LINE FEED (LF)
+<U000B> /x0b LINE TABULATION (VT)
+<U000C> /x0c FORM FEED (FF)
+<U000D> /x0d CARRIAGE RETURN (CR)
+<U000E> /x0e SHIFT OUT (SO)
+<U000F> /x0f SHIFT IN (SI)
+<U0010> /x10 DATALINK ESCAPE (DLE)
+<U0011> /x11 DEVICE CONTROL ONE (DC1)
+<U0012> /x12 DEVICE CONTROL TWO (DC2)
+<U0013> /x13 DEVICE CONTROL THREE (DC3)
+<U0014> /x14 DEVICE CONTROL FOUR (DC4)
+<U0015> /x15 NEGATIVE ACKNOWLEDGE (NAK)
+<U0016> /x16 SYNCHRONOUS IDLE (SYN)
+<U0017> /x17 END OF TRANSMISSION BLOCK (ETB)
+<U0018> /x18 CANCEL (CAN)
+<U0019> /x19 END OF MEDIUM (EM)
+<U001A> /x1a SUBSTITUTE (SUB)
+<U001B> /x1b ESCAPE (ESC)
+<U001C> /x1c FILE SEPARATOR (IS4)
+<U001D> /x1d GROUP SEPARATOR (IS3)
+<U001E> /x1e RECORD SEPARATOR (IS2)
+<U001F> /x1f UNIT SEPARATOR (IS1)
+<U0020> /x20 SPACE
+<U0021> /x21 EXCLAMATION MARK
+<U0022> /x22 QUOTATION MARK
+<U0023> /x23 NUMBER SIGN
+<U0024> /x24 DOLLAR SIGN
+<U0025> /x25 PERCENT SIGN
+<U0026> /x26 AMPERSAND
+<U0027> /x27 APOSTROPHE
+<U0028> /x28 LEFT PARENTHESIS
+<U0029> /x29 RIGHT PARENTHESIS
+<U002A> /x2a ASTERISK
+<U002B> /x2b PLUS SIGN
+<U002C> /x2c COMMA
+<U002D> /x2d HYPHEN-MINUS
+<U002E> /x2e FULL STOP
+<U002F> /x2f SOLIDUS
+<U0030> /x30 DIGIT ZERO
+<U0031> /x31 DIGIT ONE
+<U0032> /x32 DIGIT TWO
+<U0033> /x33 DIGIT THREE
+<U0034> /x34 DIGIT FOUR
+<U0035> /x35 DIGIT FIVE
+<U0036> /x36 DIGIT SIX
+<U0037> /x37 DIGIT SEVEN
+<U0038> /x38 DIGIT EIGHT
+<U0039> /x39 DIGIT NINE
+<U003A> /x3a COLON
+<U003B> /x3b SEMICOLON
+<U003C> /x3c LESS-THAN SIGN
+<U003D> /x3d EQUALS SIGN
+<U003E> /x3e GREATER-THAN SIGN
+<U003F> /x3f QUESTION MARK
+<U0040> /x40 COMMERCIAL AT
+<U0041> /x41 LATIN CAPITAL LETTER A
+<U0042> /x42 LATIN CAPITAL LETTER B
+<U0043> /x43 LATIN CAPITAL LETTER C
+<U0044> /x44 LATIN CAPITAL LETTER D
+<U0045> /x45 LATIN CAPITAL LETTER E
+<U0046> /x46 LATIN CAPITAL LETTER F
+<U0047> /x47 LATIN CAPITAL LETTER G
+<U0048> /x48 LATIN CAPITAL LETTER H
+<U0049> /x49 LATIN CAPITAL LETTER I
+<U004A> /x4a LATIN CAPITAL LETTER J
+<U004B> /x4b LATIN CAPITAL LETTER K
+<U004C> /x4c LATIN CAPITAL LETTER L
+<U004D> /x4d LATIN CAPITAL LETTER M
+<U004E> /x4e LATIN CAPITAL LETTER N
+<U004F> /x4f LATIN CAPITAL LETTER O
+<U0050> /x50 LATIN CAPITAL LETTER P
+<U0051> /x51 LATIN CAPITAL LETTER Q
+<U0052> /x52 LATIN CAPITAL LETTER R
+<U0053> /x53 LATIN CAPITAL LETTER S
+<U0054> /x54 LATIN CAPITAL LETTER T
+<U0055> /x55 LATIN CAPITAL LETTER U
+<U0056> /x56 LATIN CAPITAL LETTER V
+<U0057> /x57 LATIN CAPITAL LETTER W
+<U0058> /x58 LATIN CAPITAL LETTER X
+<U0059> /x59 LATIN CAPITAL LETTER Y
+<U005A> /x5a LATIN CAPITAL LETTER Z
+<U005B> /x5b LEFT SQUARE BRACKET
+<U005C> /x5c REVERSE SOLIDUS
+<U005D> /x5d RIGHT SQUARE BRACKET
+<U005E> /x5e CIRCUMFLEX ACCENT
+<U005F> /x5f LOW LINE
+<U0060> /x60 GRAVE ACCENT
+<U0061> /x61 LATIN SMALL LETTER A
+<U0062> /x62 LATIN SMALL LETTER B
+<U0063> /x63 LATIN SMALL LETTER C
+<U0064> /x64 LATIN SMALL LETTER D
+<U0065> /x65 LATIN SMALL LETTER E
+<U0066> /x66 LATIN SMALL LETTER F
+<U0067> /x67 LATIN SMALL LETTER G
+<U0068> /x68 LATIN SMALL LETTER H
+<U0069> /x69 LATIN SMALL LETTER I
+<U006A> /x6a LATIN SMALL LETTER J
+<U006B> /x6b LATIN SMALL LETTER K
+<U006C> /x6c LATIN SMALL LETTER L
+<U006D> /x6d LATIN SMALL LETTER M
+<U006E> /x6e LATIN SMALL LETTER N
+<U006F> /x6f LATIN SMALL LETTER O
+<U0070> /x70 LATIN SMALL LETTER P
+<U0071> /x71 LATIN SMALL LETTER Q
+<U0072> /x72 LATIN SMALL LETTER R
+<U0073> /x73 LATIN SMALL LETTER S
+<U0074> /x74 LATIN SMALL LETTER T
+<U0075> /x75 LATIN SMALL LETTER U
+<U0076> /x76 LATIN SMALL LETTER V
+<U0077> /x77 LATIN SMALL LETTER W
+<U0078> /x78 LATIN SMALL LETTER X
+<U0079> /x79 LATIN SMALL LETTER Y
+<U007A> /x7a LATIN SMALL LETTER Z
+<U007B> /x7b LEFT CURLY BRACKET
+<U007C> /x7c VERTICAL LINE
+<U007D> /x7d RIGHT CURLY BRACKET
+<U007E> /x7e TILDE
+<U007F> /x7f DELETE (DEL)
+<U0080> /x80 PADDING CHARACTER (PAD)
+%
+% Now begin the Big5 (CP950) encoding specific.
+%
+<U3000> /xa1/x40 IDEOGRAPHIC SPACE
+<UFF0C> /xa1/x41 FULLWIDTH COMMA
+<U3001> /xa1/x42 IDEOGRAPHIC COMMA
+<U3002> /xa1/x43 IDEOGRAPHIC FULL STOP
+<UFF0E> /xa1/x44 FULLWIDTH FULL STOP
+<U2027> /xa1/x45 HYPHENATION POINT
+<UFF1B> /xa1/x46 FULLWIDTH SEMICOLON
+<UFF1A> /xa1/x47 FULLWIDTH COLON
+<UFF1F> /xa1/x48 FULLWIDTH QUESTION MARK
+<UFF01> /xa1/x49 FULLWIDTH EXCLAMATION MARK
+<UFE30> /xa1/x4a PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+<U2026> /xa1/x4b HORIZONTAL ELLIPSIS
+<U2025> /xa1/x4c TWO DOT LEADER
+<UFE50> /xa1/x4d SMALL COMMA
+<UFE51> /xa1/x4e SMALL IDEOGRAPHIC COMMA
+<UFE52> /xa1/x4f SMALL FULL STOP
+<U00B7> /xa1/x50 MIDDLE DOT
+<UFE54> /xa1/x51 SMALL SEMICOLON
+<UFE55> /xa1/x52 SMALL COLON
+<UFE56> /xa1/x53 SMALL QUESTION MARK
+<UFE57> /xa1/x54 SMALL EXCLAMATION MARK
+<UFF5C> /xa1/x55 FULLWIDTH VERTICAL LINE
+<U2013> /xa1/x56 EN DASH
+<UFE31> /xa1/x57 PRESENTATION FORM FOR VERTICAL EM DASH
+<U2014> /xa1/x58 EM DASH
+<UFE33> /xa1/x59 PRESENTATION FORM FOR VERTICAL LOW LINE
+<U2574> /xa1/x5a BOX DRAWINGS LIGHT LEFT
+<UFE34> /xa1/x5b PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
+<UFE4F> /xa1/x5c WAVY LOW LINE
+<UFF08> /xa1/x5d FULLWIDTH LEFT PARENTHESIS
+<UFF09> /xa1/x5e FULLWIDTH RIGHT PARENTHESIS
+<UFE35> /xa1/x5f PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+<UFE36> /xa1/x60 PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+<UFF5B> /xa1/x61 FULLWIDTH LEFT CURLY BRACKET
+<UFF5D> /xa1/x62 FULLWIDTH RIGHT CURLY BRACKET
+<UFE37> /xa1/x63 PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+<UFE38> /xa1/x64 PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+<U3014> /xa1/x65 LEFT TORTOISE SHELL BRACKET
+<U3015> /xa1/x66 RIGHT TORTOISE SHELL BRACKET
+<UFE39> /xa1/x67 PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+<UFE3A> /xa1/x68 PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+<U3010> /xa1/x69 LEFT BLACK LENTICULAR BRACKET
+<U3011> /xa1/x6a RIGHT BLACK LENTICULAR BRACKET
+<UFE3B> /xa1/x6b PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+<UFE3C> /xa1/x6c PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+<U300A> /xa1/x6d LEFT DOUBLE ANGLE BRACKET
+<U300B> /xa1/x6e RIGHT DOUBLE ANGLE BRACKET
+<UFE3D> /xa1/x6f PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+<UFE3E> /xa1/x70 PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+<U3008> /xa1/x71 LEFT ANGLE BRACKET
+<U3009> /xa1/x72 RIGHT ANGLE BRACKET
+<UFE3F> /xa1/x73 PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+<UFE40> /xa1/x74 PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+<U300C> /xa1/x75 LEFT CORNER BRACKET
+<U300D> /xa1/x76 RIGHT CORNER BRACKET
+<UFE41> /xa1/x77 PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+<UFE42> /xa1/x78 PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+<U300E> /xa1/x79 LEFT WHITE CORNER BRACKET
+<U300F> /xa1/x7a RIGHT WHITE CORNER BRACKET
+<UFE43> /xa1/x7b PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+<UFE44> /xa1/x7c PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+<UFE59> /xa1/x7d SMALL LEFT PARENTHESIS
+<UFE5A> /xa1/x7e SMALL RIGHT PARENTHESIS
+<UFE5B> /xa1/xa1 SMALL LEFT CURLY BRACKET
+<UFE5C> /xa1/xa2 SMALL RIGHT CURLY BRACKET
+<UFE5D> /xa1/xa3 SMALL LEFT TORTOISE SHELL BRACKET
+<UFE5E> /xa1/xa4 SMALL RIGHT TORTOISE SHELL BRACKET
+<U2018> /xa1/xa5 LEFT SINGLE QUOTATION MARK
+<U2019> /xa1/xa6 RIGHT SINGLE QUOTATION MARK
+<U201C> /xa1/xa7 LEFT DOUBLE QUOTATION MARK
+<U201D> /xa1/xa8 RIGHT DOUBLE QUOTATION MARK
+<U301D> /xa1/xa9 REVERSED DOUBLE PRIME QUOTATION MARK
+<U301E> /xa1/xaa DOUBLE PRIME QUOTATION MARK
+<U2035> /xa1/xab REVERSED PRIME
+<U2032> /xa1/xac PRIME
+<UFF03> /xa1/xad FULLWIDTH NUMBER SIGN
+<UFF06> /xa1/xae FULLWIDTH AMPERSAND
+<UFF0A> /xa1/xaf FULLWIDTH ASTERISK
+<U203B> /xa1/xb0 REFERENCE MARK
+<U00A7> /xa1/xb1 SECTION SIGN
+<U3003> /xa1/xb2 DITTO MARK
+<U25CB> /xa1/xb3 WHITE CIRCLE
+<U25CF> /xa1/xb4 BLACK CIRCLE
+<U25B3> /xa1/xb5 WHITE UP-POINTING TRIANGLE
+<U25B2> /xa1/xb6 BLACK UP-POINTING TRIANGLE
+<U25CE> /xa1/xb7 BULLSEYE
+<U2606> /xa1/xb8 WHITE STAR
+<U2605> /xa1/xb9 BLACK STAR
+<U25C7> /xa1/xba WHITE DIAMOND
+<U25C6> /xa1/xbb BLACK DIAMOND
+<U25A1> /xa1/xbc WHITE SQUARE
+<U25A0> /xa1/xbd BLACK SQUARE
+<U25BD> /xa1/xbe WHITE DOWN-POINTING TRIANGLE
+<U25BC> /xa1/xbf BLACK DOWN-POINTING TRIANGLE
+<U32A3> /xa1/xc0 CIRCLED IDEOGRAPH CORRECT
+<U2105> /xa1/xc1 CARE OF
+<U00AF> /xa1/xc2 MACRON
+<UFFE3> /xa1/xc3 FULLWIDTH MACRON
+<UFF3F> /xa1/xc4 FULLWIDTH LOW LINE
+<U02CD> /xa1/xc5 MODIFIER LETTER LOW MACRON
+<UFE49> /xa1/xc6 DASHED OVERLINE
+<UFE4A> /xa1/xc7 CENTRELINE OVERLINE
+<UFE4D> /xa1/xc8 DASHED LOW LINE
+<UFE4E> /xa1/xc9 CENTRELINE LOW LINE
+<UFE4B> /xa1/xca WAVY OVERLINE
+<UFE4C> /xa1/xcb DOUBLE WAVY OVERLINE
+<UFE5F> /xa1/xcc SMALL NUMBER SIGN
+<UFE60> /xa1/xcd SMALL AMPERSAND
+<UFE61> /xa1/xce SMALL ASTERISK
+<UFF0B> /xa1/xcf FULLWIDTH PLUS SIGN
+<UFF0D> /xa1/xd0 FULLWIDTH HYPHEN-MINUS
+<U00D7> /xa1/xd1 MULTIPLICATION SIGN
+<U00F7> /xa1/xd2 DIVISION SIGN
+<U00B1> /xa1/xd3 PLUS-MINUS SIGN
+<U221A> /xa1/xd4 SQUARE ROOT
+<UFF1C> /xa1/xd5 FULLWIDTH LESS-THAN SIGN
+<UFF1E> /xa1/xd6 FULLWIDTH GREATER-THAN SIGN
+<UFF1D> /xa1/xd7 FULLWIDTH EQUALS SIGN
+<U2266> /xa1/xd8 LESS-THAN OVER EQUAL TO
+<U2267> /xa1/xd9 GREATER-THAN OVER EQUAL TO
+<U2260> /xa1/xda NOT EQUAL TO
+<U221E> /xa1/xdb INFINITY
+<U2252> /xa1/xdc APPROXIMATELY EQUAL TO OR THE IMAGE OF
+<U2261> /xa1/xdd IDENTICAL TO
+<UFE62> /xa1/xde SMALL PLUS SIGN
+<UFE63> /xa1/xdf SMALL HYPHEN-MINUS
+<UFE64> /xa1/xe0 SMALL LESS-THAN SIGN
+<UFE65> /xa1/xe1 SMALL GREATER-THAN SIGN
+<UFE66> /xa1/xe2 SMALL EQUALS SIGN
+<UFF5E> /xa1/xe3 FULLWIDTH TILDE
+<U2229> /xa1/xe4 INTERSECTION
+<U222A> /xa1/xe5 UNION
+<U22A5> /xa1/xe6 UP TACK
+<U2220> /xa1/xe7 ANGLE
+<U221F> /xa1/xe8 RIGHT ANGLE
+<U22BF> /xa1/xe9 RIGHT TRIANGLE
+<U33D2> /xa1/xea SQUARE LOG
+<U33D1> /xa1/xeb SQUARE LN
+<U222B> /xa1/xec INTEGRAL
+<U222E> /xa1/xed CONTOUR INTEGRAL
+<U2235> /xa1/xee BECAUSE
+<U2234> /xa1/xef THEREFORE
+<U2640> /xa1/xf0 FEMALE SIGN
+<U2642> /xa1/xf1 MALE SIGN
+<U2295> /xa1/xf2 CIRCLED PLUS
+<U2299> /xa1/xf3 CIRCLED DOT OPERATOR
+<U2191> /xa1/xf4 UPWARDS ARROW
+<U2193> /xa1/xf5 DOWNWARDS ARROW
+<U2190> /xa1/xf6 LEFTWARDS ARROW
+<U2192> /xa1/xf7 RIGHTWARDS ARROW
+<U2196> /xa1/xf8 NORTH WEST ARROW
+<U2197> /xa1/xf9 NORTH EAST ARROW
+<U2199> /xa1/xfa SOUTH WEST ARROW
+<U2198> /xa1/xfb SOUTH EAST ARROW
+<U2225> /xa1/xfc PARALLEL TO
+<U2223> /xa1/xfd DIVIDES
+<UFF0F> /xa1/xfe FULLWIDTH SOLIDUS
+<UFF3C> /xa2/x40 FULLWIDTH REVERSE SOLIDUS
+<U2215> /xa2/x41 DIVISION SLASH
+<UFE68> /xa2/x42 SMALL REVERSE SOLIDUS
+<UFF04> /xa2/x43 FULLWIDTH DOLLAR SIGN
+<UFFE5> /xa2/x44 FULLWIDTH YEN SIGN
+<U3012> /xa2/x45 POSTAL MARK
+<UFFE0> /xa2/x46 FULLWIDTH CENT SIGN
+<UFFE1> /xa2/x47 FULLWIDTH POUND SIGN
+<UFF05> /xa2/x48 FULLWIDTH PERCENT SIGN
+<UFF20> /xa2/x49 FULLWIDTH COMMERCIAL AT
+<U2103> /xa2/x4a DEGREE CELSIUS
+<U2109> /xa2/x4b DEGREE FAHRENHEIT
+<UFE69> /xa2/x4c SMALL DOLLAR SIGN
+<UFE6A> /xa2/x4d SMALL PERCENT SIGN
+<UFE6B> /xa2/x4e SMALL COMMERCIAL AT
+<U33D5> /xa2/x4f SQUARE MIL
+<U339C> /xa2/x50 SQUARE MM
+<U339D> /xa2/x51 SQUARE CM
+<U339E> /xa2/x52 SQUARE KM
+<U33CE> /xa2/x53 SQUARE KM CAPITAL
+<U33A1> /xa2/x54 SQUARE M SQUARED
+<U338E> /xa2/x55 SQUARE MG
+<U338F> /xa2/x56 SQUARE KG
+<U33C4> /xa2/x57 SQUARE CC
+<U00B0> /xa2/x58 DEGREE SIGN
+<U5159> /xa2/x59 <CJK>
+<U515B> /xa2/x5a <CJK>
+<U515E> /xa2/x5b <CJK>
+<U515D> /xa2/x5c <CJK>
+<U5161> /xa2/x5d <CJK>
+<U5163> /xa2/x5e <CJK>
+<U55E7> /xa2/x5f <CJK>
+<U74E9> /xa2/x60 <CJK>
+<U7CCE> /xa2/x61 <CJK>
+<U2581> /xa2/x62 LOWER ONE EIGHTH BLOCK
+<U2582> /xa2/x63 LOWER ONE QUARTER BLOCK
+<U2583> /xa2/x64 LOWER THREE EIGHTHS BLOCK
+<U2584> /xa2/x65 LOWER HALF BLOCK
+<U2585> /xa2/x66 LOWER FIVE EIGHTHS BLOCK
+<U2586> /xa2/x67 LOWER THREE QUARTERS BLOCK
+<U2587> /xa2/x68 LOWER SEVEN EIGHTHS BLOCK
+<U2588> /xa2/x69 FULL BLOCK
+<U258F> /xa2/x6a LEFT ONE EIGHTH BLOCK
+<U258E> /xa2/x6b LEFT ONE QUARTER BLOCK
+<U258D> /xa2/x6c LEFT THREE EIGHTHS BLOCK
+<U258C> /xa2/x6d LEFT HALF BLOCK
+<U258B> /xa2/x6e LEFT FIVE EIGHTHS BLOCK
+<U258A> /xa2/x6f LEFT THREE QUARTERS BLOCK
+<U2589> /xa2/x70 LEFT SEVEN EIGHTHS BLOCK
+<U253C> /xa2/x71 BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+<U2534> /xa2/x72 BOX DRAWINGS LIGHT UP AND HORIZONTAL
+<U252C> /xa2/x73 BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+<U2524> /xa2/x74 BOX DRAWINGS LIGHT VERTICAL AND LEFT
+<U251C> /xa2/x75 BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+<U2594> /xa2/x76 UPPER ONE EIGHTH BLOCK
+<U2500> /xa2/x77 BOX DRAWINGS LIGHT HORIZONTAL
+<U2502> /xa2/x78 BOX DRAWINGS LIGHT VERTICAL
+<U2595> /xa2/x79 RIGHT ONE EIGHTH BLOCK
+<U250C> /xa2/x7a BOX DRAWINGS LIGHT DOWN AND RIGHT
+<U2510> /xa2/x7b BOX DRAWINGS LIGHT DOWN AND LEFT
+<U2514> /xa2/x7c BOX DRAWINGS LIGHT UP AND RIGHT
+<U2518> /xa2/x7d BOX DRAWINGS LIGHT UP AND LEFT
+<U256D> /xa2/x7e BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+<U256E> /xa2/xa1 BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+<U2570> /xa2/xa2 BOX DRAWINGS LIGHT ARC UP AND RIGHT
+<U256F> /xa2/xa3 BOX DRAWINGS LIGHT ARC UP AND LEFT
+<U2550> /xa2/xa4 BOX DRAWINGS DOUBLE HORIZONTAL
+<U255E> /xa2/xa5 BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+<U256A> /xa2/xa6 BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+<U2561> /xa2/xa7 BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+<U25E2> /xa2/xa8 BLACK LOWER RIGHT TRIANGLE
+<U25E3> /xa2/xa9 BLACK LOWER LEFT TRIANGLE
+<U25E5> /xa2/xaa BLACK UPPER RIGHT TRIANGLE
+<U25E4> /xa2/xab BLACK UPPER LEFT TRIANGLE
+<U2571> /xa2/xac BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+<U2572> /xa2/xad BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+<U2573> /xa2/xae BOX DRAWINGS LIGHT DIAGONAL CROSS
+<UFF10> /xa2/xaf FULLWIDTH DIGIT ZERO
+<UFF11> /xa2/xb0 FULLWIDTH DIGIT ONE
+<UFF12> /xa2/xb1 FULLWIDTH DIGIT TWO
+<UFF13> /xa2/xb2 FULLWIDTH DIGIT THREE
+<UFF14> /xa2/xb3 FULLWIDTH DIGIT FOUR
+<UFF15> /xa2/xb4 FULLWIDTH DIGIT FIVE
+<UFF16> /xa2/xb5 FULLWIDTH DIGIT SIX
+<UFF17> /xa2/xb6 FULLWIDTH DIGIT SEVEN
+<UFF18> /xa2/xb7 FULLWIDTH DIGIT EIGHT
+<UFF19> /xa2/xb8 FULLWIDTH DIGIT NINE
+<U2160> /xa2/xb9 ROMAN NUMERAL ONE
+<U2161> /xa2/xba ROMAN NUMERAL TWO
+<U2162> /xa2/xbb ROMAN NUMERAL THREE
+<U2163> /xa2/xbc ROMAN NUMERAL FOUR
+<U2164> /xa2/xbd ROMAN NUMERAL FIVE
+<U2165> /xa2/xbe ROMAN NUMERAL SIX
+<U2166> /xa2/xbf ROMAN NUMERAL SEVEN
+<U2167> /xa2/xc0 ROMAN NUMERAL EIGHT
+<U2168> /xa2/xc1 ROMAN NUMERAL NINE
+<U2169> /xa2/xc2 ROMAN NUMERAL TEN
+<U3021> /xa2/xc3 HANGZHOU NUMERAL ONE
+<U3022> /xa2/xc4 HANGZHOU NUMERAL TWO
+<U3023> /xa2/xc5 HANGZHOU NUMERAL THREE
+<U3024> /xa2/xc6 HANGZHOU NUMERAL FOUR
+<U3025> /xa2/xc7 HANGZHOU NUMERAL FIVE
+<U3026> /xa2/xc8 HANGZHOU NUMERAL SIX
+<U3027> /xa2/xc9 HANGZHOU NUMERAL SEVEN
+<U3028> /xa2/xca HANGZHOU NUMERAL EIGHT
+<U3029> /xa2/xcb HANGZHOU NUMERAL NINE
+%IRREVERSIBLE%<U5341> /xa2/xcc <CJK>
+<U5344> /xa2/xcd <CJK>
+%IRREVERSIBLE%<U5345> /xa2/xce <CJK>
+<UFF21> /xa2/xcf FULLWIDTH LATIN CAPITAL LETTER A
+<UFF22> /xa2/xd0 FULLWIDTH LATIN CAPITAL LETTER B
+<UFF23> /xa2/xd1 FULLWIDTH LATIN CAPITAL LETTER C
+<UFF24> /xa2/xd2 FULLWIDTH LATIN CAPITAL LETTER D
+<UFF25> /xa2/xd3 FULLWIDTH LATIN CAPITAL LETTER E
+<UFF26> /xa2/xd4 FULLWIDTH LATIN CAPITAL LETTER F
+<UFF27> /xa2/xd5 FULLWIDTH LATIN CAPITAL LETTER G
+<UFF28> /xa2/xd6 FULLWIDTH LATIN CAPITAL LETTER H
+<UFF29> /xa2/xd7 FULLWIDTH LATIN CAPITAL LETTER I
+<UFF2A> /xa2/xd8 FULLWIDTH LATIN CAPITAL LETTER J
+<UFF2B> /xa2/xd9 FULLWIDTH LATIN CAPITAL LETTER K
+<UFF2C> /xa2/xda FULLWIDTH LATIN CAPITAL LETTER L
+<UFF2D> /xa2/xdb FULLWIDTH LATIN CAPITAL LETTER M
+<UFF2E> /xa2/xdc FULLWIDTH LATIN CAPITAL LETTER N
+<UFF2F> /xa2/xdd FULLWIDTH LATIN CAPITAL LETTER O
+<UFF30> /xa2/xde FULLWIDTH LATIN CAPITAL LETTER P
+<UFF31> /xa2/xdf FULLWIDTH LATIN CAPITAL LETTER Q
+<UFF32> /xa2/xe0 FULLWIDTH LATIN CAPITAL LETTER R
+<UFF33> /xa2/xe1 FULLWIDTH LATIN CAPITAL LETTER S
+<UFF34> /xa2/xe2 FULLWIDTH LATIN CAPITAL LETTER T
+<UFF35> /xa2/xe3 FULLWIDTH LATIN CAPITAL LETTER U
+<UFF36> /xa2/xe4 FULLWIDTH LATIN CAPITAL LETTER V
+<UFF37> /xa2/xe5 FULLWIDTH LATIN CAPITAL LETTER W
+<UFF38> /xa2/xe6 FULLWIDTH LATIN CAPITAL LETTER X
+<UFF39> /xa2/xe7 FULLWIDTH LATIN CAPITAL LETTER Y
+<UFF3A> /xa2/xe8 FULLWIDTH LATIN CAPITAL LETTER Z
+<UFF41> /xa2/xe9 FULLWIDTH LATIN SMALL LETTER A
+<UFF42> /xa2/xea FULLWIDTH LATIN SMALL LETTER B
+<UFF43> /xa2/xeb FULLWIDTH LATIN SMALL LETTER C
+<UFF44> /xa2/xec FULLWIDTH LATIN SMALL LETTER D
+<UFF45> /xa2/xed FULLWIDTH LATIN SMALL LETTER E
+<UFF46> /xa2/xee FULLWIDTH LATIN SMALL LETTER F
+<UFF47> /xa2/xef FULLWIDTH LATIN SMALL LETTER G
+<UFF48> /xa2/xf0 FULLWIDTH LATIN SMALL LETTER H
+<UFF49> /xa2/xf1 FULLWIDTH LATIN SMALL LETTER I
+<UFF4A> /xa2/xf2 FULLWIDTH LATIN SMALL LETTER J
+<UFF4B> /xa2/xf3 FULLWIDTH LATIN SMALL LETTER K
+<UFF4C> /xa2/xf4 FULLWIDTH LATIN SMALL LETTER L
+<UFF4D> /xa2/xf5 FULLWIDTH LATIN SMALL LETTER M
+<UFF4E> /xa2/xf6 FULLWIDTH LATIN SMALL LETTER N
+<UFF4F> /xa2/xf7 FULLWIDTH LATIN SMALL LETTER O
+<UFF50> /xa2/xf8 FULLWIDTH LATIN SMALL LETTER P
+<UFF51> /xa2/xf9 FULLWIDTH LATIN SMALL LETTER Q
+<UFF52> /xa2/xfa FULLWIDTH LATIN SMALL LETTER R
+<UFF53> /xa2/xfb FULLWIDTH LATIN SMALL LETTER S
+<UFF54> /xa2/xfc FULLWIDTH LATIN SMALL LETTER T
+<UFF55> /xa2/xfd FULLWIDTH LATIN SMALL LETTER U
+<UFF56> /xa2/xfe FULLWIDTH LATIN SMALL LETTER V
+<UFF57> /xa3/x40 FULLWIDTH LATIN SMALL LETTER W
+<UFF58> /xa3/x41 FULLWIDTH LATIN SMALL LETTER X
+<UFF59> /xa3/x42 FULLWIDTH LATIN SMALL LETTER Y
+<UFF5A> /xa3/x43 FULLWIDTH LATIN SMALL LETTER Z
+<U0391> /xa3/x44 GREEK CAPITAL LETTER ALPHA
+<U0392> /xa3/x45 GREEK CAPITAL LETTER BETA
+<U0393> /xa3/x46 GREEK CAPITAL LETTER GAMMA
+<U0394> /xa3/x47 GREEK CAPITAL LETTER DELTA
+<U0395> /xa3/x48 GREEK CAPITAL LETTER EPSILON
+<U0396> /xa3/x49 GREEK CAPITAL LETTER ZETA
+<U0397> /xa3/x4a GREEK CAPITAL LETTER ETA
+<U0398> /xa3/x4b GREEK CAPITAL LETTER THETA
+<U0399> /xa3/x4c GREEK CAPITAL LETTER IOTA
+<U039A> /xa3/x4d GREEK CAPITAL LETTER KAPPA
+<U039B> /xa3/x4e GREEK CAPITAL LETTER LAMDA
+<U039C> /xa3/x4f GREEK CAPITAL LETTER MU
+<U039D> /xa3/x50 GREEK CAPITAL LETTER NU
+<U039E> /xa3/x51 GREEK CAPITAL LETTER XI
+<U039F> /xa3/x52 GREEK CAPITAL LETTER OMICRON
+<U03A0> /xa3/x53 GREEK CAPITAL LETTER PI
+<U03A1> /xa3/x54 GREEK CAPITAL LETTER RHO
+<U03A3> /xa3/x55 GREEK CAPITAL LETTER SIGMA
+<U03A4> /xa3/x56 GREEK CAPITAL LETTER TAU
+<U03A5> /xa3/x57 GREEK CAPITAL LETTER UPSILON
+<U03A6> /xa3/x58 GREEK CAPITAL LETTER PHI
+<U03A7> /xa3/x59 GREEK CAPITAL LETTER CHI
+<U03A8> /xa3/x5a GREEK CAPITAL LETTER PSI
+<U03A9> /xa3/x5b GREEK CAPITAL LETTER OMEGA
+<U03B1> /xa3/x5c GREEK SMALL LETTER ALPHA
+<U03B2> /xa3/x5d GREEK SMALL LETTER BETA
+<U03B3> /xa3/x5e GREEK SMALL LETTER GAMMA
+<U03B4> /xa3/x5f GREEK SMALL LETTER DELTA
+<U03B5> /xa3/x60 GREEK SMALL LETTER EPSILON
+<U03B6> /xa3/x61 GREEK SMALL LETTER ZETA
+<U03B7> /xa3/x62 GREEK SMALL LETTER ETA
+<U03B8> /xa3/x63 GREEK SMALL LETTER THETA
+<U03B9> /xa3/x64 GREEK SMALL LETTER IOTA
+<U03BA> /xa3/x65 GREEK SMALL LETTER KAPPA
+<U03BB> /xa3/x66 GREEK SMALL LETTER LAMDA
+<U03BC> /xa3/x67 GREEK SMALL LETTER MU
+<U03BD> /xa3/x68 GREEK SMALL LETTER NU
+<U03BE> /xa3/x69 GREEK SMALL LETTER XI
+<U03BF> /xa3/x6a GREEK SMALL LETTER OMICRON
+<U03C0> /xa3/x6b GREEK SMALL LETTER PI
+<U03C1> /xa3/x6c GREEK SMALL LETTER RHO
+<U03C3> /xa3/x6d GREEK SMALL LETTER SIGMA
+<U03C4> /xa3/x6e GREEK SMALL LETTER TAU
+<U03C5> /xa3/x6f GREEK SMALL LETTER UPSILON
+<U03C6> /xa3/x70 GREEK SMALL LETTER PHI
+<U03C7> /xa3/x71 GREEK SMALL LETTER CHI
+<U03C8> /xa3/x72 GREEK SMALL LETTER PSI
+<U03C9> /xa3/x73 GREEK SMALL LETTER OMEGA
+<U3105> /xa3/x74 BOPOMOFO LETTER B
+<U3106> /xa3/x75 BOPOMOFO LETTER P
+<U3107> /xa3/x76 BOPOMOFO LETTER M
+<U3108> /xa3/x77 BOPOMOFO LETTER F
+<U3109> /xa3/x78 BOPOMOFO LETTER D
+<U310A> /xa3/x79 BOPOMOFO LETTER T
+<U310B> /xa3/x7a BOPOMOFO LETTER N
+<U310C> /xa3/x7b BOPOMOFO LETTER L
+<U310D> /xa3/x7c BOPOMOFO LETTER G
+<U310E> /xa3/x7d BOPOMOFO LETTER K
+<U310F> /xa3/x7e BOPOMOFO LETTER H
+<U3110> /xa3/xa1 BOPOMOFO LETTER J
+<U3111> /xa3/xa2 BOPOMOFO LETTER Q
+<U3112> /xa3/xa3 BOPOMOFO LETTER X
+<U3113> /xa3/xa4 BOPOMOFO LETTER ZH
+<U3114> /xa3/xa5 BOPOMOFO LETTER CH
+<U3115> /xa3/xa6 BOPOMOFO LETTER SH
+<U3116> /xa3/xa7 BOPOMOFO LETTER R
+<U3117> /xa3/xa8 BOPOMOFO LETTER Z
+<U3118> /xa3/xa9 BOPOMOFO LETTER C
+<U3119> /xa3/xaa BOPOMOFO LETTER S
+<U311A> /xa3/xab BOPOMOFO LETTER A
+<U311B> /xa3/xac BOPOMOFO LETTER O
+<U311C> /xa3/xad BOPOMOFO LETTER E
+<U311D> /xa3/xae BOPOMOFO LETTER EH
+<U311E> /xa3/xaf BOPOMOFO LETTER AI
+<U311F> /xa3/xb0 BOPOMOFO LETTER EI
+<U3120> /xa3/xb1 BOPOMOFO LETTER AU
+<U3121> /xa3/xb2 BOPOMOFO LETTER OU
+<U3122> /xa3/xb3 BOPOMOFO LETTER AN
+<U3123> /xa3/xb4 BOPOMOFO LETTER EN
+<U3124> /xa3/xb5 BOPOMOFO LETTER ANG
+<U3125> /xa3/xb6 BOPOMOFO LETTER ENG
+<U3126> /xa3/xb7 BOPOMOFO LETTER ER
+<U3127> /xa3/xb8 BOPOMOFO LETTER I
+<U3128> /xa3/xb9 BOPOMOFO LETTER U
+<U3129> /xa3/xba BOPOMOFO LETTER IU
+<U02D9> /xa3/xbb DOT ABOVE
+<U02C9> /xa3/xbc MODIFIER LETTER MACRON
+<U02CA> /xa3/xbd MODIFIER LETTER ACUTE ACCENT
+<U02C7> /xa3/xbe CARON
+<U02CB> /xa3/xbf MODIFIER LETTER GRAVE ACCENT
+<U20AC> /xa3/xe1 EURO SIGN
+<U4E00> /xa4/x40 <CJK>
+<U4E59> /xa4/x41 <CJK>
+<U4E01> /xa4/x42 <CJK>
+<U4E03> /xa4/x43 <CJK>
+<U4E43> /xa4/x44 <CJK>
+<U4E5D> /xa4/x45 <CJK>
+<U4E86> /xa4/x46 <CJK>
+<U4E8C> /xa4/x47 <CJK>
+<U4EBA> /xa4/x48 <CJK>
+<U513F> /xa4/x49 <CJK>
+<U5165> /xa4/x4a <CJK>
+<U516B> /xa4/x4b <CJK>
+<U51E0> /xa4/x4c <CJK>
+<U5200> /xa4/x4d <CJK>
+<U5201> /xa4/x4e <CJK>
+<U529B> /xa4/x4f <CJK>
+<U5315> /xa4/x50 <CJK>
+<U5341> /xa4/x51 <CJK>
+<U535C> /xa4/x52 <CJK>
+<U53C8> /xa4/x53 <CJK>
+<U4E09> /xa4/x54 <CJK>
+<U4E0B> /xa4/x55 <CJK>
+<U4E08> /xa4/x56 <CJK>
+<U4E0A> /xa4/x57 <CJK>
+<U4E2B> /xa4/x58 <CJK>
+<U4E38> /xa4/x59 <CJK>
+<U51E1> /xa4/x5a <CJK>
+<U4E45> /xa4/x5b <CJK>
+<U4E48> /xa4/x5c <CJK>
+<U4E5F> /xa4/x5d <CJK>
+<U4E5E> /xa4/x5e <CJK>
+<U4E8E> /xa4/x5f <CJK>
+<U4EA1> /xa4/x60 <CJK>
+<U5140> /xa4/x61 <CJK>
+<U5203> /xa4/x62 <CJK>
+<U52FA> /xa4/x63 <CJK>
+<U5343> /xa4/x64 <CJK>
+<U53C9> /xa4/x65 <CJK>
+<U53E3> /xa4/x66 <CJK>
+<U571F> /xa4/x67 <CJK>
+<U58EB> /xa4/x68 <CJK>
+<U5915> /xa4/x69 <CJK>
+<U5927> /xa4/x6a <CJK>
+<U5973> /xa4/x6b <CJK>
+<U5B50> /xa4/x6c <CJK>
+<U5B51> /xa4/x6d <CJK>
+<U5B53> /xa4/x6e <CJK>
+<U5BF8> /xa4/x6f <CJK>
+<U5C0F> /xa4/x70 <CJK>
+<U5C22> /xa4/x71 <CJK>
+<U5C38> /xa4/x72 <CJK>
+<U5C71> /xa4/x73 <CJK>
+<U5DDD> /xa4/x74 <CJK>
+<U5DE5> /xa4/x75 <CJK>
+<U5DF1> /xa4/x76 <CJK>
+<U5DF2> /xa4/x77 <CJK>
+<U5DF3> /xa4/x78 <CJK>
+<U5DFE> /xa4/x79 <CJK>
+<U5E72> /xa4/x7a <CJK>
+<U5EFE> /xa4/x7b <CJK>
+<U5F0B> /xa4/x7c <CJK>
+<U5F13> /xa4/x7d <CJK>
+<U624D> /xa4/x7e <CJK>
+<U4E11> /xa4/xa1 <CJK>
+<U4E10> /xa4/xa2 <CJK>
+<U4E0D> /xa4/xa3 <CJK>
+<U4E2D> /xa4/xa4 <CJK>
+<U4E30> /xa4/xa5 <CJK>
+<U4E39> /xa4/xa6 <CJK>
+<U4E4B> /xa4/xa7 <CJK>
+<U5C39> /xa4/xa8 <CJK>
+<U4E88> /xa4/xa9 <CJK>
+<U4E91> /xa4/xaa <CJK>
+<U4E95> /xa4/xab <CJK>
+<U4E92> /xa4/xac <CJK>
+<U4E94> /xa4/xad <CJK>
+<U4EA2> /xa4/xae <CJK>
+<U4EC1> /xa4/xaf <CJK>
+<U4EC0> /xa4/xb0 <CJK>
+<U4EC3> /xa4/xb1 <CJK>
+<U4EC6> /xa4/xb2 <CJK>
+<U4EC7> /xa4/xb3 <CJK>
+<U4ECD> /xa4/xb4 <CJK>
+<U4ECA> /xa4/xb5 <CJK>
+<U4ECB> /xa4/xb6 <CJK>
+<U4EC4> /xa4/xb7 <CJK>
+<U5143> /xa4/xb8 <CJK>
+<U5141> /xa4/xb9 <CJK>
+<U5167> /xa4/xba <CJK>
+<U516D> /xa4/xbb <CJK>
+<U516E> /xa4/xbc <CJK>
+<U516C> /xa4/xbd <CJK>
+<U5197> /xa4/xbe <CJK>
+<U51F6> /xa4/xbf <CJK>
+<U5206> /xa4/xc0 <CJK>
+<U5207> /xa4/xc1 <CJK>
+<U5208> /xa4/xc2 <CJK>
+<U52FB> /xa4/xc3 <CJK>
+<U52FE> /xa4/xc4 <CJK>
+<U52FF> /xa4/xc5 <CJK>
+<U5316> /xa4/xc6 <CJK>
+<U5339> /xa4/xc7 <CJK>
+<U5348> /xa4/xc8 <CJK>
+<U5347> /xa4/xc9 <CJK>
+<U5345> /xa4/xca <CJK>
+<U535E> /xa4/xcb <CJK>
+<U5384> /xa4/xcc <CJK>
+<U53CB> /xa4/xcd <CJK>
+<U53CA> /xa4/xce <CJK>
+<U53CD> /xa4/xcf <CJK>
+<U58EC> /xa4/xd0 <CJK>
+<U5929> /xa4/xd1 <CJK>
+<U592B> /xa4/xd2 <CJK>
+<U592A> /xa4/xd3 <CJK>
+<U592D> /xa4/xd4 <CJK>
+<U5B54> /xa4/xd5 <CJK>
+<U5C11> /xa4/xd6 <CJK>
+<U5C24> /xa4/xd7 <CJK>
+<U5C3A> /xa4/xd8 <CJK>
+<U5C6F> /xa4/xd9 <CJK>
+<U5DF4> /xa4/xda <CJK>
+<U5E7B> /xa4/xdb <CJK>
+<U5EFF> /xa4/xdc <CJK>
+<U5F14> /xa4/xdd <CJK>
+<U5F15> /xa4/xde <CJK>
+<U5FC3> /xa4/xdf <CJK>
+<U6208> /xa4/xe0 <CJK>
+<U6236> /xa4/xe1 <CJK>
+<U624B> /xa4/xe2 <CJK>
+<U624E> /xa4/xe3 <CJK>
+<U652F> /xa4/xe4 <CJK>
+<U6587> /xa4/xe5 <CJK>
+<U6597> /xa4/xe6 <CJK>
+<U65A4> /xa4/xe7 <CJK>
+<U65B9> /xa4/xe8 <CJK>
+<U65E5> /xa4/xe9 <CJK>
+<U66F0> /xa4/xea <CJK>
+<U6708> /xa4/xeb <CJK>
+<U6728> /xa4/xec <CJK>
+<U6B20> /xa4/xed <CJK>
+<U6B62> /xa4/xee <CJK>
+<U6B79> /xa4/xef <CJK>
+<U6BCB> /xa4/xf0 <CJK>
+<U6BD4> /xa4/xf1 <CJK>
+<U6BDB> /xa4/xf2 <CJK>
+<U6C0F> /xa4/xf3 <CJK>
+<U6C34> /xa4/xf4 <CJK>
+<U706B> /xa4/xf5 <CJK>
+<U722A> /xa4/xf6 <CJK>
+<U7236> /xa4/xf7 <CJK>
+<U723B> /xa4/xf8 <CJK>
+<U7247> /xa4/xf9 <CJK>
+<U7259> /xa4/xfa <CJK>
+<U725B> /xa4/xfb <CJK>
+<U72AC> /xa4/xfc <CJK>
+<U738B> /xa4/xfd <CJK>
+<U4E19> /xa4/xfe <CJK>
+<U4E16> /xa5/x40 <CJK>
+<U4E15> /xa5/x41 <CJK>
+<U4E14> /xa5/x42 <CJK>
+<U4E18> /xa5/x43 <CJK>
+<U4E3B> /xa5/x44 <CJK>
+<U4E4D> /xa5/x45 <CJK>
+<U4E4F> /xa5/x46 <CJK>
+<U4E4E> /xa5/x47 <CJK>
+<U4EE5> /xa5/x48 <CJK>
+<U4ED8> /xa5/x49 <CJK>
+<U4ED4> /xa5/x4a <CJK>
+<U4ED5> /xa5/x4b <CJK>
+<U4ED6> /xa5/x4c <CJK>
+<U4ED7> /xa5/x4d <CJK>
+<U4EE3> /xa5/x4e <CJK>
+<U4EE4> /xa5/x4f <CJK>
+<U4ED9> /xa5/x50 <CJK>
+<U4EDE> /xa5/x51 <CJK>
+<U5145> /xa5/x52 <CJK>
+<U5144> /xa5/x53 <CJK>
+<U5189> /xa5/x54 <CJK>
+<U518A> /xa5/x55 <CJK>
+<U51AC> /xa5/x56 <CJK>
+<U51F9> /xa5/x57 <CJK>
+<U51FA> /xa5/x58 <CJK>
+<U51F8> /xa5/x59 <CJK>
+<U520A> /xa5/x5a <CJK>
+<U52A0> /xa5/x5b <CJK>
+<U529F> /xa5/x5c <CJK>
+<U5305> /xa5/x5d <CJK>
+<U5306> /xa5/x5e <CJK>
+<U5317> /xa5/x5f <CJK>
+<U531D> /xa5/x60 <CJK>
+<U4EDF> /xa5/x61 <CJK>
+<U534A> /xa5/x62 <CJK>
+<U5349> /xa5/x63 <CJK>
+<U5361> /xa5/x64 <CJK>
+<U5360> /xa5/x65 <CJK>
+<U536F> /xa5/x66 <CJK>
+<U536E> /xa5/x67 <CJK>
+<U53BB> /xa5/x68 <CJK>
+<U53EF> /xa5/x69 <CJK>
+<U53E4> /xa5/x6a <CJK>
+<U53F3> /xa5/x6b <CJK>
+<U53EC> /xa5/x6c <CJK>
+<U53EE> /xa5/x6d <CJK>
+<U53E9> /xa5/x6e <CJK>
+<U53E8> /xa5/x6f <CJK>
+<U53FC> /xa5/x70 <CJK>
+<U53F8> /xa5/x71 <CJK>
+<U53F5> /xa5/x72 <CJK>
+<U53EB> /xa5/x73 <CJK>
+<U53E6> /xa5/x74 <CJK>
+<U53EA> /xa5/x75 <CJK>
+<U53F2> /xa5/x76 <CJK>
+<U53F1> /xa5/x77 <CJK>
+<U53F0> /xa5/x78 <CJK>
+<U53E5> /xa5/x79 <CJK>
+<U53ED> /xa5/x7a <CJK>
+<U53FB> /xa5/x7b <CJK>
+<U56DB> /xa5/x7c <CJK>
+<U56DA> /xa5/x7d <CJK>
+<U5916> /xa5/x7e <CJK>
+<U592E> /xa5/xa1 <CJK>
+<U5931> /xa5/xa2 <CJK>
+<U5974> /xa5/xa3 <CJK>
+<U5976> /xa5/xa4 <CJK>
+<U5B55> /xa5/xa5 <CJK>
+<U5B83> /xa5/xa6 <CJK>
+<U5C3C> /xa5/xa7 <CJK>
+<U5DE8> /xa5/xa8 <CJK>
+<U5DE7> /xa5/xa9 <CJK>
+<U5DE6> /xa5/xaa <CJK>
+<U5E02> /xa5/xab <CJK>
+<U5E03> /xa5/xac <CJK>
+<U5E73> /xa5/xad <CJK>
+<U5E7C> /xa5/xae <CJK>
+<U5F01> /xa5/xaf <CJK>
+<U5F18> /xa5/xb0 <CJK>
+<U5F17> /xa5/xb1 <CJK>
+<U5FC5> /xa5/xb2 <CJK>
+<U620A> /xa5/xb3 <CJK>
+<U6253> /xa5/xb4 <CJK>
+<U6254> /xa5/xb5 <CJK>
+<U6252> /xa5/xb6 <CJK>
+<U6251> /xa5/xb7 <CJK>
+<U65A5> /xa5/xb8 <CJK>
+<U65E6> /xa5/xb9 <CJK>
+<U672E> /xa5/xba <CJK>
+<U672C> /xa5/xbb <CJK>
+<U672A> /xa5/xbc <CJK>
+<U672B> /xa5/xbd <CJK>
+<U672D> /xa5/xbe <CJK>
+<U6B63> /xa5/xbf <CJK>
+<U6BCD> /xa5/xc0 <CJK>
+<U6C11> /xa5/xc1 <CJK>
+<U6C10> /xa5/xc2 <CJK>
+<U6C38> /xa5/xc3 <CJK>
+<U6C41> /xa5/xc4 <CJK>
+<U6C40> /xa5/xc5 <CJK>
+<U6C3E> /xa5/xc6 <CJK>
+<U72AF> /xa5/xc7 <CJK>
+<U7384> /xa5/xc8 <CJK>
+<U7389> /xa5/xc9 <CJK>
+<U74DC> /xa5/xca <CJK>
+<U74E6> /xa5/xcb <CJK>
+<U7518> /xa5/xcc <CJK>
+<U751F> /xa5/xcd <CJK>
+<U7528> /xa5/xce <CJK>
+<U7529> /xa5/xcf <CJK>
+<U7530> /xa5/xd0 <CJK>
+<U7531> /xa5/xd1 <CJK>
+<U7532> /xa5/xd2 <CJK>
+<U7533> /xa5/xd3 <CJK>
+<U758B> /xa5/xd4 <CJK>
+<U767D> /xa5/xd5 <CJK>
+<U76AE> /xa5/xd6 <CJK>
+<U76BF> /xa5/xd7 <CJK>
+<U76EE> /xa5/xd8 <CJK>
+<U77DB> /xa5/xd9 <CJK>
+<U77E2> /xa5/xda <CJK>
+<U77F3> /xa5/xdb <CJK>
+<U793A> /xa5/xdc <CJK>
+<U79BE> /xa5/xdd <CJK>
+<U7A74> /xa5/xde <CJK>
+<U7ACB> /xa5/xdf <CJK>
+<U4E1E> /xa5/xe0 <CJK>
+<U4E1F> /xa5/xe1 <CJK>
+<U4E52> /xa5/xe2 <CJK>
+<U4E53> /xa5/xe3 <CJK>
+<U4E69> /xa5/xe4 <CJK>
+<U4E99> /xa5/xe5 <CJK>
+<U4EA4> /xa5/xe6 <CJK>
+<U4EA6> /xa5/xe7 <CJK>
+<U4EA5> /xa5/xe8 <CJK>
+<U4EFF> /xa5/xe9 <CJK>
+<U4F09> /xa5/xea <CJK>
+<U4F19> /xa5/xeb <CJK>
+<U4F0A> /xa5/xec <CJK>
+<U4F15> /xa5/xed <CJK>
+<U4F0D> /xa5/xee <CJK>
+<U4F10> /xa5/xef <CJK>
+<U4F11> /xa5/xf0 <CJK>
+<U4F0F> /xa5/xf1 <CJK>
+<U4EF2> /xa5/xf2 <CJK>
+<U4EF6> /xa5/xf3 <CJK>
+<U4EFB> /xa5/xf4 <CJK>
+<U4EF0> /xa5/xf5 <CJK>
+<U4EF3> /xa5/xf6 <CJK>
+<U4EFD> /xa5/xf7 <CJK>
+<U4F01> /xa5/xf8 <CJK>
+<U4F0B> /xa5/xf9 <CJK>
+<U5149> /xa5/xfa <CJK>
+<U5147> /xa5/xfb <CJK>
+<U5146> /xa5/xfc <CJK>
+<U5148> /xa5/xfd <CJK>
+<U5168> /xa5/xfe <CJK>
+<U5171> /xa6/x40 <CJK>
+<U518D> /xa6/x41 <CJK>
+<U51B0> /xa6/x42 <CJK>
+<U5217> /xa6/x43 <CJK>
+<U5211> /xa6/x44 <CJK>
+<U5212> /xa6/x45 <CJK>
+<U520E> /xa6/x46 <CJK>
+<U5216> /xa6/x47 <CJK>
+<U52A3> /xa6/x48 <CJK>
+<U5308> /xa6/x49 <CJK>
+<U5321> /xa6/x4a <CJK>
+<U5320> /xa6/x4b <CJK>
+<U5370> /xa6/x4c <CJK>
+<U5371> /xa6/x4d <CJK>
+<U5409> /xa6/x4e <CJK>
+<U540F> /xa6/x4f <CJK>
+<U540C> /xa6/x50 <CJK>
+<U540A> /xa6/x51 <CJK>
+<U5410> /xa6/x52 <CJK>
+<U5401> /xa6/x53 <CJK>
+<U540B> /xa6/x54 <CJK>
+<U5404> /xa6/x55 <CJK>
+<U5411> /xa6/x56 <CJK>
+<U540D> /xa6/x57 <CJK>
+<U5408> /xa6/x58 <CJK>
+<U5403> /xa6/x59 <CJK>
+<U540E> /xa6/x5a <CJK>
+<U5406> /xa6/x5b <CJK>
+<U5412> /xa6/x5c <CJK>
+<U56E0> /xa6/x5d <CJK>
+<U56DE> /xa6/x5e <CJK>
+<U56DD> /xa6/x5f <CJK>
+<U5733> /xa6/x60 <CJK>
+<U5730> /xa6/x61 <CJK>
+<U5728> /xa6/x62 <CJK>
+<U572D> /xa6/x63 <CJK>
+<U572C> /xa6/x64 <CJK>
+<U572F> /xa6/x65 <CJK>
+<U5729> /xa6/x66 <CJK>
+<U5919> /xa6/x67 <CJK>
+<U591A> /xa6/x68 <CJK>
+<U5937> /xa6/x69 <CJK>
+<U5938> /xa6/x6a <CJK>
+<U5984> /xa6/x6b <CJK>
+<U5978> /xa6/x6c <CJK>
+<U5983> /xa6/x6d <CJK>
+<U597D> /xa6/x6e <CJK>
+<U5979> /xa6/x6f <CJK>
+<U5982> /xa6/x70 <CJK>
+<U5981> /xa6/x71 <CJK>
+<U5B57> /xa6/x72 <CJK>
+<U5B58> /xa6/x73 <CJK>
+<U5B87> /xa6/x74 <CJK>
+<U5B88> /xa6/x75 <CJK>
+<U5B85> /xa6/x76 <CJK>
+<U5B89> /xa6/x77 <CJK>
+<U5BFA> /xa6/x78 <CJK>
+<U5C16> /xa6/x79 <CJK>
+<U5C79> /xa6/x7a <CJK>
+<U5DDE> /xa6/x7b <CJK>
+<U5E06> /xa6/x7c <CJK>
+<U5E76> /xa6/x7d <CJK>
+<U5E74> /xa6/x7e <CJK>
+<U5F0F> /xa6/xa1 <CJK>
+<U5F1B> /xa6/xa2 <CJK>
+<U5FD9> /xa6/xa3 <CJK>
+<U5FD6> /xa6/xa4 <CJK>
+<U620E> /xa6/xa5 <CJK>
+<U620C> /xa6/xa6 <CJK>
+<U620D> /xa6/xa7 <CJK>
+<U6210> /xa6/xa8 <CJK>
+<U6263> /xa6/xa9 <CJK>
+<U625B> /xa6/xaa <CJK>
+<U6258> /xa6/xab <CJK>
+<U6536> /xa6/xac <CJK>
+<U65E9> /xa6/xad <CJK>
+<U65E8> /xa6/xae <CJK>
+<U65EC> /xa6/xaf <CJK>
+<U65ED> /xa6/xb0 <CJK>
+<U66F2> /xa6/xb1 <CJK>
+<U66F3> /xa6/xb2 <CJK>
+<U6709> /xa6/xb3 <CJK>
+<U673D> /xa6/xb4 <CJK>
+<U6734> /xa6/xb5 <CJK>
+<U6731> /xa6/xb6 <CJK>
+<U6735> /xa6/xb7 <CJK>
+<U6B21> /xa6/xb8 <CJK>
+<U6B64> /xa6/xb9 <CJK>
+<U6B7B> /xa6/xba <CJK>
+<U6C16> /xa6/xbb <CJK>
+<U6C5D> /xa6/xbc <CJK>
+<U6C57> /xa6/xbd <CJK>
+<U6C59> /xa6/xbe <CJK>
+<U6C5F> /xa6/xbf <CJK>
+<U6C60> /xa6/xc0 <CJK>
+<U6C50> /xa6/xc1 <CJK>
+<U6C55> /xa6/xc2 <CJK>
+<U6C61> /xa6/xc3 <CJK>
+<U6C5B> /xa6/xc4 <CJK>
+<U6C4D> /xa6/xc5 <CJK>
+<U6C4E> /xa6/xc6 <CJK>
+<U7070> /xa6/xc7 <CJK>
+<U725F> /xa6/xc8 <CJK>
+<U725D> /xa6/xc9 <CJK>
+<U767E> /xa6/xca <CJK>
+<U7AF9> /xa6/xcb <CJK>
+<U7C73> /xa6/xcc <CJK>
+<U7CF8> /xa6/xcd <CJK>
+<U7F36> /xa6/xce <CJK>
+<U7F8A> /xa6/xcf <CJK>
+<U7FBD> /xa6/xd0 <CJK>
+<U8001> /xa6/xd1 <CJK>
+<U8003> /xa6/xd2 <CJK>
+<U800C> /xa6/xd3 <CJK>
+<U8012> /xa6/xd4 <CJK>
+<U8033> /xa6/xd5 <CJK>
+<U807F> /xa6/xd6 <CJK>
+<U8089> /xa6/xd7 <CJK>
+<U808B> /xa6/xd8 <CJK>
+<U808C> /xa6/xd9 <CJK>
+<U81E3> /xa6/xda <CJK>
+<U81EA> /xa6/xdb <CJK>
+<U81F3> /xa6/xdc <CJK>
+<U81FC> /xa6/xdd <CJK>
+<U820C> /xa6/xde <CJK>
+<U821B> /xa6/xdf <CJK>
+<U821F> /xa6/xe0 <CJK>
+<U826E> /xa6/xe1 <CJK>
+<U8272> /xa6/xe2 <CJK>
+<U827E> /xa6/xe3 <CJK>
+<U866B> /xa6/xe4 <CJK>
+<U8840> /xa6/xe5 <CJK>
+<U884C> /xa6/xe6 <CJK>
+<U8863> /xa6/xe7 <CJK>
+<U897F> /xa6/xe8 <CJK>
+<U9621> /xa6/xe9 <CJK>
+<U4E32> /xa6/xea <CJK>
+<U4EA8> /xa6/xeb <CJK>
+<U4F4D> /xa6/xec <CJK>
+<U4F4F> /xa6/xed <CJK>
+<U4F47> /xa6/xee <CJK>
+<U4F57> /xa6/xef <CJK>
+<U4F5E> /xa6/xf0 <CJK>
+<U4F34> /xa6/xf1 <CJK>
+<U4F5B> /xa6/xf2 <CJK>
+<U4F55> /xa6/xf3 <CJK>
+<U4F30> /xa6/xf4 <CJK>
+<U4F50> /xa6/xf5 <CJK>
+<U4F51> /xa6/xf6 <CJK>
+<U4F3D> /xa6/xf7 <CJK>
+<U4F3A> /xa6/xf8 <CJK>
+<U4F38> /xa6/xf9 <CJK>
+<U4F43> /xa6/xfa <CJK>
+<U4F54> /xa6/xfb <CJK>
+<U4F3C> /xa6/xfc <CJK>
+<U4F46> /xa6/xfd <CJK>
+<U4F63> /xa6/xfe <CJK>
+<U4F5C> /xa7/x40 <CJK>
+<U4F60> /xa7/x41 <CJK>
+<U4F2F> /xa7/x42 <CJK>
+<U4F4E> /xa7/x43 <CJK>
+<U4F36> /xa7/x44 <CJK>
+<U4F59> /xa7/x45 <CJK>
+<U4F5D> /xa7/x46 <CJK>
+<U4F48> /xa7/x47 <CJK>
+<U4F5A> /xa7/x48 <CJK>
+<U514C> /xa7/x49 <CJK>
+<U514B> /xa7/x4a <CJK>
+<U514D> /xa7/x4b <CJK>
+<U5175> /xa7/x4c <CJK>
+<U51B6> /xa7/x4d <CJK>
+<U51B7> /xa7/x4e <CJK>
+<U5225> /xa7/x4f <CJK>
+<U5224> /xa7/x50 <CJK>
+<U5229> /xa7/x51 <CJK>
+<U522A> /xa7/x52 <CJK>
+<U5228> /xa7/x53 <CJK>
+<U52AB> /xa7/x54 <CJK>
+<U52A9> /xa7/x55 <CJK>
+<U52AA> /xa7/x56 <CJK>
+<U52AC> /xa7/x57 <CJK>
+<U5323> /xa7/x58 <CJK>
+<U5373> /xa7/x59 <CJK>
+<U5375> /xa7/x5a <CJK>
+<U541D> /xa7/x5b <CJK>
+<U542D> /xa7/x5c <CJK>
+<U541E> /xa7/x5d <CJK>
+<U543E> /xa7/x5e <CJK>
+<U5426> /xa7/x5f <CJK>
+<U544E> /xa7/x60 <CJK>
+<U5427> /xa7/x61 <CJK>
+<U5446> /xa7/x62 <CJK>
+<U5443> /xa7/x63 <CJK>
+<U5433> /xa7/x64 <CJK>
+<U5448> /xa7/x65 <CJK>
+<U5442> /xa7/x66 <CJK>
+<U541B> /xa7/x67 <CJK>
+<U5429> /xa7/x68 <CJK>
+<U544A> /xa7/x69 <CJK>
+<U5439> /xa7/x6a <CJK>
+<U543B> /xa7/x6b <CJK>
+<U5438> /xa7/x6c <CJK>
+<U542E> /xa7/x6d <CJK>
+<U5435> /xa7/x6e <CJK>
+<U5436> /xa7/x6f <CJK>
+<U5420> /xa7/x70 <CJK>
+<U543C> /xa7/x71 <CJK>
+<U5440> /xa7/x72 <CJK>
+<U5431> /xa7/x73 <CJK>
+<U542B> /xa7/x74 <CJK>
+<U541F> /xa7/x75 <CJK>
+<U542C> /xa7/x76 <CJK>
+<U56EA> /xa7/x77 <CJK>
+<U56F0> /xa7/x78 <CJK>
+<U56E4> /xa7/x79 <CJK>
+<U56EB> /xa7/x7a <CJK>
+<U574A> /xa7/x7b <CJK>
+<U5751> /xa7/x7c <CJK>
+<U5740> /xa7/x7d <CJK>
+<U574D> /xa7/x7e <CJK>
+<U5747> /xa7/xa1 <CJK>
+<U574E> /xa7/xa2 <CJK>
+<U573E> /xa7/xa3 <CJK>
+<U5750> /xa7/xa4 <CJK>
+<U574F> /xa7/xa5 <CJK>
+<U573B> /xa7/xa6 <CJK>
+<U58EF> /xa7/xa7 <CJK>
+<U593E> /xa7/xa8 <CJK>
+<U599D> /xa7/xa9 <CJK>
+<U5992> /xa7/xaa <CJK>
+<U59A8> /xa7/xab <CJK>
+<U599E> /xa7/xac <CJK>
+<U59A3> /xa7/xad <CJK>
+<U5999> /xa7/xae <CJK>
+<U5996> /xa7/xaf <CJK>
+<U598D> /xa7/xb0 <CJK>
+<U59A4> /xa7/xb1 <CJK>
+<U5993> /xa7/xb2 <CJK>
+<U598A> /xa7/xb3 <CJK>
+<U59A5> /xa7/xb4 <CJK>
+<U5B5D> /xa7/xb5 <CJK>
+<U5B5C> /xa7/xb6 <CJK>
+<U5B5A> /xa7/xb7 <CJK>
+<U5B5B> /xa7/xb8 <CJK>
+<U5B8C> /xa7/xb9 <CJK>
+<U5B8B> /xa7/xba <CJK>
+<U5B8F> /xa7/xbb <CJK>
+<U5C2C> /xa7/xbc <CJK>
+<U5C40> /xa7/xbd <CJK>
+<U5C41> /xa7/xbe <CJK>
+<U5C3F> /xa7/xbf <CJK>
+<U5C3E> /xa7/xc0 <CJK>
+<U5C90> /xa7/xc1 <CJK>
+<U5C91> /xa7/xc2 <CJK>
+<U5C94> /xa7/xc3 <CJK>
+<U5C8C> /xa7/xc4 <CJK>
+<U5DEB> /xa7/xc5 <CJK>
+<U5E0C> /xa7/xc6 <CJK>
+<U5E8F> /xa7/xc7 <CJK>
+<U5E87> /xa7/xc8 <CJK>
+<U5E8A> /xa7/xc9 <CJK>
+<U5EF7> /xa7/xca <CJK>
+<U5F04> /xa7/xcb <CJK>
+<U5F1F> /xa7/xcc <CJK>
+<U5F64> /xa7/xcd <CJK>
+<U5F62> /xa7/xce <CJK>
+<U5F77> /xa7/xcf <CJK>
+<U5F79> /xa7/xd0 <CJK>
+<U5FD8> /xa7/xd1 <CJK>
+<U5FCC> /xa7/xd2 <CJK>
+<U5FD7> /xa7/xd3 <CJK>
+<U5FCD> /xa7/xd4 <CJK>
+<U5FF1> /xa7/xd5 <CJK>
+<U5FEB> /xa7/xd6 <CJK>
+<U5FF8> /xa7/xd7 <CJK>
+<U5FEA> /xa7/xd8 <CJK>
+<U6212> /xa7/xd9 <CJK>
+<U6211> /xa7/xda <CJK>
+<U6284> /xa7/xdb <CJK>
+<U6297> /xa7/xdc <CJK>
+<U6296> /xa7/xdd <CJK>
+<U6280> /xa7/xde <CJK>
+<U6276> /xa7/xdf <CJK>
+<U6289> /xa7/xe0 <CJK>
+<U626D> /xa7/xe1 <CJK>
+<U628A> /xa7/xe2 <CJK>
+<U627C> /xa7/xe3 <CJK>
+<U627E> /xa7/xe4 <CJK>
+<U6279> /xa7/xe5 <CJK>
+<U6273> /xa7/xe6 <CJK>
+<U6292> /xa7/xe7 <CJK>
+<U626F> /xa7/xe8 <CJK>
+<U6298> /xa7/xe9 <CJK>
+<U626E> /xa7/xea <CJK>
+<U6295> /xa7/xeb <CJK>
+<U6293> /xa7/xec <CJK>
+<U6291> /xa7/xed <CJK>
+<U6286> /xa7/xee <CJK>
+<U6539> /xa7/xef <CJK>
+<U653B> /xa7/xf0 <CJK>
+<U6538> /xa7/xf1 <CJK>
+<U65F1> /xa7/xf2 <CJK>
+<U66F4> /xa7/xf3 <CJK>
+<U675F> /xa7/xf4 <CJK>
+<U674E> /xa7/xf5 <CJK>
+<U674F> /xa7/xf6 <CJK>
+<U6750> /xa7/xf7 <CJK>
+<U6751> /xa7/xf8 <CJK>
+<U675C> /xa7/xf9 <CJK>
+<U6756> /xa7/xfa <CJK>
+<U675E> /xa7/xfb <CJK>
+<U6749> /xa7/xfc <CJK>
+<U6746> /xa7/xfd <CJK>
+<U6760> /xa7/xfe <CJK>
+<U6753> /xa8/x40 <CJK>
+<U6757> /xa8/x41 <CJK>
+<U6B65> /xa8/x42 <CJK>
+<U6BCF> /xa8/x43 <CJK>
+<U6C42> /xa8/x44 <CJK>
+<U6C5E> /xa8/x45 <CJK>
+<U6C99> /xa8/x46 <CJK>
+<U6C81> /xa8/x47 <CJK>
+<U6C88> /xa8/x48 <CJK>
+<U6C89> /xa8/x49 <CJK>
+<U6C85> /xa8/x4a <CJK>
+<U6C9B> /xa8/x4b <CJK>
+<U6C6A> /xa8/x4c <CJK>
+<U6C7A> /xa8/x4d <CJK>
+<U6C90> /xa8/x4e <CJK>
+<U6C70> /xa8/x4f <CJK>
+<U6C8C> /xa8/x50 <CJK>
+<U6C68> /xa8/x51 <CJK>
+<U6C96> /xa8/x52 <CJK>
+<U6C92> /xa8/x53 <CJK>
+<U6C7D> /xa8/x54 <CJK>
+<U6C83> /xa8/x55 <CJK>
+<U6C72> /xa8/x56 <CJK>
+<U6C7E> /xa8/x57 <CJK>
+<U6C74> /xa8/x58 <CJK>
+<U6C86> /xa8/x59 <CJK>
+<U6C76> /xa8/x5a <CJK>
+<U6C8D> /xa8/x5b <CJK>
+<U6C94> /xa8/x5c <CJK>
+<U6C98> /xa8/x5d <CJK>
+<U6C82> /xa8/x5e <CJK>
+<U7076> /xa8/x5f <CJK>
+<U707C> /xa8/x60 <CJK>
+<U707D> /xa8/x61 <CJK>
+<U7078> /xa8/x62 <CJK>
+<U7262> /xa8/x63 <CJK>
+<U7261> /xa8/x64 <CJK>
+<U7260> /xa8/x65 <CJK>
+<U72C4> /xa8/x66 <CJK>
+<U72C2> /xa8/x67 <CJK>
+<U7396> /xa8/x68 <CJK>
+<U752C> /xa8/x69 <CJK>
+<U752B> /xa8/x6a <CJK>
+<U7537> /xa8/x6b <CJK>
+<U7538> /xa8/x6c <CJK>
+<U7682> /xa8/x6d <CJK>
+<U76EF> /xa8/x6e <CJK>
+<U77E3> /xa8/x6f <CJK>
+<U79C1> /xa8/x70 <CJK>
+<U79C0> /xa8/x71 <CJK>
+<U79BF> /xa8/x72 <CJK>
+<U7A76> /xa8/x73 <CJK>
+<U7CFB> /xa8/x74 <CJK>
+<U7F55> /xa8/x75 <CJK>
+<U8096> /xa8/x76 <CJK>
+<U8093> /xa8/x77 <CJK>
+<U809D> /xa8/x78 <CJK>
+<U8098> /xa8/x79 <CJK>
+<U809B> /xa8/x7a <CJK>
+<U809A> /xa8/x7b <CJK>
+<U80B2> /xa8/x7c <CJK>
+<U826F> /xa8/x7d <CJK>
+<U8292> /xa8/x7e <CJK>
+<U828B> /xa8/xa1 <CJK>
+<U828D> /xa8/xa2 <CJK>
+<U898B> /xa8/xa3 <CJK>
+<U89D2> /xa8/xa4 <CJK>
+<U8A00> /xa8/xa5 <CJK>
+<U8C37> /xa8/xa6 <CJK>
+<U8C46> /xa8/xa7 <CJK>
+<U8C55> /xa8/xa8 <CJK>
+<U8C9D> /xa8/xa9 <CJK>
+<U8D64> /xa8/xaa <CJK>
+<U8D70> /xa8/xab <CJK>
+<U8DB3> /xa8/xac <CJK>
+<U8EAB> /xa8/xad <CJK>
+<U8ECA> /xa8/xae <CJK>
+<U8F9B> /xa8/xaf <CJK>
+<U8FB0> /xa8/xb0 <CJK>
+<U8FC2> /xa8/xb1 <CJK>
+<U8FC6> /xa8/xb2 <CJK>
+<U8FC5> /xa8/xb3 <CJK>
+<U8FC4> /xa8/xb4 <CJK>
+<U5DE1> /xa8/xb5 <CJK>
+<U9091> /xa8/xb6 <CJK>
+<U90A2> /xa8/xb7 <CJK>
+<U90AA> /xa8/xb8 <CJK>
+<U90A6> /xa8/xb9 <CJK>
+<U90A3> /xa8/xba <CJK>
+<U9149> /xa8/xbb <CJK>
+<U91C6> /xa8/xbc <CJK>
+<U91CC> /xa8/xbd <CJK>
+<U9632> /xa8/xbe <CJK>
+<U962E> /xa8/xbf <CJK>
+<U9631> /xa8/xc0 <CJK>
+<U962A> /xa8/xc1 <CJK>
+<U962C> /xa8/xc2 <CJK>
+<U4E26> /xa8/xc3 <CJK>
+<U4E56> /xa8/xc4 <CJK>
+<U4E73> /xa8/xc5 <CJK>
+<U4E8B> /xa8/xc6 <CJK>
+<U4E9B> /xa8/xc7 <CJK>
+<U4E9E> /xa8/xc8 <CJK>
+<U4EAB> /xa8/xc9 <CJK>
+<U4EAC> /xa8/xca <CJK>
+<U4F6F> /xa8/xcb <CJK>
+<U4F9D> /xa8/xcc <CJK>
+<U4F8D> /xa8/xcd <CJK>
+<U4F73> /xa8/xce <CJK>
+<U4F7F> /xa8/xcf <CJK>
+<U4F6C> /xa8/xd0 <CJK>
+<U4F9B> /xa8/xd1 <CJK>
+<U4F8B> /xa8/xd2 <CJK>
+<U4F86> /xa8/xd3 <CJK>
+<U4F83> /xa8/xd4 <CJK>
+<U4F70> /xa8/xd5 <CJK>
+<U4F75> /xa8/xd6 <CJK>
+<U4F88> /xa8/xd7 <CJK>
+<U4F69> /xa8/xd8 <CJK>
+<U4F7B> /xa8/xd9 <CJK>
+<U4F96> /xa8/xda <CJK>
+<U4F7E> /xa8/xdb <CJK>
+<U4F8F> /xa8/xdc <CJK>
+<U4F91> /xa8/xdd <CJK>
+<U4F7A> /xa8/xde <CJK>
+<U5154> /xa8/xdf <CJK>
+<U5152> /xa8/xe0 <CJK>
+<U5155> /xa8/xe1 <CJK>
+<U5169> /xa8/xe2 <CJK>
+<U5177> /xa8/xe3 <CJK>
+<U5176> /xa8/xe4 <CJK>
+<U5178> /xa8/xe5 <CJK>
+<U51BD> /xa8/xe6 <CJK>
+<U51FD> /xa8/xe7 <CJK>
+<U523B> /xa8/xe8 <CJK>
+<U5238> /xa8/xe9 <CJK>
+<U5237> /xa8/xea <CJK>
+<U523A> /xa8/xeb <CJK>
+<U5230> /xa8/xec <CJK>
+<U522E> /xa8/xed <CJK>
+<U5236> /xa8/xee <CJK>
+<U5241> /xa8/xef <CJK>
+<U52BE> /xa8/xf0 <CJK>
+<U52BB> /xa8/xf1 <CJK>
+<U5352> /xa8/xf2 <CJK>
+<U5354> /xa8/xf3 <CJK>
+<U5353> /xa8/xf4 <CJK>
+<U5351> /xa8/xf5 <CJK>
+<U5366> /xa8/xf6 <CJK>
+<U5377> /xa8/xf7 <CJK>
+<U5378> /xa8/xf8 <CJK>
+<U5379> /xa8/xf9 <CJK>
+<U53D6> /xa8/xfa <CJK>
+<U53D4> /xa8/xfb <CJK>
+<U53D7> /xa8/xfc <CJK>
+<U5473> /xa8/xfd <CJK>
+<U5475> /xa8/xfe <CJK>
+<U5496> /xa9/x40 <CJK>
+<U5478> /xa9/x41 <CJK>
+<U5495> /xa9/x42 <CJK>
+<U5480> /xa9/x43 <CJK>
+<U547B> /xa9/x44 <CJK>
+<U5477> /xa9/x45 <CJK>
+<U5484> /xa9/x46 <CJK>
+<U5492> /xa9/x47 <CJK>
+<U5486> /xa9/x48 <CJK>
+<U547C> /xa9/x49 <CJK>
+<U5490> /xa9/x4a <CJK>
+<U5471> /xa9/x4b <CJK>
+<U5476> /xa9/x4c <CJK>
+<U548C> /xa9/x4d <CJK>
+<U549A> /xa9/x4e <CJK>
+<U5462> /xa9/x4f <CJK>
+<U5468> /xa9/x50 <CJK>
+<U548B> /xa9/x51 <CJK>
+<U547D> /xa9/x52 <CJK>
+<U548E> /xa9/x53 <CJK>
+<U56FA> /xa9/x54 <CJK>
+<U5783> /xa9/x55 <CJK>
+<U5777> /xa9/x56 <CJK>
+<U576A> /xa9/x57 <CJK>
+<U5769> /xa9/x58 <CJK>
+<U5761> /xa9/x59 <CJK>
+<U5766> /xa9/x5a <CJK>
+<U5764> /xa9/x5b <CJK>
+<U577C> /xa9/x5c <CJK>
+<U591C> /xa9/x5d <CJK>
+<U5949> /xa9/x5e <CJK>
+<U5947> /xa9/x5f <CJK>
+<U5948> /xa9/x60 <CJK>
+<U5944> /xa9/x61 <CJK>
+<U5954> /xa9/x62 <CJK>
+<U59BE> /xa9/x63 <CJK>
+<U59BB> /xa9/x64 <CJK>
+<U59D4> /xa9/x65 <CJK>
+<U59B9> /xa9/x66 <CJK>
+<U59AE> /xa9/x67 <CJK>
+<U59D1> /xa9/x68 <CJK>
+<U59C6> /xa9/x69 <CJK>
+<U59D0> /xa9/x6a <CJK>
+<U59CD> /xa9/x6b <CJK>
+<U59CB> /xa9/x6c <CJK>
+<U59D3> /xa9/x6d <CJK>
+<U59CA> /xa9/x6e <CJK>
+<U59AF> /xa9/x6f <CJK>
+<U59B3> /xa9/x70 <CJK>
+<U59D2> /xa9/x71 <CJK>
+<U59C5> /xa9/x72 <CJK>
+<U5B5F> /xa9/x73 <CJK>
+<U5B64> /xa9/x74 <CJK>
+<U5B63> /xa9/x75 <CJK>
+<U5B97> /xa9/x76 <CJK>
+<U5B9A> /xa9/x77 <CJK>
+<U5B98> /xa9/x78 <CJK>
+<U5B9C> /xa9/x79 <CJK>
+<U5B99> /xa9/x7a <CJK>
+<U5B9B> /xa9/x7b <CJK>
+<U5C1A> /xa9/x7c <CJK>
+<U5C48> /xa9/x7d <CJK>
+<U5C45> /xa9/x7e <CJK>
+<U5C46> /xa9/xa1 <CJK>
+<U5CB7> /xa9/xa2 <CJK>
+<U5CA1> /xa9/xa3 <CJK>
+<U5CB8> /xa9/xa4 <CJK>
+<U5CA9> /xa9/xa5 <CJK>
+<U5CAB> /xa9/xa6 <CJK>
+<U5CB1> /xa9/xa7 <CJK>
+<U5CB3> /xa9/xa8 <CJK>
+<U5E18> /xa9/xa9 <CJK>
+<U5E1A> /xa9/xaa <CJK>
+<U5E16> /xa9/xab <CJK>
+<U5E15> /xa9/xac <CJK>
+<U5E1B> /xa9/xad <CJK>
+<U5E11> /xa9/xae <CJK>
+<U5E78> /xa9/xaf <CJK>
+<U5E9A> /xa9/xb0 <CJK>
+<U5E97> /xa9/xb1 <CJK>
+<U5E9C> /xa9/xb2 <CJK>
+<U5E95> /xa9/xb3 <CJK>
+<U5E96> /xa9/xb4 <CJK>
+<U5EF6> /xa9/xb5 <CJK>
+<U5F26> /xa9/xb6 <CJK>
+<U5F27> /xa9/xb7 <CJK>
+<U5F29> /xa9/xb8 <CJK>
+<U5F80> /xa9/xb9 <CJK>
+<U5F81> /xa9/xba <CJK>
+<U5F7F> /xa9/xbb <CJK>
+<U5F7C> /xa9/xbc <CJK>
+<U5FDD> /xa9/xbd <CJK>
+<U5FE0> /xa9/xbe <CJK>
+<U5FFD> /xa9/xbf <CJK>
+<U5FF5> /xa9/xc0 <CJK>
+<U5FFF> /xa9/xc1 <CJK>
+<U600F> /xa9/xc2 <CJK>
+<U6014> /xa9/xc3 <CJK>
+<U602F> /xa9/xc4 <CJK>
+<U6035> /xa9/xc5 <CJK>
+<U6016> /xa9/xc6 <CJK>
+<U602A> /xa9/xc7 <CJK>
+<U6015> /xa9/xc8 <CJK>
+<U6021> /xa9/xc9 <CJK>
+<U6027> /xa9/xca <CJK>
+<U6029> /xa9/xcb <CJK>
+<U602B> /xa9/xcc <CJK>
+<U601B> /xa9/xcd <CJK>
+<U6216> /xa9/xce <CJK>
+<U6215> /xa9/xcf <CJK>
+<U623F> /xa9/xd0 <CJK>
+<U623E> /xa9/xd1 <CJK>
+<U6240> /xa9/xd2 <CJK>
+<U627F> /xa9/xd3 <CJK>
+<U62C9> /xa9/xd4 <CJK>
+<U62CC> /xa9/xd5 <CJK>
+<U62C4> /xa9/xd6 <CJK>
+<U62BF> /xa9/xd7 <CJK>
+<U62C2> /xa9/xd8 <CJK>
+<U62B9> /xa9/xd9 <CJK>
+<U62D2> /xa9/xda <CJK>
+<U62DB> /xa9/xdb <CJK>
+<U62AB> /xa9/xdc <CJK>
+<U62D3> /xa9/xdd <CJK>
+<U62D4> /xa9/xde <CJK>
+<U62CB> /xa9/xdf <CJK>
+<U62C8> /xa9/xe0 <CJK>
+<U62A8> /xa9/xe1 <CJK>
+<U62BD> /xa9/xe2 <CJK>
+<U62BC> /xa9/xe3 <CJK>
+<U62D0> /xa9/xe4 <CJK>
+<U62D9> /xa9/xe5 <CJK>
+<U62C7> /xa9/xe6 <CJK>
+<U62CD> /xa9/xe7 <CJK>
+<U62B5> /xa9/xe8 <CJK>
+<U62DA> /xa9/xe9 <CJK>
+<U62B1> /xa9/xea <CJK>
+<U62D8> /xa9/xeb <CJK>
+<U62D6> /xa9/xec <CJK>
+<U62D7> /xa9/xed <CJK>
+<U62C6> /xa9/xee <CJK>
+<U62AC> /xa9/xef <CJK>
+<U62CE> /xa9/xf0 <CJK>
+<U653E> /xa9/xf1 <CJK>
+<U65A7> /xa9/xf2 <CJK>
+<U65BC> /xa9/xf3 <CJK>
+<U65FA> /xa9/xf4 <CJK>
+<U6614> /xa9/xf5 <CJK>
+<U6613> /xa9/xf6 <CJK>
+<U660C> /xa9/xf7 <CJK>
+<U6606> /xa9/xf8 <CJK>
+<U6602> /xa9/xf9 <CJK>
+<U660E> /xa9/xfa <CJK>
+<U6600> /xa9/xfb <CJK>
+<U660F> /xa9/xfc <CJK>
+<U6615> /xa9/xfd <CJK>
+<U660A> /xa9/xfe <CJK>
+<U6607> /xaa/x40 <CJK>
+<U670D> /xaa/x41 <CJK>
+<U670B> /xaa/x42 <CJK>
+<U676D> /xaa/x43 <CJK>
+<U678B> /xaa/x44 <CJK>
+<U6795> /xaa/x45 <CJK>
+<U6771> /xaa/x46 <CJK>
+<U679C> /xaa/x47 <CJK>
+<U6773> /xaa/x48 <CJK>
+<U6777> /xaa/x49 <CJK>
+<U6787> /xaa/x4a <CJK>
+<U679D> /xaa/x4b <CJK>
+<U6797> /xaa/x4c <CJK>
+<U676F> /xaa/x4d <CJK>
+<U6770> /xaa/x4e <CJK>
+<U677F> /xaa/x4f <CJK>
+<U6789> /xaa/x50 <CJK>
+<U677E> /xaa/x51 <CJK>
+<U6790> /xaa/x52 <CJK>
+<U6775> /xaa/x53 <CJK>
+<U679A> /xaa/x54 <CJK>
+<U6793> /xaa/x55 <CJK>
+<U677C> /xaa/x56 <CJK>
+<U676A> /xaa/x57 <CJK>
+<U6772> /xaa/x58 <CJK>
+<U6B23> /xaa/x59 <CJK>
+<U6B66> /xaa/x5a <CJK>
+<U6B67> /xaa/x5b <CJK>
+<U6B7F> /xaa/x5c <CJK>
+<U6C13> /xaa/x5d <CJK>
+<U6C1B> /xaa/x5e <CJK>
+<U6CE3> /xaa/x5f <CJK>
+<U6CE8> /xaa/x60 <CJK>
+<U6CF3> /xaa/x61 <CJK>
+<U6CB1> /xaa/x62 <CJK>
+<U6CCC> /xaa/x63 <CJK>
+<U6CE5> /xaa/x64 <CJK>
+<U6CB3> /xaa/x65 <CJK>
+<U6CBD> /xaa/x66 <CJK>
+<U6CBE> /xaa/x67 <CJK>
+<U6CBC> /xaa/x68 <CJK>
+<U6CE2> /xaa/x69 <CJK>
+<U6CAB> /xaa/x6a <CJK>
+<U6CD5> /xaa/x6b <CJK>
+<U6CD3> /xaa/x6c <CJK>
+<U6CB8> /xaa/x6d <CJK>
+<U6CC4> /xaa/x6e <CJK>
+<U6CB9> /xaa/x6f <CJK>
+<U6CC1> /xaa/x70 <CJK>
+<U6CAE> /xaa/x71 <CJK>
+<U6CD7> /xaa/x72 <CJK>
+<U6CC5> /xaa/x73 <CJK>
+<U6CF1> /xaa/x74 <CJK>
+<U6CBF> /xaa/x75 <CJK>
+<U6CBB> /xaa/x76 <CJK>
+<U6CE1> /xaa/x77 <CJK>
+<U6CDB> /xaa/x78 <CJK>
+<U6CCA> /xaa/x79 <CJK>
+<U6CAC> /xaa/x7a <CJK>
+<U6CEF> /xaa/x7b <CJK>
+<U6CDC> /xaa/x7c <CJK>
+<U6CD6> /xaa/x7d <CJK>
+<U6CE0> /xaa/x7e <CJK>
+<U7095> /xaa/xa1 <CJK>
+<U708E> /xaa/xa2 <CJK>
+<U7092> /xaa/xa3 <CJK>
+<U708A> /xaa/xa4 <CJK>
+<U7099> /xaa/xa5 <CJK>
+<U722C> /xaa/xa6 <CJK>
+<U722D> /xaa/xa7 <CJK>
+<U7238> /xaa/xa8 <CJK>
+<U7248> /xaa/xa9 <CJK>
+<U7267> /xaa/xaa <CJK>
+<U7269> /xaa/xab <CJK>
+<U72C0> /xaa/xac <CJK>
+<U72CE> /xaa/xad <CJK>
+<U72D9> /xaa/xae <CJK>
+<U72D7> /xaa/xaf <CJK>
+<U72D0> /xaa/xb0 <CJK>
+<U73A9> /xaa/xb1 <CJK>
+<U73A8> /xaa/xb2 <CJK>
+<U739F> /xaa/xb3 <CJK>
+<U73AB> /xaa/xb4 <CJK>
+<U73A5> /xaa/xb5 <CJK>
+<U753D> /xaa/xb6 <CJK>
+<U759D> /xaa/xb7 <CJK>
+<U7599> /xaa/xb8 <CJK>
+<U759A> /xaa/xb9 <CJK>
+<U7684> /xaa/xba <CJK>
+<U76C2> /xaa/xbb <CJK>
+<U76F2> /xaa/xbc <CJK>
+<U76F4> /xaa/xbd <CJK>
+<U77E5> /xaa/xbe <CJK>
+<U77FD> /xaa/xbf <CJK>
+<U793E> /xaa/xc0 <CJK>
+<U7940> /xaa/xc1 <CJK>
+<U7941> /xaa/xc2 <CJK>
+<U79C9> /xaa/xc3 <CJK>
+<U79C8> /xaa/xc4 <CJK>
+<U7A7A> /xaa/xc5 <CJK>
+<U7A79> /xaa/xc6 <CJK>
+<U7AFA> /xaa/xc7 <CJK>
+<U7CFE> /xaa/xc8 <CJK>
+<U7F54> /xaa/xc9 <CJK>
+<U7F8C> /xaa/xca <CJK>
+<U7F8B> /xaa/xcb <CJK>
+<U8005> /xaa/xcc <CJK>
+<U80BA> /xaa/xcd <CJK>
+<U80A5> /xaa/xce <CJK>
+<U80A2> /xaa/xcf <CJK>
+<U80B1> /xaa/xd0 <CJK>
+<U80A1> /xaa/xd1 <CJK>
+<U80AB> /xaa/xd2 <CJK>
+<U80A9> /xaa/xd3 <CJK>
+<U80B4> /xaa/xd4 <CJK>
+<U80AA> /xaa/xd5 <CJK>
+<U80AF> /xaa/xd6 <CJK>
+<U81E5> /xaa/xd7 <CJK>
+<U81FE> /xaa/xd8 <CJK>
+<U820D> /xaa/xd9 <CJK>
+<U82B3> /xaa/xda <CJK>
+<U829D> /xaa/xdb <CJK>
+<U8299> /xaa/xdc <CJK>
+<U82AD> /xaa/xdd <CJK>
+<U82BD> /xaa/xde <CJK>
+<U829F> /xaa/xdf <CJK>
+<U82B9> /xaa/xe0 <CJK>
+<U82B1> /xaa/xe1 <CJK>
+<U82AC> /xaa/xe2 <CJK>
+<U82A5> /xaa/xe3 <CJK>
+<U82AF> /xaa/xe4 <CJK>
+<U82B8> /xaa/xe5 <CJK>
+<U82A3> /xaa/xe6 <CJK>
+<U82B0> /xaa/xe7 <CJK>
+<U82BE> /xaa/xe8 <CJK>
+<U82B7> /xaa/xe9 <CJK>
+<U864E> /xaa/xea <CJK>
+<U8671> /xaa/xeb <CJK>
+<U521D> /xaa/xec <CJK>
+<U8868> /xaa/xed <CJK>
+<U8ECB> /xaa/xee <CJK>
+<U8FCE> /xaa/xef <CJK>
+<U8FD4> /xaa/xf0 <CJK>
+<U8FD1> /xaa/xf1 <CJK>
+<U90B5> /xaa/xf2 <CJK>
+<U90B8> /xaa/xf3 <CJK>
+<U90B1> /xaa/xf4 <CJK>
+<U90B6> /xaa/xf5 <CJK>
+<U91C7> /xaa/xf6 <CJK>
+<U91D1> /xaa/xf7 <CJK>
+<U9577> /xaa/xf8 <CJK>
+<U9580> /xaa/xf9 <CJK>
+<U961C> /xaa/xfa <CJK>
+<U9640> /xaa/xfb <CJK>
+<U963F> /xaa/xfc <CJK>
+<U963B> /xaa/xfd <CJK>
+<U9644> /xaa/xfe <CJK>
+<U9642> /xab/x40 <CJK>
+<U96B9> /xab/x41 <CJK>
+<U96E8> /xab/x42 <CJK>
+<U9752> /xab/x43 <CJK>
+<U975E> /xab/x44 <CJK>
+<U4E9F> /xab/x45 <CJK>
+<U4EAD> /xab/x46 <CJK>
+<U4EAE> /xab/x47 <CJK>
+<U4FE1> /xab/x48 <CJK>
+<U4FB5> /xab/x49 <CJK>
+<U4FAF> /xab/x4a <CJK>
+<U4FBF> /xab/x4b <CJK>
+<U4FE0> /xab/x4c <CJK>
+<U4FD1> /xab/x4d <CJK>
+<U4FCF> /xab/x4e <CJK>
+<U4FDD> /xab/x4f <CJK>
+<U4FC3> /xab/x50 <CJK>
+<U4FB6> /xab/x51 <CJK>
+<U4FD8> /xab/x52 <CJK>
+<U4FDF> /xab/x53 <CJK>
+<U4FCA> /xab/x54 <CJK>
+<U4FD7> /xab/x55 <CJK>
+<U4FAE> /xab/x56 <CJK>
+<U4FD0> /xab/x57 <CJK>
+<U4FC4> /xab/x58 <CJK>
+<U4FC2> /xab/x59 <CJK>
+<U4FDA> /xab/x5a <CJK>
+<U4FCE> /xab/x5b <CJK>
+<U4FDE> /xab/x5c <CJK>
+<U4FB7> /xab/x5d <CJK>
+<U5157> /xab/x5e <CJK>
+<U5192> /xab/x5f <CJK>
+<U5191> /xab/x60 <CJK>
+<U51A0> /xab/x61 <CJK>
+<U524E> /xab/x62 <CJK>
+<U5243> /xab/x63 <CJK>
+<U524A> /xab/x64 <CJK>
+<U524D> /xab/x65 <CJK>
+<U524C> /xab/x66 <CJK>
+<U524B> /xab/x67 <CJK>
+<U5247> /xab/x68 <CJK>
+<U52C7> /xab/x69 <CJK>
+<U52C9> /xab/x6a <CJK>
+<U52C3> /xab/x6b <CJK>
+<U52C1> /xab/x6c <CJK>
+<U530D> /xab/x6d <CJK>
+<U5357> /xab/x6e <CJK>
+<U537B> /xab/x6f <CJK>
+<U539A> /xab/x70 <CJK>
+<U53DB> /xab/x71 <CJK>
+<U54AC> /xab/x72 <CJK>
+<U54C0> /xab/x73 <CJK>
+<U54A8> /xab/x74 <CJK>
+<U54CE> /xab/x75 <CJK>
+<U54C9> /xab/x76 <CJK>
+<U54B8> /xab/x77 <CJK>
+<U54A6> /xab/x78 <CJK>
+<U54B3> /xab/x79 <CJK>
+<U54C7> /xab/x7a <CJK>
+<U54C2> /xab/x7b <CJK>
+<U54BD> /xab/x7c <CJK>
+<U54AA> /xab/x7d <CJK>
+<U54C1> /xab/x7e <CJK>
+<U54C4> /xab/xa1 <CJK>
+<U54C8> /xab/xa2 <CJK>
+<U54AF> /xab/xa3 <CJK>
+<U54AB> /xab/xa4 <CJK>
+<U54B1> /xab/xa5 <CJK>
+<U54BB> /xab/xa6 <CJK>
+<U54A9> /xab/xa7 <CJK>
+<U54A7> /xab/xa8 <CJK>
+<U54BF> /xab/xa9 <CJK>
+<U56FF> /xab/xaa <CJK>
+<U5782> /xab/xab <CJK>
+<U578B> /xab/xac <CJK>
+<U57A0> /xab/xad <CJK>
+<U57A3> /xab/xae <CJK>
+<U57A2> /xab/xaf <CJK>
+<U57CE> /xab/xb0 <CJK>
+<U57AE> /xab/xb1 <CJK>
+<U5793> /xab/xb2 <CJK>
+<U5955> /xab/xb3 <CJK>
+<U5951> /xab/xb4 <CJK>
+<U594F> /xab/xb5 <CJK>
+<U594E> /xab/xb6 <CJK>
+<U5950> /xab/xb7 <CJK>
+<U59DC> /xab/xb8 <CJK>
+<U59D8> /xab/xb9 <CJK>
+<U59FF> /xab/xba <CJK>
+<U59E3> /xab/xbb <CJK>
+<U59E8> /xab/xbc <CJK>
+<U5A03> /xab/xbd <CJK>
+<U59E5> /xab/xbe <CJK>
+<U59EA> /xab/xbf <CJK>
+<U59DA> /xab/xc0 <CJK>
+<U59E6> /xab/xc1 <CJK>
+<U5A01> /xab/xc2 <CJK>
+<U59FB> /xab/xc3 <CJK>
+<U5B69> /xab/xc4 <CJK>
+<U5BA3> /xab/xc5 <CJK>
+<U5BA6> /xab/xc6 <CJK>
+<U5BA4> /xab/xc7 <CJK>
+<U5BA2> /xab/xc8 <CJK>
+<U5BA5> /xab/xc9 <CJK>
+<U5C01> /xab/xca <CJK>
+<U5C4E> /xab/xcb <CJK>
+<U5C4F> /xab/xcc <CJK>
+<U5C4D> /xab/xcd <CJK>
+<U5C4B> /xab/xce <CJK>
+<U5CD9> /xab/xcf <CJK>
+<U5CD2> /xab/xd0 <CJK>
+<U5DF7> /xab/xd1 <CJK>
+<U5E1D> /xab/xd2 <CJK>
+<U5E25> /xab/xd3 <CJK>
+<U5E1F> /xab/xd4 <CJK>
+<U5E7D> /xab/xd5 <CJK>
+<U5EA0> /xab/xd6 <CJK>
+<U5EA6> /xab/xd7 <CJK>
+<U5EFA> /xab/xd8 <CJK>
+<U5F08> /xab/xd9 <CJK>
+<U5F2D> /xab/xda <CJK>
+<U5F65> /xab/xdb <CJK>
+<U5F88> /xab/xdc <CJK>
+<U5F85> /xab/xdd <CJK>
+<U5F8A> /xab/xde <CJK>
+<U5F8B> /xab/xdf <CJK>
+<U5F87> /xab/xe0 <CJK>
+<U5F8C> /xab/xe1 <CJK>
+<U5F89> /xab/xe2 <CJK>
+<U6012> /xab/xe3 <CJK>
+<U601D> /xab/xe4 <CJK>
+<U6020> /xab/xe5 <CJK>
+<U6025> /xab/xe6 <CJK>
+<U600E> /xab/xe7 <CJK>
+<U6028> /xab/xe8 <CJK>
+<U604D> /xab/xe9 <CJK>
+<U6070> /xab/xea <CJK>
+<U6068> /xab/xeb <CJK>
+<U6062> /xab/xec <CJK>
+<U6046> /xab/xed <CJK>
+<U6043> /xab/xee <CJK>
+<U606C> /xab/xef <CJK>
+<U606B> /xab/xf0 <CJK>
+<U606A> /xab/xf1 <CJK>
+<U6064> /xab/xf2 <CJK>
+<U6241> /xab/xf3 <CJK>
+<U62DC> /xab/xf4 <CJK>
+<U6316> /xab/xf5 <CJK>
+<U6309> /xab/xf6 <CJK>
+<U62FC> /xab/xf7 <CJK>
+<U62ED> /xab/xf8 <CJK>
+<U6301> /xab/xf9 <CJK>
+<U62EE> /xab/xfa <CJK>
+<U62FD> /xab/xfb <CJK>
+<U6307> /xab/xfc <CJK>
+<U62F1> /xab/xfd <CJK>
+<U62F7> /xab/xfe <CJK>
+<U62EF> /xac/x40 <CJK>
+<U62EC> /xac/x41 <CJK>
+<U62FE> /xac/x42 <CJK>
+<U62F4> /xac/x43 <CJK>
+<U6311> /xac/x44 <CJK>
+<U6302> /xac/x45 <CJK>
+<U653F> /xac/x46 <CJK>
+<U6545> /xac/x47 <CJK>
+<U65AB> /xac/x48 <CJK>
+<U65BD> /xac/x49 <CJK>
+<U65E2> /xac/x4a <CJK>
+<U6625> /xac/x4b <CJK>
+<U662D> /xac/x4c <CJK>
+<U6620> /xac/x4d <CJK>
+<U6627> /xac/x4e <CJK>
+<U662F> /xac/x4f <CJK>
+<U661F> /xac/x50 <CJK>
+<U6628> /xac/x51 <CJK>
+<U6631> /xac/x52 <CJK>
+<U6624> /xac/x53 <CJK>
+<U66F7> /xac/x54 <CJK>
+<U67FF> /xac/x55 <CJK>
+<U67D3> /xac/x56 <CJK>
+<U67F1> /xac/x57 <CJK>
+<U67D4> /xac/x58 <CJK>
+<U67D0> /xac/x59 <CJK>
+<U67EC> /xac/x5a <CJK>
+<U67B6> /xac/x5b <CJK>
+<U67AF> /xac/x5c <CJK>
+<U67F5> /xac/x5d <CJK>
+<U67E9> /xac/x5e <CJK>
+<U67EF> /xac/x5f <CJK>
+<U67C4> /xac/x60 <CJK>
+<U67D1> /xac/x61 <CJK>
+<U67B4> /xac/x62 <CJK>
+<U67DA> /xac/x63 <CJK>
+<U67E5> /xac/x64 <CJK>
+<U67B8> /xac/x65 <CJK>
+<U67CF> /xac/x66 <CJK>
+<U67DE> /xac/x67 <CJK>
+<U67F3> /xac/x68 <CJK>
+<U67B0> /xac/x69 <CJK>
+<U67D9> /xac/x6a <CJK>
+<U67E2> /xac/x6b <CJK>
+<U67DD> /xac/x6c <CJK>
+<U67D2> /xac/x6d <CJK>
+<U6B6A> /xac/x6e <CJK>
+<U6B83> /xac/x6f <CJK>
+<U6B86> /xac/x70 <CJK>
+<U6BB5> /xac/x71 <CJK>
+<U6BD2> /xac/x72 <CJK>
+<U6BD7> /xac/x73 <CJK>
+<U6C1F> /xac/x74 <CJK>
+<U6CC9> /xac/x75 <CJK>
+<U6D0B> /xac/x76 <CJK>
+<U6D32> /xac/x77 <CJK>
+<U6D2A> /xac/x78 <CJK>
+<U6D41> /xac/x79 <CJK>
+<U6D25> /xac/x7a <CJK>
+<U6D0C> /xac/x7b <CJK>
+<U6D31> /xac/x7c <CJK>
+<U6D1E> /xac/x7d <CJK>
+<U6D17> /xac/x7e <CJK>
+<U6D3B> /xac/xa1 <CJK>
+<U6D3D> /xac/xa2 <CJK>
+<U6D3E> /xac/xa3 <CJK>
+<U6D36> /xac/xa4 <CJK>
+<U6D1B> /xac/xa5 <CJK>
+<U6CF5> /xac/xa6 <CJK>
+<U6D39> /xac/xa7 <CJK>
+<U6D27> /xac/xa8 <CJK>
+<U6D38> /xac/xa9 <CJK>
+<U6D29> /xac/xaa <CJK>
+<U6D2E> /xac/xab <CJK>
+<U6D35> /xac/xac <CJK>
+<U6D0E> /xac/xad <CJK>
+<U6D2B> /xac/xae <CJK>
+<U70AB> /xac/xaf <CJK>
+<U70BA> /xac/xb0 <CJK>
+<U70B3> /xac/xb1 <CJK>
+<U70AC> /xac/xb2 <CJK>
+<U70AF> /xac/xb3 <CJK>
+<U70AD> /xac/xb4 <CJK>
+<U70B8> /xac/xb5 <CJK>
+<U70AE> /xac/xb6 <CJK>
+<U70A4> /xac/xb7 <CJK>
+<U7230> /xac/xb8 <CJK>
+<U7272> /xac/xb9 <CJK>
+<U726F> /xac/xba <CJK>
+<U7274> /xac/xbb <CJK>
+<U72E9> /xac/xbc <CJK>
+<U72E0> /xac/xbd <CJK>
+<U72E1> /xac/xbe <CJK>
+<U73B7> /xac/xbf <CJK>
+<U73CA> /xac/xc0 <CJK>
+<U73BB> /xac/xc1 <CJK>
+<U73B2> /xac/xc2 <CJK>
+<U73CD> /xac/xc3 <CJK>
+<U73C0> /xac/xc4 <CJK>
+<U73B3> /xac/xc5 <CJK>
+<U751A> /xac/xc6 <CJK>
+<U752D> /xac/xc7 <CJK>
+<U754F> /xac/xc8 <CJK>
+<U754C> /xac/xc9 <CJK>
+<U754E> /xac/xca <CJK>
+<U754B> /xac/xcb <CJK>
+<U75AB> /xac/xcc <CJK>
+<U75A4> /xac/xcd <CJK>
+<U75A5> /xac/xce <CJK>
+<U75A2> /xac/xcf <CJK>
+<U75A3> /xac/xd0 <CJK>
+<U7678> /xac/xd1 <CJK>
+<U7686> /xac/xd2 <CJK>
+<U7687> /xac/xd3 <CJK>
+<U7688> /xac/xd4 <CJK>
+<U76C8> /xac/xd5 <CJK>
+<U76C6> /xac/xd6 <CJK>
+<U76C3> /xac/xd7 <CJK>
+<U76C5> /xac/xd8 <CJK>
+<U7701> /xac/xd9 <CJK>
+<U76F9> /xac/xda <CJK>
+<U76F8> /xac/xdb <CJK>
+<U7709> /xac/xdc <CJK>
+<U770B> /xac/xdd <CJK>
+<U76FE> /xac/xde <CJK>
+<U76FC> /xac/xdf <CJK>
+<U7707> /xac/xe0 <CJK>
+<U77DC> /xac/xe1 <CJK>
+<U7802> /xac/xe2 <CJK>
+<U7814> /xac/xe3 <CJK>
+<U780C> /xac/xe4 <CJK>
+<U780D> /xac/xe5 <CJK>
+<U7946> /xac/xe6 <CJK>
+<U7949> /xac/xe7 <CJK>
+<U7948> /xac/xe8 <CJK>
+<U7947> /xac/xe9 <CJK>
+<U79B9> /xac/xea <CJK>
+<U79BA> /xac/xeb <CJK>
+<U79D1> /xac/xec <CJK>
+<U79D2> /xac/xed <CJK>
+<U79CB> /xac/xee <CJK>
+<U7A7F> /xac/xef <CJK>
+<U7A81> /xac/xf0 <CJK>
+<U7AFF> /xac/xf1 <CJK>
+<U7AFD> /xac/xf2 <CJK>
+<U7C7D> /xac/xf3 <CJK>
+<U7D02> /xac/xf4 <CJK>
+<U7D05> /xac/xf5 <CJK>
+<U7D00> /xac/xf6 <CJK>
+<U7D09> /xac/xf7 <CJK>
+<U7D07> /xac/xf8 <CJK>
+<U7D04> /xac/xf9 <CJK>
+<U7D06> /xac/xfa <CJK>
+<U7F38> /xac/xfb <CJK>
+<U7F8E> /xac/xfc <CJK>
+<U7FBF> /xac/xfd <CJK>
+<U8004> /xac/xfe <CJK>
+<U8010> /xad/x40 <CJK>
+<U800D> /xad/x41 <CJK>
+<U8011> /xad/x42 <CJK>
+<U8036> /xad/x43 <CJK>
+<U80D6> /xad/x44 <CJK>
+<U80E5> /xad/x45 <CJK>
+<U80DA> /xad/x46 <CJK>
+<U80C3> /xad/x47 <CJK>
+<U80C4> /xad/x48 <CJK>
+<U80CC> /xad/x49 <CJK>
+<U80E1> /xad/x4a <CJK>
+<U80DB> /xad/x4b <CJK>
+<U80CE> /xad/x4c <CJK>
+<U80DE> /xad/x4d <CJK>
+<U80E4> /xad/x4e <CJK>
+<U80DD> /xad/x4f <CJK>
+<U81F4> /xad/x50 <CJK>
+<U8222> /xad/x51 <CJK>
+<U82E7> /xad/x52 <CJK>
+<U8303> /xad/x53 <CJK>
+<U8305> /xad/x54 <CJK>
+<U82E3> /xad/x55 <CJK>
+<U82DB> /xad/x56 <CJK>
+<U82E6> /xad/x57 <CJK>
+<U8304> /xad/x58 <CJK>
+<U82E5> /xad/x59 <CJK>
+<U8302> /xad/x5a <CJK>
+<U8309> /xad/x5b <CJK>
+<U82D2> /xad/x5c <CJK>
+<U82D7> /xad/x5d <CJK>
+<U82F1> /xad/x5e <CJK>
+<U8301> /xad/x5f <CJK>
+<U82DC> /xad/x60 <CJK>
+<U82D4> /xad/x61 <CJK>
+<U82D1> /xad/x62 <CJK>
+<U82DE> /xad/x63 <CJK>
+<U82D3> /xad/x64 <CJK>
+<U82DF> /xad/x65 <CJK>
+<U82EF> /xad/x66 <CJK>
+<U8306> /xad/x67 <CJK>
+<U8650> /xad/x68 <CJK>
+<U8679> /xad/x69 <CJK>
+<U867B> /xad/x6a <CJK>
+<U867A> /xad/x6b <CJK>
+<U884D> /xad/x6c <CJK>
+<U886B> /xad/x6d <CJK>
+<U8981> /xad/x6e <CJK>
+<U89D4> /xad/x6f <CJK>
+<U8A08> /xad/x70 <CJK>
+<U8A02> /xad/x71 <CJK>
+<U8A03> /xad/x72 <CJK>
+<U8C9E> /xad/x73 <CJK>
+<U8CA0> /xad/x74 <CJK>
+<U8D74> /xad/x75 <CJK>
+<U8D73> /xad/x76 <CJK>
+<U8DB4> /xad/x77 <CJK>
+<U8ECD> /xad/x78 <CJK>
+<U8ECC> /xad/x79 <CJK>
+<U8FF0> /xad/x7a <CJK>
+<U8FE6> /xad/x7b <CJK>
+<U8FE2> /xad/x7c <CJK>
+<U8FEA> /xad/x7d <CJK>
+<U8FE5> /xad/x7e <CJK>
+<U8FED> /xad/xa1 <CJK>
+<U8FEB> /xad/xa2 <CJK>
+<U8FE4> /xad/xa3 <CJK>
+<U8FE8> /xad/xa4 <CJK>
+<U90CA> /xad/xa5 <CJK>
+<U90CE> /xad/xa6 <CJK>
+<U90C1> /xad/xa7 <CJK>
+<U90C3> /xad/xa8 <CJK>
+<U914B> /xad/xa9 <CJK>
+<U914A> /xad/xaa <CJK>
+<U91CD> /xad/xab <CJK>
+<U9582> /xad/xac <CJK>
+<U9650> /xad/xad <CJK>
+<U964B> /xad/xae <CJK>
+<U964C> /xad/xaf <CJK>
+<U964D> /xad/xb0 <CJK>
+<U9762> /xad/xb1 <CJK>
+<U9769> /xad/xb2 <CJK>
+<U97CB> /xad/xb3 <CJK>
+<U97ED> /xad/xb4 <CJK>
+<U97F3> /xad/xb5 <CJK>
+<U9801> /xad/xb6 <CJK>
+<U98A8> /xad/xb7 <CJK>
+<U98DB> /xad/xb8 <CJK>
+<U98DF> /xad/xb9 <CJK>
+<U9996> /xad/xba <CJK>
+<U9999> /xad/xbb <CJK>
+<U4E58> /xad/xbc <CJK>
+<U4EB3> /xad/xbd <CJK>
+<U500C> /xad/xbe <CJK>
+<U500D> /xad/xbf <CJK>
+<U5023> /xad/xc0 <CJK>
+<U4FEF> /xad/xc1 <CJK>
+<U5026> /xad/xc2 <CJK>
+<U5025> /xad/xc3 <CJK>
+<U4FF8> /xad/xc4 <CJK>
+<U5029> /xad/xc5 <CJK>
+<U5016> /xad/xc6 <CJK>
+<U5006> /xad/xc7 <CJK>
+<U503C> /xad/xc8 <CJK>
+<U501F> /xad/xc9 <CJK>
+<U501A> /xad/xca <CJK>
+<U5012> /xad/xcb <CJK>
+<U5011> /xad/xcc <CJK>
+<U4FFA> /xad/xcd <CJK>
+<U5000> /xad/xce <CJK>
+<U5014> /xad/xcf <CJK>
+<U5028> /xad/xd0 <CJK>
+<U4FF1> /xad/xd1 <CJK>
+<U5021> /xad/xd2 <CJK>
+<U500B> /xad/xd3 <CJK>
+<U5019> /xad/xd4 <CJK>
+<U5018> /xad/xd5 <CJK>
+<U4FF3> /xad/xd6 <CJK>
+<U4FEE> /xad/xd7 <CJK>
+<U502D> /xad/xd8 <CJK>
+<U502A> /xad/xd9 <CJK>
+<U4FFE> /xad/xda <CJK>
+<U502B> /xad/xdb <CJK>
+<U5009> /xad/xdc <CJK>
+<U517C> /xad/xdd <CJK>
+<U51A4> /xad/xde <CJK>
+<U51A5> /xad/xdf <CJK>
+<U51A2> /xad/xe0 <CJK>
+<U51CD> /xad/xe1 <CJK>
+<U51CC> /xad/xe2 <CJK>
+<U51C6> /xad/xe3 <CJK>
+<U51CB> /xad/xe4 <CJK>
+<U5256> /xad/xe5 <CJK>
+<U525C> /xad/xe6 <CJK>
+<U5254> /xad/xe7 <CJK>
+<U525B> /xad/xe8 <CJK>
+<U525D> /xad/xe9 <CJK>
+<U532A> /xad/xea <CJK>
+<U537F> /xad/xeb <CJK>
+<U539F> /xad/xec <CJK>
+<U539D> /xad/xed <CJK>
+<U53DF> /xad/xee <CJK>
+<U54E8> /xad/xef <CJK>
+<U5510> /xad/xf0 <CJK>
+<U5501> /xad/xf1 <CJK>
+<U5537> /xad/xf2 <CJK>
+<U54FC> /xad/xf3 <CJK>
+<U54E5> /xad/xf4 <CJK>
+<U54F2> /xad/xf5 <CJK>
+<U5506> /xad/xf6 <CJK>
+<U54FA> /xad/xf7 <CJK>
+<U5514> /xad/xf8 <CJK>
+<U54E9> /xad/xf9 <CJK>
+<U54ED> /xad/xfa <CJK>
+<U54E1> /xad/xfb <CJK>
+<U5509> /xad/xfc <CJK>
+<U54EE> /xad/xfd <CJK>
+<U54EA> /xad/xfe <CJK>
+<U54E6> /xae/x40 <CJK>
+<U5527> /xae/x41 <CJK>
+<U5507> /xae/x42 <CJK>
+<U54FD> /xae/x43 <CJK>
+<U550F> /xae/x44 <CJK>
+<U5703> /xae/x45 <CJK>
+<U5704> /xae/x46 <CJK>
+<U57C2> /xae/x47 <CJK>
+<U57D4> /xae/x48 <CJK>
+<U57CB> /xae/x49 <CJK>
+<U57C3> /xae/x4a <CJK>
+<U5809> /xae/x4b <CJK>
+<U590F> /xae/x4c <CJK>
+<U5957> /xae/x4d <CJK>
+<U5958> /xae/x4e <CJK>
+<U595A> /xae/x4f <CJK>
+<U5A11> /xae/x50 <CJK>
+<U5A18> /xae/x51 <CJK>
+<U5A1C> /xae/x52 <CJK>
+<U5A1F> /xae/x53 <CJK>
+<U5A1B> /xae/x54 <CJK>
+<U5A13> /xae/x55 <CJK>
+<U59EC> /xae/x56 <CJK>
+<U5A20> /xae/x57 <CJK>
+<U5A23> /xae/x58 <CJK>
+<U5A29> /xae/x59 <CJK>
+<U5A25> /xae/x5a <CJK>
+<U5A0C> /xae/x5b <CJK>
+<U5A09> /xae/x5c <CJK>
+<U5B6B> /xae/x5d <CJK>
+<U5C58> /xae/x5e <CJK>
+<U5BB0> /xae/x5f <CJK>
+<U5BB3> /xae/x60 <CJK>
+<U5BB6> /xae/x61 <CJK>
+<U5BB4> /xae/x62 <CJK>
+<U5BAE> /xae/x63 <CJK>
+<U5BB5> /xae/x64 <CJK>
+<U5BB9> /xae/x65 <CJK>
+<U5BB8> /xae/x66 <CJK>
+<U5C04> /xae/x67 <CJK>
+<U5C51> /xae/x68 <CJK>
+<U5C55> /xae/x69 <CJK>
+<U5C50> /xae/x6a <CJK>
+<U5CED> /xae/x6b <CJK>
+<U5CFD> /xae/x6c <CJK>
+<U5CFB> /xae/x6d <CJK>
+<U5CEA> /xae/x6e <CJK>
+<U5CE8> /xae/x6f <CJK>
+<U5CF0> /xae/x70 <CJK>
+<U5CF6> /xae/x71 <CJK>
+<U5D01> /xae/x72 <CJK>
+<U5CF4> /xae/x73 <CJK>
+<U5DEE> /xae/x74 <CJK>
+<U5E2D> /xae/x75 <CJK>
+<U5E2B> /xae/x76 <CJK>
+<U5EAB> /xae/x77 <CJK>
+<U5EAD> /xae/x78 <CJK>
+<U5EA7> /xae/x79 <CJK>
+<U5F31> /xae/x7a <CJK>
+<U5F92> /xae/x7b <CJK>
+<U5F91> /xae/x7c <CJK>
+<U5F90> /xae/x7d <CJK>
+<U6059> /xae/x7e <CJK>
+<U6063> /xae/xa1 <CJK>
+<U6065> /xae/xa2 <CJK>
+<U6050> /xae/xa3 <CJK>
+<U6055> /xae/xa4 <CJK>
+<U606D> /xae/xa5 <CJK>
+<U6069> /xae/xa6 <CJK>
+<U606F> /xae/xa7 <CJK>
+<U6084> /xae/xa8 <CJK>
+<U609F> /xae/xa9 <CJK>
+<U609A> /xae/xaa <CJK>
+<U608D> /xae/xab <CJK>
+<U6094> /xae/xac <CJK>
+<U608C> /xae/xad <CJK>
+<U6085> /xae/xae <CJK>
+<U6096> /xae/xaf <CJK>
+<U6247> /xae/xb0 <CJK>
+<U62F3> /xae/xb1 <CJK>
+<U6308> /xae/xb2 <CJK>
+<U62FF> /xae/xb3 <CJK>
+<U634E> /xae/xb4 <CJK>
+<U633E> /xae/xb5 <CJK>
+<U632F> /xae/xb6 <CJK>
+<U6355> /xae/xb7 <CJK>
+<U6342> /xae/xb8 <CJK>
+<U6346> /xae/xb9 <CJK>
+<U634F> /xae/xba <CJK>
+<U6349> /xae/xbb <CJK>
+<U633A> /xae/xbc <CJK>
+<U6350> /xae/xbd <CJK>
+<U633D> /xae/xbe <CJK>
+<U632A> /xae/xbf <CJK>
+<U632B> /xae/xc0 <CJK>
+<U6328> /xae/xc1 <CJK>
+<U634D> /xae/xc2 <CJK>
+<U634C> /xae/xc3 <CJK>
+<U6548> /xae/xc4 <CJK>
+<U6549> /xae/xc5 <CJK>
+<U6599> /xae/xc6 <CJK>
+<U65C1> /xae/xc7 <CJK>
+<U65C5> /xae/xc8 <CJK>
+<U6642> /xae/xc9 <CJK>
+<U6649> /xae/xca <CJK>
+<U664F> /xae/xcb <CJK>
+<U6643> /xae/xcc <CJK>
+<U6652> /xae/xcd <CJK>
+<U664C> /xae/xce <CJK>
+<U6645> /xae/xcf <CJK>
+<U6641> /xae/xd0 <CJK>
+<U66F8> /xae/xd1 <CJK>
+<U6714> /xae/xd2 <CJK>
+<U6715> /xae/xd3 <CJK>
+<U6717> /xae/xd4 <CJK>
+<U6821> /xae/xd5 <CJK>
+<U6838> /xae/xd6 <CJK>
+<U6848> /xae/xd7 <CJK>
+<U6846> /xae/xd8 <CJK>
+<U6853> /xae/xd9 <CJK>
+<U6839> /xae/xda <CJK>
+<U6842> /xae/xdb <CJK>
+<U6854> /xae/xdc <CJK>
+<U6829> /xae/xdd <CJK>
+<U68B3> /xae/xde <CJK>
+<U6817> /xae/xdf <CJK>
+<U684C> /xae/xe0 <CJK>
+<U6851> /xae/xe1 <CJK>
+<U683D> /xae/xe2 <CJK>
+<U67F4> /xae/xe3 <CJK>
+<U6850> /xae/xe4 <CJK>
+<U6840> /xae/xe5 <CJK>
+<U683C> /xae/xe6 <CJK>
+<U6843> /xae/xe7 <CJK>
+<U682A> /xae/xe8 <CJK>
+<U6845> /xae/xe9 <CJK>
+<U6813> /xae/xea <CJK>
+<U6818> /xae/xeb <CJK>
+<U6841> /xae/xec <CJK>
+<U6B8A> /xae/xed <CJK>
+<U6B89> /xae/xee <CJK>
+<U6BB7> /xae/xef <CJK>
+<U6C23> /xae/xf0 <CJK>
+<U6C27> /xae/xf1 <CJK>
+<U6C28> /xae/xf2 <CJK>
+<U6C26> /xae/xf3 <CJK>
+<U6C24> /xae/xf4 <CJK>
+<U6CF0> /xae/xf5 <CJK>
+<U6D6A> /xae/xf6 <CJK>
+<U6D95> /xae/xf7 <CJK>
+<U6D88> /xae/xf8 <CJK>
+<U6D87> /xae/xf9 <CJK>
+<U6D66> /xae/xfa <CJK>
+<U6D78> /xae/xfb <CJK>
+<U6D77> /xae/xfc <CJK>
+<U6D59> /xae/xfd <CJK>
+<U6D93> /xae/xfe <CJK>
+<U6D6C> /xaf/x40 <CJK>
+<U6D89> /xaf/x41 <CJK>
+<U6D6E> /xaf/x42 <CJK>
+<U6D5A> /xaf/x43 <CJK>
+<U6D74> /xaf/x44 <CJK>
+<U6D69> /xaf/x45 <CJK>
+<U6D8C> /xaf/x46 <CJK>
+<U6D8A> /xaf/x47 <CJK>
+<U6D79> /xaf/x48 <CJK>
+<U6D85> /xaf/x49 <CJK>
+<U6D65> /xaf/x4a <CJK>
+<U6D94> /xaf/x4b <CJK>
+<U70CA> /xaf/x4c <CJK>
+<U70D8> /xaf/x4d <CJK>
+<U70E4> /xaf/x4e <CJK>
+<U70D9> /xaf/x4f <CJK>
+<U70C8> /xaf/x50 <CJK>
+<U70CF> /xaf/x51 <CJK>
+<U7239> /xaf/x52 <CJK>
+<U7279> /xaf/x53 <CJK>
+<U72FC> /xaf/x54 <CJK>
+<U72F9> /xaf/x55 <CJK>
+<U72FD> /xaf/x56 <CJK>
+<U72F8> /xaf/x57 <CJK>
+<U72F7> /xaf/x58 <CJK>
+<U7386> /xaf/x59 <CJK>
+<U73ED> /xaf/x5a <CJK>
+<U7409> /xaf/x5b <CJK>
+<U73EE> /xaf/x5c <CJK>
+<U73E0> /xaf/x5d <CJK>
+<U73EA> /xaf/x5e <CJK>
+<U73DE> /xaf/x5f <CJK>
+<U7554> /xaf/x60 <CJK>
+<U755D> /xaf/x61 <CJK>
+<U755C> /xaf/x62 <CJK>
+<U755A> /xaf/x63 <CJK>
+<U7559> /xaf/x64 <CJK>
+<U75BE> /xaf/x65 <CJK>
+<U75C5> /xaf/x66 <CJK>
+<U75C7> /xaf/x67 <CJK>
+<U75B2> /xaf/x68 <CJK>
+<U75B3> /xaf/x69 <CJK>
+<U75BD> /xaf/x6a <CJK>
+<U75BC> /xaf/x6b <CJK>
+<U75B9> /xaf/x6c <CJK>
+<U75C2> /xaf/x6d <CJK>
+<U75B8> /xaf/x6e <CJK>
+<U768B> /xaf/x6f <CJK>
+<U76B0> /xaf/x70 <CJK>
+<U76CA> /xaf/x71 <CJK>
+<U76CD> /xaf/x72 <CJK>
+<U76CE> /xaf/x73 <CJK>
+<U7729> /xaf/x74 <CJK>
+<U771F> /xaf/x75 <CJK>
+<U7720> /xaf/x76 <CJK>
+<U7728> /xaf/x77 <CJK>
+<U77E9> /xaf/x78 <CJK>
+<U7830> /xaf/x79 <CJK>
+<U7827> /xaf/x7a <CJK>
+<U7838> /xaf/x7b <CJK>
+<U781D> /xaf/x7c <CJK>
+<U7834> /xaf/x7d <CJK>
+<U7837> /xaf/x7e <CJK>
+<U7825> /xaf/xa1 <CJK>
+<U782D> /xaf/xa2 <CJK>
+<U7820> /xaf/xa3 <CJK>
+<U781F> /xaf/xa4 <CJK>
+<U7832> /xaf/xa5 <CJK>
+<U7955> /xaf/xa6 <CJK>
+<U7950> /xaf/xa7 <CJK>
+<U7960> /xaf/xa8 <CJK>
+<U795F> /xaf/xa9 <CJK>
+<U7956> /xaf/xaa <CJK>
+<U795E> /xaf/xab <CJK>
+<U795D> /xaf/xac <CJK>
+<U7957> /xaf/xad <CJK>
+<U795A> /xaf/xae <CJK>
+<U79E4> /xaf/xaf <CJK>
+<U79E3> /xaf/xb0 <CJK>
+<U79E7> /xaf/xb1 <CJK>
+<U79DF> /xaf/xb2 <CJK>
+<U79E6> /xaf/xb3 <CJK>
+<U79E9> /xaf/xb4 <CJK>
+<U79D8> /xaf/xb5 <CJK>
+<U7A84> /xaf/xb6 <CJK>
+<U7A88> /xaf/xb7 <CJK>
+<U7AD9> /xaf/xb8 <CJK>
+<U7B06> /xaf/xb9 <CJK>
+<U7B11> /xaf/xba <CJK>
+<U7C89> /xaf/xbb <CJK>
+<U7D21> /xaf/xbc <CJK>
+<U7D17> /xaf/xbd <CJK>
+<U7D0B> /xaf/xbe <CJK>
+<U7D0A> /xaf/xbf <CJK>
+<U7D20> /xaf/xc0 <CJK>
+<U7D22> /xaf/xc1 <CJK>
+<U7D14> /xaf/xc2 <CJK>
+<U7D10> /xaf/xc3 <CJK>
+<U7D15> /xaf/xc4 <CJK>
+<U7D1A> /xaf/xc5 <CJK>
+<U7D1C> /xaf/xc6 <CJK>
+<U7D0D> /xaf/xc7 <CJK>
+<U7D19> /xaf/xc8 <CJK>
+<U7D1B> /xaf/xc9 <CJK>
+<U7F3A> /xaf/xca <CJK>
+<U7F5F> /xaf/xcb <CJK>
+<U7F94> /xaf/xcc <CJK>
+<U7FC5> /xaf/xcd <CJK>
+<U7FC1> /xaf/xce <CJK>
+<U8006> /xaf/xcf <CJK>
+<U8018> /xaf/xd0 <CJK>
+<U8015> /xaf/xd1 <CJK>
+<U8019> /xaf/xd2 <CJK>
+<U8017> /xaf/xd3 <CJK>
+<U803D> /xaf/xd4 <CJK>
+<U803F> /xaf/xd5 <CJK>
+<U80F1> /xaf/xd6 <CJK>
+<U8102> /xaf/xd7 <CJK>
+<U80F0> /xaf/xd8 <CJK>
+<U8105> /xaf/xd9 <CJK>
+<U80ED> /xaf/xda <CJK>
+<U80F4> /xaf/xdb <CJK>
+<U8106> /xaf/xdc <CJK>
+<U80F8> /xaf/xdd <CJK>
+<U80F3> /xaf/xde <CJK>
+<U8108> /xaf/xdf <CJK>
+<U80FD> /xaf/xe0 <CJK>
+<U810A> /xaf/xe1 <CJK>
+<U80FC> /xaf/xe2 <CJK>
+<U80EF> /xaf/xe3 <CJK>
+<U81ED> /xaf/xe4 <CJK>
+<U81EC> /xaf/xe5 <CJK>
+<U8200> /xaf/xe6 <CJK>
+<U8210> /xaf/xe7 <CJK>
+<U822A> /xaf/xe8 <CJK>
+<U822B> /xaf/xe9 <CJK>
+<U8228> /xaf/xea <CJK>
+<U822C> /xaf/xeb <CJK>
+<U82BB> /xaf/xec <CJK>
+<U832B> /xaf/xed <CJK>
+<U8352> /xaf/xee <CJK>
+<U8354> /xaf/xef <CJK>
+<U834A> /xaf/xf0 <CJK>
+<U8338> /xaf/xf1 <CJK>
+<U8350> /xaf/xf2 <CJK>
+<U8349> /xaf/xf3 <CJK>
+<U8335> /xaf/xf4 <CJK>
+<U8334> /xaf/xf5 <CJK>
+<U834F> /xaf/xf6 <CJK>
+<U8332> /xaf/xf7 <CJK>
+<U8339> /xaf/xf8 <CJK>
+<U8336> /xaf/xf9 <CJK>
+<U8317> /xaf/xfa <CJK>
+<U8340> /xaf/xfb <CJK>
+<U8331> /xaf/xfc <CJK>
+<U8328> /xaf/xfd <CJK>
+<U8343> /xaf/xfe <CJK>
+<U8654> /xb0/x40 <CJK>
+<U868A> /xb0/x41 <CJK>
+<U86AA> /xb0/x42 <CJK>
+<U8693> /xb0/x43 <CJK>
+<U86A4> /xb0/x44 <CJK>
+<U86A9> /xb0/x45 <CJK>
+<U868C> /xb0/x46 <CJK>
+<U86A3> /xb0/x47 <CJK>
+<U869C> /xb0/x48 <CJK>
+<U8870> /xb0/x49 <CJK>
+<U8877> /xb0/x4a <CJK>
+<U8881> /xb0/x4b <CJK>
+<U8882> /xb0/x4c <CJK>
+<U887D> /xb0/x4d <CJK>
+<U8879> /xb0/x4e <CJK>
+<U8A18> /xb0/x4f <CJK>
+<U8A10> /xb0/x50 <CJK>
+<U8A0E> /xb0/x51 <CJK>
+<U8A0C> /xb0/x52 <CJK>
+<U8A15> /xb0/x53 <CJK>
+<U8A0A> /xb0/x54 <CJK>
+<U8A17> /xb0/x55 <CJK>
+<U8A13> /xb0/x56 <CJK>
+<U8A16> /xb0/x57 <CJK>
+<U8A0F> /xb0/x58 <CJK>
+<U8A11> /xb0/x59 <CJK>
+<U8C48> /xb0/x5a <CJK>
+<U8C7A> /xb0/x5b <CJK>
+<U8C79> /xb0/x5c <CJK>
+<U8CA1> /xb0/x5d <CJK>
+<U8CA2> /xb0/x5e <CJK>
+<U8D77> /xb0/x5f <CJK>
+<U8EAC> /xb0/x60 <CJK>
+<U8ED2> /xb0/x61 <CJK>
+<U8ED4> /xb0/x62 <CJK>
+<U8ECF> /xb0/x63 <CJK>
+<U8FB1> /xb0/x64 <CJK>
+<U9001> /xb0/x65 <CJK>
+<U9006> /xb0/x66 <CJK>
+<U8FF7> /xb0/x67 <CJK>
+<U9000> /xb0/x68 <CJK>
+<U8FFA> /xb0/x69 <CJK>
+<U8FF4> /xb0/x6a <CJK>
+<U9003> /xb0/x6b <CJK>
+<U8FFD> /xb0/x6c <CJK>
+<U9005> /xb0/x6d <CJK>
+<U8FF8> /xb0/x6e <CJK>
+<U9095> /xb0/x6f <CJK>
+<U90E1> /xb0/x70 <CJK>
+<U90DD> /xb0/x71 <CJK>
+<U90E2> /xb0/x72 <CJK>
+<U9152> /xb0/x73 <CJK>
+<U914D> /xb0/x74 <CJK>
+<U914C> /xb0/x75 <CJK>
+<U91D8> /xb0/x76 <CJK>
+<U91DD> /xb0/x77 <CJK>
+<U91D7> /xb0/x78 <CJK>
+<U91DC> /xb0/x79 <CJK>
+<U91D9> /xb0/x7a <CJK>
+<U9583> /xb0/x7b <CJK>
+<U9662> /xb0/x7c <CJK>
+<U9663> /xb0/x7d <CJK>
+<U9661> /xb0/x7e <CJK>
+<U965B> /xb0/xa1 <CJK>
+<U965D> /xb0/xa2 <CJK>
+<U9664> /xb0/xa3 <CJK>
+<U9658> /xb0/xa4 <CJK>
+<U965E> /xb0/xa5 <CJK>
+<U96BB> /xb0/xa6 <CJK>
+<U98E2> /xb0/xa7 <CJK>
+<U99AC> /xb0/xa8 <CJK>
+<U9AA8> /xb0/xa9 <CJK>
+<U9AD8> /xb0/xaa <CJK>
+<U9B25> /xb0/xab <CJK>
+<U9B32> /xb0/xac <CJK>
+<U9B3C> /xb0/xad <CJK>
+<U4E7E> /xb0/xae <CJK>
+<U507A> /xb0/xaf <CJK>
+<U507D> /xb0/xb0 <CJK>
+<U505C> /xb0/xb1 <CJK>
+<U5047> /xb0/xb2 <CJK>
+<U5043> /xb0/xb3 <CJK>
+<U504C> /xb0/xb4 <CJK>
+<U505A> /xb0/xb5 <CJK>
+<U5049> /xb0/xb6 <CJK>
+<U5065> /xb0/xb7 <CJK>
+<U5076> /xb0/xb8 <CJK>
+<U504E> /xb0/xb9 <CJK>
+<U5055> /xb0/xba <CJK>
+<U5075> /xb0/xbb <CJK>
+<U5074> /xb0/xbc <CJK>
+<U5077> /xb0/xbd <CJK>
+<U504F> /xb0/xbe <CJK>
+<U500F> /xb0/xbf <CJK>
+<U506F> /xb0/xc0 <CJK>
+<U506D> /xb0/xc1 <CJK>
+<U515C> /xb0/xc2 <CJK>
+<U5195> /xb0/xc3 <CJK>
+<U51F0> /xb0/xc4 <CJK>
+<U526A> /xb0/xc5 <CJK>
+<U526F> /xb0/xc6 <CJK>
+<U52D2> /xb0/xc7 <CJK>
+<U52D9> /xb0/xc8 <CJK>
+<U52D8> /xb0/xc9 <CJK>
+<U52D5> /xb0/xca <CJK>
+<U5310> /xb0/xcb <CJK>
+<U530F> /xb0/xcc <CJK>
+<U5319> /xb0/xcd <CJK>
+<U533F> /xb0/xce <CJK>
+<U5340> /xb0/xcf <CJK>
+<U533E> /xb0/xd0 <CJK>
+<U53C3> /xb0/xd1 <CJK>
+<U66FC> /xb0/xd2 <CJK>
+<U5546> /xb0/xd3 <CJK>
+<U556A> /xb0/xd4 <CJK>
+<U5566> /xb0/xd5 <CJK>
+<U5544> /xb0/xd6 <CJK>
+<U555E> /xb0/xd7 <CJK>
+<U5561> /xb0/xd8 <CJK>
+<U5543> /xb0/xd9 <CJK>
+<U554A> /xb0/xda <CJK>
+<U5531> /xb0/xdb <CJK>
+<U5556> /xb0/xdc <CJK>
+<U554F> /xb0/xdd <CJK>
+<U5555> /xb0/xde <CJK>
+<U552F> /xb0/xdf <CJK>
+<U5564> /xb0/xe0 <CJK>
+<U5538> /xb0/xe1 <CJK>
+<U552E> /xb0/xe2 <CJK>
+<U555C> /xb0/xe3 <CJK>
+<U552C> /xb0/xe4 <CJK>
+<U5563> /xb0/xe5 <CJK>
+<U5533> /xb0/xe6 <CJK>
+<U5541> /xb0/xe7 <CJK>
+<U5557> /xb0/xe8 <CJK>
+<U5708> /xb0/xe9 <CJK>
+<U570B> /xb0/xea <CJK>
+<U5709> /xb0/xeb <CJK>
+<U57DF> /xb0/xec <CJK>
+<U5805> /xb0/xed <CJK>
+<U580A> /xb0/xee <CJK>
+<U5806> /xb0/xef <CJK>
+<U57E0> /xb0/xf0 <CJK>
+<U57E4> /xb0/xf1 <CJK>
+<U57FA> /xb0/xf2 <CJK>
+<U5802> /xb0/xf3 <CJK>
+<U5835> /xb0/xf4 <CJK>
+<U57F7> /xb0/xf5 <CJK>
+<U57F9> /xb0/xf6 <CJK>
+<U5920> /xb0/xf7 <CJK>
+<U5962> /xb0/xf8 <CJK>
+<U5A36> /xb0/xf9 <CJK>
+<U5A41> /xb0/xfa <CJK>
+<U5A49> /xb0/xfb <CJK>
+<U5A66> /xb0/xfc <CJK>
+<U5A6A> /xb0/xfd <CJK>
+<U5A40> /xb0/xfe <CJK>
+<U5A3C> /xb1/x40 <CJK>
+<U5A62> /xb1/x41 <CJK>
+<U5A5A> /xb1/x42 <CJK>
+<U5A46> /xb1/x43 <CJK>
+<U5A4A> /xb1/x44 <CJK>
+<U5B70> /xb1/x45 <CJK>
+<U5BC7> /xb1/x46 <CJK>
+<U5BC5> /xb1/x47 <CJK>
+<U5BC4> /xb1/x48 <CJK>
+<U5BC2> /xb1/x49 <CJK>
+<U5BBF> /xb1/x4a <CJK>
+<U5BC6> /xb1/x4b <CJK>
+<U5C09> /xb1/x4c <CJK>
+<U5C08> /xb1/x4d <CJK>
+<U5C07> /xb1/x4e <CJK>
+<U5C60> /xb1/x4f <CJK>
+<U5C5C> /xb1/x50 <CJK>
+<U5C5D> /xb1/x51 <CJK>
+<U5D07> /xb1/x52 <CJK>
+<U5D06> /xb1/x53 <CJK>
+<U5D0E> /xb1/x54 <CJK>
+<U5D1B> /xb1/x55 <CJK>
+<U5D16> /xb1/x56 <CJK>
+<U5D22> /xb1/x57 <CJK>
+<U5D11> /xb1/x58 <CJK>
+<U5D29> /xb1/x59 <CJK>
+<U5D14> /xb1/x5a <CJK>
+<U5D19> /xb1/x5b <CJK>
+<U5D24> /xb1/x5c <CJK>
+<U5D27> /xb1/x5d <CJK>
+<U5D17> /xb1/x5e <CJK>
+<U5DE2> /xb1/x5f <CJK>
+<U5E38> /xb1/x60 <CJK>
+<U5E36> /xb1/x61 <CJK>
+<U5E33> /xb1/x62 <CJK>
+<U5E37> /xb1/x63 <CJK>
+<U5EB7> /xb1/x64 <CJK>
+<U5EB8> /xb1/x65 <CJK>
+<U5EB6> /xb1/x66 <CJK>
+<U5EB5> /xb1/x67 <CJK>
+<U5EBE> /xb1/x68 <CJK>
+<U5F35> /xb1/x69 <CJK>
+<U5F37> /xb1/x6a <CJK>
+<U5F57> /xb1/x6b <CJK>
+<U5F6C> /xb1/x6c <CJK>
+<U5F69> /xb1/x6d <CJK>
+<U5F6B> /xb1/x6e <CJK>
+<U5F97> /xb1/x6f <CJK>
+<U5F99> /xb1/x70 <CJK>
+<U5F9E> /xb1/x71 <CJK>
+<U5F98> /xb1/x72 <CJK>
+<U5FA1> /xb1/x73 <CJK>
+<U5FA0> /xb1/x74 <CJK>
+<U5F9C> /xb1/x75 <CJK>
+<U607F> /xb1/x76 <CJK>
+<U60A3> /xb1/x77 <CJK>
+<U6089> /xb1/x78 <CJK>
+<U60A0> /xb1/x79 <CJK>
+<U60A8> /xb1/x7a <CJK>
+<U60CB> /xb1/x7b <CJK>
+<U60B4> /xb1/x7c <CJK>
+<U60E6> /xb1/x7d <CJK>
+<U60BD> /xb1/x7e <CJK>
+<U60C5> /xb1/xa1 <CJK>
+<U60BB> /xb1/xa2 <CJK>
+<U60B5> /xb1/xa3 <CJK>
+<U60DC> /xb1/xa4 <CJK>
+<U60BC> /xb1/xa5 <CJK>
+<U60D8> /xb1/xa6 <CJK>
+<U60D5> /xb1/xa7 <CJK>
+<U60C6> /xb1/xa8 <CJK>
+<U60DF> /xb1/xa9 <CJK>
+<U60B8> /xb1/xaa <CJK>
+<U60DA> /xb1/xab <CJK>
+<U60C7> /xb1/xac <CJK>
+<U621A> /xb1/xad <CJK>
+<U621B> /xb1/xae <CJK>
+<U6248> /xb1/xaf <CJK>
+<U63A0> /xb1/xb0 <CJK>
+<U63A7> /xb1/xb1 <CJK>
+<U6372> /xb1/xb2 <CJK>
+<U6396> /xb1/xb3 <CJK>
+<U63A2> /xb1/xb4 <CJK>
+<U63A5> /xb1/xb5 <CJK>
+<U6377> /xb1/xb6 <CJK>
+<U6367> /xb1/xb7 <CJK>
+<U6398> /xb1/xb8 <CJK>
+<U63AA> /xb1/xb9 <CJK>
+<U6371> /xb1/xba <CJK>
+<U63A9> /xb1/xbb <CJK>
+<U6389> /xb1/xbc <CJK>
+<U6383> /xb1/xbd <CJK>
+<U639B> /xb1/xbe <CJK>
+<U636B> /xb1/xbf <CJK>
+<U63A8> /xb1/xc0 <CJK>
+<U6384> /xb1/xc1 <CJK>
+<U6388> /xb1/xc2 <CJK>
+<U6399> /xb1/xc3 <CJK>
+<U63A1> /xb1/xc4 <CJK>
+<U63AC> /xb1/xc5 <CJK>
+<U6392> /xb1/xc6 <CJK>
+<U638F> /xb1/xc7 <CJK>
+<U6380> /xb1/xc8 <CJK>
+<U637B> /xb1/xc9 <CJK>
+<U6369> /xb1/xca <CJK>
+<U6368> /xb1/xcb <CJK>
+<U637A> /xb1/xcc <CJK>
+<U655D> /xb1/xcd <CJK>
+<U6556> /xb1/xce <CJK>
+<U6551> /xb1/xcf <CJK>
+<U6559> /xb1/xd0 <CJK>
+<U6557> /xb1/xd1 <CJK>
+<U555F> /xb1/xd2 <CJK>
+<U654F> /xb1/xd3 <CJK>
+<U6558> /xb1/xd4 <CJK>
+<U6555> /xb1/xd5 <CJK>
+<U6554> /xb1/xd6 <CJK>
+<U659C> /xb1/xd7 <CJK>
+<U659B> /xb1/xd8 <CJK>
+<U65AC> /xb1/xd9 <CJK>
+<U65CF> /xb1/xda <CJK>
+<U65CB> /xb1/xdb <CJK>
+<U65CC> /xb1/xdc <CJK>
+<U65CE> /xb1/xdd <CJK>
+<U665D> /xb1/xde <CJK>
+<U665A> /xb1/xdf <CJK>
+<U6664> /xb1/xe0 <CJK>
+<U6668> /xb1/xe1 <CJK>
+<U6666> /xb1/xe2 <CJK>
+<U665E> /xb1/xe3 <CJK>
+<U66F9> /xb1/xe4 <CJK>
+<U52D7> /xb1/xe5 <CJK>
+<U671B> /xb1/xe6 <CJK>
+<U6881> /xb1/xe7 <CJK>
+<U68AF> /xb1/xe8 <CJK>
+<U68A2> /xb1/xe9 <CJK>
+<U6893> /xb1/xea <CJK>
+<U68B5> /xb1/xeb <CJK>
+<U687F> /xb1/xec <CJK>
+<U6876> /xb1/xed <CJK>
+<U68B1> /xb1/xee <CJK>
+<U68A7> /xb1/xef <CJK>
+<U6897> /xb1/xf0 <CJK>
+<U68B0> /xb1/xf1 <CJK>
+<U6883> /xb1/xf2 <CJK>
+<U68C4> /xb1/xf3 <CJK>
+<U68AD> /xb1/xf4 <CJK>
+<U6886> /xb1/xf5 <CJK>
+<U6885> /xb1/xf6 <CJK>
+<U6894> /xb1/xf7 <CJK>
+<U689D> /xb1/xf8 <CJK>
+<U68A8> /xb1/xf9 <CJK>
+<U689F> /xb1/xfa <CJK>
+<U68A1> /xb1/xfb <CJK>
+<U6882> /xb1/xfc <CJK>
+<U6B32> /xb1/xfd <CJK>
+<U6BBA> /xb1/xfe <CJK>
+<U6BEB> /xb2/x40 <CJK>
+<U6BEC> /xb2/x41 <CJK>
+<U6C2B> /xb2/x42 <CJK>
+<U6D8E> /xb2/x43 <CJK>
+<U6DBC> /xb2/x44 <CJK>
+<U6DF3> /xb2/x45 <CJK>
+<U6DD9> /xb2/x46 <CJK>
+<U6DB2> /xb2/x47 <CJK>
+<U6DE1> /xb2/x48 <CJK>
+<U6DCC> /xb2/x49 <CJK>
+<U6DE4> /xb2/x4a <CJK>
+<U6DFB> /xb2/x4b <CJK>
+<U6DFA> /xb2/x4c <CJK>
+<U6E05> /xb2/x4d <CJK>
+<U6DC7> /xb2/x4e <CJK>
+<U6DCB> /xb2/x4f <CJK>
+<U6DAF> /xb2/x50 <CJK>
+<U6DD1> /xb2/x51 <CJK>
+<U6DAE> /xb2/x52 <CJK>
+<U6DDE> /xb2/x53 <CJK>
+<U6DF9> /xb2/x54 <CJK>
+<U6DB8> /xb2/x55 <CJK>
+<U6DF7> /xb2/x56 <CJK>
+<U6DF5> /xb2/x57 <CJK>
+<U6DC5> /xb2/x58 <CJK>
+<U6DD2> /xb2/x59 <CJK>
+<U6E1A> /xb2/x5a <CJK>
+<U6DB5> /xb2/x5b <CJK>
+<U6DDA> /xb2/x5c <CJK>
+<U6DEB> /xb2/x5d <CJK>
+<U6DD8> /xb2/x5e <CJK>
+<U6DEA> /xb2/x5f <CJK>
+<U6DF1> /xb2/x60 <CJK>
+<U6DEE> /xb2/x61 <CJK>
+<U6DE8> /xb2/x62 <CJK>
+<U6DC6> /xb2/x63 <CJK>
+<U6DC4> /xb2/x64 <CJK>
+<U6DAA> /xb2/x65 <CJK>
+<U6DEC> /xb2/x66 <CJK>
+<U6DBF> /xb2/x67 <CJK>
+<U6DE6> /xb2/x68 <CJK>
+<U70F9> /xb2/x69 <CJK>
+<U7109> /xb2/x6a <CJK>
+<U710A> /xb2/x6b <CJK>
+<U70FD> /xb2/x6c <CJK>
+<U70EF> /xb2/x6d <CJK>
+<U723D> /xb2/x6e <CJK>
+<U727D> /xb2/x6f <CJK>
+<U7281> /xb2/x70 <CJK>
+<U731C> /xb2/x71 <CJK>
+<U731B> /xb2/x72 <CJK>
+<U7316> /xb2/x73 <CJK>
+<U7313> /xb2/x74 <CJK>
+<U7319> /xb2/x75 <CJK>
+<U7387> /xb2/x76 <CJK>
+<U7405> /xb2/x77 <CJK>
+<U740A> /xb2/x78 <CJK>
+<U7403> /xb2/x79 <CJK>
+<U7406> /xb2/x7a <CJK>
+<U73FE> /xb2/x7b <CJK>
+<U740D> /xb2/x7c <CJK>
+<U74E0> /xb2/x7d <CJK>
+<U74F6> /xb2/x7e <CJK>
+<U74F7> /xb2/xa1 <CJK>
+<U751C> /xb2/xa2 <CJK>
+<U7522> /xb2/xa3 <CJK>
+<U7565> /xb2/xa4 <CJK>
+<U7566> /xb2/xa5 <CJK>
+<U7562> /xb2/xa6 <CJK>
+<U7570> /xb2/xa7 <CJK>
+<U758F> /xb2/xa8 <CJK>
+<U75D4> /xb2/xa9 <CJK>
+<U75D5> /xb2/xaa <CJK>
+<U75B5> /xb2/xab <CJK>
+<U75CA> /xb2/xac <CJK>
+<U75CD> /xb2/xad <CJK>
+<U768E> /xb2/xae <CJK>
+<U76D4> /xb2/xaf <CJK>
+<U76D2> /xb2/xb0 <CJK>
+<U76DB> /xb2/xb1 <CJK>
+<U7737> /xb2/xb2 <CJK>
+<U773E> /xb2/xb3 <CJK>
+<U773C> /xb2/xb4 <CJK>
+<U7736> /xb2/xb5 <CJK>
+<U7738> /xb2/xb6 <CJK>
+<U773A> /xb2/xb7 <CJK>
+<U786B> /xb2/xb8 <CJK>
+<U7843> /xb2/xb9 <CJK>
+<U784E> /xb2/xba <CJK>
+<U7965> /xb2/xbb <CJK>
+<U7968> /xb2/xbc <CJK>
+<U796D> /xb2/xbd <CJK>
+<U79FB> /xb2/xbe <CJK>
+<U7A92> /xb2/xbf <CJK>
+<U7A95> /xb2/xc0 <CJK>
+<U7B20> /xb2/xc1 <CJK>
+<U7B28> /xb2/xc2 <CJK>
+<U7B1B> /xb2/xc3 <CJK>
+<U7B2C> /xb2/xc4 <CJK>
+<U7B26> /xb2/xc5 <CJK>
+<U7B19> /xb2/xc6 <CJK>
+<U7B1E> /xb2/xc7 <CJK>
+<U7B2E> /xb2/xc8 <CJK>
+<U7C92> /xb2/xc9 <CJK>
+<U7C97> /xb2/xca <CJK>
+<U7C95> /xb2/xcb <CJK>
+<U7D46> /xb2/xcc <CJK>
+<U7D43> /xb2/xcd <CJK>
+<U7D71> /xb2/xce <CJK>
+<U7D2E> /xb2/xcf <CJK>
+<U7D39> /xb2/xd0 <CJK>
+<U7D3C> /xb2/xd1 <CJK>
+<U7D40> /xb2/xd2 <CJK>
+<U7D30> /xb2/xd3 <CJK>
+<U7D33> /xb2/xd4 <CJK>
+<U7D44> /xb2/xd5 <CJK>
+<U7D2F> /xb2/xd6 <CJK>
+<U7D42> /xb2/xd7 <CJK>
+<U7D32> /xb2/xd8 <CJK>
+<U7D31> /xb2/xd9 <CJK>
+<U7F3D> /xb2/xda <CJK>
+<U7F9E> /xb2/xdb <CJK>
+<U7F9A> /xb2/xdc <CJK>
+<U7FCC> /xb2/xdd <CJK>
+<U7FCE> /xb2/xde <CJK>
+<U7FD2> /xb2/xdf <CJK>
+<U801C> /xb2/xe0 <CJK>
+<U804A> /xb2/xe1 <CJK>
+<U8046> /xb2/xe2 <CJK>
+<U812F> /xb2/xe3 <CJK>
+<U8116> /xb2/xe4 <CJK>
+<U8123> /xb2/xe5 <CJK>
+<U812B> /xb2/xe6 <CJK>
+<U8129> /xb2/xe7 <CJK>
+<U8130> /xb2/xe8 <CJK>
+<U8124> /xb2/xe9 <CJK>
+<U8202> /xb2/xea <CJK>
+<U8235> /xb2/xeb <CJK>
+<U8237> /xb2/xec <CJK>
+<U8236> /xb2/xed <CJK>
+<U8239> /xb2/xee <CJK>
+<U838E> /xb2/xef <CJK>
+<U839E> /xb2/xf0 <CJK>
+<U8398> /xb2/xf1 <CJK>
+<U8378> /xb2/xf2 <CJK>
+<U83A2> /xb2/xf3 <CJK>
+<U8396> /xb2/xf4 <CJK>
+<U83BD> /xb2/xf5 <CJK>
+<U83AB> /xb2/xf6 <CJK>
+<U8392> /xb2/xf7 <CJK>
+<U838A> /xb2/xf8 <CJK>
+<U8393> /xb2/xf9 <CJK>
+<U8389> /xb2/xfa <CJK>
+<U83A0> /xb2/xfb <CJK>
+<U8377> /xb2/xfc <CJK>
+<U837B> /xb2/xfd <CJK>
+<U837C> /xb2/xfe <CJK>
+<U8386> /xb3/x40 <CJK>
+<U83A7> /xb3/x41 <CJK>
+<U8655> /xb3/x42 <CJK>
+<U5F6A> /xb3/x43 <CJK>
+<U86C7> /xb3/x44 <CJK>
+<U86C0> /xb3/x45 <CJK>
+<U86B6> /xb3/x46 <CJK>
+<U86C4> /xb3/x47 <CJK>
+<U86B5> /xb3/x48 <CJK>
+<U86C6> /xb3/x49 <CJK>
+<U86CB> /xb3/x4a <CJK>
+<U86B1> /xb3/x4b <CJK>
+<U86AF> /xb3/x4c <CJK>
+<U86C9> /xb3/x4d <CJK>
+<U8853> /xb3/x4e <CJK>
+<U889E> /xb3/x4f <CJK>
+<U8888> /xb3/x50 <CJK>
+<U88AB> /xb3/x51 <CJK>
+<U8892> /xb3/x52 <CJK>
+<U8896> /xb3/x53 <CJK>
+<U888D> /xb3/x54 <CJK>
+<U888B> /xb3/x55 <CJK>
+<U8993> /xb3/x56 <CJK>
+<U898F> /xb3/x57 <CJK>
+<U8A2A> /xb3/x58 <CJK>
+<U8A1D> /xb3/x59 <CJK>
+<U8A23> /xb3/x5a <CJK>
+<U8A25> /xb3/x5b <CJK>
+<U8A31> /xb3/x5c <CJK>
+<U8A2D> /xb3/x5d <CJK>
+<U8A1F> /xb3/x5e <CJK>
+<U8A1B> /xb3/x5f <CJK>
+<U8A22> /xb3/x60 <CJK>
+<U8C49> /xb3/x61 <CJK>
+<U8C5A> /xb3/x62 <CJK>
+<U8CA9> /xb3/x63 <CJK>
+<U8CAC> /xb3/x64 <CJK>
+<U8CAB> /xb3/x65 <CJK>
+<U8CA8> /xb3/x66 <CJK>
+<U8CAA> /xb3/x67 <CJK>
+<U8CA7> /xb3/x68 <CJK>
+<U8D67> /xb3/x69 <CJK>
+<U8D66> /xb3/x6a <CJK>
+<U8DBE> /xb3/x6b <CJK>
+<U8DBA> /xb3/x6c <CJK>
+<U8EDB> /xb3/x6d <CJK>
+<U8EDF> /xb3/x6e <CJK>
+<U9019> /xb3/x6f <CJK>
+<U900D> /xb3/x70 <CJK>
+<U901A> /xb3/x71 <CJK>
+<U9017> /xb3/x72 <CJK>
+<U9023> /xb3/x73 <CJK>
+<U901F> /xb3/x74 <CJK>
+<U901D> /xb3/x75 <CJK>
+<U9010> /xb3/x76 <CJK>
+<U9015> /xb3/x77 <CJK>
+<U901E> /xb3/x78 <CJK>
+<U9020> /xb3/x79 <CJK>
+<U900F> /xb3/x7a <CJK>
+<U9022> /xb3/x7b <CJK>
+<U9016> /xb3/x7c <CJK>
+<U901B> /xb3/x7d <CJK>
+<U9014> /xb3/x7e <CJK>
+<U90E8> /xb3/xa1 <CJK>
+<U90ED> /xb3/xa2 <CJK>
+<U90FD> /xb3/xa3 <CJK>
+<U9157> /xb3/xa4 <CJK>
+<U91CE> /xb3/xa5 <CJK>
+<U91F5> /xb3/xa6 <CJK>
+<U91E6> /xb3/xa7 <CJK>
+<U91E3> /xb3/xa8 <CJK>
+<U91E7> /xb3/xa9 <CJK>
+<U91ED> /xb3/xaa <CJK>
+<U91E9> /xb3/xab <CJK>
+<U9589> /xb3/xac <CJK>
+<U966A> /xb3/xad <CJK>
+<U9675> /xb3/xae <CJK>
+<U9673> /xb3/xaf <CJK>
+<U9678> /xb3/xb0 <CJK>
+<U9670> /xb3/xb1 <CJK>
+<U9674> /xb3/xb2 <CJK>
+<U9676> /xb3/xb3 <CJK>
+<U9677> /xb3/xb4 <CJK>
+<U966C> /xb3/xb5 <CJK>
+<U96C0> /xb3/xb6 <CJK>
+<U96EA> /xb3/xb7 <CJK>
+<U96E9> /xb3/xb8 <CJK>
+<U7AE0> /xb3/xb9 <CJK>
+<U7ADF> /xb3/xba <CJK>
+<U9802> /xb3/xbb <CJK>
+<U9803> /xb3/xbc <CJK>
+<U9B5A> /xb3/xbd <CJK>
+<U9CE5> /xb3/xbe <CJK>
+<U9E75> /xb3/xbf <CJK>
+<U9E7F> /xb3/xc0 <CJK>
+<U9EA5> /xb3/xc1 <CJK>
+<U9EBB> /xb3/xc2 <CJK>
+<U50A2> /xb3/xc3 <CJK>
+<U508D> /xb3/xc4 <CJK>
+<U5085> /xb3/xc5 <CJK>
+<U5099> /xb3/xc6 <CJK>
+<U5091> /xb3/xc7 <CJK>
+<U5080> /xb3/xc8 <CJK>
+<U5096> /xb3/xc9 <CJK>
+<U5098> /xb3/xca <CJK>
+<U509A> /xb3/xcb <CJK>
+<U6700> /xb3/xcc <CJK>
+<U51F1> /xb3/xcd <CJK>
+<U5272> /xb3/xce <CJK>
+<U5274> /xb3/xcf <CJK>
+<U5275> /xb3/xd0 <CJK>
+<U5269> /xb3/xd1 <CJK>
+<U52DE> /xb3/xd2 <CJK>
+<U52DD> /xb3/xd3 <CJK>
+<U52DB> /xb3/xd4 <CJK>
+<U535A> /xb3/xd5 <CJK>
+<U53A5> /xb3/xd6 <CJK>
+<U557B> /xb3/xd7 <CJK>
+<U5580> /xb3/xd8 <CJK>
+<U55A7> /xb3/xd9 <CJK>
+<U557C> /xb3/xda <CJK>
+<U558A> /xb3/xdb <CJK>
+<U559D> /xb3/xdc <CJK>
+<U5598> /xb3/xdd <CJK>
+<U5582> /xb3/xde <CJK>
+<U559C> /xb3/xdf <CJK>
+<U55AA> /xb3/xe0 <CJK>
+<U5594> /xb3/xe1 <CJK>
+<U5587> /xb3/xe2 <CJK>
+<U558B> /xb3/xe3 <CJK>
+<U5583> /xb3/xe4 <CJK>
+<U55B3> /xb3/xe5 <CJK>
+<U55AE> /xb3/xe6 <CJK>
+<U559F> /xb3/xe7 <CJK>
+<U553E> /xb3/xe8 <CJK>
+<U55B2> /xb3/xe9 <CJK>
+<U559A> /xb3/xea <CJK>
+<U55BB> /xb3/xeb <CJK>
+<U55AC> /xb3/xec <CJK>
+<U55B1> /xb3/xed <CJK>
+<U557E> /xb3/xee <CJK>
+<U5589> /xb3/xef <CJK>
+<U55AB> /xb3/xf0 <CJK>
+<U5599> /xb3/xf1 <CJK>
+<U570D> /xb3/xf2 <CJK>
+<U582F> /xb3/xf3 <CJK>
+<U582A> /xb3/xf4 <CJK>
+<U5834> /xb3/xf5 <CJK>
+<U5824> /xb3/xf6 <CJK>
+<U5830> /xb3/xf7 <CJK>
+<U5831> /xb3/xf8 <CJK>
+<U5821> /xb3/xf9 <CJK>
+<U581D> /xb3/xfa <CJK>
+<U5820> /xb3/xfb <CJK>
+<U58F9> /xb3/xfc <CJK>
+<U58FA> /xb3/xfd <CJK>
+<U5960> /xb3/xfe <CJK>
+<U5A77> /xb4/x40 <CJK>
+<U5A9A> /xb4/x41 <CJK>
+<U5A7F> /xb4/x42 <CJK>
+<U5A92> /xb4/x43 <CJK>
+<U5A9B> /xb4/x44 <CJK>
+<U5AA7> /xb4/x45 <CJK>
+<U5B73> /xb4/x46 <CJK>
+<U5B71> /xb4/x47 <CJK>
+<U5BD2> /xb4/x48 <CJK>
+<U5BCC> /xb4/x49 <CJK>
+<U5BD3> /xb4/x4a <CJK>
+<U5BD0> /xb4/x4b <CJK>
+<U5C0A> /xb4/x4c <CJK>
+<U5C0B> /xb4/x4d <CJK>
+<U5C31> /xb4/x4e <CJK>
+<U5D4C> /xb4/x4f <CJK>
+<U5D50> /xb4/x50 <CJK>
+<U5D34> /xb4/x51 <CJK>
+<U5D47> /xb4/x52 <CJK>
+<U5DFD> /xb4/x53 <CJK>
+<U5E45> /xb4/x54 <CJK>
+<U5E3D> /xb4/x55 <CJK>
+<U5E40> /xb4/x56 <CJK>
+<U5E43> /xb4/x57 <CJK>
+<U5E7E> /xb4/x58 <CJK>
+<U5ECA> /xb4/x59 <CJK>
+<U5EC1> /xb4/x5a <CJK>
+<U5EC2> /xb4/x5b <CJK>
+<U5EC4> /xb4/x5c <CJK>
+<U5F3C> /xb4/x5d <CJK>
+<U5F6D> /xb4/x5e <CJK>
+<U5FA9> /xb4/x5f <CJK>
+<U5FAA> /xb4/x60 <CJK>
+<U5FA8> /xb4/x61 <CJK>
+<U60D1> /xb4/x62 <CJK>
+<U60E1> /xb4/x63 <CJK>
+<U60B2> /xb4/x64 <CJK>
+<U60B6> /xb4/x65 <CJK>
+<U60E0> /xb4/x66 <CJK>
+<U611C> /xb4/x67 <CJK>
+<U6123> /xb4/x68 <CJK>
+<U60FA> /xb4/x69 <CJK>
+<U6115> /xb4/x6a <CJK>
+<U60F0> /xb4/x6b <CJK>
+<U60FB> /xb4/x6c <CJK>
+<U60F4> /xb4/x6d <CJK>
+<U6168> /xb4/x6e <CJK>
+<U60F1> /xb4/x6f <CJK>
+<U610E> /xb4/x70 <CJK>
+<U60F6> /xb4/x71 <CJK>
+<U6109> /xb4/x72 <CJK>
+<U6100> /xb4/x73 <CJK>
+<U6112> /xb4/x74 <CJK>
+<U621F> /xb4/x75 <CJK>
+<U6249> /xb4/x76 <CJK>
+<U63A3> /xb4/x77 <CJK>
+<U638C> /xb4/x78 <CJK>
+<U63CF> /xb4/x79 <CJK>
+<U63C0> /xb4/x7a <CJK>
+<U63E9> /xb4/x7b <CJK>
+<U63C9> /xb4/x7c <CJK>
+<U63C6> /xb4/x7d <CJK>
+<U63CD> /xb4/x7e <CJK>
+<U63D2> /xb4/xa1 <CJK>
+<U63E3> /xb4/xa2 <CJK>
+<U63D0> /xb4/xa3 <CJK>
+<U63E1> /xb4/xa4 <CJK>
+<U63D6> /xb4/xa5 <CJK>
+<U63ED> /xb4/xa6 <CJK>
+<U63EE> /xb4/xa7 <CJK>
+<U6376> /xb4/xa8 <CJK>
+<U63F4> /xb4/xa9 <CJK>
+<U63EA> /xb4/xaa <CJK>
+<U63DB> /xb4/xab <CJK>
+<U6452> /xb4/xac <CJK>
+<U63DA> /xb4/xad <CJK>
+<U63F9> /xb4/xae <CJK>
+<U655E> /xb4/xaf <CJK>
+<U6566> /xb4/xb0 <CJK>
+<U6562> /xb4/xb1 <CJK>
+<U6563> /xb4/xb2 <CJK>
+<U6591> /xb4/xb3 <CJK>
+<U6590> /xb4/xb4 <CJK>
+<U65AF> /xb4/xb5 <CJK>
+<U666E> /xb4/xb6 <CJK>
+<U6670> /xb4/xb7 <CJK>
+<U6674> /xb4/xb8 <CJK>
+<U6676> /xb4/xb9 <CJK>
+<U666F> /xb4/xba <CJK>
+<U6691> /xb4/xbb <CJK>
+<U667A> /xb4/xbc <CJK>
+<U667E> /xb4/xbd <CJK>
+<U6677> /xb4/xbe <CJK>
+<U66FE> /xb4/xbf <CJK>
+<U66FF> /xb4/xc0 <CJK>
+<U671F> /xb4/xc1 <CJK>
+<U671D> /xb4/xc2 <CJK>
+<U68FA> /xb4/xc3 <CJK>
+<U68D5> /xb4/xc4 <CJK>
+<U68E0> /xb4/xc5 <CJK>
+<U68D8> /xb4/xc6 <CJK>
+<U68D7> /xb4/xc7 <CJK>
+<U6905> /xb4/xc8 <CJK>
+<U68DF> /xb4/xc9 <CJK>
+<U68F5> /xb4/xca <CJK>
+<U68EE> /xb4/xcb <CJK>
+<U68E7> /xb4/xcc <CJK>
+<U68F9> /xb4/xcd <CJK>
+<U68D2> /xb4/xce <CJK>
+<U68F2> /xb4/xcf <CJK>
+<U68E3> /xb4/xd0 <CJK>
+<U68CB> /xb4/xd1 <CJK>
+<U68CD> /xb4/xd2 <CJK>
+<U690D> /xb4/xd3 <CJK>
+<U6912> /xb4/xd4 <CJK>
+<U690E> /xb4/xd5 <CJK>
+<U68C9> /xb4/xd6 <CJK>
+<U68DA> /xb4/xd7 <CJK>
+<U696E> /xb4/xd8 <CJK>
+<U68FB> /xb4/xd9 <CJK>
+<U6B3E> /xb4/xda <CJK>
+<U6B3A> /xb4/xdb <CJK>
+<U6B3D> /xb4/xdc <CJK>
+<U6B98> /xb4/xdd <CJK>
+<U6B96> /xb4/xde <CJK>
+<U6BBC> /xb4/xdf <CJK>
+<U6BEF> /xb4/xe0 <CJK>
+<U6C2E> /xb4/xe1 <CJK>
+<U6C2F> /xb4/xe2 <CJK>
+<U6C2C> /xb4/xe3 <CJK>
+<U6E2F> /xb4/xe4 <CJK>
+<U6E38> /xb4/xe5 <CJK>
+<U6E54> /xb4/xe6 <CJK>
+<U6E21> /xb4/xe7 <CJK>
+<U6E32> /xb4/xe8 <CJK>
+<U6E67> /xb4/xe9 <CJK>
+<U6E4A> /xb4/xea <CJK>
+<U6E20> /xb4/xeb <CJK>
+<U6E25> /xb4/xec <CJK>
+<U6E23> /xb4/xed <CJK>
+<U6E1B> /xb4/xee <CJK>
+<U6E5B> /xb4/xef <CJK>
+<U6E58> /xb4/xf0 <CJK>
+<U6E24> /xb4/xf1 <CJK>
+<U6E56> /xb4/xf2 <CJK>
+<U6E6E> /xb4/xf3 <CJK>
+<U6E2D> /xb4/xf4 <CJK>
+<U6E26> /xb4/xf5 <CJK>
+<U6E6F> /xb4/xf6 <CJK>
+<U6E34> /xb4/xf7 <CJK>
+<U6E4D> /xb4/xf8 <CJK>
+<U6E3A> /xb4/xf9 <CJK>
+<U6E2C> /xb4/xfa <CJK>
+<U6E43> /xb4/xfb <CJK>
+<U6E1D> /xb4/xfc <CJK>
+<U6E3E> /xb4/xfd <CJK>
+<U6ECB> /xb4/xfe <CJK>
+<U6E89> /xb5/x40 <CJK>
+<U6E19> /xb5/x41 <CJK>
+<U6E4E> /xb5/x42 <CJK>
+<U6E63> /xb5/x43 <CJK>
+<U6E44> /xb5/x44 <CJK>
+<U6E72> /xb5/x45 <CJK>
+<U6E69> /xb5/x46 <CJK>
+<U6E5F> /xb5/x47 <CJK>
+<U7119> /xb5/x48 <CJK>
+<U711A> /xb5/x49 <CJK>
+<U7126> /xb5/x4a <CJK>
+<U7130> /xb5/x4b <CJK>
+<U7121> /xb5/x4c <CJK>
+<U7136> /xb5/x4d <CJK>
+<U716E> /xb5/x4e <CJK>
+<U711C> /xb5/x4f <CJK>
+<U724C> /xb5/x50 <CJK>
+<U7284> /xb5/x51 <CJK>
+<U7280> /xb5/x52 <CJK>
+<U7336> /xb5/x53 <CJK>
+<U7325> /xb5/x54 <CJK>
+<U7334> /xb5/x55 <CJK>
+<U7329> /xb5/x56 <CJK>
+<U743A> /xb5/x57 <CJK>
+<U742A> /xb5/x58 <CJK>
+<U7433> /xb5/x59 <CJK>
+<U7422> /xb5/x5a <CJK>
+<U7425> /xb5/x5b <CJK>
+<U7435> /xb5/x5c <CJK>
+<U7436> /xb5/x5d <CJK>
+<U7434> /xb5/x5e <CJK>
+<U742F> /xb5/x5f <CJK>
+<U741B> /xb5/x60 <CJK>
+<U7426> /xb5/x61 <CJK>
+<U7428> /xb5/x62 <CJK>
+<U7525> /xb5/x63 <CJK>
+<U7526> /xb5/x64 <CJK>
+<U756B> /xb5/x65 <CJK>
+<U756A> /xb5/x66 <CJK>
+<U75E2> /xb5/x67 <CJK>
+<U75DB> /xb5/x68 <CJK>
+<U75E3> /xb5/x69 <CJK>
+<U75D9> /xb5/x6a <CJK>
+<U75D8> /xb5/x6b <CJK>
+<U75DE> /xb5/x6c <CJK>
+<U75E0> /xb5/x6d <CJK>
+<U767B> /xb5/x6e <CJK>
+<U767C> /xb5/x6f <CJK>
+<U7696> /xb5/x70 <CJK>
+<U7693> /xb5/x71 <CJK>
+<U76B4> /xb5/x72 <CJK>
+<U76DC> /xb5/x73 <CJK>
+<U774F> /xb5/x74 <CJK>
+<U77ED> /xb5/x75 <CJK>
+<U785D> /xb5/x76 <CJK>
+<U786C> /xb5/x77 <CJK>
+<U786F> /xb5/x78 <CJK>
+<U7A0D> /xb5/x79 <CJK>
+<U7A08> /xb5/x7a <CJK>
+<U7A0B> /xb5/x7b <CJK>
+<U7A05> /xb5/x7c <CJK>
+<U7A00> /xb5/x7d <CJK>
+<U7A98> /xb5/x7e <CJK>
+<U7A97> /xb5/xa1 <CJK>
+<U7A96> /xb5/xa2 <CJK>
+<U7AE5> /xb5/xa3 <CJK>
+<U7AE3> /xb5/xa4 <CJK>
+<U7B49> /xb5/xa5 <CJK>
+<U7B56> /xb5/xa6 <CJK>
+<U7B46> /xb5/xa7 <CJK>
+<U7B50> /xb5/xa8 <CJK>
+<U7B52> /xb5/xa9 <CJK>
+<U7B54> /xb5/xaa <CJK>
+<U7B4D> /xb5/xab <CJK>
+<U7B4B> /xb5/xac <CJK>
+<U7B4F> /xb5/xad <CJK>
+<U7B51> /xb5/xae <CJK>
+<U7C9F> /xb5/xaf <CJK>
+<U7CA5> /xb5/xb0 <CJK>
+<U7D5E> /xb5/xb1 <CJK>
+<U7D50> /xb5/xb2 <CJK>
+<U7D68> /xb5/xb3 <CJK>
+<U7D55> /xb5/xb4 <CJK>
+<U7D2B> /xb5/xb5 <CJK>
+<U7D6E> /xb5/xb6 <CJK>
+<U7D72> /xb5/xb7 <CJK>
+<U7D61> /xb5/xb8 <CJK>
+<U7D66> /xb5/xb9 <CJK>
+<U7D62> /xb5/xba <CJK>
+<U7D70> /xb5/xbb <CJK>
+<U7D73> /xb5/xbc <CJK>
+<U5584> /xb5/xbd <CJK>
+<U7FD4> /xb5/xbe <CJK>
+<U7FD5> /xb5/xbf <CJK>
+<U800B> /xb5/xc0 <CJK>
+<U8052> /xb5/xc1 <CJK>
+<U8085> /xb5/xc2 <CJK>
+<U8155> /xb5/xc3 <CJK>
+<U8154> /xb5/xc4 <CJK>
+<U814B> /xb5/xc5 <CJK>
+<U8151> /xb5/xc6 <CJK>
+<U814E> /xb5/xc7 <CJK>
+<U8139> /xb5/xc8 <CJK>
+<U8146> /xb5/xc9 <CJK>
+<U813E> /xb5/xca <CJK>
+<U814C> /xb5/xcb <CJK>
+<U8153> /xb5/xcc <CJK>
+<U8174> /xb5/xcd <CJK>
+<U8212> /xb5/xce <CJK>
+<U821C> /xb5/xcf <CJK>
+<U83E9> /xb5/xd0 <CJK>
+<U8403> /xb5/xd1 <CJK>
+<U83F8> /xb5/xd2 <CJK>
+<U840D> /xb5/xd3 <CJK>
+<U83E0> /xb5/xd4 <CJK>
+<U83C5> /xb5/xd5 <CJK>
+<U840B> /xb5/xd6 <CJK>
+<U83C1> /xb5/xd7 <CJK>
+<U83EF> /xb5/xd8 <CJK>
+<U83F1> /xb5/xd9 <CJK>
+<U83F4> /xb5/xda <CJK>
+<U8457> /xb5/xdb <CJK>
+<U840A> /xb5/xdc <CJK>
+<U83F0> /xb5/xdd <CJK>
+<U840C> /xb5/xde <CJK>
+<U83CC> /xb5/xdf <CJK>
+<U83FD> /xb5/xe0 <CJK>
+<U83F2> /xb5/xe1 <CJK>
+<U83CA> /xb5/xe2 <CJK>
+<U8438> /xb5/xe3 <CJK>
+<U840E> /xb5/xe4 <CJK>
+<U8404> /xb5/xe5 <CJK>
+<U83DC> /xb5/xe6 <CJK>
+<U8407> /xb5/xe7 <CJK>
+<U83D4> /xb5/xe8 <CJK>
+<U83DF> /xb5/xe9 <CJK>
+<U865B> /xb5/xea <CJK>
+<U86DF> /xb5/xeb <CJK>
+<U86D9> /xb5/xec <CJK>
+<U86ED> /xb5/xed <CJK>
+<U86D4> /xb5/xee <CJK>
+<U86DB> /xb5/xef <CJK>
+<U86E4> /xb5/xf0 <CJK>
+<U86D0> /xb5/xf1 <CJK>
+<U86DE> /xb5/xf2 <CJK>
+<U8857> /xb5/xf3 <CJK>
+<U88C1> /xb5/xf4 <CJK>
+<U88C2> /xb5/xf5 <CJK>
+<U88B1> /xb5/xf6 <CJK>
+<U8983> /xb5/xf7 <CJK>
+<U8996> /xb5/xf8 <CJK>
+<U8A3B> /xb5/xf9 <CJK>
+<U8A60> /xb5/xfa <CJK>
+<U8A55> /xb5/xfb <CJK>
+<U8A5E> /xb5/xfc <CJK>
+<U8A3C> /xb5/xfd <CJK>
+<U8A41> /xb5/xfe <CJK>
+<U8A54> /xb6/x40 <CJK>
+<U8A5B> /xb6/x41 <CJK>
+<U8A50> /xb6/x42 <CJK>
+<U8A46> /xb6/x43 <CJK>
+<U8A34> /xb6/x44 <CJK>
+<U8A3A> /xb6/x45 <CJK>
+<U8A36> /xb6/x46 <CJK>
+<U8A56> /xb6/x47 <CJK>
+<U8C61> /xb6/x48 <CJK>
+<U8C82> /xb6/x49 <CJK>
+<U8CAF> /xb6/x4a <CJK>
+<U8CBC> /xb6/x4b <CJK>
+<U8CB3> /xb6/x4c <CJK>
+<U8CBD> /xb6/x4d <CJK>
+<U8CC1> /xb6/x4e <CJK>
+<U8CBB> /xb6/x4f <CJK>
+<U8CC0> /xb6/x50 <CJK>
+<U8CB4> /xb6/x51 <CJK>
+<U8CB7> /xb6/x52 <CJK>
+<U8CB6> /xb6/x53 <CJK>
+<U8CBF> /xb6/x54 <CJK>
+<U8CB8> /xb6/x55 <CJK>
+<U8D8A> /xb6/x56 <CJK>
+<U8D85> /xb6/x57 <CJK>
+<U8D81> /xb6/x58 <CJK>
+<U8DCE> /xb6/x59 <CJK>
+<U8DDD> /xb6/x5a <CJK>
+<U8DCB> /xb6/x5b <CJK>
+<U8DDA> /xb6/x5c <CJK>
+<U8DD1> /xb6/x5d <CJK>
+<U8DCC> /xb6/x5e <CJK>
+<U8DDB> /xb6/x5f <CJK>
+<U8DC6> /xb6/x60 <CJK>
+<U8EFB> /xb6/x61 <CJK>
+<U8EF8> /xb6/x62 <CJK>
+<U8EFC> /xb6/x63 <CJK>
+<U8F9C> /xb6/x64 <CJK>
+<U902E> /xb6/x65 <CJK>
+<U9035> /xb6/x66 <CJK>
+<U9031> /xb6/x67 <CJK>
+<U9038> /xb6/x68 <CJK>
+<U9032> /xb6/x69 <CJK>
+<U9036> /xb6/x6a <CJK>
+<U9102> /xb6/x6b <CJK>
+<U90F5> /xb6/x6c <CJK>
+<U9109> /xb6/x6d <CJK>
+<U90FE> /xb6/x6e <CJK>
+<U9163> /xb6/x6f <CJK>
+<U9165> /xb6/x70 <CJK>
+<U91CF> /xb6/x71 <CJK>
+<U9214> /xb6/x72 <CJK>
+<U9215> /xb6/x73 <CJK>
+<U9223> /xb6/x74 <CJK>
+<U9209> /xb6/x75 <CJK>
+<U921E> /xb6/x76 <CJK>
+<U920D> /xb6/x77 <CJK>
+<U9210> /xb6/x78 <CJK>
+<U9207> /xb6/x79 <CJK>
+<U9211> /xb6/x7a <CJK>
+<U9594> /xb6/x7b <CJK>
+<U958F> /xb6/x7c <CJK>
+<U958B> /xb6/x7d <CJK>
+<U9591> /xb6/x7e <CJK>
+<U9593> /xb6/xa1 <CJK>
+<U9592> /xb6/xa2 <CJK>
+<U958E> /xb6/xa3 <CJK>
+<U968A> /xb6/xa4 <CJK>
+<U968E> /xb6/xa5 <CJK>
+<U968B> /xb6/xa6 <CJK>
+<U967D> /xb6/xa7 <CJK>
+<U9685> /xb6/xa8 <CJK>
+<U9686> /xb6/xa9 <CJK>
+<U968D> /xb6/xaa <CJK>
+<U9672> /xb6/xab <CJK>
+<U9684> /xb6/xac <CJK>
+<U96C1> /xb6/xad <CJK>
+<U96C5> /xb6/xae <CJK>
+<U96C4> /xb6/xaf <CJK>
+<U96C6> /xb6/xb0 <CJK>
+<U96C7> /xb6/xb1 <CJK>
+<U96EF> /xb6/xb2 <CJK>
+<U96F2> /xb6/xb3 <CJK>
+<U97CC> /xb6/xb4 <CJK>
+<U9805> /xb6/xb5 <CJK>
+<U9806> /xb6/xb6 <CJK>
+<U9808> /xb6/xb7 <CJK>
+<U98E7> /xb6/xb8 <CJK>
+<U98EA> /xb6/xb9 <CJK>
+<U98EF> /xb6/xba <CJK>
+<U98E9> /xb6/xbb <CJK>
+<U98F2> /xb6/xbc <CJK>
+<U98ED> /xb6/xbd <CJK>
+<U99AE> /xb6/xbe <CJK>
+<U99AD> /xb6/xbf <CJK>
+<U9EC3> /xb6/xc0 <CJK>
+<U9ECD> /xb6/xc1 <CJK>
+<U9ED1> /xb6/xc2 <CJK>
+<U4E82> /xb6/xc3 <CJK>
+<U50AD> /xb6/xc4 <CJK>
+<U50B5> /xb6/xc5 <CJK>
+<U50B2> /xb6/xc6 <CJK>
+<U50B3> /xb6/xc7 <CJK>
+<U50C5> /xb6/xc8 <CJK>
+<U50BE> /xb6/xc9 <CJK>
+<U50AC> /xb6/xca <CJK>
+<U50B7> /xb6/xcb <CJK>
+<U50BB> /xb6/xcc <CJK>
+<U50AF> /xb6/xcd <CJK>
+<U50C7> /xb6/xce <CJK>
+<U527F> /xb6/xcf <CJK>
+<U5277> /xb6/xd0 <CJK>
+<U527D> /xb6/xd1 <CJK>
+<U52DF> /xb6/xd2 <CJK>
+<U52E6> /xb6/xd3 <CJK>
+<U52E4> /xb6/xd4 <CJK>
+<U52E2> /xb6/xd5 <CJK>
+<U52E3> /xb6/xd6 <CJK>
+<U532F> /xb6/xd7 <CJK>
+<U55DF> /xb6/xd8 <CJK>
+<U55E8> /xb6/xd9 <CJK>
+<U55D3> /xb6/xda <CJK>
+<U55E6> /xb6/xdb <CJK>
+<U55CE> /xb6/xdc <CJK>
+<U55DC> /xb6/xdd <CJK>
+<U55C7> /xb6/xde <CJK>
+<U55D1> /xb6/xdf <CJK>
+<U55E3> /xb6/xe0 <CJK>
+<U55E4> /xb6/xe1 <CJK>
+<U55EF> /xb6/xe2 <CJK>
+<U55DA> /xb6/xe3 <CJK>
+<U55E1> /xb6/xe4 <CJK>
+<U55C5> /xb6/xe5 <CJK>
+<U55C6> /xb6/xe6 <CJK>
+<U55E5> /xb6/xe7 <CJK>
+<U55C9> /xb6/xe8 <CJK>
+<U5712> /xb6/xe9 <CJK>
+<U5713> /xb6/xea <CJK>
+<U585E> /xb6/xeb <CJK>
+<U5851> /xb6/xec <CJK>
+<U5858> /xb6/xed <CJK>
+<U5857> /xb6/xee <CJK>
+<U585A> /xb6/xef <CJK>
+<U5854> /xb6/xf0 <CJK>
+<U586B> /xb6/xf1 <CJK>
+<U584C> /xb6/xf2 <CJK>
+<U586D> /xb6/xf3 <CJK>
+<U584A> /xb6/xf4 <CJK>
+<U5862> /xb6/xf5 <CJK>
+<U5852> /xb6/xf6 <CJK>
+<U584B> /xb6/xf7 <CJK>
+<U5967> /xb6/xf8 <CJK>
+<U5AC1> /xb6/xf9 <CJK>
+<U5AC9> /xb6/xfa <CJK>
+<U5ACC> /xb6/xfb <CJK>
+<U5ABE> /xb6/xfc <CJK>
+<U5ABD> /xb6/xfd <CJK>
+<U5ABC> /xb6/xfe <CJK>
+<U5AB3> /xb7/x40 <CJK>
+<U5AC2> /xb7/x41 <CJK>
+<U5AB2> /xb7/x42 <CJK>
+<U5D69> /xb7/x43 <CJK>
+<U5D6F> /xb7/x44 <CJK>
+<U5E4C> /xb7/x45 <CJK>
+<U5E79> /xb7/x46 <CJK>
+<U5EC9> /xb7/x47 <CJK>
+<U5EC8> /xb7/x48 <CJK>
+<U5F12> /xb7/x49 <CJK>
+<U5F59> /xb7/x4a <CJK>
+<U5FAC> /xb7/x4b <CJK>
+<U5FAE> /xb7/x4c <CJK>
+<U611A> /xb7/x4d <CJK>
+<U610F> /xb7/x4e <CJK>
+<U6148> /xb7/x4f <CJK>
+<U611F> /xb7/x50 <CJK>
+<U60F3> /xb7/x51 <CJK>
+<U611B> /xb7/x52 <CJK>
+<U60F9> /xb7/x53 <CJK>
+<U6101> /xb7/x54 <CJK>
+<U6108> /xb7/x55 <CJK>
+<U614E> /xb7/x56 <CJK>
+<U614C> /xb7/x57 <CJK>
+<U6144> /xb7/x58 <CJK>
+<U614D> /xb7/x59 <CJK>
+<U613E> /xb7/x5a <CJK>
+<U6134> /xb7/x5b <CJK>
+<U6127> /xb7/x5c <CJK>
+<U610D> /xb7/x5d <CJK>
+<U6106> /xb7/x5e <CJK>
+<U6137> /xb7/x5f <CJK>
+<U6221> /xb7/x60 <CJK>
+<U6222> /xb7/x61 <CJK>
+<U6413> /xb7/x62 <CJK>
+<U643E> /xb7/x63 <CJK>
+<U641E> /xb7/x64 <CJK>
+<U642A> /xb7/x65 <CJK>
+<U642D> /xb7/x66 <CJK>
+<U643D> /xb7/x67 <CJK>
+<U642C> /xb7/x68 <CJK>
+<U640F> /xb7/x69 <CJK>
+<U641C> /xb7/x6a <CJK>
+<U6414> /xb7/x6b <CJK>
+<U640D> /xb7/x6c <CJK>
+<U6436> /xb7/x6d <CJK>
+<U6416> /xb7/x6e <CJK>
+<U6417> /xb7/x6f <CJK>
+<U6406> /xb7/x70 <CJK>
+<U656C> /xb7/x71 <CJK>
+<U659F> /xb7/x72 <CJK>
+<U65B0> /xb7/x73 <CJK>
+<U6697> /xb7/x74 <CJK>
+<U6689> /xb7/x75 <CJK>
+<U6687> /xb7/x76 <CJK>
+<U6688> /xb7/x77 <CJK>
+<U6696> /xb7/x78 <CJK>
+<U6684> /xb7/x79 <CJK>
+<U6698> /xb7/x7a <CJK>
+<U668D> /xb7/x7b <CJK>
+<U6703> /xb7/x7c <CJK>
+<U6994> /xb7/x7d <CJK>
+<U696D> /xb7/x7e <CJK>
+<U695A> /xb7/xa1 <CJK>
+<U6977> /xb7/xa2 <CJK>
+<U6960> /xb7/xa3 <CJK>
+<U6954> /xb7/xa4 <CJK>
+<U6975> /xb7/xa5 <CJK>
+<U6930> /xb7/xa6 <CJK>
+<U6982> /xb7/xa7 <CJK>
+<U694A> /xb7/xa8 <CJK>
+<U6968> /xb7/xa9 <CJK>
+<U696B> /xb7/xaa <CJK>
+<U695E> /xb7/xab <CJK>
+<U6953> /xb7/xac <CJK>
+<U6979> /xb7/xad <CJK>
+<U6986> /xb7/xae <CJK>
+<U695D> /xb7/xaf <CJK>
+<U6963> /xb7/xb0 <CJK>
+<U695B> /xb7/xb1 <CJK>
+<U6B47> /xb7/xb2 <CJK>
+<U6B72> /xb7/xb3 <CJK>
+<U6BC0> /xb7/xb4 <CJK>
+<U6BBF> /xb7/xb5 <CJK>
+<U6BD3> /xb7/xb6 <CJK>
+<U6BFD> /xb7/xb7 <CJK>
+<U6EA2> /xb7/xb8 <CJK>
+<U6EAF> /xb7/xb9 <CJK>
+<U6ED3> /xb7/xba <CJK>
+<U6EB6> /xb7/xbb <CJK>
+<U6EC2> /xb7/xbc <CJK>
+<U6E90> /xb7/xbd <CJK>
+<U6E9D> /xb7/xbe <CJK>
+<U6EC7> /xb7/xbf <CJK>
+<U6EC5> /xb7/xc0 <CJK>
+<U6EA5> /xb7/xc1 <CJK>
+<U6E98> /xb7/xc2 <CJK>
+<U6EBC> /xb7/xc3 <CJK>
+<U6EBA> /xb7/xc4 <CJK>
+<U6EAB> /xb7/xc5 <CJK>
+<U6ED1> /xb7/xc6 <CJK>
+<U6E96> /xb7/xc7 <CJK>
+<U6E9C> /xb7/xc8 <CJK>
+<U6EC4> /xb7/xc9 <CJK>
+<U6ED4> /xb7/xca <CJK>
+<U6EAA> /xb7/xcb <CJK>
+<U6EA7> /xb7/xcc <CJK>
+<U6EB4> /xb7/xcd <CJK>
+<U714E> /xb7/xce <CJK>
+<U7159> /xb7/xcf <CJK>
+<U7169> /xb7/xd0 <CJK>
+<U7164> /xb7/xd1 <CJK>
+<U7149> /xb7/xd2 <CJK>
+<U7167> /xb7/xd3 <CJK>
+<U715C> /xb7/xd4 <CJK>
+<U716C> /xb7/xd5 <CJK>
+<U7166> /xb7/xd6 <CJK>
+<U714C> /xb7/xd7 <CJK>
+<U7165> /xb7/xd8 <CJK>
+<U715E> /xb7/xd9 <CJK>
+<U7146> /xb7/xda <CJK>
+<U7168> /xb7/xdb <CJK>
+<U7156> /xb7/xdc <CJK>
+<U723A> /xb7/xdd <CJK>
+<U7252> /xb7/xde <CJK>
+<U7337> /xb7/xdf <CJK>
+<U7345> /xb7/xe0 <CJK>
+<U733F> /xb7/xe1 <CJK>
+<U733E> /xb7/xe2 <CJK>
+<U746F> /xb7/xe3 <CJK>
+<U745A> /xb7/xe4 <CJK>
+<U7455> /xb7/xe5 <CJK>
+<U745F> /xb7/xe6 <CJK>
+<U745E> /xb7/xe7 <CJK>
+<U7441> /xb7/xe8 <CJK>
+<U743F> /xb7/xe9 <CJK>
+<U7459> /xb7/xea <CJK>
+<U745B> /xb7/xeb <CJK>
+<U745C> /xb7/xec <CJK>
+<U7576> /xb7/xed <CJK>
+<U7578> /xb7/xee <CJK>
+<U7600> /xb7/xef <CJK>
+<U75F0> /xb7/xf0 <CJK>
+<U7601> /xb7/xf1 <CJK>
+<U75F2> /xb7/xf2 <CJK>
+<U75F1> /xb7/xf3 <CJK>
+<U75FA> /xb7/xf4 <CJK>
+<U75FF> /xb7/xf5 <CJK>
+<U75F4> /xb7/xf6 <CJK>
+<U75F3> /xb7/xf7 <CJK>
+<U76DE> /xb7/xf8 <CJK>
+<U76DF> /xb7/xf9 <CJK>
+<U775B> /xb7/xfa <CJK>
+<U776B> /xb7/xfb <CJK>
+<U7766> /xb7/xfc <CJK>
+<U775E> /xb7/xfd <CJK>
+<U7763> /xb7/xfe <CJK>
+<U7779> /xb8/x40 <CJK>
+<U776A> /xb8/x41 <CJK>
+<U776C> /xb8/x42 <CJK>
+<U775C> /xb8/x43 <CJK>
+<U7765> /xb8/x44 <CJK>
+<U7768> /xb8/x45 <CJK>
+<U7762> /xb8/x46 <CJK>
+<U77EE> /xb8/x47 <CJK>
+<U788E> /xb8/x48 <CJK>
+<U78B0> /xb8/x49 <CJK>
+<U7897> /xb8/x4a <CJK>
+<U7898> /xb8/x4b <CJK>
+<U788C> /xb8/x4c <CJK>
+<U7889> /xb8/x4d <CJK>
+<U787C> /xb8/x4e <CJK>
+<U7891> /xb8/x4f <CJK>
+<U7893> /xb8/x50 <CJK>
+<U787F> /xb8/x51 <CJK>
+<U797A> /xb8/x52 <CJK>
+<U797F> /xb8/x53 <CJK>
+<U7981> /xb8/x54 <CJK>
+<U842C> /xb8/x55 <CJK>
+<U79BD> /xb8/x56 <CJK>
+<U7A1C> /xb8/x57 <CJK>
+<U7A1A> /xb8/x58 <CJK>
+<U7A20> /xb8/x59 <CJK>
+<U7A14> /xb8/x5a <CJK>
+<U7A1F> /xb8/x5b <CJK>
+<U7A1E> /xb8/x5c <CJK>
+<U7A9F> /xb8/x5d <CJK>
+<U7AA0> /xb8/x5e <CJK>
+<U7B77> /xb8/x5f <CJK>
+<U7BC0> /xb8/x60 <CJK>
+<U7B60> /xb8/x61 <CJK>
+<U7B6E> /xb8/x62 <CJK>
+<U7B67> /xb8/x63 <CJK>
+<U7CB1> /xb8/x64 <CJK>
+<U7CB3> /xb8/x65 <CJK>
+<U7CB5> /xb8/x66 <CJK>
+<U7D93> /xb8/x67 <CJK>
+<U7D79> /xb8/x68 <CJK>
+<U7D91> /xb8/x69 <CJK>
+<U7D81> /xb8/x6a <CJK>
+<U7D8F> /xb8/x6b <CJK>
+<U7D5B> /xb8/x6c <CJK>
+<U7F6E> /xb8/x6d <CJK>
+<U7F69> /xb8/x6e <CJK>
+<U7F6A> /xb8/x6f <CJK>
+<U7F72> /xb8/x70 <CJK>
+<U7FA9> /xb8/x71 <CJK>
+<U7FA8> /xb8/x72 <CJK>
+<U7FA4> /xb8/x73 <CJK>
+<U8056> /xb8/x74 <CJK>
+<U8058> /xb8/x75 <CJK>
+<U8086> /xb8/x76 <CJK>
+<U8084> /xb8/x77 <CJK>
+<U8171> /xb8/x78 <CJK>
+<U8170> /xb8/x79 <CJK>
+<U8178> /xb8/x7a <CJK>
+<U8165> /xb8/x7b <CJK>
+<U816E> /xb8/x7c <CJK>
+<U8173> /xb8/x7d <CJK>
+<U816B> /xb8/x7e <CJK>
+<U8179> /xb8/xa1 <CJK>
+<U817A> /xb8/xa2 <CJK>
+<U8166> /xb8/xa3 <CJK>
+<U8205> /xb8/xa4 <CJK>
+<U8247> /xb8/xa5 <CJK>
+<U8482> /xb8/xa6 <CJK>
+<U8477> /xb8/xa7 <CJK>
+<U843D> /xb8/xa8 <CJK>
+<U8431> /xb8/xa9 <CJK>
+<U8475> /xb8/xaa <CJK>
+<U8466> /xb8/xab <CJK>
+<U846B> /xb8/xac <CJK>
+<U8449> /xb8/xad <CJK>
+<U846C> /xb8/xae <CJK>
+<U845B> /xb8/xaf <CJK>
+<U843C> /xb8/xb0 <CJK>
+<U8435> /xb8/xb1 <CJK>
+<U8461> /xb8/xb2 <CJK>
+<U8463> /xb8/xb3 <CJK>
+<U8469> /xb8/xb4 <CJK>
+<U846D> /xb8/xb5 <CJK>
+<U8446> /xb8/xb6 <CJK>
+<U865E> /xb8/xb7 <CJK>
+<U865C> /xb8/xb8 <CJK>
+<U865F> /xb8/xb9 <CJK>
+<U86F9> /xb8/xba <CJK>
+<U8713> /xb8/xbb <CJK>
+<U8708> /xb8/xbc <CJK>
+<U8707> /xb8/xbd <CJK>
+<U8700> /xb8/xbe <CJK>
+<U86FE> /xb8/xbf <CJK>
+<U86FB> /xb8/xc0 <CJK>
+<U8702> /xb8/xc1 <CJK>
+<U8703> /xb8/xc2 <CJK>
+<U8706> /xb8/xc3 <CJK>
+<U870A> /xb8/xc4 <CJK>
+<U8859> /xb8/xc5 <CJK>
+<U88DF> /xb8/xc6 <CJK>
+<U88D4> /xb8/xc7 <CJK>
+<U88D9> /xb8/xc8 <CJK>
+<U88DC> /xb8/xc9 <CJK>
+<U88D8> /xb8/xca <CJK>
+<U88DD> /xb8/xcb <CJK>
+<U88E1> /xb8/xcc <CJK>
+<U88CA> /xb8/xcd <CJK>
+<U88D5> /xb8/xce <CJK>
+<U88D2> /xb8/xcf <CJK>
+<U899C> /xb8/xd0 <CJK>
+<U89E3> /xb8/xd1 <CJK>
+<U8A6B> /xb8/xd2 <CJK>
+<U8A72> /xb8/xd3 <CJK>
+<U8A73> /xb8/xd4 <CJK>
+<U8A66> /xb8/xd5 <CJK>
+<U8A69> /xb8/xd6 <CJK>
+<U8A70> /xb8/xd7 <CJK>
+<U8A87> /xb8/xd8 <CJK>
+<U8A7C> /xb8/xd9 <CJK>
+<U8A63> /xb8/xda <CJK>
+<U8AA0> /xb8/xdb <CJK>
+<U8A71> /xb8/xdc <CJK>
+<U8A85> /xb8/xdd <CJK>
+<U8A6D> /xb8/xde <CJK>
+<U8A62> /xb8/xdf <CJK>
+<U8A6E> /xb8/xe0 <CJK>
+<U8A6C> /xb8/xe1 <CJK>
+<U8A79> /xb8/xe2 <CJK>
+<U8A7B> /xb8/xe3 <CJK>
+<U8A3E> /xb8/xe4 <CJK>
+<U8A68> /xb8/xe5 <CJK>
+<U8C62> /xb8/xe6 <CJK>
+<U8C8A> /xb8/xe7 <CJK>
+<U8C89> /xb8/xe8 <CJK>
+<U8CCA> /xb8/xe9 <CJK>
+<U8CC7> /xb8/xea <CJK>
+<U8CC8> /xb8/xeb <CJK>
+<U8CC4> /xb8/xec <CJK>
+<U8CB2> /xb8/xed <CJK>
+<U8CC3> /xb8/xee <CJK>
+<U8CC2> /xb8/xef <CJK>
+<U8CC5> /xb8/xf0 <CJK>
+<U8DE1> /xb8/xf1 <CJK>
+<U8DDF> /xb8/xf2 <CJK>
+<U8DE8> /xb8/xf3 <CJK>
+<U8DEF> /xb8/xf4 <CJK>
+<U8DF3> /xb8/xf5 <CJK>
+<U8DFA> /xb8/xf6 <CJK>
+<U8DEA> /xb8/xf7 <CJK>
+<U8DE4> /xb8/xf8 <CJK>
+<U8DE6> /xb8/xf9 <CJK>
+<U8EB2> /xb8/xfa <CJK>
+<U8F03> /xb8/xfb <CJK>
+<U8F09> /xb8/xfc <CJK>
+<U8EFE> /xb8/xfd <CJK>
+<U8F0A> /xb8/xfe <CJK>
+<U8F9F> /xb9/x40 <CJK>
+<U8FB2> /xb9/x41 <CJK>
+<U904B> /xb9/x42 <CJK>
+<U904A> /xb9/x43 <CJK>
+<U9053> /xb9/x44 <CJK>
+<U9042> /xb9/x45 <CJK>
+<U9054> /xb9/x46 <CJK>
+<U903C> /xb9/x47 <CJK>
+<U9055> /xb9/x48 <CJK>
+<U9050> /xb9/x49 <CJK>
+<U9047> /xb9/x4a <CJK>
+<U904F> /xb9/x4b <CJK>
+<U904E> /xb9/x4c <CJK>
+<U904D> /xb9/x4d <CJK>
+<U9051> /xb9/x4e <CJK>
+<U903E> /xb9/x4f <CJK>
+<U9041> /xb9/x50 <CJK>
+<U9112> /xb9/x51 <CJK>
+<U9117> /xb9/x52 <CJK>
+<U916C> /xb9/x53 <CJK>
+<U916A> /xb9/x54 <CJK>
+<U9169> /xb9/x55 <CJK>
+<U91C9> /xb9/x56 <CJK>
+<U9237> /xb9/x57 <CJK>
+<U9257> /xb9/x58 <CJK>
+<U9238> /xb9/x59 <CJK>
+<U923D> /xb9/x5a <CJK>
+<U9240> /xb9/x5b <CJK>
+<U923E> /xb9/x5c <CJK>
+<U925B> /xb9/x5d <CJK>
+<U924B> /xb9/x5e <CJK>
+<U9264> /xb9/x5f <CJK>
+<U9251> /xb9/x60 <CJK>
+<U9234> /xb9/x61 <CJK>
+<U9249> /xb9/x62 <CJK>
+<U924D> /xb9/x63 <CJK>
+<U9245> /xb9/x64 <CJK>
+<U9239> /xb9/x65 <CJK>
+<U923F> /xb9/x66 <CJK>
+<U925A> /xb9/x67 <CJK>
+<U9598> /xb9/x68 <CJK>
+<U9698> /xb9/x69 <CJK>
+<U9694> /xb9/x6a <CJK>
+<U9695> /xb9/x6b <CJK>
+<U96CD> /xb9/x6c <CJK>
+<U96CB> /xb9/x6d <CJK>
+<U96C9> /xb9/x6e <CJK>
+<U96CA> /xb9/x6f <CJK>
+<U96F7> /xb9/x70 <CJK>
+<U96FB> /xb9/x71 <CJK>
+<U96F9> /xb9/x72 <CJK>
+<U96F6> /xb9/x73 <CJK>
+<U9756> /xb9/x74 <CJK>
+<U9774> /xb9/x75 <CJK>
+<U9776> /xb9/x76 <CJK>
+<U9810> /xb9/x77 <CJK>
+<U9811> /xb9/x78 <CJK>
+<U9813> /xb9/x79 <CJK>
+<U980A> /xb9/x7a <CJK>
+<U9812> /xb9/x7b <CJK>
+<U980C> /xb9/x7c <CJK>
+<U98FC> /xb9/x7d <CJK>
+<U98F4> /xb9/x7e <CJK>
+<U98FD> /xb9/xa1 <CJK>
+<U98FE> /xb9/xa2 <CJK>
+<U99B3> /xb9/xa3 <CJK>
+<U99B1> /xb9/xa4 <CJK>
+<U99B4> /xb9/xa5 <CJK>
+<U9AE1> /xb9/xa6 <CJK>
+<U9CE9> /xb9/xa7 <CJK>
+<U9E82> /xb9/xa8 <CJK>
+<U9F0E> /xb9/xa9 <CJK>
+<U9F13> /xb9/xaa <CJK>
+<U9F20> /xb9/xab <CJK>
+<U50E7> /xb9/xac <CJK>
+<U50EE> /xb9/xad <CJK>
+<U50E5> /xb9/xae <CJK>
+<U50D6> /xb9/xaf <CJK>
+<U50ED> /xb9/xb0 <CJK>
+<U50DA> /xb9/xb1 <CJK>
+<U50D5> /xb9/xb2 <CJK>
+<U50CF> /xb9/xb3 <CJK>
+<U50D1> /xb9/xb4 <CJK>
+<U50F1> /xb9/xb5 <CJK>
+<U50CE> /xb9/xb6 <CJK>
+<U50E9> /xb9/xb7 <CJK>
+<U5162> /xb9/xb8 <CJK>
+<U51F3> /xb9/xb9 <CJK>
+<U5283> /xb9/xba <CJK>
+<U5282> /xb9/xbb <CJK>
+<U5331> /xb9/xbc <CJK>
+<U53AD> /xb9/xbd <CJK>
+<U55FE> /xb9/xbe <CJK>
+<U5600> /xb9/xbf <CJK>
+<U561B> /xb9/xc0 <CJK>
+<U5617> /xb9/xc1 <CJK>
+<U55FD> /xb9/xc2 <CJK>
+<U5614> /xb9/xc3 <CJK>
+<U5606> /xb9/xc4 <CJK>
+<U5609> /xb9/xc5 <CJK>
+<U560D> /xb9/xc6 <CJK>
+<U560E> /xb9/xc7 <CJK>
+<U55F7> /xb9/xc8 <CJK>
+<U5616> /xb9/xc9 <CJK>
+<U561F> /xb9/xca <CJK>
+<U5608> /xb9/xcb <CJK>
+<U5610> /xb9/xcc <CJK>
+<U55F6> /xb9/xcd <CJK>
+<U5718> /xb9/xce <CJK>
+<U5716> /xb9/xcf <CJK>
+<U5875> /xb9/xd0 <CJK>
+<U587E> /xb9/xd1 <CJK>
+<U5883> /xb9/xd2 <CJK>
+<U5893> /xb9/xd3 <CJK>
+<U588A> /xb9/xd4 <CJK>
+<U5879> /xb9/xd5 <CJK>
+<U5885> /xb9/xd6 <CJK>
+<U587D> /xb9/xd7 <CJK>
+<U58FD> /xb9/xd8 <CJK>
+<U5925> /xb9/xd9 <CJK>
+<U5922> /xb9/xda <CJK>
+<U5924> /xb9/xdb <CJK>
+<U596A> /xb9/xdc <CJK>
+<U5969> /xb9/xdd <CJK>
+<U5AE1> /xb9/xde <CJK>
+<U5AE6> /xb9/xdf <CJK>
+<U5AE9> /xb9/xe0 <CJK>
+<U5AD7> /xb9/xe1 <CJK>
+<U5AD6> /xb9/xe2 <CJK>
+<U5AD8> /xb9/xe3 <CJK>
+<U5AE3> /xb9/xe4 <CJK>
+<U5B75> /xb9/xe5 <CJK>
+<U5BDE> /xb9/xe6 <CJK>
+<U5BE7> /xb9/xe7 <CJK>
+<U5BE1> /xb9/xe8 <CJK>
+<U5BE5> /xb9/xe9 <CJK>
+<U5BE6> /xb9/xea <CJK>
+<U5BE8> /xb9/xeb <CJK>
+<U5BE2> /xb9/xec <CJK>
+<U5BE4> /xb9/xed <CJK>
+<U5BDF> /xb9/xee <CJK>
+<U5C0D> /xb9/xef <CJK>
+<U5C62> /xb9/xf0 <CJK>
+<U5D84> /xb9/xf1 <CJK>
+<U5D87> /xb9/xf2 <CJK>
+<U5E5B> /xb9/xf3 <CJK>
+<U5E63> /xb9/xf4 <CJK>
+<U5E55> /xb9/xf5 <CJK>
+<U5E57> /xb9/xf6 <CJK>
+<U5E54> /xb9/xf7 <CJK>
+<U5ED3> /xb9/xf8 <CJK>
+<U5ED6> /xb9/xf9 <CJK>
+<U5F0A> /xb9/xfa <CJK>
+<U5F46> /xb9/xfb <CJK>
+<U5F70> /xb9/xfc <CJK>
+<U5FB9> /xb9/xfd <CJK>
+<U6147> /xb9/xfe <CJK>
+<U613F> /xba/x40 <CJK>
+<U614B> /xba/x41 <CJK>
+<U6177> /xba/x42 <CJK>
+<U6162> /xba/x43 <CJK>
+<U6163> /xba/x44 <CJK>
+<U615F> /xba/x45 <CJK>
+<U615A> /xba/x46 <CJK>
+<U6158> /xba/x47 <CJK>
+<U6175> /xba/x48 <CJK>
+<U622A> /xba/x49 <CJK>
+<U6487> /xba/x4a <CJK>
+<U6458> /xba/x4b <CJK>
+<U6454> /xba/x4c <CJK>
+<U64A4> /xba/x4d <CJK>
+<U6478> /xba/x4e <CJK>
+<U645F> /xba/x4f <CJK>
+<U647A> /xba/x50 <CJK>
+<U6451> /xba/x51 <CJK>
+<U6467> /xba/x52 <CJK>
+<U6434> /xba/x53 <CJK>
+<U646D> /xba/x54 <CJK>
+<U647B> /xba/x55 <CJK>
+<U6572> /xba/x56 <CJK>
+<U65A1> /xba/x57 <CJK>
+<U65D7> /xba/x58 <CJK>
+<U65D6> /xba/x59 <CJK>
+<U66A2> /xba/x5a <CJK>
+<U66A8> /xba/x5b <CJK>
+<U669D> /xba/x5c <CJK>
+<U699C> /xba/x5d <CJK>
+<U69A8> /xba/x5e <CJK>
+<U6995> /xba/x5f <CJK>
+<U69C1> /xba/x60 <CJK>
+<U69AE> /xba/x61 <CJK>
+<U69D3> /xba/x62 <CJK>
+<U69CB> /xba/x63 <CJK>
+<U699B> /xba/x64 <CJK>
+<U69B7> /xba/x65 <CJK>
+<U69BB> /xba/x66 <CJK>
+<U69AB> /xba/x67 <CJK>
+<U69B4> /xba/x68 <CJK>
+<U69D0> /xba/x69 <CJK>
+<U69CD> /xba/x6a <CJK>
+<U69AD> /xba/x6b <CJK>
+<U69CC> /xba/x6c <CJK>
+<U69A6> /xba/x6d <CJK>
+<U69C3> /xba/x6e <CJK>
+<U69A3> /xba/x6f <CJK>
+<U6B49> /xba/x70 <CJK>
+<U6B4C> /xba/x71 <CJK>
+<U6C33> /xba/x72 <CJK>
+<U6F33> /xba/x73 <CJK>
+<U6F14> /xba/x74 <CJK>
+<U6EFE> /xba/x75 <CJK>
+<U6F13> /xba/x76 <CJK>
+<U6EF4> /xba/x77 <CJK>
+<U6F29> /xba/x78 <CJK>
+<U6F3E> /xba/x79 <CJK>
+<U6F20> /xba/x7a <CJK>
+<U6F2C> /xba/x7b <CJK>
+<U6F0F> /xba/x7c <CJK>
+<U6F02> /xba/x7d <CJK>
+<U6F22> /xba/x7e <CJK>
+<U6EFF> /xba/xa1 <CJK>
+<U6EEF> /xba/xa2 <CJK>
+<U6F06> /xba/xa3 <CJK>
+<U6F31> /xba/xa4 <CJK>
+<U6F38> /xba/xa5 <CJK>
+<U6F32> /xba/xa6 <CJK>
+<U6F23> /xba/xa7 <CJK>
+<U6F15> /xba/xa8 <CJK>
+<U6F2B> /xba/xa9 <CJK>
+<U6F2F> /xba/xaa <CJK>
+<U6F88> /xba/xab <CJK>
+<U6F2A> /xba/xac <CJK>
+<U6EEC> /xba/xad <CJK>
+<U6F01> /xba/xae <CJK>
+<U6EF2> /xba/xaf <CJK>
+<U6ECC> /xba/xb0 <CJK>
+<U6EF7> /xba/xb1 <CJK>
+<U7194> /xba/xb2 <CJK>
+<U7199> /xba/xb3 <CJK>
+<U717D> /xba/xb4 <CJK>
+<U718A> /xba/xb5 <CJK>
+<U7184> /xba/xb6 <CJK>
+<U7192> /xba/xb7 <CJK>
+<U723E> /xba/xb8 <CJK>
+<U7292> /xba/xb9 <CJK>
+<U7296> /xba/xba <CJK>
+<U7344> /xba/xbb <CJK>
+<U7350> /xba/xbc <CJK>
+<U7464> /xba/xbd <CJK>
+<U7463> /xba/xbe <CJK>
+<U746A> /xba/xbf <CJK>
+<U7470> /xba/xc0 <CJK>
+<U746D> /xba/xc1 <CJK>
+<U7504> /xba/xc2 <CJK>
+<U7591> /xba/xc3 <CJK>
+<U7627> /xba/xc4 <CJK>
+<U760D> /xba/xc5 <CJK>
+<U760B> /xba/xc6 <CJK>
+<U7609> /xba/xc7 <CJK>
+<U7613> /xba/xc8 <CJK>
+<U76E1> /xba/xc9 <CJK>
+<U76E3> /xba/xca <CJK>
+<U7784> /xba/xcb <CJK>
+<U777D> /xba/xcc <CJK>
+<U777F> /xba/xcd <CJK>
+<U7761> /xba/xce <CJK>
+<U78C1> /xba/xcf <CJK>
+<U789F> /xba/xd0 <CJK>
+<U78A7> /xba/xd1 <CJK>
+<U78B3> /xba/xd2 <CJK>
+<U78A9> /xba/xd3 <CJK>
+<U78A3> /xba/xd4 <CJK>
+<U798E> /xba/xd5 <CJK>
+<U798F> /xba/xd6 <CJK>
+<U798D> /xba/xd7 <CJK>
+<U7A2E> /xba/xd8 <CJK>
+<U7A31> /xba/xd9 <CJK>
+<U7AAA> /xba/xda <CJK>
+<U7AA9> /xba/xdb <CJK>
+<U7AED> /xba/xdc <CJK>
+<U7AEF> /xba/xdd <CJK>
+<U7BA1> /xba/xde <CJK>
+<U7B95> /xba/xdf <CJK>
+<U7B8B> /xba/xe0 <CJK>
+<U7B75> /xba/xe1 <CJK>
+<U7B97> /xba/xe2 <CJK>
+<U7B9D> /xba/xe3 <CJK>
+<U7B94> /xba/xe4 <CJK>
+<U7B8F> /xba/xe5 <CJK>
+<U7BB8> /xba/xe6 <CJK>
+<U7B87> /xba/xe7 <CJK>
+<U7B84> /xba/xe8 <CJK>
+<U7CB9> /xba/xe9 <CJK>
+<U7CBD> /xba/xea <CJK>
+<U7CBE> /xba/xeb <CJK>
+<U7DBB> /xba/xec <CJK>
+<U7DB0> /xba/xed <CJK>
+<U7D9C> /xba/xee <CJK>
+<U7DBD> /xba/xef <CJK>
+<U7DBE> /xba/xf0 <CJK>
+<U7DA0> /xba/xf1 <CJK>
+<U7DCA> /xba/xf2 <CJK>
+<U7DB4> /xba/xf3 <CJK>
+<U7DB2> /xba/xf4 <CJK>
+<U7DB1> /xba/xf5 <CJK>
+<U7DBA> /xba/xf6 <CJK>
+<U7DA2> /xba/xf7 <CJK>
+<U7DBF> /xba/xf8 <CJK>
+<U7DB5> /xba/xf9 <CJK>
+<U7DB8> /xba/xfa <CJK>
+<U7DAD> /xba/xfb <CJK>
+<U7DD2> /xba/xfc <CJK>
+<U7DC7> /xba/xfd <CJK>
+<U7DAC> /xba/xfe <CJK>
+<U7F70> /xbb/x40 <CJK>
+<U7FE0> /xbb/x41 <CJK>
+<U7FE1> /xbb/x42 <CJK>
+<U7FDF> /xbb/x43 <CJK>
+<U805E> /xbb/x44 <CJK>
+<U805A> /xbb/x45 <CJK>
+<U8087> /xbb/x46 <CJK>
+<U8150> /xbb/x47 <CJK>
+<U8180> /xbb/x48 <CJK>
+<U818F> /xbb/x49 <CJK>
+<U8188> /xbb/x4a <CJK>
+<U818A> /xbb/x4b <CJK>
+<U817F> /xbb/x4c <CJK>
+<U8182> /xbb/x4d <CJK>
+<U81E7> /xbb/x4e <CJK>
+<U81FA> /xbb/x4f <CJK>
+<U8207> /xbb/x50 <CJK>
+<U8214> /xbb/x51 <CJK>
+<U821E> /xbb/x52 <CJK>
+<U824B> /xbb/x53 <CJK>
+<U84C9> /xbb/x54 <CJK>
+<U84BF> /xbb/x55 <CJK>
+<U84C6> /xbb/x56 <CJK>
+<U84C4> /xbb/x57 <CJK>
+<U8499> /xbb/x58 <CJK>
+<U849E> /xbb/x59 <CJK>
+<U84B2> /xbb/x5a <CJK>
+<U849C> /xbb/x5b <CJK>
+<U84CB> /xbb/x5c <CJK>
+<U84B8> /xbb/x5d <CJK>
+<U84C0> /xbb/x5e <CJK>
+<U84D3> /xbb/x5f <CJK>
+<U8490> /xbb/x60 <CJK>
+<U84BC> /xbb/x61 <CJK>
+<U84D1> /xbb/x62 <CJK>
+<U84CA> /xbb/x63 <CJK>
+<U873F> /xbb/x64 <CJK>
+<U871C> /xbb/x65 <CJK>
+<U873B> /xbb/x66 <CJK>
+<U8722> /xbb/x67 <CJK>
+<U8725> /xbb/x68 <CJK>
+<U8734> /xbb/x69 <CJK>
+<U8718> /xbb/x6a <CJK>
+<U8755> /xbb/x6b <CJK>
+<U8737> /xbb/x6c <CJK>
+<U8729> /xbb/x6d <CJK>
+<U88F3> /xbb/x6e <CJK>
+<U8902> /xbb/x6f <CJK>
+<U88F4> /xbb/x70 <CJK>
+<U88F9> /xbb/x71 <CJK>
+<U88F8> /xbb/x72 <CJK>
+<U88FD> /xbb/x73 <CJK>
+<U88E8> /xbb/x74 <CJK>
+<U891A> /xbb/x75 <CJK>
+<U88EF> /xbb/x76 <CJK>
+<U8AA6> /xbb/x77 <CJK>
+<U8A8C> /xbb/x78 <CJK>
+<U8A9E> /xbb/x79 <CJK>
+<U8AA3> /xbb/x7a <CJK>
+<U8A8D> /xbb/x7b <CJK>
+<U8AA1> /xbb/x7c <CJK>
+<U8A93> /xbb/x7d <CJK>
+<U8AA4> /xbb/x7e <CJK>
+<U8AAA> /xbb/xa1 <CJK>
+<U8AA5> /xbb/xa2 <CJK>
+<U8AA8> /xbb/xa3 <CJK>
+<U8A98> /xbb/xa4 <CJK>
+<U8A91> /xbb/xa5 <CJK>
+<U8A9A> /xbb/xa6 <CJK>
+<U8AA7> /xbb/xa7 <CJK>
+<U8C6A> /xbb/xa8 <CJK>
+<U8C8D> /xbb/xa9 <CJK>
+<U8C8C> /xbb/xaa <CJK>
+<U8CD3> /xbb/xab <CJK>
+<U8CD1> /xbb/xac <CJK>
+<U8CD2> /xbb/xad <CJK>
+<U8D6B> /xbb/xae <CJK>
+<U8D99> /xbb/xaf <CJK>
+<U8D95> /xbb/xb0 <CJK>
+<U8DFC> /xbb/xb1 <CJK>
+<U8F14> /xbb/xb2 <CJK>
+<U8F12> /xbb/xb3 <CJK>
+<U8F15> /xbb/xb4 <CJK>
+<U8F13> /xbb/xb5 <CJK>
+<U8FA3> /xbb/xb6 <CJK>
+<U9060> /xbb/xb7 <CJK>
+<U9058> /xbb/xb8 <CJK>
+<U905C> /xbb/xb9 <CJK>
+<U9063> /xbb/xba <CJK>
+<U9059> /xbb/xbb <CJK>
+<U905E> /xbb/xbc <CJK>
+<U9062> /xbb/xbd <CJK>
+<U905D> /xbb/xbe <CJK>
+<U905B> /xbb/xbf <CJK>
+<U9119> /xbb/xc0 <CJK>
+<U9118> /xbb/xc1 <CJK>
+<U911E> /xbb/xc2 <CJK>
+<U9175> /xbb/xc3 <CJK>
+<U9178> /xbb/xc4 <CJK>
+<U9177> /xbb/xc5 <CJK>
+<U9174> /xbb/xc6 <CJK>
+<U9278> /xbb/xc7 <CJK>
+<U9280> /xbb/xc8 <CJK>
+<U9285> /xbb/xc9 <CJK>
+<U9298> /xbb/xca <CJK>
+<U9296> /xbb/xcb <CJK>
+<U927B> /xbb/xcc <CJK>
+<U9293> /xbb/xcd <CJK>
+<U929C> /xbb/xce <CJK>
+<U92A8> /xbb/xcf <CJK>
+<U927C> /xbb/xd0 <CJK>
+<U9291> /xbb/xd1 <CJK>
+<U95A1> /xbb/xd2 <CJK>
+<U95A8> /xbb/xd3 <CJK>
+<U95A9> /xbb/xd4 <CJK>
+<U95A3> /xbb/xd5 <CJK>
+<U95A5> /xbb/xd6 <CJK>
+<U95A4> /xbb/xd7 <CJK>
+<U9699> /xbb/xd8 <CJK>
+<U969C> /xbb/xd9 <CJK>
+<U969B> /xbb/xda <CJK>
+<U96CC> /xbb/xdb <CJK>
+<U96D2> /xbb/xdc <CJK>
+<U9700> /xbb/xdd <CJK>
+<U977C> /xbb/xde <CJK>
+<U9785> /xbb/xdf <CJK>
+<U97F6> /xbb/xe0 <CJK>
+<U9817> /xbb/xe1 <CJK>
+<U9818> /xbb/xe2 <CJK>
+<U98AF> /xbb/xe3 <CJK>
+<U98B1> /xbb/xe4 <CJK>
+<U9903> /xbb/xe5 <CJK>
+<U9905> /xbb/xe6 <CJK>
+<U990C> /xbb/xe7 <CJK>
+<U9909> /xbb/xe8 <CJK>
+<U99C1> /xbb/xe9 <CJK>
+<U9AAF> /xbb/xea <CJK>
+<U9AB0> /xbb/xeb <CJK>
+<U9AE6> /xbb/xec <CJK>
+<U9B41> /xbb/xed <CJK>
+<U9B42> /xbb/xee <CJK>
+<U9CF4> /xbb/xef <CJK>
+<U9CF6> /xbb/xf0 <CJK>
+<U9CF3> /xbb/xf1 <CJK>
+<U9EBC> /xbb/xf2 <CJK>
+<U9F3B> /xbb/xf3 <CJK>
+<U9F4A> /xbb/xf4 <CJK>
+<U5104> /xbb/xf5 <CJK>
+<U5100> /xbb/xf6 <CJK>
+<U50FB> /xbb/xf7 <CJK>
+<U50F5> /xbb/xf8 <CJK>
+<U50F9> /xbb/xf9 <CJK>
+<U5102> /xbb/xfa <CJK>
+<U5108> /xbb/xfb <CJK>
+<U5109> /xbb/xfc <CJK>
+<U5105> /xbb/xfd <CJK>
+<U51DC> /xbb/xfe <CJK>
+<U5287> /xbc/x40 <CJK>
+<U5288> /xbc/x41 <CJK>
+<U5289> /xbc/x42 <CJK>
+<U528D> /xbc/x43 <CJK>
+<U528A> /xbc/x44 <CJK>
+<U52F0> /xbc/x45 <CJK>
+<U53B2> /xbc/x46 <CJK>
+<U562E> /xbc/x47 <CJK>
+<U563B> /xbc/x48 <CJK>
+<U5639> /xbc/x49 <CJK>
+<U5632> /xbc/x4a <CJK>
+<U563F> /xbc/x4b <CJK>
+<U5634> /xbc/x4c <CJK>
+<U5629> /xbc/x4d <CJK>
+<U5653> /xbc/x4e <CJK>
+<U564E> /xbc/x4f <CJK>
+<U5657> /xbc/x50 <CJK>
+<U5674> /xbc/x51 <CJK>
+<U5636> /xbc/x52 <CJK>
+<U562F> /xbc/x53 <CJK>
+<U5630> /xbc/x54 <CJK>
+<U5880> /xbc/x55 <CJK>
+<U589F> /xbc/x56 <CJK>
+<U589E> /xbc/x57 <CJK>
+<U58B3> /xbc/x58 <CJK>
+<U589C> /xbc/x59 <CJK>
+<U58AE> /xbc/x5a <CJK>
+<U58A9> /xbc/x5b <CJK>
+<U58A6> /xbc/x5c <CJK>
+<U596D> /xbc/x5d <CJK>
+<U5B09> /xbc/x5e <CJK>
+<U5AFB> /xbc/x5f <CJK>
+<U5B0B> /xbc/x60 <CJK>
+<U5AF5> /xbc/x61 <CJK>
+<U5B0C&g