52 files changed, 27146 insertions, 2526 deletions
diff --git a/qmake/CHANGES b/qmake/CHANGES index 995c16e..ca786ee 100644 --- a/qmake/CHANGES +++ b/qmake/CHANGES @@ -1 +1,29 @@ +1.07a - + + support for precompiled headers added + +1.06b - + + support for reading and writing libtool (.la) files + support for reading pkgconfig (.pkg) files + + PWD added as an automatic variable to mean the directory + the file being parsed is in (this change required that the + directory be set to the file being parsed as well, function + tests that query relative paths will need to be relative the + file being parsed). + + persistant data cache introduced + +1.05a - + + caching of more information (speed ups) + $$list() added to be used as a lambda function in qmake + $$files() added to allow regular expression matching + $$fromfile() added to grab one single variable value from a parsed file + $$prompt() added to allow querying for user input from qmake + include() modified to support specifying which variables to import + equals() test added to test for equality + MSVC.net generator added [partial solution files in vcsubdirs] + 1.04a - @@ -10,3 +38,3 @@ - Dependancy / Mocable caching. qmake can cache these expensive operations with qmake_cache + Dependency / Mocable caching. qmake can cache these expensive operations with qmake_cache CONFIG. @@ -23,3 +51,3 @@ - 1) libtool like library dependancies to static libraries build with qmake + 1) libtool like library dependencies to static libraries build with qmake 2) library dependencies, when on .pro depends on another library - it will diff --git a/qmake/Makefile b/qmake/Makefile index 01bb1a1..5a72210 100644 --- a/qmake/Makefile +++ b/qmake/Makefile @@ -2,5 +2,2 @@ QMAKESPECSDIR=$(OPIEDIR)/mkspecs -######################################################################## -## This file was autogenerated by configure, all changes will be lost ## -######################################################################## CC = gcc @@ -9,5 +6,6 @@ CXX = g++ #qmake code -OBJS=project.o main.o makefile.o unixmake2.o unixmake.o borland_bmake.o \ - mingw_make.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o option.o winmakefile.o \ - projectgenerator.o metrowerks_xml.o pbuilder_pbx.o msvc_objectmodel.o +OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o msvc_nmake.o \ + borland_bmake.o mingw_make.o msvc_dsp.o msvc_vcproj.o option.o \ + winmakefile.o projectgenerator.o metrowerks_xml.o pbuilder_pbx.o \ + msvc_objectmodel.o meta.o qtmd5.o @@ -18,10 +16,30 @@ QOBJS=qstring.o qtextstream.o qiodevice.o qglobal.o qgdict.o qcstring.o \ qfileinfo_unix.o qdir_unix.o qfileinfo.o qdatetime.o qstringlist.o qmap.o \ - qconfig.o - -CFLAGS= \ + qconfig.o qunicodetables.o qsettings.o qlocale.o + +#all sources, used for the depend target +DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp qtmd5.cpp generators/makefile.cpp generators/unix/unixmake2.cpp \ + generators/unix/unixmake.cpp generators/win32/msvc_nmake.cpp generators/win32/borland_bmake.cpp \ + generators/win32/winmakefile.cpp generators/projectgenerator.cpp generators/mac/metrowerks_xml.cpp \ + generators/mac/pbuilder_pbx.cpp generators/win32/msvc_objectmodel.cpp \ + $(OPIEDIR)/qmake/tools/qstring.cpp $(OPIEDIR)/qmake/tools/qtextstream.cpp \ + $(OPIEDIR)/qmake/tools/qiodevice.cpp $(OPIEDIR)/qmake/tools/qglobal.cpp \ + $(OPIEDIR)/qmake/tools/qgdict.cpp $(OPIEDIR)/qmake/tools/qcstring.cpp \ + $(OPIEDIR)/qmake/tools/qdatastream.cpp $(OPIEDIR)/qmake/src/tools/qgarray.cpp \ + $(OPIEDIR)/qmake/tools/qbuffer.cpp $(OPIEDIR)/qmake/tools/qglist.cpp \ + $(OPIEDIR)/qmake/tools/qptrcollection.cpp $(OPIEDIR)/qmake/tools/qfile.cpp \ + $(OPIEDIR)/qmake/tools/qfile_unix.cpp $(OPIEDIR)/qmake/tools/qregexp.cpp \ + $(OPIEDIR)/qmake/tools/qgvector.cpp $(OPIEDIR)/qmake/tools/qgcache.cpp \ + $(OPIEDIR)/qmake/tools/qbitarray.cpp $(OPIEDIR)/qmake/tools/qdir.cpp \ + $(OPIEDIR)/qmake/tools/quuid.cpp $(OPIEDIR)/qmake/tools/qfileinfo_unix.cpp \ + $(OPIEDIR)/qmake/tools/qdir_unix.cpp $(OPIEDIR)/qmake/tools/qfileinfo.cpp \ + $(OPIEDIR)/qmake/tools/qdatetime.cpp $(OPIEDIR)/qmake/tools/qstringlist.cpp \ + $(OPIEDIR)/qmake/tools/qmap.cpp $(OPIEDIR)/qmake/tools/qconfig.cpp \ + $(OPIEDIR)/qmake/tools/qsettings.cpp $(OPIEDIR)/qmake/tools/qurl.cpp \ + $(OPIEDIR)/qmake/tools/qsettings_mac.cpp $(OPIEDIR)/qmake/tools/qlocale.cpp + +CXXFLAGS= \ -I. -Igenerators -Igenerators/unix -Igenerators/win32 -Igenerators/mac \ - -I$(OPIEDIR)/qmake/include -I$(OPIEDIR)/qmake/include/qmake -I$(QMAKESPECSDIR)/default \ - -I$(OPIEDIR)/qmake/include/private \ - -DQT_NO_TEXTCODEC -DQT_LITE_COMPONENT -DQT_NO_STL -DQT_NO_COMPRESS -CXXFLAGS= $(CFLAGS) + -I$(OPIEDIR)/qmake/include/qmake -I$(OPIEDIR)/qmake/include -I$(OPIEDIR)/qmake/include/private \ + -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_STL \ + -DQT_NO_COMPRESS -I$(QMAKESPECSDIR)/default -DHAVE_QCONFIG_CPP LFLAGS= @@ -45,2 +63,3 @@ distclean:: clean + # don't use optimization for these @@ -61,2 +80,11 @@ qcstring.o: $(OPIEDIR)/qmake/tools/qcstring.cpp +qsettings.o: $(OPIEDIR)/qmake/tools/qsettings.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qsettings.cpp + +qsettings_mac.o: $(OPIEDIR)/qmake/tools/qsettings_mac.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qsettings_mac.cpp + +qurl.o: $(OPIEDIR)/qmake/kernel/qurl.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/kernel/qurl.cpp + qstring.o: $(OPIEDIR)/qmake/tools/qstring.cpp @@ -64,2 +92,5 @@ qstring.o: $(OPIEDIR)/qmake/tools/qstring.cpp +qlocale.o: $(OPIEDIR)/qmake/tools/qlocale.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qlocale.cpp + qdatastream.o: $(OPIEDIR)/qmake/tools/qdatastream.cpp @@ -67,2 +98,5 @@ qdatastream.o: $(OPIEDIR)/qmake/tools/qdatastream.cpp +qunicodetables.o: $(OPIEDIR)/qmake/tools/qunicodetables.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qunicodetables.cpp + qgarray.o: $(OPIEDIR)/qmake/tools/qgarray.cpp @@ -130,2 +164,8 @@ project.o: project.cpp project.h option.h +property.o: property.cpp project.h option.h + $(CXX) -c -o $@ $(CXXFLAGS) property.cpp + +meta.o: meta.cpp project.h option.h + $(CXX) -c -o $@ $(CXXFLAGS) meta.cpp + main.o: main.cpp project.h @@ -136,2 +176,5 @@ option.o: option.cpp option.h +qtmd5.o: qtmd5.cpp + $(CXX) -c -o $@ $(CXXFLAGS) qtmd5.cpp + makefile.o: generators/makefile.cpp @@ -173,6 +216,5 @@ projectgenerator.o: generators/projectgenerator.cpp #default rules -.c.o: - $(CC) -c -o $@ $(CFLAGS) $< - .cpp.o: $(CXX) -c -o $@ $(CXXFLAGS) $< + +# DO NOT DELETE THIS LINE -- make depend depends on it diff --git a/qmake/generators/mac/metrowerks_xml.cpp b/qmake/generators/mac/metrowerks_xml.cpp index 125749d..baaeeec 100644 --- a/qmake/generators/mac/metrowerks_xml.cpp +++ b/qmake/generators/mac/metrowerks_xml.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of MetrowerksMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -44,3 +42,3 @@ #include <time.h> -#ifdef Q_OS_MAC +#if !defined(QWS) && defined(Q_OS_MAC) #include <Carbon/Carbon.h> @@ -50,3 +48,2 @@ - MetrowerksMakefileGenerator::MetrowerksMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE) @@ -609,3 +606,3 @@ MetrowerksMakefileGenerator::init() QString -MetrowerksMakefileGenerator::findTemplate(QString file) +MetrowerksMakefileGenerator::findTemplate(const QString &file) { @@ -623,3 +620,3 @@ MetrowerksMakefileGenerator::createFork(const QString &f) { -#if defined(Q_OS_MACX) +#if !defined(QWS) && defined(Q_OS_MACX) FSRef fref; @@ -666,3 +663,3 @@ MetrowerksMakefileGenerator::fixifyToMacPath(QString &p, QString &v, bool ) st_volume = var("QMAKE_VOLUMENAME"); -#ifdef Q_OS_MAC +#if !defined(QWS) && defined(Q_OS_MACX) if(st_volume.isEmpty()) { @@ -735,3 +732,3 @@ MetrowerksMakefileGenerator::processPrlFiles() for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { - prl = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::prl_ext; + prl = mdd->local_dir + Option::dir_sep + "lib" + lib; if(processPrlFile(prl)) { @@ -753,3 +750,3 @@ MetrowerksMakefileGenerator::processPrlFiles() QString prl = "/System/Library/Frameworks/" + opt + - ".framework/" + opt + Option::prl_ext; + ".framework/" + opt; if(processPrlFile(prl)) diff --git a/qmake/generators/mac/metrowerks_xml.h b/qmake/generators/mac/metrowerks_xml.h index ae3cfae..0aa3615 100644 --- a/qmake/generators/mac/metrowerks_xml.h +++ b/qmake/generators/mac/metrowerks_xml.h @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of MetrowerksMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -36,4 +34,5 @@ **********************************************************************/ -#ifndef __METROWERKSMAKE_H__ -#define __METROWERKSMAKE_H__ + +#ifndef __METROWERKS_XML_H__ +#define __METROWERKS_XML_H__ @@ -52,3 +51,3 @@ class MetrowerksMakefileGenerator : public MakefileGenerator bool writeMakefile(QTextStream &); - QString findTemplate(QString file); + QString findTemplate(const QString &file); void init(); @@ -68,2 +67,2 @@ inline MetrowerksMakefileGenerator::~MetrowerksMakefileGenerator() -#endif /* __METROWERKSMAKE_H__ */ +#endif /* __METROWERKS_XML_H__ */ diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index b46005b..9d1286e 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of ProjectBuilderMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -39,2 +37,3 @@ #include "option.h" +#include "meta.h" #include <qdir.h> @@ -44,2 +43,3 @@ #include <time.h> +#include "qtmd5.h" #ifdef Q_OS_UNIX @@ -51,3 +51,2 @@ - ProjectBuilderMakefileGenerator::ProjectBuilderMakefileGenerator(QMakeProject *p) : UnixMakefileGenerator(p) @@ -69,8 +68,6 @@ ProjectBuilderMakefileGenerator::writeMakefile(QTextStream &t) project->variables()["MAKEFILE"].append("Makefile"); - if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") { + if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") return writeMakeParts(t); - } else if(project->first("TEMPLATE") == "subdirs") { - writeSubdirs(t, FALSE); - return TRUE; - } + else if(project->first("TEMPLATE") == "subdirs") + return writeSubdirs(t, FALSE); return FALSE; @@ -79,2 +76,198 @@ ProjectBuilderMakefileGenerator::writeMakefile(QTextStream &t) bool +ProjectBuilderMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) +{ + QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"), + QDir::currentDirPath()); + QFile mkwrapf(mkwrap); + if(mkwrapf.open(IO_WriteOnly | IO_Translate)) { + debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1()); + QTextStream mkwrapt(&mkwrapf); + UnixMakefileGenerator::writeSubdirs(mkwrapt, direct); + } + + //HEADER + t << "// !$*UTF8*$!" << "\n" + << "{" << "\n" + << "\t" << "archiveVersion = 1;" << "\n" + << "\t" << "classes = {" << "\n" << "\t" << "};" << "\n" + << "\t" << "objectVersion = " << pbuilderVersion() << ";" << "\n" + << "\t" << "objects = {" << endl; + + //SUBDIRS + QStringList subdirs = project->variables()["SUBDIRS"]; + QString oldpwd = QDir::currentDirPath(); + QMap<QString, QStringList> groups; + for(QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it) { + QFileInfo fi(Option::fixPathToLocalOS((*it), TRUE)); + if(fi.exists()) { + if(fi.isDir()) { + QString profile = (*it); + if(!profile.endsWith(Option::dir_sep)) + profile += Option::dir_sep; + profile += fi.baseName() + ".pro"; + subdirs.append(profile); + } else { + QMakeProject tmp_proj; + QString dir = fi.dirPath(), fn = fi.fileName(); + if(!dir.isEmpty()) { + if(!QDir::setCurrent(dir)) + fprintf(stderr, "Cannot find directory: %s\n", dir.latin1()); + } + if(tmp_proj.read(fn, oldpwd)) { + if(Option::debug_level) { + QMap<QString, QStringList> &vars = tmp_proj.variables(); + for(QMap<QString, QStringList>::Iterator it = vars.begin(); + it != vars.end(); ++it) { + if(it.key().left(1) != "." && !it.data().isEmpty()) + debug_msg(1, "%s: %s === %s", fn.latin1(), it.key().latin1(), + it.data().join(" :: ").latin1()); + } + } + if(tmp_proj.first("TEMPLATE") == "subdirs") { + subdirs += fileFixify(tmp_proj.variables()["SUBDIRS"]); + } else if(tmp_proj.first("TEMPLATE") == "app" || tmp_proj.first("TEMPLATE") == "lib") { + QString pbxproj = QDir::currentDirPath() + Option::dir_sep + tmp_proj.first("TARGET") + projectSuffix(); + if(!QFile::exists(pbxproj)) { + warn_msg(WarnLogic, "Ignored (not found) '%s'", pbxproj.latin1()); + goto nextfile; // # Dirty! + } + project->variables()["QMAKE_PBX_SUBDIRS"] += pbxproj; + //PROJECTREF + { + bool in_root = TRUE; + QString name = QDir::currentDirPath(); + QString project_key = keyFor(pbxproj + "_PROJECTREF"); + if(project->isActiveConfig("flat")) { + QString flat_file = fileFixify(name, oldpwd, Option::output_dir, TRUE); + if(flat_file.find(Option::dir_sep) != -1) { + QStringList dirs = QStringList::split(Option::dir_sep, flat_file); + name = dirs.back(); + } + } else { + QString flat_file = fileFixify(name, oldpwd, Option::output_dir, TRUE); + if(QDir::isRelativePath(flat_file) && flat_file.find(Option::dir_sep) != -1) { + QString last_grp("QMAKE_PBX_HEIR_GROUP"); + QStringList dirs = QStringList::split(Option::dir_sep, flat_file); + name = dirs.back(); + for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { + QString new_grp(last_grp + Option::dir_sep + (*dir_it)), new_grp_key(keyFor(new_grp)); + if(dir_it == dirs.begin()) { + if(!groups.contains(new_grp)) + project->variables()["QMAKE_PBX_GROUPS"].append(new_grp_key); + } else { + if(!groups[last_grp].contains(new_grp_key)) + groups[last_grp] += new_grp_key; + } + last_grp = new_grp; + } + groups[last_grp] += project_key; + in_root = FALSE; + } + } + if(in_root) + project->variables()["QMAKE_PBX_GROUPS"] += project_key; + t << "\t\t" << project_key << " = {" << "\n" + << "\t\t\t" << "isa = PBXFileReference;" << "\n" + << "\t\t\t" << "name = " << tmp_proj.first("TARGET") << ";" << "\n" + << "\t\t\t" << "path = " << pbxproj << ";" << "\n" + << "\t\t\t" << "refType = 0;" << "\n" + << "\t\t\t" << "sourceTree = \"<absolute>\";" << "\n" + << "\t\t" << "};" << "\n"; + //PRODUCTGROUP + t << "\t\t" << keyFor(pbxproj + "_PRODUCTGROUP") << " = {" << "\n" + << "\t\t\t" << "children = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXGroup;" << "\n" + << "\t\t\t" << "name = Products;" << "\n" + << "\t\t\t" << "refType = 4;" << "\n" + << "\t\t\t" << "sourceTree = \"<group>\";" << "\n" + << "\t\t" << "};" << "\n"; + } + } + } +nextfile: + QDir::setCurrent(oldpwd); + } + } + } + for(QMap<QString, QStringList>::Iterator grp_it = groups.begin(); grp_it != groups.end(); ++grp_it) { + t << "\t\t" << keyFor(grp_it.key()) << " = {" << "\n" + << "\t\t\t" << "isa = PBXGroup;" << "\n" + << "\t\t\t" << "children = (" << "\n" + << valGlue(grp_it.data(), "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "name = \"" << grp_it.key().section(Option::dir_sep, -1) << "\";" << "\n" + << "\t\t\t" << "refType = 4;" << "\n" + << "\t\t" << "};" << "\n"; + } + + //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER + //BUILDSTYLE + QString active_buildstyle; +#if 0 + for(int as_release = 0; as_release < 2; as_release++) +#else + bool as_release = !project->isActiveConfig("debug"); +#endif + { + QString key = keyFor("QMAKE_PBX_" + QString(as_release ? "RELEASE" : "DEBUG")); + if(project->isActiveConfig("debug") != as_release) + active_buildstyle = key; + project->variables()["QMAKE_PBX_BUILDSTYLES"].append(key); + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << "buildRules = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n" + << "\t\t\t\t" << "COPY_PHASE_STRIP = " << (as_release ? "YES" : "NO") << ";" << "\n"; + if(as_release) + t << "\t\t\t\t" << "DEBUGGING_SYMBOLS = NO;" << "\n"; + t << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "isa = PBXBuildStyle;" << "\n" + << "\t\t\t" << "name = " << (as_release ? "Deployment" : "Development") << ";" << "\n" + << "\t\t" << "};" << "\n"; + } + + //ROOT_GROUP + t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {" << "\n" + << "\t\t\t" << "children = (" << "\n" + << varGlue("QMAKE_PBX_GROUPS", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXGroup;" << "\n" + << "\t\t\t" << "refType = 4;" << "\n" + << "\t\t\t" << "sourceTree = \"<group>\";" << "\n" + << "\t\t" << "};" << "\n"; + + //ROOT + t << "\t\t" << keyFor("QMAKE_PBX_ROOT") << " = {" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n" + << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "buildStyles = (" << "\n" + << varGlue("QMAKE_PBX_BUILDSTYLES", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXProject;" << "\n" + << "\t\t\t" << "mainGroup = " << keyFor("QMAKE_PBX_ROOT_GROUP") << ";" << "\n" + << "\t\t\t" << "projectDirPath = \"\";" << "\n" + << "\t\t\t" << "projectReferences = (" << "\n"; + { + QStringList &libdirs = project->variables()["QMAKE_PBX_SUBDIRS"]; + for(QStringList::Iterator it = libdirs.begin(); it != libdirs.end(); ++it) + t << "\t\t\t\t" << "{" << "\n" + << "\t\t\t\t\t" << "ProductGroup = " << keyFor((*it) + "_PRODUCTGROUP") << ";" << "\n" + << "\t\t\t\t\t" << "ProjectRef = " << keyFor((*it) + "_PROJECTREF") << ";" << "\n" + << "\t\t\t\t" << "}," << "\n"; + } + t << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "targets = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t" << "};" << "\n"; + + //FOOTER + t << "\t" << "};" << "\n" + << "\t" << "rootObject = " << keyFor("QMAKE_PBX_ROOT") << ";" << "\n" + << "}" << endl; + + return TRUE; +} + +bool ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) @@ -109,3 +302,3 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) mkfile = fileFixify(mkfile, QDir::currentDirPath()); - project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key); + project->variables()["QMAKE_PBX_PRESCRIPT_BUILDPHASES"].append(phase_key); t << "\t\t" << phase_key << " = {" << "\n" @@ -128,56 +321,114 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QMap<QString, QStringList> groups; - QString srcs[] = { "SOURCES", "SRCMOC", "UICIMPLS", QString::null }; + QString srcs[] = { "HEADERS", "SOURCES", "SRCMOC", "UICIMPLS", "QMAKE_IMAGE_COLLECTION", + "FORMS", "QMAKE_INTERNAL_INCLUDED_FILES", QString::null }; for(i = 0; !srcs[i].isNull(); i++) { tmp = project->variables()[srcs[i]]; + if(srcs[i] == "QMAKE_INTERNAL_INCLUDED_FILES") { + QString pfile = project->projectFile(); + if(pfile != "(stdin)") + tmp.prepend(pfile); + } QStringList &src_list = project->variables()["QMAKE_PBX_" + srcs[i]]; + QStringList &root_group_list = project->variables()["QMAKE_PBX_GROUPS"]; + + //hard coded groups.. + QString src_group; + if(srcs[i] == "SOURCES") + src_group = "Sources"; + else if(srcs[i] == "HEADERS") + src_group = "Headers"; + else if(srcs[i] == "SRCMOC") + src_group = "Sources [moc]"; + else if(srcs[i] == "UICIMPLS" || srcs[i] == "FORMS") + src_group = "Sources [uic]"; + else if(srcs[i] == "QMAKE_IMAGE_COLLECTION") + src_group = "Sources [images]"; + else if(srcs[i] == "QMAKE_INTERNAL_INCLUDED_FILES") + src_group = "Sources [qmake]"; + for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) { - QString file = fileFixify((*it)); - if(file.endsWith(Option::moc_ext)) - continue; - bool in_root = TRUE; - QString src_key = keyFor(file); - if(!project->isActiveConfig("flat")) { - QString flat_file = fileFixify(file, QDir::currentDirPath(), Option::output_dir, TRUE); - if(QDir::isRelativePath(flat_file) && flat_file.find(Option::dir_sep) != -1) { - QString last_grp("QMAKE_PBX_" + srcs[i] + "_HEIR_GROUP"); - QStringList dirs = QStringList::split(Option::dir_sep, flat_file); - dirs.pop_back(); //remove the file portion as it will be added via src_key - for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { - QString new_grp(last_grp + Option::dir_sep + (*dir_it)), - new_grp_key(keyFor(new_grp)), last_grp_key(keyFor(last_grp)); - if(dir_it == dirs.begin()) { - if(!groups.contains(new_grp)) - project->variables()["QMAKE_PBX_" + srcs[i]].append(new_grp_key); - } else { - groups[last_grp] += new_grp_key; + QStringList files = (*it); + bool buildable = TRUE; + if(srcs[i] == "FORMS") { + QString form_dot_h = (*it) + Option::h_ext.first(); + if(QFile::exists(form_dot_h)) + files += form_dot_h; + buildable = FALSE; + } else if(srcs[i] == "HEADERS" || srcs[i] == "QMAKE_INTERNAL_INCLUDED_FILES") { + buildable = FALSE; + } + + files = fileFixify(files); + for(QStringList::Iterator file_it = files.begin(); file_it != files.end(); ++file_it) { + QString file = (*file_it); + if(file.length() >= 2 && (file[0] == '"' || file[0] == '\'') && file[(int) file.length()-1] == file[0]) + file = file.mid(1, file.length()-2); + if(file.endsWith(Option::cpp_moc_ext) || file.endsWith(Option::prl_ext)) + continue; + bool in_root = TRUE; + QString src_key = keyFor(file), name = file; + if(project->isActiveConfig("flat")) { + QString flat_file = fileFixify(file, QDir::currentDirPath(), Option::output_dir, TRUE); + if(flat_file.find(Option::dir_sep) != -1) { + QStringList dirs = QStringList::split(Option::dir_sep, flat_file); + name = dirs.back(); + } + } else { + QString flat_file = fileFixify(file, QDir::currentDirPath(), Option::output_dir, TRUE); + if(QDir::isRelativePath(flat_file) && flat_file.find(Option::dir_sep) != -1) { + QString last_grp("QMAKE_PBX_" + src_group + "_HEIR_GROUP"); + QStringList dirs = QStringList::split(Option::dir_sep, flat_file); + name = dirs.back(); + dirs.pop_back(); //remove the file portion as it will be added via src_key + for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { + QString new_grp(last_grp + Option::dir_sep + (*dir_it)), new_grp_key(keyFor(new_grp)); + if(dir_it == dirs.begin()) { + if(!src_list.contains(new_grp_key)) + src_list.append(new_grp_key); + } else { + if(!groups[last_grp].contains(new_grp_key)) + groups[last_grp] += new_grp_key; + } + last_grp = new_grp; + } + groups[last_grp] += src_key; + in_root = FALSE; + } + } + if(in_root) + src_list.append(src_key); + //source reference + t << "\t\t" << src_key << " = {" << "\n" + << "\t\t\t" << "isa = PBXFileReference;" << "\n" + << "\t\t\t" << "name = \"" << name << "\";" << "\n" + << "\t\t\t" << "path = \"" << file << "\";" << "\n" + << "\t\t\t" << "refType = " << reftypeForFile(file) << ";" << "\n"; + if (ideType() == MAC_XCODE) { + QString filetype; + for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { + if(file.endsWith((*cppit))) { + filetype = "sourcecode.cpp.cpp"; + break; } - last_grp = new_grp; } - groups[last_grp] += src_key; - in_root = FALSE; + if(!filetype.isNull()) + t << "\t\t\t" << "lastKnownFileType = " << filetype << ";" << "\n"; + } + t << "\t\t" << "};" << "\n"; + if(buildable) { //build reference + QString obj_key = file + ".o"; + obj_key = keyFor(obj_key); + t << "\t\t" << obj_key << " = {" << "\n" + << "\t\t\t" << "fileRef = " << src_key << ";" << "\n" + << "\t\t\t" << "isa = PBXBuildFile;" << "\n" + << "\t\t\t" << "settings = {" << "\n" + << "\t\t\t\t" << "ATTRIBUTES = (" << "\n" + << "\t\t\t\t" << ");" << "\n" + << "\t\t\t" << "};" << "\n" + << "\t\t" << "};" << "\n"; + project->variables()["QMAKE_PBX_OBJ"].append(obj_key); } } - if(in_root) - src_list.append(src_key); - //source reference - t << "\t\t" << src_key << " = {" << "\n" - << "\t\t\t" << "isa = PBXFileReference;" << "\n" - << "\t\t\t" << "path = \"" << file << "\";" << "\n" - << "\t\t\t" << "refType = " << reftypeForFile(file) << ";" << "\n" - << "\t\t" << "};" << "\n"; - //build reference - QString obj_key = file + ".o"; - obj_key = keyFor(obj_key); - t << "\t\t" << obj_key << " = {" << "\n" - << "\t\t\t" << "fileRef = " << src_key << ";" << "\n" - << "\t\t\t" << "isa = PBXBuildFile;" << "\n" - << "\t\t\t" << "settings = {" << "\n" - << "\t\t\t\t" << "ATTRIBUTES = (" << "\n" - << "\t\t\t\t" << ");" << "\n" - << "\t\t\t" << "};" << "\n" - << "\t\t" << "};" << "\n"; - project->variables()["QMAKE_PBX_OBJ"].append(obj_key); } if(!src_list.isEmpty()) { - QString grp; if(srcs[i] == "SOURCES") { @@ -198,22 +449,11 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } - grp = "Sources"; - } else if(srcs[i] == "SRCMOC") { - grp = "Mocables"; - } else if(srcs[i] == "UICIMPLS") { - grp = "UICables"; } - QString grp_key = keyFor(grp); - project->variables()["QMAKE_PBX_GROUPS"].append(grp_key); - t << "\t\t" << grp_key << " = {" << "\n" - << "\t\t\t" << "children = (" << "\n" - << varGlue("QMAKE_PBX_" + srcs[i], "\t\t\t\t", ",\n\t\t\t\t", "\n") - << "\t\t\t" << ");" << "\n" - << "\t\t\t" << "isa = PBXGroup;" << "\n" - << "\t\t\t" << "name = " << grp << ";" << "\n" - << "\t\t\t" << "refType = 4;" << "\n" - << "\t\t" << "};" << "\n"; + + QString src_group_key = keyFor(src_group); + if(root_group_list.findIndex(src_group_key) == -1) + root_group_list += src_group_key; + groups[src_group] += src_list; } } - for(QMap<QString, QStringList>::Iterator grp_it = groups.begin(); - grp_it != groups.end(); ++grp_it) { + for(QMap<QString, QStringList>::Iterator grp_it = groups.begin(); grp_it != groups.end(); ++grp_it) { t << "\t\t" << keyFor(grp_it.key()) << " = {" << "\n" @@ -238,4 +478,4 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) writeHeader(mkt); - mkt << "MOC = " << var("QMAKE_MOC") << endl; - mkt << "UIC = " << var("QMAKE_UIC") << endl; + mkt << "MOC = " << Option::fixPathToTargetOS(var("QMAKE_MOC")) << endl; + mkt << "UIC = " << Option::fixPathToTargetOS(var("QMAKE_UIC")) << endl; mkt << "LEX = " << var("QMAKE_LEX") << endl; @@ -247,2 +487,3 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) mkt << "FORMS = " << varList("UICIMPLS") << endl; + mkt << "IMAGES = " << varList("QMAKE_IMAGE_COLLECTION") << endl; mkt << "MOCS = " << varList("SRCMOC") << endl; @@ -266,4 +507,4 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) mkt << "\n"; - mkt << "preprocess: $(FORMS) $(MOCS) $(PARSERS)" << endl; - mkt << "preprocess_clean: mocclean uiclean parser_clean" << endl << endl; + mkt << "preprocess: $(FORMS) $(MOCS) $(PARSERS) $(IMAGES)" << endl; + mkt << "clean preprocess_clean: mocclean uiclean parser_clean" << endl << endl; mkt << "mocclean:" << "\n"; @@ -274,2 +515,4 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) mkt << "\t-rm -f $(FORMS)" << "\n"; + if(!project->isEmpty("QMAKE_IMAGE_COLLECTION")) + mkt << "\t-rm -f $(IMAGES)" << "\n"; mkt << "parser_clean:" << "\n"; @@ -283,32 +526,27 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) writeLexSrc(mkt, "LEXSOURCES"); + writeImageSrc(mkt, "QMAKE_IMAGE_COLLECTION"); mkf.close(); } - QString target_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET"); mkfile = fileFixify(mkfile, QDir::currentDirPath()); - t << "\t\t" << target_key << " = {" << "\n" - << "\t\t\t" << "buildArgumentsString = \"-f " << mkfile << "\";" << "\n" - << "\t\t\t" << "buildPhases = (" << "\n" + QString phase_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET"); +// project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key); + project->variables()["QMAKE_PBX_PRESCRIPT_BUILDPHASES"].append(phase_key); + t << "\t\t" << phase_key << " = {" << "\n" + << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" + << "\t\t\t" << "files = (" << "\n" << "\t\t\t" << ");" << "\n" - << "\t\t\t" << "buildSettings = {" << "\n" - << "\t\t\t" << "};" << "\n" - << "\t\t\t" << "buildToolPath = \"/usr/bin/gnumake\";"<< "\n" - << "\t\t\t" << "buildWorkingDirectory = \"" << QDir::currentDirPath() << "\";" << "\n" - << "\t\t\t" << "dependencies = (" << "\n" + << "\t\t\t" << "generatedFileNames = (" << "\n" + << varGlue("QMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n") << "\t\t\t" << ");" << "\n" - << "\t\t\t" << "isa = PBXLegacyTarget;" << "\n" - << "\t\t\t" << "name = QtPreprocessors;" << "\n" - << "\t\t\t" << "productName = QtPreprocessors;" << "\n" - << "\t\t\t" << "settingsToExpand = 6;" << "\n" - << "\t\t\t" << "settingsToPassInEnvironment = 287;" << "\n" - << "\t\t\t" << "settingsToPassOnCommandLine = 280;" << "\n" - << "\t\t\t" << "shouldsUseHeadermap = 0;" << "\n" + << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n" + << "\t\t\t" << "name = \"Qt Preprocessors\";" << "\n" + << "\t\t\t" << "neededFileNames = (" << "\n" + << varGlue("QMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "shellPath = /bin/sh;" << "\n" + << "\t\t\t" << "shellScript = \"make -C " << QDir::currentDirPath() << + " -f " << mkfile << "\";" << "\n" << "\t\t" << "};" << "\n"; + } - QString target_depend_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET_DEPEND"); - project->variables()["QMAKE_PBX_TARGETDEPENDS"].append(target_depend_key); - t << "\t\t" << target_depend_key << " = {" << "\n" - << "\t\t\t" << "isa = PBXTargetDependency;" << "\n" - << "\t\t\t" << "target = " << target_key << ";" << "\n" - << "\t\t" << "};" << "\n"; - } //SOURCE BUILDPHASE @@ -329,3 +567,3 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QStringList &libdirs = project->variables()["QMAKE_PBX_LIBPATHS"]; - QString libs[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null }; + QString libs[] = { "QMAKE_LFLAGS", "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null }; for(i = 0; !libs[i].isNull(); i++) { @@ -335,2 +573,4 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString library, name, opt = (*it).stripWhiteSpace(); + if(opt.length() >= 2 && (opt[0] == '"' || opt[0] == '\'') && opt[(int) opt.length()-1] == opt[0]) + opt = opt.mid(1, opt.length()-2); if(opt.startsWith("-L")) { @@ -339,2 +579,5 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) libdirs.append(r); + } else if(opt == "-prebind") { + project->variables()["QMAKE_DO_PREBINDING"].append("TRUE"); + remove = TRUE; } else if(opt.startsWith("-l")) { @@ -344,3 +587,3 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(project->isActiveConfig("link_prl")) { - /* This isn't real nice, but it is real useful. This looks in a prl + /* This isn't real nice, but it is real usefull. This looks in a prl for what the library will ultimately be called so we can stick it @@ -351,10 +594,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) */ - QString prl_file = (*lit) + Option::dir_sep + lib + Option::prl_ext; - if(QFile::exists(prl_file)) { - QMakeProject proj; - if(proj.read(prl_file, QDir::currentDirPath())) { - if(!proj.isEmpty("QMAKE_PRL_TARGET")) { - library = (*lit) + Option::dir_sep + proj.first("QMAKE_PRL_TARGET"); + QString lib_file = (*lit) + Option::dir_sep + lib; + if(QMakeMetaInfo::libExists(lib_file)) { + QMakeMetaInfo libinfo; + if(libinfo.readLib(lib_file)) { + if(!libinfo.isEmpty("QMAKE_PRL_TARGET")) { + library = (*lit) + Option::dir_sep + libinfo.first("QMAKE_PRL_TARGET"); debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)", - opt.latin1(), prl_file.latin1(), library.latin1()); + opt.latin1(), lib_file.latin1(), library.latin1()); remove = TRUE; @@ -362,3 +605,2 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } - } @@ -394,2 +636,4 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } + } else if(opt == "-undefined") { + ++it; //the next option is not a library.. } else if(opt.left(1) != "-") { @@ -455,3 +699,3 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) mkfile = fileFixify(mkfile, QDir::currentDirPath()); - project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key); + project->variables()["QMAKE_PBX_PRESCRIPT_BUILDPHASES"].append(phase_key); t << "\t\t" << phase_key << " = {" << "\n" @@ -500,4 +744,3 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } - if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console") && - project->first("TEMPLATE") == "app") { //BUNDLE RESOURCES + if(!project->isActiveConfig("console") && project->first("TEMPLATE") == "app") { //BUNDLE RESOURCES QString grp("Bundle Resources"), key = keyFor(grp); @@ -513,17 +756,2 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } - - //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER - //PRODUCTS - { - QString grp("Products"), key = keyFor(grp); - project->variables()["QMAKE_PBX_GROUPS"].append(key); - t << "\t\t" << key << " = {" << "\n" - << "\t\t\t" << "children = (" << "\n" - << "\t\t\t\t" << keyFor("QMAKE_PBX_REFERENCE") << "\n" - << "\t\t\t" << ");" << "\n" - << "\t\t\t" << "isa = PBXGroup;" << "\n" - << "\t\t\t" << "name = Products;" << "\n" - << "\t\t\t" << "refType = 4;" << "\n" - << "\t\t" << "};" << "\n"; - } { //INSTALL BUILDPHASE (sh script) @@ -542,3 +770,3 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) targ += ".app"; - } else if(!project->isActiveConfig("staticlib") && + } else if(!project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin") && !project->isActiveConfig("frameworklib")) { @@ -561,3 +789,3 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) targ = project->first("TARGET"); - if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { + if(!project->isActiveConfig("console")) { targ += ".app"; @@ -570,7 +798,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) targ = project->first("TARGET_"); - int slsh = targ.findRev(Option::dir_sep); - if(slsh != -1) - targ = targ.right(targ.length() - slsh - 1); } - QTextStream sht(&shf); + int slsh = targ.findRev(Option::dir_sep); + if(slsh != -1) + targ = targ.right(targ.length() - slsh - 1); + QString dstdir = project->first("DESTDIR"); @@ -578,12 +806,14 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) + QTextStream sht(&shf); sht << "#!/bin/sh" << endl; //copy the actual target - sht << "OUT_TARG=\"" << targ << "\"\n" - << "[ -z \"$BUILD_ROOT\" ] || OUT_TARG=\"${BUILD_ROOT}/${OUT_TARG}\"" << endl; - sht << "[ \"$OUT_TARG\" = \"" + sht << "OUT_TARG=\"${TARGET_BUILD_DIR}/${FULL_PRODUCT_NAME}\"\n" + << "if [ -e \"$OUT_TARG\" ]; then" << "\n" + << " [ \"$OUT_TARG\" = \"" << (dstdir.isEmpty() ? QDir::currentDirPath() + QDir::separator(): dstdir) << targ << "\" ] || " << "[ \"$OUT_TARG\" = \"" << targ << "\" ] || " - << "cp -r \"$OUT_TARG\" " << "\"" << dstdir << targ << "\"" << endl; + << "cp -r \"$OUT_TARG\" " << "\"" << dstdir << targ << "\"" << "\n" + << "fi" << endl; //rename as a framework - if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("frameworklib")) + if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("frameworklib") && !project->isActiveConfig("plugin")) sht << "ln -sf \"" << targ << "\" " << "\"" << dstdir << targ << "\"" << endl; @@ -602,3 +832,3 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t" << phase_key << " = {" << "\n" - << "\t\t\t" << "buildActionMask = 8;" << "\n" //only on install! + << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" << "\t\t\t" << "files = (" << "\n" @@ -616,2 +846,41 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } + if(/*ideType() == MAC_XCODE &&*/ !project->isEmpty("QMAKE_PBX_PRESCRIPT_BUILDPHASES") && 0) { + // build reference + t << "\t\t" << keyFor("QMAKE_PBX_PRESCRIPT_BUILDREFERENCE") << " = {" << "\n" + << "\t\t\t" << "includeInIndex = 0;" << "\n" + << "\t\t\t" << "isa = PBXFileReference;" << "\n" + << "\t\t\t" << "path = preprocessor.out;" << "\n" + << "\t\t\t" << "refType = 3;" << "\n" + << "\t\t\t" << "sourceTree = BUILT_PRODUCTS_DIR;" << "\n" + << "\t\t" << "};" << "\n"; + project->variables()["QMAKE_PBX_PRODUCTS"].append(keyFor("QMAKE_PBX_PRESCRIPTS_BUILDREFERENCE")); + //build phase + QString prescript_key = keyFor("QMAKE_PBX_PRESCRIPTS_BUILDPHASE"); + project->variables()["QMAKE_PBX_TARGETS"].append(prescript_key); + t << "\t\t" << prescript_key << " = {" << "\n" + << "\t\t\t" << "buildPhases = (" << "\n" + << varGlue("QMAKE_PBX_PRESCRIPT_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "buildRules = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n" + << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "dependencies = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXNativeTarget;" << "\n" + << "\t\t\t" << "name = \"Qt Preprocessor Steps\";" << "\n" + << "\t\t\t" << "productName = \"Qt Preprocessor Steps\";" << "\n" + << "\t\t\t" << "productReference = " << keyFor("QMAKE_PBX_PRESCRIPTS_BUILDREFERENCE") << ";" << "\n" + << "\t\t\t" << "productType = \"com.apple.product-type.tool\";" << "\n" + << "\t\t" << "};" << "\n"; + //dependency + t << "\t\t" << keyFor("QMAKE_PBX_PRESCRIPTS_DEPENDENCY") << " = {" << "\n" + << "\t\t\t" << "isa = PBXTargetDependency;" << "\n" + << "\t\t\t" << "target = " << keyFor("QMAKE_PBX_PRESCRIPTS_BUILDPHASE") << ";" << "\n" + << "\t\t" << "};" << "\n"; + project->variables()["QMAKE_PBX_TARGET_DEPENDS"].append(keyFor("QMAKE_PBX_PRESCRIPTS_DEPENDENCY")); + project->variables()["QMAKE_PBX_PRESCRIPT_BUILDPHASES"].clear(); //these are already consumed above + } + + //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER //ROOT_GROUP @@ -627,3 +896,5 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) //REFERENCE - t << "\t\t" << keyFor("QMAKE_PBX_REFERENCE") << " = {" << "\n"; + project->variables()["QMAKE_PBX_PRODUCTS"].append(keyFor(pbx_dir + "QMAKE_PBX_REFERENCE")); + t << "\t\t" << keyFor(pbx_dir + "QMAKE_PBX_REFERENCE") << " = {" << "\n" + << "\t\t\t" << "fallbackIsa = PBXFileReference;" << "\n"; if(project->first("TEMPLATE") == "app") { @@ -655,9 +926,26 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t\t\t" << "isa = PBXLibraryReference;" << "\n" + << "\t\t\t" << "expectedFileType = \"compiled.mach-o.dylib\";" << "\n" << "\t\t\t" << "path = " << lib << ";\n" - << "\t\t\t" << "refType = " << reftypeForFile(lib) << ";" << "\n"; + << "\t\t\t" << "refType = " << 3/*reftypeForFile(lib)*/ << ";" << "\n" + << "\t\t\t" << "sourceTree = BUILT_PRODUCTS_DIR" << ";" << "\n"; } t << "\t\t" << "};" << "\n"; + { //Products group + QString grp("Products"), key = keyFor(grp); + project->variables()["QMAKE_PBX_GROUPS"].append(key); + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << "children = (" << "\n" + << varGlue("QMAKE_PBX_PRODUCTS", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXGroup;" << "\n" + << "\t\t\t" << "name = Products;" << "\n" + << "\t\t\t" << "refType = 4;" << "\n" + << "\t\t" << "};" << "\n"; + } //TARGET - t << "\t\t" << keyFor("QMAKE_PBX_TARGET") << " = {" << "\n" + QString target_key = keyFor("QMAKE_PBX_TARGET"); + project->variables()["QMAKE_PBX_TARGETS"].append(target_key); + t << "\t\t" << target_key << " = {" << "\n" << "\t\t\t" << "buildPhases = (" << "\n" + << varGlue("QMAKE_PBX_PRESCRIPT_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", ",\n") << varGlue("QMAKE_PBX_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", "\n") @@ -665,2 +953,4 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << "buildSettings = {" << "\n" + << "\t\t\t\t" << "CC = \"" << fixEnvsList("QMAKE_CC") << "\";" << "\n" + << "\t\t\t\t" << "CPLUSPLUS = \"" << fixEnvsList("QMAKE_CXX") << "\";" << "\n" << "\t\t\t\t" << "FRAMEWORK_SEARCH_PATHS = \"\";" << "\n" @@ -670,4 +960,4 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t\t" << "OTHER_CFLAGS = \"" << - fixEnvsList("QMAKE_CFLAGS") << varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") << - varGlue("DEFINES"," -D"," -D","") << "\";" << "\n" + fixEnvsList("QMAKE_CFLAGS") << fixQuotes(varGlue("PRL_EXPORT_DEFINES"," -D"," -D","")) << + fixQuotes(varGlue("DEFINES"," -D"," -D","")) << "\";" << "\n" << "\t\t\t\t" << "LEXFLAGS = \"" << var("QMAKE_LEXFLAGS") << "\";" << "\n" @@ -675,7 +965,37 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t\t" << "OTHER_CPLUSPLUSFLAGS = \"" << - fixEnvsList("QMAKE_CXXFLAGS") << varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") << - varGlue("DEFINES"," -D"," -D","") << "\";" << "\n" + fixEnvsList("QMAKE_CXXFLAGS") << fixQuotes(varGlue("PRL_EXPORT_DEFINES"," -D"," -D","")) << + fixQuotes(varGlue("DEFINES"," -D"," -D","")) << "\";" << "\n" << "\t\t\t\t" << "OTHER_REZFLAGS = \"\";" << "\n" << "\t\t\t\t" << "SECTORDER_FLAGS = \"\";" << "\n" - << "\t\t\t\t" << "WARNING_CFLAGS = \"\";" << "\n"; + << "\t\t\t\t" << "WARNING_CFLAGS = \"\";" << "\n" + << "\t\t\t\t" << "PREBINDING = " << (project->isEmpty("QMAKE_DO_PREBINDING") ? "NO" : "YES") << ";" << "\n"; + if(!project->isEmpty("PRECOMPILED_HEADER")) { + if (ideType() == MAC_XCODE) { + t << "\t\t\t\t" << "GCC_PRECOMPILE_PREFIX_HEADER = \"YES\";" << "\n" + << "\t\t\t\t" << "GCC_PREFIX_HEADER = \"" << project->first("PRECOMPILED_HEADER") << "\";" << "\n"; + } else { + t << "\t\t\t\t" << "PRECOMPILE_PREFIX_HEADER = \"YES\";" << "\n" + << "\t\t\t\t" << "PREFIX_HEADER = \"" << project->first("PRECOMPILED_HEADER") << "\";" << "\n"; + } + } + if(project->first("TEMPLATE") == "app") { + QString plist = fileFixify(project->first("QMAKE_INFO_PLIST")); + if(plist.isEmpty()) + plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"); + if(QFile::exists(plist)) { + QFile plist_in_file(plist); + if(plist_in_file.open(IO_ReadOnly)) { + QTextStream plist_in(&plist_in_file); + QString plist_in_text = plist_in.read(); + plist_in_text = plist_in_text.replace("@ICON@", (project->isEmpty("RC_FILE") ? QString("") : project->first("RC_FILE").section(Option::dir_sep, -1))); + plist_in_text = plist_in_text.replace("@EXECUTABLE@", project->first("QMAKE_ORIG_TARGET")); + QFile plist_out_file("Info.plist"); + if(plist_out_file.open(IO_WriteOnly | IO_Translate)) { + QTextStream plist_out(&plist_out_file); + plist_out << plist_in_text; + t << "\t\t\t\t" << "INFOPLIST_FILE = \"Info.plist\";" << "\n"; + } + } + } + } #if 1 @@ -687,10 +1007,33 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) " " << fixEnvsList("QMAKE_LIBS") << "\";" << "\n"; + if(!project->isEmpty("DESTDIR")) { + QString dir = project->first("DESTDIR"); + if (QDir::isRelativePath(dir)) + dir.prepend(QDir::currentDirPath() + Option::dir_sep); + t << "\t\t\t\t" << "INSTALL_DIR = \"" << dir << "\";" << "\n"; + } + if ( project->first("TEMPLATE") == "lib") { + t << "\t\t\t\t" << "INSTALL_PATH = \"" << "\";" << "\n"; + } + if(!project->isEmpty("VERSION") && project->first("VERSION") != "0.0.0") { + t << "\t\t\t\t" << "DYLIB_CURRENT_VERSION = \"" << project->first("VER_MAJ") << "." + << project->first("VER_MIN") << "." << project->first("VER_PAT") << "\";" << "\n"; + if(project->isEmpty("COMPAT_VERSION")) + t << "\t\t\t\t" << "DYLIB_COMPATIBILITY_VERSION = \"" << project->first("VER_MAJ") << "." + << project->first("VER_MIN") << "\";" << "\n"; + } + if(!project->isEmpty("COMPAT_VERSION")) + t << "\t\t\t\t" << "DYLIB_COMPATIBILITY_VERSION = \"" << project->first("COMPAT_VERSION") << "\";" << "\n"; + + if(ideType() == MAC_XCODE) { + if(!project->isEmpty("OBJECTS_DIR")) + t << "\t\t\t\t" << "OBJROOT = \"" << project->first("OBJECTS_DIR") << "\";" << "\n"; + } +#if 0 if(!project->isEmpty("DESTDIR")) - t << "\t\t\t\t" << "INSTALL_PATH = \"" << project->first("DESTDIR") << "\";" << "\n"; - if(!project->isEmpty("VERSION") && project->first("VERSION") != "0.0.0") - t << "\t\t\t\t" << "DYLIB_CURRENT_VERSION = \"" << project->first("VERSION") << "\";" << "\n"; - if(!project->isEmpty("OBJECTS_DIR")) - t << "\t\t\t\t" << "OBJECT_FILE_DIR = \"" << project->first("OBJECTS_DIR") << "\";" << "\n"; + t << "\t\t\t\t" << "SYMROOT = \"" << project->first("DESTDIR") << "\";" << "\n"; + else + t << "\t\t\t\t" << "SYMROOT = \"" << QDir::currentDirPath() << "\";" << "\n"; +#endif if(project->first("TEMPLATE") == "app") { - if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) + if(ideType() == MAC_PBUILDER && !project->isActiveConfig("console")) t << "\t\t\t\t" << "WRAPPER_EXTENSION = app;" << "\n"; @@ -698,18 +1041,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } else { - QString lib = project->first("QMAKE_ORIG_TARGET"); if(!project->isActiveConfig("plugin") && project->isActiveConfig("staticlib")) { t << "\t\t\t\t" << "LIBRARY_STYLE = STATIC;" << "\n"; - lib = project->first("TARGET"); } else { t << "\t\t\t\t" << "LIBRARY_STYLE = DYNAMIC;" << "\n"; - if(!project->isActiveConfig("frameworklib")) { - if(project->isActiveConfig("plugin")) - lib = project->first("TARGET"); - else - lib = project->first("TARGET_"); - } } - int slsh = lib.findRev(Option::dir_sep); - if(slsh != -1) - lib = lib.right(lib.length() - slsh - 1); + QString lib = project->first("QMAKE_ORIG_TARGET"); + if (!project->isActiveConfig("frameworklib") && !project->isActiveConfig("staticlib")) + lib.prepend("lib"); t << "\t\t\t\t" << "PRODUCT_NAME = " << lib << ";" << "\n"; @@ -717,4 +1052,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) tmp = project->variables()["QMAKE_PBX_VARS"]; - for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) - t << "\t\t\t\t" << (*it) << " = \"" << getenv((*it)) << "\";" << "\n"; + for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) { + QString var = (*it), val = getenv(var); + if(!val && var == "TB") + val = "/usr/bin/"; + t << "\t\t\t\t" << var << " = \"" << val << "\";" << "\n"; + } t << "\t\t\t" << "};" << "\n" @@ -723,36 +1062,59 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << "dependencies = (" << "\n" - << varGlue("QMAKE_PBX_TARGETDEPENDS", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << varGlue("QMAKE_PBX_TARGET_DEPENDS", "\t\t\t\t", ",\n\t\t\t\t", "\n") << "\t\t\t" << ");" << "\n" - << "\t\t\t" << "productReference = " << keyFor("QMAKE_PBX_REFERENCE") << ";" << "\n" + << "\t\t\t" << "productReference = " << keyFor(pbx_dir + "QMAKE_PBX_REFERENCE") << ";" << "\n" << "\t\t\t" << "shouldUseHeadermap = 1;" << "\n"; + if(ideType() == MAC_XCODE) + t << "\t\t\t" << "isa = PBXNativeTarget;" << "\n"; if(project->first("TEMPLATE") == "app") { - if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { - t << "\t\t\t" << "isa = PBXApplicationTarget;" << "\n" - << "\t\t\t" << "productSettingsXML = " << "\"" << "<?xml version=" - << "\\\"1.0\\\" encoding=" << "\\\"UTF-8\\\"" << "?>" << "\n" - << "\t\t\t\t" << "<!DOCTYPE plist SYSTEM \\\"file://localhost/System/" - << "Library/DTDs/PropertyList.dtd\\\">" << "\n" - << "\t\t\t\t" << "<plist version=\\\"0.9\\\">" << "\n" - << "\t\t\t\t" << "<dict>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundleDevelopmentRegion</key>" << "\n" - << "\t\t\t\t\t" << "<string>English</string>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundleExecutable</key>" << "\n" - << "\t\t\t\t\t" << "<string>" << project->first("QMAKE_ORIG_TARGET") << "</string>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundleIconFile</key>" << "\n" - << "\t\t\t\t\t" << "<string>" << var("RC_FILE").section(Option::dir_sep, -1) << "</string>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundleInfoDictionaryVersion</key>" << "\n" - << "\t\t\t\t\t" << "<string>6.0</string>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundlePackageType</key>" << "\n" - << "\t\t\t\t\t" << "<string>APPL</string>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundleSignature</key>" << "\n" - << "\t\t\t\t\t" << "<string>????</string>" << "\n" - << "\t\t\t\t\t" << "<key>CFBundleVersion</key>" << "\n" - << "\t\t\t\t\t" << "<string>0.1</string>" << "\n" - << "\t\t\t\t\t" << "<key>CSResourcesFileMapped</key>" << "\n" - << "\t\t\t\t\t" << "<true/>" << "\n" - << "\t\t\t\t" << "</dict>" << "\n" - << "\t\t\t\t" << "</plist>" << "\";" << "\n"; + if(project->isActiveConfig("console")) { + if(ideType() == MAC_XCODE) + t << "\t\t\t" << "productType = \"com.apple.product-type.tool\";" << "\n"; + else + t << "\t\t\t" << "isa = PBXToolTarget;" << "\n"; } else { - t << "\t\t\t" << "isa = PBXToolTarget;" << "\n"; + if(ideType() == MAC_XCODE) + t << "\t\t\t" << "productType = \"com.apple.product-type.application\";" << "\n"; + else + t << "\t\t\t" << "isa = PBXApplicationReference;" << "\n"; + t << "\t\t\t" << "productSettingsXML = \""; + bool read_plist = false; + if(QFile::exists("Info.plist")) { + QFile plist("Info.plist"); + if(plist.open(IO_ReadOnly)) { + read_plist = true; + QTextStream stream(&plist); + while(!stream.eof()) + t << stream.readLine().replace('"', "\\\"") << endl; + } + } + if(!read_plist) { + t << "<?xml version=" + << "\\\"1.0\\\" encoding=" << "\\\"UTF-8\\\"" << "?>" << "\n" + << "\t\t\t\t" << "<!DOCTYPE plist SYSTEM \\\"file://localhost/System/" + << "Library/DTDs/PropertyList.dtd\\\">" << "\n" + << "\t\t\t\t" << "<plist version=\\\"0.9\\\">" << "\n" + << "\t\t\t\t" << "<dict>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundleDevelopmentRegion</key>" << "\n" + << "\t\t\t\t\t" << "<string>English</string>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundleExecutable</key>" << "\n" + << "\t\t\t\t\t" << "<string>" << project->first("QMAKE_ORIG_TARGET") << "</string>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundleIconFile</key>" << "\n" + << "\t\t\t\t\t" << "<string>" << var("RC_FILE").section(Option::dir_sep, -1) << "</string>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundleInfoDictionaryVersion</key>" << "\n" + << "\t\t\t\t\t" << "<string>6.0</string>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundlePackageType</key>" << "\n" + << "\t\t\t\t\t" << "<string>APPL</string>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundleSignature</key>" << "\n" + //Although the output below looks strange it is to avoid the trigraph ??< + << "\t\t\t\t\t" << "<string>????" << "</string>" << "\n" + << "\t\t\t\t\t" << "<key>CFBundleVersion</key>" << "\n" + << "\t\t\t\t\t" << "<string>0.1</string>" << "\n" + << "\t\t\t\t\t" << "<key>CSResourcesFileMapped</key>" << "\n" + << "\t\t\t\t\t" << "<true/>" << "\n" + << "\t\t\t\t" << "</dict>" << "\n" + << "\t\t\t\t" << "</plist>"; + } } + t << "\";" << "\n"; t << "\t\t\t" << "name = \"" << project->first("QMAKE_ORIG_TARGET") << "\";" << "\n" @@ -761,8 +1123,16 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString lib = project->first("QMAKE_ORIG_TARGET"); - if(!project->isActiveConfig("frameworklib")) + if(!project->isActiveConfig("frameworklib") && !project->isActiveConfig("staticlib")) lib.prepend("lib"); - t << "\t\t\t" << "isa = PBXLibraryTarget;" << "\n" - << "\t\t\t" << "name = \"" << lib << "\";" << "\n" + t << "\t\t\t" << "name = \"" << lib << "\";" << "\n" << "\t\t\t" << "productName = " << lib << ";" << "\n"; + if(ideType() == MAC_XCODE) { + if(project->isActiveConfig("staticlib")) + t << "\t\t\t" << "productType = \"com.apple.product-type.library.static\";" << "\n"; + else + t << "\t\t\t" << "productType = \"com.apple.product-type.library.dynamic\";" << "\n"; + } else { + t << "\t\t\t" << "isa = PBXLibraryTarget;" << "\n"; + } } + t << "\t\t\t" << "startupPath = \"<<ProjectDirectory>>\";" << "\n"; if(!project->isEmpty("DESTDIR")) @@ -771,8 +1141,12 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) //DEBUG/RELEASE - for(i = 0; i < 2; i++) { - bool as_release = !i; - if(project->isActiveConfig("debug")) - as_release = i; - QString key = "QMAKE_PBX_" + QString(as_release ? "RELEASE" : "DEBUG"); - key = keyFor(key); + QString active_buildstyle; +#if 0 + for(int as_release = 0; as_release < 2; as_release++) +#else + bool as_release = !project->isActiveConfig("debug"); +#endif + { + QString key = keyFor("QMAKE_PBX_" + QString(as_release ? "RELEASE" : "DEBUG")); + if(project->isActiveConfig("debug") != as_release) + active_buildstyle = key; project->variables()["QMAKE_PBX_BUILDSTYLES"].append(key); @@ -783,4 +1157,12 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t\t" << "COPY_PHASE_STRIP = " << (as_release ? "YES" : "NO") << ";" << "\n"; - if(as_release) + if(as_release) { t << "\t\t\t\t" << "DEBUGGING_SYMBOLS = NO;" << "\n"; + } else { + t << "\t\t\t\t" << "GCC_ENABLE_FIX_AND_CONTINUE = " + << (project->isActiveConfig("no_fix_and_continue") ? "NO" : "YES") << ";" << "\n" + << "\t\t\t\t" << "GCC_GENERATE_DEBUGGING_SYMBOLS = YES;" << "\n" + << "\t\t\t\t" << "GCC_OPTIMIZATION_LEVEL = 0;" << "\n" + << "\t\t\t\t" << "ZERO_LINK =" + << (project->isActiveConfig("no_zero_link") ? "NO" : "YES") << ";" << "\n"; + } t << "\t\t\t" << "};" << "\n" @@ -795,6 +1177,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "hasScannedForEncodings = 1;" << "\n" << "\t\t\t" << "isa = PBXProject;" << "\n" << "\t\t\t" << "mainGroup = " << keyFor("QMAKE_PBX_ROOT_GROUP") << ";" << "\n" + << "\t\t\t" << "projectDirPath = \"\";" << "\n" << "\t\t\t" << "targets = (" << "\n" - << "\t\t\t\t" << keyFor("QMAKE_PBX_TARGET") << "\n" + << varGlue("QMAKE_PBX_TARGETS", "\t\t\t\t", ",\n\t\t\t\t", "\n") << "\t\t\t" << ");" << "\n" @@ -807,22 +1191,24 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) - QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"), - QDir::currentDirPath()); - QFile mkwrapf(mkwrap); - if(mkwrapf.open(IO_WriteOnly | IO_Translate)) { - debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1()); - QTextStream mkwrapt(&mkwrapf); - writeHeader(mkwrapt); - const char *cleans = "uiclean mocclean preprocess_clean "; - mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n" - << "all:" << "\n\t" - << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild") << "\n" - << "install: all" << "\n\t" - << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild install") << "\n" - << "distclean clean: preprocess_clean" << "\n\t" - << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild clean") << "\n" - << (!did_preprocess ? cleans : "") << ":" << "\n"; - if(did_preprocess) - mkwrapt << cleans << ":" << "\n\t" - << "make -f " - << pbx_dir << Option::dir_sep << "qt_preprocess.mak $@" << endl; + if(project->isActiveConfig("generate_pbxbuild_makefile")) { + QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"), + QDir::currentDirPath()); + QFile mkwrapf(mkwrap); + if(mkwrapf.open(IO_WriteOnly | IO_Translate)) { + debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1()); + QTextStream mkwrapt(&mkwrapf); + writeHeader(mkwrapt); + const char *cleans = "uiclean mocclean preprocess_clean "; + mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n" + << "all:" << "\n\t" + << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << "\n" + << "install: all" << "\n\t" + << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " install\n" + << "distclean clean: preprocess_clean" << "\n\t" + << "cd " << project->first("QMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " clean" << "\n" + << (!did_preprocess ? cleans : "") << ":" << "\n"; + if(did_preprocess) + mkwrapt << cleans << ":" << "\n\t" + << "make -f " + << pbx_dir << Option::dir_sep << "qt_preprocess.mak $@" << endl; + } } @@ -832,3 +1218,11 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString -ProjectBuilderMakefileGenerator::fixEnvs(QString file) +ProjectBuilderMakefileGenerator::fixQuotes(const QString &val) +{ + QString ret(val); + ret = ret.replace(QRegExp("('|\")"), "\\\\1"); + return ret; +} + +QString +ProjectBuilderMakefileGenerator::fixEnvs(const QString &file) { @@ -844,3 +1238,3 @@ ProjectBuilderMakefileGenerator::fixEnvs(QString file) QString -ProjectBuilderMakefileGenerator::fixEnvsList(QString where) +ProjectBuilderMakefileGenerator::fixEnvsList(const QString &where) { @@ -858,28 +1252,11 @@ ProjectBuilderMakefileGenerator::fixEnvsList(QString where) QString -ProjectBuilderMakefileGenerator::keyFor(QString block) +ProjectBuilderMakefileGenerator::keyFor(const QString &block) { -#if 0 //This make this code much easier to debug.. - return block; +#if 1 //This make this code much easier to debug.. + if(project->isActiveConfig("no_pb_munge_key")) + return block; #endif - QString ret; if(!keys.contains(block)) { -#if 0 - static unsigned int r = 0; - ret.sprintf("%024x", ++r); -#else //not really necesary, but makes it look more interesting.. - static struct { unsigned int a1, a2, a3; } r = { 0, 0, 0 }; - if(!r.a1 && !r.a2 && !r.a3) { - r.a1 = rand(); - r.a2 = rand(); - r.a3 = rand(); - } - switch(rand() % 3) { - case 0: ++r.a1; break; - case 1: ++r.a2; break; - case 2: ++r.a3; break; - } - ret.sprintf("%08x%08x%08x", r.a1, r.a2, r.a3); -#endif - ret = ret.upper(); + ret = qtMD5(block.utf8()).left(24).upper(); keys.insert(block, ret); @@ -894,24 +1271,23 @@ ProjectBuilderMakefileGenerator::openOutput(QFile &file) const { - if(project->first("TEMPLATE") != "subdirs") { - QFileInfo fi(file); - if(fi.extension() != "pbxproj" || file.name().isEmpty()) { - QString output = file.name(); - if(fi.isDir()) - output += QDir::separator(); - if(fi.extension() != "pbproj") { - if(file.name().isEmpty() || fi.isDir()) - output += project->first("TARGET"); - output += QString(".pbproj") + QDir::separator(); - } else if(output[(int)output.length() - 1] != QDir::separator()) { - output += QDir::separator(); - } - output += QString("project.pbxproj"); - file.setName(output); + if(QDir::isRelativePath(file.name())) + file.setName(Option::output_dir + file.name()); //pwd when qmake was run + QFileInfo fi(file); + if(fi.extension() != "pbxproj" || file.name().isEmpty()) { + QString output = file.name(); + if(fi.isDir()) + output += QDir::separator(); + if(!output.endsWith(projectSuffix())) { + if(file.name().isEmpty() || fi.isDir()) + output += project->first("TARGET"); + output += projectSuffix() + QDir::separator(); + } else if(output[(int)output.length() - 1] != QDir::separator()) { + output += QDir::separator(); } - bool ret = UnixMakefileGenerator::openOutput(file); - ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1); - Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2); - return ret; + output += QString("project.pbxproj"); + file.setName(output); } - return UnixMakefileGenerator::openOutput(file); + bool ret = UnixMakefileGenerator::openOutput(file); + ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1); + Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2); + return ret; } @@ -930,6 +1306,10 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const QString version, version_plist = project->first("QMAKE_PBUILDER_VERSION_PLIST"); - if(version_plist.isEmpty()) - version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist"; - else + if(version_plist.isEmpty()) { + if(ideType() == MAC_XCODE && QFile::exists("/Developer/Applications/Xcode.app/Contents/version.plist")) + version_plist = "/Developer/Applications/Xcode.app/Contents/version.plist"; + else + version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist"; + } else { version_plist = version_plist.replace(QRegExp("\""), ""); + } QFile version_file(version_plist); @@ -956,7 +1336,11 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const version_file.close(); - } else debug_msg(1, "pbuilder: version.plist: Failure to open %s", version_plist.latin1()); - if(version.startsWith("2.0")) - ret = "38"; - else if(version == "1.1") - ret = "34"; + } else { debug_msg(1, "pbuilder: version.plist: Failure to open %s", version_plist.latin1()); } + if(version_plist.contains("Xcode")) { + ret = "39"; + } else { + if(version.startsWith("2.")) + ret = "38"; + else if(version == "1.1") + ret = "34"; + } } else { @@ -976,8 +1360,37 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const -QString -ProjectBuilderMakefileGenerator::reftypeForFile(QString where) +int +ProjectBuilderMakefileGenerator::reftypeForFile(const QString &where) { + int ret = 0; //absolute is the default.. if(QDir::isRelativePath(where)) - return "4"; //relative - return "0"; //absolute + ret = 4; //relative + return ret; +} + +ProjectBuilderMakefileGenerator::IDE_TYPE +ProjectBuilderMakefileGenerator::ideType() const +{ + if(!project->isActiveConfig("no_pbx_xcode") && + (QFile::exists("/Developer/Applications/Xcode.app") || project->isActiveConfig("pbx_xcode"))) + return ProjectBuilderMakefileGenerator::MAC_XCODE; + return ProjectBuilderMakefileGenerator::MAC_PBUILDER; +} + +QString +ProjectBuilderMakefileGenerator::projectSuffix() const +{ + if(ideType() == MAC_XCODE) + return ".xcode"; + return ".pbproj"; +} + +QString +ProjectBuilderMakefileGenerator::pbxbuild() +{ + if(QFile::exists("/usr/bin/pbbuild")) + return "pbbuild"; + if(QFile::exists("/usr/bin/xcodebuild")) + return "xcodebuild"; + return (ideType() == MAC_XCODE ? "xcodebuild" : "pbxbuild"); } + diff --git a/qmake/generators/mac/pbuilder_pbx.h b/qmake/generators/mac/pbuilder_pbx.h index ec2e1be..4ffb9a8 100644 --- a/qmake/generators/mac/pbuilder_pbx.h +++ b/qmake/generators/mac/pbuilder_pbx.h @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of ProjectBuilderMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -36,4 +34,5 @@ **********************************************************************/ -#ifndef __PBUILDERMAKE_H__ -#define __PBUILDERMAKE_H__ + +#ifndef __PBUILDER_PBX_H__ +#define __PBUILDER_PBX_H__ @@ -45,2 +44,3 @@ class ProjectBuilderMakefileGenerator : public UnixMakefileGenerator int pbuilderVersion() const; + bool writeSubdirs(QTextStream &, bool); bool writeMakeParts(QTextStream &); @@ -48,7 +48,13 @@ class ProjectBuilderMakefileGenerator : public UnixMakefileGenerator + QString pbxbuild(); QMap<QString, QString> keys; - QString keyFor(QString file); - QString fixEnvs(QString file); - QString fixEnvsList(QString where); - QString reftypeForFile(QString file); + QString keyFor(const QString &file); + QString fixQuotes(const QString &val); + QString fixEnvs(const QString &file); + QString fixEnvsList(const QString &where); + int reftypeForFile(const QString &where); + QString projectSuffix() const; + + enum IDE_TYPE { MAC_XCODE, MAC_PBUILDER }; + IDE_TYPE ideType() const; @@ -60,2 +66,3 @@ public: protected: + bool doPrecompiledHeaders() const { return FALSE; } virtual bool doDepends() const { return FALSE; } //never necesary @@ -67,2 +74,2 @@ inline ProjectBuilderMakefileGenerator::~ProjectBuilderMakefileGenerator() -#endif /* __PBUILDERMAKE_H__ */ +#endif /* __PBUILDER_PBX_H__ */ diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index c12375d..5ce387f 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of MakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -39,2 +37,3 @@ #include "option.h" +#include "meta.h" #include <qdir.h> @@ -60,4 +59,5 @@ #endif +#define QMAKE_EOL(x) (x == '\r' || x == '\n') -static QString mkdir_p_asstring(const QString &dir) +QString mkdir_p_asstring(const QString &dir) { @@ -76,3 +76,2 @@ static bool createDir(const QString& fullPath) return FALSE; - QDir dirTmp; @@ -144,3 +143,3 @@ MakefileGenerator::generateMocList(const QString &fn_target) if(*(big_buffer + x) == '/') { //c++ style comment - for( ;x < total_size_read && *(big_buffer + x) != '\n'; x++); + for( ;x < total_size_read && !QMAKE_EOL(*(big_buffer + x)); x++); line_count++; @@ -162,3 +161,3 @@ MakefileGenerator::generateMocList(const QString &fn_target) } - } else if(*(big_buffer + x) == '\n') { + } else if(QMAKE_EOL(*(big_buffer + x))) { line_count++; @@ -189,3 +188,3 @@ MakefileGenerator::generateMocList(const QString &fn_target) *(big_buffer+x+len) = '\0'; - debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", fn_target.latin1(), + debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", fn_target.latin1(), line_count, big_buffer+x); @@ -202,3 +201,3 @@ MakefileGenerator::generateMocList(const QString &fn_target) bool cpp_ext = FALSE; - for(QStringList::Iterator cppit = Option::cpp_ext.begin(); + for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { @@ -208,10 +207,10 @@ MakefileGenerator::generateMocList(const QString &fn_target) if(cpp_ext) { - mocFile += fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + Option::moc_ext; + mocFile += Option::cpp_moc_mod + fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + Option::cpp_moc_ext; project->variables()["_SRCMOC"].append(mocFile); } else if(project->variables()["HEADERS"].findIndex(fn_target) != -1) { - for(QStringList::Iterator hit = Option::h_ext.begin(); + for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) { if((fn_target.right(ext_len) == (*hit))) { - mocFile += Option::moc_mod + fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + - Option::cpp_ext.first(); + mocFile += Option::h_moc_mod + fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + + Option::h_moc_ext; logicWarn(mocFile, "SOURCES"); @@ -234,3 +233,3 @@ MakefileGenerator::generateMocList(const QString &fn_target) x++; - if(*(big_buffer+x) == '\n') + if(QMAKE_EOL(*(big_buffer+x))) line_count++; @@ -245,5 +244,7 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const { - QStringList &fndeps = findDependencies(f); - if(!fndeps.isEmpty()) + if(processedDependencies(f)) return TRUE; + setProcessedDependencies(f, TRUE); + + QStringList &fndeps = findDependencies(f); QString fn = fileFixify(f, QDir::currentDirPath(), Option::output_dir); @@ -285,3 +286,3 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const if(*(big_buffer + x) == '/') { //c++ style comment - for( ; x < total_size_read && *(big_buffer + x) != '\n'; x++); + for( ; x < total_size_read && !QMAKE_EOL(*(big_buffer + x)); x++); } else if(*(big_buffer + x) == '*') { //c style comment @@ -293,3 +294,3 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const } - } else if(*(big_buffer + x) == '\n') { + } else if(QMAKE_EOL(*(big_buffer + x))) { line_count++; @@ -300,2 +301,5 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const } + while(x < total_size_read && //Skip spaces + (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t')) + x++; if(*(big_buffer + x) == '#') { @@ -320,3 +324,4 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const int inc_len; - for(inc_len = 0; *(big_buffer + x + inc_len) != term; inc_len++); + for(inc_len = 0; *(big_buffer + x + inc_len) != term && + !QMAKE_EOL(*(big_buffer + x + inc_len)); inc_len++); *(big_buffer + x + inc_len) = '\0'; @@ -327,3 +332,3 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const x++); - char term = '\n'; + char term = 0; if(*(big_buffer + x) == '"') @@ -332,3 +337,3 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const term = '\''; - if(term != '\n') + if(term) x++; @@ -336,3 +341,5 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const int msg_len; - for(msg_len = 0; *(big_buffer + x + msg_len) != term; msg_len++); + for(msg_len = 0; (term && *(big_buffer + x + msg_len) != term) && + !QMAKE_EOL(*(big_buffer + x + msg_len)); msg_len++); + const char saved_term = *(big_buffer + x + msg_len); *(big_buffer + x + msg_len) = '\0'; @@ -341,3 +348,3 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const line_count, msg.latin1()); - *(big_buffer + x + msg_len) = term; //put it back + *(big_buffer + x + msg_len) = saved_term; //put it back } @@ -353,3 +360,3 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const (*(big_buffer + x + 11) == ' ' || *(big_buffer + x + 11) == '>')) { - for(x += 12; *(big_buffer + x) != '>'; x++); + for(x += 11; *(big_buffer + x) != '>'; x++); int inc_len = 0; @@ -358,2 +365,22 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const inc = big_buffer + x; + } else if(total_size_read >= x + 13 && !strncmp(big_buffer + x, "customwidget", 12) && + (*(big_buffer + x + 12) == ' ' || *(big_buffer + x + 12) == '>')) { + for(x += 13; *(big_buffer + x) != '>'; x++); //skip up to > + while(x < total_size_read) { + for(x++; *(big_buffer + x) != '<'; x++); //skip up to < + x++; + if(total_size_read >= x + 7 && !strncmp(big_buffer+x, "header", 6) && + (*(big_buffer + x + 6) == ' ' || *(big_buffer + x + 6) == '>')) { + for(x += 7; *(big_buffer + x) != '>'; x++); //skip up to > + int inc_len = 0; + for(x += 1 ; *(big_buffer + x + inc_len) != '<'; inc_len++); + *(big_buffer + x + inc_len) = '\0'; + inc = big_buffer + x; + break; + } else if(total_size_read >= x + 14 && !strncmp(big_buffer+x, "/customwidget", 13) && + (*(big_buffer + x + 13) == ' ' || *(big_buffer + x + 13) == '>')) { + x += 14; + break; + } + } } else if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include", 7) && @@ -419,3 +446,2 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const } - QString fqn; @@ -425,2 +451,6 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const goto handle_fqn; + } else if(project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH") && + !stat(inc, &fst) && !S_ISDIR(fst.st_mode)) { + fqn = inc; + goto handle_fqn; } else { @@ -448,2 +478,3 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const fqn = depHeuristics[inc]; + from_source_dir = FALSE; } else if(Option::mkfile::do_dep_heuristics) { //some heuristics.. @@ -468,5 +499,5 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const fqn += inc_file; - from_source_dir = FALSE; //uics go in the output_dir (so don't fix them) + from_source_dir = FALSE; //uics go in the output_dir (so don't fix them) fqn = fileFixify(fqn, QDir::currentDirPath(), Option::output_dir); - goto handle_fqn; + goto cache_fqn; } @@ -490,3 +521,5 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const fqn = d + inc; - goto handle_fqn; + from_source_dir = FALSE; //uics go in the output_dir (so don't fix them) + fqn = fileFixify(fqn, QDir::currentDirPath(), Option::output_dir); + goto cache_fqn; } @@ -511,3 +544,5 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const fqn = d + inc; - goto handle_fqn; + from_source_dir = FALSE; //uics go in the output_dir (so don't fix them) + fqn = fileFixify(fqn, QDir::currentDirPath(), Option::output_dir); + goto cache_fqn; } @@ -516,4 +551,5 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const } - if(mocAware() && //is it a moc file? - (inc.endsWith(Option::cpp_ext.first()) || inc.endsWith(Option::moc_ext))) { + if( mocAware() && //is it a moc file? + ( inc.endsWith(Option::cpp_ext.first()) || inc.endsWith(Option::cpp_moc_ext) ) + || ( (Option::cpp_ext.first() != Option::h_moc_ext) && inc.endsWith(Option::h_moc_ext) )) { QString mocs[] = { QString("_HDRMOC"), QString("_SRCMOC"), QString::null }; @@ -529,4 +565,4 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const l.remove(it); - } else if(!findMocSource(fqn).endsWith(fn)) { - /* Not really a very good test, but this will at least avoid + } else if(!findMocSource(fqn).endsWith(fileFixify(fn))) { + /* Not really a very good test, but this will at least avoid confusion if it really does happen (since tmake/qmake @@ -538,3 +574,3 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const from_source_dir = FALSE; //mocs go in the output_dir (so don't fix them) - goto handle_fqn; + goto cache_fqn; } @@ -543,2 +579,8 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const } + fqn = findDependency(inc); //all else fails.. + cache_fqn: + if(from_source_dir) { + fqn = fileFixify(fqn); + from_source_dir = FALSE; + } depHeuristics.insert(inc, fqn); @@ -557,3 +599,3 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const //read past new line now.. - for( ; x < total_size_read && (*(big_buffer + x) != '\n'); x++); + for( ; x < total_size_read && !QMAKE_EOL(*(big_buffer + x)); x++); line_count++; @@ -565,4 +607,4 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const QStringList &deplist = findDependencies((*fnit)); - for(QStringList::Iterator it = deplist.begin(); it != deplist.end(); ++it) - if(fndeps.findIndex((*it)) == -1) + for(QStringList::Iterator it = deplist.begin(); it != deplist.end(); ++it) + if(fndeps.findIndex((*it)) == -1 && (*it) != fn) fndeps.append((*it)); @@ -608,3 +650,3 @@ MakefileGenerator::initOutPaths() QString("UI_SOURCES_DIR"), QString("UI_DIR"), QString("DESTDIR"), - QString("SUBLIBS_DIR"), QString::null }; + QString("SUBLIBS_DIR"), QString("DLLDESTDIR"), QString::null }; for(int x = 0; dirs[x] != QString::null; x++) { @@ -612,2 +654,6 @@ MakefileGenerator::initOutPaths() QString orig_path = v[dirs[x]].first(); +#ifdef Q_WS_WIN + // We don't want to add a separator for DLLDESTDIR on Windows + if (!(dirs[x] == "DLLDESTDIR")) +#endif { @@ -663,2 +709,7 @@ MakefileGenerator::initOutPaths() } + if ( !v["DESTDIR"].isEmpty() ) { + QDir d(v["DESTDIR"].first()); + if(Option::fixPathToLocalOS(d.absPath()) == Option::fixPathToLocalOS(Option::output_dir)) + v.remove("DESTDIR"); + } QDir::current().cd( currentDir ); @@ -676,8 +727,13 @@ MakefileGenerator::init() QString paths[] = { QString("SOURCES"), QString("FORMS"), QString("YACCSOURCES"), QString("INCLUDEPATH"), - QString("HEADERS"), QString("HEADERS_ORIG"), - QString("LEXSOURCES"), QString("QMAKE_INTERNAL_INCLUDED_FILES"), QString::null }; + QString("HEADERS"), QString("HEADERS_ORIG"), QString("LEXSOURCES"), + QString("QMAKE_INTERNAL_INCLUDED_FILES"), + QString("PRECOMPILED_HEADER"), QString::null }; for(int y = 0; paths[y] != QString::null; y++) { QStringList &l = v[paths[y]]; - if(!l.isEmpty()) - l = fileFixify(l); + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + if ((*it).isEmpty()) + continue; + if(QFile::exists((*it))) + (*it) = fileFixify((*it)); + } } @@ -763,2 +819,3 @@ MakefileGenerator::init() findDependencies(file) = files; + setProcessedDependencies(file, TRUE); } @@ -811,7 +868,8 @@ MakefileGenerator::init() QString sources[] = { QString("OBJECTS"), QString("LEXSOURCES"), QString("YACCSOURCES"), - QString("HEADERS"), QString("SOURCES"), QString("FORMS"), - QString::null }; + QString("HEADERS"), QString("SOURCES"), QString("FORMS"), + QString("PRECOMPILED_HEADER"), QString::null }; depHeuristics.clear(); bool write_cache = FALSE, read_cache = QFile::exists(cache_file); - for(int x = 0; sources[x] != QString::null; x++) { + int x; + for(x = 0; sources[x] != QString::null; x++) { QStringList vpath, &l = v[sources[x]]; @@ -819,7 +877,6 @@ MakefileGenerator::init() if(!(*val_it).isEmpty()) { - QString file = Option::fixPathToLocalOS((*val_it)); - QStringList file_list(file); + QString file = fileFixify((*val_it), QDir::currentDirPath(), Option::output_dir); if(!QFile::exists(file)) { bool found = FALSE; - if(QDir::isRelativePath(file)) { + if(QDir::isRelativePath((*val_it))) { if(vpath.isEmpty()) @@ -860,9 +917,8 @@ MakefileGenerator::init() } else { - file_list.clear(); for(int i = 0; i < (int)d.count(); i++) { - file_list.append(dir + d[i]); + QString file = fileFixify(dir + d[i]); if(i == (int)d.count() - 1) - (*val_it) = dir + d[i]; + (*val_it) = file; else - l.insert(val_it, dir + d[i]); + l.insert(val_it, file); } @@ -878,40 +934,42 @@ MakefileGenerator::init() } - for(QStringList::Iterator file_it = file_list.begin(); - file_it != file_list.end(); ++file_it) { - QString file_list_file = fileFixify((*file_it)); - bool found_cache_moc = FALSE, found_cache_dep = FALSE; - if(read_cache && Option::output.name() != "-" && - project->isActiveConfig("qmake_cache")) { - if(!findDependencies(file_list_file).isEmpty()) - found_cache_dep = TRUE; - if(cache_found_files[(*file_it)] == (void *)2) - found_cache_moc = TRUE; - if(!found_cache_moc || !found_cache_dep) - write_cache = TRUE; - } - /* Do moc before dependency checking since some includes can come from - moc_*.cpp files */ - if(found_cache_moc) { - QString moc = findMocDestination(file_list_file); - if(!moc.isEmpty()) { - for(QStringList::Iterator cppit = Option::cpp_ext.begin(); - cppit != Option::cpp_ext.end(); ++cppit) { - if(file_list_file.endsWith((*cppit))) { - QStringList &deps = findDependencies(file_list_file); - if(!deps.contains(moc)) - deps.append(moc); - break; - } - } + } + } + } + for(x = 0; sources[x] != QString::null; x++) { + QStringList &l = v[sources[x]]; + for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { + bool found_cache_moc = FALSE, found_cache_dep = FALSE; + if(read_cache && Option::output.name() != "-" && + project->isActiveConfig("qmake_cache")) { + if(processedDependencies((*val_it))) + found_cache_dep = TRUE; + if(cache_found_files[(*val_it)] == (void *)2) + found_cache_moc = TRUE; + if(!found_cache_moc || !found_cache_dep) + write_cache = TRUE; + } + /* Do moc before dependency checking since some includes can come from + moc_*.cpp files */ + if(found_cache_moc) { + QString fixed_file(fileFixify((*val_it), QDir::currentDirPath(), Option::output_dir)); + QString moc = findMocDestination(fixed_file); + if(!moc.isEmpty()) { + for(QStringList::Iterator cppit = Option::cpp_ext.begin(); + cppit != Option::cpp_ext.end(); ++cppit) { + if(fixed_file.endsWith((*cppit))) { + QStringList &deps = findDependencies(fixed_file); + if(!deps.contains(moc)) + deps.append(moc); + break; } - } else if(mocAware() && (sources[x] == "SOURCES" || sources[x] == "HEADERS") && - (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || - Option::mkfile::do_mocs)) { - generateMocList((*file_it)); - } - if(!found_cache_dep && sources[x] != "OBJECTS") { - debug_msg(5, "Looking for dependencies for %s", (*file_it).latin1()); - generateDependencies(deplist, (*file_it), doDepends()); } } + } else if(mocAware() && (sources[x] == "SOURCES" || sources[x] == "HEADERS") && + (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || + Option::mkfile::do_mocs)) { + generateMocList((*val_it)); + } + if(!found_cache_dep && sources[x] != "OBJECTS") { + debug_msg(5, "Looking for dependencies for %s", (*val_it).latin1()); + generateDependencies(deplist, (*val_it), doDepends()); } @@ -934,3 +992,3 @@ MakefileGenerator::init() it != depends.end(); ++it) - cachet << depKeyMap[it.key()] << " = " << it.data().join(" ") << endl; + cachet << dependencyKey(it.key()) << " = " << it.data().join(" ") << endl; cachet << "[mocable]" << endl; @@ -1055,3 +1113,3 @@ MakefileGenerator::init() decl = project->first("UI_HEADERS_DIR"); - if(!decl.isEmpty() || (project->isEmpty("UI_HEADERS_DIR") && + if(!decl.isEmpty() || (project->isEmpty("UI_HEADERS_DIR") && !project->isEmpty("UI_SOURCES_DIR")) ) { @@ -1074,6 +1132,6 @@ MakefileGenerator::init() impl = fileFixify(impl, QDir::currentDirPath(), Option::output_dir); - if(!impl.isEmpty()) + if(!impl.isEmpty() && !impl.endsWith(Option::dir_sep)) impl += Option::dir_sep; impl += fi.baseName(TRUE) + Option::cpp_ext.first(); - if(Option::output_dir != QDir::currentDirPath() && + if(Option::output_dir != QDir::currentDirPath() && project->isEmpty("UI_DIR") && project->isEmpty("UI_HEADERS_DIR")) { @@ -1086,3 +1144,3 @@ MakefileGenerator::init() decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); - if(!decl.isEmpty()) + if(!decl.isEmpty() && !decl.endsWith(Option::dir_sep)) decl += Option::dir_sep; @@ -1095,3 +1153,3 @@ MakefileGenerator::init() - QString mocable = Option::moc_mod + fi.baseName(TRUE) + Option::cpp_ext.first(); + QString mocable = Option::h_moc_mod + fi.baseName(TRUE) + Option::h_moc_ext; if(!v["MOC_DIR"].isEmpty()) @@ -1108,2 +1166,10 @@ MakefileGenerator::init() + //Translation files + if(!project->isEmpty("TRANSLATIONS")) { + QStringList &trf = project->variables()["TRANSLATIONS"]; + for(QStringList::Iterator it = trf.begin(); it != trf.end(); ++it) { + (*it) = Option::fixPathToLocalOS((*it)); + } + } + //Image files @@ -1134,3 +1200,3 @@ MakefileGenerator::init() } - if(Option::output_dir != QDir::currentDirPath()) + if(Option::output_dir != QDir::currentDirPath()) project->variables()["INCLUDEPATH"].append(fileFixify(Option::output_dir, Option::output_dir, @@ -1142,3 +1208,4 @@ MakefileGenerator::init() project->variables()["INCLUDEPATH"].append(project->first("MOC_DIR")); - v["OBJMOC"] = createObjectList("_HDRMOC") + createObjectList("_UIMOC"); + if ( Option::h_moc_ext == Option::cpp_ext.first() ) + v["OBJMOC"] = createObjectList("_HDRMOC") + createObjectList("_UIMOC"); @@ -1151,2 +1218,20 @@ MakefileGenerator::init() } + + QString fixpaths[] = { QString("PRE_TARGETDEPS"), QString("POST_TARGETDEPS"), QString::null }; + for(int path = 0; !fixpaths[path].isNull(); path++) { + QStringList &l = v[fixpaths[path]]; + for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { + if(!(*val_it).isEmpty()) + (*val_it) = Option::fixPathToTargetOS((*val_it), FALSE); + } + } + + // Make sure the INCLUDEPATH doesn't contain any empty(/null) entries + QStringList &ipl = project->variables()["INCLUDEPATH"]; + for(QStringList::Iterator ipl_it = ipl.begin(); ipl_it != ipl.end();) { + if ((*ipl_it).isEmpty()) + ipl_it = ipl.remove(ipl_it); + else + ++ipl_it; + } } @@ -1157,6 +1242,6 @@ MakefileGenerator::processPrlFile(QString &file) bool ret = FALSE, try_replace_file=FALSE; - QString prl_file; - if(file.endsWith(Option::prl_ext)) { + QString meta_file, orig_file = file; + if(QMakeMetaInfo::libExists(file)) { try_replace_file = TRUE; - prl_file = file; + meta_file = file; file = ""; @@ -1167,8 +1252,8 @@ MakefileGenerator::processPrlFile(QString &file) tmp = tmp.left(ext); - prl_file = tmp + Option::prl_ext; + meta_file = tmp; } - prl_file = fileFixify(prl_file); - if(!QFile::exists(fileFixify(prl_file, QDir::currentDirPath(), Option::output_dir)) && + meta_file = fileFixify(meta_file); + if(!QMakeMetaInfo::libExists(fileFixify(meta_file, QDir::currentDirPath(), Option::output_dir)) && project->isActiveConfig("qt")) { - QString stem = prl_file, dir, extn; + QString stem = meta_file, dir, extn; int slsh = stem.findRev('/'), hadlib = 0; @@ -1192,6 +1277,6 @@ MakefileGenerator::processPrlFile(QString &file) stem += "-mt"; //try the thread case - prl_file = dir; + meta_file = dir; if(hadlib) - prl_file += "lib"; - prl_file += stem + extn; + meta_file += "lib"; + meta_file += stem + extn; try_replace_file = TRUE; @@ -1199,28 +1284,42 @@ MakefileGenerator::processPrlFile(QString &file) } - QString real_prl_file = Option::fixPathToLocalOS(prl_file); - if(project->variables()["QMAKE_PRL_INTERNAL_FILES"].findIndex(prl_file) != -1) { + QString real_meta_file = Option::fixPathToLocalOS(meta_file); + if(project->variables()["QMAKE_PRL_INTERNAL_FILES"].findIndex(QMakeMetaInfo::findLib(meta_file)) != -1) { ret = TRUE; - } else if(!real_prl_file.isEmpty() && - QFile::exists(fileFixify(real_prl_file, QDir::currentDirPath(), Option::output_dir))) { - project->variables()["QMAKE_PRL_INTERNAL_FILES"].append(prl_file); - QMakeProject proj; - debug_msg(1, "Processing PRL file: %s", real_prl_file.latin1()); - if(!proj.read(fileFixify(real_prl_file, QDir::currentDirPath(), Option::output_dir), - QDir::currentDirPath(), TRUE)) { - fprintf(stderr, "Error processing prl file: %s\n", real_prl_file.latin1()); - } else { - ret = TRUE; - QMap<QString, QStringList> &vars = proj.variables(); - for( QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) - processPrlVariable(it.key(), it.data()); - if(try_replace_file && !proj.isEmpty("QMAKE_PRL_TARGET")) { - QString dir; - int slsh = real_prl_file.findRev(Option::dir_sep); - if(slsh != -1) - dir = real_prl_file.left(slsh+1); - file = dir + proj.first("QMAKE_PRL_TARGET"); + } else if(!meta_file.isEmpty()) { + QString f = fileFixify(real_meta_file, QDir::currentDirPath(), Option::output_dir); + if(QMakeMetaInfo::libExists(f)) { + QMakeMetaInfo libinfo; + debug_msg(1, "Processing PRL file: %s", real_meta_file.latin1()); + if(!libinfo.readLib(f)) { + fprintf(stderr, "Error processing meta file: %s\n", real_meta_file.latin1()); + } else if(project->isActiveConfig("no_read_prl_" + libinfo.type().lower())) { + debug_msg(2, "Ignored meta file %s [%s]", real_meta_file.latin1(), libinfo.type().latin1()); + } else { + ret = TRUE; + QMap<QString, QStringList> &vars = libinfo.variables(); + for( QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) + processPrlVariable(it.key(), it.data()); + if(try_replace_file && !libinfo.isEmpty("QMAKE_PRL_TARGET")) { + QString dir; + int slsh = real_meta_file.findRev(Option::dir_sep); + if(slsh != -1) + dir = real_meta_file.left(slsh+1); + file = libinfo.first("QMAKE_PRL_TARGET"); + if(QDir::isRelativePath(file)) + file.prepend(dir); + } } } - if(ret) - project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"].append(prl_file); + if(ret) { + QString mf = QMakeMetaInfo::findLib(meta_file); + project->variables()["QMAKE_PRL_INTERNAL_FILES"].append(mf); + project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"].append(mf); + } + } + if(try_replace_file && file.isEmpty()) { +#if 0 + warn_msg(WarnLogic, "Found prl [%s] file with no target [%s]!", meta_file.latin1(), + orig_file.latin1()); +#endif + file = orig_file; } @@ -1298,2 +1397,6 @@ MakefileGenerator::writePrlFile(QTextStream &t) t << "QMAKE_PRL_DEFINES = " << project->variables()["PRL_EXPORT_DEFINES"].join(" ") << endl; + if(!project->isEmpty("PRL_EXPORT_CFLAGS")) + t << "QMAKE_PRL_CFLAGS = " << project->variables()["PRL_EXPORT_CFLAGS"].join(" ") << endl; + if(!project->isEmpty("PRL_EXPORT_CXXFLAGS")) + t << "QMAKE_PRL_CXXFLAGS = " << project->variables()["PRL_EXPORT_CXXFLAGS"].join(" ") << endl; if(!project->isEmpty("CONFIG")) @@ -1318,2 +1421,3 @@ MakefileGenerator::write() { + usePlatformDir(); init(); @@ -1322,2 +1426,3 @@ MakefileGenerator::write() Option::qmake_mode == Option::QMAKE_GENERATE_PRL) && + project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty() && project->isActiveConfig("create_prl") && project->first("TEMPLATE") == "lib" && @@ -1348,3 +1453,3 @@ MakefileGenerator::write() - if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || + if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || //write prl file Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) { @@ -1356,2 +1461,57 @@ MakefileGenerator::write() +// Manipulate directories, so it's possible to build +// several cross-platform targets concurrently +void +MakefileGenerator::usePlatformDir() +{ + QString pltDir(project->first("QMAKE_PLATFORM_DIR")); + if(pltDir.isEmpty()) + return; + char sep = QDir::separator(); + QString slashPltDir = sep + pltDir; + + QString filePath = project->first("DESTDIR"); + project->variables()["DESTDIR"] = filePath + + (filePath.isEmpty() ? pltDir : slashPltDir); + + filePath = project->first("DLLDESTDIR"); + project->variables()["DLLDESTDIR"] = filePath + + (filePath.isEmpty() ? pltDir : slashPltDir); + + filePath = project->first("OBJECTS_DIR"); + project->variables()["OBJECTS_DIR"] = filePath + + (filePath.isEmpty() ? pltDir : slashPltDir); + + filePath = project->first("QMAKE_LIBDIR_QT"); + project->variables()["QMAKE_LIBDIR_QT"] = filePath + + (filePath.isEmpty() ? pltDir : slashPltDir); + + filePath = project->first("QMAKE_LIBS_QT"); + int fpi = filePath.findRev(sep); + if (fpi == -1) + project->variables()["QMAKE_LIBS_QT"].prepend(pltDir + sep); + else + project->variables()["QMAKE_LIBS_QT"] = filePath.left(fpi) + + slashPltDir + + filePath.mid(fpi); + + filePath = project->first("QMAKE_LIBS_QT_THREAD"); + fpi = filePath.findRev(sep); + if (fpi == -1) + project->variables()["QMAKE_LIBS_QT_THREAD"].prepend(pltDir + sep); + else + project->variables()["QMAKE_LIBS_QT_THREAD"] = filePath.left(fpi) + + slashPltDir + + filePath.mid(fpi); + + filePath = project->first("QMAKE_LIBS_QT_ENTRY"); + fpi = filePath.findRev(sep); + if (fpi == -1) + project->variables()["QMAKE_LIBS_QT_ENTRY"].prepend(pltDir + sep); + else + project->variables()["QMAKE_LIBS_QT_ENTRY"] = filePath.left(fpi) + + slashPltDir + + filePath.mid(fpi); +} + void @@ -1374,3 +1534,3 @@ MakefileGenerator::writeObj(QTextStream &t, const QString &obj, const QString &s for(QStringList::Iterator dit = deps.begin(); dit != deps.end(); dit++) { - if((*dit).endsWith(Option::moc_ext)) + if((*dit).endsWith(Option::cpp_moc_ext)) odep += (*dit) + " "; @@ -1408,4 +1568,4 @@ MakefileGenerator::writeObj(QTextStream &t, const QString &obj, const QString &s if (!use_implicit_rule && !project->isEmpty(comp)) { - QString p = var(comp); - p.replace(stringSrc, (*sit)); + QString p = var(comp), srcf(*sit); + p.replace(stringSrc, srcf); p.replace(stringObj, (*oit)); @@ -1423,3 +1583,3 @@ MakefileGenerator::writeUicSrc(QTextStream &t, const QString &ui) for(QStringList::Iterator it = uil.begin(); it != uil.end(); it++) { - QString deps = findDependencies((*it)).join(" \\\n\t\t"), decl, impl; + QString decl, impl; { @@ -1427,8 +1587,6 @@ MakefileGenerator::writeUicSrc(QTextStream &t, const QString &ui) decl = tmp.replace(QRegExp("\\" + Option::ui_ext + "$"), Option::h_ext.first()); - decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); - int dlen = decl.findRev(Option::dir_sep) + 1; + int dlen = decl.findRev(Option::dir_sep) + 1; tmp = (*it); impl = tmp.replace(QRegExp("\\" + Option::ui_ext + "$"), Option::cpp_ext.first()); - impl = fileFixify(impl, QDir::currentDirPath(), Option::output_dir); - int ilen = decl.findRev(Option::dir_sep) + 1; + int ilen = decl.findRev(Option::dir_sep) + 1; if(!project->isEmpty("UI_DIR")) { @@ -1446,13 +1604,19 @@ MakefileGenerator::writeUicSrc(QTextStream &t, const QString &ui) } - } - if(decl_dir.isEmpty()) - decl_dir = decl.left(dlen); - if(impl_dir.isEmpty()) - impl_dir = impl.left(ilen); - if(!impl_dir.isEmpty()) - createDir(Option::output_dir + Option::dir_sep + impl_dir); - if(!decl_dir.isEmpty() && decl_dir != impl_dir) - createDir(Option::output_dir + Option::dir_sep + decl_dir); - } - t << decl << ": " << (*it) << " " << deps << "\n\t" + } + impl = fileFixify(impl, QDir::currentDirPath(), Option::output_dir); + decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); + if(decl_dir.isEmpty()) + decl_dir = decl.section(Option::dir_sep,0,-2); + if(impl_dir.isEmpty()) + impl_dir = impl.section(Option::dir_sep,0,-2); + if (QDir::isRelativePath(impl_dir)) + impl_dir.prepend(Option::output_dir + Option::dir_sep); + if (QDir::isRelativePath(decl_dir)) + decl_dir.prepend(Option::output_dir + Option::dir_sep); + createDir(impl_dir); + createDir(decl_dir); + } + QStringList deps = findDependencies((*it)); + deps.remove(decl); //avoid circular dependencies.. + t << decl << ": " << (*it) << " " << deps.join(" \\\n\t\t") << "\n\t" << "$(UIC) " << (*it) << " -o " << decl << endl << endl; @@ -1460,8 +1624,8 @@ MakefileGenerator::writeUicSrc(QTextStream &t, const QString &ui) QString mildDecl = decl; - int k = mildDecl.findRev( Option::dir_sep ); + int k = mildDecl.findRev(Option::dir_sep); if ( k != -1 ) mildDecl = mildDecl.mid( k + 1 ); - - t << impl << ": " << decl << " " << (*it) << " " << deps << "\n\t" - << "$(UIC) " << (*it) << " -i " << mildDecl << " -o " << impl << endl << endl; + t << impl << ": " << decl << " " << (*it) << " " << deps.join(" \\\n\t\t") << "\n\t" + << "$(UIC)"; + t << " " << (*it) << " -i " << mildDecl << " -o " << impl << endl << endl; } @@ -1479,3 +1643,4 @@ MakefileGenerator::writeMocObj(QTextStream &t, const QString &obj, const QString QString hdr = findMocSource((*sit)); - t << (*oit) << ": " << (*sit) << " " + t << (*oit) << ": " + << (*sit) << " " << findDependencies((*sit)).join(" \\\n\t\t") << " " << hdr << " " << findDependencies(hdr).join(" \\\n\t\t"); @@ -1492,4 +1657,4 @@ MakefileGenerator::writeMocObj(QTextStream &t, const QString &obj, const QString if (!use_implicit_rule && !project->isEmpty("QMAKE_RUN_CXX")) { - QString p = var("QMAKE_RUN_CXX"); - p.replace(stringSrc, (*sit)); + QString p = var("QMAKE_RUN_CXX"), srcf(*sit); + p.replace(stringSrc, srcf); p.replace(stringObj, (*oit)); @@ -1514,3 +1679,4 @@ MakefileGenerator::writeMocSrc(QTextStream &t, const QString &src) t << m << ": " << deps << "\n\t" - << "$(MOC) " << (*it) << " -o " << m << endl << endl; + << "$(MOC)"; + t << " " << (*it) << " -o " << m << endl << endl; } @@ -1547,3 +1713,6 @@ MakefileGenerator::writeYaccSrc(QTextStream &t, const QString &src) mangle = fi.baseName(TRUE); - yaccflags += " -p " + mangle; + if(!project->isEmpty("QMAKE_YACCFLAGS_MANGLE")) + yaccflags += " " + var("QMAKE_YACCFLAGS_MANGLE").replace(stringBase, mangle); + else + yaccflags += " -p " + mangle; } @@ -1623,5 +1792,5 @@ MakefileGenerator::writeImageObj(QTextStream &t, const QString &obj) if(!use_implicit_rule && !project->isEmpty("QMAKE_RUN_CXX")) { - QString p = var("QMAKE_RUN_CXX"); - p.replace( stringSrc, src); - p.replace( stringObj, (*oit)); + QString p = var("QMAKE_RUN_CXX"), srcf(src); + p.replace(stringSrc, srcf); + p.replace(stringObj, (*oit)); t << "\n\t" << p; @@ -1663,3 +1832,4 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) QString pvar = (*it) + ".path"; - if(project->variables()[pvar].isEmpty()) { + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_path") == -1 && + project->variables()[pvar].isEmpty()) { warn_msg(WarnLogic, "%s is not defined: install target not created\n", pvar.latin1()); @@ -1671,9 +1841,9 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) QString target, dst= fileFixify(project->variables()[pvar].first()); -#ifndef Q_WS_WIN if(dst.right(1) != Option::dir_sep) dst += Option::dir_sep; -#endif - QStringList tmp, &uninst = project->variables()[(*it) + ".uninstall"]; + QStringList tmp, uninst = project->variables()[(*it) + ".uninstall"]; //other tmp = project->variables()[(*it) + ".extra"]; + if(tmp.isEmpty()) + tmp = project->variables()[(*it) + ".commands"]; //to allow compatible name if(!tmp.isEmpty()) { @@ -1705,7 +1875,12 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) target += "\t"; - target += QString(fi.isDir() ? "-$(COPY_DIR)" : "-$(COPY_FILE)") + " \"" + - Option::fixPathToTargetOS(fileFixify(wild), FALSE) + "\" \"" + root + dst + "\"\n"; + QString cmd = QString(fi.isDir() ? "-$(INSTALL_DIR)" : "-$(INSTALL_FILE)") + " \"" + + Option::fixPathToTargetOS(fileFixify(wild, QString::null, + QString::null, FALSE, FALSE), FALSE) + + "\" \"" + root + dst + "\"\n"; + target += cmd; if(!project->isActiveConfig("debug") && !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) - target += QString("\t-") + var("QMAKE_STRIP") + " \"" + root + fileFixify(dst + filestr) + "\"\n"; + target += QString("\t-") + var("QMAKE_STRIP") + " \"" + + root + fileFixify(dst + filestr, QString::null, QString::null, FALSE, FALSE) + + "\"\n"; if(!uninst.isEmpty()) @@ -1718,5 +1893,6 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) #endif - + " \"" + root + fileFixify(dst + filestr) + "\""); + + " \"" + root + fileFixify(dst + filestr, QString::null, QString::null, FALSE, FALSE) + "\""); continue; } + fixEnvVariables(dirstr); QDir dir(dirstr, filestr); //wild @@ -1734,12 +1910,17 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) #endif - + " \"" + root + fileFixify(dst + file) + "\""); - QFileInfo fi(file); + + " \"" + root + fileFixify(dst + file, QString::null, QString::null, FALSE, FALSE) + + "\""); + QFileInfo fi(Option::fixPathToTargetOS(fileFixify(dirstr + file), TRUE)); if(!target.isEmpty()) target += "\t"; - target += QString(fi.isDir() ? "-$(COPY_DIR)" : "-$(COPY_FILE)") + " \"" + - Option::fixPathToTargetOS(fileFixify(dirstr + file), FALSE) + - "\" \"" + root + fileFixify(dst) + "\"\n"; + QString cmd = QString(fi.isDir() ? "-$(INSTALL_DIR)" : "-$(INSTALL_FILE)") + " \"" + + Option::fixPathToTargetOS(fileFixify(dirstr + file, QString::null, + QString::null, FALSE, FALSE), FALSE) + + "\" \"" + root + dst + "\"\n"; + target += cmd; if(!project->isActiveConfig("debug") && !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) - target += QString("\t-") + var("QMAKE_STRIP") + " \"" + root + fileFixify(dst + file) + "\"\n"; + target += QString("\t-") + var("QMAKE_STRIP") + " \"" + + root + fileFixify(dst + file, QString::null, QString::null, FALSE, FALSE) + + "\"\n"; } @@ -1748,7 +1929,19 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) //default? - if(do_default) + if(do_default) { target = defaultInstall((*it)); + uninst = project->variables()[(*it) + ".uninstall"]; + } if(!target.isEmpty()) { - t << "install_" << (*it) << ": " << "\n\t"; + t << "install_" << (*it) << ": all "; + const QStringList &deps = project->variables()[(*it) + ".depends"]; + if(!deps.isEmpty()) { + for(QStringList::ConstIterator dep_it = deps.begin(); dep_it != deps.end(); ++dep_it) { + QString targ = var((*dep_it) + ".target"); + if(targ.isEmpty()) + targ = (*dep_it); + t << targ; + } + } + t << "\n\t"; const QStringList &dirs = project->variables()[pvar]; @@ -1763,3 +1956,2 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) t << target << endl << endl; - all_installs += QString("install_") + (*it) + " "; if(!uninst.isEmpty()) { @@ -1768,5 +1960,10 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) << "-$(DEL_DIR) \"" << ( root + dst ) << "\"" << endl << endl; - all_uninstalls += "uninstall_" + (*it) + " "; } t << endl; + + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_default_install") == -1) { + all_installs += QString("install_") + (*it) + " "; + if(!uninst.isEmpty()) + all_uninstalls += "uninstall_" + (*it) + " "; + } } else { @@ -1775,4 +1972,4 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) } - t << "install: all " << all_installs << "\n\n"; - t << "uninstall: " << all_uninstalls << "\n\n"; + t << "install: " << all_installs << " " << var("INSTALLDEPS") << "\n\n"; + t << "uninstall: " << all_uninstalls << " " << var("UNINSTALLDEPS") << "\n\n"; } @@ -1973,4 +2170,8 @@ MakefileGenerator::writeMakeQmake(QTextStream &t) t << fileFixify(Option::mkfile::cachefile) << " "; - if(!specdir().isEmpty()) - t << specdir() << Option::dir_sep << "qmake.conf" << " "; + if(!specdir().isEmpty()) { + if (QFile::exists(Option::fixPathToLocalOS(specdir()+QDir::separator()+"qmake.conf"))) + t << specdir() << Option::dir_sep << "qmake.conf" << " "; + else if (QFile::exists(Option::fixPathToLocalOS(specdir()+QDir::separator()+"tmake.conf"))) + t << specdir() << Option::dir_sep << "tmake.conf" << " "; + } t << project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"].join(" \\\n\t\t") << "\n\t" @@ -1988,3 +2189,4 @@ MakefileGenerator::writeMakeQmake(QTextStream &t) QStringList -MakefileGenerator::fileFixify(const QStringList& files, const QString &out_dir, const QString &in_dir, bool force_fix) const +MakefileGenerator::fileFixify(const QStringList& files, const QString &out_dir, const QString &in_dir, + bool force_fix, bool canon) const { @@ -1995,3 +2197,3 @@ MakefileGenerator::fileFixify(const QStringList& files, const QString &out_dir, if(!(*it).isEmpty()) - ret << fileFixify((*it), out_dir, in_dir, force_fix); + ret << fileFixify((*it), out_dir, in_dir, force_fix, canon); } @@ -2001,10 +2203,14 @@ MakefileGenerator::fileFixify(const QStringList& files, const QString &out_dir, QString -MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const QString &in_d, bool force_fix) const +MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, + const QString &in_d, bool force_fix, bool canon) const { - if(file0.isEmpty()) + if(file0.isEmpty()) return file0; QString key = file0; - if(!in_d.isEmpty() || !out_d.isEmpty() || force_fix) - key.prepend(in_d + "--" + out_d + "--" + QString::number((int)force_fix) + "-"); - if(fileFixed.contains(key)) + if(QDir::isRelativePath(file0)) + key.prepend(QDir::currentDirPath() + "--"); + if(!in_d.isEmpty() || !out_d.isEmpty() || force_fix || !canon) + key.prepend(in_d + "--" + out_d + "--" + QString::number((int)force_fix) + "--" + + QString::number((int)canon) + "-"); + if(fileFixed.contains(key)) return fileFixed[key]; @@ -2029,3 +2235,3 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) { //absoluteify it - QString qfile = Option::fixPathToLocalOS(file); + QString qfile = Option::fixPathToLocalOS(file, TRUE, canon); if(QDir::isRelativePath(file)) { //already absolute @@ -2037,10 +2243,13 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const } else { //fix it.. - QString qfile(Option::fixPathToLocalOS(file, TRUE)), in_dir(in_d), out_dir(out_d); + QString qfile(Option::fixPathToLocalOS(file, TRUE, canon)), in_dir(in_d), out_dir(out_d); { - if(out_dir.isNull()) - out_dir = Option::output_dir; + if(out_dir.isNull() || QDir::isRelativePath(out_dir)) + out_dir.prepend(Option::output_dir + QDir::separator()); if(out_dir == ".") out_dir = QDir::currentDirPath(); - if(in_dir.isEmpty() || in_dir == ".") + if(in_dir.isEmpty() || QDir::isRelativePath(in_dir)) + in_dir.prepend(QDir::currentDirPath() + QDir::separator()); + if(in_dir == ".") in_dir = QDir::currentDirPath(); + if(!QDir::isRelativePath(in_dir) || !QDir::isRelativePath(out_dir)) { @@ -2067,4 +2276,4 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const } - file = Option::fixPathToTargetOS(file, FALSE); - if(QFile::exists(file) && file == Option::fixPathToTargetOS(file, TRUE)) { + file = Option::fixPathToTargetOS(file, FALSE, canon); + if(canon && QFile::exists(file) && file == Option::fixPathToTargetOS(file, TRUE, canon)) { QString real_file = QDir(file).canonicalPath(); @@ -2073,3 +2282,3 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const } - QString match_dir = Option::fixPathToTargetOS(out_dir, FALSE); + QString match_dir = Option::fixPathToTargetOS(out_dir, FALSE, canon); if(file == match_dir) { @@ -2102,3 +2311,3 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const } - file = Option::fixPathToTargetOS(file, FALSE); + file = Option::fixPathToTargetOS(file, FALSE, canon); if(file.isEmpty()) @@ -2107,3 +2316,4 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const file = quote + file + quote; - debug_msg(3, "Fixed %s :: to :: %s (%d)", orig_file.latin1(), file.latin1(), depth); + debug_msg(3, "Fixed %s :: to :: %s (%d) [%s::%s]", orig_file.latin1(), file.latin1(), depth, + in_d.latin1(), out_d.latin1()); ((MakefileGenerator*)this)->fileFixed.insert(key, file); @@ -2140,2 +2350,27 @@ void MakefileGenerator::logicWarn(const QString &f, const QString &w) +QString +MakefileGenerator::dependencyKey(const QString &file) const +{ + QString key = file; + Option::fixPathToTargetOS(key); + if(key.find(Option::dir_sep)) + key = key.right(key.length() - key.findRev(Option::dir_sep) - 1); + return key; +} + +void +MakefileGenerator::setProcessedDependencies(const QString &file, bool b) +{ + depProcessed[dependencyKey(file)] = b; +} + +bool +MakefileGenerator::processedDependencies(const QString &file) +{ + QString key = dependencyKey(file); + if(!depProcessed.contains(key)) + return FALSE; + return depProcessed[key]; +} + QStringList @@ -2143,9 +2378,3 @@ QStringList { - QString key = file; - Option::fixPathToTargetOS(key); - if(key.find(Option::dir_sep)) - key = key.right(key.length() - key.findRev(Option::dir_sep) - 1); - if(!depKeyMap.contains(key)) - depKeyMap.insert(key, file); - return depends[key]; + return depends[dependencyKey(file)]; } @@ -2159,4 +2388,4 @@ MakefileGenerator::specdir() spec = Option::mkfile::qmakespec; - const char *d = getenv("QTDIR"); - if(d) { +#if 0 + if(const char *d = getenv("QTDIR")) { QString qdir = Option::fixPathToTargetOS(QString(d)); @@ -2174,2 +2403,5 @@ MakefileGenerator::specdir() } +#else + spec = Option::fixPathToTargetOS(spec); +#endif return spec; @@ -2183,2 +2415,4 @@ MakefileGenerator::openOutput(QFile &file) const if(!file.name().isEmpty()) { + if(QDir::isRelativePath(file.name())) + file.setName(Option::output_dir + file.name()); //pwd when qmake was run QFileInfo fi(file); diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 4fdabe8..e818089 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of MakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -43,2 +41,8 @@ +#ifdef Q_OS_WIN32 +#define QT_POPEN _popen +#else +#define QT_POPEN popen +#endif + class MakefileGenerator @@ -49,3 +53,5 @@ class MakefileGenerator QString build_args(); - QMap<QString, QString> depHeuristics, depKeyMap, fileFixed; + QString dependencyKey(const QString &file) const; + QMap<QString, bool> depProcessed; + QMap<QString, QString> depHeuristics, fileFixed; QMap<QString, QString> mocablesToMOC, mocablesFromMOC; @@ -83,3 +89,3 @@ protected: QString findMocDestination(const QString &src_file) const; - QStringList &findDependencies(const QString &file); + virtual QStringList &findDependencies(const QString &file); @@ -99,2 +105,5 @@ protected: + //for cross-platform dependent directories + virtual void usePlatformDir(); + //for installs @@ -110,4 +119,8 @@ protected: virtual bool findLibraries(); + virtual QString findDependency(const QString &); - QString var(const QString &var); + void setProcessedDependencies(const QString &file, bool b); + bool processedDependencies(const QString &file); + + virtual QString var(const QString &var); QString varGlue(const QString &var, const QString &before, const QString &glue, const QString &after); @@ -120,5 +133,5 @@ protected: QString fileFixify(const QString& file, const QString &out_dir=QString::null, - const QString &in_dir=QString::null, bool force_fix=FALSE) const; + const QString &in_dir=QString::null, bool force_fix=FALSE, bool canon=TRUE) const; QStringList fileFixify(const QStringList& files, const QString &out_dir=QString::null, - const QString &in_dir=QString::null, bool force_fix=FALSE) const; + const QString &in_dir=QString::null, bool force_fix=FALSE, bool canon=TRUE) const; public: @@ -128,3 +141,3 @@ public: static MakefileGenerator *create(QMakeProject *); - bool write(); + virtual bool write(); virtual bool openOutput(QFile &) const; @@ -168,2 +181,5 @@ inline bool MakefileGenerator::findLibraries() +inline QString MakefileGenerator::findDependency(const QString &) +{ return QString(""); } + inline MakefileGenerator::~MakefileGenerator() @@ -171,2 +187,3 @@ inline MakefileGenerator::~MakefileGenerator() +QString mkdir_p_asstring(const QString &dir); diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp index 1515216..1c17379 100644 --- a/qmake/generators/projectgenerator.cpp +++ b/qmake/generators/projectgenerator.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of ProjectGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -159,2 +157,3 @@ ProjectGenerator::init() dirs.prepend("."); + const QString out_file = fileFixify(Option::output.name()); for(QStringList::Iterator pd = dirs.begin(); pd != dirs.end(); pd++) { @@ -173,8 +172,11 @@ ProjectGenerator::init() for(int i = 0; i < (int)d.count(); i++) { - QString nd = newdir + QDir::separator() + d[i]; + QString nd = newdir; + if(nd == ".") + nd = ""; + else if(!nd.isEmpty() && !nd.endsWith(QString(QChar(QDir::separator())))) + nd += QDir::separator(); + nd += d[i]; fileFixify(nd); - if(d[i] != "." && d[i] != ".." && !subdirs.contains(nd)) { - if(newdir + d[i] != Option::output_dir + Option::output.name()) - subdirs.append(nd); - } + if(d[i] != "." && d[i] != ".." && !subdirs.contains(nd) && !out_file.endsWith(nd)) + subdirs.append(nd); } @@ -326,3 +328,3 @@ ProjectGenerator::init() } - if(!found && (*val_it).endsWith(Option::moc_ext)) + if(!found && (*val_it).endsWith(Option::cpp_moc_ext)) found = TRUE; @@ -393,3 +395,3 @@ ProjectGenerator::addFile(QString file) dir = file.left(s+1); - if(file.mid(dir.length(), Option::moc_mod.length()) == Option::moc_mod) + if(file.mid(dir.length(), Option::h_moc_mod.length()) == Option::h_moc_mod) return FALSE; @@ -437,3 +439,3 @@ ProjectGenerator::addFile(QString file) QString -ProjectGenerator::getWritableVar(const QString &v, bool /*fixPath*/) +ProjectGenerator::getWritableVar(const QString &v, bool fixPath) { @@ -457,6 +459,10 @@ ProjectGenerator::getWritableVar(const QString &v, bool /*fixPath*/) } +#if 0 // ### Commented out for now so that project generation works. - // Sam: can you look at why this was needed? - /* if(fixPath) - join = join.replace("\\", "/");*/ + // Sam: it had to do with trailing \'s (ie considered continuation lines) + if(fixPath) + join = join.replace("\\", "/"); +#else + Q_UNUSED(fixPath); +#endif return ret + join + "\n"; diff --git a/qmake/generators/projectgenerator.h b/qmake/generators/projectgenerator.h index 055a784..bebb259 100644 --- a/qmake/generators/projectgenerator.h +++ b/qmake/generators/projectgenerator.h @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of ProjectGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index e274481..caaddee 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -1,7 +1,5 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. -** -** Created : 970521 +** Implementation of UnixMakefileGenerator class. ** @@ -9,3 +7,3 @@ ** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -80,6 +78,20 @@ UnixMakefileGenerator::init() } + if( project->isEmpty("QMAKE_CFLAGS_PRECOMPILE")) + project->variables()["QMAKE_CFLAGS_PRECOMPILE"].append("-x c-header -c"); + if( project->isEmpty("QMAKE_CXXFLAGS_PRECOMPILE")) + project->variables()["QMAKE_CXXFLAGS_PRECOMPILE"].append("-x c++-header -c"); + if( project->isEmpty("QMAKE_CFLAGS_USE_PRECOMPILE")) + project->variables()["QMAKE_CFLAGS_USE_PRECOMPILE"].append("-include"); + if( project->isEmpty("QMAKE_EXTENSION_PLUGIN") ) + project->variables()["QMAKE_EXTENSION_PLUGIN"].append(project->first("QMAKE_EXTENSION_SHLIB")); if( project->isEmpty("QMAKE_COPY_FILE") ) - project->variables()["QMAKE_COPY_FILE"].append( "$(COPY) -p" ); + project->variables()["QMAKE_COPY_FILE"].append( "$(COPY)" ); if( project->isEmpty("QMAKE_COPY_DIR") ) - project->variables()["QMAKE_COPY_DIR"].append( "$(COPY) -pR" ); + project->variables()["QMAKE_COPY_DIR"].append( "$(COPY) -R" ); + if( project->isEmpty("QMAKE_INSTALL_FILE") ) + project->variables()["QMAKE_INSTALL_FILE"].append( "$(COPY_FILE)" ); + if( project->isEmpty("QMAKE_INSTALL_DIR") ) + project->variables()["QMAKE_INSTALL_DIR"].append( "$(COPY_DIR)" ); + if( project->isEmpty("QMAKE_LIBTOOL") ) + project->variables()["QMAKE_LIBTOOL"].append( "libtool --silent" ); //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET @@ -105,4 +117,3 @@ UnixMakefileGenerator::init() project->isActiveConfig("dll")) || is_qt; - if(!project->isActiveConfig("global_init_link_order")) - project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; + project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; if ( (!project->isEmpty("QMAKE_LIB_FLAG") && !project->isActiveConfig("staticlib") ) || @@ -139,17 +150,18 @@ UnixMakefileGenerator::init() if ( !project->isEmpty("QMAKE_RPATH") ) - project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR", " " + var("QMAKE_RPATH"), - " " + var("QMAKE_RPATH"), ""); + project->variables()["QMAKE_LFLAGS"] += varGlue("QMAKE_LIBDIR", " " + var("QMAKE_RPATH"), + " " + var("QMAKE_RPATH"), ""); project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue( "QMAKE_LIBDIR", "-L", " -L", "" ); } - if ( extern_libs && (project->isActiveConfig("qt") || project->isActiveConfig("opengl")) ) { - if(configs.findIndex("x11lib") == -1) - configs.append("x11lib"); - if ( project->isActiveConfig("opengl") && configs.findIndex("x11inc") == -1 ) - configs.append("x11inc"); + if ( project->isActiveConfig("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); } - if ( project->isActiveConfig("x11") ) { - if(configs.findIndex("x11lib") == -1) - configs.append("x11lib"); - if(configs.findIndex("x11inc") == -1) - configs.append("x11inc"); + if ( project->isActiveConfig("qtopiainc") ) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"]; + if ( project->isActiveConfig("qtopialib") ) { + if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA")) + project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QTOPIA", "-L", " -L", ""); + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"]; } @@ -165,9 +177,13 @@ UnixMakefileGenerator::init() if ( !is_qt ) { - if ( !project->isEmpty("QMAKE_LIBDIR_QT") ) { - if ( !project->isEmpty("QMAKE_RPATH") ) - project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", " " + var("QMAKE_RPATH"), - " " + var("QMAKE_RPATH"), ""); - project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", "-L", " -L", ""); + if ( !project->isEmpty("QMAKE_RPATH") ) { + if ( !project->isEmpty("QMAKE_RTLDIR_QT") ) + project->variables()["QMAKE_LFLAGS"] += varGlue("QMAKE_RTLDIR_QT", " " + var("QMAKE_RPATH"), + " " + var("QMAKE_RPATH"), ""); + else if ( !project->isEmpty("QMAKE_LIBDIR_QT") ) + project->variables()["QMAKE_LFLAGS"] += varGlue("QMAKE_LIBDIR_QT", " " + var("QMAKE_RPATH"), + " " + var("QMAKE_RPATH"), ""); } - if (project->isActiveConfig("thread") && !project->isEmpty("QMAKE_LIBS_QT_THREAD")) + if ( !project->isEmpty("QMAKE_LIBDIR_QT") ) + project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", "-L", " -L", ""); + if ( project->isActiveConfig("thread") && !project->isEmpty("QMAKE_LIBS_QT_THREAD") ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; @@ -177,3 +193,3 @@ UnixMakefileGenerator::init() } - if ( project->isActiveConfig("opengl") ) { + if ( project->isActiveConfig("opengl") && !project->isActiveConfig("dlopen_opengl")) { project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"]; @@ -186,4 +202,14 @@ UnixMakefileGenerator::init() } - if(project->isActiveConfig("global_init_link_order")) - project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; + if ( extern_libs && (project->isActiveConfig("qt") || project->isActiveConfig("opengl")) ) { + if(configs.findIndex("x11lib") == -1) + configs.append("x11lib"); + if ( project->isActiveConfig("opengl") && configs.findIndex("x11inc") == -1 ) + configs.append("x11inc"); + } + if ( project->isActiveConfig("x11") ) { + if(configs.findIndex("x11lib") == -1) + configs.append("x11lib"); + if(configs.findIndex("x11inc") == -1) + configs.append("x11inc"); + } if ( project->isActiveConfig("x11inc") ) @@ -202,6 +228,10 @@ UnixMakefileGenerator::init() project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT"); - if ( !project->isEmpty("QMAKE_CFLAGS_THREAD")) + if ( !project->isEmpty("QMAKE_CFLAGS_THREAD")) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"]; - if( !project->isEmpty("QMAKE_CXXFLAGS_THREAD")) + project->variables()["PRL_EXPORT_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"]; + } + if( !project->isEmpty("QMAKE_CXXFLAGS_THREAD")) { project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"]; + project->variables()["PRL_EXPORT_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"]; + } project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_THREAD"]; @@ -213,13 +243,13 @@ UnixMakefileGenerator::init() setMocAware(TRUE); - if ( project->isEmpty("QMAKE_RUN_CC") ) - project->variables()["QMAKE_RUN_CC"].append("$(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src"); - if ( project->isEmpty("QMAKE_RUN_CC_IMP") ) - project->variables()["QMAKE_RUN_CC_IMP"].append("$(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<"); - if ( project->isEmpty("QMAKE_RUN_CXX") ) - project->variables()["QMAKE_RUN_CXX"].append("$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src"); - if ( project->isEmpty("QMAKE_RUN_CXX_IMP") ) - project->variables()["QMAKE_RUN_CXX_IMP"].append("$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<"); - project->variables()["QMAKE_FILETAGS"] += QStringList::split("HEADERS SOURCES TARGET DESTDIR", " "); - if ( !project->isEmpty("PRECOMPH") ) { - initOutPaths(); // Need to fix MOC_DIR since we do this before init() + QString compile_flag = var("QMAKE_COMPILE_FLAG"); + if(compile_flag.isEmpty()) + compile_flag = "-c"; + if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) { + QString prefix_flags = project->first("QMAKE_CFLAGS_PREFIX_INCLUDE"); + if(prefix_flags.isEmpty()) + prefix_flags = "-include"; + compile_flag += " " + prefix_flags + " " + project->first("QMAKE_ORIG_TARGET"); + } + if(!project->isEmpty("ALLMOC_HEADER")) { + initOutPaths(); // Need to fix outdirs since we do this before init() (because we could add to SOURCES et al) QString allmoc = fileFixify(project->first("MOC_DIR") + "/allmoc.cpp", QDir::currentDirPath(), Option::output_dir); @@ -229,4 +259,15 @@ UnixMakefileGenerator::init() } + if ( project->isEmpty("QMAKE_RUN_CC") ) + project->variables()["QMAKE_RUN_CC"].append("$(CC) " + compile_flag + " $(CFLAGS) $(INCPATH) -o $obj $src"); + if ( project->isEmpty("QMAKE_RUN_CC_IMP") ) + project->variables()["QMAKE_RUN_CC_IMP"].append("$(CC) " + compile_flag + " $(CFLAGS) $(INCPATH) -o $@ $<"); + if ( project->isEmpty("QMAKE_RUN_CXX") ) + project->variables()["QMAKE_RUN_CXX"].append("$(CXX) " + compile_flag + " $(CXXFLAGS) $(INCPATH) -o $obj $src"); + if ( project->isEmpty("QMAKE_RUN_CXX_IMP") ) + project->variables()["QMAKE_RUN_CXX_IMP"].append("$(CXX) " + compile_flag + " $(CXXFLAGS) $(INCPATH) -o $@ $<"); + project->variables()["QMAKE_FILETAGS"] += QStringList::split("HEADERS SOURCES TARGET DESTDIR", " "); if( project->isActiveConfig("GNUmake") && !project->isEmpty("QMAKE_CFLAGS_DEPS")) include_deps = TRUE; //do not generate deps + if(project->isActiveConfig("compile_libtool")) + Option::obj_ext = ".lo"; //override the .o @@ -242,6 +283,8 @@ UnixMakefileGenerator::init() - QString plist = specdir() + QDir::separator() + "Info.plist." + - project->first("TEMPLATE"); + QString plist = fileFixify(project->first("QMAKE_INFO_PLIST")); + if(plist.isEmpty()) + plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"); if(QFile::exists(Option::fixPathToLocalOS(plist))) { - project->variables()["QMAKE_INFO_PLIST"].append(plist); + if(project->isEmpty("QMAKE_INFO_PLIST")) + project->variables()["QMAKE_INFO_PLIST"].append(plist); project->variables()["QMAKE_INFO_PLIST_OUT"].append(project->first("DESTDIR") + @@ -285,2 +328,45 @@ UnixMakefileGenerator::init() } + + if(project->isActiveConfig("compile_libtool")) { + const QString libtoolify[] = { "QMAKE_RUN_CC", "QMAKE_RUN_CC_IMP", + "QMAKE_RUN_CXX", "QMAKE_RUN_CXX_IMP", + "QMAKE_LINK_THREAD", "QMAKE_LINK", "QMAKE_AR_CMD", "QMAKE_LINK_SHLIB_CMD", + QString::null }; + for(int i = 0; !libtoolify[i].isNull(); i++) { + QStringList &l = project->variables()[libtoolify[i]]; + if(!l.isEmpty()) { + QString libtool_flags, comp_flags; + if(libtoolify[i].startsWith("QMAKE_LINK") || libtoolify[i] == "QMAKE_AR_CMD") { + libtool_flags += " --mode=link"; + if(project->isActiveConfig("staticlib")) { + libtool_flags += " -static"; + } else { + if(!project->isEmpty("QMAKE_LIB_FLAG")) { + int maj = project->first("VER_MAJ").toInt(); + int min = project->first("VER_MIN").toInt(); + int pat = project->first("VER_PAT").toInt(); + comp_flags += " -version-info " + QString::number(10*maj + min) + + ":" + QString::number(pat) + ":0"; + if(libtoolify[i] != "QMAKE_AR_CMD") { + QString rpath = Option::output_dir; + if(!project->isEmpty("DESTDIR")) { + rpath = project->first("DESTDIR"); + if(QDir::isRelativePath(rpath)) + rpath.prepend(Option::output_dir + Option::dir_sep); + } + comp_flags += " -rpath " + Option::fixPathToTargetOS(rpath, FALSE); + } + } + } + if(project->isActiveConfig("plugin")) + libtool_flags += " -module"; + } else { + libtool_flags += " --mode=compile"; + } + l.first().prepend("$(LIBTOOL)" + libtool_flags + " "); + if(!comp_flags.isEmpty()) + l.first() += comp_flags; + } + } + } } @@ -288,42 +374,55 @@ UnixMakefileGenerator::init() QStringList -UnixMakefileGenerator::uniqueSetLFlags(const QStringList &list1, QStringList &list2) +UnixMakefileGenerator::combineSetLFlags(const QStringList &list1, const QStringList &list2) { + if(project->isActiveConfig("no_smart_library_merge")) + return list1 + list2; + QStringList ret; - for(QStringList::ConstIterator it = list1.begin(); it != list1.end(); ++it) { - bool unique = TRUE; - if((*it).startsWith("-")) { - if((*it).startsWith("-l") || (*it).startsWith("-L")) { - unique = list2.findIndex((*it)) == -1; - } else if(project->isActiveConfig("macx") && (*it).startsWith("-framework")) { - int as_one = TRUE; - QString framework_in; - if((*it).length() > 11) { - framework_in = (*it).mid(11); - } else { - if(it != list1.end()) { - ++it; - as_one = FALSE; - framework_in = (*it); + for(int i = 0; i < 2; i++) { + const QStringList *lst = i ? &list2 : &list1; + for(QStringList::ConstIterator it = lst->begin(); it != lst->end(); ++it) { + if((*it).startsWith("-")) { + if((*it).startsWith("-L")) { + if(ret.findIndex((*it)) == -1) + ret.append((*it)); + } else if((*it).startsWith("-l")) { + while(1) { + QStringList::Iterator idx = ret.find((*it)); + if(idx == ret.end()) + break; + ret.remove(idx); } - } - if(!framework_in.isEmpty()) { - for(QStringList::ConstIterator outit = list2.begin(); outit != list2.end(); ++outit) { - if((*outit).startsWith("-framework")) { - QString framework_out; - if((*outit).length() > 11) { - framework_out = (*outit).mid(11); - } else { - if(it != list2.end()) { - ++outit; - framework_out = (*outit); + ret.append((*it)); + } else if(project->isActiveConfig("macx") && (*it).startsWith("-framework")) { + int as_one = TRUE; + QString framework_in; + if((*it).length() > 11) { + framework_in = (*it).mid(11); + } else { + if(it != lst->end()) { + ++it; + as_one = FALSE; + framework_in = (*it); + } + } + if(!framework_in.isEmpty()) { + for(QStringList::Iterator outit = ret.begin(); outit != ret.end(); ++outit) { + if((*outit).startsWith("-framework")) { + int found = 0; + if((*outit).length() > 11) { + if(framework_in == (*outit).mid(11)) + found = 1; + } else { + if(it != lst->end()) { + ++outit; + if(framework_in == (*outit)) { + --outit; + found = 2; + } + } } - } - if(framework_out == framework_in) { - unique = FALSE; - break; + for(int i = 0; i < found; i++) + outit = ret.remove(outit); } } - } - if(unique) { - unique = FALSE; //because I'm about to just insert it myself if(as_one) { @@ -335,11 +434,23 @@ UnixMakefileGenerator::uniqueSetLFlags(const QStringList &list1, QStringList &li } + } else { +#if 1 + while(1) { + QStringList::Iterator idx = ret.find((*it)); + if(idx == ret.end()) + break; + ret.remove(idx); + } +#endif + ret.append((*it)); } - } else { - unique = (list2.findIndex((*it)) == -1); + } else /*if(QFile::exists((*it)))*/ { + while(1) { + QStringList::Iterator idx = ret.find((*it)); + if(idx == ret.end()) + break; + ret.remove(idx); + } + ret.append((*it)); } - } else if(QFile::exists((*it))) { - unique = (list2.findIndex((*it)) == -1); } - if(unique) - ret.append((*it)); } @@ -348,3 +459,2 @@ UnixMakefileGenerator::uniqueSetLFlags(const QStringList &list1, QStringList &li - void @@ -353,3 +463,4 @@ UnixMakefileGenerator::processPrlVariable(const QString &var, const QStringList if(var == "QMAKE_PRL_LIBS") - project->variables()["QMAKE_CURRENT_PRL_LIBS"] += uniqueSetLFlags(l, project->variables()["QMAKE_LIBS"]); + project->variables()["QMAKE_CURRENT_PRL_LIBS"] = combineSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"] + + project->variables()["QMAKE_LIBS"], l); else @@ -358,2 +469,68 @@ UnixMakefileGenerator::processPrlVariable(const QString &var, const QStringList +QString +UnixMakefileGenerator::findDependency(const QString &dep) +{ + QStringList::Iterator it; + { + QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"]; + for(it = qut.begin(); it != qut.end(); ++it) { + QString targ = var((*it) + ".target"); + if(targ.isEmpty()) + targ = (*it); + if(targ.endsWith(dep)) + return targ; + } + } + { + QStringList &quc = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QString out = tmp_out; + QFileInfo fi(Option::fixPathToLocalOS((*input))); + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(out.endsWith(dep)) + return out; + } + } + } + } + return MakefileGenerator::findDependency(dep); +} + +QStringList +&UnixMakefileGenerator::findDependencies(const QString &file) +{ + QStringList &ret = MakefileGenerator::findDependencies(file); + // Note: The QMAKE_IMAGE_COLLECTION file have all images + // as dependency, so don't add precompiled header then + if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER") + && file != project->first("QMAKE_IMAGE_COLLECTION")) { + QString header_prefix = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep; + header_prefix += project->first("QMAKE_PRECOMP_PREFIX"); + if(file.endsWith(".c")) { + QString precomp_h = header_prefix + "c"; + if(!ret.contains(precomp_h)) + ret += precomp_h; + } else { + for(QStringList::Iterator it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) { + if(file.endsWith(*it)) { + QString precomp_h = header_prefix + "c++"; + if(!ret.contains(precomp_h)) + ret += precomp_h; + break; + } + } + } + } + return ret; +} + bool @@ -402,3 +579,3 @@ UnixMakefileGenerator::findLibraries() if(!stub.isEmpty()) { - const QString modifs[] = { "-mt", QString::null }; + const QString modifs[] = { "", "-mt", QString::null }; for(int modif = 0; !modifs[modif].isNull(); modif++) { @@ -433,4 +610,14 @@ UnixMakefileGenerator::findLibraries() } + if(!found && project->isActiveConfig("compile_libtool")) { + for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { + if(QFile::exists(mdd->local_dir + Option::dir_sep + "lib" + stub + modifs[modif] + Option::libtool_ext)) { + (*it) = mdd->real_dir + Option::dir_sep + "lib" + stub + modifs[modif] + Option::libtool_ext; + found = TRUE; + break; + } + } + } if(found) break; + } @@ -442,2 +629,10 @@ UnixMakefileGenerator::findLibraries() +QString linkLib(const QString &file, const QString &libName) { + QString ret; + QRegExp reg("^.*lib(" + libName + "[^./=]*).*$"); + if(reg.exactMatch(file)) + ret = "-l" + reg.cap(1); + return ret; +} + void @@ -455,3 +650,3 @@ UnixMakefileGenerator::processPrlFiles() project->variables()["QMAKE_CURRENT_PRL_LIBS"].clear(); - QString opt = (*it).stripWhiteSpace();; + QString opt = (*it).stripWhiteSpace(); if(opt.startsWith("-")) { @@ -463,5 +658,14 @@ UnixMakefileGenerator::processPrlFiles() } else if(opt.startsWith("-l") && !processed[opt]) { - QString lib = opt.right(opt.length() - 2), prl; + QString lib = opt.right(opt.length() - 2); for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { - prl = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::prl_ext; + if(!project->isActiveConfig("compile_libtool")) { //give them the .libs.. + QString la = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::libtool_ext; + if(QFile::exists(la) && QFile::exists(mdd->local_dir + Option::dir_sep + ".libs")) { + l_out.append("-L" + mdd->real_dir + Option::dir_sep + ".libs"); + libdirs.append(new MakefileDependDir(mdd->real_dir + Option::dir_sep + ".libs", + mdd->local_dir + Option::dir_sep + ".libs")); + } + } + + QString prl = mdd->local_dir + Option::dir_sep + "lib" + lib; if(processPrlFile(prl)) { @@ -469,6 +673,3 @@ UnixMakefileGenerator::processPrlFiles() prl.replace(0, mdd->local_dir.length(), mdd->real_dir); - QRegExp reg("^.*lib(" + lib + "[^./=]*)\\..*$"); - if(reg.exactMatch(prl)) - prl = "-l" + reg.cap(1); - opt = prl; + opt = linkLib(prl, lib); processed.insert(opt, (void*)1); @@ -486,3 +687,3 @@ UnixMakefileGenerator::processPrlFiles() QString prl = "/System/Library/Frameworks/" + opt + - ".framework/" + opt + Option::prl_ext; + ".framework/" + opt; if(processPrlFile(prl)) @@ -493,11 +694,16 @@ UnixMakefileGenerator::processPrlFiles() l_out.append(opt); - l_out += uniqueSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"], l_out); + l_out = combineSetLFlags(l_out, project->variables()["QMAKE_CURRENT_PRL_LIBS"]); } else { - if(!processed[opt] && processPrlFile(opt)) { - processed.insert(opt, (void*)1); - ret = TRUE; + QString lib = opt; + if(!processed[lib] && processPrlFile(lib)) { + processed.insert(lib, (void*)1); + ret = TRUE; } +#if 0 + if(ret) + opt = linkLib(lib, ""); +#endif if(!opt.isEmpty()) - l_out.append(opt); - l_out += uniqueSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"], l_out); + l_out.append(opt); + l_out = combineSetLFlags(l_out, project->variables()["QMAKE_CURRENT_PRL_LIBS"]); } @@ -539,3 +745,4 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } else if(project->first("TEMPLATE") == "lib") { - if(project->isActiveConfig("create_prl") && !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) { + if(project->isActiveConfig("create_prl") && !project->isActiveConfig("no_install_prl") && + !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) { QString dst_prl = project->first("QMAKE_INTERNAL_PRL_FILE"); @@ -545,3 +752,3 @@ UnixMakefileGenerator::defaultInstall(const QString &t) dst_prl = root + targetdir + dst_prl; - ret += "-$(COPY) \"" + project->first("QMAKE_INTERNAL_PRL_FILE") + "\" \"" + dst_prl + "\""; + ret += "-$(INSTALL_FILE) \"" + project->first("QMAKE_INTERNAL_PRL_FILE") + "\" \"" + dst_prl + "\""; if(!uninst.isEmpty()) @@ -550,2 +757,49 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } + if(project->isActiveConfig("create_libtool") && !project->isActiveConfig("compile_libtool")) { + QString src_lt = var("QMAKE_ORIG_TARGET"); + int slsh = src_lt.findRev(Option::dir_sep); + if(slsh != -1) + src_lt = src_lt.right(src_lt.length() - slsh); + int dot = src_lt.find('.'); + if(dot != -1) + src_lt = src_lt.left(dot); + src_lt += Option::libtool_ext; + src_lt.prepend("lib"); + QString dst_lt = root + targetdir + src_lt; + if(!project->isEmpty("DESTDIR")) { + src_lt.prepend(var("DESTDIR")); + src_lt = Option::fixPathToLocalOS(fileFixify(src_lt, + QDir::currentDirPath(), Option::output_dir)); + } + if(!ret.isEmpty()) + ret += "\n\t"; + ret += "-$(INSTALL_FILE) \"" + src_lt + "\" \"" + dst_lt + "\""; + if(!uninst.isEmpty()) + uninst.append("\n\t"); + uninst.append("-$(DEL_FILE) \"" + dst_lt + "\""); + } + if(project->isActiveConfig("create_pc")) { + QString src_pc = var("QMAKE_ORIG_TARGET"); + int slsh = src_pc.findRev(Option::dir_sep); + if(slsh != -1) + src_pc = src_pc.right(src_pc.length() - slsh); + int dot = src_pc.find('.'); + if(dot != -1) + src_pc = src_pc.left(dot); + src_pc += ".pc"; + QString d = root + targetdir + "pkgconfig" + Option::dir_sep; + QString dst_pc = d + src_pc; + if(!project->isEmpty("DESTDIR")) { + src_pc.prepend(var("DESTDIR")); + src_pc = Option::fixPathToLocalOS(fileFixify(src_pc, + QDir::currentDirPath(), Option::output_dir)); + } + if(!ret.isEmpty()) + ret += "\n\t"; + ret += mkdir_p_asstring(d) + "\n\t"; + ret += "-$(INSTALL_FILE) \"" + src_pc + "\" \"" + dst_pc + "\""; + if(!uninst.isEmpty()) + uninst.append("\n\t"); + uninst.append("-$(DEL_FILE) \"" + dst_pc + "\""); + } if ( project->isEmpty("QMAKE_CYGWIN_SHLIB") ) { @@ -560,40 +814,60 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } - QString src_targ = target; - if(!destdir.isEmpty()) - src_targ = Option::fixPathToTargetOS(destdir + target, FALSE); - QString dst_targ = root + fileFixify(targetdir + target); - if(!ret.isEmpty()) - ret += "\n\t"; - ret += QString(resource ? "-$(COPY_DIR)" : "-$(COPY)") + " \"" + - src_targ + "\" \"" + dst_targ + "\""; - if(!project->isActiveConfig("debug") && !project->isEmpty("QMAKE_STRIP")) { - ret += "\n\t-" + var("QMAKE_STRIP"); - if(!project->isEmpty("QMAKE_STRIPFLAGS_LIB") && project->first("TEMPLATE") == "lib") - ret += " " + var("QMAKE_STRIPFLAGS_LIB"); + + if(!resource && project->isActiveConfig("compile_libtool")) { + QString src_targ = target; + if(src_targ == "$(TARGET)") + src_targ = "$(TARGETL)"; + QString dst_dir = fileFixify(targetdir); + if(QDir::isRelativePath(dst_dir)) + dst_dir = Option::fixPathToTargetOS(Option::output_dir + Option::dir_sep + dst_dir); + ret = "-$(LIBTOOL) --mode=install cp \"" + src_targ + "\" \"" + root + dst_dir + "\""; + uninst.append("-$(LIBTOOL) --mode=uninstall \"" + src_targ + "\""); + } else { + QString src_targ = target; + if(!destdir.isEmpty()) + src_targ = Option::fixPathToTargetOS(destdir + target, FALSE); + QString dst_targ = root + fileFixify(targetdir + target, + QDir::currentDirPath(), Option::output_dir); + if(!ret.isEmpty()) + ret += "\n\t"; if(resource) - ret = " \"" + dst_targ + "/Contents/MacOS/$(QMAKE_TARGET)\""; + ret += "$(DEL_FILE) -r \"" + dst_targ + "\"" + "\n\t"; + if(!ret.isEmpty()) + ret += "\n\t"; + ret += QString(resource ? "-$(INSTALL_DIR)" : "-$(INSTALL_FILE)") + " \"" + + src_targ + "\" \"" + dst_targ + "\""; + if(!project->isActiveConfig("debug") && !project->isEmpty("QMAKE_STRIP") && + (project->first("TEMPLATE") != "lib" || !project->isActiveConfig("staticlib"))) { + ret += "\n\t-" + var("QMAKE_STRIP"); + if(project->first("TEMPLATE") == "lib" && !project->isEmpty("QMAKE_STRIPFLAGS_LIB")) + ret += " " + var("QMAKE_STRIPFLAGS_LIB"); + else if(project->first("TEMPLATE") == "app" && !project->isEmpty("QMAKE_STRIPFLAGS_APP")) + ret += " " + var("QMAKE_STRIPFLAGS_APP"); + if(resource) + ret = " \"" + dst_targ + "/Contents/MacOS/$(QMAKE_TARGET)\""; + else + ret += " \"" + dst_targ + "\""; + } + if(!uninst.isEmpty()) + uninst.append("\n\t"); + if(resource) + uninst.append("-$(DEL_FILE) -r \"" + dst_targ + "\""); else - ret += " \"" + dst_targ + "\""; - } - if(!uninst.isEmpty()) - uninst.append("\n\t"); - if(resource) - uninst.append("-$(DEL_FILE) -r \"" + dst_targ + "\""); - else - uninst.append("-$(DEL_FILE) \"" + dst_targ + "\""); - if(!links.isEmpty()) { - for(QStringList::Iterator it = links.begin(); it != links.end(); it++) { - if(Option::target_mode == Option::TARG_WIN_MODE || - Option::target_mode == Option::TARG_MAC9_MODE) { - } else if(Option::target_mode == Option::TARG_UNIX_MODE || - Option::target_mode == Option::TARG_MACX_MODE) { - QString link = Option::fixPathToTargetOS(destdir + (*it), FALSE); - int lslash = link.findRev(Option::dir_sep); - if(lslash != -1) - link = link.right(link.length() - (lslash + 1)); - QString dst_link = root + fileFixify(targetdir + link); - ret += "\n\t-$(SYMLINK) \"$(TARGET)\" \"" + dst_link + "\""; - if(!uninst.isEmpty()) - uninst.append("\n\t"); - uninst.append("-$(DEL_FILE) \"" + dst_link + "\""); + uninst.append("-$(DEL_FILE) \"" + dst_targ + "\""); + if(!links.isEmpty()) { + for(QStringList::Iterator it = links.begin(); it != links.end(); it++) { + if(Option::target_mode == Option::TARG_WIN_MODE || + Option::target_mode == Option::TARG_MAC9_MODE) { + } else if(Option::target_mode == Option::TARG_UNIX_MODE || + Option::target_mode == Option::TARG_MACX_MODE) { + QString link = Option::fixPathToTargetOS(destdir + (*it), FALSE); + int lslash = link.findRev(Option::dir_sep); + if(lslash != -1) + link = link.right(link.length() - (lslash + 1)); + QString dst_link = root + targetdir + link; + ret += "\n\t-$(SYMLINK) \"$(TARGET)\" \"" + dst_link + "\""; + if(!uninst.isEmpty()) + uninst.append("\n\t"); + uninst.append("-$(DEL_FILE) \"" + dst_link + "\""); + } } @@ -603,2 +877 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } - diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h index 3d00214..91ec3b1 100644 --- a/qmake/generators/unix/unixmake.h +++ b/qmake/generators/unix/unixmake.h @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of UnixMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -36,2 +34,3 @@ **********************************************************************/ + #ifndef __UNIXMAKE_H__ @@ -45,3 +44,11 @@ class UnixMakefileGenerator : public MakefileGenerator bool writeMakefile(QTextStream &); - QStringList uniqueSetLFlags(const QStringList &list1, QStringList &list2); + void writeExtraVariables(QTextStream &); + QString libtoolFileName(); + void writeLibtoolFile(); // for libtool + QString pkgConfigPrefix() const; + QString pkgConfigFileName(); + QString pkgConfigFixPath(QString) const; + void writePkgConfigFile(); // for pkg-config + QStringList combineSetLFlags(const QStringList &list1, const QStringList &list2); + void writePrlFile(QTextStream &); @@ -52,2 +59,3 @@ public: protected: + virtual bool doPrecompiledHeaders() const { return project->isActiveConfig("precompile_header"); } virtual bool doDepends() const { return !include_deps && MakefileGenerator::doDepends(); } @@ -58,2 +66,4 @@ protected: virtual bool findLibraries(); + virtual QString findDependency(const QString &); + virtual QStringList &findDependencies(const QString &); virtual void init(); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index d8a4a0d..21348a6 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ ** -** Definition of ________ class. ** -** Created : 970521 +** Implementation of UnixMakefileGenerator class. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -39,2 +37,3 @@ #include "option.h" +#include "meta.h" #include <qregexp.h> @@ -44,2 +43,3 @@ +QString mkdir_p_asstring(const QString &dir); @@ -50,2 +50,19 @@ UnixMakefileGenerator::UnixMakefileGenerator(QMakeProject *p) : MakefileGenerato +void +UnixMakefileGenerator::writePrlFile(QTextStream &t) +{ + MakefileGenerator::writePrlFile(t); + // libtool support + if(project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib") { //write .la + if(project->isActiveConfig("compile_libtool")) + warn_msg(WarnLogic, "create_libtool specified with compile_libtool can lead to conflicting .la\n" + "formats, create_libtool has been disabled\n"); + else + writeLibtoolFile(); + } + // pkg-config support + if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib") + writePkgConfigFile(); +} + bool @@ -53,5 +70,12 @@ UnixMakefileGenerator::writeMakefile(QTextStream &t) { + writeHeader(t); if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { - t << "all clean:" << "\n\t" + t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; + { //write the extra unix targets.. + QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"]; + for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it) + t << *it << " "; + } + t << "all clean install distclean mocables uninstall uicables:" << "\n\t" << "@echo \"Some of the required modules (" @@ -75,5 +99,27 @@ UnixMakefileGenerator::writeMakefile(QTextStream &t) void +UnixMakefileGenerator::writeExtraVariables(QTextStream &t) +{ + bool first = TRUE; + QMap<QString, QStringList> &vars = project->variables(); + QStringList &exports = project->variables()["QMAKE_EXTRA_UNIX_VARIABLES"]; + for(QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) { + for(QStringList::Iterator exp_it = exports.begin(); exp_it != exports.end(); ++exp_it) { + QRegExp rx((*exp_it), FALSE, TRUE); + if(rx.exactMatch(it.key())) { + if(first) { + t << "\n####### Custom Variables" << endl; + first = FALSE; + } + t << "EXPORT_" << it.key() << " = " << it.data().join(" ") << endl; + } + } + } + if(!first) + t << endl; +} + +void UnixMakefileGenerator::writeMakeParts(QTextStream &t) { - QString deps = fileFixify(Option::output.name()), prl; + QString deps = fileFixify(Option::output.name()), target_deps, prl; bool do_incremental = (project->isActiveConfig("incremental") && @@ -81,3 +127,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) (!project->variables()["QMAKE_APP_FLAG"].isEmpty() || - !project->isActiveConfig("staticlib"))), + !project->isActiveConfig("staticlib"))), src_incremental=FALSE, moc_incremental=FALSE; @@ -137,2 +183,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "GZIP = " << var("QMAKE_GZIP") << endl; + if(project->isActiveConfig("compile_libtool")) + t << "LIBTOOL = " << var("QMAKE_LIBTOOL") << endl; t << "COPY = " << var("QMAKE_COPY") << endl; @@ -140,2 +188,5 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "COPY_DIR = " << var("QMAKE_COPY_DIR") << endl; + t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl; + t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; @@ -222,2 +273,16 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) do_incremental = FALSE; + if(!project->isEmpty("QMAKE_EXTRA_UNIX_COMPILERS")) { + t << "OBJCOMP = " << varList("OBJCOMP") << endl; + target_deps += " $(OBJCOMP)"; + + QStringList &comps = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"]; + for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) { + QStringList &vars = project->variables()[(*compit) + ".variables"]; + for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) { + QStringList vals = project->variables()[(*varit)]; + if(!vals.isEmpty()) + t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << endl; + } + } + } t << "DIST = " << valList(fileFixify(project->variables()["DISTFILES"])) << endl; @@ -225,2 +290,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "DESTDIR = " << var("DESTDIR") << endl; + if(project->isActiveConfig("compile_libtool")) + t << "TARGETL = " << var("TARGET_la") << endl; t << "TARGET = " << var("TARGET") << endl; @@ -240,5 +307,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } + writeExtraVariables(t); t << endl; - // blasted incldues + // blasted includes QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"]; @@ -251,3 +319,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "####### Implicit rules" << endl << endl; - t << ".SUFFIXES: .c"; + t << ".SUFFIXES: .c " << Option::obj_ext; QStringList::Iterator cppit; @@ -257,4 +325,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) - t << (*cppit) << ".o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".c.o:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; + t << (*cppit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".c" << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; @@ -280,3 +348,2 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) - QString src[] = { "SOURCES", "UICIMPLS", "SRCMOC", QString::null }; @@ -300,6 +367,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) d_file = odir + ".deps/" + d_file + ".d"; - QStringList deps = findDependencies((*it)).grep(QRegExp(Option::moc_ext + "$")); + QStringList deps = findDependencies((*it)).grep(QRegExp(Option::cpp_moc_ext + "$")); if(!deps.isEmpty()) t << d_file << ": " << deps.join(" ") << endl; - t << "-include " << d_file << endl; + t << var("QMAKE_CFLAGS_USE_PRECOMPILE") << " " << d_file << endl; } @@ -325,4 +392,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) for(it = l.begin(); it != l.end(); ++it) { - QMakeProject proj; - if(proj.read((*it), QDir::currentDirPath()) && !proj.isEmpty("QMAKE_PRL_BUILD_DIR")) { + QMakeMetaInfo libinfo; + if(libinfo.readLib((*it)) && !libinfo.isEmpty("QMAKE_PRL_BUILD_DIR")) { QString dir; @@ -331,3 +398,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) dir = (*it).left(slsh + 1); - QString targ = dir + proj.first("QMAKE_PRL_TARGET"); + QString targ = dir + libinfo.first("QMAKE_PRL_TARGET"); deps += " " + targ; @@ -335,3 +402,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << "@echo \"Creating '" << targ << "'\"" << "\n\t" - << "(cd " << proj.first("QMAKE_PRL_BUILD_DIR") << ";" + << "(cd " << libinfo.first("QMAKE_PRL_BUILD_DIR") << ";" << "$(MAKE) )" << endl; @@ -394,3 +461,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) //real target - t << var("TARGET") << ": " << var("PRE_TARGETDEPS") << " " << incr_deps + t << var("TARGET") << ": " << var("PRE_TARGETDEPS") << " " << incr_deps << " " << target_deps << " " << var("POST_TARGETDEPS") << "\n\t"; @@ -400,3 +467,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << var("QMAKE_PRE_LINK") << "\n\t"; - t << "$(LINK) $(LFLAGS) -o $(TARGET) " << incr_deps << " " << incr_objs << " $(LIBS)"; + t << "$(LINK) $(LFLAGS) -o $(TARGET) " << incr_deps << " " << incr_objs << " $(OBJCOMP) $(LIBS)"; if(!project->isEmpty("QMAKE_POST_LINK")) @@ -408,4 +475,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) - t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " - << var("POST_TARGETDEPS") << "\n\t"; + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << target_deps << " " << var("POST_TARGETDEPS") << "\n\t"; if(!destdir.isEmpty()) @@ -414,3 +481,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << var("QMAKE_PRE_LINK") << "\n\t"; - t << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)"; + t << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(OBJCOMP) $(LIBS)"; if(!project->isEmpty("QMAKE_POST_LINK")) @@ -470,4 +537,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) //real target - t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") << " " - << incr_deps << " $(SUBLIBS) " << var("POST_TARGETDEPS"); + t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") << " " + << incr_deps << " $(SUBLIBS) " << target_deps << " " << var("POST_TARGETDEPS"); } else { @@ -475,4 +542,5 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) var("DESTDIR_TARGET") << endl << endl; - t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") - << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) " << var("POST_TARGETDEPS"); + t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") + << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) $(OBJCOMP) " << target_deps + << " " << var("POST_TARGETDEPS"); } @@ -483,3 +551,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) - if(project->isActiveConfig("plugin")) { + if(project->isActiveConfig("compile_libtool")) { + t << "\n\t" + << var("QMAKE_LINK_SHLIB_CMD"); + } else if(project->isActiveConfig("plugin")) { t << "\n\t" @@ -528,3 +599,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "staticlib: $(TARGETA)" << endl << endl; - t << "$(TARGETA): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC)"; + t << "$(TARGETA): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(OBJCOMP)"; if(do_incremental) @@ -541,3 +612,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } else { - t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << var("DESTDIR") << "$(TARGET) " + t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << var("DESTDIR") << "$(TARGET) " << varGlue("QMAKE_AR_SUBLIBS", var("DESTDIR"), " " + var("DESTDIR"), "") << "\n\n" @@ -545,4 +616,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(project->isEmpty("QMAKE_AR_SUBLIBS")) { - t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") - << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("POST_TARGETDEPS") << "\n\t"; + t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") + << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(OBJCOMP) " << var("POST_TARGETDEPS") << "\n\t"; if(!project->isEmpty("DESTDIR")) { @@ -557,3 +628,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t" << "$(RANLIB) $(TARGET)" << "\n"; - if(!project->isEmpty("DESTDIR")) + if(!project->isEmpty("DESTDIR")) t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)" << "\n" @@ -562,9 +633,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(); - QStringList objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"], + QStringList objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"] + + project->variables()["OBJCOMP"], libs = project->variables()["QMAKE_AR_SUBLIBS"]; libs.prepend("$(TARGET)"); - for(QStringList::Iterator libit = libs.begin(), objit = objs.begin(); + for(QStringList::Iterator libit = libs.begin(), objit = objs.begin(); libit != libs.end(); ++libit) { QStringList build; - for(int cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++) + for(int cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++) build << (*objit); @@ -572,6 +644,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if((*libit) == "$(TARGET)") { - t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") + t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) " << var("POST_TARGETDEPS") << valList(build) << "\n\t"; ar = project->variables()["QMAKE_AR_CMD"].first(); - ar = ar.replace("$(OBJMOC)", "").replace("$(OBJECTS)", + ar = ar.replace("$(OBJMOC)", "").replace("$(OBJECTS)", build.join(" ")); @@ -591,3 +663,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t" << "$(RANLIB) " << (*libit) << "\n"; - if(!project->isEmpty("DESTDIR")) + if(!project->isEmpty("DESTDIR")) t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << (*libit) << "\n" @@ -599,3 +671,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) - t << "mocables: $(SRCMOC)" << endl << endl; + t << "mocables: $(SRCMOC)" << endl + << "uicables: $(UICDECLS) $(UICIMPLS)" << endl << endl; @@ -605,8 +678,11 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) //better than the alternative for now. - QString moc = project->first("QMAKE_MOC"), target = project->first("TARGET"); + QString moc = project->first("QMAKE_MOC"), target = project->first("TARGET"), + moc_dir = "$(QTDIR)/src/moc"; + if(!project->isEmpty("QMAKE_MOC_SRC")) + moc_dir = project->first("QMAKE_MOC_SRC"); fixEnvVariables(target); fixEnvVariables(moc); - if(target != moc) + if(target != moc) t << "$(MOC): \n\t" - << "( cd $(QTDIR)/src/moc ; $(MAKE) )" << endl << endl; + << "( cd " << moc_dir << " && $(MAKE) )" << endl << endl; } @@ -614,2 +690,21 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) writeMakeQmake(t); + if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isActiveConfig("no_autoqmake")) { + QString meta_files; + if(project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib" && + !project->isActiveConfig("compile_libtool")) { //libtool + if(!meta_files.isEmpty()) + meta_files += " "; + meta_files += libtoolFileName(); + } + if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib") { //pkg-config + if(!meta_files.isEmpty()) + meta_files += " "; + meta_files += pkgConfigFileName(); + } + if(!meta_files.isEmpty()) { + QStringList files = fileFixify(Option::mkfile::project_files); + t << meta_files << ": " << "\n\t" + << "@$(QMAKE) -prl " << buildArgs() << " " << files.join(" ") << endl; + } + } @@ -626,3 +721,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) QString info_plist = project->first("QMAKE_INFO_PLIST"), - info_plist_out = project->first("QMAKE_INFO_PLIST_OUT"); + info_plist_out = project->first("QMAKE_INFO_PLIST_OUT"); QString destdir = project->first("DESTDIR"); @@ -632,8 +727,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "@$(DEL_FILE) " << info_plist_out << "\n\t" - << "@cp \"" << info_plist << "\" \"" << info_plist_out << "\"" << endl; + << "@sed -e \"s,@ICON@,application.icns,g\" -e \"s,@EXECUTABLE@," << var("QMAKE_ORIG_TARGET") + << ",g\" \"" << info_plist << "\" >\"" << info_plist_out << "\"" << endl; if(!project->first("RC_FILE").isEmpty()) { QString dir = destdir + "../Resources/"; - t << dir << "application.icns:" << "\n\t" + t << dir << "application.icns: " << var("RC_FILE") << "\n\t" << "@test -d " << dir << " || mkdir -p " << dir << "\n\t" - << "@cp " << var("RC_FILE") << " " << dir << "application.icns" << endl; + << "@$(DEL_FILE) " << dir << "application.icns" << "\n\t" + << "@$(COPY_FILE) " << var("RC_FILE") << " " << dir << "application.icns" << endl; } @@ -650,2 +747,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "$(COPY_FILE) --parents " << var("TRANSLATIONS") << " " << ddir_c << Option::dir_sep << " && "; + if(!project->isEmpty("IMAGES")) + t << "$(COPY_FILE) --parents " << var("IMAGES") << " " << ddir_c << Option::dir_sep << " && "; if(!project->isEmpty("FORMS")) { @@ -654,3 +753,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) QString ui_h = fileFixify((*formit) + Option::h_ext.first()); - if(QFile::exists(ui_h) ) + if(QFile::exists(ui_h) ) ui_headers << ui_h; @@ -668,4 +767,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) QString clean_targets; + t << "mocclean:" << "\n"; if(mocAware()) { - t << "mocclean:" << "\n"; if(!objMoc.isEmpty() || !srcMoc.isEmpty() || moc_incremental) { @@ -699,4 +798,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) dir += Option::dir_sep; - clean << dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first(); - clean << dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first(); + clean << ( dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first() ); + clean << ( dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first() ); } @@ -719,3 +818,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) dir += Option::dir_sep; - clean << dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first(); + clean << ( dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first() ); } @@ -737,4 +836,14 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "clean:" << clean_targets << "\n\t"; - if(!project->isEmpty("OBJECTS")) - t << "-$(DEL_FILE) $(OBJECTS) " << "\n\t"; + if(!project->isEmpty("OBJECTS")) { + if(project->isActiveConfig("compile_libtool")) + t << "-$(LIBTOOL) --mode=clean $(DEL_FILE) $(OBJECTS)" << "\n\t"; + else + t << "-$(DEL_FILE) $(OBJECTS)" << "\n\t"; + } + if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) { + QString header_prefix = project->first("QMAKE_PRECOMP_PREFIX"); + QString precomph_out_dir = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep; + t << "-$(DEL_FILE) " << precomph_out_dir << header_prefix + "c " + << precomph_out_dir << header_prefix << "c++" << "\n\t"; + } if(!project->isEmpty("IMAGES")) @@ -764,2 +873,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t-$(DEL_FILE) -r " << destdir.section(Option::dir_sep, 0, -4) << "\n"; + else if(project->isActiveConfig("compile_libtool")) + t << "\t-$(LIBTOOL) --mode=clean $(DEL_FILE) " << "$(TARGET)" << "\n"; else @@ -767,3 +878,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty() && - !project->isActiveConfig("plugin")) + !project->isActiveConfig("plugin") && !project->isActiveConfig("compile_libtool")) t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " @@ -772,15 +883,37 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) - if ( !project->isEmpty("PRECOMPH") ) { + if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER") ) { + QString precomph = fileFixify(project->first("PRECOMPILED_HEADER")); + t << "###### Prefix headers" << endl; + QString comps[] = { "C", "CXX", QString::null }; + for(int i = 0; !comps[i].isNull(); i++) { + QString flags = var("QMAKE_" + comps[i] + "FLAGS_PRECOMPILE"); + flags += " $(" + comps[i] + "FLAGS)"; + + QString header_prefix = project->first("QMAKE_PRECOMP_PREFIX"); + QString outdir = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep, outfile = outdir; + QString compiler; + if(comps[i] == "C") { + outfile += header_prefix + "c"; + compiler = "$(CC) "; + } else { + outfile += header_prefix + "c++"; + compiler = "$(CXX) "; + } + t << outfile << ": " << precomph << " " << findDependencies(precomph).join(" \\\n\t\t") + << "\n\t" << "test -d " << outdir << " || mkdir -p " << outdir + << "\n\t" << compiler << flags << " $(INCPATH) " << precomph << " -o " << outfile << endl << endl; + } + } + if(!project->isEmpty("ALLMOC_HEADER")) { QString outdir = project->first("MOC_DIR"); - QString qt_dot_h = Option::fixPathToLocalOS(project->first("PRECOMPH")); - t << "###### Combined headers" << endl << endl; - //XXX - t << outdir << "allmoc.cpp: " << qt_dot_h << " " + QString precomph = fileFixify(project->first("ALLMOC_HEADER")); + t << "###### Combined headers" << endl << endl + << outdir << "allmoc.cpp: " << precomph << " " << varList("HEADERS_ORIG") << "\n\t" - << "echo '#include \"" << qt_dot_h << "\"' >" << outdir << "allmoc.cpp" << "\n\t" + << "echo '#include \"" << precomph << "\"' >" << outdir << "allmoc.cpp" << "\n\t" << "$(CXX) -E -DQT_MOC_CPP -DQT_NO_STL $(CXXFLAGS) $(INCPATH) >" << outdir << "allmoc.h " - << outdir << "allmoc.cpp" << "\n\t" + << outdir << "allmoc.cpp" << "\n\t" << "$(MOC) -o " << outdir << "allmoc.cpp " << outdir << "allmoc.h" << "\n\t" << "perl -pi -e 's{#include \"allmoc.h\"}{#define QT_H_CPP\\n#include \"" - << qt_dot_h << "\"}' " << outdir << "allmoc.cpp" << "\n\t" + << precomph << "\"}' " << outdir << "allmoc.cpp" << "\n\t" << "$(DEL_FILE) " << outdir << "allmoc.h" << endl << endl; @@ -788,3 +921,3 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) - // blasted user defined targets + // user defined targets QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"]; @@ -802,2 +935,4 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } + if(project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; t << targ << ":" << deps << "\n\t" @@ -805,2 +940,50 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } + // user defined compilers + QStringList &quc = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + QString tmp_dep = project->variables()[(*it) + ".depends"].join(" "); + QStringList &vars = project->variables()[(*it) + ".variables"]; + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out, cmd = tmp_cmd, deps; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + cmd.replace("${QMAKE_FILE_BASE}", fi.baseName()); + cmd.replace("${QMAKE_FILE_OUT}", out); + cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3) + cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); + if(!tmp_dep.isEmpty()) { + char buff[256]; + QString dep_cmd = tmp_dep; + dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) { + while(!feof(proc)) { + int read_in = int(fread(buff, 1, 255, proc)); + if(!read_in) + break; + int l = 0; + for(int i = 0; i < read_in; i++) { + if(buff[i] == '\n' || buff[i] == ' ') { + deps += " " + QCString(buff+l, (i - l) + 1); + l = i; + } + } + } + fclose(proc); + } + } + t << out << ": " << in << deps << "\n\t" + << cmd << endl << endl; + } + } + } t <<"FORCE:" << endl << endl; @@ -816,2 +999,8 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) { + // blasted includes + QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"]; + for(QStringList::Iterator qeui_it = qeui.begin(); qeui_it != qeui.end(); ++qeui_it) + t << "include " << (*qeui_it) << endl; + writeExtraVariables(t); + QPtrList<SubDir> subdirs; @@ -834,2 +1023,4 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) } else { + if(!file.isEmpty()) + sd->profile = file.section(Option::dir_sep, -1) + ".pro"; sd->directory = file; @@ -859,4 +1050,8 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; + t << "CHK_DIR_EXISTS= " << var("QMAKE_CHK_DIR_EXISTS") << endl; + t << "MKDIR = " << var("QMAKE_MKDIR") << endl; + t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl; t << "SUBTARGETS = "; // subdirectory targets are sub-directory - for( it.toFirst(); it.current(); ++it) + for( it.toFirst(); it.current(); ++it) t << " \\\n\t\t" << it.current()->target; @@ -876,4 +1071,6 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) if(have_dir) - t << "cd " << (*it)->directory << " && "; - t << "$(QMAKE) " << (*it)->profile << buildArgs() << out << endl; + t << mkdir_p_asstring((*it)->directory) << "\n\t" + << "cd " << (*it)->directory << " && "; + QString profile = fileFixify((*it)->profile, (*it)->directory, (*it)->directory); + t << "$(QMAKE) " << profile << buildArgs() << out << endl; //actually compile @@ -889,3 +1086,3 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) ++it; - if (it.current()) + if (it.current()) t << it.current()->target << ": " << tar << endl; @@ -898,3 +1095,4 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) if(project->isEmpty("SUBDIRS")) { - t << "all qmake_all distclean install uiclean mocclean lexclean yaccclean clean: FORCE" << endl; + t << "all qmake_all distclean uicables mocables install_subdirs uninstall_subdirs" + << " uiclean mocclean lexclean yaccclean clean " << var("SUBDIR_TARGETS") << ": FORCE" << endl; } else { @@ -912,3 +1110,3 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; "; - t << "grep \"^qmake_all:\" " << (*it)->makefile + t << "grep \"^qmake_all:\" " << (*it)->makefile << " && $(MAKE) -f " << (*it)->makefile << " qmake_all" << "; ) || true"; @@ -916,3 +1114,4 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) t << endl; - t << "clean uninstall install uiclean mocclean lexclean yaccclean: qmake_all FORCE"; + t << "clean uicables mocables uiclean mocclean lexclean yaccclean " + << var("SUBDIR_TARGETS") << ": qmake_all FORCE"; for( it.toFirst(); it.current(); ++it) { @@ -924,2 +1123,18 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) t << endl; + t << "uninstall_subdirs: qmake_all FORCE"; + for( it.toFirst(); it.current(); ++it) { + t << "\n\t ( "; + if(!(*it)->directory.isEmpty()) + t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; "; + t << "$(MAKE) -f " << (*it)->makefile << " uninstall" << "; ) || true"; + } + t << endl; + t << "install_subdirs: qmake_all FORCE"; + for( it.toFirst(); it.current(); ++it) { + t << "\n\t ( "; + if(!(*it)->directory.isEmpty()) + t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; "; + t << "$(MAKE) -f " << (*it)->makefile << " install" << "; ) || true"; + } + t << endl; t << "distclean: qmake_all FORCE"; @@ -933,2 +1148,27 @@ UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) } + + //installations + project->variables()["INSTALLDEPS"] += "install_subdirs"; + project->variables()["UNINSTALLDEPS"] += "uninstall_subdirs"; + writeInstalls(t, "INSTALLS"); + + // user defined targets + QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"]; + for(QStringList::Iterator qut_it = qut.begin(); qut_it != qut.end(); ++qut_it) { + QString targ = var((*qut_it) + ".target"), + cmd = var((*qut_it) + ".commands"), deps; + if(targ.isEmpty()) + targ = (*qut_it); + QStringList &deplist = project->variables()[(*qut_it) + ".depends"]; + for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) { + QString dep = var((*dep_it) + ".target"); + if(dep.isEmpty()) + dep = (*dep_it); + deps += " " + dep; + } + if(project->variables()[(*qut_it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; + t << targ << ":" << deps << "\n\t" + << cmd << endl << endl; + } t <<"FORCE:" << endl << endl; @@ -969,2 +1209,5 @@ void UnixMakefileGenerator::init2() project->variables()["TARGETA"].append(project->first("DESTDIR") + "lib" + project->first("TARGET") + ".a"); + if( project->isActiveConfig("compile_libtool") ) + project->variables()["TARGET_la"] = project->first("DESTDIR") + "lib" + project->first("TARGET") + Option::libtool_ext; + if ( !project->variables()["QMAKE_AR_CMD"].isEmpty() ) @@ -973,12 +1216,15 @@ void UnixMakefileGenerator::init2() project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGETA) $(OBJECTS) $(OBJMOC)"); - if( project->isActiveConfig("plugin") ) { + if( project->isActiveConfig("compile_libtool") ) { + project->variables()["TARGET"] = project->variables()["TARGET_la"]; + } else if( project->isActiveConfig("plugin") ) { project->variables()["TARGET_x.y.z"].append("lib" + - project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB")); + project->first("TARGET") + "." + + project->first("QMAKE_EXTENSION_PLUGIN")); if(project->isActiveConfig("lib_version_first")) project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + - project->first("VER_MAJ") + "." + - project->first("QMAKE_EXTENSION_SHLIB")); + project->first("VER_MAJ") + "." + + project->first("QMAKE_EXTENSION_PLUGIN")); else project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + - project->first("QMAKE_EXTENSION_SHLIB") + + project->first("QMAKE_EXTENSION_PLUGIN") + "." + project->first("VER_MAJ")); @@ -991,6 +1237,6 @@ void UnixMakefileGenerator::init2() if(project->isActiveConfig("lib_version_first")) - project->variables()["TARGET_x"].append("lib" + project->first("VER_MAJ") + "." + + project->variables()["TARGET_x"].append("lib" + project->first("VER_MAJ") + "." + project->first("TARGET")); else - project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + + project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ")); @@ -1077,3 +1323,3 @@ void UnixMakefileGenerator::init2() project->variables()["QMAKE_LINK_SHLIB_CMD"].append( - "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)"); + "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) $(OBJCOMP)"); } @@ -1082,9 +1328,15 @@ void UnixMakefileGenerator::init2() if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { - project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SHAPP"]; + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_APP"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_APP"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_APP"]; } else if ( project->isActiveConfig("dll") ) { - project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_SHLIB"]; - project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_SHLIB"]; + if( !project->isActiveConfig("plugin") || !project->isActiveConfig("plugin_no_share_shlib_cflags")) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_SHLIB"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_SHLIB"]; + } if ( project->isActiveConfig("plugin") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_PLUGIN"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_PLUGIN"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PLUGIN"]; - if( !project->isActiveConfig("plugin_no_soname") ) + if( project->isActiveConfig("plugin_with_soname") && !project->isActiveConfig("compile_libtool")) project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"]; @@ -1092,3 +1344,19 @@ void UnixMakefileGenerator::init2() project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SHLIB"]; - project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"]; + if(!project->isEmpty("QMAKE_LFLAGS_COMPAT_VERSION")) { + if(project->isEmpty("COMPAT_VERSION")) + project->variables()["QMAKE_LFLAGS"] += QString(project->first("QMAKE_LFLAGS_COMPAT_VERSION") + + project->first("VER_MAJ") + "." + + project->first("VER_MIN")); + else + project->variables()["QMAKE_LFLAGS"] += QString(project->first("QMAKE_LFLAGS_COMPAT_VERSION") + + project->first("COMPATIBILITY_VERSION")); + } + if(!project->isEmpty("QMAKE_LFLAGS_VERSION")) { + project->variables()["QMAKE_LFLAGS"] += QString(project->first("QMAKE_LFLAGS_VERSION") + + project->first("VER_MAJ") + "." + + project->first("VER_MIN") + "." + + project->first("VER_PAT")); + } + if(!project->isActiveConfig("compile_libtool")) + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"]; } @@ -1109,2 +1377,212 @@ void UnixMakefileGenerator::init2() } + QStringList &quc = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"]; + for(QStringList::Iterator it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + if(tmp_out.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1) + project->variables()["OBJCOMP"] += out; + } + } + } +} + +QString +UnixMakefileGenerator::libtoolFileName() +{ + QString ret = var("TARGET"); + int slsh = ret.findRev(Option::dir_sep); + if(slsh != -1) + ret = ret.right(ret.length() - slsh); + int dot = ret.find('.'); + if(dot != -1) + ret = ret.left(dot); + ret += Option::libtool_ext; + if(!project->isEmpty("DESTDIR")) + ret.prepend(var("DESTDIR")); + return ret; +} + +void +UnixMakefileGenerator::writeLibtoolFile() +{ + QString fname = libtoolFileName(), lname = fname; + int slsh = lname.findRev(Option::dir_sep); + if(slsh != -1) + lname = lname.right(lname.length() - slsh - 1); + QFile ft(fname); + if(!ft.open(IO_WriteOnly)) + return; + project->variables()["ALL_DEPS"].append(fname); + + QTextStream t(&ft); + t << "# " << lname << " - a libtool library file\n"; + time_t now = time(NULL); + t << "# Generated by qmake/libtool (" << qmake_version() << ") (Qt " + << QT_VERSION_STR << ") on: " << ctime(&now) << "\n"; + + t << "# The name that we can dlopen(3).\n" + << "dlname='" << var(project->isActiveConfig("plugin") ? "TARGET" : "TARGET_x") + << "'\n\n"; + + t << "# Names of this library.\n"; + t << "library_names='"; + if(project->isActiveConfig("plugin")) { + t << var("TARGET"); + } else { + if (project->isEmpty("QMAKE_HPUX_SHLIB")) + t << var("TARGET_x.y.z") << " "; + t << var("TARGET_x") << " " << var("TARGET_"); + } + t << "'\n\n"; + + t << "# The name of the static archive.\n" + << "old_library='" << lname.left(lname.length()-Option::libtool_ext.length()) << ".a'\n\n"; + + t << "# Libraries that this one depends upon.\n"; + QStringList libs; + if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) + libs = project->variables()["QMAKE_INTERNAL_PRL_LIBS"]; + else + libs << "QMAKE_LIBS"; //obvious one + t << "dependency_libs='"; + for(QStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it) + t << project->variables()[(*it)].join(" ") << " "; + t << "'\n\n"; + + t << "# Version information for " << lname << "\n"; + int maj = project->first("VER_MAJ").toInt(); + int min = project->first("VER_MIN").toInt(); + int pat = project->first("VER_PAT").toInt(); + t << "current=" << (10*maj + min) << "\n" // best I can think of + << "age=0\n" + << "revision=" << pat << "\n\n"; + + t << "# Is this an already installed library.\n" + "installed=yes\n\n"; // ### + + t << "# Files to dlopen/dlpreopen.\n" + "dlopen=''\n" + "dlpreopen=''\n\n"; + + QString install_dir = project->first("target.path"); + if(install_dir.isEmpty()) + install_dir = project->first("DESTDIR"); + t << "# Directory that this library needs to be installed in:\n" + "libdir='" << Option::fixPathToTargetOS(install_dir, FALSE) << "'\n"; +} + +QString +UnixMakefileGenerator::pkgConfigFileName() +{ + QString ret = var("TARGET"); + int slsh = ret.findRev(Option::dir_sep); + if(slsh != -1) + ret = ret.right(ret.length() - slsh); + if(ret.startsWith("lib")) + ret = ret.mid(3); + int dot = ret.find('.'); + if(dot != -1) + ret = ret.left(dot); + ret += Option::pkgcfg_ext; + if(!project->isEmpty("DESTDIR")) { + ret.prepend(var("DESTDIR")); + ret = Option::fixPathToLocalOS(fileFixify(ret,QDir::currentDirPath(), Option::output_dir)); + } + return ret; +} + +QString +UnixMakefileGenerator::pkgConfigPrefix() const +{ + if(!project->isEmpty("QMAKE_PKGCONFIG_PREFIX")) + return project->first("QMAKE_PKGCONFIG_PREFIX"); + return qInstallPath(); +} + +QString +UnixMakefileGenerator::pkgConfigFixPath(QString path) const +{ + QString prefix = pkgConfigPrefix(); + if(path.startsWith(prefix)) + path = path.replace(prefix, "${prefix}"); + return path; +} + +void +UnixMakefileGenerator::writePkgConfigFile() // ### does make sense only for libqt so far +{ + QString fname = pkgConfigFileName(), lname = fname; + int slsh = lname.findRev(Option::dir_sep); + if(slsh != -1) + lname = lname.right(lname.length() - slsh - 1); + QFile ft(fname); + if(!ft.open(IO_WriteOnly)) + return; + project->variables()["ALL_DEPS"].append(fname); + QTextStream t(&ft); + + QString prefix = pkgConfigPrefix(); + QString libDir = project->first("QMAKE_PKGCONFIG_LIBDIR"); + if(libDir.isEmpty()) + libDir = prefix + "/lib"; + QString includeDir = project->first("QMAKE_PKGCONFIG_INCDIR"); + if(includeDir.isEmpty()) + includeDir = prefix + "/include"; + + t << "prefix=" << prefix << endl; + t << "exec_prefix=${prefix}\n" + << "libdir=" << pkgConfigFixPath(libDir) << "\n" + << "includedir=" << pkgConfigFixPath(includeDir) << endl; + // non-standard entry. Provides useful info normally only + // contained in the internal .qmake.cache file + t << varGlue("CONFIG", "qt_config=", " ", "") << endl << endl; + + t << "Name: Qt" << endl; + QString desc = project->first("QMAKE_PKGCONFIG_DESCRIPTION"); + if(desc.isEmpty()) { + desc = project->first("TARGET").lower(); + desc.replace(0, 1, desc[0].upper()); + if(project->first("TEMPLATE") == "lib") { + if(project->isActiveConfig("plugin")) + desc += " Plugin"; + else + desc += " Library"; + } else if(project->first("TEMPLATE") == "app") { + desc += " Application"; + } + } + t << "Description: " << desc << endl; + t << "Version: " << project->first("VERSION") << endl; + + // libs + QStringList libs; + if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) + libs = project->variables()["QMAKE_INTERNAL_PRL_LIBS"]; + else + libs << "QMAKE_LIBS"; //obvious one + if(project->isActiveConfig("thread")) + libs << "QMAKE_LFLAGS_THREAD"; //not sure about this one, but what about things like -pthread? + t << "Libs: -L${libdir} -l" << lname.left(lname.length()-Option::libtool_ext.length()) << " "; + for(QStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it) + t << project->variables()[(*it)].join(" ") << " "; + t << endl; + + // flags + // ### too many + t << "Cflags: " + // << var("QMAKE_CXXFLAGS") << " " + << varGlue("PRL_EXPORT_DEFINES","-D"," -D"," ") + << project->variables()["PRL_EXPORT_CXXFLAGS"].join(" ") + // << varGlue("DEFINES","-D"," -D"," ") + << " -I${includedir}"; } diff --git a/qmake/generators/win32/borland_bmake.cpp b/qmake/generators/win32/borland_bmake.cpp index 26eea88..12607cf 100644 --- a/qmake/generators/win32/borland_bmake.cpp +++ b/qmake/generators/win32/borland_bmake.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** NmakeMakefileGenerator of BorlandMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -85,6 +83,6 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << "YACC = " << var("QMAKE_YACC") << endl; - t << "CFLAGS = " << var("QMAKE_CFLAGS") << " " + t << "CFLAGS = " << var("QMAKE_CFLAGS") << " " << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " << varGlue("DEFINES","-D"," -D","") << endl; - t << "CXXFLAGS= " << var("QMAKE_CXXFLAGS") << " " + t << "CXXFLAGS= " << var("QMAKE_CXXFLAGS") << " " << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " @@ -116,7 +114,7 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) } - t << "MOC = " << (project->isEmpty("QMAKE_MOC") ? QString("moc") : + t << "MOC = " << (project->isEmpty("QMAKE_MOC") ? QString("moc") : Option::fixPathToTargetOS(var("QMAKE_MOC"), FALSE)) << endl; - t << "UIC = " << (project->isEmpty("QMAKE_UIC") ? QString("uic") : + t << "UIC = " << (project->isEmpty("QMAKE_UIC") ? QString("uic") : Option::fixPathToTargetOS(var("QMAKE_UIC"), FALSE)) << endl; - t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : + t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : Option::fixPathToTargetOS(var("QMAKE_QMAKE"), FALSE)) << endl; @@ -136,2 +134,4 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << "MKDIR = " << var("QMAKE_MKDIR") << endl; + t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl; t << endl; @@ -147,2 +147,19 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << "OBJMOC = " << varList("OBJMOC") << endl; + + QString extraCompilerDeps; + if(!project->isEmpty("QMAKE_EXTRA_WIN_COMPILERS")) { + t << "OBJCOMP = " << varList("OBJCOMP") << endl; + extraCompilerDeps += " $(OBJCOMP) "; + + QStringList &comps = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) { + QStringList &vars = project->variables()[(*compit) + ".variables"]; + for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) { + QStringList vals = project->variables()[(*varit)]; + if(!vals.isEmpty()) + t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << endl; + } + } + } + t << "DIST = " << varList("DISTFILES") << endl; @@ -164,5 +181,5 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) t << "####### Build rules" << endl << endl; - t << "all: " << varGlue("ALL_DEPS",""," "," ") << " $(TARGET)" << endl << endl; - t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " - << var("POST_TARGETDEPS"); + t << "all: " << fileFixify(Option::output.name()) << " " << varGlue("ALL_DEPS"," "," "," ") << " $(TARGET)" << endl << endl; + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << extraCompilerDeps << var("POST_TARGETDEPS"); if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { @@ -171,3 +188,3 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) } else { - t << "\n\t-del $(TARGET)" + t << "\n\t-$(DEL_FILE) $(TARGET)" << "\n\t" << "$(LIB) $(TARGET) @&&|" << " \n+" @@ -176,2 +193,3 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) } + t << extraCompilerDeps; t << endl << "|" << endl; @@ -184,3 +202,3 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { - t << "\n\t" << "-copy $(TARGET) " << *dlldir; + t << "\n\t" << "-$(COPY_FILE) \"$(TARGET)\" " << *dlldir; } @@ -194,10 +212,10 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) if ( project->isActiveConfig("dll")) { - t << "\n\t" << ("-$(IDC) $(TARGET) /idl tmp\\" + targetfilename + ".idl -version " + version); - t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"); - t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /idl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" ); } else { - t << "\n\t" << ("-$(TARGET) -dumpidl tmp\\" + targetfilename + ".idl -version " + version); - t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"); - t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb"); + t << "\n\t" << ("-$(TARGET) -dumpidl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); t << "\n\t" << ("-$(TARGET) -regserver"); @@ -211,3 +229,4 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) } - t << "mocables: $(SRCMOC)" << endl << endl; + t << "mocables: $(SRCMOC)" << endl + << "uicables: $(UICIMPLS) $(UICDECLS)" << endl << endl; @@ -215,24 +234,51 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) + QStringList dist_files = Option::mkfile::project_files; + if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES")) + dist_files += project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"]; + if(!project->isEmpty("TRANSLATIONS")) + dist_files << var("TRANSLATIONS"); + if(!project->isEmpty("FORMS")) { + QStringList &forms = project->variables()["FORMS"]; + for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) { + QString ui_h = fileFixify((*formit) + Option::h_ext.first()); + if(QFile::exists(ui_h) ) + dist_files << ui_h; + } + } t << "dist:" << "\n\t" - << "$(ZIP) " << var("PROJECT") << ".zip " << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" - << endl << endl; + << "$(ZIP) " << var("QMAKE_ORIG_TARGET") << ".zip " << "$(SOURCES) $(HEADERS) $(DIST) $(FORMS) " + << dist_files.join(" ") << " " << var("TRANSLATIONS") << " " << var("IMAGES") << endl << endl; + + t << "uiclean:"; + QString uiclean = varGlue("UICDECLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + varGlue("UICIMPLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ",""); + if ( uiclean.isEmpty() ) { + // Borland make does not like an empty command section + uiclean = "\n\t@cd ."; + } + t << uiclean << endl; + + t << "mocclean:"; + QString mocclean = varGlue("SRCMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + varGlue("OBJMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ",""); + if ( mocclean.isEmpty() ) { + // Borland make does not like an empty command section + mocclean = "\n\t@cd ."; + } + t << mocclean << endl; - t << "clean:\n" - << varGlue("OBJECTS","\t-del ","\n\t-del ","") - << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","") - << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","") - << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","") - << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","") - << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","") - << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ",""); + t << "clean: uiclean mocclean" + << varGlue("OBJECTS","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("CLEAN_FILES","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ",""); if ( project->isActiveConfig("activeqt")) { - t << ("\n\t-del tmp\\" + targetfilename + ".*"); - t << "\n\t-del tmp\\dump.*"; + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".idl"); + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".tlb"); } if(!project->isEmpty("IMAGES")) - t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", ""); + t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-$(DEL_FILE) ", "\n\t-$(DEL_FILE) ", ""); + t << endl; - // blasted user defined targets + // user defined targets + QStringList::Iterator it; QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; - for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) { + for(it = qut.begin(); it != qut.end(); ++it) { QString targ = var((*it) + ".target"), @@ -248,2 +294,5 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) } + if(!project->variables()["QMAKE_NOFORCE"].isEmpty() && + project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; t << "\n\n" << targ << ":" << deps << "\n\t" @@ -254,4 +303,53 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + QString tmp_dep = project->variables()[(*it) + ".depends"].join(" "); + QStringList &vars = project->variables()[(*it) + ".variables"]; + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out, cmd = tmp_cmd, deps; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + cmd.replace("${QMAKE_FILE_BASE}", fi.baseName()); + cmd.replace("${QMAKE_FILE_OUT}", out); + cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3) + cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); + if(!tmp_dep.isEmpty()) { + char buff[256]; + QString dep_cmd = tmp_dep; + dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) { + while(!feof(proc)) { + int read_in = int(fread(buff, 1, 255, proc)); + if(!read_in) + break; + int l = 0; + for(int i = 0; i < read_in; i++) { + if(buff[i] == '\n' || buff[i] == ' ') { + deps += " " + QCString(buff+l, (i - l) + 1); + l = i; + } + } + } + fclose(proc); + } + } + t << out << ": " << in << deps << "\n\t" + << cmd << endl << endl; + } + } + } + t << endl; + t << "distclean: clean" - << "\n\t-del $(TARGET)" + << "\n\t-$(DEL_FILE) $(TARGET)" << endl << endl; @@ -267,3 +365,3 @@ BorlandMakefileGenerator::init() project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; - + /* this should probably not be here, but I'm using it to wrap the .t files */ @@ -281,3 +379,8 @@ BorlandMakefileGenerator::init() } - + + if(project->isEmpty("QMAKE_INSTALL_FILE")) + project->variables()["QMAKE_INSTALL_FILE"].append("$(COPY_FILE)"); + if(project->isEmpty("QMAKE_INSTALL_DIR")) + project->variables()["QMAKE_INSTALL_DIR"].append("$(COPY_DIR)"); + bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qtmt"QTDLL_POSTFIX); @@ -288,2 +391,8 @@ BorlandMakefileGenerator::init() if(configs.findIndex("qt") == -1) configs.append("qt"); + if ( project->isActiveConfig("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); + } if ( project->isActiveConfig("qt") ) { @@ -316,3 +425,3 @@ BorlandMakefileGenerator::init() if(project->isActiveConfig("qt")) { - if ( project->isActiveConfig("thread") ) + if ( project->isActiveConfig("thread") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT"); @@ -327,5 +436,5 @@ BorlandMakefileGenerator::init() if ( project->isActiveConfig("dll") ) { - project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"]; - project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"]; - } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"]; + } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DBG"]; @@ -358,2 +467,9 @@ BorlandMakefileGenerator::init() } + if ( project->isActiveConfig("qtopiainc") ) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"]; + if ( project->isActiveConfig("qtopialib") ) { + if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA")) + project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QTOPIA"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"]; + } if ( project->isActiveConfig("qt") ) { @@ -362,3 +478,3 @@ BorlandMakefileGenerator::init() project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"]; - if ( !project->isActiveConfig("debug") ) + if ( !project->isActiveConfig("debug") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG"); @@ -470,2 +586,16 @@ BorlandMakefileGenerator::init() project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; + // Update -lname to name.lib, and -Ldir to + QStringList &libList = project->variables()["QMAKE_LIBS"]; + for( QStringList::Iterator stIt = libList.begin(); stIt != libList.end(); ) { + QString s = *stIt; + if( s.startsWith( "-l" ) ) { + stIt = libList.remove( stIt ); + stIt = libList.insert( stIt, s.mid( 2 ) + ".lib" ); + } else if( s.startsWith( "-L" ) ) { + stIt = libList.remove( stIt ); + project->variables()["QMAKE_LIBDIR"].append(QDir::convertSeparators(s.mid( 2 ))); + } else { + stIt++; + } + } project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', @@ -473,3 +603,4 @@ BorlandMakefileGenerator::init() QStringList &l = project->variables()["QMAKE_FILETAGS"]; - for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QStringList::Iterator it; + for(it = l.begin(); it != l.end(); ++it) { QStringList &gdmf = project->variables()[(*it)]; @@ -488,2 +619,3 @@ BorlandMakefileGenerator::init() project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["CLEAN_FILES"] += project->variables()["RES_FILE"]; } @@ -508,2 +640,22 @@ BorlandMakefileGenerator::init() } + + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + if(tmp_out.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1) + project->variables()["OBJCOMP"] += out; + } + } + } } diff --git a/qmake/generators/win32/borland_bmake.h b/qmake/generators/win32/borland_bmake.h index 5ffed58..700e7f7 100644 --- a/qmake/generators/win32/borland_bmake.h +++ b/qmake/generators/win32/borland_bmake.h @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of BorlandMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -36,2 +34,3 @@ **********************************************************************/ + #ifndef __BORLAND_BMAKE_H__ diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index 7f58a55..c693d6a 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -1,524 +1,708 @@ -/****************************************************************************
-** $Id$
-**
-** Definition of ________ class.
-**
-** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
-**
-** This file is part of the network module of the Qt GUI Toolkit.
-**
-** This file may be distributed under the terms of the Q Public License
-** as defined by Trolltech AS of Norway and appearing in the file
-** LICENSE.QPL included in the packaging of this file.
-**
-** This file may be distributed and/or modified under the terms of the
-** GNU General Public License version 2 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.
-**
-** Licensees holding valid Qt Enterprise Edition licenses may use this
-** file in accordance with the Qt Commercial License Agreement provided
-** with the Software.
-**
-** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
-** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-**
-** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
-** information about Qt Commercial License Agreements.
-** See http://www.trolltech.com/qpl/ for QPL licensing information.
-** See http://www.trolltech.com/gpl/ for GPL licensing information.
-**
-** Contact info@trolltech.com if any conditions of this licensing are
-** not clear to you.
-**
-**********************************************************************/
-
-#include "mingw_make.h"
-#include "option.h"
-#include <qregexp.h>
-#include <qdir.h>
-#include <stdlib.h>
-#include <time.h>
-
-
-MingwMakefileGenerator::MingwMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE)
-{
- Option::obj_ext = ".o";
-}
-
-bool
-MingwMakefileGenerator::writeMakefile(QTextStream &t)
-{
- writeHeader(t);
- if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
- t << "all clean:" << "\n\t"
- << "@echo \"Some of the required modules ("
- << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t"
- << "@echo \"Skipped.\"" << endl << endl;
- writeMakeQmake(t);
- return TRUE;
- }
-
- if(project->first("TEMPLATE") == "app" ||
- project->first("TEMPLATE") == "lib") {
- writeMingwParts(t);
- return MakefileGenerator::writeMakefile(t);
- }
- else if(project->first("TEMPLATE") == "subdirs") {
- writeSubDirs(t);
- return TRUE;
- }
- return FALSE;
-}
-
-void
-MingwMakefileGenerator::writeMingwParts(QTextStream &t)
-{
- t << "####### Compiler, tools and options" << endl << endl;
- t << "CC = " << var("QMAKE_CC") << endl;
- t << "CXX = " << var("QMAKE_CXX") << endl;
- t << "LEX = " << var("QMAKE_LEX") << endl;
- t << "YACC = " << var("QMAKE_YACC") << endl;
- t << "CFLAGS = " << var("QMAKE_CFLAGS") << " "
- << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
- << varGlue("DEFINES","-D"," -D","") << endl;
- t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " "
- << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
- << varGlue("DEFINES","-D"," -D","") << endl;
- t << "LEXFLAGS =" << var("QMAKE_LEXFLAGS") << endl;
- t << "YACCFLAGS =" << var("QMAKE_YACCFLAGS") << endl;
-
- t << "INCPATH = ";
- QStringList &incs = project->variables()["INCLUDEPATH"];
- for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) {
- QString inc = (*incit);
- inc.replace(QRegExp("\\\\$"), "\\\\");
- inc.replace(QRegExp("\""), "");
- t << " -I" << inc ;
- }
- t << " -I" << specdir()
- << endl;
- if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
- t << "LINK = " << var("QMAKE_LINK") << endl;
- t << "LFLAGS = ";
- if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() )
- t << varGlue("QMAKE_LIBDIR","-L",";","") << " ";
- t << var("QMAKE_LFLAGS") << endl;
- t << "LIBS = " << var("QMAKE_LIBS").replace(QRegExp("(\\slib|^lib)")," -l") << endl;
- }
- else {
- t << "LIB = " << var("QMAKE_LIB") << endl;
- }
- t << "MOC = " << (project->isEmpty("QMAKE_MOC") ? QString("moc") :
- Option::fixPathToTargetOS(var("QMAKE_MOC"), FALSE)) << endl;
- t << "UIC = " << (project->isEmpty("QMAKE_UIC") ? QString("uic") :
- Option::fixPathToTargetOS(var("QMAKE_UIC"), FALSE)) << endl;
- t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") :
- Option::fixPathToTargetOS(var("QMAKE_QMAKE"), FALSE)) << endl;
- t << "IDC = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") :
- Option::fixPathToTargetOS(var("QMAKE_IDC"), FALSE)) << endl;
- t << "IDL = " << (project->isEmpty("QMAKE_IDL") ? QString("midl") :
- Option::fixPathToTargetOS(var("QMAKE_IDL"), FALSE)) << endl;
- t << "ZIP = " << var("QMAKE_ZIP") << endl;
- t << "DEF_FILE = " << varList("DEF_FILE") << endl;
- t << "COPY_FILE = " << var("QMAKE_COPY") << endl;
- t << "COPY_DIR = " << var("QMAKE_COPY") << endl;
- t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
- t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl;
- t << "MOVE = " << var("QMAKE_MOVE") << endl;
- t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl;
- t << "MKDIR = " << var("QMAKE_MKDIR") << endl;
- t << endl;
-
- t << "####### Output directory" << endl << endl;
- if (! project->variables()["OBJECTS_DIR"].isEmpty())
- t << "OBJECTS_DIR = " << var("OBJECTS_DIR").replace(QRegExp("\\\\$"),"") << endl;
- else
- t << "OBJECTS_DIR = . " << endl;
- if (! project->variables()["MOC_DIR"].isEmpty())
- t << "MOC_DIR = " << var("MOC_DIR").replace(QRegExp("\\\\$"),"") << endl;
- else
- t << "MOC_DIR = . " << endl;
- t << endl;
-
- t << "####### Files" << endl << endl;
- t << "HEADERS = " << varList("HEADERS") << endl;
- t << "SOURCES = " << varList("SOURCES") << endl;
-// t << "OBJECTS = " << varList("OBJECTS").replace(QRegExp("\\.obj"),".o") << endl;
- t << "OBJECTS = " << varList("OBJECTS") << endl;
- t << "FORMS = " << varList("FORMS") << endl;
- t << "UICDECLS = " << varList("UICDECLS") << endl;
- t << "UICIMPLS = " << varList("UICIMPLS") << endl;
- t << "SRCMOC = " << varList("SRCMOC") << endl;
- t << "OBJMOC = " << varList("OBJMOC") << endl;
-// t << "OBJMOC = " << varList("OBJMOC").replace(QRegExp("\\.obj"),".o") << endl;
- t << "DIST = " << varList("DISTFILES") << endl;
- t << "TARGET = ";
- if( !project->variables()[ "DESTDIR" ].isEmpty() )
- t << varGlue("TARGET",project->first("DESTDIR"),"",project->first("TARGET_EXT"));
- else
- t << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first();
- t << endl;
- t << endl;
-
- t << "####### Implicit rules" << endl << endl;
- t << ".SUFFIXES: .cpp .cxx .cc .C .c" << endl << endl;
- t << ".cpp.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
- t << ".cxx.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
- t << ".cc.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
- t << ".C.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
- t << ".c.o:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl;
-
- t << "####### Build rules" << endl << endl;
- t << "all: " << "$(OBJECTS_DIR) " << "$(MOC_DIR) " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl;
- t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) "
- << var("POST_TARGETDEPS");
- if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
- t << "\n\t" << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)";
- } else {
- t << "\n\t" << "$(LIB) $(TARGET) $(OBJECTS) $(OBJMOC)";
- }
-
- if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) {
- QStringList dlldirs = project->variables()["DLLDESTDIR"];
- for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) {
- t << "\n\t" << "copy $(TARGET) " << *dlldir;
- }
- }
- QString targetfilename = project->variables()["TARGET"].first();
- if(project->isActiveConfig("activeqt")) {
- QString version = project->variables()["VERSION"].first();
- if ( version.isEmpty() )
- version = "1.0";
-
- if ( project->isActiveConfig("dll")) {
- t << "\n\t" << ("-$(IDC) $(TARGET) /idl tmp\\" + targetfilename + ".idl -version " + version);
- t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl");
- t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb");
- t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" );
- } else {
- t << "\n\t" << ("-$(TARGET) -dumpidl tmp\\" + targetfilename + ".idl -version " + version);
- t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl");
- t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb");
- t << "\n\t" << "-$(TARGET) -regserver";
- }
- }
- t << endl << endl;
-
- if(!project->variables()["RC_FILE"].isEmpty()) {
- t << var("RES_FILE") << ": " << var("RC_FILE") << "\n\t"
- << var("QMAKE_RC") << " -i " << var("RC_FILE") << " -o " << var("RC_FILE").replace(QRegExp("\\.rc"),".o") << endl << endl;
- }
- project->variables()["RES_FILE"].first().replace(QRegExp("\\.rc"),".o");
-
- t << "mocables: $(SRCMOC)" << endl << endl;
-
- t << "$(OBJECTS_DIR):" << "\n\t"
- << "@if not exist $(OBJECTS_DIR) mkdir $(OBJECTS_DIR)" << endl << endl;
-
- t << "$(MOC_DIR):" << "\n\t"
- << "@if not exist $(MOC_DIR) mkdir $(MOC_DIR)" << endl << endl;
-
- writeMakeQmake(t);
-
- t << "dist:" << "\n\t"
- << "$(ZIP) " << var("PROJECT") << ".zip "
- << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" << endl << endl;
-
- t << "clean:"
- << varGlue("OBJECTS","\n\t-del ","\n\t-del ","").replace(QRegExp("\\.obj"),".o")
- << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","")
- << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","").replace(QRegExp("\\.obj"),".o")
- << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","")
- << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","")
- << "\n\t-del $(TARGET)"
- << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","")
- << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ","");
- if ( project->isActiveConfig("activeqt")) {
- t << ("\n\t-del tmp\\" + targetfilename + ".*");
- t << "\n\t-del tmp\\dump.*";
- }
- if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty())
- t << "\n\t-del " << var("DLLDESTDIR") << "\\" << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first();
- if(!project->isEmpty("IMAGES"))
- t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", "");
-
- // blasted user defined targets
- QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"];
- for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) {
- QString targ = var((*it) + ".target"),
- cmd = var((*it) + ".commands"), deps;
- if(targ.isEmpty())
- targ = (*it);
- QStringList &deplist = project->variables()[(*it) + ".depends"];
- for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) {
- QString dep = var((*dep_it) + ".target");
- if(dep.isEmpty())
- dep = (*dep_it);
- deps += " " + dep;
- }
- t << "\n\n" << targ << ":" << deps << "\n\t"
- << cmd;
- }
-
- t << endl << endl;
-}
-
-
-void
-MingwMakefileGenerator::init()
-{
- if(init_flag)
- return;
- init_flag = TRUE;
-
- /* this should probably not be here, but I'm using it to wrap the .t files */
- if(project->first("TEMPLATE") == "app")
- project->variables()["QMAKE_APP_FLAG"].append("1");
- else if(project->first("TEMPLATE") == "lib")
- project->variables()["QMAKE_LIB_FLAG"].append("1");
- else if(project->first("TEMPLATE") == "subdirs") {
- MakefileGenerator::init();
- if(project->variables()["MAKEFILE"].isEmpty())
- project->variables()["MAKEFILE"].append("Makefile");
- if(project->variables()["QMAKE"].isEmpty())
- project->variables()["QMAKE"].append("qmake");
- return;
- }
-
- bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX);
- project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
-
- // LIBS defined in Profile comes first for gcc
- project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
-
- QString targetfilename = project->variables()["TARGET"].first();
- QStringList &configs = project->variables()["CONFIG"];
- if (project->isActiveConfig("qt") && project->isActiveConfig("shared"))
- project->variables()["DEFINES"].append("QT_DLL");
- if (project->isActiveConfig("qt_dll"))
- if(configs.findIndex("qt") == -1) configs.append("qt");
- if ( project->isActiveConfig("qt") ) {
- if ( project->isActiveConfig( "plugin" ) ) {
- project->variables()["CONFIG"].append("dll");
- if(project->isActiveConfig("qt"))
- project->variables()["DEFINES"].append("QT_PLUGIN");
- }
- if ( (project->variables()["DEFINES"].findIndex("QT_NODLL") == -1) &&
- ((project->variables()["DEFINES"].findIndex("QT_MAKEDLL") != -1 ||
- project->variables()["DEFINES"].findIndex("QT_DLL") != -1) ||
- (getenv("QT_DLL") && !getenv("QT_NODLL"))) ) {
- project->variables()["QMAKE_QT_DLL"].append("1");
- if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() )
- project->variables()["CONFIG"].append("dll");
- }
- if ( project->isActiveConfig("thread") )
- project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT");
- if ( project->isActiveConfig("accessibility" ) )
- project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT");
- if ( project->isActiveConfig("tablet") )
- project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT");
- }
- if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
- project->variables()["CONFIG"].remove("staticlib");
- project->variables()["QMAKE_APP_OR_DLL"].append("1");
- } else {
- project->variables()["CONFIG"].append("staticlib");
- }
- if ( project->isActiveConfig("warn_off") ) {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"];
- } else if ( project->isActiveConfig("warn_on") ) {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"];
- }
- if ( project->isActiveConfig("debug") ) {
- if ( project->isActiveConfig("thread") ) {
- // use the DLL RT even here
- if ( project->variables()["DEFINES"].contains("QT_DLL") ) {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"];
- } else {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DBG"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"];
- }
- }
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"];
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"];
- } else {
- if ( project->isActiveConfig("thread") ) {
- if ( project->variables()["DEFINES"].contains("QT_DLL") ) {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLL"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"];
- } else {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT"];
- }
- }
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"];
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"];
- }
-
- if ( !project->variables()["QMAKE_INCDIR"].isEmpty())
- project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"];
- if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") )
- project->variables()["CONFIG"].append("windows");
- if ( project->isActiveConfig("qt") ) {
- project->variables()["CONFIG"].append("moc");
- project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"];
- project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"];
- if ( !project->isActiveConfig("debug") )
- project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG");
- if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) {
- if ( !project->variables()["QMAKE_QT_DLL"].isEmpty()) {
- project->variables()["DEFINES"].append("QT_MAKEDLL");
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_QT_DLL"];
- }
- } else {
- if(project->isActiveConfig("thread"))
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
- else
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
- if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
- int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt");
- if ( hver == -1 )
- hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt");
- if(hver != -1) {
- QString ver;
- ver.sprintf("libqt-%s" QTDLL_POSTFIX "%d.a", (project->isActiveConfig("thread") ? "-mt" : ""), hver);
- QStringList &libs = project->variables()["QMAKE_LIBS"];
-// @@@HGTODO maybe we must change the replace regexp if we understand what's going on
- for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit)
- (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver);
- }
- }
- if ( project->isActiveConfig( "activeqt" ) ) {
- project->variables().remove("QMAKE_LIBS_QT_ENTRY");
- project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib";
- if ( project->isActiveConfig( "dll" ) )
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"];
- }
- if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) {
- project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"];
- }
- }
- }
- if ( project->isActiveConfig("opengl") ) {
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"];
- }
- if ( project->isActiveConfig("dll") ) {
- project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE_DLL"];
- project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE_DLL"];
- project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE_DLL"];
- project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS_DLL"];
- if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty()) {
- project->variables()["TARGET_EXT"].append(
- QStringList::split('.',project->first("VERSION")).join("") + ".dll");
- } else {
- project->variables()["TARGET_EXT"].append(".dll");
- }
- } else {
- project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE"];
- project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE"];
- project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE"];
- project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS"];
- if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty()) {
- project->variables()["TARGET_EXT"].append(".exe");
- } else {
- project->variables()["TARGET_EXT"].append(".a");
- project->variables()["QMAKE_LFLAGS"].append("-static");
- if(project->variables()["TARGET"].first().left(3) != "lib")
- project->variables()["TARGET"].first().prepend("lib");
- }
- }
- if ( project->isActiveConfig("windows") ) {
- if ( project->isActiveConfig("console") ) {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"];
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"];
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"];
- } else {
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"];
- }
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"];
- } else {
- project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"];
- project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"];
- project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"];
- project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"];
- }
-
- if ( project->isActiveConfig("moc") )
- setMocAware(TRUE);
- project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ',
- "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH");
- QStringList &l = project->variables()["QMAKE_FILETAGS"];
- for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
- QStringList &gdmf = project->variables()[(*it)];
- for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner)
- (*inner) = Option::fixPathToTargetOS((*inner), FALSE);
- }
-
- if ( project->isActiveConfig("dll") )
- project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,--out-implib,") + project->first("DESTDIR") + "\\lib"+ project->first("TARGET") + ".a");
-
- if ( !project->variables()["DEF_FILE"].isEmpty() )
- project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,--output-def,") + project->first("DEF_FILE"));
-// if(!project->isActiveConfig("incremental"))
-// project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no"));
-
-#if 0
- if ( !project->variables()["VERSION"].isEmpty() ) {
- QString version = project->variables()["VERSION"][0];
- int firstDot = version.find( "." );
- QString major = version.left( firstDot );
- QString minor = version.right( version.length() - firstDot - 1 );
- minor.replace( ".", "" );
- project->variables()["QMAKE_LFLAGS"].append( "/VERSION:" + major + "." + minor );
- }
-#endif
- if ( !project->variables()["RC_FILE"].isEmpty()) {
- if ( !project->variables()["RES_FILE"].isEmpty()) {
- fprintf(stderr, "Both .rc and .res file specified.\n");
- fprintf(stderr, "Please specify one of them, not both.");
- exit(666);
- }
- project->variables()["RES_FILE"] = project->variables()["RC_FILE"];
- project->variables()["RES_FILE"].first().replace(".rc",".o");
- project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"];
- }
- if ( !project->variables()["RES_FILE"].isEmpty())
- project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"];
-
- MakefileGenerator::init();
- if ( !project->variables()["VERSION"].isEmpty()) {
- QStringList l = QStringList::split('.', project->first("VERSION"));
- project->variables()["VER_MAJ"].append(l[0]);
- project->variables()["VER_MIN"].append(l[1]);
- }
- if(project->isActiveConfig("dll")) {
- project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") +"lib" + project->first("TARGET") + ".a");
- }
-}
-
-void
-MingwMakefileGenerator::writeSubDirs(QTextStream &t)
-{
- QString qs ;
- QTextStream ts (&qs, IO_WriteOnly) ;
- Win32MakefileGenerator::writeSubDirs( ts ) ;
- QRegExp rx("(\\n\\tcd [^\\n\\t]+)(\\n\\t.+)\\n\\t@cd ..") ;
- rx.setMinimal(true);
- int pos = 0 ;
- while ( -1 != (pos = rx.search( qs, pos)))
- {
- QString qsMatch = rx.cap(2);
- qsMatch.replace("\n\t"," && \\\n\t");
- qs.replace(pos+rx.cap(1).length(), rx.cap(2).length(), qsMatch );
- pos += (rx.cap(1).length()+qsMatch.length());
- }
- t << qs ;
-}
+/**************************************************************************** +** +** +** Implementation of MingwMakefileGenerator class. +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of qmake. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition licenses may use this +** file in accordance with the Qt Commercial License Agreement provided +** with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "mingw_make.h" +#include "option.h" +#include <qregexp.h> +#include <qdir.h> +#include <stdlib.h> +#include <time.h> + + +MingwMakefileGenerator::MingwMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) +{ + Option::obj_ext = ".o"; +} + +bool +MingwMakefileGenerator::findLibraries() // todo - pascal +{ + return TRUE; +} + +bool +MingwMakefileGenerator::writeMakefile(QTextStream &t) +{ + writeHeader(t); + if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { + t << "all clean:" << "\n\t" + << "@echo \"Some of the required modules (" + << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t" + << "@echo \"Skipped.\"" << endl << endl; + writeMakeQmake(t); + return TRUE; + } + + if(project->first("TEMPLATE") == "app" || + project->first("TEMPLATE") == "lib") { + writeMingwParts(t); + return MakefileGenerator::writeMakefile(t); + } + else if(project->first("TEMPLATE") == "subdirs") { + writeSubDirs(t); + return TRUE; + } + return FALSE; + } + +void createLdObjectScriptFile(const QString & fileName, QStringList & objList) +{ + QString filePath = Option::output_dir + QDir::separator() + fileName; + QFile file(filePath); + if (file.open(IO_WriteOnly | IO_Translate )) { + QTextStream t(&file); + t << "INPUT(" << endl; + for (QStringList::Iterator it = objList.begin(); it != objList.end(); ++it ) { + t << *it << endl; + } + t << ");" << endl; + file.close(); + } +} + +void +MingwMakefileGenerator::writeMingwParts(QTextStream &t) +{ + t << "####### Compiler, tools and options" << endl << endl; + t << "CC = " << var("QMAKE_CC") << endl; + t << "CXX = " << var("QMAKE_CXX") << endl; + t << "LEX = " << var("QMAKE_LEX") << endl; + t << "YACC = " << var("QMAKE_YACC") << endl; + t << "CFLAGS = " << var("QMAKE_CFLAGS") << " " + << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " + << varGlue("DEFINES","-D"," -D","") << endl; + t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " " + << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " + << varGlue("DEFINES","-D"," -D","") << endl; + t << "LEXFLAGS =" << var("QMAKE_LEXFLAGS") << endl; + t << "YACCFLAGS =" << var("QMAKE_YACCFLAGS") << endl; + + t << "INCPATH = "; + QStringList &incs = project->variables()["INCLUDEPATH"]; + for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) { + QString inc = (*incit); + inc.replace(QRegExp("\\\\$"), "\\\\"); + inc.replace(QRegExp("\""), ""); + t << " -I" << "\"" << inc << "\""; + } + t << " -I" << "\"" << specdir() << "\"" << endl; + if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { + t << "LINK = " << var("QMAKE_LINK") << endl; + t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl; + t << "LIBS = "; + if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) + t << varGlue("QMAKE_LIBDIR","-L\"","\" -L\"","\"") << " "; + t << var("QMAKE_LIBS").replace(QRegExp("(\\slib|^lib)")," -l") << endl; + } + else { + t << "LIB = " << var("QMAKE_LIB") << endl; + } + t << "MOC = " << (project->isEmpty("QMAKE_MOC") ? QString("moc") : + Option::fixPathToTargetOS(var("QMAKE_MOC"), FALSE)) << endl; + t << "UIC = " << (project->isEmpty("QMAKE_UIC") ? QString("uic") : + Option::fixPathToTargetOS(var("QMAKE_UIC"), FALSE)) << endl; + t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : + Option::fixPathToTargetOS(var("QMAKE_QMAKE"), FALSE)) << endl; + t << "IDC = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") : + Option::fixPathToTargetOS(var("QMAKE_IDC"), FALSE)) << endl; + t << "IDL = " << (project->isEmpty("QMAKE_IDL") ? QString("midl") : + Option::fixPathToTargetOS(var("QMAKE_IDL"), FALSE)) << endl; + t << "ZIP = " << var("QMAKE_ZIP") << endl; + t << "DEF_FILE = " << varList("DEF_FILE") << endl; + t << "COPY_FILE = " << var("QMAKE_COPY") << endl; + t << "COPY_DIR = " << var("QMAKE_COPY") << endl; + t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; + t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; + t << "MOVE = " << var("QMAKE_MOVE") << endl; + t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; + t << "MKDIR = " << var("QMAKE_MKDIR") << endl; + t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl; + t << endl; + + t << "####### Output directory" << endl << endl; + if (! project->variables()["OBJECTS_DIR"].isEmpty()) + t << "OBJECTS_DIR = " << var("OBJECTS_DIR").replace(QRegExp("\\\\$"),"") << endl; + else + t << "OBJECTS_DIR = . " << endl; + if (! project->variables()["MOC_DIR"].isEmpty()) + t << "MOC_DIR = " << var("MOC_DIR").replace(QRegExp("\\\\$"),"") << endl; + else + t << "MOC_DIR = . " << endl; + t << endl; + + t << "####### Files" << endl << endl; + t << "HEADERS = " << varList("HEADERS") << endl; + t << "SOURCES = " << varList("SOURCES") << endl; + QString objectsLinkLine; + if (!project->variables()["QMAKE_APP_OR_DLL"].isEmpty() && + project->variables()["OBJECTS"].count() > var("QMAKE_LINK_OBJECT_MAX").toUInt()) { + createLdObjectScriptFile(var("QMAKE_LINK_OBJECT_SCRIPT"), project->variables()["OBJECTS"]); + objectsLinkLine = var("QMAKE_LINK_OBJECT_SCRIPT"); + } else { + objectsLinkLine = "$(OBJECTS)"; + } + t << "OBJECTS = " << varList("OBJECTS") << endl; + t << "FORMS = " << varList("FORMS") << endl; + t << "UICDECLS = " << varList("UICDECLS") << endl; + t << "UICIMPLS = " << varList("UICIMPLS") << endl; + t << "SRCMOC = " << varList("SRCMOC") << endl; + QString objmocLinkLine; + if (!project->variables()["QMAKE_APP_OR_DLL"].isEmpty() && + project->variables()["OBJMOC"].count() > var("QMAKE_LINK_OBJECT_MAX").toUInt()) { + createLdObjectScriptFile(var("QMAKE_LINK_OBJMOC_SCRIPT"), project->variables()["OBJMOC"]); + objmocLinkLine = var("QMAKE_LINK_OBJMOC_SCRIPT"); + } else { + objmocLinkLine = "$(OBJMOC)"; + } + t << "OBJMOC = " << varList("OBJMOC") << endl; + QString extraCompilerDeps; + if(!project->isEmpty("QMAKE_EXTRA_WIN_COMPILERS")) { + t << "OBJCOMP = " << varList("OBJCOMP") << endl; + extraCompilerDeps += " $(OBJCOMP) "; + + QStringList &comps = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) { + QStringList &vars = project->variables()[(*compit) + ".variables"]; + for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) { + QStringList vals = project->variables()[(*varit)]; + if(!vals.isEmpty()) + t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << endl; + } + } + } + + t << "DIST = " << varList("DISTFILES") << endl; + t << "TARGET = "; + if( !project->variables()[ "DESTDIR" ].isEmpty() ) + t << varGlue("TARGET",project->first("DESTDIR"),"",project->first("TARGET_EXT")); + else + t << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first(); + t << endl; + t << endl; + + t << "####### Implicit rules" << endl << endl; + t << ".SUFFIXES: .cpp .cxx .cc .C .c" << endl << endl; + t << ".cpp.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".cxx.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".cc.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".C.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".c.o:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; + + t << "####### Build rules" << endl << endl; + t << "all: " << "$(OBJECTS_DIR) " << "$(MOC_DIR) " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl; + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << extraCompilerDeps << var("POST_TARGETDEPS"); + if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { + t << "\n\t" << "$(LINK) $(LFLAGS) -o $(TARGET) " << objectsLinkLine << " " << objmocLinkLine << " $(LIBS)"; + } else { + t << "\n\t" << "$(LIB) $(TARGET) " << objectsLinkLine << " " << objmocLinkLine; + } + t << extraCompilerDeps; + if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) { + QStringList dlldirs = project->variables()["DLLDESTDIR"]; + for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { + t << "\n\t" << "$(COPY_FILE) \"$(TARGET)\" " << *dlldir; + } + } + QString targetfilename = project->variables()["TARGET"].first(); + if(project->isActiveConfig("activeqt")) { + QString version = project->variables()["VERSION"].first(); + if ( version.isEmpty() ) + version = "1.0"; + + if ( project->isActiveConfig("dll")) { + t << "\n\t" << ("-$(IDC) $(TARGET) /idl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" ); + } else { + t << "\n\t" << ("-$(TARGET) -dumpidl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << "-$(TARGET) -regserver"; + } + } + t << endl << endl; + + if(!project->variables()["RC_FILE"].isEmpty()) { + t << var("RES_FILE") << ": " << var("RC_FILE") << "\n\t" + << var("QMAKE_RC") << " -i " << var("RC_FILE") << " -o " << var("RC_FILE").replace(QRegExp("\\.rc"),".o") << " --include-dir=" << QFileInfo(var("RC_FILE")).dirPath() << endl << endl; + } + project->variables()["RES_FILE"].first().replace(QRegExp("\\.rc"),".o"); + + t << "mocables: $(SRCMOC)" << endl << endl; + + t << "$(OBJECTS_DIR):" << "\n\t" + << "@if not exist $(OBJECTS_DIR) $(MKDIR) $(OBJECTS_DIR)" << endl << endl; + + t << "$(MOC_DIR):" << "\n\t" + << "@if not exist $(MOC_DIR) $(MKDIR) $(MOC_DIR)" << endl << endl; + + writeMakeQmake(t); + + t << "dist:" << "\n\t" + << "$(ZIP) " << var("PROJECT") << ".zip " + << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" << endl << endl; + + t << "clean:" + << varGlue("OBJECTS","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","").replace(QRegExp("\\.obj"),".o") + << varGlue("SRCMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("OBJMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","").replace(QRegExp("\\.obj"),".o") + << varGlue("UICDECLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("UICIMPLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << "\n\t-$(DEL_FILE) $(TARGET)" + << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("CLEAN_FILES","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ",""); + if ( project->isActiveConfig("activeqt")) { + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".idl"); + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + } + if(!project->isEmpty("IMAGES")) + t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-$(DEL_FILE) ", "\n\t-$(DEL_FILE) ", ""); + + // user defined targets + QStringList::Iterator it; + QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; + + for(it = qut.begin(); it != qut.end(); ++it) { + QString targ = var((*it) + ".target"), + cmd = var((*it) + ".commands"), deps; + if(targ.isEmpty()) + targ = (*it); + QStringList &deplist = project->variables()[(*it) + ".depends"]; + for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) { + QString dep = var((*dep_it) + ".target"); + if(dep.isEmpty()) + dep = (*dep_it); + deps += " " + dep; + } + t << "\n\n" << targ << ":" << deps << "\n\t" + << cmd; + } + + t << endl << endl; + + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + QString tmp_dep = project->variables()[(*it) + ".depends"].join(" "); + QStringList &vars = project->variables()[(*it) + ".variables"]; + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out, cmd = tmp_cmd, deps; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + cmd.replace("${QMAKE_FILE_BASE}", fi.baseName()); + cmd.replace("${QMAKE_FILE_OUT}", out); + cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3) + cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); + if(!tmp_dep.isEmpty()) { + char buff[256]; + QString dep_cmd = tmp_dep; + dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) { + while(!feof(proc)) { + int read_in = int(fread(buff, 1, 255, proc)); + if(!read_in) + break; + int l = 0; + for(int i = 0; i < read_in; i++) { + if(buff[i] == '\n' || buff[i] == ' ') { + deps += " " + QCString(buff+l, (i - l) + 1); + l = i; + } + } + } + fclose(proc); + } + } + t << out << ": " << in << deps << "\n\t" + << cmd << endl << endl; + } + } + } + t << endl; +} + + +void +MingwMakefileGenerator::init() +{ + if(init_flag) + return; + init_flag = TRUE; + + /* this should probably not be here, but I'm using it to wrap the .t files */ + if(project->first("TEMPLATE") == "app") + project->variables()["QMAKE_APP_FLAG"].append("1"); + else if(project->first("TEMPLATE") == "lib") + project->variables()["QMAKE_LIB_FLAG"].append("1"); + else if(project->first("TEMPLATE") == "subdirs") { + MakefileGenerator::init(); + if(project->variables()["MAKEFILE"].isEmpty()) + project->variables()["MAKEFILE"].append("Makefile"); + if(project->variables()["QMAKE"].isEmpty()) + project->variables()["QMAKE"].append("qmake"); + return; + } + + if(project->isEmpty("QMAKE_INSTALL_FILE")) + project->variables()["QMAKE_INSTALL_FILE"].append("$(COPY_FILE)"); + if(project->isEmpty("QMAKE_INSTALL_DIR")) + project->variables()["QMAKE_INSTALL_DIR"].append("$(COPY_DIR)"); + + bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX); + project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; + + // LIBS defined in Profile comes first for gcc + project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; + + QString targetfilename = project->variables()["TARGET"].first(); + QStringList &configs = project->variables()["CONFIG"]; + + if (project->isActiveConfig("qt") && project->isActiveConfig("shared")) + project->variables()["DEFINES"].append("QT_DLL"); + + if (project->isActiveConfig("qt_dll")) + if (configs.findIndex("qt") == -1) + configs.append("qt"); + + if ( project->isActiveConfig("qt") ) { + if ( project->isActiveConfig( "plugin" ) ) { + project->variables()["CONFIG"].append("dll"); + if(project->isActiveConfig("qt")) + project->variables()["DEFINES"].append("QT_PLUGIN"); + } + if ( (project->variables()["DEFINES"].findIndex("QT_NODLL") == -1) && + ((project->variables()["DEFINES"].findIndex("QT_MAKEDLL") != -1 || + project->variables()["DEFINES"].findIndex("QT_DLL") != -1) || + (getenv("QT_DLL") && !getenv("QT_NODLL"))) ) { + project->variables()["QMAKE_QT_DLL"].append("1"); + if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) + project->variables()["CONFIG"].append("dll"); + } + if ( project->isActiveConfig("thread") ) + project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT"); + if ( project->isActiveConfig("accessibility" ) ) + project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT"); + if ( project->isActiveConfig("tablet") ) + project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT"); + } + + if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { + project->variables()["CONFIG"].remove("staticlib"); + project->variables()["QMAKE_APP_OR_DLL"].append("1"); + } else { + project->variables()["CONFIG"].append("staticlib"); + } + + if ( project->isActiveConfig("warn_off") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"]; + } else if ( project->isActiveConfig("warn_on") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"]; + } + + if ( project->isActiveConfig("debug") ) { + if ( project->isActiveConfig("thread") ) { + // use the DLL RT even here + if ( project->variables()["DEFINES"].contains("QT_DLL") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DBG"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"]; + } + } + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"]; + } else { + if ( project->isActiveConfig("thread") ) { + if ( project->variables()["DEFINES"].contains("QT_DLL") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLL"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT"]; + } + } + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"]; + } + + if ( !project->variables()["QMAKE_INCDIR"].isEmpty()) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"]; + + if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") ) + project->variables()["CONFIG"].append("windows"); + + if ( project->isActiveConfig("qt") ) { + project->variables()["CONFIG"].append("moc"); + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; + project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"]; + if ( !project->isActiveConfig("debug") ) + project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG"); + if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { + if ( !project->variables()["QMAKE_QT_DLL"].isEmpty()) { + project->variables()["DEFINES"].append("QT_MAKEDLL"); + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_QT_DLL"]; + } + } else { + + if(project->isActiveConfig("thread")) + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; + else + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; + if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { + int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt"); + if ( hver == -1 ) + hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt"); + if(hver != -1) { + QString ver; + ver.sprintf("libqt-%s" QTDLL_POSTFIX "%d.a", (project->isActiveConfig("thread") ? "-mt" : ""), hver); + QStringList &libs = project->variables()["QMAKE_LIBS"]; +// @@@HGTODO maybe we must change the replace regexp if we understand what's going on + for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) + (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver); + } + } + if ( project->isActiveConfig( "activeqt" ) ) { + project->variables().remove("QMAKE_LIBS_QT_ENTRY"); + project->variables()["QMAKE_LIBS_QT_ENTRY"] = "-lqaxserver"; + if ( project->isActiveConfig( "dll" ) ) { + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"]; + } + } + if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) { + project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"]; + } + + // QMAKE_LIBS_QT_ENTRY should be first on the link line as it needs qt + project->variables()["QMAKE_LIBS"].remove(project->variables()["QMAKE_LIBS_QT_ENTRY"].first()); + project->variables()["QMAKE_LIBS"].prepend(project->variables()["QMAKE_LIBS_QT_ENTRY"].first()); + + } + } + + if ( project->isActiveConfig("opengl") ) { + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"]; + } + + if ( project->isActiveConfig("dll") ) { + project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE_DLL"]; + project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE_DLL"]; + project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE_DLL"]; + project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS_DLL"]; + if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty()) { + project->variables()["TARGET_EXT"].append( + QStringList::split('.',project->first("VERSION")).join("") + ".dll"); + } else { + project->variables()["TARGET_EXT"].append(".dll"); + } + } else { + project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE"]; + project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE"]; + project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE"]; + project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS"]; + if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty()) { + project->variables()["TARGET_EXT"].append(".exe"); + } else { + project->variables()["TARGET_EXT"].append(".a"); + project->variables()["QMAKE_LFLAGS"].append("-static"); + if(project->variables()["TARGET"].first().left(3) != "lib") + project->variables()["TARGET"].first().prepend("lib"); + } + } + + if ( project->isActiveConfig("windows") ) { + if ( project->isActiveConfig("console") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; + } else { + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"]; + } + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; + } + + if ( project->isActiveConfig("exceptions") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_OFF"]; + } + + if ( project->isActiveConfig("rtti") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_OFF"]; + } + + if ( project->isActiveConfig("moc") ) + setMocAware(TRUE); + + // add -L libs to libdir + QStringList &libs = project->variables()["QMAKE_LIBS"]; + for ( QStringList::Iterator libit = libs.begin(); libit != libs.end(); ) { + if ( (*libit).startsWith( "-L" ) ) { + project->variables()["QMAKE_LIBDIR"] += (*libit).mid(2); + libit = libs.remove( libit ); + } else { + ++libit; + } + } + + project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', + "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH"); + QStringList &l = project->variables()["QMAKE_FILETAGS"]; + QStringList::Iterator it; + for(it = l.begin(); it != l.end(); ++it) { + QStringList &gdmf = project->variables()[(*it)]; + for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner) + (*inner) = Option::fixPathToTargetOS((*inner), FALSE); + } + + if ( project->isActiveConfig("dll") ) { + QString destDir = ""; + if (!project->first("DESTDIR").isEmpty()) + destDir = project->first("DESTDIR") + Option::dir_sep; + project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,--out-implib,") + + destDir + "lib" + project->first("TARGET") + ".a"); + } + + if ( !project->variables()["DEF_FILE"].isEmpty() ) + project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,") + project->first("DEF_FILE")); +// if(!project->isActiveConfig("incremental")) +// project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no")); + +#if 0 + if ( !project->variables()["VERSION"].isEmpty() ) { + QString version = project->variables()["VERSION"][0]; + int firstDot = version.find( "." ); + QString major = version.left( firstDot ); + QString minor = version.right( version.length() - firstDot - 1 ); + minor.replace( ".", "" ); + project->variables()["QMAKE_LFLAGS"].append( "/VERSION:" + major + "." + minor ); + } +#endif + + if ( !project->variables()["RC_FILE"].isEmpty()) { + if ( !project->variables()["RES_FILE"].isEmpty()) { + fprintf(stderr, "Both .rc and .res file specified.\n"); + fprintf(stderr, "Please specify one of them, not both."); + exit(666); + } + project->variables()["RES_FILE"] = project->variables()["RC_FILE"]; + project->variables()["RES_FILE"].first().replace(".rc",".o"); + project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["CLEAN_FILES"] += project->variables()["RES_FILE"]; + } + + if ( !project->variables()["RES_FILE"].isEmpty()) + project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"]; + + MakefileGenerator::init(); + + if ( !project->variables()["VERSION"].isEmpty()) { + QStringList l = QStringList::split('.', project->first("VERSION")); + project->variables()["VER_MAJ"].append(l[0]); + project->variables()["VER_MIN"].append(l[1]); + } + + if(project->isActiveConfig("dll")) { + project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") +"lib" + project->first("TARGET") + ".a"); + } + + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + if(tmp_out.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1) + project->variables()["OBJCOMP"] += out; + } + } + } +} + +void +MingwMakefileGenerator::writeSubDirs(QTextStream &t) +{ + QString qs ; + QTextStream ts (&qs, IO_WriteOnly) ; + Win32MakefileGenerator::writeSubDirs( ts ) ; + QRegExp rx("(\\n\\tcd [^\\n\\t]+)(\\n\\t.+)\\n\\t@cd ..") ; + rx.setMinimal(TRUE); + int pos = 0 ; + while ( -1 != (pos = rx.search( qs, pos))) + { + QString qsMatch = rx.cap(2); + qsMatch.replace("\n\t"," && \\\n\t"); + qs.replace(pos+rx.cap(1).length(), rx.cap(2).length(), qsMatch ); + pos += (rx.cap(1).length()+qsMatch.length()); + } + t << qs ; +} diff --git a/qmake/generators/win32/mingw_make.h b/qmake/generators/win32/mingw_make.h index c00bf1b..d971e3a 100644 --- a/qmake/generators/win32/mingw_make.h +++ b/qmake/generators/win32/mingw_make.h @@ -1,58 +1,61 @@ -/****************************************************************************
-** $Id$
-**
-** Definition of ________ class.
-**
-** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
-**
-** This file is part of the network module of the Qt GUI Toolkit.
-**
-** This file may be distributed under the terms of the Q Public License
-** as defined by Trolltech AS of Norway and appearing in the file
-** LICENSE.QPL included in the packaging of this file.
-**
-** This file may be distributed and/or modified under the terms of the
-** GNU General Public License version 2 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file.
-**
-** Licensees holding valid Qt Enterprise Edition licenses may use this
-** file in accordance with the Qt Commercial License Agreement provided
-** with the Software.
-**
-** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
-** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-**
-** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
-** information about Qt Commercial License Agreements.
-** See http://www.trolltech.com/qpl/ for QPL licensing information.
-** See http://www.trolltech.com/gpl/ for GPL licensing information.
-**
-** Contact info@trolltech.com if any conditions of this licensing are
-** not clear to you.
-**
-**********************************************************************/
-#ifndef __MINGW_MAKE_H__
-#define __MINGW_MAKE_H__
-
-#include "winmakefile.h"
-
-class MingwMakefileGenerator : public Win32MakefileGenerator
-{
- bool init_flag;
- void writeMingwParts(QTextStream &);
- void writeSubDirs(QTextStream &t) ;
-
- bool writeMakefile(QTextStream &);
- void init();
-
-public:
- MingwMakefileGenerator(QMakeProject *p);
- ~MingwMakefileGenerator();
-
-};
-
-inline MingwMakefileGenerator::~MingwMakefileGenerator()
-{ }
-
-#endif /* __MINGW_MAKE_H__ */
+/**************************************************************************** +** +** +** Definition of MingwMakefileGenerator class. +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of qmake. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition licenses may use this +** file in accordance with the Qt Commercial License Agreement provided +** with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef __MINGW_MAKE_H__ +#define __MINGW_MAKE_H__ + +#include "winmakefile.h" + +class MingwMakefileGenerator : public Win32MakefileGenerator +{ + bool init_flag; + void writeMingwParts(QTextStream &); + void writeSubDirs(QTextStream &t) ; + + bool writeMakefile(QTextStream &); + void init(); + + virtual bool findLibraries(); + +public: + MingwMakefileGenerator(QMakeProject *p); + ~MingwMakefileGenerator(); + +}; + +inline MingwMakefileGenerator::~MingwMakefileGenerator() +{ } + +#endif /* __MINGW_MAKE_H__ */ diff --git a/qmake/generators/win32/msvc_dsp.cpp b/qmake/generators/win32/msvc_dsp.cpp index 3fa0496..d2abac6 100644 --- a/qmake/generators/win32/msvc_dsp.cpp +++ b/qmake/generators/win32/msvc_dsp.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of DspMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -80,2 +78,4 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) } + if (dspfile.startsWith("\"") && dspfile.endsWith("\"")) + dspfile = dspfile.mid(1, dspfile.length() - 2); QString dspfile_loc = findTemplate(dspfile); @@ -89,2 +89,26 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) + QString platform = "Win32"; + if ( !project->variables()["QMAKE_PLATFORM"].isEmpty() ) + platform = varGlue("QMAKE_PLATFORM", "", " ", ""); + + // Setup PCH variables + precompH = project->first("PRECOMPILED_HEADER"); + QString namePCH = QFileInfo(precompH).fileName(); + usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header"); + if (usePCH) { + // Created files + QString origTarget = project->first("QMAKE_ORIG_TARGET"); + origTarget.replace(QRegExp("-"), "_"); + precompObj = "\"$(IntDir)\\" + origTarget + Option::obj_ext + "\""; + precompPch = "\"$(IntDir)\\" + origTarget + ".pch\""; + // Add PRECOMPILED_HEADER to HEADERS + if (!project->variables()["HEADERS"].contains(precompH)) + project->variables()["HEADERS"] += precompH; + // Add precompile compiler options + project->variables()["PRECOMPILED_FLAGS_REL"] = "/Yu\"" + namePCH + "\" /FI\"" + namePCH + "\" "; + project->variables()["PRECOMPILED_FLAGS_DEB"] = "/Yu\"" + namePCH + "\" /FI\"" + namePCH + "\" "; + // Return to variable pool + project->variables()["PRECOMPILED_OBJECT"] = precompObj; + project->variables()["PRECOMPILED_PCH"] = precompPch; + } int rep; @@ -113,3 +137,5 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) t << "# Begin Source File\n\nSOURCE=" << (*it) << endl; - if ( project->isActiveConfig("moc") && (*it).endsWith(Option::moc_ext)) { + if (usePCH && (*it).endsWith(".c")) + t << "# SUBTRACT CPP /FI\"" << namePCH << "\" /Yu\"" << namePCH << "\" /Fp" << endl; + if ( project->isActiveConfig("moc") && (*it).endsWith(Option::cpp_moc_ext)) { QString base = (*it); @@ -126,4 +152,4 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF " << endl << endl; @@ -148,21 +174,73 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) t << "# Begin Source File\n\nSOURCE=" << (*it) << endl << endl; - if ( project->isActiveConfig("moc") && !findMocDestination((*it)).isEmpty()) { - QString base = (*it); + QString compilePCH; + QStringList customDependencies; + QString createMOC; + QString buildCmdsR, buildCmdsD; + QString buildCmds = "\nBuildCmds= \\\n"; + // Create unique baseID + QString base = (*it); + { base.replace(QRegExp("\\..*$"), "").upper(); base.replace(QRegExp("[^a-zA-Z]"), "_"); + } + if (usePCH && precompH.endsWith(*it)) { + QString basicBuildCmd = QString("\tcl.exe /TP /W3 /FD /c /D \"WIN32\" /Yc /Fp\"%1\" /Fo\"%2\" %3 %4 %5 %6 %7 %8 %9 /D \"") + .arg(precompPch) + .arg(precompObj) + .arg(var("MSVCDSP_INCPATH")) + .arg(var("MSVCDSP_DEFINES")) + .arg(var("MSVCDSP_CXXFLAGS")); + buildCmdsR = basicBuildCmd + .arg("/D \"NDEBUG\"") + .arg(var("QMAKE_CXXFLAGS_RELEASE")) + .arg(var("MSVCDSP_MTDEF")) + .arg(var("MSVCDSP_RELDEFS")); + buildCmdsD = basicBuildCmd + .arg("/D \"_DEBUG\" /Od") + .arg(var("QMAKE_CXXFLAGS_DEBUG")) + .arg(var("MSVCDSP_MTDEFD")) + .arg(var("MSVCDSP_DEBUG_OPT")); + if (project->first("TEMPLATE") == "vcapp") { // App + buildCmdsR += var("MSVCDSP_WINCONDEF"); + buildCmdsD += var("MSVCDSP_WINCONDEF"); + } else if (project->isActiveConfig("dll")) { // Dll + buildCmdsR += "_WINDOWS\" /D \"_USRDLL"; + buildCmdsD += "_WINDOWS\" /D \"_USRDLL"; + } else { // Lib + buildCmdsR += "_LIB"; + buildCmdsD += "_LIB"; + } + buildCmdsR += "\" /Fd\"$(IntDir)\\\\\" " + (*it) + " \\\n"; + buildCmdsD += "\" /Fd\"$(IntDir)\\\\\" " + (*it) + " \\\n"; + + compilePCH = precompPch + " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n $(BuildCmds)\n\n"; + QStringList &tmp = findDependencies(precompH); + if(!tmp.isEmpty()) // Got Deps for PCH + customDependencies += tmp; + } + if (project->isActiveConfig("moc") && !findMocDestination((*it)).isEmpty()) { QString mocpath = var( "QMAKE_MOC" ); mocpath = mocpath.replace( QRegExp( "\\..*$" ), "" ) + " "; - - QString build = "\n\n# Begin Custom Build - Moc'ing " + (*it) + - "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + findMocDestination((*it)) + - "\"" " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n" - "\t" + mocpath + (*it) + " -o " + - findMocDestination((*it)) + "\n\n" "# End Custom Build\n\n"; - - t << "USERDEP_" << base << "=\"$(QTDIR)\\bin\\moc.exe\"" << endl << endl; - - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" - << build << "!ENDIF " << endl << endl; + buildCmds += "\t" + mocpath + (*it) + " -o " + findMocDestination((*it)) + " \\\n"; + createMOC = "\"" + findMocDestination((*it)) + "\" : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n $(BuildCmds)\n\n"; + customDependencies += "\"$(QTDIR)\\bin\\moc.exe\""; + } + if (!createMOC.isEmpty() || !compilePCH.isEmpty()) { + bool doMOC = !createMOC.isEmpty(); + bool doPCH = !compilePCH.isEmpty(); + QString build = "\n\n# Begin Custom Build - "+ + QString(doMOC?"Moc'ing ":"") + + QString((doMOC&&doPCH)?" and ":"") + + QString(doPCH?"Creating PCH cpp from ":"") + + (*it) + "...\nInputPath=.\\" + (*it) + "\n\n" + + buildCmds + "%1\n" + + createMOC + + compilePCH + + "# End Custom Build\n\n"; + + t << "USERDEP_" << base << "=" << valGlue(customDependencies, "\"", "\" \"", "\"") << endl << endl; + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build.arg(buildCmdsR) + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build.arg(buildCmdsD) + << "!ENDIF " << endl << endl; } @@ -254,3 +332,3 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) t << "# Begin Source File\n\nSOURCE=" << (*it) << endl; - if ( project->isActiveConfig("moc") && (*it).endsWith(Option::moc_ext)) { + if ( project->isActiveConfig("moc") && (*it).endsWith(Option::cpp_moc_ext)) { QString base = (*it); @@ -267,4 +345,4 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF " << endl << endl; @@ -389,3 +467,4 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) " -i " + fname + ".h -o " + uiSourcesDir + fname + ".cpp \\\n" - "\t" + mocpath + uiHeadersDir + fname + ".h -o " + mocFile + "moc_" + fname + ".cpp \\\n"; + "\t" + mocpath + " " + uiHeadersDir + + fname + ".h -o " + mocFile + Option::h_moc_mod + fname + Option::h_moc_ext + " \\\n"; @@ -395,3 +474,3 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) "\t$(BuildCmds)\n\n" - "\"" + mocFile + "moc_" + fname + ".cpp\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" + "\"" + mocFile + Option::h_moc_mod + fname + Option::h_moc_ext + "\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" "\t$(BuildCmds)\n\n"); @@ -400,4 +479,4 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF \n\n" << "# End Source File" << endl; @@ -431,4 +510,4 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) "# End Custom Build\n\n"; - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF \n\n" << build @@ -467,4 +546,4 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF \n\n" @@ -534,2 +613,3 @@ DspMakefileGenerator::init() + /* this should probably not be here, but I'm using it to wrap the .t files */ @@ -550,2 +630,8 @@ DspMakefileGenerator::init() if(configs.findIndex("qt") == -1) configs.append("qt"); + if ( project->isActiveConfig("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); + } if ( project->isActiveConfig("qt") ) { @@ -583,2 +669,10 @@ DspMakefileGenerator::init() + if ( project->isActiveConfig("qtopiainc") ) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"]; + if ( project->isActiveConfig("qtopialib") ) { + if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA")) + project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QTOPIA"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"]; + } + if ( project->isActiveConfig("qt") ) { @@ -636,2 +730,4 @@ DspMakefileGenerator::init() project->variables()["MSVCDSP_OBJECTSDIRREL"] = project->first("OBJECTS_DIR"); + else + project->variables()["MSVCDSP_OBJECTSDIRREL"] = "Release"; project->variables()["MSVCDSP_OBJECTSDIRDEB"] = "Debug"; @@ -672,2 +768,6 @@ DspMakefileGenerator::init() if ( project->isActiveConfig("dll") ) { + project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE_DLL"]; + project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE_DLL"]; + project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE_DLL"]; + project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS_DLL"]; if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { @@ -680,2 +780,6 @@ DspMakefileGenerator::init() } else { + project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE"]; + project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE"]; + project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE"]; + project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS"]; if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) @@ -686,2 +790,19 @@ DspMakefileGenerator::init() + if ( project->isActiveConfig("windows") ) { + if ( project->isActiveConfig("console") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; + } else { + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"]; + } + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; + } + project->variables()["MSVCDSP_VER"] = "6.00"; @@ -734,3 +855,2 @@ DspMakefileGenerator::init() project->variables()["MSVCDSP_DSPTYPE"].append("0x0103"); - project->variables()["MSVCDSP_SUBSYSTEM"].append("console"); } else { @@ -739,3 +859,2 @@ DspMakefileGenerator::init() project->variables()["MSVCDSP_DSPTYPE"].append("0x0101"); - project->variables()["MSVCDSP_SUBSYSTEM"].append("windows"); } @@ -750,3 +869,16 @@ DspMakefileGenerator::init() project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"]; + + processPrlFiles(); + // Update -lname to name.lib, + QStringList &libs2 = project->variables()["QMAKE_LIBS"]; + for ( QStringList::Iterator libit2 = libs2.begin(); libit2 != libs2.end(); ++libit2 ) { + if ( (*libit2).startsWith( "-l" ) ) { + (*libit2) = (*libit2).mid( 2 ) + ".lib"; + } else if ( (*libit2).startsWith( "-L" ) ) { + project->variables()["QMAKE_LIBDIR"] += (*libit2).mid(2); + libit2 = libs2.remove( libit2 ); + } + } + project->variables()["MSVCDSP_LFLAGS" ] += project->variables()["QMAKE_LFLAGS"]; @@ -758,3 +890,5 @@ DspMakefileGenerator::init() - processPrlFiles(); + if (!project->variables()["RES_FILE"].isEmpty()) + project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"]; + QStringList &libs = project->variables()["QMAKE_LIBS"]; @@ -770,2 +904,4 @@ DspMakefileGenerator::init() inc.replace("\"", ""); + if(inc.endsWith("\\")) // Remove trailing \'s from paths + inc.truncate(inc.length()-1); project->variables()["MSVCDSP_INCPATH"].append("/I \"" + inc + "\""); @@ -822,11 +958,8 @@ DspMakefileGenerator::init() version = "1.0"; - - project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".idl" ); - project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".tlb" ); - project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".midl" ); + project->variables()["MSVCDSP_IDLSOURCES"].append( var("OBJECTS_DIR") + targetfilename + ".idl" ); if ( project->isActiveConfig( "dll" ) ) { activeQtStepPreCopyDll += - "\t" + idc + " %1 -idl tmp\\" + targetfilename + ".idl -version " + version + - "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" - "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb"; + "\t" + idc + " %1 -idl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version + + "\t" + idl + " /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb" + + "\t" + idc + " %2 /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"; activeQtStepPostCopyDll += @@ -843,5 +976,5 @@ DspMakefileGenerator::init() activeQtStepPreCopyDll += - "\t%1 -dumpidl tmp\\" + targetfilename + ".idl -version " + version + - "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" - "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb"; + "\t%1 -dumpidl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version + + "\t" + idl + " /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb" + + "\t" + idc + " %2 /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"; activeQtStepPostCopyDll += @@ -883,3 +1016,3 @@ DspMakefileGenerator::init() } - project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCDSP_LIBS"; + project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCDSP_LIBS"; } @@ -921,3 +1054,2 @@ DspMakefileGenerator::beginGroupForFile(QString file, QTextStream &t, return; - fileFixify(file, QDir::currentDirPath(), QDir::currentDirPath(), TRUE); @@ -933,9 +1065,12 @@ DspMakefileGenerator::beginGroupForFile(QString file, QTextStream &t, } - if(file.startsWith(currentGroup)) - file = file.mid(currentGroup.length()); + + QString tempFile = file; + if(tempFile.startsWith(currentGroup)) + tempFile = tempFile.mid(currentGroup.length()); int dirSep = currentGroup.findRev( Option::dir_sep ); - while( !file.startsWith( currentGroup ) && dirSep != -1 ) { + + while( !tempFile.startsWith( currentGroup ) && dirSep != -1 ) { currentGroup.truncate( dirSep ); dirSep = currentGroup.findRev( Option::dir_sep ); - if ( !file.startsWith( currentGroup ) && dirSep != -1 ) + if ( !tempFile.startsWith( currentGroup ) && dirSep != -1 ) t << "\n# End Group\n"; @@ -946,2 +1081,3 @@ DspMakefileGenerator::beginGroupForFile(QString file, QTextStream &t, } + QStringList dirs = QStringList::split(Option::dir_sep, file.right( file.length() - currentGroup.length() ) ); @@ -975,2 +1111,4 @@ DspMakefileGenerator::openOutput(QFile &file) const if(!file.name().isEmpty()) { + if(QDir::isRelativePath(file.name())) + file.setName(Option::output_dir + file.name()); //pwd when qmake was run QFileInfo fi(file); diff --git a/qmake/generators/win32/msvc_dsp.h b/qmake/generators/win32/msvc_dsp.h index 3a7d18e..0e86539 100644 --- a/qmake/generators/win32/msvc_dsp.h +++ b/qmake/generators/win32/msvc_dsp.h @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of DspMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -36,2 +34,3 @@ **********************************************************************/ + #ifndef __MSVC_DSP_H__ @@ -64,2 +63,6 @@ protected: virtual bool findLibraries(); + + QString precompH, + precompObj, precompPch; + bool usePCH; }; diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index ecef34d..528cb19 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of NmakeMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -45,3 +43,2 @@ - NmakeMakefileGenerator::NmakeMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) @@ -56,2 +53,7 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { + { //write the extra unix targets.. + QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; + for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it) + t << *it << " "; + } t << "all clean:" << "\n\t" @@ -76,2 +78,20 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) +QStringList +&NmakeMakefileGenerator::findDependencies(const QString &file) +{ + QStringList &aList = MakefileGenerator::findDependencies(file); + // Note: The QMAKE_IMAGE_COLLECTION file have all images + // as dependency, so don't add precompiled header then + if (file == project->first("QMAKE_IMAGE_COLLECTION")) + return aList; + for(QStringList::Iterator it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) { + if(file.endsWith(*it)) { + if(!aList.contains(precompH)) + aList += precompH; + break; + } + } + return aList; +} + void @@ -97,4 +117,4 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) QString inc = (*incit); - inc.replace(QRegExp("\\\\$"), "\\\\"); - inc.replace("\"", ""); + if (inc.endsWith("\\")) + inc.truncate(inc.length()-1); t << " -I\"" << inc << "\""; @@ -113,4 +133,4 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) QString lib = (*libit); - lib.replace(QRegExp("\\\\$"), "\\\\"); - lib.replace(QRegExp("\""), ""); + if (lib.endsWith("\\")) + lib.truncate(lib.length()-1); t << " \"" << lib << "\""; @@ -140,2 +160,4 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) t << "MKDIR = " << var("QMAKE_MKDIR") << endl; + t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl; t << endl; @@ -151,2 +173,19 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) t << "OBJMOC = " << varList("OBJMOC") << endl; + + QString extraCompilerDeps; + if(!project->isEmpty("QMAKE_EXTRA_WIN_COMPILERS")) { + t << "OBJCOMP = " << varList("OBJCOMP") << endl; + extraCompilerDeps += " $(OBJCOMP) "; + + QStringList &comps = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) { + QStringList &vars = project->variables()[(*compit) + ".variables"]; + for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) { + QStringList vals = project->variables()[(*varit)]; + if(!vals.isEmpty()) + t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << endl; + } + } + } + t << "DIST = " << varList("DISTFILES") << endl; @@ -166,2 +205,3 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) t << endl << endl; + if(!project->isActiveConfig("no_batch")) { @@ -173,8 +213,10 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) source_directories.insert(".", (void*)1); - if(!project->isEmpty("MOC_DIR")) - source_directories.insert(project->first("MOC_DIR"), (void*)1); - if(!project->isEmpty("UI_SOURCES_DIR")) - source_directories.insert(project->first("UI_SOURCES_DIR"), (void*)1); - else if(!project->isEmpty("UI_DIR")) - source_directories.insert(project->first("UI_DIR"), (void*)1); + QString directories[] = { QString("MOC_DIR"), QString("UI_SOURCES_DIR"), QString("UI_DIR"), QString::null }; + for(int y = 0; !directories[y].isNull(); y++) { + QString dirTemp = project->first(directories[y]); + if (dirTemp.endsWith("\\")) + dirTemp.truncate(dirTemp.length()-1); + if(!dirTemp.isEmpty()) + source_directories.insert(dirTemp, (void*)1); + } QString srcs[] = { QString("SOURCES"), QString("UICIMPLS"), QString("SRCMOC"), QString::null }; @@ -208,5 +250,5 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) t << "####### Build rules" << endl << endl; - t << "all: " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl; - t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " - << var("POST_TARGETDEPS"); + t << "all: " << fileFixify(Option::output.name()) << " " << varGlue("ALL_DEPS"," "," "," ") << "$(TARGET)" << endl << endl; + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << extraCompilerDeps << var("POST_TARGETDEPS"); if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { @@ -218,2 +260,3 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) } + t << extraCompilerDeps; t << endl << "<<" << endl; @@ -224,3 +267,3 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { - t << "\n\t" << "-copy $(TARGET) " << *dlldir; + t << "\n\t" << "-$(COPY_FILE) \"$(TARGET)\" " << *dlldir; } @@ -234,10 +277,10 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) if ( project->isActiveConfig("dll")) { - t << "\n\t" << ("-$(IDC) $(TARGET) /idl tmp\\" + targetfilename + ".idl -version " + version); - t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"); - t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /idl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" ); } else { - t << "\n\t" << ("-$(TARGET) -dumpidl tmp\\" + targetfilename + ".idl -version " + version); - t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"); - t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb"); + t << "\n\t" << ("-$(TARGET) -dumpidl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); t << "\n\t" << "-$(TARGET) -regserver"; @@ -252,3 +295,4 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) - t << "mocables: $(SRCMOC)" << endl << endl; + t << "mocables: $(SRCMOC)" << endl + << "uicables: $(UICIMPLS) $(UICDECLS)" << endl << endl; @@ -256,25 +300,44 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) + QStringList dist_files = Option::mkfile::project_files; + if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES")) + dist_files += project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"]; + if(!project->isEmpty("TRANSLATIONS")) + dist_files << var("TRANSLATIONS"); + if(!project->isEmpty("FORMS")) { + QStringList &forms = project->variables()["FORMS"]; + for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) { + QString ui_h = fileFixify((*formit) + Option::h_ext.first()); + if(QFile::exists(ui_h) ) + dist_files << ui_h; + } + } t << "dist:" << "\n\t" - << "$(ZIP) " << var("PROJECT") << ".zip " - << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" << endl << endl; - - t << "clean:" - << varGlue("OBJECTS","\n\t-del ","\n\t-del ","") - << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","") - << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","") - << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","") - << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","") - << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","") - << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ",""); - + << "$(ZIP) " << var("QMAKE_ORIG_TARGET") << ".zip " << "$(SOURCES) $(HEADERS) $(DIST) $(FORMS) " + << dist_files.join(" ") << " " << var("TRANSLATIONS") << " " << var("IMAGES") << endl << endl; + + t << "uiclean:" + << varGlue("UICDECLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("UICIMPLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") << endl; + + t << "mocclean:" + << varGlue("SRCMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("OBJMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") << endl; + + t << "clean: uiclean mocclean" + << varGlue("OBJECTS","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","\n") + << varGlue("CLEAN_FILES","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","\n"); if ( project->isActiveConfig("activeqt")) { - t << ("\n\t-del tmp\\" + targetfilename + ".*"); - t << "\n\t-del tmp\\dump.*"; + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".idl"); + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".tlb"); } if(!project->isEmpty("IMAGES")) - t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", ""); + t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-$(DEL_FILE) ", "\n\t-$(DEL_FILE) ", ""); + t << endl; + + // user defined targets - // blasted user defined targets + QStringList::Iterator it; QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; - for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) { + for(it = qut.begin(); it != qut.end(); ++it) { QString targ = var((*it) + ".target"), @@ -290,2 +353,5 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) } + if(!project->variables()["QMAKE_NOFORCE"].isEmpty() && + project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; t << "\n\n" << targ << ":" << deps << "\n\t" @@ -293,10 +359,95 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) } - t << endl << endl; + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + QString tmp_dep = project->variables()[(*it) + ".depends"].join(" "); + QStringList &vars = project->variables()[(*it) + ".variables"]; + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out, cmd = tmp_cmd, deps; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + cmd.replace("${QMAKE_FILE_BASE}", fi.baseName()); + cmd.replace("${QMAKE_FILE_OUT}", out); + cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3) + cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); + if(!tmp_dep.isEmpty()) { + char buff[256]; + QString dep_cmd = tmp_dep; + dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) { + while(!feof(proc)) { + int read_in = int(fread(buff, 1, 255, proc)); + if(!read_in) + break; + int l = 0; + for(int i = 0; i < read_in; i++) { + if(buff[i] == '\n' || buff[i] == ' ') { + deps += " " + QCString(buff+l, (i - l) + 1); + l = i; + } + } + } + fclose(proc); + } + } + t << out << ": " << in << deps << "\n\t" + << cmd << endl << endl; + } + } + } + t << endl; + + if(project->variables()["QMAKE_NOFORCE"].isEmpty()) + t << "FORCE:" << endl << endl; + t << "distclean: clean" - << "\n\t-del $(TARGET)" + << "\n\t-$(DEL_FILE) $(TARGET)" << endl << endl; + + // precompiled header + if(usePCH) { + QString precompRule = QString("-c -Yc -Fp%1 -Fo%2").arg(precompPch).arg(precompObj); + t << precompObj << ": " << precompH << " " << findDependencies(precompH).join(" \\\n\t\t") + << "\n\t" << "$(CXX) " + precompRule +" $(CXXFLAGS) $(INCPATH) -TP " << precompH << endl << endl; + } } +QString +NmakeMakefileGenerator::var(const QString &value) +{ + if (usePCH) { + if ((value == "QMAKE_RUN_CXX_IMP_BATCH" + || value == "QMAKE_RUN_CXX_IMP" + || value == "QMAKE_RUN_CXX")) { + QFileInfo precompHInfo(precompH); + QString precompRule = QString("-c -FI%1 -Yu%2 -Fp%3") + .arg(precompHInfo.fileName()) + .arg(precompHInfo.fileName()) + .arg(precompPch); + QString p = MakefileGenerator::var(value); + p.replace("-c", precompRule); + // Cannot use -Gm with -FI & -Yu, as this gives an + // internal compiler error, on the newer compilers + p.remove("-Gm"); + return p; + } else if (value == "QMAKE_CXXFLAGS") { + // Remove internal compiler error option + return MakefileGenerator::var(value).remove("-Gm"); + } + } + + // Normal val + return MakefileGenerator::var(value); +} @@ -323,2 +474,7 @@ NmakeMakefileGenerator::init() + if(project->isEmpty("QMAKE_INSTALL_FILE")) + project->variables()["QMAKE_INSTALL_FILE"].append("$(COPY_FILE)"); + if(project->isEmpty("QMAKE_INSTALL_DIR")) + project->variables()["QMAKE_INSTALL_DIR"].append("$(COPY_DIR)"); + bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX); @@ -332,2 +488,8 @@ NmakeMakefileGenerator::init() if(configs.findIndex("qt") == -1) configs.append("qt"); + if ( project->isActiveConfig("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); + } if ( project->isActiveConfig("qt") ) { @@ -403,2 +565,9 @@ NmakeMakefileGenerator::init() project->variables()["CONFIG"].append("windows"); + if ( project->isActiveConfig("qtopiainc") ) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"]; + if ( project->isActiveConfig("qtopialib") ) { + if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA")) + project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QTOPIA"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"]; + } if ( project->isActiveConfig("qt") ) { @@ -510,2 +679,17 @@ NmakeMakefileGenerator::init() project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; + + QStringList &libList = project->variables()["QMAKE_LIBS"]; + for( QStringList::Iterator stIt = libList.begin(); stIt != libList.end(); ) { + QString s = *stIt; + if( s.startsWith( "-l" ) ) { + stIt = libList.remove( stIt ); + stIt = libList.insert( stIt, s.mid( 2 ) + ".lib" ); + } else if( s.startsWith( "-L" ) ) { + stIt = libList.remove( stIt ); + project->variables()["QMAKE_LIBDIR"].append(QDir::convertSeparators(s.mid( 2 ))); + } else { + stIt++; + } + } + project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', @@ -513,3 +697,4 @@ NmakeMakefileGenerator::init() QStringList &l = project->variables()["QMAKE_FILETAGS"]; - for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QStringList::Iterator it; + for(it = l.begin(); it != l.end(); ++it) { QStringList &gdmf = project->variables()[(*it)]; @@ -541,2 +726,3 @@ NmakeMakefileGenerator::init() project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["CLEAN_FILES"] += project->variables()["RES_FILE"]; } @@ -545,3 +731,21 @@ NmakeMakefileGenerator::init() + // Base class init! MakefileGenerator::init(); + + // Setup PCH variables + precompH = project->first("PRECOMPILED_HEADER"); + usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header"); + if (usePCH) { + // Created files + precompObj = var("OBJECTS_DIR") + project->first("TARGET") + "_pch" + Option::obj_ext; + precompPch = var("OBJECTS_DIR") + project->first("TARGET") + "_pch.pch"; + // Add linking of precompObj (required for whole precompiled classes) + project->variables()["OBJECTS"] += precompObj; + // Add pch file to cleanup + project->variables()["QMAKE_CLEAN"] += precompPch; + // Return to variable pool + project->variables()["PRECOMPILED_OBJECT"] = precompObj; + project->variables()["PRECOMPILED_PCH"] = precompPch; + } + if ( !project->variables()["VERSION"].isEmpty()) { @@ -560,2 +764,23 @@ NmakeMakefileGenerator::init() project->variables()["QMAKE_CLEAN"].append("vc*.pdb"); + project->variables()["QMAKE_CLEAN"].append("vc*.idb"); + } + + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + if(tmp_out.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1) + project->variables()["OBJCOMP"] += out; + } + } } diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h index 579fc35..f2996cd 100644 --- a/qmake/generators/win32/msvc_nmake.h +++ b/qmake/generators/win32/msvc_nmake.h @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of NmakeMakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -36,2 +34,3 @@ **********************************************************************/ + #ifndef __MSVC_NMAKE_H__ @@ -49,2 +48,8 @@ class NmakeMakefileGenerator : public Win32MakefileGenerator +protected: + QStringList &findDependencies(const QString &file); + QString var(const QString &value); + QString precompH, precompObj, precompPch; + bool usePCH; + public: diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 7ffe4f7..a672c2d 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of VCProject class. ** -** Copyright (C) 2002 Trolltech AS. All rights reserved. +** Copyright (C) 2002-2003 Trolltech AS. All rights reserved. ** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -39,17 +39,3 @@ #include <qstringlist.h> -#include <quuid.h> - -#if defined(Q_OS_WIN32) -#include <objbase.h> -#ifndef GUID_DEFINED -#define GUID_DEFINED -typedef struct _GUID -{ - ulong Data1; - ushort Data2; - ushort Data3; - uchar Data4[8]; -} GUID; -#endif -#endif +#include <qfileinfo.h> @@ -283,3 +269,2 @@ struct XPair { - // Streaming operators for property Pairs --------------------------- @@ -320,3 +305,3 @@ QTextStream &operator<<( QTextStream &strm, const SPair &prop ) if ( !prop.value.isEmpty() ) - strm << prop.name << prop.value.latin1() << "\""; + strm << prop.name << QString(prop.value).remove("\"") << "\""; return strm; @@ -336,3 +321,3 @@ VCCLCompilerTool::VCCLCompilerTool() BrowseInformation( brInfoNone ), - BufferSecurityCheck( unset ), + BufferSecurityCheck( _False ), CallingConvention( callConventionDefault ), @@ -348,3 +333,3 @@ VCCLCompilerTool::VCCLCompilerTool() EnableIntrinsicFunctions( unset ), - ExceptionHandling( unset ), + ExceptionHandling( _False ), ExpandAttributedSource( unset ), @@ -356,3 +341,3 @@ VCCLCompilerTool::VCCLCompilerTool() ImproveFloatingPointConsistency( unset ), - InlineFunctionExpansion( expandOnlyInline ), + InlineFunctionExpansion( expandDefault ), KeepComments( unset ), @@ -360,5 +345,6 @@ VCCLCompilerTool::VCCLCompilerTool() OmitFramePointers( unset ), - Optimization( optimizeDisabled ), + Optimization( optimizeCustom ), OptimizeForProcessor( procOptimizeBlended ), OptimizeForWindowsApplication( unset ), + ProgramDataBaseFileName( "" ), RuntimeLibrary( rtMultiThreaded ), @@ -373,3 +359,3 @@ VCCLCompilerTool::VCCLCompilerTool() UndefineAllPreprocessorDefinitions( unset ), - UsePrecompiledHeader( pchGenerateAuto ), + UsePrecompiledHeader( pchNone ), WarnAsError( unset ), @@ -397,3 +383,3 @@ QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) strm << TPair( _CompileOnly, tool.CompileOnly ); - strm << EPair( _DebugInformationFormat, tool.DebugInformationFormat ); + if ( tool.DebugInformationFormat != debugUnknown ) strm << EPair( _DebugInformationFormat, tool.DebugInformationFormat ); strm << TPair( _DefaultCharIsUnsigned, tool.DefaultCharIsUnsigned ); @@ -411,3 +397,3 @@ QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) strm << XPair( _ForcedUsingFiles, tool.ForcedUsingFiles ); - strm << EPair( _GeneratePreprocessedFile, tool.GeneratePreprocessedFile ); + if ( tool.GeneratePreprocessedFile != preprocessUnknown)strm << EPair( _GeneratePreprocessedFile, tool.GeneratePreprocessedFile ); strm << TPair( _GlobalOptimizations, tool.GlobalOptimizations ); @@ -415,3 +401,3 @@ QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) strm << TPair( _ImproveFloatingPointConsistency, tool.ImproveFloatingPointConsistency ); - strm << EPair( _InlineFunctionExpansion, tool.InlineFunctionExpansion ); + if ( tool.InlineFunctionExpansion != expandDefault ) strm << EPair( _InlineFunctionExpansion, tool.InlineFunctionExpansion ); strm << TPair( _KeepComments, tool.KeepComments ); @@ -420,3 +406,3 @@ QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) strm << TPair( _OmitFramePointers, tool.OmitFramePointers ); - strm << EPair( _Optimization, tool.Optimization ); + if ( tool.Optimization != optimizeDefault ) strm << EPair( _Optimization, tool.Optimization ); if ( tool.OptimizeForProcessor != procOptimizeBlended ) strm << EPair( _OptimizeForProcessor, tool.OptimizeForProcessor ); @@ -427,4 +413,4 @@ QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) strm << XPair( _PreprocessorDefinitions, tool.PreprocessorDefinitions ); - strm << SPair( _ProgramDataBaseFileName, tool.ProgramDataBaseFileName ); - strm << EPair( _RuntimeLibrary, tool.RuntimeLibrary ); + if ( !tool.ProgramDataBaseFileName.isNull() ) strm << _ProgramDataBaseFileName << tool.ProgramDataBaseFileName.latin1() << "\""; + if ( tool.RuntimeLibrary != rtUnknown ) strm << EPair( _RuntimeLibrary, tool.RuntimeLibrary ); strm << TPair( _RuntimeTypeInfo, tool.RuntimeTypeInfo ); @@ -443,3 +429,3 @@ QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) strm << TPair( _WarnAsError, tool.WarnAsError ); - strm << EPair( _WarningLevel, tool.WarningLevel ); + if ( tool.WarningLevel != warningLevelUnknown ) strm << EPair( _WarningLevel, tool.WarningLevel ); strm << TPair( _WholeProgramOptimization, tool.WholeProgramOptimization ); @@ -476,3 +462,3 @@ bool VCCLCompilerTool::parseOption( const char* option ) } - AdditionalUsingDirectories += option+2; + AdditionalUsingDirectories += option+3; break; @@ -482,3 +468,3 @@ bool VCCLCompilerTool::parseOption( const char* option ) case 'D': - PreprocessorDefinitions += option+1; + PreprocessorDefinitions += option+2; break; @@ -486,3 +472,5 @@ bool VCCLCompilerTool::parseOption( const char* option ) if ( second == 'H' ) { - if ( third == 'a' || third == 'c' || third == 's' ) { + if ( third == 'a' + || (third == 'c' && fourth != 's') + || (third == 's' && fourth != 'c') ) { // ExceptionHandling must be false, or it will override @@ -492,2 +480,7 @@ bool VCCLCompilerTool::parseOption( const char* option ) break; + } else if ( (third == 'c' && fourth == 's') + || (third == 's' && fourth == 'c') ) { + ExceptionHandling = _True; + AdditionalOptions += option; + break; } @@ -593,2 +586,5 @@ bool VCCLCompilerTool::parseOption( const char* option ) case 'X': + // ExceptionHandling == true will override with + // an /EHsc option, which is correct with /GX + ExceptionHandling = _True; // Fall-through case 'Z': @@ -956,6 +952,6 @@ VCLinkerTool::VCLinkerTool() IgnoreEmbeddedIDL( unset ), - IgnoreImportLibrary( unset ), + IgnoreImportLibrary( _True ), LargeAddressAware( addrAwareDefault ), LinkDLL( unset ), - LinkIncremental( linkIncrementalYes ), + LinkIncremental( linkIncrementalDefault ), LinkTimeCodeGeneration( unset ), @@ -1021,3 +1017,3 @@ QTextStream &operator<<( QTextStream &strm, const VCLinkerTool &tool ) strm << SPair( _OutputFile, tool.OutputFile ); - strm << SPair( _ProgramDatabaseFile, tool.ProgramDatabaseFile ); + strm << _ProgramDatabaseFile << tool.ProgramDatabaseFile << "\""; strm << TPair( _RegisterOutput, tool.RegisterOutput ); @@ -1709,5 +1705,5 @@ QTextStream &operator<<( QTextStream &strm, const VCCustomBuildTool &tool ) strm << XPair( _AdditionalDependencies4, tool.AdditionalDependencies, ";" ); - strm << SPair( _CommandLine4, tool.CommandLine ); + strm << XPair( _CommandLine4, tool.CommandLine, "\n" ); strm << SPair( _Description4, tool.Description ); - strm << SPair( _Outputs4, tool.Outputs ); + strm << XPair( _Outputs4, tool.Outputs, ";" ); strm << SPair( _ToolPath, tool.ToolPath ); @@ -1828,39 +1824,35 @@ VCFilter::VCFilter() { + useCustomBuildTool = FALSE; + useCompilerTool = FALSE; } -void VCFilter::generateMOC( QTextStream &strm, QString str ) const +void VCFilter::addMOCstage( QTextStream &strm, QString filename ) { - QString mocOutput = Project->findMocDestination( str ); + QString mocOutput = Project->findMocDestination( filename ); QString mocApp = Project->var( "QMAKE_MOC" ); - if( mocOutput.isEmpty() ) { + if( mocOutput.isEmpty() && filename.endsWith(".moc") ) { // In specialcases we DO moc .cpp files // when the result is an .moc file - if ( !str.endsWith(".moc") ) - return; - mocOutput = str; - str = Project->findMocSource( mocOutput ); + mocOutput = filename; + filename = Project->findMocSource( mocOutput ); } - strm << _begFileConfiguration; - strm << _Name5; - strm << Config->Name; - strm << "\">"; - strm << _begTool5; - strm << _VCCustomBuildTool; - strm << _Description6; - strm << "Moc'ing " << str << "...\""; - strm << _CommandLine6; - strm << mocApp; - strm << " " << str << " -o " << mocOutput << "\""; - strm << _AdditionalDependencies6; - strm << mocApp << "\""; - strm << _Outputs6; - strm << mocOutput << "\""; - strm << "/>"; - strm << _endFileConfiguration; + if (mocOutput.isEmpty()) + return; + + CustomBuildTool = VCCustomBuildTool(); + useCustomBuildTool = TRUE; + CustomBuildTool.Description = "Moc'ing " + filename + "..."; + CustomBuildTool.CommandLine += (mocApp + " " + + filename + " -o " + mocOutput); + CustomBuildTool.AdditionalDependencies = mocApp; + CustomBuildTool.Outputs += mocOutput; } -void VCFilter::generateUIC( QTextStream &strm, const QString& str ) const +void VCFilter::addUICstage( QTextStream &strm, QString str ) { + CustomBuildTool = VCCustomBuildTool(); + useCustomBuildTool = TRUE; + QString uicApp = Project->var("QMAKE_UIC"); @@ -1897,23 +1889,99 @@ void VCFilter::generateUIC( QTextStream &strm, const QString& str ) const - strm << _begFileConfiguration; - strm << _Name5; - strm << Config->Name; - strm << "\">"; - strm << _begTool5; - strm << _VCCustomBuildTool; - strm << _Description6; - strm << "Uic'ing " << str << "...\""; - strm << _CommandLine6; - strm << uicApp << " " << str << " -o " << uiHeaders << fname << ".h && "; // Create .h from .ui file - strm << uicApp << " " << str << " -i " << fname << ".h -o " << uiSources << fname << ".cpp && "; // Create .cpp from .ui file - strm << mocApp << " " << uiHeaders << fname << ".h -o " << mocDir << "moc_" << fname << ".cpp\""; - strm << _AdditionalDependencies6; - strm << mocApp << ";" << uicApp << "\""; - strm << _Outputs6; - strm << uiHeaders << fname << ".h;" << uiSources << fname << ".cpp;" << mocDir << "moc_" << fname << ".cpp\""; - strm << "/>"; - strm << _endFileConfiguration; + if ( mocDir.isEmpty() ) + mocDir = pname; + + CustomBuildTool.Description = ("Uic'ing " + str + "...\""); + CustomBuildTool.CommandLine += // Create .h from .ui file + uicApp + " " + str + " -o " + uiHeaders + fname + ".h"; + CustomBuildTool.CommandLine += // Create .cpp from .ui file + uicApp + " " + str + " -i " + fname + ".h -o " + uiSources + fname + ".cpp"; + CustomBuildTool.CommandLine += // Moc the headerfile + mocApp + " " + uiHeaders + fname + ".h -o " + mocDir + Option::h_moc_mod + fname + Option::h_moc_ext; + + CustomBuildTool.AdditionalDependencies += mocApp; + CustomBuildTool.AdditionalDependencies += uicApp; + CustomBuildTool.Outputs += + uiHeaders + fname + ".h;" + uiSources + fname + ".cpp;" + mocDir + Option::h_moc_mod + fname + Option::h_moc_ext; } -QTextStream &operator<<( QTextStream &strm, const VCFilter &tool ) +void VCFilter::modifyPCHstage( QTextStream &strm, QString str ) +{ + bool isCFile = str.endsWith(".c"); + bool isHFile = (str.endsWith(".h") && str == Project->precompH); + + if (!isCFile && !isHFile) + return; + + CompilerTool = VCCLCompilerTool(); + useCompilerTool = TRUE; + + // Unset some default options + CompilerTool.BufferSecurityCheck = unset; + CompilerTool.DebugInformationFormat = debugUnknown; + CompilerTool.ExceptionHandling = unset; + CompilerTool.GeneratePreprocessedFile = preprocessUnknown; + CompilerTool.Optimization = optimizeDefault; + CompilerTool.ProgramDataBaseFileName = QString::null; + CompilerTool.RuntimeLibrary = rtUnknown; + CompilerTool.WarningLevel = warningLevelUnknown; + + // Setup PCH options + CompilerTool.UsePrecompiledHeader = (isCFile ? pchNone : pchCreateUsingSpecific); + CompilerTool.PrecompiledHeaderThrough = "$(NOINHERIT)"; + CompilerTool.ForcedIncludeFiles = "$(NOINHERIT)"; +} + +bool VCFilter::addIMGstage( QTextStream &strm, QString str ) +{ + bool isCorH = FALSE; + if (str.endsWith(".c") || str.endsWith(".rc")) + isCorH = TRUE; + QStringList::Iterator it; + for(it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) + if(str.endsWith(*it)) + isCorH = TRUE; + for(it = Option::h_ext.begin(); it != Option::h_ext.end(); ++it) + if(str.endsWith(*it)) + isCorH = TRUE; + + QString collectionName = Project->project->first("QMAKE_IMAGE_COLLECTION"); + if (str.isEmpty() || isCorH || collectionName.isEmpty()) + return FALSE; + + CustomBuildTool = VCCustomBuildTool(); + useCustomBuildTool = TRUE; + + // Some projects (like designer core) may have too many images to + // call uic directly. Therefor we have to create a temporary + // file, with the image list, and call uic with the -f option. + QString tmpFileCmd = "echo "; + QString tmpImageFilename = ".imgcol"; + QStringList& list = Project->project->variables()["IMAGES"]; + bool firstOutput = TRUE; + it = list.begin(); + while( it!=list.end() ) { + tmpFileCmd += (*it) + " "; + ++it; + if (tmpFileCmd.length()>250 || it==list.end()) { + CustomBuildTool.CommandLine += tmpFileCmd + + (firstOutput?"> ":">> ") + + tmpImageFilename; + tmpFileCmd = "echo "; + firstOutput = FALSE; + } + } + + QString uicApp = Project->var("QMAKE_UIC"); + CustomBuildTool.Description = ("Generate imagecollection"); + CustomBuildTool.CommandLine += + uicApp + " -embed " + Project->project->first("QMAKE_ORIG_TARGET") + + " -f .imgcol -o " + collectionName; + CustomBuildTool.AdditionalDependencies += uicApp; + CustomBuildTool.AdditionalDependencies += list; + CustomBuildTool.Outputs = collectionName; + CustomBuildTool.Outputs += tmpImageFilename; + return TRUE; +} + +QTextStream &operator<<( QTextStream &strm, VCFilter &tool ) { @@ -1927,3 +1995,49 @@ QTextStream &operator<<( QTextStream &strm, const VCFilter &tool ) strm << ">"; + + bool resourceBuild = FALSE; + int currentLevels = 0; + QStringList currentDirs; for ( QStringList::ConstIterator it = tool.Files.begin(); it != tool.Files.end(); ++it ) { + if ( !tool.flat_files ) { + QStringList newDirs = QStringList::split('\\',(*it)); + newDirs.pop_back(); // Skip the filename + + int newLevels = int(newDirs.count()); + int equalLevels = 0; + for (int i = 0; i<currentLevels; i++, equalLevels++ ) + if (currentDirs[i] != newDirs[i]) + break; + int closeFilters = currentLevels - equalLevels; + int openFilters = newLevels - equalLevels; + + // close previous non-equal filter + while ( closeFilters-- ) + strm << _endFilter; + + // open new non-equal filters + newLevels = 0; + while ( openFilters-- ) { + strm << _begFilter; + strm << SPair( _Name3, newDirs[equalLevels + newLevels] ); + strm << _Filter << "\">"; // Blank filter + ++newLevels; + } + currentDirs = newDirs; + currentLevels = int(newDirs.count()); + } + + tool.useCustomBuildTool = FALSE; + tool.useCompilerTool = FALSE; + // Add UIC, MOC and PCH stages to file + if ( tool.CustomBuild == moc ) + tool.addMOCstage( strm, *it ); + else if ( tool.CustomBuild == uic ) + tool.addUICstage( strm, *it ); + else if ( tool.CustomBuild == resource ) { + if (!resourceBuild) + resourceBuild = tool.addIMGstage(strm, *it); + } + if (tool.Project->usePCH) + tool.modifyPCHstage( strm, *it ); + strm << _begFile; @@ -1931,9 +2045,23 @@ QTextStream &operator<<( QTextStream &strm, const VCFilter &tool ) strm << ">"; - if ( tool.CustomBuild == moc ) - tool.generateMOC( strm, *it ); - else if ( tool.CustomBuild == uic ) - tool.generateUIC( strm, *it ); + // Output custom build and compiler options + // for all configurations + if (tool.useCustomBuildTool || tool.useCompilerTool) { + for ( uint i = 0; i < tool.Config->count(); i++ ) { + strm << _begFileConfiguration; + strm << _Name5; + strm << (*tool.Config)[i].Name; + strm << "\">"; + if (tool.useCustomBuildTool) + strm << tool.CustomBuildTool; + if (tool.useCompilerTool) + strm << tool.CompilerTool; + strm << _endFileConfiguration; + } + } strm << _endFile; } - + // close remaining open filters, in non-flat mode + while ( !tool.flat_files && currentLevels-- ) { + strm << _endFilter; + } strm << _endFilter; @@ -1945,13 +2073,5 @@ VCProject::VCProject() { -#if defined(Q_WS_WIN32) - GUID guid; - QUuid uniqueId; - HRESULT h = CoCreateGuid( &guid ); - if ( h == S_OK ) - uniqueId = QUuid( guid ); - ProjectGUID = uniqueId.toString(); -#else - // Qt doesn't support GUID on other platforms yet - ProjectGUID = ""; -#endif + VCConfiguration conf; + Configuration += conf ; // Release + //Configuration += conf ; // Debug added later, after Release init } @@ -1975,13 +2095,14 @@ QTextStream &operator<<( QTextStream &strm, const VCProject &tool ) strm << _begConfigurations; - strm << tool.Configuration; + for ( uint i = 0; i < tool.Configuration.count(); i++ ) + strm << tool.Configuration[i]; strm << _endConfigurations; strm << _begFiles; - strm << tool.SourceFiles; - strm << tool.HeaderFiles; - strm << tool.MOCFiles; - strm << tool.UICFiles; - strm << tool.FormFiles; - strm << tool.TranslationFiles; - strm << tool.LexYaccFiles; - strm << tool.ResourceFiles; + strm << (VCFilter&)tool.SourceFiles; + strm << (VCFilter&)tool.HeaderFiles; + strm << (VCFilter&)tool.MOCFiles; + strm << (VCFilter&)tool.UICFiles; + strm << (VCFilter&)tool.FormFiles; + strm << (VCFilter&)tool.TranslationFiles; + strm << (VCFilter&)tool.LexYaccFiles; + strm << (VCFilter&)tool.ResourceFiles; strm << _endFiles; diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 1dca68d..9ce38d2 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -1,9 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of VCProject class. ** -** Copyright (C) 2002 Trolltech AS. All rights reserved. +** Copyright (C) 2002-2003 Trolltech AS. All rights reserved. ** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -34,2 +34,3 @@ **********************************************************************/ + #ifndef __MSVC_OBJECTMODEL_H__ @@ -58,3 +59,4 @@ enum customBuildCheck { uic, - lexyacc + lexyacc, + resource }; @@ -116,2 +118,3 @@ enum ConfigurationTypes { enum debugOption { + debugUnknown = -1, debugDisabled, @@ -242,3 +245,4 @@ enum inlineExpansionOption { expandOnlyInline, - expandAnySuitable + expandAnySuitable, + expandDefault // Not useful number, but stops the output }; @@ -298,3 +302,4 @@ enum optimizeOption { optimizeFull, - optimizeCustom + optimizeCustom, + optimizeDefault // Not useful number, but stops the output }; @@ -317,2 +322,3 @@ enum pchOption { enum preprocessOption { + preprocessUnknown = -1, preprocessNo, @@ -332,2 +338,3 @@ enum RemoteDebuggerType { enum runtimeLibraryOption { + rtUnknown = -1, rtMultiThreaded, @@ -381,2 +388,3 @@ enum useOfMfc { enum warningLevelOption { + warningLevelUnknown = -1, warningLevel_0, @@ -613,5 +621,5 @@ public: QStringList AdditionalDependencies; - QString CommandLine; + QStringList CommandLine; QString Description; - QString Outputs; + QStringList Outputs; QString ToolName; @@ -721,4 +729,6 @@ public: ~VCFilter(){} - void generateMOC( QTextStream &strm, QString str ) const; - void generateUIC( QTextStream &strm, const QString& str ) const; + void addMOCstage( QTextStream &strm, QString str ); + void addUICstage( QTextStream &strm, QString str ); + bool addIMGstage( QTextStream &strm, QString str ); + void modifyPCHstage( QTextStream &strm, QString str ); @@ -730,4 +740,9 @@ public: VcprojGenerator* Project; - VCConfiguration* Config; + QValueList<VCConfiguration> *Config; customBuildCheck CustomBuild; + bool useCustomBuildTool; + VCCustomBuildTool CustomBuildTool; + bool useCompilerTool; + VCCLCompilerTool CompilerTool; + bool flat_files; }; @@ -750,3 +765,3 @@ public: // XML sub-parts - VCConfiguration Configuration; + QValueList<VCConfiguration> Configuration; VCFilter SourceFiles; @@ -769,3 +784,3 @@ QTextStream &operator<<( QTextStream &, const VCEventTool & ); QTextStream &operator<<( QTextStream &, const VCConfiguration & ); -QTextStream &operator<<( QTextStream &, const VCFilter & ); +QTextStream &operator<<( QTextStream &, VCFilter & ); QTextStream &operator<<( QTextStream &, const VCProject & ); diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index d2cbc31..aa8fe16 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of VcprojGenerator class. +** Implementation of VcprojGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -39,2 +37,3 @@ #include "option.h" +#include "qtmd5.h" // SG's MD5 addon #include <qdir.h> @@ -44,19 +43,58 @@ #include <stdlib.h> +#include <qsettings.h> + +//#define DEBUG_SOLUTION_GEN +//#define DEBUG_PROJECT_GEN + +// Registry keys for .NET version detection ------------------------- +const char* _regNet2002 = "Microsoft\\VisualStudio\\7.0\\Setup\\VC\\ProductDir"; +const char* _regNet2003 = "Microsoft\\VisualStudio\\7.1\\Setup\\VC\\ProductDir"; -#if defined(Q_OS_WIN32) -#include <objbase.h> -#ifndef GUID_DEFINED -#define GUID_DEFINED -typedef struct _GUID +bool use_net2003_version() { - ulong Data1; - ushort Data2; - ushort Data3; - uchar Data4[8]; -} GUID; -#endif +#ifndef Q_OS_WIN32 + return FALSE; // Always generate 7.0 versions on other platforms +#else + // Only search for the version once + static int current_version = -1; + if (current_version!=-1) + return (current_version==71); + + // Fallback to .NET 2002 + current_version = 70; + + // Get registry entries for both versions + bool ok = false; + QSettings setting; + QString path2002 = setting.readEntry(_regNet2002); + QString path2003 = setting.readEntry(_regNet2003); + + if ( path2002.isNull() || path2003.isNull() ) { + // Only have one MSVC, so use that one + current_version = (path2003.isNull() ? 70 : 71); + } else { + // Have both, so figure out the current + QString paths = getenv("PATH"); + QStringList pathlist = QStringList::split(";", paths.lower()); + + path2003 = path2003.lower(); + QStringList::iterator it; + for(it=pathlist.begin(); it!=pathlist.end(); ++it) { + if ((*it).contains(path2003)) { + current_version = 71; + } else if ((*it).contains(path2002) + && current_version == 71) { + fprintf( stderr, "Both .NET 2002 & .NET 2003 directories for VC found in you PATH variable!\nFallback to .NET 2002 project generation" ); + current_version = 70; + break; + } + } + } + return (current_version==71); #endif +}; // Flatfile Tags ---------------------------------------------------- -const char* _snlHeader = "Microsoft Visual Studio Solution File, Format Version 7.00"; +const char* _slnHeader70 = "Microsoft Visual Studio Solution File, Format Version 7.00"; +const char* _slnHeader71 = "Microsoft Visual Studio Solution File, Format Version 8.00"; // The following UUID _may_ change for later servicepacks... @@ -68,18 +106,21 @@ const char* _snlHeader = "Microsoft Visual Studio Solution File, Format Version // platforms are actually usable. -const char* _snlMSVCvcprojGUID = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; -const char* _snlProjectBeg = "\nProject(\""; -const char* _snlProjectMid = "\") = "; -const char* _snlProjectEnd = "\nEndProject"; -const char* _snlGlobalBeg = "\nGlobal"; -const char* _snlGlobalEnd = "\nEndGlobal"; -const char* _snlSolutionConf = "\n\tGlobalSection(SolutionConfiguration) = preSolution" - "\n\t\tConfigName.0 = Release" +const char* _slnMSVCvcprojGUID = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; +const char* _slnProjectBeg = "\nProject(\""; +const char* _slnProjectMid = "\") = "; +const char* _slnProjectEnd = "\nEndProject"; +const char* _slnGlobalBeg = "\nGlobal"; +const char* _slnGlobalEnd = "\nEndGlobal"; +const char* _slnSolutionConf = "\n\tGlobalSection(SolutionConfiguration) = preSolution" + "\n\t\tConfigName.0 = Debug" + "\n\t\tConfigName.1 = Release" "\n\tEndGlobalSection"; -const char* _snlProjDepBeg = "\n\tGlobalSection(ProjectDependencies) = postSolution"; -const char* _snlProjDepEnd = "\n\tEndGlobalSection"; -const char* _snlProjConfBeg = "\n\tGlobalSection(ProjectConfiguration) = postSolution"; -const char* _snlProjConfTag1 = ".Release.ActiveCfg = Release|Win32"; -const char* _snlProjConfTag2 = ".Release.Build.0 = Release|Win32"; -const char* _snlProjConfEnd = "\n\tEndGlobalSection"; -const char* _snlExtSections = "\n\tGlobalSection(ExtensibilityGlobals) = postSolution" +const char* _slnProjDepBeg = "\n\tGlobalSection(ProjectDependencies) = postSolution"; +const char* _slnProjDepEnd = "\n\tEndGlobalSection"; +const char* _slnProjConfBeg = "\n\tGlobalSection(ProjectConfiguration) = postSolution"; +const char* _slnProjRelConfTag1 = ".Release.ActiveCfg = Release|Win32"; +const char* _slnProjRelConfTag2 = ".Release.Build.0 = Release|Win32"; +const char* _slnProjDbgConfTag1 = ".Debug.ActiveCfg = Debug|Win32"; +const char* _slnProjDbgConfTag2 = ".Debug.Build.0 = Debug|Win32"; +const char* _slnProjConfEnd = "\n\tEndGlobalSection"; +const char* _slnExtSections = "\n\tGlobalSection(ExtensibilityGlobals) = postSolution" "\n\tEndGlobalSection" @@ -128,2 +169,3 @@ struct VcsolutionDepend { ::target targetType; + bool debugBuild; QStringList dependencies; @@ -131,2 +173,31 @@ struct VcsolutionDepend { +QUuid VcprojGenerator::getProjectUUID(const QString &filename) +{ + bool validUUID = true; + + // Read GUID from variable-space + QUuid uuid = project->first("GUID"); + + // If none, create one based on the MD5 of absolute project path + if (uuid.isNull() || !filename.isNull()) { + QString abspath = filename.isNull()?project->first("QMAKE_MAKEFILE"):filename; + qtMD5(abspath.utf8(), (unsigned char*)(&uuid)); + validUUID = !uuid.isNull(); + uuid.data4[0] = (uuid.data4[0] & 0x3F) | 0x80; // UV_DCE variant + uuid.data3 = (uuid.data3 & 0x0FFF) | (QUuid::Name<<12); + } + + // If still not valid, generate new one, and suggest adding to .pro + if (uuid.isNull() || !validUUID) { + uuid = QUuid::createUuid(); + fprintf(stderr, + "qmake couldn't create a GUID based on filepath, and we couldn't\nfind a valid GUID in the .pro file (Consider adding\n'GUID = %s' to the .pro file)\n", + uuid.toString().upper().latin1()); + } + + // Store GUID in variable-space + project->values("GUID") = uuid.toString().upper(); + return uuid; +} + QUuid VcprojGenerator::increaseUUID( const QUuid &id ) @@ -165,20 +236,13 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) - t << _snlHeader; - QUuid solutionGUID; -#if defined(Q_WS_WIN32) - GUID guid; - HRESULT h = CoCreateGuid( &guid ); - if ( h == S_OK ) - solutionGUID = QUuid( guid ); -#else - // Qt doesn't support GUID on other platforms yet, - // so we use the all-zero uuid, and increase that. -#endif - + t << (use_net2003_version() ? _slnHeader71 : _slnHeader70); QDict<VcsolutionDepend> solution_depends; + QPtrList<VcsolutionDepend> solution_cleanup; solution_cleanup.setAutoDelete(TRUE); + + QStringList subdirs = project->variables()["SUBDIRS"]; QString oldpwd = QDir::currentDirPath(); + for(QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it) { @@ -201,4 +265,3 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) if(tmp_proj.first("TEMPLATE") == "vcsubdirs") { - QStringList tmp_subdirs = fileFixify(tmp_proj.variables()["SUBDIRS"]); - subdirs += tmp_subdirs; + subdirs += fileFixify(tmp_proj.variables()["SUBDIRS"]); } else if(tmp_proj.first("TEMPLATE") == "vcapp" || tmp_proj.first("TEMPLATE") == "vclib") { @@ -225,3 +288,3 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) if(!QFile::exists(QDir::currentDirPath() + Option::dir_sep + vcproj)) { - qDebug( "Ignored (not found) '%s'", QString(QDir::currentDirPath() + Option::dir_sep + vcproj).latin1() ); + warn_msg(WarnLogic, "Ignored (not found) '%s'", QString(QDir::currentDirPath() + Option::dir_sep + vcproj).latin1() ); goto nextfile; // # Dirty! @@ -232,24 +295,44 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) newDep->orig_target = tmp_proj.first("QMAKE_ORIG_TARGET"); - newDep->target = tmp_proj.first("TARGET").section(Option::dir_sep, -1); + newDep->target = tmp_proj.first("MSVCPROJ_TARGET").section(Option::dir_sep, -1); newDep->targetType = tmp_vcproj.projectTarget; - { - static QUuid uuid = solutionGUID; - uuid = increaseUUID( uuid ); - newDep->uuid = uuid.toString().upper(); - } + newDep->debugBuild = tmp_proj.isActiveConfig("debug"); + newDep->uuid = getProjectUUID(Option::fixPathToLocalOS(QDir::currentDirPath() + QDir::separator() + vcproj)).toString().upper(); + + // We want to store it as the .lib name. if(newDep->target.endsWith(".dll")) newDep->target = newDep->target.left(newDep->target.length()-3) + "lib"; + + // All projects using Forms are dependent on uic.exe if(!tmp_proj.isEmpty("FORMS")) newDep->dependencies << "uic.exe"; - { - QStringList where("QMAKE_LIBS"); - if(!tmp_proj.isEmpty("QMAKE_INTERNAL_PRL_LIBS")) - where = tmp_proj.variables()["QMAKE_INTERNAL_PRL_LIBS"]; - for(QStringList::iterator wit = where.begin(); - wit != where.end(); ++wit) { - QStringList &l = tmp_proj.variables()[(*wit)]; - for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { - QString opt = (*it); - if(!opt.startsWith("/")) //Not a switch - newDep->dependencies << opt.section(Option::dir_sep, -1); + + // Add all unknown libs to the deps + QStringList where("QMAKE_LIBS"); + if(!tmp_proj.isEmpty("QMAKE_INTERNAL_PRL_LIBS")) + where = tmp_proj.variables()["QMAKE_INTERNAL_PRL_LIBS"]; + for(QStringList::iterator wit = where.begin(); + wit != where.end(); ++wit) { + QStringList &l = tmp_proj.variables()[(*wit)]; + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QString opt = (*it); + if(!opt.startsWith("/") && // Not a switch + opt != newDep->target && // Not self + opt != "opengl32.lib" && // We don't care about these libs + opt != "glu32.lib" && // to make depgen alittle faster + opt != "kernel32.lib" && + opt != "user32.lib" && + opt != "gdi32.lib" && + opt != "comdlg32.lib" && + opt != "advapi32.lib" && + opt != "shell32.lib" && + opt != "ole32.lib" && + opt != "oleaut32.lib" && + opt != "uuid.lib" && + opt != "imm32.lib" && + opt != "winmm.lib" && + opt != "wsock32.lib" && + opt != "winspool.lib" && + opt != "delayimp.lib" ) + { + newDep->dependencies << opt.section(Option::dir_sep, -1); } @@ -257,14 +340,11 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) } +#ifdef DEBUG_SOLUTION_GEN + qDebug( "Deps for %20s: [%s]", newDep->target.latin1(), newDep->dependencies.join(" :: " ).latin1() ); +#endif solution_cleanup.append(newDep); solution_depends.insert(newDep->target, newDep); - { - QRegExp libVersion("[0-9]{3,3}\\.lib$"); - if(libVersion.search(newDep->target) != -1) - solution_depends.insert(newDep->target.left(newDep->target.length() - - libVersion.matchedLength()) + ".lib", newDep); - } - t << _snlProjectBeg << _snlMSVCvcprojGUID << _snlProjectMid + t << _slnProjectBeg << _slnMSVCvcprojGUID << _slnProjectMid << "\"" << newDep->orig_target << "\", \"" << newDep->vcprojFile << "\", \"" << newDep->uuid << "\""; - t << _snlProjectEnd; + t << _slnProjectEnd; } @@ -276,6 +356,10 @@ nextfile: } - t << _snlGlobalBeg; - t << _snlSolutionConf; - t << _snlProjDepBeg; + t << _slnGlobalBeg; + t << _slnSolutionConf; + t << _slnProjDepBeg; + + // Figure out dependencies for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) { + if(solution_cleanup.current()->targetType == StaticLib) + continue; // Shortcut, Static libs are not dep. int cnt = 0; @@ -283,19 +367,20 @@ nextfile: dit != solution_cleanup.current()->dependencies.end(); - ++dit) { - VcsolutionDepend *vc; - if((vc=solution_depends[*dit])) { - if(solution_cleanup.current()->targetType != StaticLib || vc->targetType == Application) - t << "\n\t\t" << solution_cleanup.current()->uuid << "." << cnt++ << " = " << vc->uuid; - } + ++dit) + { + VcsolutionDepend *vc = solution_depends[*dit]; + if(vc) + t << "\n\t\t" << solution_cleanup.current()->uuid << "." << cnt++ << " = " << vc->uuid; } } - t << _snlProjDepEnd; - t << _snlProjConfBeg; + t << _slnProjDepEnd; + t << _slnProjConfBeg; for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) { - t << "\n\t\t" << solution_cleanup.current()->uuid << _snlProjConfTag1; - t << "\n\t\t" << solution_cleanup.current()->uuid << _snlProjConfTag2; + t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjDbgConfTag1; + t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjDbgConfTag2; + t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjRelConfTag1; + t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjRelConfTag2; } - t << _snlProjConfEnd; - t << _snlExtSections; - t << _snlGlobalEnd; + t << _slnProjConfEnd; + t << _slnExtSections; + t << _slnGlobalEnd; } @@ -371,2 +456,20 @@ void VcprojGenerator::init() } + + // Setup PCH variables + precompH = project->first("PRECOMPILED_HEADER"); + usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header"); + if (usePCH) { + precompHFilename = QFileInfo(precompH).fileName(); + // Created files + QString origTarget = project->first("QMAKE_ORIG_TARGET"); + precompObj = origTarget + Option::obj_ext; + precompPch = origTarget + ".pch"; + // Add PRECOMPILED_HEADER to HEADERS + if (!project->variables()["HEADERS"].contains(precompH)) + project->variables()["HEADERS"] += precompH; + // Return to variable pool + project->variables()["PRECOMPILED_OBJECT"] = precompObj; + project->variables()["PRECOMPILED_PCH"] = precompPch; + } + initProject(); // Fills the whole project with proper data @@ -391,4 +494,5 @@ void VcprojGenerator::initProject() vcProject.Name = project->first("QMAKE_ORIG_TARGET"); - vcProject.Version = "7.00"; - vcProject.PlatformName = ( vcProject.Configuration.idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32" ); + vcProject.Version = use_net2003_version() ? "7.10" : "7.00"; + vcProject.ProjectGUID = getProjectUUID().toString().upper(); + vcProject.PlatformName = ( vcProject.Configuration[0].idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32" ); // These are not used by Qt, but may be used by customers @@ -414,6 +518,6 @@ void VcprojGenerator::initConfiguration() case SharedLib: - vcProject.Configuration.ConfigurationType = typeDynamicLibrary; + vcProject.Configuration[0].ConfigurationType = typeDynamicLibrary; break; case StaticLib: - vcProject.Configuration.ConfigurationType = typeStaticLibrary; + vcProject.Configuration[0].ConfigurationType = typeStaticLibrary; break; @@ -421,24 +525,26 @@ void VcprojGenerator::initConfiguration() default: - vcProject.Configuration.ConfigurationType = typeApplication; + vcProject.Configuration[0].ConfigurationType = typeApplication; break; } - vcProject.Configuration.Name = ( project->isActiveConfig( "debug" ) ? "Debug|" : "Release|" ); - vcProject.Configuration.Name += ( vcProject.Configuration.idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32" ); - vcProject.Configuration.ATLMinimizesCRunTimeLibraryUsage = ( project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True ); - vcProject.Configuration.BuildBrowserInformation = triState( temp.isEmpty() ? (short)unset : temp.toShort() ); + + // Release version of the Configuration --------------- + VCConfiguration &RConf = vcProject.Configuration[0]; + RConf.Name = "Release"; + RConf.Name += ( RConf.idl.TargetEnvironment == midlTargetWin64 ? "|Win64" : "|Win32" ); + RConf.ATLMinimizesCRunTimeLibraryUsage = ( project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True ); + RConf.BuildBrowserInformation = triState( temp.isEmpty() ? (short)unset : temp.toShort() ); temp = project->first("CharacterSet"); - vcProject.Configuration.CharacterSet = charSet( temp.isEmpty() ? (short)charSetNotSet : temp.toShort() ); - vcProject.Configuration.DeleteExtensionsOnClean = project->first("DeleteExtensionsOnClean"); - vcProject.Configuration.ImportLibrary = vcProject.Configuration.linker.ImportLibrary; - vcProject.Configuration.IntermediateDirectory = project->first("OBJECTS_DIR"); -// temp = (projectTarget == StaticLib) ? project->first("DESTDIR"):project->first("DLLDESTDIR"); - vcProject.Configuration.OutputDirectory = "."; //( temp.isEmpty() ? QString(".") : temp ); - vcProject.Configuration.PrimaryOutput = project->first("PrimaryOutput"); - vcProject.Configuration.WholeProgramOptimization = vcProject.Configuration.compiler.WholeProgramOptimization; + RConf.CharacterSet = charSet( temp.isEmpty() ? (short)charSetNotSet : temp.toShort() ); + RConf.DeleteExtensionsOnClean = project->first("DeleteExtensionsOnClean"); + RConf.ImportLibrary = RConf.linker.ImportLibrary; + RConf.IntermediateDirectory = project->first("OBJECTS_DIR"); + RConf.OutputDirectory = "."; + RConf.PrimaryOutput = project->first("PrimaryOutput"); + RConf.WholeProgramOptimization = RConf.compiler.WholeProgramOptimization; temp = project->first("UseOfATL"); if ( !temp.isEmpty() ) - vcProject.Configuration.UseOfATL = useOfATL( temp.toShort() ); + RConf.UseOfATL = useOfATL( temp.toShort() ); temp = project->first("UseOfMfc"); if ( !temp.isEmpty() ) - vcProject.Configuration.UseOfMfc = useOfMfc( temp.toShort() ); + RConf.UseOfMfc = useOfMfc( temp.toShort() ); @@ -450,2 +556,35 @@ void VcprojGenerator::initConfiguration() initPreLinkEventTools(); + + // Debug version of the Configuration ----------------- + VCConfiguration DConf = vcProject.Configuration[0]; // Create copy configuration for debug + DConf.Name = "Debug"; + DConf.Name += ( DConf.idl.TargetEnvironment == midlTargetWin64 ? "|Win64" : "|Win32" ); + + // Set definite values in both configurations + DConf.compiler.PreprocessorDefinitions.remove("NDEBUG"); + RConf.compiler.PreprocessorDefinitions += "NDEBUG"; + RConf.linker.GenerateDebugInformation = _False; + DConf.linker.GenerateDebugInformation = _True; + + // Modify configurations, based on Qt build + if ( project->isActiveConfig("debug") ) { + RConf.IntermediateDirectory = + RConf.compiler.AssemblerListingLocation = + RConf.compiler.ObjectFile = "Release\\"; + RConf.librarian.OutputFile = + RConf.linker.OutputFile = RConf.IntermediateDirectory + "\\" + project->first("MSVCPROJ_TARGET"); + RConf.linker.parseOptions(project->variables()["QMAKE_LFLAGS_RELEASE"]); + RConf.compiler.parseOptions(project->variables()["QMAKE_CFLAGS_RELEASE"]); + } else { + DConf.IntermediateDirectory = + DConf.compiler.AssemblerListingLocation = + DConf.compiler.ObjectFile = "Debug\\"; + DConf.librarian.OutputFile = + DConf.linker.OutputFile = DConf.IntermediateDirectory + "\\" + project->first("MSVCPROJ_TARGET"); + DConf.linker.DelayLoadDLLs.clear(); + DConf.compiler.parseOptions(project->variables()["QMAKE_CFLAGS_DEBUG"]); + } + + // Add Debug configuration to project + vcProject.Configuration += DConf; } @@ -458,6 +597,19 @@ void VcprojGenerator::initCompilerTool() - vcProject.Configuration.compiler.AssemblerListingLocation = placement ; - vcProject.Configuration.compiler.ProgramDataBaseFileName = placement ; - vcProject.Configuration.compiler.ObjectFile = placement ; - vcProject.Configuration.compiler.PrecompiledHeaderFile = placement + project->first("QMAKE_ORIG_TARGET") + ".pch"; + VCConfiguration &RConf = vcProject.Configuration[0]; + RConf.compiler.AssemblerListingLocation = placement ; + RConf.compiler.ProgramDataBaseFileName = ".\\" ; + RConf.compiler.ObjectFile = placement ; + // PCH + if ( usePCH ) { + RConf.compiler.UsePrecompiledHeader = pchUseUsingSpecific; + RConf.compiler.PrecompiledHeaderFile = "$(IntDir)\\" + precompPch; + RConf.compiler.PrecompiledHeaderThrough = precompHFilename; + RConf.compiler.ForcedIncludeFiles = precompHFilename; + // Minimal build option triggers an Internal Compiler Error + // when used in conjunction with /FI and /Yu, so remove it + project->variables()["QMAKE_CFLAGS_DEBUG"].remove("-Gm"); + project->variables()["QMAKE_CFLAGS_DEBUG"].remove("/Gm"); + project->variables()["QMAKE_CXXFLAGS_DEBUG"].remove("-Gm"); + project->variables()["QMAKE_CXXFLAGS_DEBUG"].remove("/Gm"); + } @@ -465,11 +617,11 @@ void VcprojGenerator::initCompilerTool() // Debug version - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_DEBUG"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_DEBUG"] ); if ( project->isActiveConfig("thread") ) { if ( (projectTarget == Application) || (projectTarget == StaticLib) ) - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DBG"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DBG"] ); else - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"] ); } else { - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_ST_DBG"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DBG"] ); } @@ -477,13 +629,13 @@ void VcprojGenerator::initCompilerTool() // Release version - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_RELEASE"] ); - vcProject.Configuration.compiler.PreprocessorDefinitions += "QT_NO_DEBUG"; - vcProject.Configuration.compiler.PreprocessorDefinitions += "NDEBUG"; + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_RELEASE"] ); + RConf.compiler.PreprocessorDefinitions += "QT_NO_DEBUG"; + RConf.compiler.PreprocessorDefinitions += "NDEBUG"; if ( project->isActiveConfig("thread") ) { if ( (projectTarget == Application) || (projectTarget == StaticLib) ) - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] ); else - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLL"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLL"] ); } else { - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_ST"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] ); } @@ -493,7 +645,7 @@ void VcprojGenerator::initCompilerTool() if ( project->isActiveConfig("warn_off") ) - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_OFF"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_OFF"] ); else if ( project->isActiveConfig("warn_on") ) - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_ON"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_ON"] ); if ( project->isActiveConfig("windows") ) - vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["MSVCPROJ_WINCONDEF"]; + RConf.compiler.PreprocessorDefinitions += project->variables()["MSVCPROJ_WINCONDEF"]; @@ -502,7 +654,13 @@ void VcprojGenerator::initCompilerTool() if ( projectTarget == SharedLib ) - vcProject.Configuration.compiler.PreprocessorDefinitions += "_WINDOWS"; - - vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["DEFINES"]; - vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["PRL_EXPORT_DEFINES"]; - vcProject.Configuration.compiler.parseOptions( project->variables()["MSVCPROJ_INCPATH"] ); + RConf.compiler.PreprocessorDefinitions += "_WINDOWS"; + + RConf.compiler.PreprocessorDefinitions += project->variables()["DEFINES"]; + RConf.compiler.PreprocessorDefinitions += project->variables()["PRL_EXPORT_DEFINES"]; + QStringList::iterator it; + for(it=RConf.compiler.PreprocessorDefinitions.begin(); + it!=RConf.compiler.PreprocessorDefinitions.end(); + ++it) + (*it).replace('\"', """); + + RConf.compiler.parseOptions( project->variables()["MSVCPROJ_INCPATH"] ); } @@ -511,10 +669,11 @@ void VcprojGenerator::initLibrarianTool() { - vcProject.Configuration.librarian.OutputFile = project->first( "DESTDIR" ); - if( vcProject.Configuration.librarian.OutputFile.isEmpty() ) - vcProject.Configuration.librarian.OutputFile = ".\\"; + VCConfiguration &RConf = vcProject.Configuration[0]; + RConf.librarian.OutputFile = project->first( "DESTDIR" ); + if( RConf.librarian.OutputFile.isEmpty() ) + RConf.librarian.OutputFile = ".\\"; - if( !vcProject.Configuration.librarian.OutputFile.endsWith("\\") ) - vcProject.Configuration.librarian.OutputFile += '\\'; + if( !RConf.librarian.OutputFile.endsWith("\\") ) + RConf.librarian.OutputFile += '\\'; - vcProject.Configuration.librarian.OutputFile += project->first("MSVCPROJ_TARGET"); + RConf.librarian.OutputFile += project->first("MSVCPROJ_TARGET"); } @@ -523,4 +682,5 @@ void VcprojGenerator::initLinkerTool() { - vcProject.Configuration.linker.parseOptions( project->variables()["MSVCPROJ_LFLAGS"] ); - vcProject.Configuration.linker.AdditionalDependencies += project->variables()["MSVCPROJ_LIBS"]; + VCConfiguration &RConf = vcProject.Configuration[0]; + RConf.linker.parseOptions( project->variables()["MSVCPROJ_LFLAGS"] ); + RConf.linker.AdditionalDependencies += project->variables()["MSVCPROJ_LIBS"]; @@ -528,7 +688,7 @@ void VcprojGenerator::initLinkerTool() case Application: - vcProject.Configuration.linker.OutputFile = project->first( "DESTDIR" ); + RConf.linker.OutputFile = project->first( "DESTDIR" ); break; case SharedLib: - vcProject.Configuration.linker.parseOptions( project->variables()["MSVCPROJ_LIBOPTIONS"] ); - vcProject.Configuration.linker.OutputFile = project->first( "DLLDESTDIR" ); + RConf.linker.parseOptions( project->variables()["MSVCPROJ_LIBOPTIONS"] ); + RConf.linker.OutputFile = project->first( "DESTDIR" ); break; @@ -538,15 +698,14 @@ void VcprojGenerator::initLinkerTool() - if( vcProject.Configuration.linker.OutputFile.isEmpty() ) - vcProject.Configuration.linker.OutputFile = ".\\"; + if( RConf.linker.OutputFile.isEmpty() ) + RConf.linker.OutputFile = ".\\"; - if( !vcProject.Configuration.linker.OutputFile.endsWith("\\") ) - vcProject.Configuration.linker.OutputFile += '\\'; + if( !RConf.linker.OutputFile.endsWith("\\") ) + RConf.linker.OutputFile += '\\'; - vcProject.Configuration.linker.OutputFile += project->first("MSVCPROJ_TARGET"); - vcProject.Configuration.linker.ProgramDatabaseFile = project->first("OBJECTS_DIR") + project->first("QMAKE_ORIG_TARGET") + ".pdb"; + RConf.linker.OutputFile += project->first("MSVCPROJ_TARGET"); if ( project->isActiveConfig("debug") ){ - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_DEBUG"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_DEBUG"] ); } else { - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_RELEASE"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_RELEASE"] ); } @@ -554,3 +713,3 @@ void VcprojGenerator::initLinkerTool() if ( project->isActiveConfig("dll") ){ - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_QT_DLL"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_QT_DLL"] ); } @@ -558,5 +717,5 @@ void VcprojGenerator::initLinkerTool() if ( project->isActiveConfig("console") ){ - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_CONSOLE"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_CONSOLE"] ); } else { - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_WINDOWS"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_WINDOWS"] ); } @@ -575,21 +734,2 @@ void VcprojGenerator::initPreBuildEventTools() { - QString collectionName = project->first("QMAKE_IMAGE_COLLECTION"); - if( !collectionName.isEmpty() ) { - QStringList& list = project->variables()["IMAGES"]; - vcProject.Configuration.preBuild.Description = "Generate imagecollection"; - //vcProject.Configuration.preBuild.AdditionalDependencies += list; - - QFile imgs( ".imgcol" ); - imgs.open( IO_WriteOnly ); - QTextStream s( &imgs ); - QStringList::ConstIterator it = list.begin(); - while( it!=list.end() ) { - s << *it << " "; - it++; - } - - vcProject.Configuration.preBuild.CommandLine = project->first("QMAKE_UIC") + " -embed " + project->first("QMAKE_ORIG_TARGET") + " -f .imgcol -o " + collectionName; - //vcProject.Configuration.preBuild.Outputs = collectionName; - - } } @@ -598,5 +738,14 @@ void VcprojGenerator::initPostBuildEventTools() { + VCConfiguration &RConf = vcProject.Configuration[0]; if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) { - vcProject.Configuration.postBuild.Description = var("QMAKE_POST_LINK"); - vcProject.Configuration.postBuild.CommandLine = var("QMAKE_POST_LINK"); + RConf.postBuild.Description = var("QMAKE_POST_LINK"); + RConf.postBuild.CommandLine = var("QMAKE_POST_LINK"); + RConf.postBuild.Description.replace(" && ", " && "); + RConf.postBuild.CommandLine.replace(" && ", " && "); + } + if ( !project->variables()["MSVCPROJ_COPY_DLL"].isEmpty() ) { + if ( !RConf.postBuild.CommandLine.isEmpty() ) + RConf.postBuild.CommandLine += " && "; + RConf.postBuild.Description += var("MSVCPROJ_COPY_DLL_DESC"); + RConf.postBuild.CommandLine += var("MSVCPROJ_COPY_DLL"); } @@ -608,30 +757,26 @@ void VcprojGenerator::initPostBuildEventTools() - vcProject.Configuration.postBuild.Description = "Finalizing ActiveQt server..."; - if ( !vcProject.Configuration.postBuild.CommandLine.isEmpty() ) - vcProject.Configuration.postBuild.CommandLine += " && "; + RConf.postBuild.Description = "Finalizing ActiveQt server..."; + if ( !RConf.postBuild.CommandLine.isEmpty() ) + RConf.postBuild.CommandLine += " && "; if( project->isActiveConfig( "dll" ) ) { // In process - vcProject.Configuration.postBuild.CommandLine += + RConf.postBuild.CommandLine += // call idc to generate .idl file from .dll - idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " -idl " + objdir + name + ".idl -version 1.0 && " + + idc + " "$(TargetPath)" -idl " + objdir + name + ".idl -version 1.0 && " + // call midl to create implementations of the .idl file - project->first( "QMAKE_IDL" ) + " " + objdir + name + ".idl /nologo /o " + objdir + name + ".midl /tlb " + objdir + name + ".tlb /iid " + objdir + - "dump.midl /dlldata " + objdir + "dump.midl /cstub " + objdir + "dump.midl /header " + objdir + "dump.midl /proxy " + objdir + "dump.midl /sstub " + - objdir + "dump.midl && " + + project->first( "QMAKE_IDL" ) + " /nologo " + objdir + name + ".idl /tlb " + objdir + name + ".tlb && " + // call idc to replace tlb... - idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /tlb " + objdir + name + ".tlb && " + + idc + " "$(TargetPath)" /tlb " + objdir + name + ".tlb && " + // register server - idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /regserver"; + idc + " "$(TargetPath)" /regserver"; } else { // out of process - vcProject.Configuration.postBuild.CommandLine = + RConf.postBuild.CommandLine = // call application to dump idl - vcProject.Configuration.OutputDirectory + "\\" + nameext + " -dumpidl " + objdir + name + ".idl -version 1.0 && " + + ""$(TargetPath)" -dumpidl " + objdir + name + ".idl -version 1.0 && " + // call midl to create implementations of the .idl file - project->first( "QMAKE_IDL" ) + " " + objdir + name + ".idl /nologo /o " + objdir + name + ".midl /tlb " + objdir + name + ".tlb /iid " + objdir + - "dump.midl /dlldata " + objdir + "dump.midl /cstub " + objdir + "dump.midl /header " + objdir + "dump.midl /proxy " + objdir + "dump.midl /sstub " + - objdir + "dump.midl && " + + project->first( "QMAKE_IDL" ) + " /nologo " + objdir + name + ".idl /tlb " + objdir + name + ".tlb && " + // call idc to replace tlb... - idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /tlb " + objdir + name + ".tlb && " + + idc + " "$(TargetPath)" /tlb " + objdir + name + ".tlb && " + // call app to register - vcProject.Configuration.OutputDirectory + "\\" + nameext + " -regserver"; + ""$(TargetPath)" -regserver"; } @@ -644,4 +789,79 @@ void VcprojGenerator::initPreLinkEventTools() + +// ------------------------------------------------------------------ +// Helper functions to do proper sorting of the +// qstringlists, for both flat and non-flat modes. +inline bool XLessThanY( QString &x, QString &y, bool flat_mode ) +{ + if ( flat_mode ) { + QString subX = x.mid( x.findRev('\\')+1 ); + QString subY = y.mid( y.findRev('\\')+1 ); + return QString::compare(subX, subY) < 0; + } + + int xPos = 0; + int yPos = 0; + int xSlashPos; + int ySlashPos; + for (;;) { + xSlashPos = x.find('\\', xPos); + ySlashPos = y.find('\\', yPos); + + if (xSlashPos == -1 && ySlashPos != -1) { + return false; + } else if (xSlashPos != -1 && ySlashPos == -1) { + return true; + } else if (xSlashPos == -1 /* && yySlashPos == -1 */) { + QString subX = x.mid(xPos); + QString subY = y.mid(yPos); + return QString::compare(subX, subY) < 0; + } else { + QString subX = x.mid(xPos, xSlashPos - xPos); + QString subY = y.mid(yPos, ySlashPos - yPos); + int cmp = QString::compare(subX, subY); + if (cmp != 0) + return cmp < 0; + } + xPos = xSlashPos + 1; + yPos = ySlashPos + 1; + } + return false; +} +void nonflatDir_BubbleSort( QStringList& list, bool flat_mode ) +{ + QStringList::Iterator b = list.begin(); + QStringList::Iterator e = list.end(); + QStringList::Iterator last = e; + --last; // goto last + if ( last == b ) // shortcut + return; + while( b != last ) {// sort them + bool swapped = FALSE; + QStringList::Iterator swap_pos = b; + QStringList::Iterator x = e; + QStringList::Iterator y = x; + --y; + QString swap_str; + do { + --x; + --y; + if ( XLessThanY(*x,*y, flat_mode) ) { + swapped = TRUE; + swap_str = (*x); // Swap ------- + (*x) = (*y); + (*y) = swap_str; // ------------ + swap_pos = y; + } + } while( y != b ); + if ( !swapped ) + return; + b = swap_pos; + ++b; + } +} +// ------------------------------------------------------------------ + void VcprojGenerator::initSourceFiles() { + vcProject.SourceFiles.flat_files = project->isActiveConfig("flat"); vcProject.SourceFiles.Name = "Source Files"; @@ -649,3 +869,4 @@ void VcprojGenerator::initSourceFiles() vcProject.SourceFiles.Files += project->variables()["SOURCES"]; - vcProject.SourceFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.SourceFiles.Files, + vcProject.SourceFiles.flat_files ); vcProject.SourceFiles.Project = this; @@ -657,2 +878,3 @@ void VcprojGenerator::initHeaderFiles() { + vcProject.HeaderFiles.flat_files = project->isActiveConfig("flat"); vcProject.HeaderFiles.Name = "Header Files"; @@ -660,3 +882,8 @@ void VcprojGenerator::initHeaderFiles() vcProject.HeaderFiles.Files += project->variables()["HEADERS"]; - vcProject.HeaderFiles.Files.sort(); + if (usePCH) { // Generated PCH cpp file + if (!vcProject.HeaderFiles.Files.contains(precompH)) + vcProject.HeaderFiles.Files += precompH; + } + nonflatDir_BubbleSort( vcProject.HeaderFiles.Files, + vcProject.HeaderFiles.flat_files ); vcProject.HeaderFiles.Project = this; @@ -668,2 +895,3 @@ void VcprojGenerator::initMOCFiles() { + vcProject.MOCFiles.flat_files = project->isActiveConfig("flat"); vcProject.MOCFiles.Name = "Generated MOC Files"; @@ -671,3 +899,4 @@ void VcprojGenerator::initMOCFiles() vcProject.MOCFiles.Files += project->variables()["SRCMOC"]; - vcProject.MOCFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.MOCFiles.Files, + vcProject.MOCFiles.flat_files ); vcProject.MOCFiles.Project = this; @@ -679,3 +908,4 @@ void VcprojGenerator::initUICFiles() { - vcProject.UICFiles.Name = "Generated UI Files"; + vcProject.UICFiles.flat_files = project->isActiveConfig("flat"); + vcProject.UICFiles.Name = "Generated Form Files"; vcProject.UICFiles.Filter = "cpp;c;cxx;h;hpp;hxx;"; @@ -684,3 +914,4 @@ void VcprojGenerator::initUICFiles() vcProject.UICFiles.Files += project->variables()["UICIMPLS"]; - vcProject.UICFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.UICFiles.Files, + vcProject.UICFiles.flat_files ); vcProject.UICFiles.Config = &(vcProject.Configuration); @@ -691,2 +922,3 @@ void VcprojGenerator::initFormsFiles() { + vcProject.FormFiles.flat_files = project->isActiveConfig("flat"); vcProject.FormFiles.Name = "Forms"; @@ -695,3 +927,4 @@ void VcprojGenerator::initFormsFiles() vcProject.FormFiles.Files += project->variables()["FORMS"]; - vcProject.FormFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.FormFiles.Files, + vcProject.FormFiles.flat_files ); vcProject.FormFiles.Project = this; @@ -703,2 +936,3 @@ void VcprojGenerator::initTranslationFiles() { + vcProject.TranslationFiles.flat_files = project->isActiveConfig("flat"); vcProject.TranslationFiles.Name = "Translations Files"; @@ -707,3 +941,4 @@ void VcprojGenerator::initTranslationFiles() vcProject.TranslationFiles.Files += project->variables()["TRANSLATIONS"]; - vcProject.TranslationFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.TranslationFiles.Files, + vcProject.TranslationFiles.flat_files ); vcProject.TranslationFiles.Project = this; @@ -715,2 +950,3 @@ void VcprojGenerator::initLexYaccFiles() { + vcProject.LexYaccFiles.flat_files = project->isActiveConfig("flat"); vcProject.LexYaccFiles.Name = "Lex / Yacc Files"; @@ -720,4 +956,6 @@ void VcprojGenerator::initLexYaccFiles() vcProject.LexYaccFiles.Files += project->variables()["YACCSOURCES"]; - vcProject.LexYaccFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.LexYaccFiles.Files, + vcProject.LexYaccFiles.flat_files ); vcProject.LexYaccFiles.Project = this; + vcProject.LexYaccFiles.Config = &(vcProject.Configuration); vcProject.LexYaccFiles.CustomBuild = lexyacc; @@ -727,2 +965,3 @@ void VcprojGenerator::initResourceFiles() { + vcProject.ResourceFiles.flat_files = project->isActiveConfig("flat"); vcProject.ResourceFiles.Name = "Resources"; @@ -734,5 +973,7 @@ void VcprojGenerator::initResourceFiles() vcProject.ResourceFiles.Files += project->variables()["IDLSOURCES"]; - vcProject.ResourceFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.ResourceFiles.Files, + vcProject.ResourceFiles.flat_files ); vcProject.ResourceFiles.Project = this; - vcProject.ResourceFiles.CustomBuild = none; + vcProject.ResourceFiles.Config = &(vcProject.Configuration); + vcProject.ResourceFiles.CustomBuild = resource; } @@ -867,3 +1108,2 @@ void VcprojGenerator::initOld() project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"]; - project->variables()["MSVCPROJ_LFLAGS"].append("/DEF:"+project->first("DEF_FILE")); } @@ -941,2 +1181,11 @@ void VcprojGenerator::initOld() + // /VERSION:x.yz ------------------------------------------------- + if ( !project->variables()["VERSION"].isEmpty() ) { + QString version = project->variables()["VERSION"][0]; + int firstDot = version.find( "." ); + QString major = version.left( firstDot ); + QString minor = version.right( version.length() - firstDot - 1 ); + minor.replace( ".", "" ); + project->variables()["QMAKE_LFLAGS"].append( "/VERSION:" + major + "." + minor ); + } @@ -951,2 +1200,3 @@ void VcprojGenerator::initOld() } else if( s.startsWith( "-L" ) ) { + project->variables()["QMAKE_LIBDIR"] += (*it).mid(2); it = libList.remove( it ); @@ -1052,10 +1302,2 @@ void VcprojGenerator::initOld() project->variables()["MSVCPROJ_TARGET"] = dest; - if ( project->isActiveConfig("dll") ) { - QString imp = project->first( "DESTDIR" ); - if( !imp.isNull() && !imp.endsWith( "\\" ) ) - imp += "\\"; - imp += dest; - imp.replace(QRegExp("\\.dll"), ".lib"); - project->variables()["MSVCPROJ_LIBOPTIONS"] += QString("/IMPLIB:") + imp; - } @@ -1064,15 +1306,20 @@ void VcprojGenerator::initOld() QStringList dlldirs = project->variables()["DLLDESTDIR"]; - QString copydll = "# Begin Special Build Tool\n" - "TargetPath=" + dest + "\n" - "SOURCE=$(InputPath)\n" - "PostBuild_Desc=Copy DLL to " + project->first("DLLDESTDIR") + "\n" - "PostBuild_Cmds="; - - for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { - copydll += "copy \"" + dest + "\" \"" + *dlldir + "\"\t"; + QString copydll(""); + QStringList::Iterator dlldir; + for ( dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { + if ( !copydll.isEmpty() ) + copydll += " && "; + copydll += "copy "$(TargetPath)" "" + *dlldir + """; } - copydll += "\n# End Special Build Tool"; - project->variables()["MSVCPROJ_COPY_DLL_REL"].append( copydll ); - project->variables()["MSVCPROJ_COPY_DLL_DBG"].append( copydll ); + QString deststr( "Copy " + dest + " to " ); + for ( dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ) { + deststr += *dlldir; + ++dlldir; + if ( dlldir != dlldirs.end() ) + deststr += ", "; + } + + project->variables()["MSVCPROJ_COPY_DLL"].append( copydll ); + project->variables()["MSVCPROJ_COPY_DLL_DESC"].append( deststr ); } @@ -1087,5 +1334,4 @@ void VcprojGenerator::initOld() - project->variables()["MSVCPROJ_IDLSOURCES"].append( "tmp\\" + targetfilename + ".idl" ); - project->variables()["MSVCPROJ_IDLSOURCES"].append( "tmp\\" + targetfilename + ".tlb" ); - project->variables()["MSVCPROJ_IDLSOURCES"].append( "tmp\\" + targetfilename + ".midl" ); + QString objdir = project->first( "OBJECTS_DIR" ); + project->variables()["MSVCPROJ_IDLSOURCES"].append( objdir + targetfilename + ".idl" ); if ( project->isActiveConfig( "dll" ) ) { @@ -1096,5 +1342,5 @@ void VcprojGenerator::initOld() "PostBuild_Cmds=" + - idc + " %1 -idl tmp\\" + targetfilename + ".idl -version " + version + - "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" - "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb" + idc + " %1 -idl " + objdir + targetfilename + ".idl -version " + version + + "\t" + idl + " /nologo " + objdir + targetfilename + ".idl /tlb " + objdir + targetfilename + ".tlb" + + "\t" + idc + " %1 /tlb " + objdir + targetfilename + ".tlb" "\tregsvr32 /s %1\n" @@ -1113,5 +1359,5 @@ void VcprojGenerator::initOld() "PostBuild_Cmds=" - "%1 -dumpidl tmp\\" + targetfilename + ".idl -version " + version + - "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" - "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb" + "%1 -dumpidl " + objdir + targetfilename + ".idl -version " + version + + "\t" + idl + " /nologo " + objdir + targetfilename + ".idl /tlb " + objdir + targetfilename + ".tlb" + "\t" + idc + " %1 /tlb " + objdir + targetfilename + ".tlb" "\t%1 -regserver\n" @@ -1125,5 +1371,7 @@ void VcprojGenerator::initOld() } - } + if ( !project->variables()["DEF_FILE"].isEmpty() ) + project->variables()["MSVCPROJ_LFLAGS"].append("/DEF:"+project->first("DEF_FILE")); + // FORMS --------------------------------------------------------- diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index 69e0c02..d1ca666 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -1,3 +1,4 @@ + /**************************************************************************** -** $Id$ +** ** @@ -5,7 +6,5 @@ ** -** Created : 970521 -** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -36,2 +35,3 @@ **********************************************************************/ + #ifndef __MSVC_VCPROJ_H__ @@ -65,2 +65,5 @@ public: virtual bool doDepends() const { return FALSE; } //never necesary + QString precompH, precompHFilename, + precompObj, precompPch; + bool usePCH; @@ -97,2 +100,3 @@ protected: private: + QUuid getProjectUUID(const QString &filename=QString::null); QUuid increaseUUID(const QUuid &id); diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index bc3fed9..cd733c6 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of Win32MakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -40,2 +38,3 @@ #include "project.h" +#include "meta.h" #include <qtextstream.h> @@ -99,4 +98,3 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) - if(!project->isEmpty("MAKEFILE")) - t << "MAKEFILE= " << var("MAKEFILE") << endl; + t << "MAKEFILE = " << (project->isEmpty("MAKEFILE") ? QString("Makefile") : var("MAKEFILE")) << endl; t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; @@ -106,3 +104,3 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) t << endl << endl; - t << "all: qmake_all $(SUBTARGETS)" << endl << endl; + t << "all: $(MAKEFILE) $(SUBTARGETS)" << endl << endl; @@ -116,4 +114,2 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) t << mkfile << ":"; - if(project->variables()["QMAKE_NOFORCE"].isEmpty()) - t << " FORCE"; if(have_dir) @@ -147,2 +143,12 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) + if (project->isActiveConfig("ordered")) { // generate dependencies + for( it.toFirst(); it.current(); ) { + QString tar = it.current()->target; + ++it; + if (it.current()) + t << it.current()->target << ": " << tar << endl; + } + t << endl; + } + if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].findIndex("qmake_all") == -1) @@ -177,7 +183,14 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) - QString targs[] = { QString("clean"), QString("install"), QString("mocclean"), QString::null }; - for(int x = 0; targs[x] != QString::null; x++) { - t << targs[x] << ": qmake_all"; - if(targs[x] == "clean") - t << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ", ""); + QStringList targs; + targs << "clean" << "install_subdirs" << "mocables" << "uicables" << "uiclean" << "mocclean"; + targs += project->values("SUBDIR_TARGETS"); + for(QStringList::Iterator targ_it = targs.begin(); targ_it != targs.end(); ++targ_it) { + t << (*targ_it) << ": qmake_all"; + QString targ = (*targ_it); + if(targ == "install_subdirs") + targ = "install"; + else if(targ == "uninstall_subdirs") + targ = "uninstall"; + if(targ == "clean") + t << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ", ""); if (!subdirs.isEmpty()) { @@ -189,3 +202,3 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) QString in_file = " -f " + (*it)->makefile; - t << "\n\t" << "$(MAKE) " << in_file << " " << targs[x]; + t << "\n\t" << "$(MAKE) " << in_file << " " << targ; if(have_dir) { @@ -204,2 +217,28 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) + //installations + project->variables()["INSTALLDEPS"] += "install_subdirs"; + project->variables()["UNINSTALLDEPS"] += "uninstall_subdirs"; + writeInstalls(t, "INSTALLS"); + + // user defined targets + QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; + for(QStringList::Iterator sit = qut.begin(); sit != qut.end(); ++sit) { + QString targ = var((*sit) + ".target"), + cmd = var((*sit) + ".commands"), deps; + if(targ.isEmpty()) + targ = (*sit); + QStringList &deplist = project->variables()[(*sit) + ".depends"]; + for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) { + QString dep = var((*dep_it) + ".target"); + if(dep.isEmpty()) + dep = (*dep_it); + deps += " " + dep; + } + if(!project->variables()["QMAKE_NOFORCE"].isEmpty() && + project->variables()[(*sit) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; + t << "\n\n" << targ << ":" << deps << "\n\t" + << cmd; + } + if(project->variables()["QMAKE_NOFORCE"].isEmpty()) @@ -228,8 +267,6 @@ Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem } - if(dir.exists(dllStem + Option::prl_ext)) { - QMakeProject proj; - if(proj.read(bd + dllStem + Option::prl_ext, QDir::currentDirPath(), TRUE)) { - if(!proj.isEmpty("QMAKE_PRL_VERSION")) - biggest = QMAX(biggest, proj.first("QMAKE_PRL_VERSION").replace(".", "").toInt()); - } + QMakeMetaInfo libinfo; + if(libinfo.readLib(bd + dllStem)) { + if(!libinfo.isEmpty("QMAKE_PRL_VERSION")) + biggest = QMAX(biggest, libinfo.first("QMAKE_PRL_VERSION").replace(".", "").toInt()); } @@ -238,2 +275,38 @@ Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem +QString +Win32MakefileGenerator::findDependency(const QString &dep) +{ + { + QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; + for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) { + QString targ = var((*it) + ".target"); + if(targ.isEmpty()) + targ = (*it); + if(targ.endsWith(dep)) + return targ; + } + } + { + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(QStringList::Iterator it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QString out = tmp_out; + QFileInfo fi(Option::fixPathToLocalOS((*input))); + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(out.endsWith(dep)) + return out; + } + } + } + } + return MakefileGenerator::findDependency(dep); +} @@ -280,3 +353,3 @@ Win32MakefileGenerator::findLibraries(const QString &where) extension += ".lib"; - if(QFile::exists(mdd->local_dir + Option::dir_sep + lib + Option::prl_ext) || + if(QMakeMetaInfo::libExists(mdd->local_dir + Option::dir_sep + lib) || QFile::exists(mdd->local_dir + Option::dir_sep + lib + extension)) { @@ -305,22 +378,24 @@ Win32MakefileGenerator::findLibraries(const QString &where) } - if(file.endsWith(".lib")) { - file = file.left(file.length() - 4); - if(!file.at(file.length()-1).isNumber()) { - for(MakefileDependDir *mdd = lib_dirs.first(); mdd; mdd = lib_dirs.next() ) { - QString lib_tmpl(file + "%1" + ".lib"); - int ver = findHighestVersion(mdd->local_dir, file); - if(ver != -1) { - if(ver) - lib_tmpl = lib_tmpl.arg(ver); - else - lib_tmpl = lib_tmpl.arg(""); - if(slsh != -1) { - QString dir = mdd->real_dir; - if(!dir.endsWith(Option::dir_sep)) - dir += Option::dir_sep; - lib_tmpl.prepend(dir); + if (!project->variables()["QMAKE_QT_DLL"].isEmpty()) { + if(file.endsWith(".lib")) { + file = file.left(file.length() - 4); + if(!file.at(file.length()-1).isNumber()) { + for(MakefileDependDir *mdd = lib_dirs.first(); mdd; mdd = lib_dirs.next() ) { + QString lib_tmpl(file + "%1" + ".lib"); + int ver = findHighestVersion(mdd->local_dir, file); + if(ver != -1) { + if(ver) + lib_tmpl = lib_tmpl.arg(ver); + else + lib_tmpl = lib_tmpl.arg(""); + if(slsh != -1) { + QString dir = mdd->real_dir; + if(!dir.endsWith(Option::dir_sep)) + dir += Option::dir_sep; + lib_tmpl.prepend(dir); + } + modified_opt = TRUE; + (*it) = lib_tmpl; + break; } - modified_opt = TRUE; - (*it) = lib_tmpl; - break; } diff --git a/qmake/generators/win32/winmakefile.h b/qmake/generators/win32/winmakefile.h index 75ba0e0..dac4a99 100644 --- a/qmake/generators/win32/winmakefile.h +++ b/qmake/generators/win32/winmakefile.h @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of Win32MakefileGenerator class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -36,2 +34,3 @@ **********************************************************************/ + #ifndef __WINMAKEFILE_H__ @@ -55,2 +54,3 @@ protected: bool findLibraries(const QString &); + QString findDependency(const QString &); virtual bool findLibraries(); diff --git a/qmake/include/private/qdir_p.h b/qmake/include/private/qdir_p.h index a6c7c91..4d9dfc6 100644 --- a/qmake/include/private/qdir_p.h +++ b/qmake/include/private/qdir_p.h @@ -1,3 +1,3 @@ /**************************************************************************** -** $Id$ +** ** diff --git a/qmake/include/private/qlocale_p.h b/qmake/include/private/qlocale_p.h new file mode 100644 index 0000000..26c05c9 --- a/dev/null +++ b/qmake/include/private/qlocale_p.h @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** +** Declaration of the QLocalePrivate class +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef QLOCALE_P_H +#define QLOCALE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of internal files. This header file may change from version to version +// without notice, or even be removed. +// +// We mean it. +// +// + +#include <qstring.h> + +struct QLocalePrivate +{ +public: + const QChar &decimal() const { return (QChar&)m_decimal; } + const QChar &group() const { return (QChar&)m_group; } + const QChar &list() const { return (QChar&)m_list; } + const QChar &percent() const { return (QChar&)m_percent; } + const QChar &zero() const { return (QChar&)m_zero; } + QChar plus() const { return QChar('+'); } + const QChar &minus() const { return (QChar&)m_minus; } + const QChar &exponential() const { return (QChar&)m_exponential; } + QString infinity() const; + QString nan() const; + + Q_UINT32 languageId() const { return m_language_id; } + Q_UINT32 countryId() const { return m_country_id; } + + bool isDigit(QChar d) const; + + enum GroupSeparatorMode { + FailOnGroupSeparators, + ParseGroupSeparators + }; + + enum DoubleForm { + DFExponent = 0, // %e or %E + DFDecimal, // %f or %F + DFSignificantDigits, // %g or %G + _DFMax = DFSignificantDigits + }; + + enum Flags { + NoFlags = 0, + + // These correspond to the options in a printf format string + Alternate = 0x01, + ZeroPadded = 0x02, + LeftAdjusted = 0x04, + BlankBeforePositive = 0x08, + AlwaysShowSign = 0x10, + ThousandsGroup = 0x20, + CapitalEorX = 0x40 // %x, %e, %f, %g vs. %X, %E, %F, %G + }; + + QString doubleToString(double d, + int precision = -1, + DoubleForm form = DFSignificantDigits, + int width = -1, + unsigned flags = NoFlags) const; + QString longLongToString(Q_LLONG l, int precision = -1, + int base = 10, + int width = -1, + unsigned flags = NoFlags) const; + QString unsLongLongToString(Q_ULLONG l, int precision = -1, + int base = 10, + int width = -1, + unsigned flags = NoFlags) const; + double stringToDouble(QString num, bool *ok, GroupSeparatorMode group_sep_mode) const; + Q_LLONG stringToLongLong(QString num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const; + Q_ULLONG stringToUnsLongLong(QString num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const; + bool removeGroupSeparators(QString &num_str) const; + bool numberToCLocale(QString &locale_num, GroupSeparatorMode group_sep_mode) const; + + Q_UINT32 m_language_id, m_country_id; + + Q_UINT16 m_decimal, m_group, m_list, m_percent, + m_zero, m_minus, m_exponential; + + static const QString m_infinity; + static const QString m_nan; + static const QChar m_plus; + + static const char *systemLocaleName(); +}; + +#endif diff --git a/qmake/include/private/qsettings_p.h b/qmake/include/private/qsettings_p.h index 095291c..4b76f44 100644 --- a/qmake/include/private/qsettings_p.h +++ b/qmake/include/private/qsettings_p.h @@ -1,3 +1,3 @@ /**************************************************************************** -** $Id$ +** ** @@ -5,12 +5,20 @@ ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** Created : 990124 ** -** This file is part of the tools module of the Qt GUI Toolkit. +** Copyright (C) 1999-2002 Trolltech AS. All rights reserved. ** -** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition -** licenses for Windows may use this file in accordance with the Qt Commercial -** License Agreement provided with the Software. +** This file is part of the kernel module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. ** -** This file is not available for use under any other license without -** express written permission from the copyright holder. +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. ** @@ -21,2 +29,4 @@ ** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. ** @@ -48,2 +58,3 @@ +#ifndef QT_NO_SETTINGS class QSettingsSysPrivate; @@ -130,4 +141,5 @@ public: #endif -}; +}; +#endif //QT_NO_SETTINGS #endif // QSETTINGS_P_H diff --git a/qmake/include/qfiledefs_p.h b/qmake/include/qfiledefs_p.h new file mode 100644 index 0000000..659aaec --- a/dev/null +++ b/qmake/include/qfiledefs_p.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** +** Common macros and system include files for QFile, QFileInfo and QDir. +** +** Created : 930812 +** +** Copyright (C) 1992-2001 Trolltech AS. All rights reserved. +** +** This file is part of the tools module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef QFILEDEFS_P_H +#define QFILEDEFS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qfileinfo*.cpp. This header file may change from version to version +// without notice, or even be removed. +// +// We mean it. +// +// + +// Be sure to include qplatformdefs.h first! +struct QFileInfoCache +{ +#if defined(Q_WS_WIN) + QT_STATBUF st; +#else + struct stat st; +#endif +}; + + +#endif diff --git a/qmake/include/qglobal.h b/qmake/include/qglobal.h index 94e5607..b7e919d 100644 --- a/qmake/include/qglobal.h +++ b/qmake/include/qglobal.h @@ -1,3 +1,3 @@ /**************************************************************************** -** $Id$ +** ** @@ -7,3 +7,3 @@ ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** @@ -40,3 +40,3 @@ -#define QT_VERSION_STR "3.1.2" +#define QT_VERSION_STR "3.3.2" /* @@ -44,3 +44,3 @@ */ -#define QT_VERSION 0x030102 +#define QT_VERSION 0x030302 @@ -51,2 +51,3 @@ MAC9 - Mac OS 9 + DARWIN - Darwin OS (Without Mac OS X) MSDOS - MS-DOS and Windows @@ -80,3 +81,5 @@ -#if defined(__APPLE__) && defined(__GNUC__) +#if defined(__DARWIN_X11__) +# define Q_OS_DARWIN +#elif defined(__APPLE__) && defined(__GNUC__) # define Q_OS_MACX @@ -113,3 +116,3 @@ # define Q_OS_LINUX -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__DragonFly__) # define Q_OS_FREEBSD @@ -151,2 +154,3 @@ # define Q_OS_UNIXWARE7 +#elif defined(__MAKEDEPEND__) #else @@ -155,14 +159,11 @@ +#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) +# define Q_OS_WIN +#endif + #if defined(Q_OS_MAC9) || defined(Q_OS_MACX) -/* This hack forces the generater to compile qmake not for maxosx native. It is - * compiled for Linux and generates usual makefiles.. - * Does anyone has a better solution for this ? (eilers) - */ -// # define Q_OS_MAC -#define Q_OS_LINUX -#warning "boeser Hack !! (se)" -#undef Q_OS_MACX +# define Q_OS_MAC #endif -#if defined(Q_OS_MAC9) || defined(Q_OS_MSDOS) || defined(Q_OS_OS2) || defined(Q_OS_WIN32) || defined(Q_OS_WIN64) +#if defined(Q_OS_MAC9) || defined(Q_OS_MSDOS) || defined(Q_OS_OS2) || defined(Q_OS_WIN) # undef Q_OS_UNIX @@ -179,3 +180,3 @@ MWERKS - Metrowerks CodeWarrior - MSVC - Microsoft Visual C/C++ + MSVC - Microsoft Visual C/C++, Intel C++ for Windows BOR - Borland/Turbo C++ @@ -194,3 +195,3 @@ KAI - KAI C++ - INTEL - Intel C++ + INTEL - Intel C++ for Linux, Intel C++ for Windows HIGHC - MetaWare High C/C++ @@ -224,3 +225,2 @@ # define QMAC_PASCAL pascal -# define Q_NO_USING_KEYWORD /* ### check "using" status */ @@ -234,3 +234,3 @@ # define Q_CC_MSVC_NET -# if _MSC_VER < 1310 +# if _MSC_VER < 1310 || defined(Q_OS_WIN64) # define Q_TYPENAME @@ -238,3 +238,11 @@ # endif -# define Q_NO_USING_KEYWORD /* ### check "using" status */ +/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */ +# if defined(__INTEL_COMPILER) +# define Q_CC_INTEL +# if !defined(__EXCEPTIONS) +# define Q_NO_EXCEPTIONS +# endif +# else +# define Q_NO_USING_KEYWORD /* ### check "using" status */ +# endif @@ -286,4 +294,13 @@ # endif + +/* ARM gcc pads structs to 32 bits, even when they contain a single + char, or short. We tell gcc to pack QChars to 16 bits, to avoid + QString bloat. However, gcc 3.4 doesn't allow us to create references to + members of a packed struct. (Pointers are OK, because then you + supposedly know what you are doing.) */ # if (defined(__arm__) || defined(__ARMEL__)) && !defined(QT_MOC_CPP) # define Q_PACKED __attribute__ ((packed)) +# if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 +# define Q_NO_PACKED_REFERENCE +# endif # endif @@ -307,2 +324,4 @@ Visual Age C++ 5.0 C Compiler 5.0 + ... ... + Visual Age C++ 6.0 C Compiler 6.0 @@ -331,3 +350,3 @@ it separately anyway. */ -#elif defined(__DECCXX) +#elif defined(__DECCXX) || defined(__DECC) # define Q_CC_DEC @@ -372,3 +391,3 @@ -/* The Portland Group compiler is based on EDG and does define __EDG__ */ +/* The Comeau compiler is based on EDG and does define __EDG__ */ # if defined(__COMO__) @@ -377,3 +396,6 @@ -/* Using the `using' keyword avoids KAI C++ warnings */ +/* The `using' keyword was introduced to avoid KAI C++ warnings + but it's now causing KAI C++ errors instead. The standard is + unclear about the use of this keyword, and in practice every + compiler is using its own set of rules. Forget it. */ # elif defined(__KCC) @@ -383,4 +405,5 @@ # endif +# define Q_NO_USING_KEYWORD -/* Using the `using' keyword avoids Intel C++ warnings */ +/* Using the `using' keyword avoids Intel C++ for Linux warnings */ # elif defined(__INTEL_COMPILER) @@ -432,3 +455,2 @@ # define Q_BROKEN_TEMPLATE_SPECIALIZATION -# define Q_STRICT_INLINING_RULES # define Q_NO_EXPLICIT_KEYWORD @@ -440,2 +462,5 @@ # define Q_NO_USING_KEYWORD /* ### check "using" status */ +# if defined(_COMPILER_VERSION) && (_COMPILER_VERSION >= 740) +# pragma set woff 3624,3625, 3649 /* turn off some harmless warnings */ +# endif # endif @@ -455,3 +480,3 @@ -#elif defined(__SUNPRO_CC) +#elif defined(__SUNPRO_CC) || defined(__SUNPRO_C) # define Q_CC_SUN @@ -607,2 +632,9 @@ const bool true = TRUE; +// +// Proper for-scoping +// ### turn on in 4.0 + +#if 0 && defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) +# define for if(0){}else for +#endif @@ -667,3 +699,2 @@ typedef unsigned int Q_UINT32; // 32 bit unsigned #if defined(Q_OS_WIN64) -// LLP64 64-bit model on Windows typedef __int64 Q_LONG; // word up to 64 bit signed @@ -671,12 +702,18 @@ typedef unsigned __int64 Q_ULONG; // word up to 64 bit unsigned #else -// LP64 64-bit model on Linux -typedef long Q_LONG; -typedef unsigned long Q_ULONG; +typedef long Q_LONG; // word up to 64 bit signed +typedef unsigned long Q_ULONG; // word up to 64 bit unsigned #endif - -#if !defined(QT_CLEAN_NAMESPACE) -// mininum size of 64 bits is not guaranteed -#define Q_INT64 Q_LONG -#define Q_UINT64 Q_ULONG +#if defined(Q_OS_WIN) && !defined(Q_CC_GNU) +# define Q_INT64_C(c) c ## i64 // signed 64 bit constant +# define Q_UINT64_C(c) c ## ui64 // unsigned 64 bit constant +typedef __int64 Q_INT64; // 64 bit signed +typedef unsigned __int64 Q_UINT64; // 64 bit unsigned +#else +# define Q_INT64_C(c) c ## LL // signed 64 bit constant +# define Q_UINT64_C(c) c ## ULL // unsigned 64 bit constant +typedef long long Q_INT64; // 64 bit signed +typedef unsigned long long Q_UINT64; // 64 bit unsigned #endif +typedef Q_INT64 Q_LLONG; // signed long long +typedef Q_UINT64 Q_ULLONG; // unsigned long long @@ -686,3 +723,3 @@ typedef unsigned long Q_ULONG; #if defined(QT_LARGEFILE_SUPPORT) - typedef unsigned long long QtOffset; + typedef Q_ULLONG QtOffset; #else @@ -710,13 +747,13 @@ class QDataStream; #if defined(QCONFIG_LOCAL) -#include <qconfig-local.h> +#include "qconfig-local.h" #elif defined(QCONFIG_MINIMAL) -#include <qconfig-minimal.h> +#include "qconfig-minimal.h" #elif defined(QCONFIG_SMALL) -#include <qconfig-small.h> +#include "qconfig-small.h" #elif defined(QCONFIG_MEDIUM) -#include <qconfig-medium.h> +#include "qconfig-medium.h" #elif defined(QCONFIG_LARGE) -#include <qconfig-large.h> +#include "qconfig-large.h" #else // everything... -#include <qconfig.h> +#include "qconfig.h" #endif @@ -731,2 +768,5 @@ class QDataStream; #include "qmodules.h" +#ifndef QT_MODULE_DIALOGS +# define QT_NO_DIALOG +#endif #ifndef QT_MODULE_ICONVIEW @@ -783,4 +823,4 @@ class QDataStream; #ifndef QT_H -#include <qfeatures.h> -#endif // QT_H +#include "qfeatures.h" +#endif /* QT_H */ @@ -792,3 +832,3 @@ class QDataStream; -#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) +#if defined(Q_OS_WIN) # if defined(QT_NODLL) @@ -852,2 +892,3 @@ Q_EXPORT const char *qVersion(); Q_EXPORT bool qSysInfo( int *wordSize, bool *bigEndian ); +Q_EXPORT bool qSharedBuild(); #if defined(Q_OS_MAC) @@ -885,3 +926,2 @@ Q_EXPORT int qWinVersion(); // - #define Q_UNUSED(x) (void)x; @@ -1017,11 +1057,15 @@ Q_EXPORT const char *qInstallPathPlugins(); Q_EXPORT const char *qInstallPathData(); +Q_EXPORT const char *qInstallPathTranslations(); +Q_EXPORT const char *qInstallPathSysconf(); -#endif // __cplusplus +#endif /* __cplusplus */ -// compilers which follow outdated template instantiation rules -// require a class to have a comparison operator to exist when -// a QValueList of this type is instantiated. It's not actually -// used in the list, though. Hence the dummy implementation. -// Just in case other code relies on it we better trigger a warning -// mandating a real implementation. +/* + compilers which follow outdated template instantiation rules + require a class to have a comparison operator to exist when + a QValueList of this type is instantiated. It's not actually + used in the list, though. Hence the dummy implementation. + Just in case other code relies on it we better trigger a warning + mandating a real implementation. +*/ #ifdef Q_FULL_TEMPLATE_INSTANTIATION @@ -1036,9 +1080,9 @@ Q_EXPORT const char *qInstallPathData(); -#endif // QGLOBAL_H +#endif /* QGLOBAL_H */ -// -// Avoid some particularly useless warnings from some stupid compilers. -// To get ALL C++ compiler warnings, define QT_CC_WARNINGS or comment out -// the line "#define QT_NO_WARNINGS" -// +/* + Avoid some particularly useless warnings from some stupid compilers. + To get ALL C++ compiler warnings, define QT_CC_WARNINGS or comment out + the line "#define QT_NO_WARNINGS" +*/ @@ -1068,5 +1112,4 @@ Q_EXPORT const char *qInstallPathData(); # pragma warn -sig -# elif defined(Q_CC_MWERKS) -# pragma warn_possunwant off # endif #endif + diff --git a/qmake/include/qlocale.h b/qmake/include/qlocale.h new file mode 100644 index 0000000..20ad03b --- a/dev/null +++ b/qmake/include/qlocale.h @@ -0,0 +1,491 @@ +/**************************************************************************** +** +** +** Declaration of the QLocale class +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of the tools module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef QLOCALE_H +#define QLOCALE_H + +#include "qstring.h" + +struct QLocalePrivate; + +class Q_EXPORT QLocale +{ + friend class QString; + +public: + enum Language { + C = 1, + Abkhazian = 2, + Afan = 3, + Afar = 4, + Afrikaans = 5, + Albanian = 6, + Amharic = 7, + Arabic = 8, + Armenian = 9, + Assamese = 10, + Aymara = 11, + Azerbaijani = 12, + Bashkir = 13, + Basque = 14, + Bengali = 15, + Bhutani = 16, + Bihari = 17, + Bislama = 18, + Breton = 19, + Bulgarian = 20, + Burmese = 21, + Byelorussian = 22, + Cambodian = 23, + Catalan = 24, + Chinese = 25, + Corsican = 26, + Croatian = 27, + Czech = 28, + Danish = 29, + Dutch = 30, + English = 31, + Esperanto = 32, + Estonian = 33, + Faroese = 34, + FijiLanguage = 35, + Finnish = 36, + French = 37, + Frisian = 38, + Gaelic = 39, + Galician = 40, + Georgian = 41, + German = 42, + Greek = 43, + Greenlandic = 44, + Guarani = 45, + Gujarati = 46, + Hausa = 47, + Hebrew = 48, + Hindi = 49, + Hungarian = 50, + Icelandic = 51, + Indonesian = 52, + Interlingua = 53, + Interlingue = 54, + Inuktitut = 55, + Inupiak = 56, + Irish = 57, + Italian = 58, + Japanese = 59, + Javanese = 60, + Kannada = 61, + Kashmiri = 62, + Kazakh = 63, + Kinyarwanda = 64, + Kirghiz = 65, + Korean = 66, + Kurdish = 67, + Kurundi = 68, + Laothian = 69, + Latin = 70, + Latvian = 71, + Lingala = 72, + Lithuanian = 73, + Macedonian = 74, + Malagasy = 75, + Malay = 76, + Malayalam = 77, + Maltese = 78, + Maori = 79, + Marathi = 80, + Moldavian = 81, + Mongolian = 82, + NauruLanguage = 83, + Nepali = 84, + Norwegian = 85, + Occitan = 86, + Oriya = 87, + Pashto = 88, + Persian = 89, + Polish = 90, + Portuguese = 91, + Punjabi = 92, + Quechua = 93, + RhaetoRomance = 94, + Romanian = 95, + Russian = 96, + Samoan = 97, + Sangho = 98, + Sanskrit = 99, + Serbian = 100, + SerboCroatian = 101, + Sesotho = 102, + Setswana = 103, + Shona = 104, + Sindhi = 105, + Singhalese = 106, + Siswati = 107, + Slovak = 108, + Slovenian = 109, + Somali = 110, + Spanish = 111, + Sundanese = 112, + Swahili = 113, + Swedish = 114, + Tagalog = 115, + Tajik = 116, + Tamil = 117, + Tatar = 118, + Telugu = 119, + Thai = 120, + Tibetan = 121, + Tigrinya = 122, + TongaLanguage = 123, + Tsonga = 124, + Turkish = 125, + Turkmen = 126, + Twi = 127, + Uigur = 128, + Ukrainian = 129, + Urdu = 130, + Uzbek = 131, + Vietnamese = 132, + Volapuk = 133, + Welsh = 134, + Wolof = 135, + Xhosa = 136, + Yiddish = 137, + Yoruba = 138, + Zhuang = 139, + Zulu = 140, + LastLanguage = Zulu + }; + + enum Country { + AnyCountry = 0, + Afghanistan = 1, + Albania = 2, + Algeria = 3, + AmericanSamoa = 4, + Andorra = 5, + Angola = 6, + Anguilla = 7, + Antarctica = 8, + AntiguaAndBarbuda = 9, + Argentina = 10, + Armenia = 11, + Aruba = 12, + Australia = 13, + Austria = 14, + Azerbaijan = 15, + Bahamas = 16, + Bahrain = 17, + Bangladesh = 18, + Barbados = 19, + Belarus = 20, + Belgium = 21, + Belize = 22, + Benin = 23, + Bermuda = 24, + Bhutan = 25, + Bolivia = 26, + BosniaAndHerzegowina = 27, + Botswana = 28, + BouvetIsland = 29, + Brazil = 30, + BritishIndianOceanTerritory = 31, + BruneiDarussalam = 32, + Bulgaria = 33, + BurkinaFaso = 34, + Burundi = 35, + Cambodia = 36, + Cameroon = 37, + Canada = 38, + CapeVerde = 39, + CaymanIslands = 40, + CentralAfricanRepublic = 41, + Chad = 42, + Chile = 43, + China = 44, + ChristmasIsland = 45, + CocosIslands = 46, + Colombia = 47, + Comoros = 48, + DemocraticRepublicOfCongo = 49, + PeoplesRepublicOfCongo = 50, + CookIslands = 51, + CostaRica = 52, + IvoryCoast = 53, + Croatia = 54, + Cuba = 55, + Cyprus = 56, + CzechRepublic = 57, + Denmark = 58, + Djibouti = 59, + Dominica = 60, + DominicanRepublic = 61, + EastTimor = 62, + Ecuador = 63, + Egypt = 64, + ElSalvador = 65, + EquatorialGuinea = 66, + Eritrea = 67, + Estonia = 68, + Ethiopia = 69, + FalklandIslands = 70, + FaroeIslands = 71, + FijiCountry = 72, + Finland = 73, + France = 74, + MetropolitanFrance = 75, + FrenchGuiana = 76, + FrenchPolynesia = 77, + FrenchSouthernTerritories = 78, + Gabon = 79, + Gambia = 80, + Georgia = 81, + Germany = 82, + Ghana = 83, + Gibraltar = 84, + Greece = 85, + Greenland = 86, + Grenada = 87, + Guadeloupe = 88, + Guam = 89, + Guatemala = 90, + Guinea = 91, + GuineaBissau = 92, + Guyana = 93, + Haiti = 94, + HeardAndMcDonaldIslands = 95, + Honduras = 96, + HongKong = 97, + Hungary = 98, + Iceland = 99, + India = 100, + Indonesia = 101, + Iran = 102, + Iraq = 103, + Ireland = 104, + Israel = 105, + Italy = 106, + Jamaica = 107, + Japan = 108, + Jordan = 109, + Kazakhstan = 110, + Kenya = 111, + Kiribati = 112, + DemocraticRepublicOfKorea = 113, + RepublicOfKorea = 114, + Kuwait = 115, + Kyrgyzstan = 116, + Lao = 117, + Latvia = 118, + Lebanon = 119, + Lesotho = 120, + Liberia = 121, + LibyanArabJamahiriya = 122, + Liechtenstein = 123, + Lithuania = 124, + Luxembourg = 125, + Macau = 126, + Macedonia = 127, + Madagascar = 128, + Malawi = 129, + Malaysia = 130, + Maldives = 131, + Mali = 132, + Malta = 133, + MarshallIslands = 134, + Martinique = 135, + Mauritania = 136, + Mauritius = 137, + Mayotte = 138, + Mexico = 139, + Micronesia = 140, + Moldova = 141, + Monaco = 142, + Mongolia = 143, + Montserrat = 144, + Morocco = 145, + Mozambique = 146, + Myanmar = 147, + Namibia = 148, + NauruCountry = 149, + Nepal = 150, + Netherlands = 151, + NetherlandsAntilles = 152, + NewCaledonia = 153, + NewZealand = 154, + Nicaragua = 155, + Niger = 156, + Nigeria = 157, + Niue = 158, + NorfolkIsland = 159, + NorthernMarianaIslands = 160, + Norway = 161, + Oman = 162, + Pakistan = 163, + Palau = 164, + PalestinianTerritory = 165, + Panama = 166, + PapuaNewGuinea = 167, + Paraguay = 168, + Peru = 169, + Philippines = 170, + Pitcairn = 171, + Poland = 172, + Portugal = 173, + PuertoRico = 174, + Qatar = 175, + Reunion = 176, + Romania = 177, + RussianFederation = 178, + Rwanda = 179, + SaintKittsAndNevis = 180, + StLucia = 181, + StVincentAndTheGrenadines = 182, + Samoa = 183, + SanMarino = 184, + SaoTomeAndPrincipe = 185, + SaudiArabia = 186, + Senegal = 187, + Seychelles = 188, + SierraLeone = 189, + Singapore = 190, + Slovakia = 191, + Slovenia = 192, + SolomonIslands = 193, + Somalia = 194, + SouthAfrica = 195, + SouthGeorgiaAndTheSouthSandwichIslands = 196, + Spain = 197, + SriLanka = 198, + StHelena = 199, + StPierreAndMiquelon = 200, + Sudan = 201, + Suriname = 202, + SvalbardAndJanMayenIslands = 203, + Swaziland = 204, + Sweden = 205, + Switzerland = 206, + SyrianArabRepublic = 207, + Taiwan = 208, + Tajikistan = 209, + Tanzania = 210, + Thailand = 211, + Togo = 212, + Tokelau = 213, + TongaCountry = 214, + TrinidadAndTobago = 215, + Tunisia = 216, + Turkey = 217, + Turkmenistan = 218, + TurksAndCaicosIslands = 219, + Tuvalu = 220, + Uganda = 221, + Ukraine = 222, + UnitedArabEmirates = 223, + UnitedKingdom = 224, + UnitedStates = 225, + UnitedStatesMinorOutlyingIslands = 226, + Uruguay = 227, + Uzbekistan = 228, + Vanuatu = 229, + VaticanCityState = 230, + Venezuela = 231, + VietNam = 232, + BritishVirginIslands = 233, + USVirginIslands = 234, + WallisAndFutunaIslands = 235, + WesternSahara = 236, + Yemen = 237, + Yugoslavia = 238, + Zambia = 239, + Zimbabwe = 240, + LastCountry = Zimbabwe + }; + + QLocale(); + QLocale(const QString &name); + QLocale(Language language, Country country = AnyCountry); + QLocale(const QLocale &other); + + QLocale &operator=(const QLocale &other); + + Language language() const; + Country country() const; + QString name() const; + + short toShort(const QString &s, bool *ok = 0) const; + ushort toUShort(const QString &s, bool *ok = 0) const; + int toInt(const QString &s, bool *ok = 0) const; + uint toUInt(const QString &s, bool *ok = 0) const; + Q_LONG toLong(const QString &s, bool *ok = 0) const; + Q_ULONG toULong(const QString &s, bool *ok = 0) const; + Q_LLONG toLongLong(const QString &s, bool *ok = 0) const; + Q_ULLONG toULongLong(const QString &s, bool *ok = 0) const; + float toFloat(const QString &s, bool *ok = 0) const; + double toDouble(const QString &s, bool *ok = 0) const; + + QString toString(short i) const + { return toString((Q_LLONG)i); } + QString toString(ushort i) const + { return toString((Q_ULLONG)i); } + QString toString(int i) const + { return toString((Q_LLONG)i); } + QString toString(uint i) const + { return toString((Q_ULLONG)i); } +#if !defined(Q_OS_WIN64) + QString toString(Q_LONG i) const + { return toString((Q_LLONG)i); } + QString toString(Q_ULONG i) const + { return toString((Q_ULLONG)i); } +#endif + QString toString(Q_LLONG i) const; + QString toString(Q_ULLONG i) const; + QString toString(float i, char f = 'g', int prec = 6) const + { return toString((double) i, f, prec); } + QString toString(double i, char f = 'g', int prec = 6) const; + + static QString languageToString(Language language); + static QString countryToString(Country country); + static void setDefault(const QLocale &locale); + + static QLocale c() { return QLocale(C); } + static QLocale system(); + +private: + const QLocalePrivate *d; + static const QLocalePrivate *default_d; +}; + +#endif diff --git a/qmake/include/qsettings.h b/qmake/include/qsettings.h new file mode 100644 index 0000000..72f04eb --- a/dev/null +++ b/qmake/include/qsettings.h @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** +** Definition of QSettings class +** +** Created : 000626 +** +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. +** +** This file is part of the tools module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef QSETTINGS_H +#define QSETTINGS_H + +#ifndef QT_H +#include "qdatetime.h" +#include "qstringlist.h" +#endif // QT_H + +#ifndef QT_NO_SETTINGS + +class QSettingsPrivate; + + +class Q_EXPORT QSettings +{ +public: + enum Format { + Native = 0, + Ini + }; + enum System { + Unix = 0, + Windows, + Mac + }; + enum Scope { + User, + Global + }; + + QSettings(); + QSettings( Format format ); + + ~QSettings(); + +#if !defined(Q_NO_BOOL_TYPE) + bool writeEntry( const QString &, bool ); +#endif + bool writeEntry( const QString &, double ); + bool writeEntry( const QString &, int ); + bool writeEntry( const QString &, const char * ); + bool writeEntry( const QString &, const QString & ); + bool writeEntry( const QString &, const QStringList & ); + bool writeEntry( const QString &, const QStringList &, const QChar& sep ); + + QStringList entryList(const QString &) const; + QStringList subkeyList(const QString &) const; + + //### remove non const versions in 4.0 + QStringList readListEntry( const QString &, bool * = 0 ); + QStringList readListEntry( const QString &, const QChar& sep, bool * = 0 ); + QString readEntry( const QString &, const QString &def = QString::null, bool * = 0 ); + int readNumEntry( const QString &, int def = 0, bool * = 0 ); + double readDoubleEntry( const QString &, double def = 0, bool * = 0 ); + bool readBoolEntry( const QString &, bool def = FALSE, bool * = 0 ); + + //### make those non-inlined in 4.0 + QStringList readListEntry( const QString &key, bool *ok = 0 ) const + { + QSettings *that = (QSettings*)this; + return that->readListEntry( key, ok ); + } + QStringList readListEntry( const QString &key, const QChar& sep, bool *ok = 0 ) const + { + QSettings *that = (QSettings*)this; + return that->readListEntry( key, sep, ok ); + } + QString readEntry( const QString &key, const QString &def = QString::null, + bool *ok = 0 ) const + { + QSettings *that = (QSettings*)this; + return that->readEntry( key, def, ok ); + } + int readNumEntry( const QString &key, int def = 0, bool *ok = 0 ) const + { + QSettings *that = (QSettings*)this; + return that->readNumEntry( key, def, ok ); + } + + double readDoubleEntry( const QString &key, double def = 0, bool *ok = 0 ) const + { + QSettings *that = (QSettings*)this; + return that->readDoubleEntry( key, def, ok ); + } + bool readBoolEntry( const QString &key, bool def = FALSE, bool *ok = 0 ) const + { + QSettings *that = (QSettings*)this; + return that->readBoolEntry( key, def, ok ); + } + + bool removeEntry( const QString & ); + + void insertSearchPath( System, const QString & ); + void removeSearchPath( System, const QString & ); + + void setPath( const QString &domain, const QString &product, Scope = Global ); + + void beginGroup( const QString &group ); + void endGroup(); + void resetGroup(); + QString group() const; + + bool sync(); + +private: + QSettingsPrivate *d; + +#if defined(Q_DISABLE_COPY) + QSettings(const QSettings &); + QSettings &operator=(const QSettings &); +#endif + + QDateTime lastModificationTime( const QString & ); + + friend class QApplication; +}; + +#endif // QT_NO_SETTINGS +#endif // QSETTINGS_H diff --git a/qmake/include/qunicodetables_p.h b/qmake/include/qunicodetables_p.h new file mode 100644 index 0000000..0e799e4 --- a/dev/null +++ b/qmake/include/qunicodetables_p.h @@ -0,0 +1,263 @@ +/**************************************************************************** +** +** +** ??? +** +** Copyright (C) 2003 Trolltech AS. All rights reserved. +** +** This file is part of the widgets module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef QUNICODETABLES_P_H +#define QUNICODETABLES_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of internal files. This header file may change from version to version +// without notice, or even be removed. +// +// We mean it. +// +// + +#ifndef QT_H +#include "qstring.h" +#endif // QT_H + +#ifdef QT_NO_UNICODETABLES +# include <ctype.h> +#endif + +class QUnicodeTables { +public: + static const Q_UINT8 unicode_info[]; +#ifndef QT_NO_UNICODETABLES + static const Q_UINT16 decomposition_map[]; + static const Q_UINT16 decomposition_info[]; + static const Q_UINT16 ligature_map[]; + static const Q_UINT16 ligature_info[]; + static const Q_UINT8 direction_info[]; + static const Q_UINT8 combining_info[]; + static const Q_UINT16 case_info[]; + static const Q_INT8 decimal_info[]; + static const Q_UINT16 symmetricPairs[]; + static const int symmetricPairsSize; + static const Q_UINT8 line_break_info[]; +#else + static const Q_UINT8 latin1_line_break_info[]; +#endif + static const unsigned char otherScripts[]; + static const unsigned char indicScripts[]; + static const unsigned char scriptTable[]; + enum { SCRIPTS_INDIC = 0x7e }; + + // see http://www.unicode.org/reports/tr14/tr14-13.html + // we don't use the XX and AI properties and map them to AL instead. + enum LineBreakClass { + LineBreak_OP, LineBreak_CL, LineBreak_QU, LineBreak_GL, LineBreak_NS, + LineBreak_EX, LineBreak_SY, LineBreak_IS, LineBreak_PR, LineBreak_PO, + LineBreak_NU, LineBreak_AL, LineBreak_ID, LineBreak_IN, LineBreak_HY, + LineBreak_BA, LineBreak_BB, LineBreak_B2, LineBreak_ZW, LineBreak_CM, + LineBreak_SA, LineBreak_BK, LineBreak_CR, LineBreak_LF, LineBreak_SG, + LineBreak_CB, LineBreak_SP + }; +}; + + +inline QChar::Category category( const QChar &c ) +{ +#ifdef QT_NO_UNICODETABLES + if ( c.unicode() > 0xff ) return QChar::Letter_Uppercase; //######## + return (QChar::Category)QUnicodeTables::unicode_info[c.unicode()]; +#else + register int uc = ((int)QUnicodeTables::unicode_info[c.row()]) << 8; + uc += c.cell(); + return (QChar::Category)QUnicodeTables::unicode_info[uc]; +#endif // QT_NO_UNICODETABLES +} + +inline QChar lower( const QChar &c ) +{ +#ifndef QT_NO_UNICODETABLES + int row = c.row(); + int cell = c.cell(); + register int ci = QUnicodeTables::case_info[row]; + register int uc = ((int)QUnicodeTables::unicode_info[c.row()]) << 8; + uc += c.cell(); + if (QUnicodeTables::unicode_info[uc] != QChar::Letter_Uppercase || !ci) + return c; + Q_UINT16 lower = QUnicodeTables::case_info[(ci<<8)+cell]; + return lower ? QChar(lower) : c; +#else + if ( c.row() ) + return c; + return QChar( tolower((uchar) c.latin1()) ); +#endif +} + +inline QChar upper( const QChar &c ) +{ +#ifndef QT_NO_UNICODETABLES + int row = c.row(); + int cell = c.cell(); + register int ci = QUnicodeTables::case_info[row]; + register int uc = ((int)QUnicodeTables::unicode_info[c.row()]) << 8; + uc += c.cell(); + if (QUnicodeTables::unicode_info[uc] != QChar::Letter_Lowercase || !ci) + return c; + Q_UINT16 upper = QUnicodeTables::case_info[(ci<<8)+cell]; + return upper ? QChar(upper) : c; +#else + if ( c.row() ) + return c; + return QChar( toupper((uchar) c.latin1()) ); +#endif +} + +inline QChar::Direction direction( const QChar &c ) +{ +#ifndef QT_NO_UNICODETABLES + register int pos = QUnicodeTables::direction_info[c.row()]; + return (QChar::Direction) (QUnicodeTables::direction_info[(pos<<8)+c.cell()] & 0x1f); +#else + Q_UNUSED(c); + return QChar::DirL; +#endif +} + +inline bool mirrored( const QChar &c ) +{ +#ifndef QT_NO_UNICODETABLES + register int pos = QUnicodeTables::direction_info[c.row()]; + return QUnicodeTables::direction_info[(pos<<8)+c.cell()] > 128; +#else + Q_UNUSED(c); + return FALSE; +#endif +} + + +inline QChar mirroredChar( const QChar &ch ) +{ +#ifndef QT_NO_UNICODETABLES + if(!::mirrored( ch )) + return ch; + + int i; + int c = ch.unicode(); + for (i = 0; i < QUnicodeTables::symmetricPairsSize; i ++) { + if (QUnicodeTables::symmetricPairs[i] == c) + return QUnicodeTables::symmetricPairs[(i%2) ? (i-1) : (i+1)]; + } +#endif + return ch; +} + +inline QChar::Joining joining( const QChar &ch ) +{ +#ifndef QT_NO_UNICODETABLES + register int pos = QUnicodeTables::direction_info[ch.row()]; + return (QChar::Joining) ((QUnicodeTables::direction_info[(pos<<8)+ch.cell()] >> 5) &0x3); +#else + Q_UNUSED(ch); + return QChar::OtherJoining; +#endif +} + +inline bool isMark( const QChar &ch ) +{ + QChar::Category c = ::category( ch ); + return c >= QChar::Mark_NonSpacing && c <= QChar::Mark_Enclosing; +} + +inline unsigned char combiningClass( const QChar &ch ) +{ +#ifndef QT_NO_UNICODETABLES + const int pos = QUnicodeTables::combining_info[ch.row()]; + return QUnicodeTables::combining_info[(pos<<8) + ch.cell()]; +#else + Q_UNUSED(ch); + return 0; +#endif +} + +inline bool isSpace( const QChar &ch ) +{ + if( ch.unicode() >= 9 && ch.unicode() <=13 ) return TRUE; + QChar::Category c = ::category( ch ); + return c >= QChar::Separator_Space && c <= QChar::Separator_Paragraph; +} + +inline int lineBreakClass( const QChar &ch ) +{ +#ifdef QT_NO_UNICODETABLES + return ch.row() ? QUnicodeTables::LineBreak_AL + : QUnicodeTables::latin1_line_break_info[ch.cell()]; +#else + register int pos = ((int)QUnicodeTables::line_break_info[ch.row()] << 8) + ch.cell(); + return QUnicodeTables::line_break_info[pos]; +#endif +} + +inline int scriptForChar( ushort uc ) +{ + unsigned char script = QUnicodeTables::scriptTable[(uc>>8)]; + if ( script >= QUnicodeTables::SCRIPTS_INDIC ) { + if ( script == QUnicodeTables::SCRIPTS_INDIC ) { + script = QUnicodeTables::indicScripts[ (uc-0x0900)>>7 ]; + } else { + // 0x80 + SCRIPTS_xx + unsigned char index = script-0x80; + unsigned char cell = uc &0xff; + while( QUnicodeTables::otherScripts[index++] < cell ) + index++; + script = QUnicodeTables::otherScripts[index]; + } + } + return script; +} + +#ifdef Q_WS_X11 +#define SCRIPT_FOR_CHAR( script, c ) \ +do { \ + unsigned short _uc = (c).unicode(); \ + if ( _uc < 0x100 ) { \ + script = QFont::Latin; \ + } else { \ + script = (QFont::Script)scriptForChar( _uc ); \ + } \ +} while( FALSE ) +#else +#define SCRIPT_FOR_CHAR( script, c ) \ + script = (QFont::Script)scriptForChar( (c).unicode() ) +#endif + +#endif diff --git a/qmake/include/quuid.h b/qmake/include/quuid.h index 664c149..f5d8a86 100644 --- a/qmake/include/quuid.h +++ b/qmake/include/quuid.h @@ -1,3 +1,3 @@ /**************************************************************************** -** $Id$ +** ** @@ -41,3 +41,3 @@ #ifndef QT_H -#include <qstring.h> +#include "qstring.h" #endif // QT_H @@ -59,4 +59,21 @@ typedef struct _GUID + struct Q_EXPORT QUuid { + enum Variant { + VarUnknown =-1, + NCS = 0, // 0 - - + DCE = 2, // 1 0 - + Microsoft = 6, // 1 1 0 + Reserved = 7 // 1 1 1 + }; + + enum Version { + VerUnknown =-1, + Time = 1, // 0 0 0 1 + EmbeddedPOSIX = 2, // 0 0 1 0 + Name = 3, // 0 0 1 1 + Random = 4 // 0 1 0 0 + }; + QUuid() @@ -116,2 +133,5 @@ struct Q_EXPORT QUuid + bool operator<(const QUuid &other ) const; + bool operator>(const QUuid &other ) const; + #if defined(Q_OS_WIN32) @@ -155,2 +175,5 @@ struct Q_EXPORT QUuid #endif + static QUuid createUuid(); + QUuid::Variant variant() const; + QUuid::Version version() const; diff --git a/qmake/main.cpp b/qmake/main.cpp index cc2d08a..a731314 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** ??? ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -38,2 +36,3 @@ #include "project.h" +#include "property.h" #include "option.h" @@ -52,2 +51,6 @@ #undef main +#ifdef Q_OS_MAC +// for qurl +bool qt_resolve_symlinks = FALSE; +#endif @@ -61,11 +64,32 @@ int main(int argc, char **argv) QString oldpwd = sunworkshop42workaround.currentDirPath(); - Option::output_dir = oldpwd; //for now this is the output dir #ifdef Q_WS_WIN - if ( !(Option::output_dir.length() == 3 && Option::output_dir[0].isLetter() && Option::output_dir.endsWith(":/") ) ) + if(!(oldpwd.length() == 3 && oldpwd[0].isLetter() && oldpwd.endsWith(":/") ) ) #endif { - if(Option::output_dir.right(1) != QString(QChar(QDir::separator()))) - Option::output_dir += QDir::separator(); + if(oldpwd.right(1) != QString(QChar(QDir::separator()))) + oldpwd += QDir::separator(); + } + Option::output_dir = oldpwd; //for now this is the output dir + + if(Option::output.name() != "-") { + QFileInfo fi(Option::output); + QString dir; + if(fi.isDir()) { + dir = fi.filePath(); + } else { + QString tmp_dir = fi.dirPath(); + if(!tmp_dir.isEmpty() && QFile::exists(tmp_dir)) + dir = tmp_dir; + } + if(!dir.isNull() && dir != ".") + Option::output_dir = dir; + if(QDir::isRelativePath(Option::output_dir)) + Option::output_dir.prepend(oldpwd); } - QMakeProject proj; + + QMakeProperty prop; + if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY || Option::qmake_mode == Option::QMAKE_SET_PROPERTY) + return prop.exec() ? 0 : 101; + + QMakeProject proj(&prop); int exit_val = 0; @@ -79,3 +103,3 @@ int main(int argc, char **argv) Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { - QString fn = (*pfile); + QString fn = Option::fixPathToLocalOS((*pfile)); @@ -87,3 +111,3 @@ int main(int argc, char **argv) debug_msg(1, "Changing dir to: %s", fn.left(di).latin1()); - if(!QDir::setCurrent(fn.left(fn.findRev(Option::dir_sep)))) + if(!QDir::setCurrent(fn.left(di))) fprintf(stderr, "Cannot find directory: %s\n", fn.left(di).latin1()); @@ -125,2 +149,3 @@ int main(int argc, char **argv) Option::output.setName(proj.first("QMAKE_MAKEFILE")); + Option::output_dir = oldpwd; if(!mkfile->openOutput(Option::output)) { @@ -151,3 +176,3 @@ int main(int argc, char **argv) for(QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) { - if(it.key().left(1) != "." && !it.data().isEmpty()) + if(!it.key().startsWith(".") && !it.data().isEmpty()) debug_msg(1, "%s === %s", it.key().latin1(), it.data().join(" :: ").latin1()); diff --git a/qmake/meta.cpp b/qmake/meta.cpp new file mode 100644 index 0000000..f314cb0 --- a/dev/null +++ b/qmake/meta.cpp @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** +** Implementation of QMakeMetaInfo class. +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of qmake. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition licenses may use this +** file in accordance with the Qt Commercial License Agreement provided +** with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "meta.h" +#include "project.h" +#include "option.h" +#include <qdir.h> + +QMap<QString, QMap<QString, QStringList> > QMakeMetaInfo::cache_vars; + +QMakeMetaInfo::QMakeMetaInfo() +{ + +} + + +bool +QMakeMetaInfo::readLib(const QString &lib) +{ + clear(); + QString meta_file = findLib(lib); + + if(cache_vars.contains(meta_file)) { + vars = cache_vars[meta_file]; + return TRUE; + } + + bool ret = FALSE; + if(!meta_file.isNull()) { + if(meta_file.endsWith(Option::pkgcfg_ext)) { + if((ret=readPkgCfgFile(meta_file))) + meta_type = "pkgcfg"; + } else if(meta_file.endsWith(Option::libtool_ext)) { + if((ret=readLibtoolFile(meta_file))) + meta_type = "libtool"; + } else if(meta_file.endsWith(Option::prl_ext)) { + QMakeProject proj; + if(!proj.read(Option::fixPathToLocalOS(meta_file), + QDir::currentDirPath(), QMakeProject::ReadProFile)) + return FALSE; + meta_type = "qmake"; + vars = proj.variables(); + ret = TRUE; + } else { + warn_msg(WarnLogic, "QMakeMetaInfo: unknown file format for %s", meta_file.latin1()); + } + } + if(ret) + cache_vars.insert(meta_file, vars); + return ret; +} + + +void +QMakeMetaInfo::clear() +{ + vars.clear(); +} + + +QString +QMakeMetaInfo::findLib(const QString &lib) +{ + QString ret = QString::null; + QString extns[] = { Option::prl_ext, /*Option::pkgcfg_ext, Option::libtool_ext,*/ QString::null }; + for(int extn = 0; !extns[extn].isNull(); extn++) { + if(lib.endsWith(extns[extn])) + ret = QFile::exists(lib) ? lib : QString::null; + } + if(ret.isNull()) { + for(int extn = 0; !extns[extn].isNull(); extn++) { + if(QFile::exists(lib + extns[extn])) { + ret = lib + extns[extn]; + break; + } + } + } + if(ret.isNull()) + debug_msg(2, "QMakeMetaInfo: Cannot find info file for %s", lib.latin1()); + else + debug_msg(2, "QMakeMetaInfo: Found info file %s for %s", ret.latin1(), lib.latin1()); + return ret; +} + + +bool +QMakeMetaInfo::readLibtoolFile(const QString &f) +{ + /* I can just run the .la through the .pro parser since they are compatible.. */ + QMakeProject proj; + if(!proj.read(Option::fixPathToLocalOS(f), QDir::currentDirPath(), QMakeProject::ReadProFile)) + return FALSE; + QString dirf = Option::fixPathToTargetOS(f).section(Option::dir_sep, 0, -2); + if(dirf == f) + dirf = ""; + else if(!dirf.isEmpty() && !dirf.endsWith(Option::output_dir)) + dirf += Option::dir_sep; + QMap<QString, QStringList> &v = proj.variables(); + for(QMap<QString, QStringList>::Iterator it = v.begin(); it != v.end(); ++it) { + QStringList lst = it.data(); + if(lst.count() == 1 && (lst.first().startsWith("'") || lst.first().startsWith("\"")) && + lst.first().endsWith(QString(lst.first()[0]))) + lst = lst.first().mid(1, lst.first().length() - 2); + if(!vars.contains("QMAKE_PRL_TARGET") && + (it.key() == "dlname" || it.key() == "library_names" || it.key() == "old_library")) { + QString dir = v["libdir"].first(); + if((dir.startsWith("'") || dir.startsWith("\"")) && dir.endsWith(QString(dir[0]))) + dir = dir.mid(1, dir.length() - 2); + dir = dir.stripWhiteSpace(); + if(!dir.isEmpty() && !dir.endsWith(Option::dir_sep)) + dir += Option::dir_sep; + if(lst.count() == 1) + lst = QStringList::split(" ", lst.first()); + for(QStringList::Iterator lst_it = lst.begin(); lst_it != lst.end(); ++lst_it) { + bool found = FALSE; + QString dirs[] = { "", dir, dirf, dirf + ".libs" + QDir::separator(), "(term)" }; + for(int i = 0; !found && dirs[i] != "(term)"; i++) { + if(QFile::exists(dirs[i] + (*lst_it))) { + QString targ = dirs[i] + (*lst_it); + if(QDir::isRelativePath(targ)) + targ.prepend(QDir::currentDirPath() + QDir::separator()); + vars["QMAKE_PRL_TARGET"] << targ; + found = TRUE; + } + } + if(found) + break; + } + } else if(it.key() == "dependency_libs") { + if(lst.count() == 1) { + QString dep = lst.first(); + if((dep.startsWith("'") || dep.startsWith("\"")) && dep.endsWith(QString(dep[0]))) + dep = dep.mid(1, dep.length() - 2); + lst = QStringList::split(" ", dep.stripWhiteSpace()); + } + QMakeProject *conf = NULL; + for(QStringList::Iterator lit = lst.begin(); lit != lst.end(); ++lit) { + if((*lit).startsWith("-R")) { + if(!conf) { + conf = new QMakeProject; + conf->read(QMakeProject::ReadAll ^ QMakeProject::ReadProFile); + } + if(!conf->isEmpty("QMAKE_RPATH")) + (*lit) = conf->first("QMAKE_RPATH") + (*lit).mid(2); + } + } + if(conf) + delete conf; + vars["QMAKE_PRL_LIBS"] += lst; + } + } + return TRUE; +} + +bool +QMakeMetaInfo::readPkgCfgFile(const QString &f) +{ + fprintf(stderr, "Must implement reading in pkg-config files (%s)!!!\n", f.latin1()); + return FALSE; +} diff --git a/qmake/meta.h b/qmake/meta.h new file mode 100644 index 0000000..2edbfca --- a/dev/null +++ b/qmake/meta.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** +** Definition of QMakeMetaInfo class. +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of qmake. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition licenses may use this +** file in accordance with the Qt Commercial License Agreement provided +** with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef __META_H__ +#define __META_H__ + +#include <qmap.h> +#include <qstringlist.h> +#include <qstring.h> + +class QMakeMetaInfo +{ + bool readLibtoolFile(const QString &f); + bool readPkgCfgFile(const QString &f); + QMap<QString, QStringList> vars; + QString meta_type; + static QMap<QString, QMap<QString, QStringList> > cache_vars; + void clear(); +public: + QMakeMetaInfo(); + + bool readLib(const QString &lib); + static QString findLib(const QString &lib); + static bool libExists(const QString &lib); + QString type() const; + + bool isEmpty(const QString &v); + QStringList &values(const QString &v); + QString first(const QString &v); + QMap<QString, QStringList> &variables(); +}; + +inline bool QMakeMetaInfo::isEmpty(const QString &v) +{ return !vars.contains(v) || vars[v].isEmpty(); } + +inline QString QMakeMetaInfo::type() const +{ return meta_type; } + +inline QStringList &QMakeMetaInfo::values(const QString &v) +{ return vars[v]; } + +inline QString QMakeMetaInfo::first(const QString &v) +{ +#if defined(Q_CC_SUN) && (__SUNPRO_CC == 0x500) || defined(Q_CC_HP) + // workaround for Sun WorkShop 5.0 bug fixed in Forte 6 + if (isEmpty(v)) + return QString(""); + else + return vars[v].first(); +#else + return isEmpty(v) ? QString("") : vars[v].first(); +#endif +} + +inline QMap<QString, QStringList> &QMakeMetaInfo::variables() +{ return vars; } + +inline bool QMakeMetaInfo::libExists(const QString &lib) +{ return !findLib(lib).isNull(); } + +#endif /* __META_H__ */ diff --git a/qmake/option.cpp b/qmake/option.cpp index 8b7e5e8..e6928fa 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of Option class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -46,5 +44,8 @@ QString Option::prf_ext; QString Option::prl_ext; +QString Option::libtool_ext; +QString Option::pkgcfg_ext; QString Option::ui_ext; QStringList Option::h_ext; -QString Option::moc_ext; +QString Option::cpp_moc_ext; +QString Option::h_moc_ext; QStringList Option::cpp_ext; @@ -54,3 +55,4 @@ QString Option::yacc_ext; QString Option::dir_sep; -QString Option::moc_mod; +QString Option::h_moc_mod; +QString Option::cpp_moc_mod; QString Option::yacc_mod; @@ -82,2 +84,5 @@ Option::TARG_MODE Option::target_mode = Option::TARG_UNIX_MODE; +//QMAKE_*_PROPERTY stuff +QStringList Option::prop::properties; + //QMAKE_GENERATE_PROJECT stuff @@ -106,2 +111,4 @@ static Option::QMAKE_MODE default_mode(QString progname) return Option::QMAKE_GENERATE_PROJECT; + else if(progname == "qt-config") + return Option::QMAKE_QUERY_PROPERTY; return Option::QMAKE_GENERATE_MAKEFILE; @@ -163,3 +170,8 @@ bool usage(const char *a0) -bool +enum { + QMAKE_CMDLINE_SUCCESS, + QMAKE_CMDLINE_SHOW_USAGE, + QMAKE_CMDLINE_BAIL +}; +int Option::internalParseCommandLine(int argc, char **argv, int skip) @@ -180,2 +192,6 @@ Option::internalParseCommandLine(int argc, char **argv, int skip) Option::qmake_mode = Option::QMAKE_GENERATE_PRL; + } else if(opt == "set") { + Option::qmake_mode = Option::QMAKE_SET_PROPERTY; + } else if(opt == "query") { + Option::qmake_mode = Option::QMAKE_QUERY_PROPERTY; } else if(opt == "makefile") { @@ -210,5 +226,5 @@ Option::internalParseCommandLine(int argc, char **argv, int skip) fprintf(stderr, "Qmake is free software from Trolltech AS.\n"); - return FALSE; + return QMAKE_CMDLINE_BAIL; } else if(opt == "h" || opt == "help") { - return FALSE; + return QMAKE_CMDLINE_SHOW_USAGE; } else if(opt == "Wall") { @@ -241,3 +257,3 @@ Option::internalParseCommandLine(int argc, char **argv, int skip) fprintf(stderr, "***Unknown option -%s\n", opt.latin1()); - return usage(argv[0]); + return QMAKE_CMDLINE_SHOW_USAGE; } @@ -252,3 +268,3 @@ Option::internalParseCommandLine(int argc, char **argv, int skip) fprintf(stderr, "***Unknown option -%s\n", opt.latin1()); - return FALSE; + return QMAKE_CMDLINE_SHOW_USAGE; } @@ -264,10 +280,20 @@ Option::internalParseCommandLine(int argc, char **argv, int skip) } else { - QFileInfo fi(arg); - if(!fi.convertToAbs()) //strange - arg = fi.filePath(); - if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || - Option::qmake_mode == Option::QMAKE_GENERATE_PRL) - Option::mkfile::project_files.append(arg); - else - Option::projfile::project_dirs.append(arg); + bool handled = TRUE; + if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY || + Option::qmake_mode == Option::QMAKE_SET_PROPERTY) { + Option::prop::properties.append(arg); + } else { + QFileInfo fi(arg); + if(!fi.convertToAbs()) //strange + arg = fi.filePath(); + if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || + Option::qmake_mode == Option::QMAKE_GENERATE_PRL) + Option::mkfile::project_files.append(arg); + else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) + Option::projfile::project_dirs.append(arg); + else + handled = FALSE; + } + if(!handled) + return QMAKE_CMDLINE_SHOW_USAGE; } @@ -275,3 +301,3 @@ Option::internalParseCommandLine(int argc, char **argv, int skip) } - return TRUE; + return QMAKE_CMDLINE_SUCCESS; } @@ -282,3 +308,4 @@ Option::parseCommandLine(int argc, char **argv) { - Option::moc_mod = "moc_"; + Option::cpp_moc_mod = ""; + Option::h_moc_mod = "moc_"; Option::lex_mod = "_lex"; @@ -286,2 +313,4 @@ Option::parseCommandLine(int argc, char **argv) Option::prl_ext = ".prl"; + Option::libtool_ext = ".la"; + Option::pkgcfg_ext = ".pc"; Option::prf_ext = ".prf"; @@ -289,3 +318,4 @@ Option::parseCommandLine(int argc, char **argv) Option::h_ext << ".h" << ".hpp" << ".hh" << ".H" << ".hxx"; - Option::moc_ext = ".moc"; + Option::cpp_moc_ext = ".moc"; + Option::h_moc_ext = ".cpp"; Option::cpp_ext << ".cpp" << ".cc" << ".cxx" << ".C"; @@ -336,4 +366,7 @@ Option::parseCommandLine(int argc, char **argv) } - if(!internalParseCommandLine(argc, argv, 1)) - return usage(argv[0]); + { + int ret = internalParseCommandLine(argc, argv, 1); + if(ret != QMAKE_CMDLINE_SUCCESS) + return ret == QMAKE_CMDLINE_SHOW_USAGE ? usage(argv[0]) : FALSE; + } @@ -383,2 +416,6 @@ bool Option::postProcessProject(QMakeProject *project) + if(!project->isEmpty("QMAKE_EXT_PKGCONFIG")) + Option::pkgcfg_ext = project->first("QMAKE_EXT_PKGCONFIG"); + if(!project->isEmpty("QMAKE_EXT_LIBTOOL")) + Option::libtool_ext = project->first("QMAKE_EXT_LIBTOOL"); if(!project->isEmpty("QMAKE_EXT_PRL")) @@ -389,4 +426,6 @@ bool Option::postProcessProject(QMakeProject *project) Option::ui_ext = project->first("QMAKE_EXT_UI"); - if(!project->isEmpty("QMAKE_EXT_MOC")) - Option::moc_ext = project->first("QMAKE_EXT_MOC"); + if(!project->isEmpty("QMAKE_EXT_CPP_MOC")) + Option::cpp_moc_ext = project->first("QMAKE_EXT_CPP_MOC"); + if(!project->isEmpty("QMAKE_EXT_H_MOC")) + Option::h_moc_ext = project->first("QMAKE_EXT_H_MOC"); if(!project->isEmpty("QMAKE_EXT_LEX")) @@ -397,4 +436,6 @@ bool Option::postProcessProject(QMakeProject *project) Option::obj_ext = project->first("QMAKE_EXT_OBJ"); - if(!project->isEmpty("QMAKE_MOD_MOC")) - Option::moc_mod = project->first("QMAKE_MOD_MOC"); + if(!project->isEmpty("QMAKE_H_MOD_MOC")) + Option::h_moc_mod = project->first("QMAKE_H_MOD_MOC"); + if(!project->isEmpty("QMAKE_CPP_MOD_MOC")) + Option::cpp_moc_mod = project->first("QMAKE_CPP_MOD_MOC"); if(!project->isEmpty("QMAKE_MOD_LEX")) diff --git a/qmake/option.h b/qmake/option.h index 8bd348e..6197605 100644 --- a/qmake/option.h +++ b/qmake/option.h @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of Option class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -36,2 +34,3 @@ **********************************************************************/ + #ifndef __OPTION_H__ @@ -45,3 +44,3 @@ #define QMAKE_VERSION_MAJOR 1 -#define QMAKE_VERSION_MINOR 5 +#define QMAKE_VERSION_MINOR 7 #define QMAKE_VERSION_PATCH 0 @@ -62,2 +61,4 @@ struct Option //simply global convenience + static QString libtool_ext; + static QString pkgcfg_ext; static QString prf_ext; @@ -67,3 +68,4 @@ struct Option static QStringList cpp_ext; - static QString moc_ext; + static QString h_moc_ext; + static QString cpp_moc_ext; static QString obj_ext; @@ -71,3 +73,4 @@ struct Option static QString yacc_ext; - static QString moc_mod; + static QString h_moc_mod; + static QString cpp_moc_mod; static QString lex_mod; @@ -85,3 +88,3 @@ struct Option enum QMAKE_MODE { QMAKE_GENERATE_NOTHING, QMAKE_GENERATE_PROJECT, QMAKE_GENERATE_MAKEFILE, - QMAKE_GENERATE_PRL }; + QMAKE_GENERATE_PRL, QMAKE_SET_PROPERTY, QMAKE_QUERY_PROPERTY }; static QMAKE_MODE qmake_mode; @@ -98,2 +101,8 @@ struct Option + + //QMAKE_*_PROPERTY options + struct prop { + static QStringList properties; + }; + //QMAKE_GENERATE_PROJECT options @@ -120,3 +129,3 @@ struct Option private: - static bool internalParseCommandLine(int, char **, int=0); + static int internalParseCommandLine(int, char **, int=0); }; diff --git a/qmake/project.cpp b/qmake/project.cpp index 834823d..8aa6ff7 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Implementation of QMakeProject class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -38,2 +36,3 @@ #include "project.h" +#include "property.h" #include "option.h" @@ -60,2 +59,3 @@ struct parser_info { } parser; + static void qmake_error_msg(const char *msg) @@ -65,2 +65,42 @@ static void qmake_error_msg(const char *msg) +QStringList qmake_mkspec_paths() +{ + QStringList ret; + const QString concat = QDir::separator() + QString("mkspecs"); + if(const char *qmakepath = getenv("QMAKEPATH")) { +#ifdef Q_OS_WIN + QStringList lst = QStringList::split(';', qmakepath); + for(QStringList::Iterator it = lst.begin(); it != lst.end(); ++it) { + QStringList lst2 = QStringList::split(':', (*it)); + for(QStringList::Iterator it2 = lst2.begin(); it2 != lst2.end(); ++it2) + ret << ((*it2) + concat); + } +#else + QStringList lst = QStringList::split(':', qmakepath); + for(QStringList::Iterator it = lst.begin(); it != lst.end(); ++it) + ret << ((*it) + concat); +#endif + } + if(const char *qtdir = getenv("QTDIR")) + ret << (QString(qtdir) + concat); +#ifdef QT_INSTALL_PREFIX + ret << (QT_INSTALL_PREFIX + concat); +#endif +#if defined(HAVE_QCONFIG_CPP) + ret << (qInstallPath() + concat); +#endif +#ifdef QT_INSTALL_DATA + ret << (QT_INSTALL_DATA + concat); +#endif +#if defined(HAVE_QCONFIG_CPP) + ret << (qInstallPathData() + concat); +#endif + + /* prefer $QTDIR if it is set */ + if (getenv("QTDIR")) + ret << getenv("QTDIR"); + ret << qInstallPathData(); + return ret; +} + static QString varMap(const QString &x) @@ -70,8 +110,22 @@ static QString varMap(const QString &x) ret = "QMAKE" + ret.mid(5); - if(ret == "INTERFACES") + else if(ret == "INTERFACES") ret = "FORMS"; - if(ret == "QMAKE_POST_BUILD") + else if(ret == "QMAKE_POST_BUILD") ret = "QMAKE_POST_LINK"; - if(ret == "TARGETDEPS") + else if(ret == "TARGETDEPS") ret = "POST_TARGETDEPS"; + else if(ret == "LIBPATH") + ret = "QMAKE_LIBDIR"; + else if(ret == "QMAKE_EXT_MOC") + ret = "QMAKE_EXT_CPP_MOC"; + else if(ret == "QMAKE_MOD_MOC") + ret = "QMAKE_H_MOD_MOC"; + else if(ret == "QMAKE_LFLAGS_SHAPP") + ret = "QMAKE_LFLAGS_APP"; + else if(ret == "PRECOMPH") + ret = "PRECOMPILED_HEADER"; + else if(ret == "PRECOMPCPP") + ret = "PRECOMPILED_SOURCE"; + else if(ret == "INCPATH") + ret = "INCLUDEPATH"; return ret; @@ -81,7 +135,11 @@ static QStringList split_arg_list(const QString ¶ms) { - QStringList args; - int last = 0, parens = 0; QChar quote = 0; - for(int x = 0; x < (int)params.length(); x++) { - if(params[x] == ')') { + QStringList args; + for(int x = 0, last = 0, parens = 0; x <= (int)params.length(); x++) { + if(x == (int)params.length()) { + QString mid = params.mid(last, x - last).stripWhiteSpace(); + if(mid[(int)mid.length()-1] == quote) + mid.truncate(1); + args << mid; + } else if(params[x] == ')') { parens--; @@ -94,3 +152,3 @@ static QStringList split_arg_list(const QString ¶ms) } else if(!parens && !quote && params[x] == ',') { - args << params.mid(last, x - last); + args << params.mid(last, x - last).stripWhiteSpace(); last = x+1; @@ -98,4 +156,2 @@ static QStringList split_arg_list(const QString ¶ms) } - if(last != (int)params.length()) - args << params.mid(last); return args; @@ -105,3 +161,3 @@ static QStringList split_value_list(const QString &vals, bool do_semicolon=FALSE { - int last = 0; + QString build; QStringList ret; @@ -109,14 +165,18 @@ static QStringList split_value_list(const QString &vals, bool do_semicolon=FALSE for(int x = 0; x < (int)vals.length(); x++) { - if(!quote.isEmpty() && vals[x] == quote.top()) { + if(x != (int)vals.length()-1 && vals[x] == '\\' && (vals[x+1] == '\'' || vals[x+1] == '"')) + build += vals[x++]; //get that 'escape' + else if(!quote.isEmpty() && vals[x] == quote.top()) quote.pop(); - } else if(vals[x] == '\'' || vals[x] == '"') { + else if(vals[x] == '\'' || vals[x] == '"') quote.push(vals[x]); - } else if(quote.isEmpty() && - ((do_semicolon && vals[x] == ';') || vals[x] == ' ')) { - ret << vals.mid(last, x - last); - last = x+1; + + if(quote.isEmpty() && ((do_semicolon && vals[x] == ';') || vals[x] == ' ')) { + ret << build; + build = ""; + } else { + build += vals[x]; } } - if(last != (int)vals.length()) - ret << vals.mid(last); + if(!build.isEmpty()) + ret << build; return ret; @@ -126,2 +186,17 @@ QMakeProject::QMakeProject() { + prop = NULL; +} + +QMakeProject::QMakeProject(QMakeProperty *p) +{ + prop = p; +} + +void +QMakeProject::reset() +{ + /* scope blocks start at true */ + test_status = TestNone; + scope_flag = 0x01; + scope_block = 0; } @@ -132,3 +207,3 @@ QMakeProject::parse(const QString &t, QMap<QString, QStringList> &place) QString s = t.simplifyWhiteSpace(); - int hash_mark = s.find('#'); + int hash_mark = s.find("#"); if(hash_mark != -1) //good bye comments @@ -149,3 +224,3 @@ QMakeProject::parse(const QString &t, QMap<QString, QStringList> &place) /* adjust scope for each block which appears on a single line */ - for(int i = (s.contains('{')-s.contains('}')); i; i--) + for(int i = (s.contains('{')-s.contains('}')); i>0; i--) scope_flag &= ~(0x01 << (++scope_block)); @@ -230,3 +305,3 @@ QMakeProject::parse(const QString &t, QMap<QString, QStringList> &place) } else { - test = isActiveConfig(comp_scope.stripWhiteSpace(), TRUE); + test = isActiveConfig(comp_scope.stripWhiteSpace(), TRUE, &place); } @@ -250,2 +325,10 @@ QMakeProject::parse(const QString &t, QMap<QString, QStringList> &place) } + } else if(!parens && *d == '}') { + if(!scope_block) { + warn_msg(WarnParser, "Possible braces mismatch %s:%d", parser.file.latin1(), parser.line_no); + } else { + debug_msg(1, "Project Parser: %s:%d : Leaving block %d", parser.file.latin1(), + parser.line_no, scope_block); + --scope_block; + } } else { @@ -255,2 +338,3 @@ QMakeProject::parse(const QString &t, QMap<QString, QStringList> &place) } + var = var.stripWhiteSpace(); if(!scope_count || (scope_count == 1 && else_line)) @@ -262,3 +346,3 @@ QMakeProject::parse(const QString &t, QMap<QString, QStringList> &place) if(!*d) { - if(!var.isEmpty()) + if(!var.stripWhiteSpace().isEmpty()) qmake_error_msg("Parse Error ('" + s + "')"); @@ -268,3 +352,4 @@ QMakeProject::parse(const QString &t, QMap<QString, QStringList> &place) SKIP_WS(d); - for( ; *d && op.find('=') == -1; op += *(d++)); + for( ; *d && op.find('=') == -1; op += *(d++)) + ; op.replace(QRegExp("\\s"), ""); @@ -286,3 +371,2 @@ QMakeProject::parse(const QString &t, QMap<QString, QStringList> &place) - var = var.stripWhiteSpace(); #undef SKIP_WS @@ -292,6 +376,6 @@ QMakeProject::parse(const QString &t, QMap<QString, QStringList> &place) if(parser.file != last_file) { - fprintf(stderr, "#file %s:%d\n", parser.file.latin1(), parser.line_no); + fprintf(stdout, "#file %s:%d\n", parser.file.latin1(), parser.line_no); last_file = parser.file; } - fprintf(stderr, "%s %s %s\n", var.latin1(), op.latin1(), vals.latin1()); + fprintf(stdout, "%s %s %s\n", var.latin1(), op.latin1(), vals.latin1()); } @@ -307,3 +391,3 @@ QMakeProject::parse(const QString &t, QMap<QString, QStringList> &place) debug_msg(1, "Project Parser: %s:%d :%s: :%s: (%s)", parser.file.latin1(), parser.line_no, - var.latin1(), op.latin1(), vallist.join(" :: ").latin1()); + var.latin1(), op.latin1(), vallist.isEmpty() ? "" : vallist.join(" :: ").latin1()); @@ -371,6 +455,3 @@ QMakeProject::read(const QString &file, QMap<QString, QStringList> &place) parser_info pi = parser; - /* scope blocks start at true */ - test_status = TestNone; - scope_flag = 0x01; - scope_block = 0; + reset(); @@ -397,10 +478,11 @@ QMakeProject::read(const QString &file, QMap<QString, QStringList> &place) int prelen = line.length(); - { - int hash_mark = line.find('#'); - if(hash_mark != -1) //bye comments - line = line.left(hash_mark); - } + + int hash_mark = line.find("#"); + if(hash_mark != -1) //good bye comments + line = line.left(hash_mark); if(!line.isEmpty() && line.right(1) == "\\") { - line.truncate(line.length() - 1); - s += line + " "; + if (!line.startsWith("#")) { + line.truncate(line.length() - 1); + s += line + " "; + } } else if(!line.isEmpty() || (line.isEmpty() && !prelen)) { @@ -421,2 +503,5 @@ QMakeProject::read(const QString &file, QMap<QString, QStringList> &place) parser = pi; + if(scope_block != 0) + warn_msg(WarnParser, "%s: Unterminated conditional at end of file.", + file.latin1()); return ret; @@ -425,11 +510,11 @@ QMakeProject::read(const QString &file, QMap<QString, QStringList> &place) bool -QMakeProject::read(const QString &project, const QString &, bool just_project) +QMakeProject::read(const QString &project, const QString &, uchar cmd) { - if(just_project) { //nothing more, nothing less - pfile = project; - if(pfile != "-" && !QFile::exists(pfile) && pfile.right(4) != ".pro") - pfile += ".pro"; - return read(pfile, vars); - } + pfile = project; + return read(cmd); +} +bool +QMakeProject::read(uchar cmd) +{ if(cfile.isEmpty()) { @@ -441,4 +526,3 @@ QMakeProject::read(const QString &project, const QString &, bool just_project) - /* parse the cache */ - if(Option::mkfile::do_cache) { + if(cmd & ReadCache && Option::mkfile::do_cache) { /* parse the cache */ if(Option::mkfile::cachefile.isEmpty()) { //find it as it has not been specified @@ -464,60 +548,92 @@ QMakeProject::read(const QString &project, const QString &, bool just_project) } - /* parse mkspec */ - QStringList mkspec_roots; - /* prefer $QTDIR if it is set */ - if (getenv("QTDIR")) - mkspec_roots << getenv("QTDIR"); - mkspec_roots << qInstallPathData(); - if(Option::mkfile::qmakespec.isEmpty()) { - for(QStringList::Iterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { - QString mkspec = (*it) + QDir::separator() + QString("mkspecs") + - QDir::separator() + "default"; - if(QFile::exists(mkspec)) { - Option::mkfile::qmakespec = mkspec; - break; - } - } + if(cmd & ReadConf) { /* parse mkspec */ + QStringList mkspec_roots = qmake_mkspec_paths(); if(Option::mkfile::qmakespec.isEmpty()) { - fprintf(stderr, "QMAKESPEC has not been set, so configuration cannot be deduced.\n"); - return FALSE; + for(QStringList::Iterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { + QString mkspec = (*it) + QDir::separator() + "default"; + if(QFile::exists(mkspec)) { + Option::mkfile::qmakespec = mkspec; + break; + } + } + if(Option::mkfile::qmakespec.isEmpty()) { + fprintf(stderr, "QMAKESPEC has not been set, so configuration cannot be deduced.\n"); + return FALSE; + } } - } - if(QDir::isRelativePath(Option::mkfile::qmakespec)) { - bool found_mkspec = FALSE; - for(QStringList::Iterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { - QString mkspec = (*it) + QDir::separator() + QString("mkspecs") + - QDir::separator() + Option::mkfile::qmakespec; - if(QFile::exists(mkspec)) { - found_mkspec = TRUE; - Option::mkfile::qmakespec = mkspec; - break; + if(QDir::isRelativePath(Option::mkfile::qmakespec)) { + bool found_mkspec = FALSE; + for(QStringList::Iterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) { + QString mkspec = (*it) + QDir::separator() + Option::mkfile::qmakespec; + if(QFile::exists(mkspec)) { + found_mkspec = TRUE; + Option::mkfile::qmakespec = mkspec; + break; + } + } + if(!found_mkspec) { + fprintf(stderr, "Could not find mkspecs for your QMAKESPEC after trying:\n\t%s\n", + mkspec_roots.join("\n\t").latin1()); + return FALSE; } } - if(!found_mkspec) { - fprintf(stderr, "Could not find mkspecs for your QMAKESPEC after trying:\n\t%s\n", - mkspec_roots.join("\n\t").latin1()); + + /* parse qmake configuration */ + while(Option::mkfile::qmakespec.endsWith(QString(QChar(QDir::separator())))) + Option::mkfile::qmakespec.truncate(Option::mkfile::qmakespec.length()-1); + QString spec = Option::mkfile::qmakespec + QDir::separator() + "qmake.conf"; + if(!QFile::exists(spec) && + QFile::exists(Option::mkfile::qmakespec + QDir::separator() + "tmake.conf")) + spec = Option::mkfile::qmakespec + QDir::separator() + "tmake.conf"; + debug_msg(1, "QMAKESPEC conf: reading %s", spec.latin1()); + if(!read(spec, base_vars)) { + fprintf(stderr, "Failure to read QMAKESPEC conf file %s.\n", spec.latin1()); return FALSE; } + if(Option::mkfile::do_cache && !Option::mkfile::cachefile.isEmpty()) { + debug_msg(1, "QMAKECACHE file: reading %s", Option::mkfile::cachefile.latin1()); + read(Option::mkfile::cachefile, base_vars); + } + } + if(cmd & ReadCmdLine) { + /* commandline */ + cfile = pfile; + parser.line_no = 1; //really arg count now.. duh + parser.file = "(internal)"; + reset(); + for(QStringList::Iterator it = Option::before_user_vars.begin(); + it != Option::before_user_vars.end(); ++it) { + if(!parse((*it), base_vars)) { + fprintf(stderr, "Argument failed to parse: %s\n", (*it).latin1()); + return FALSE; + } + parser.line_no++; + } } + } + + vars = base_vars; /* start with the base */ - /* parse qmake configuration */ - QString spec = Option::mkfile::qmakespec + QDir::separator() + "qmake.conf"; - debug_msg(1, "QMAKESPEC conf: reading %s", spec.latin1()); - if(!read(spec, base_vars)) { - fprintf(stderr, "Failure to read QMAKESPEC conf file %s.\n", spec.latin1()); + if(cmd & ReadProFile) { /* parse project file */ + debug_msg(1, "Project file: reading %s", pfile.latin1()); + if(pfile != "-" && !QFile::exists(pfile) && !pfile.endsWith(".pro")) + pfile += ".pro"; + if(!read(pfile, vars)) return FALSE; - } - if(Option::mkfile::do_cache && !Option::mkfile::cachefile.isEmpty()) { - debug_msg(1, "QMAKECACHE file: reading %s", Option::mkfile::cachefile.latin1()); - read(Option::mkfile::cachefile, base_vars); - } + } - /* commandline */ - cfile = project; + if(cmd & ReadPostFiles) { /* parse post files */ + const QStringList l = vars["QMAKE_POST_INCLUDE_FILES"]; + for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) + read((*it), vars); + } + + if(cmd & ReadCmdLine) { parser.line_no = 1; //really arg count now.. duh parser.file = "(internal)"; - for(QStringList::Iterator it = Option::before_user_vars.begin(); - it != Option::before_user_vars.end(); ++it) { - if(!parse((*it), base_vars)) { + reset(); + for(QStringList::Iterator it = Option::after_user_vars.begin(); + it != Option::after_user_vars.end(); ++it) { + if(!parse((*it), vars)) { fprintf(stderr, "Argument failed to parse: %s\n", (*it).latin1()); @@ -529,27 +645,6 @@ QMakeProject::read(const QString &project, const QString &, bool just_project) - /* parse project file */ - debug_msg(1, "Project file: reading %s", project.latin1()); - vars = base_vars; /* start with the base */ - - pfile = project; - if(pfile != "-" && !QFile::exists(pfile) && pfile.right(4) != ".pro") - pfile += ".pro"; - - if(!read(pfile, vars)) - return FALSE; - - parser.line_no = 1; //really arg count now.. duh - parser.file = "(internal)"; - for(QStringList::Iterator it = Option::after_user_vars.begin(); - it != Option::after_user_vars.end(); ++it) { - if(!parse((*it), vars)) { - fprintf(stderr, "Argument failed to parse: %s\n", (*it).latin1()); - return FALSE; - } - parser.line_no++; - } - /* now let the user override the template from an option.. */ if(!Option::user_template.isEmpty()) { - debug_msg(1, "Overriding TEMPLATE (%s) with: %s", vars["TEMPLATE"].first().latin1(), Option::user_template.latin1()); + debug_msg(1, "Overriding TEMPLATE (%s) with: %s", vars["TEMPLATE"].first().latin1(), + Option::user_template.latin1()); vars["TEMPLATE"].clear(); @@ -563,5 +658,4 @@ QMakeProject::read(const QString &project, const QString &, bool just_project) templ = QStringList(templ.first().left(templ.first().length() - 2)); - if ( !Option::user_template_prefix.isEmpty() ) { + if ( !Option::user_template_prefix.isEmpty() ) templ.first().prepend(Option::user_template_prefix); - } @@ -595,3 +689,3 @@ QMakeProject::read(const QString &project, const QString &, bool just_project) bool -QMakeProject::isActiveConfig(const QString &x, bool regex) +QMakeProject::isActiveConfig(const QString &x, bool regex, QMap<QString, QStringList> *place) { @@ -639,3 +733,3 @@ QMakeProject::isActiveConfig(const QString &x, bool regex) - QStringList &configs = vars["CONFIG"]; + QStringList &configs = (place ? (*place)["CONFIG"] : vars["CONFIG"]); for(QStringList::Iterator it = configs.begin(); it != configs.end(); ++it) { @@ -779,3 +873,6 @@ QMakeProject::doProjectTest(const QString& func, QStringList args, QMap<QString, } else if(func == "include" || func == "load") { - if(args.count() != 1) { + QString seek_var; + if(args.count() == 2 && func == "include") { + seek_var = args[1]; + } else if(args.count() != 1) { QString func_desc = "include(file)"; @@ -796,29 +893,71 @@ QMakeProject::doProjectTest(const QString& func, QStringList args, QMap<QString, if(file.find(Option::dir_sep) == -1 || !QFile::exists(file)) { - if(QFile::exists(Option::mkfile::qmakespec + QDir::separator() + file)) { - file.prepend(Option::mkfile::qmakespec + QDir::separator()); - } else { - bool found = FALSE; - QStringList feature_roots; - if(getenv("QTDIR")) - feature_roots << getenv("QTDIR"); + bool found = FALSE; + const QString concat = QDir::separator() + QString("mkspecs") + + QDir::separator() + QString("features"); + QStringList feature_roots; + if(const char *mkspec_path = getenv("QMAKEFEATURES")) { +#ifdef Q_OS_WIN + QStringList lst = QStringList::split(';', mkspec_path); + for(QStringList::Iterator it = lst.begin(); it != lst.end(); ++it) + feature_roots += QStringList::split(':', (*it)); +#else + feature_roots += QStringList::split(':', mkspec_path); +#endif + } + if(const char *qmakepath = getenv("QMAKEPATH")) { +#ifdef Q_OS_WIN + QStringList lst = QStringList::split(';', qmakepath); + for(QStringList::Iterator it = lst.begin(); it != lst.end(); ++it) { + QStringList lst2 = QStringList::split(':', (*it)); + for(QStringList::Iterator it2 = lst2.begin(); it2 != lst2.end(); ++it2) + feature_roots << ((*it2) + concat); + } +#else + QStringList lst = QStringList::split(':', qmakepath); + for(QStringList::Iterator it = lst.begin(); it != lst.end(); ++it) + feature_roots << ((*it) + concat); +#endif + } + feature_roots << Option::mkfile::qmakespec; + if(const char *qtdir = getenv("QTDIR")) + feature_roots << (qtdir + concat); #ifdef QT_INSTALL_PREFIX - feature_roots << QT_INSTALL_PREFIX; + feature_roots << (QT_INSTALL_PREFIX + concat); +#endif +#if defined(HAVE_QCONFIG_CPP) + feature_roots << (qInstallPath() + concat); #endif #ifdef QT_INSTALL_DATA - feature_roots << QT_INSTALL_DATA; + feature_roots << (QT_INSTALL_DATA + concat); #endif - for(QStringList::Iterator it = feature_roots.begin(); it != feature_roots.end(); ++it) { - QString prf = (*it) + QDir::separator() + QString("mkspecs") + - QDir::separator() + QString("features") + QDir::separator() + file; - if(QFile::exists(prf)) { - found = TRUE; - file = prf; - break; - } - } - if(!found) { - printf("Project LOAD(): Feature %s cannot be found.\n", args.first().latin1()); - exit(3); +#if defined(HAVE_QCONFIG_CPP) + feature_roots << (qInstallPathData() + concat); +#endif + for(QStringList::Iterator it = feature_roots.begin(); it != feature_roots.end(); ++it) { + QString prf = (*it) + QDir::separator() + file; + if(QFile::exists(prf)) { + found = TRUE; + file = prf; + break; } } + if(!found) { + printf("Project LOAD(): Feature %s cannot be found.\n", args.first().latin1()); + exit(3); + } + } + } + if(QDir::isRelativePath(file)) { + QStringList include_roots; + include_roots << Option::output_dir; + QString pfilewd = QFileInfo(parser.file).dirPath(); + if(pfilewd.isEmpty()) + include_roots << pfilewd; + if(Option::output_dir != QDir::currentDirPath()) + include_roots << QDir::currentDirPath(); + for(QStringList::Iterator it = include_roots.begin(); it != include_roots.end(); ++it) { + if(QFile::exists((*it) + QDir::separator() + file)) { + file = (*it) + QDir::separator() + file; + break; + } } @@ -826,3 +965,17 @@ QMakeProject::doProjectTest(const QString& func, QStringList args, QMap<QString, + if(Option::mkfile::do_preprocess) //nice to see this first.. + fprintf(stderr, "#switching file %s(%s) - %s:%d\n", func.latin1(), file.latin1(), + parser.file.latin1(), parser.line_no); debug_msg(1, "Project Parser: %s'ing file %s.", func.latin1(), file.latin1()); + QString orig_file = file; + int di = file.findRev(Option::dir_sep); + QDir sunworkshop42workaround = QDir::current(); + QString oldpwd = sunworkshop42workaround.currentDirPath(); + if(di != -1) { + if(!QDir::setCurrent(file.left(file.findRev(Option::dir_sep)))) { + fprintf(stderr, "Cannot find directory: %s\n", file.left(di).latin1()); + return FALSE; + } + file = file.right(file.length() - di - 1); + } parser_info pi = parser; @@ -831,8 +984,15 @@ QMakeProject::doProjectTest(const QString& func, QStringList args, QMap<QString, TestStatus sc = test_status; - bool r = read(file.latin1(), place); + bool r = FALSE; + if(!seek_var.isNull()) { + QMap<QString, QStringList> tmp; + if((r = read(file.latin1(), tmp))) + place[seek_var] += tmp[seek_var]; + } else { + r = read(file.latin1(), place); + } if(r) - vars["QMAKE_INTERNAL_INCLUDED_FILES"].append(file); + vars["QMAKE_INTERNAL_INCLUDED_FILES"].append(orig_file); else warn_msg(WarnParser, "%s:%d: Failure to include file %s.", - pi.file.latin1(), pi.line_no, file.latin1()); + pi.file.latin1(), pi.line_no, orig_file.latin1()); parser = pi; @@ -841,2 +1001,3 @@ QMakeProject::doProjectTest(const QString& func, QStringList args, QMap<QString, scope_block = sb; + QDir::setCurrent(oldpwd); return r; @@ -856,3 +1017,3 @@ QMakeProject::doProjectTest(const QString& func, QStringList args, QMap<QString, fixEnvVariables(msg); - printf("Project %s: %s\n", func.upper().latin1(), msg.latin1()); + fprintf(stderr, "Project %s: %s\n", func.upper().latin1(), msg.latin1()); if(func == "message") @@ -892,3 +1053,3 @@ QMakeProject::doProjectCheckReqs(const QStringList &deps, QMap<QString, QStringL } else { - test = isActiveConfig(chk, TRUE); + test = isActiveConfig(chk, TRUE, &place); } @@ -913,3 +1074,3 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & for(int var_begin, var_last=0; (var_begin = str.find("$$", var_last)) != -1; var_last = var_begin) { - if(var_begin >= int( str.length() + 2 ) ) { + if(var_begin >= (int)str.length() + 2) { break; @@ -922,3 +1083,3 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & int var_incr = var_begin + 2; - bool in_braces = FALSE, as_env = FALSE; + bool in_braces = FALSE, as_env = FALSE, as_prop = FALSE; if(str[var_incr] == '{') { @@ -926,3 +1087,3 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & var_incr++; - while(var_incr < int( str.length() ) && + while(var_incr < (int)str.length() && (str[var_incr] == ' ' || str[var_incr] == '\t' || str[var_incr] == '\n')) @@ -933,5 +1094,8 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & var_incr++; + } else if(str[var_incr] == '[') { + as_prop = TRUE; + var_incr++; } QString val, args; - while(var_incr < int( str.length() ) && + while(var_incr < (int)str.length() && (str[var_incr].isLetter() || str[var_incr].isNumber() || str[var_incr] == '.' || str[var_incr] == '_')) @@ -943,2 +1107,13 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & parser.file.latin1(), parser.line_no, + str.mid(var_begin, QMAX(var_incr - var_begin, + (int)str.length())).latin1(), str.latin1()); + var_begin += var_incr; + continue; + } + var_incr++; + } else if(as_prop) { + if(str[var_incr] != ']') { + var_incr++; + warn_msg(WarnParser, "%s:%d: Unterminated prop-variable replacement '%s' (%s)", + parser.file.latin1(), parser.line_no, str.mid(var_begin, QMAX(var_incr - var_begin, int(str.length()))).latin1(), str.latin1()); @@ -949,3 +1124,3 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & } else if(str[var_incr] == '(') { //args - for(int parens = 0; var_incr < int( str.length() ); var_incr++) { + for(int parens = 0; var_incr < (int)str.length(); var_incr++) { if(str[var_incr] == '(') { @@ -964,3 +1139,3 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & } - if(var_incr > int( str.length() ) || (in_braces && str[var_incr] != '}')) { + if(var_incr > (int)str.length() || (in_braces && str[var_incr] != '}')) { var_incr++; @@ -968,3 +1143,4 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & parser.file.latin1(), parser.line_no, - str.mid(var_begin, QMAX(var_incr - var_begin, int( str.length() ))).latin1(), str.latin1()); + str.mid(var_begin, QMAX(var_incr - var_begin, + (int)str.length())).latin1(), str.latin1()); var_begin += var_incr; @@ -978,2 +1154,5 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & replacement = getenv(val); + } else if(as_prop) { + if(prop) + replacement = prop->value(val); } else if(args.isEmpty()) { @@ -983,2 +1162,10 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & replacement = "\t"; + else if(val == "LITERAL_DOLLAR") + replacement = "$"; + else if(val == "LITERAL_HASH") + replacement = "#"; + else if(val == "PWD") + replacement = QDir::currentDirPath(); + else if(val == "DIR_SEPARATOR") + replacement = Option::dir_sep; else @@ -986,19 +1173,83 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & } else { - QStringList arg_list = split_arg_list(args); - for(QStringList::Iterator arit = arg_list.begin(); arit != arg_list.end(); ++arit) { - (*arit) = (*arit).stripWhiteSpace(); // blah, get rid of space - doVariableReplace((*arit), place); - } + QStringList arg_list = split_arg_list(doVariableReplace(args, place)); debug_msg(1, "Running function: %s( %s )", val.latin1(), arg_list.join("::").latin1()); if(val.lower() == "member") { - if(arg_list.count() < 1 || arg_list.count() > 2) { - fprintf(stderr, "%s:%d: member(var, place) requires two arguments.\n", + if(arg_list.count() < 1 || arg_list.count() > 3) { + fprintf(stderr, "%s:%d: member(var, start, end) requires three arguments.\n", parser.file.latin1(), parser.line_no); } else { - uint pos = 0; - if(arg_list.count() == 2) - pos = arg_list[1].toInt(); const QStringList &var = place[varMap(arg_list.first())]; - if(var.count() >= pos) - replacement = var[pos]; + int start = 0; + if(arg_list.count() >= 2) + start = arg_list[1].toInt(); + if(start < 0) + start += int(var.count()); + int end = start; + if(arg_list.count() == 3) + end = arg_list[2].toInt(); + if(end < 0) + end += int(var.count()); + if(end < start) + end = start; + for(int i = start; i <= end && (int)var.count() >= i; i++) { + if(!replacement.isEmpty()) + replacement += " "; + replacement += var[i]; + } + } + } else if(val.lower() == "fromfile") { + if(arg_list.count() != 2) { + fprintf(stderr, "%s:%d: fromfile(file, variable) requires two arguments.\n", + parser.file.latin1(), parser.line_no); + } else { + QString file = arg_list[0]; + file = Option::fixPathToLocalOS(file); + file.replace("\"", ""); + + if(QDir::isRelativePath(file)) { + QStringList include_roots; + include_roots << Option::output_dir; + QString pfilewd = QFileInfo(parser.file).dirPath(); + if(pfilewd.isEmpty()) + include_roots << pfilewd; + if(Option::output_dir != QDir::currentDirPath()) + include_roots << QDir::currentDirPath(); + for(QStringList::Iterator it = include_roots.begin(); it != include_roots.end(); ++it) { + if(QFile::exists((*it) + QDir::separator() + file)) { + file = (*it) + QDir::separator() + file; + break; + } + } + } + QString orig_file = file; + int di = file.findRev(Option::dir_sep); + QDir sunworkshop42workaround = QDir::current(); + QString oldpwd = sunworkshop42workaround.currentDirPath(); + if(di != -1 && QDir::setCurrent(file.left(file.findRev(Option::dir_sep)))) + file = file.right(file.length() - di - 1); + parser_info pi = parser; + int sb = scope_block; + int sf = scope_flag; + TestStatus sc = test_status; + QMap<QString, QStringList> tmp; + bool r = read(file.latin1(), tmp); + if(r) { + replacement = tmp[arg_list[1]].join(" "); + vars["QMAKE_INTERNAL_INCLUDED_FILES"].append(orig_file); + } else { + warn_msg(WarnParser, "%s:%d: Failure to include file %s.", + pi.file.latin1(), pi.line_no, orig_file.latin1()); + } + parser = pi; + test_status = sc; + scope_flag = sf; + scope_block = sb; + QDir::setCurrent(oldpwd); + } + } else if(val.lower() == "eval") { + for(QStringList::ConstIterator arg_it = arg_list.begin(); + arg_it != arg_list.end(); ++arg_it) { + if(!replacement.isEmpty()) + replacement += " "; + replacement += place[(*arg_it)].join(" "); } @@ -1010,3 +1261,3 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & for(QStringList::ConstIterator arg_it = arg_list.begin(); - arg_it != arg_list.end(); ++arg_it) + arg_it != arg_list.end(); ++arg_it) lst += split_value_list((*arg_it)); @@ -1028,2 +1279,20 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & } + } else if(val.lower() == "split") { + if(arg_list.count() < 2 || arg_list.count() > 3) { + fprintf(stderr, "%s:%d split(var, sep, join) requires three arguments\n", + parser.file.latin1(), parser.line_no); + } else { + QString sep = arg_list[1], join = " "; + if(arg_list.count() == 3) + join = arg_list[2]; + QStringList var = place[varMap(arg_list.first())]; + for(QStringList::Iterator vit = var.begin(); vit != var.end(); ++vit) { + QStringList lst = QStringList::split(sep, (*vit)); + for(QStringList::Iterator spltit = lst.begin(); spltit != lst.end(); ++spltit) { + if(!replacement.isEmpty()) + replacement += join; + replacement += (*spltit); + } + } + } } else if(val.lower() == "find") { @@ -1052,3 +1321,3 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & while(proc && !feof(proc)) { - int read_in = fread(buff, 1, 255, proc); + int read_in = int(fread(buff, 1, 255, proc)); if(!read_in) @@ -1063,2 +1332,47 @@ QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> & } + } else if(val.lower() == "files") { + if(arg_list.count() != 1) { + fprintf(stderr, "%s:%d files(pattern) requires one argument\n", + parser.file.latin1(), parser.line_no); + } else { + QString dir, regex = arg_list[0]; + regex = Option::fixPathToLocalOS(regex); + regex.replace("\"", ""); + if(regex.findRev(QDir::separator()) != -1) { + dir = regex.left(regex.findRev(QDir::separator()) + 1); + regex = regex.right(regex.length() - dir.length()); + } + QDir d(dir, regex); + for(int i = 0; i < (int)d.count(); i++) { + if(!replacement.isEmpty()) + replacement += " "; + replacement += dir + d[i]; + } + } + } else if(val.lower() == "prompt") { + if(arg_list.count() != 1) { + fprintf(stderr, "%s:%d prompt(question) requires one argument\n", + parser.file.latin1(), parser.line_no); + } else if(projectFile() == "-") { + fprintf(stderr, "%s:%d prompt(question) cannot be used when '-o -' is used.\n", + parser.file.latin1(), parser.line_no); + } else { + QString msg = arg_list.first(); + if((msg.startsWith("\"") || msg.startsWith("'")) && msg.endsWith(msg.left(1))) + msg = msg.mid(1, msg.length()-2); + msg.replace(QString("${QMAKE_FILE}"), parser.file.latin1()); + msg.replace(QString("${QMAKE_LINE_NUMBER}"), QString::number(parser.line_no)); + msg.replace(QString("${QMAKE_DATE}"), QDateTime::currentDateTime().toString()); + doVariableReplace(msg, place); + fixEnvVariables(msg); + if(!msg.endsWith("?")) + msg += "?"; + fprintf(stderr, "Project %s: %s ", val.upper().latin1(), msg.latin1()); + + QFile qfile; + if(qfile.open(IO_ReadOnly, stdin)) { + QTextStream t(&qfile); + replacement = t.readLine(); + } + } } else { diff --git a/qmake/project.h b/qmake/project.h index ec19f0c..0ca2a92 100644 --- a/qmake/project.h +++ b/qmake/project.h @@ -1,11 +1,9 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. +** Definition of QMakeProject class. ** -** Created : 970521 +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. -** -** This file is part of the network module of the Qt GUI Toolkit. +** This file is part of qmake. ** @@ -36,2 +34,3 @@ **********************************************************************/ + #ifndef __PROJECT_H__ @@ -43,2 +42,4 @@ +class QMakeProperty; + class QMakeProject @@ -49,2 +50,4 @@ class QMakeProject QString pfile, cfile; + QMakeProperty *prop; + void reset(); QMap<QString, QStringList> vars, base_vars, cache; @@ -58,4 +61,8 @@ public: QMakeProject(); + QMakeProject(QMakeProperty *); + + enum { ReadCache=0x01, ReadConf=0x02, ReadCmdLine=0x04, ReadProFile=0x08, ReadPostFiles=0x10, ReadAll=0xFF }; + bool read(const QString &project, const QString &pwd, uchar cmd=ReadAll); + bool read(uchar cmd=ReadAll); - bool read(const QString &project, const QString &pwd, bool just_project=FALSE); QString projectFile(); @@ -67,3 +74,3 @@ public: QMap<QString, QStringList> &variables(); - bool isActiveConfig(const QString &x, bool regex=FALSE); + bool isActiveConfig(const QString &x, bool regex=FALSE, QMap<QString, QStringList> *place=NULL); diff --git a/qmake/property.cpp b/qmake/property.cpp new file mode 100644 index 0000000..7ec1b11 --- a/dev/null +++ b/qmake/property.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** +** Implementation of QMakeProperty class. +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of qmake. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition licenses may use this +** file in accordance with the Qt Commercial License Agreement provided +** with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "property.h" +#include "option.h" +#include <qsettings.h> +#include <qdir.h> +#include <qmap.h> +#include <qstringlist.h> +#include <stdio.h> + +QStringList qmake_mkspec_paths(); //project.cpp + +QMakeProperty::QMakeProperty() : sett(NULL) +{ +} + +QMakeProperty::~QMakeProperty() +{ + delete sett;; + sett = NULL; +} + + +bool QMakeProperty::initSettings() +{ + if(sett) + return TRUE; + sett = new QSettings; + return TRUE; +} + +QString +QMakeProperty::keyBase(bool version) const +{ + QString ret = "/QMake/properties/"; + if(version) + ret += QString(qmake_version()) + "/"; + return ret; +} + + +QString +QMakeProperty::value(QString v, bool just_check) +{ + if(v == "QT_INSTALL_PREFIX") { +#ifdef QT_INSTALL_PREFIX + return QT_INSTALL_PREFIX; +#elif defined(HAVE_QCONFIG_CPP) + return qInstallPath(); +#endif + } else if(v == "QT_INSTALL_DATA") { +#ifdef QT_INSTALL_DATA + return QT_INSTALL_DATA; +#elif defined(HAVE_QCONFIG_CPP) + return qInstallPathData(); +#endif + } else if(v == "QMAKE_MKSPECS") { + return qmake_mkspec_paths().join(Option::target_mode == Option::TARG_WIN_MODE ? ";" : ":"); + } else if(v == "QMAKE_VERSION") { + return qmake_version(); + } + + if(initSettings()) { + bool ok; + int slash = v.findRev('/'); + QString ret = sett->readEntry(keyBase(slash == -1) + v, QString::null, &ok); + if(!ok) { + QString version = qmake_version(); + if(slash != -1) { + version = v.left(slash-1); + v = v.mid(slash+1); + } + QStringList subs = sett->subkeyList(keyBase(FALSE)); + subs.sort(); + for(QStringList::Iterator it = subs.fromLast(); it != subs.end(); --it) { + if((*it).isEmpty() || (*it) > version) + continue; + ret = sett->readEntry(keyBase(FALSE) + (*it) + "/" + v, QString::null, &ok); + if(ok) { + if(!just_check) + debug_msg(1, "Fell back from %s -> %s for '%s'.", version.latin1(), + (*it).latin1(), v.latin1()); + return ret; + } + } + } + return ok ? ret : QString::null; + } + return QString::null; +} + +bool +QMakeProperty::hasValue(QString v) +{ + if(initSettings()) + return !value(v, TRUE).isNull(); + return FALSE; +} + +void +QMakeProperty::setValue(QString var, const QString &val) +{ + if(initSettings()) + sett->writeEntry(keyBase() + var, val); +} + +bool +QMakeProperty::exec() +{ + bool ret = TRUE; + if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY) { + if(Option::prop::properties.isEmpty() && initSettings()) { + QStringList subs = sett->subkeyList(keyBase(FALSE)); + subs.sort(); + for(QStringList::Iterator it = subs.fromLast(); it != subs.end(); --it) { + if((*it).isEmpty()) + continue; + QStringList keys = sett->entryList(keyBase(FALSE) + (*it)); + for(QStringList::Iterator it2 = keys.begin(); it2 != keys.end(); it2++) { + QString ret = sett->readEntry(keyBase(FALSE) + (*it) + "/" + (*it2)); + if((*it) != qmake_version()) + fprintf(stdout, "%s/", (*it).latin1()); + fprintf(stdout, "%s:%s\n", (*it2).latin1(), ret.latin1()); + } + } + return TRUE; + } + for(QStringList::Iterator it = Option::prop::properties.begin(); + it != Option::prop::properties.end(); it++) { + if(Option::prop::properties.count() > 1) + fprintf(stdout, "%s:", (*it).latin1()); + if(!hasValue((*it))) { + ret = FALSE; + fprintf(stdout, "**Unknown**\n"); + } else { + fprintf(stdout, "%s\n", value((*it)).latin1()); + } + } + } else if(Option::qmake_mode == Option::QMAKE_SET_PROPERTY) { + for(QStringList::Iterator it = Option::prop::properties.begin(); + it != Option::prop::properties.end(); it++) { + QString var = (*it); + it++; + if(it == Option::prop::properties.end()) { + ret = FALSE; + break; + } + if(!var.startsWith(".")) + setValue(var, (*it)); + } + } + return ret; +} diff --git a/qmake/property.h b/qmake/property.h new file mode 100644 index 0000000..d69d47f --- a/dev/null +++ b/qmake/property.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** +** Definition of QMakeProperty class. +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of qmake. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition licenses may use this +** file in accordance with the Qt Commercial License Agreement provided +** with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#ifndef __PROPERTY_H__ +#define __PROPERTY_H__ + +#include <qstring.h> + +class QSettings; + +class QMakeProperty +{ + QSettings *sett; + QString keyBase(bool =TRUE) const; + bool initSettings(); + QString value(QString, bool just_check); +public: + QMakeProperty(); + ~QMakeProperty(); + + bool hasValue(QString); + QString value(QString v) { return value(v, FALSE); } + void setValue(QString, const QString &); + + bool exec(); +}; + +#endif /* __PROPERTY_H__ */ diff --git a/qmake/qtmd5.cpp b/qmake/qtmd5.cpp new file mode 100644 index 0000000..03c60c3 --- a/dev/null +++ b/qmake/qtmd5.cpp @@ -0,0 +1,304 @@ +/* derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm */ +#include <qstring.h> +#include "qtmd5.h" + +typedef unsigned char *POINTER; +typedef unsigned short int UINT2; +typedef unsigned long int UINT4; + +typedef struct { + UINT4 state[4]; // state(ABCD) + UINT4 count[2]; // number of bits, modulo 2^64(lsb first) + unsigned char buffer[64]; // input buffer +} MD5_CTX; + +static void MD5Init(MD5_CTX *); +static void MD5Update(MD5_CTX *, unsigned char *, unsigned int); +static void MD5Final(unsigned char [16], MD5_CTX *); +static void MD5Transform(UINT4[4], unsigned char[64]); +static void Encode(unsigned char *, UINT4 *, unsigned int); +static void Decode(UINT4 *, unsigned char *, unsigned int); +static void MD5_memset(POINTER, int, unsigned int); +static void MD5_memcpy(POINTER output,POINTER input,unsigned int len); + +// Constants for MD5Transform routine. +enum { + S11 = 7, S12 = 12, S13 = 17, S14 = 22, S21 = 5, S22 = 9, S23 = 14, S24 = 20, + S31 = 4, S32 = 11, S33 = 16, S34 = 23, S41 = 6, S42 = 10, S43 = 15, S44 = 21 +}; + +static unsigned char PADDING[64] = { + 0x80, 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 +}; + +// F, G, H and I are basic MD5 functions. +static inline UINT4 F(UINT4 x, UINT4 y, UINT4 z) +{ + return(x & y) |((~x) & z); +} + +static inline UINT4 G(UINT4 x, UINT4 y, UINT4 z) +{ + return(x & z) |(y &(~z)); +} + +static inline UINT4 H(UINT4 x, UINT4 y, UINT4 z) +{ + return x ^ y ^ z; +} + +static inline UINT4 I(UINT4 x, UINT4 y, UINT4 z) +{ + return y ^(x |(~z)); +} + +static inline UINT4 rotateLeft(UINT4 x, UINT4 n) +{ + return(x << n) |(x >>(32-(n))); +} + +// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +// Rotation is separate from addition to prevent recomputation. +static inline void FF(UINT4 &a, UINT4 b, UINT4 c, UINT4 d, UINT4 x, UINT4 s, UINT4 ac) +{ + a += F(b, c, d) + x + ac; + a = rotateLeft(a, s); + a += b; +} + +static inline void GG(UINT4 &a, UINT4 b, UINT4 c, UINT4 d, UINT4 x, UINT4 s, UINT4 ac) +{ + a += G(b, c, d) + x +(UINT4)(ac); + a = rotateLeft(a, s); + a += b; +} + +static inline void HH(UINT4 &a, UINT4 b, UINT4 c, UINT4 d, UINT4 x, UINT4 s, UINT4 ac) +{ + a += H(b, c, d) + x +(UINT4)(ac); + a = rotateLeft(a, s); + a += b; +} + +static inline void II(UINT4 &a, UINT4 b, UINT4 c, UINT4 d, UINT4 x, UINT4 s, UINT4 ac) +{ + a += I(b, c, d) + x +(UINT4)(ac); + a = rotateLeft(a, s); + a += b; +} + +// MD5 initialization. Begins an MD5 operation, writing a new context. +static void MD5Init(MD5_CTX *context) +{ + context->count[0] = context->count[1] = 0; + + // Load magic initialization constants. + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +// MD5 block update operation. Continues an MD5 message-digest +// operation, processing another message block, and updating the +// context. +static void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputLen) +{ + unsigned int i, index, partLen; + // Compute number of bytes mod 64 + index =(unsigned int)((context->count[0] >> 3) & 0x3F); + + // Update number of bits + if ((context->count[0] +=((UINT4)inputLen << 3)) <((UINT4)inputLen << 3)) + context->count[1]++; + + context->count[1] +=((UINT4)inputLen >> 29); + partLen = 64 - index; + + // Transform as many times as possible. + if (inputLen >= partLen) { + MD5_memcpy((POINTER)&context->buffer[index],(POINTER)input, partLen); + MD5Transform(context->state, context->buffer); + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform(context->state, &input[i]); + index = 0; + } else { + i = 0; + } + + // Buffer remaining input + MD5_memcpy((POINTER)&context->buffer[index],(POINTER)&input[i], + inputLen-i); +} + +// MD5 finalization. Ends an MD5 message-digest operation, writing the +// the message digest and zeroizing the context. +static void MD5Final(unsigned char digest[16], MD5_CTX *context) +{ + unsigned char bits[8]; + unsigned int index, padLen; + + // Save number of bits + Encode(bits, context->count, 8); + + // Pad out to 56 mod 64. + index =(unsigned int)((context->count[0] >> 3) & 0x3f); + padLen =(index < 56) ?(56 - index) :(120 - index); + MD5Update(context, PADDING, padLen); + + // Append length(before padding) + MD5Update(context, bits, 8); + + // Store state in digest + Encode(digest, context->state, 16); + + // Zeroize sensitive information. + MD5_memset((POINTER)context, 0, sizeof(*context)); +} + +// MD5 basic transformation. Transforms state based on block. +static void MD5Transform(UINT4 state[4], unsigned char block[64]) +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + Decode(x, block, 64); + + // Round 1 + FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + // Round 2 + GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + // Round 3 + HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + // Round 4 + II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + // Zeroize sensitive information. + MD5_memset((POINTER)x, 0, sizeof(x)); +} + +// Encodes input(UINT4) into output(unsigned char). Assumes len is a +// multiple of 4. +static void Encode(unsigned char *output, UINT4 *input, unsigned int len) +{ + unsigned int i, j; + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char) (input[i] & 0xff); + output[j+1] = (unsigned char) ((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char) ((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char) ((input[i] >> 24) & 0xff); + } +} + +// Decodes input(unsigned char) into output(UINT4). Assumes len is a +// multiple of 4. +static void Decode(UINT4 *output, unsigned char *input, unsigned int len) +{ + unsigned int i, j; + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] =((UINT4)input[j]) |(((UINT4)input[j+1]) << 8) | + (((UINT4)input[j+2]) << 16) |(((UINT4)input[j+3]) << 24); +} + +// Note: Replace "for loop" with standard memset if possible. +static void MD5_memset(POINTER output, int value, unsigned int len) +{ + unsigned int i; + for (i = 0; i < len; i++) + ((char *)output)[i] =(char)value; +} + +// Note: Replace "for loop" with standard memcpy if possible. +static void MD5_memcpy(POINTER output,POINTER input,unsigned int len) +{ + unsigned int i; + for (i = 0; i < len; i++) + output[i] = input[i]; +} + +void qtMD5(const QByteArray &src, unsigned char *digest) +{ + MD5_CTX context; + + MD5Init(&context); + MD5Update(&context, (unsigned char *) src.data(), src.size()); + MD5Final(digest, &context); +} + +QString qtMD5(const QByteArray &src) +{ + unsigned char digest[16]; + qtMD5(src, digest); + + QString output, tmp; + for (int i = 0; i < 16; ++i) + output += tmp.sprintf("%02x", digest[i]); + return output; +} diff --git a/qmake/qtmd5.h b/qmake/qtmd5.h new file mode 100644 index 0000000..c8e541b --- a/dev/null +++ b/qmake/qtmd5.h @@ -0,0 +1,11 @@ +#ifndef QTMD5_H +#define QTMD5_H +#include <qstring.h> +#include <qcstring.h> + +void qtMD5(const QByteArray &src, unsigned char *digest); +QString qtMD5(const QByteArray &src); + +#endif + + diff --git a/qmake/tools/qconfig.cpp b/qmake/tools/qconfig.cpp index 5297a4e..1a1b796 100644 --- a/qmake/tools/qconfig.cpp +++ b/qmake/tools/qconfig.cpp @@ -2,16 +2,21 @@ -static const char QT_INSTALL_PREFIX [256] = "/opt/qt-x11-free-3.1.2"; -static const char QT_INSTALL_BINS [256] = "/opt/qt-x11-free-3.1.2/bin"; -static const char QT_INSTALL_DOCS [256] = "/opt/qt-x11-free-3.1.2/doc"; -static const char QT_INSTALL_HEADERS[256] = "/opt/qt-x11-free-3.1.2/include"; -static const char QT_INSTALL_LIBS [256] = "/opt/qt-x11-free-3.1.2/lib"; -static const char QT_INSTALL_PLUGINS[256] = "/opt/qt-x11-free-3.1.2/plugins"; -static const char QT_INSTALL_DATA [256] = "/opt/qt-x11-free-3.1.2"; +static const char QT_INSTALL_PREFIX [267] = "qt_nstpath=/home/ich/programming/kde/qt-copy"; +static const char QT_INSTALL_BINS [267] = "qt_binpath=/home/ich/programming/kde/qt-copy/bin"; +static const char QT_INSTALL_DOCS [267] = "qt_docpath=/home/ich/programming/kde/qt-copy/doc"; +static const char QT_INSTALL_HEADERS [267] = "qt_hdrpath=/home/ich/programming/kde/qt-copy/include"; +static const char QT_INSTALL_LIBS [267] = "qt_libpath=/home/ich/programming/kde/qt-copy/lib"; +static const char QT_INSTALL_PLUGINS [267] = "qt_plgpath=/home/ich/programming/kde/qt-copy/plugins"; +static const char QT_INSTALL_DATA [267] = "qt_datpath=/home/ich/programming/kde/qt-copy"; +static const char QT_INSTALL_TRANSLATIONS[267] = "qt_trnpath=/home/ich/programming/kde/qt-copy/translations"; +static const char QT_INSTALL_SYSCONF [267] = "qt_cnfpath=/home/ich/programming/kde/qt-copy/etc/settings"; -const char *qInstallPath() { return QT_INSTALL_PREFIX; } -const char *qInstallPathDocs() { return QT_INSTALL_DOCS; } -const char *qInstallPathHeaders() { return QT_INSTALL_HEADERS; } -const char *qInstallPathLibs() { return QT_INSTALL_LIBS; } -const char *qInstallPathBins() { return QT_INSTALL_BINS; } -const char *qInstallPathPlugins() { return QT_INSTALL_PLUGINS; } -const char *qInstallPathData() { return QT_INSTALL_DATA; } +/* strlen( "qt_xxxpath=" ) == 11 */ +const char *qInstallPath() { return QT_INSTALL_PREFIX + 11; } +const char *qInstallPathDocs() { return QT_INSTALL_DOCS + 11; } +const char *qInstallPathHeaders() { return QT_INSTALL_HEADERS + 11; } +const char *qInstallPathLibs() { return QT_INSTALL_LIBS + 11; } +const char *qInstallPathBins() { return QT_INSTALL_BINS + 11; } +const char *qInstallPathPlugins() { return QT_INSTALL_PLUGINS + 11; } +const char *qInstallPathData() { return QT_INSTALL_DATA + 11; } +const char *qInstallPathTranslations() { return QT_INSTALL_TRANSLATIONS + 11; } +const char *qInstallPathSysconf() { return QT_INSTALL_SYSCONF + 11; } diff --git a/qmake/tools/qlocale.cpp b/qmake/tools/qlocale.cpp new file mode 100644 index 0000000..5c04288 --- a/dev/null +++ b/qmake/tools/qlocale.cpp @@ -0,0 +1,6083 @@ +/**************************************************************************** +** +** +** Implementation of the QLocale class +** +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of the tools module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include <sys/types.h> +#include <ctype.h> +#include <float.h> +#include <limits.h> +#include <math.h> +#include <stdlib.h> + +#include "qlocale.h" +#include "qlocale_p.h" + +#ifdef QT_QLOCALE_USES_FCVT +# include <qmutex.h> +#endif + +#if defined (Q_WS_WIN) +# include <windows.h> +// mingw defines NAN and INFINITY to 0/0 and x/0 +# if defined(Q_CC_GNU) +# undef NAN +# undef INFINITY +# else +# define isnan(d) _isnan(d) +# endif +#endif + +#if !defined( QWS ) && defined( Q_OS_MAC ) +# include <Carbon/Carbon.h> +#endif + +#if defined (Q_OS_SOLARIS) +# include <ieeefp.h> +#endif + +#if defined (Q_OS_OSF) && (defined(__DECC) || defined(__DECCXX)) +# define INFINITY DBL_INFINITY +# define NAN DBL_QNAN +#endif + +enum { + LittleEndian, + BigEndian + +#ifdef Q_BYTE_ORDER +# if Q_BYTE_ORDER == Q_BIG_ENDIAN + , ByteOrder = BigEndian +# elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN + , ByteOrder = LittleEndian +# else +# error "undefined byte order" +# endif +}; +#else +}; +static const unsigned int one = 1; +static const bool ByteOrder = ((*((unsigned char *) &one) == 0) ? BigEndian : LittleEndian); +#endif + +#if !defined(INFINITY) +static const unsigned char be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }; +static const unsigned char le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; +static inline double inf() +{ + return (ByteOrder == BigEndian ? + *((const double *) be_inf_bytes) : + *((const double *) le_inf_bytes)); +} +# define INFINITY (::inf()) +#endif + +#if !defined(NAN) +static const unsigned char be_nan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }; +static const unsigned char le_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; +static inline double nan() +{ + return (ByteOrder == BigEndian ? + *((const double *) be_nan_bytes) : + *((const double *) le_nan_bytes)); +} +# define NAN (::nan()) +#endif + +// Sizes as defined by the ISO C99 standard - fallback +#ifndef LLONG_MAX +# define LLONG_MAX Q_INT64_C(9223372036854775807) +#endif +#ifndef LLONG_MIN +# define LLONG_MIN (-LLONG_MAX - Q_INT64_C(1)) +#endif +#ifndef ULLONG_MAX +# define ULLONG_MAX Q_UINT64_C(0xffffffffffffffff) +#endif + +#ifndef QT_QLOCALE_USES_FCVT +static char *qdtoa(double d, int mode, int ndigits, int *decpt, + int *sign, char **rve, char **digits_str); +static double qstrtod(const char *s00, char const **se, bool *ok); +#endif +static Q_LLONG qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok); +static Q_ULLONG qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok); + +static const uint locale_index[] = { + 0, // unused + 0, // C + 0, // Abkhazian + 0, // Afan + 0, // Afar + 1, // Afrikaans + 2, // Albanian + 0, // Amharic + 3, // Arabic + 19, // Armenian + 0, // Assamese + 0, // Aymara + 20, // Azerbaijani + 0, // Bashkir + 21, // Basque + 0, // Bengali + 0, // Bhutani + 0, // Bihari + 0, // Bislama + 0, // Breton + 22, // Bulgarian + 0, // Burmese + 23, // Byelorussian + 0, // Cambodian + 24, // Catalan + 25, // Chinese + 0, // Corsican + 30, // Croatian + 31, // Czech + 32, // Danish + 33, // Dutch + 35, // English + 0, // Esperanto + 47, // Estonian + 48, // Faroese + 0, // Fiji + 49, // Finnish + 50, // French + 0, // Frisian + 0, // Gaelic + 56, // Galician + 57, // Georgian + 58, // German + 63, // Greek + 0, // Greenlandic + 0, // Guarani + 64, // Gujarati + 0, // Hausa + 65, // Hebrew + 66, // Hindi + 67, // Hungarian + 68, // Icelandic + 69, // Indonesian + 0, // Interlingua + 0, // Interlingue + 0, // Inuktitut + 0, // Inupiak + 0, // Irish + 70, // Italian + 72, // Japanese + 0, // Javanese + 73, // Kannada + 0, // Kashmiri + 74, // Kazakh + 0, // Kinyarwanda + 75, // Kirghiz + 76, // Korean + 0, // Kurdish + 0, // Kurundi + 0, // Laothian + 0, // Latin + 77, // Latvian + 0, // Lingala + 78, // Lithuanian + 79, // Macedonian + 0, // Malagasy + 80, // Malay + 0, // Malayalam + 0, // Maltese + 0, // Maori + 82, // Marathi + 0, // Moldavian + 83, // Mongolian + 0, // Nauru + 0, // Nepali + 84, // Norwegian + 0, // Occitan + 0, // Oriya + 0, // Pashto + 85, // Persian + 86, // Polish + 87, // Portuguese + 89, // Punjabi + 0, // Quechua + 0, // RhaetoRomance + 90, // Romanian + 91, // Russian + 0, // Samoan + 0, // Sangho + 92, // Sanskrit + 0, // Serbian + 0, // SerboCroatian + 0, // Sesotho + 0, // Setswana + 0, // Shona + 0, // Sindhi + 0, // Singhalese + 0, // Siswati + 93, // Slovak + 94, // Slovenian + 0, // Somali + 95, // Spanish + 0, // Sundanese + 114, // Swahili + 115, // Swedish + 0, // Tagalog + 0, // Tajik + 117, // Tamil + 0, // Tatar + 118, // Telugu + 119, // Thai + 0, // Tibetan + 0, // Tigrinya + 0, // Tonga + 0, // Tsonga + 120, // Turkish + 0, // Turkmen + 0, // Twi + 0, // Uigur + 121, // Ukrainian + 122, // Urdu + 123, // Uzbek + 124, // Vietnamese + 0, // Volapuk + 0, // Welsh + 0, // Wolof + 0, // Xhosa + 0, // Yiddish + 0, // Yoruba + 0, // Zhuang + 0, // Zulu + 0 // trailing 0 +}; + +static const QLocalePrivate locale_data[] = { +// lang terr dec group list prcnt zero minus exp + { 1, 0, 46, 44, 59, 37, 48, 45, 101 }, // C/AnyCountry + { 5, 195, 46, 44, 44, 37, 48, 45, 101 }, // Afrikaans/SouthAfrica + { 6, 2, 44, 46, 59, 37, 48, 45, 101 }, // Albanian/Albania + { 8, 186, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/SaudiArabia + { 8, 3, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Algeria + { 8, 17, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Bahrain + { 8, 64, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Egypt + { 8, 103, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Iraq + { 8, 109, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Jordan + { 8, 115, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Kuwait + { 8, 119, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Lebanon + { 8, 122, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/LibyanArabJamahiriya + { 8, 145, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Morocco + { 8, 162, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Oman + { 8, 175, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Qatar + { 8, 207, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/SyrianArabRepublic + { 8, 216, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Tunisia + { 8, 223, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/UnitedArabEmirates + { 8, 237, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Yemen + { 9, 11, 46, 44, 44, 37, 48, 45, 101 }, // Armenian/Armenia + { 12, 15, 44, 160, 59, 37, 48, 45, 101 }, // Azerbaijani/Azerbaijan + { 14, 197, 44, 46, 59, 37, 48, 45, 101 }, // Basque/Spain + { 20, 33, 44, 160, 59, 37, 48, 45, 101 }, // Bulgarian/Bulgaria + { 22, 20, 44, 160, 59, 37, 48, 45, 101 }, // Byelorussian/Belarus + { 24, 197, 44, 46, 59, 37, 48, 45, 101 }, // Catalan/Spain + { 25, 44, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/China + { 25, 97, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/HongKong + { 25, 126, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Macau + { 25, 190, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Singapore + { 25, 208, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Taiwan + { 27, 54, 44, 46, 59, 37, 48, 45, 101 }, // Croatian/Croatia + { 28, 57, 44, 160, 59, 37, 48, 45, 101 }, // Czech/CzechRepublic + { 29, 58, 44, 46, 59, 37, 48, 45, 101 }, // Danish/Denmark + { 30, 151, 44, 46, 59, 37, 48, 45, 101 }, // Dutch/Netherlands + { 30, 21, 44, 46, 59, 37, 48, 45, 101 }, // Dutch/Belgium + { 31, 225, 46, 44, 44, 37, 48, 45, 101 }, // English/UnitedStates + { 31, 13, 46, 44, 44, 37, 48, 45, 101 }, // English/Australia + { 31, 22, 46, 44, 59, 37, 48, 45, 101 }, // English/Belize + { 31, 38, 46, 44, 44, 37, 48, 45, 101 }, // English/Canada + { 31, 104, 46, 44, 44, 37, 48, 45, 101 }, // English/Ireland + { 31, 107, 46, 44, 44, 37, 48, 45, 101 }, // English/Jamaica + { 31, 154, 46, 44, 44, 37, 48, 45, 101 }, // English/NewZealand + { 31, 170, 46, 44, 44, 37, 48, 45, 101 }, // English/Philippines + { 31, 195, 46, 44, 44, 37, 48, 45, 101 }, // English/SouthAfrica + { 31, 215, 46, 44, 59, 37, 48, 45, 101 }, // English/TrinidadAndTobago + { 31, 224, 46, 44, 44, 37, 48, 45, 101 }, // English/UnitedKingdom + { 31, 240, 46, 44, 44, 37, 48, 45, 101 }, // English/Zimbabwe + { 33, 68, 44, 160, 59, 37, 48, 45, 101 }, // Estonian/Estonia + { 34, 71, 44, 46, 59, 37, 48, 45, 101 }, // Faroese/FaroeIslands + { 36, 73, 44, 160, 59, 37, 48, 45, 101 }, // Finnish/Finland + { 37, 74, 44, 160, 59, 37, 48, 45, 101 }, // French/France + { 37, 21, 44, 46, 59, 37, 48, 45, 101 }, // French/Belgium + { 37, 38, 44, 160, 59, 37, 48, 45, 101 }, // French/Canada + { 37, 125, 44, 160, 59, 37, 48, 45, 101 }, // French/Luxembourg + { 37, 142, 44, 160, 59, 37, 48, 45, 101 }, // French/Monaco + { 37, 206, 46, 39, 59, 37, 48, 45, 101 }, // French/Switzerland + { 40, 197, 44, 46, 44, 37, 48, 45, 101 }, // Galician/Spain + { 41, 81, 44, 160, 59, 37, 48, 45, 101 }, // Georgian/Georgia + { 42, 82, 44, 46, 59, 37, 48, 45, 101 }, // German/Germany + { 42, 14, 44, 46, 59, 37, 48, 45, 101 }, // German/Austria + { 42, 123, 46, 39, 59, 37, 48, 45, 101 }, // German/Liechtenstein + { 42, 125, 44, 46, 59, 37, 48, 45, 101 }, // German/Luxembourg + { 42, 206, 46, 39, 59, 37, 48, 45, 101 }, // German/Switzerland + { 43, 85, 44, 46, 59, 37, 48, 45, 101 }, // Greek/Greece + { 46, 100, 46, 44, 44, 37, 2790, 45, 101 }, // Gujarati/India + { 48, 105, 46, 44, 44, 37, 48, 45, 101 }, // Hebrew/Israel + { 49, 100, 46, 44, 44, 37, 48, 45, 101 }, // Hindi/India + { 50, 98, 44, 160, 59, 37, 48, 45, 101 }, // Hungarian/Hungary + { 51, 99, 44, 46, 59, 37, 48, 45, 101 }, // Icelandic/Iceland + { 52, 101, 44, 46, 59, 37, 48, 45, 101 }, // Indonesian/Indonesia + { 58, 106, 44, 46, 59, 37, 48, 45, 101 }, // Italian/Italy + { 58, 206, 46, 39, 59, 37, 48, 45, 101 }, // Italian/Switzerland + { 59, 108, 46, 44, 44, 37, 48, 45, 101 }, // Japanese/Japan + { 61, 100, 46, 44, 44, 37, 3302, 45, 101 }, // Kannada/India + { 63, 110, 44, 160, 59, 37, 48, 45, 101 }, // Kazakh/Kazakhstan + { 65, 116, 44, 160, 59, 37, 48, 45, 101 }, // Kirghiz/Kyrgyzstan + { 66, 114, 46, 44, 44, 37, 48, 45, 101 }, // Korean/RepublicOfKorea + { 71, 118, 44, 160, 59, 37, 48, 45, 101 }, // Latvian/Latvia + { 73, 124, 44, 46, 59, 37, 48, 45, 101 }, // Lithuanian/Lithuania + { 74, 127, 44, 46, 59, 37, 48, 45, 101 }, // Macedonian/Macedonia + { 76, 130, 44, 46, 59, 37, 48, 45, 101 }, // Malay/Malaysia + { 76, 32, 44, 46, 59, 37, 48, 45, 101 }, // Malay/BruneiDarussalam + { 80, 100, 46, 44, 44, 37, 2406, 45, 101 }, // Marathi/India + { 82, 143, 44, 160, 59, 37, 48, 45, 101 }, // Mongolian/Mongolia + { 85, 161, 44, 160, 59, 37, 48, 45, 101 }, // Norwegian/Norway + { 89, 102, 46, 44, 59, 37, 1776, 45, 101 }, // Persian/Iran + { 90, 172, 44, 160, 59, 37, 48, 45, 101 }, // Polish/Poland + { 91, 173, 44, 46, 59, 37, 48, 45, 101 }, // Portuguese/Portugal + { 91, 30, 44, 46, 59, 37, 48, 45, 101 }, // Portuguese/Brazil + { 92, 100, 46, 44, 44, 37, 2662, 45, 101 }, // Punjabi/India + { 95, 177, 44, 46, 59, 37, 48, 45, 101 }, // Romanian/Romania + { 96, 178, 44, 160, 59, 37, 48, 45, 101 }, // Russian/RussianFederation + { 99, 100, 46, 44, 44, 37, 2406, 45, 101 }, // Sanskrit/India + { 108, 191, 44, 160, 59, 37, 48, 45, 101 }, // Slovak/Slovakia + { 109, 192, 44, 46, 59, 37, 48, 45, 101 }, // Slovenian/Slovenia + { 111, 197, 44, 46, 59, 37, 48, 45, 101 }, // Spanish/Spain + { 111, 10, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Argentina + { 111, 26, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Bolivia + { 111, 43, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Chile + { 111, 47, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Colombia + { 111, 52, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/CostaRica + { 111, 61, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/DominicanRepublic + { 111, 63, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Ecuador + { 111, 65, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/ElSalvador + { 111, 90, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Guatemala + { 111, 96, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Honduras + { 111, 139, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Mexico + { 111, 155, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Nicaragua + { 111, 166, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Panama + { 111, 168, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Paraguay + { 111, 169, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Peru + { 111, 174, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/PuertoRico + { 111, 227, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Uruguay + { 111, 231, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Venezuela + { 113, 111, 46, 44, 44, 37, 48, 45, 101 }, // Swahili/Kenya + { 114, 205, 44, 160, 59, 37, 48, 45, 101 }, // Swedish/Sweden + { 114, 73, 44, 160, 59, 37, 48, 45, 101 }, // Swedish/Finland + { 117, 100, 46, 44, 44, 37, 48, 45, 101 }, // Tamil/India + { 119, 100, 46, 44, 44, 37, 3174, 45, 101 }, // Telugu/India + { 120, 211, 46, 44, 44, 37, 3664, 45, 101 }, // Thai/Thailand + { 125, 217, 44, 46, 59, 37, 48, 45, 101 }, // Turkish/Turkey + { 129, 222, 44, 160, 59, 37, 48, 45, 101 }, // Ukrainian/Ukraine + { 130, 163, 46, 44, 59, 37, 1776, 45, 101 }, // Urdu/Pakistan + { 131, 228, 44, 160, 59, 37, 48, 45, 101 }, // Uzbek/Uzbekistan + { 132, 232, 44, 46, 44, 37, 48, 45, 101 }, // Vietnamese/VietNam + { 0, 0, 0, 0, 0, 0, 0, 0, 0 } // trailing 0s +}; + +static const char language_name_list[] = +"Default\0" +"C\0" +"Abkhazian\0" +"Afan\0" +"Afar\0" +"Afrikaans\0" +"Albanian\0" +"Amharic\0" +"Arabic\0" +"Armenian\0" +"Assamese\0" +"Aymara\0" +"Azerbaijani\0" +"Bashkir\0" +"Basque\0" +"Bengali\0" +"Bhutani\0" +"Bihari\0" +"Bislama\0" +"Breton\0" +"Bulgarian\0" +"Burmese\0" +"Byelorussian\0" +"Cambodian\0" +"Catalan\0" +"Chinese\0" +"Corsican\0" +"Croatian\0" +"Czech\0" +"Danish\0" +"Dutch\0" +"English\0" +"Esperanto\0" +"Estonian\0" +"Faroese\0" +"Fiji\0" +"Finnish\0" +"French\0" +"Frisian\0" +"Gaelic\0" +"Galician\0" +"Georgian\0" +"German\0" +"Greek\0" +"Greenlandic\0" +"Guarani\0" +"Gujarati\0" +"Hausa\0" +"Hebrew\0" +"Hindi\0" +"Hungarian\0" +"Icelandic\0" +"Indonesian\0" +"Interlingua\0" +"Interlingue\0" +"Inuktitut\0" +"Inupiak\0" +"Irish\0" +"Italian\0" +"Japanese\0" +"Javanese\0" +"Kannada\0" +"Kashmiri\0" +"Kazakh\0" +"Kinyarwanda\0" +"Kirghiz\0" +"Korean\0" +"Kurdish\0" +"Kurundi\0" +"Laothian\0" +"Latin\0" +"Latvian\0" +"Lingala\0" +"Lithuanian\0" +"Macedonian\0" +"Malagasy\0" +"Malay\0" +"Malayalam\0" +"Maltese\0" +"Maori\0" +"Marathi\0" +"Moldavian\0" +"Mongolian\0" +"Nauru\0" +"Nepali\0" +"Norwegian\0" +"Occitan\0" +"Oriya\0" +"Pashto\0" +"Persian\0" +"Polish\0" +"Portuguese\0" +"Punjabi\0" +"Quechua\0" +"RhaetoRomance\0" +"Romanian\0" +"Russian\0" +"Samoan\0" +"Sangho\0" +"Sanskrit\0" +"Serbian\0" +"SerboCroatian\0" +"Sesotho\0" +"Setswana\0" +"Shona\0" +"Sindhi\0" +"Singhalese\0" +"Siswati\0" +"Slovak\0" +"Slovenian\0" +"Somali\0" +"Spanish\0" +"Sundanese\0" +"Swahili\0" +"Swedish\0" +"Tagalog\0" +"Tajik\0" +"Tamil\0" +"Tatar\0" +"Telugu\0" +"Thai\0" +"Tibetan\0" +"Tigrinya\0" +"Tonga\0" +"Tsonga\0" +"Turkish\0" +"Turkmen\0" +"Twi\0" +"Uigur\0" +"Ukrainian\0" +"Urdu\0" +"Uzbek\0" +"Vietnamese\0" +"Volapuk\0" +"Welsh\0" +"Wolof\0" +"Xhosa\0" +"Yiddish\0" +"Yoruba\0" +"Zhuang\0" +"Zulu\0"; + +static const uint language_name_index[] = { + 0, // Unused + 8, // C + 10, // Abkhazian + 20, // Afan + 25, // Afar + 30, // Afrikaans + 40, // Albanian + 49, // Amharic + 57, // Arabic + 64, // Armenian + 73, // Assamese + 82, // Aymara + 89, // Azerbaijani + 101, // Bashkir + 109, // Basque + 116, // Bengali + 124, // Bhutani + 132, // Bihari + 139, // Bislama + 147, // Breton + 154, // Bulgarian + 164, // Burmese + 172, // Byelorussian + 185, // Cambodian + 195, // Catalan + 203, // Chinese + 211, // Corsican + 220, // Croatian + 229, // Czech + 235, // Danish + 242, // Dutch + 248, // English + 256, // Esperanto + 266, // Estonian + 275, // Faroese + 283, // Fiji + 288, // Finnish + 296, // French + 303, // Frisian + 311, // Gaelic + 318, // Galician + 327, // Georgian + 336, // German + 343, // Greek + 349, // Greenlandic + 361, // Guarani + 369, // Gujarati + 378, // Hausa + 384, // Hebrew + 391, // Hindi + 397, // Hungarian + 407, // Icelandic + 417, // Indonesian + 428, // Interlingua + 440, // Interlingue + 452, // Inuktitut + 462, // Inupiak + 470, // Irish + 476, // Italian + 484, // Japanese + 493, // Javanese + 502, // Kannada + 510, // Kashmiri + 519, // Kazakh + 526, // Kinyarwanda + 538, // Kirghiz + 546, // Korean + 553, // Kurdish + 561, // Kurundi + 569, // Laothian + 578, // Latin + 584, // Latvian + 592, // Lingala + 600, // Lithuanian + 611, // Macedonian + 622, // Malagasy + 631, // Malay + 637, // Malayalam + 647, // Maltese + 655, // Maori + 661, // Marathi + 669, // Moldavian + 679, // Mongolian + 689, // Nauru + 695, // Nepali + 702, // Norwegian + 712, // Occitan + 720, // Oriya + 726, // Pashto + 733, // Persian + 741, // Polish + 748, // Portuguese + 759, // Punjabi + 767, // Quechua + 775, // RhaetoRomance + 789, // Romanian + 798, // Russian + 806, // Samoan + 813, // Sangho + 820, // Sanskrit + 829, // Serbian + 837, // SerboCroatian + 851, // Sesotho + 859, // Setswana + 868, // Shona + 874, // Sindhi + 881, // Singhalese + 892, // Siswati + 900, // Slovak + 907, // Slovenian + 917, // Somali + 924, // Spanish + 932, // Sundanese + 942, // Swahili + 950, // Swedish + 958, // Tagalog + 966, // Tajik + 972, // Tamil + 978, // Tatar + 984, // Telugu + 991, // Thai + 996, // Tibetan + 1004, // Tigrinya + 1013, // Tonga + 1019, // Tsonga + 1026, // Turkish + 1034, // Turkmen + 1042, // Twi + 1046, // Uigur + 1052, // Ukrainian + 1062, // Urdu + 1067, // Uzbek + 1073, // Vietnamese + 1084, // Volapuk + 1092, // Welsh + 1098, // Wolof + 1104, // Xhosa + 1110, // Yiddish + 1118, // Yoruba + 1125, // Zhuang + 1132 // Zulu +}; + +static const char country_name_list[] = +"Default\0" +"Afghanistan\0" +"Albania\0" +"Algeria\0" +"AmericanSamoa\0" +"Andorra\0" +"Angola\0" +"Anguilla\0" +"Antarctica\0" +"AntiguaAndBarbuda\0" +"Argentina\0" +"Armenia\0" +"Aruba\0" +"Australia\0" +"Austria\0" +"Azerbaijan\0" +"Bahamas\0" +"Bahrain\0" +"Bangladesh\0" +"Barbados\0" +"Belarus\0" +"Belgium\0" +"Belize\0" +"Benin\0" +"Bermuda\0" +"Bhutan\0" +"Bolivia\0" +"BosniaAndHerzegowina\0" +"Botswana\0" +"BouvetIsland\0" +"Brazil\0" +"BritishIndianOceanTerritory\0" +"BruneiDarussalam\0" +"Bulgaria\0" +"BurkinaFaso\0" +"Burundi\0" +"Cambodia\0" +"Cameroon\0" +"Canada\0" +"CapeVerde\0" +"CaymanIslands\0" +"CentralAfricanRepublic\0" +"Chad\0" +"Chile\0" +"China\0" +"ChristmasIsland\0" +"CocosIslands\0" +"Colombia\0" +"Comoros\0" +"DemocraticRepublicOfCongo\0" +"PeoplesRepublicOfCongo\0" +"CookIslands\0" +"CostaRica\0" +"IvoryCoast\0" +"Croatia\0" +"Cuba\0" +"Cyprus\0" +"CzechRepublic\0" +"Denmark\0" +"Djibouti\0" +"Dominica\0" +"DominicanRepublic\0" +"EastTimor\0" +"Ecuador\0" +"Egypt\0" +"ElSalvador\0" +"EquatorialGuinea\0" +"Eritrea\0" +"Estonia\0" +"Ethiopia\0" +"FalklandIslands\0" +"FaroeIslands\0" +"Fiji\0" +"Finland\0" +"France\0" +"MetropolitanFrance\0" +"FrenchGuiana\0" +"FrenchPolynesia\0" +"FrenchSouthernTerritories\0" +"Gabon\0" +"Gambia\0" +"Georgia\0" +"Germany\0" +"Ghana\0" +"Gibraltar\0" +"Greece\0" +"Greenland\0" +"Grenada\0" +"Guadeloupe\0" +"Guam\0" +"Guatemala\0" +"Guinea\0" +"GuineaBissau\0" +"Guyana\0" +"Haiti\0" +"HeardAndMcDonaldIslands\0" +"Honduras\0" +"HongKong\0" +"Hungary\0" +"Iceland\0" +"India\0" +"Indonesia\0" +"Iran\0" +"Iraq\0" +"Ireland\0" +"Israel\0" +"Italy\0" +"Jamaica\0" +"Japan\0" +"Jordan\0" +"Kazakhstan\0" +"Kenya\0" +"Kiribati\0" +"DemocraticRepublicOfKorea\0" +"RepublicOfKorea\0" +"Kuwait\0" +"Kyrgyzstan\0" +"Lao\0" +"Latvia\0" +"Lebanon\0" +"Lesotho\0" +"Liberia\0" +"LibyanArabJamahiriya\0" +"Liechtenstein\0" +"Lithuania\0" +"Luxembourg\0" +"Macau\0" +"Macedonia\0" +"Madagascar\0" +"Malawi\0" +"Malaysia\0" +"Maldives\0" +"Mali\0" +"Malta\0" +"MarshallIslands\0" +"Martinique\0" +"Mauritania\0" +"Mauritius\0" +"Mayotte\0" +"Mexico\0" +"Micronesia\0" +"Moldova\0" +"Monaco\0" +"Mongolia\0" +"Montserrat\0" +"Morocco\0" +"Mozambique\0" +"Myanmar\0" +"Namibia\0" +"Nauru\0" +"Nepal\0" +"Netherlands\0" +"NetherlandsAntilles\0" +"NewCaledonia\0" +"NewZealand\0" +"Nicaragua\0" +"Niger\0" +"Nigeria\0" +"Niue\0" +"NorfolkIsland\0" +"NorthernMarianaIslands\0" +"Norway\0" +"Oman\0" +"Pakistan\0" +"Palau\0" +"PalestinianTerritory\0" +"Panama\0" +"PapuaNewGuinea\0" +"Paraguay\0" +"Peru\0" +"Philippines\0" +"Pitcairn\0" +"Poland\0" +"Portugal\0" +"PuertoRico\0" +"Qatar\0" +"Reunion\0" +"Romania\0" +"RussianFederation\0" +"Rwanda\0" +"SaintKittsAndNevis\0" +"StLucia\0" +"StVincentAndTheGrenadines\0" +"Samoa\0" +"SanMarino\0" +"SaoTomeAndPrincipe\0" +"SaudiArabia\0" +"Senegal\0" +"Seychelles\0" +"SierraLeone\0" +"Singapore\0" +"Slovakia\0" +"Slovenia\0" +"SolomonIslands\0" +"Somalia\0" +"SouthAfrica\0" +"SouthGeorgiaAndTheSouthSandwichIslands\0" +"Spain\0" +"SriLanka\0" +"StHelena\0" +"StPierreAndMiquelon\0" +"Sudan\0" +"Suriname\0" +"SvalbardAndJanMayenIslands\0" +"Swaziland\0" +"Sweden\0" +"Switzerland\0" +"SyrianArabRepublic\0" +"Taiwan\0" +"Tajikistan\0" +"Tanzania\0" +"Thailand\0" +"Togo\0" +"Tokelau\0" +"Tonga\0" +"TrinidadAndTobago\0" +"Tunisia\0" +"Turkey\0" +"Turkmenistan\0" +"TurksAndCaicosIslands\0" +"Tuvalu\0" +"Uganda\0" +"Ukraine\0" +"UnitedArabEmirates\0" +"UnitedKingdom\0" +"UnitedStates\0" +"UnitedStatesMinorOutlyingIslands\0" +"Uruguay\0" +"Uzbekistan\0" +"Vanuatu\0" +"VaticanCityState\0" +"Venezuela\0" +"VietNam\0" +"BritishVirginIslands\0" +"USVirginIslands\0" +"WallisAndFutunaIslands\0" +"WesternSahara\0" +"Yemen\0" +"Yugoslavia\0" +"Zambia\0" +"Zimbabwe\0"; + +static const uint country_name_index[] = { + 0, // AnyCountry + 8, // Afghanistan + 20, // Albania + 28, // Algeria + 36, // AmericanSamoa + 50, // Andorra + 58, // Angola + 65, // Anguilla + 74, // Antarctica + 85, // AntiguaAndBarbuda + 103, // Argentina + 113, // Armenia + 121, // Aruba + 127, // Australia + 137, // Austria + 145, // Azerbaijan + 156, // Bahamas + 164, // Bahrain + 172, // Bangladesh + 183, // Barbados + 192, // Belarus + 200, // Belgium + 208, // Belize + 215, // Benin + 221, // Bermuda + 229, // Bhutan + 236, // Bolivia + 244, // BosniaAndHerzegowina + 265, // Botswana + 274, // BouvetIsland + 287, // Brazil + 294, // BritishIndianOceanTerritory + 322, // BruneiDarussalam + 339, // Bulgaria + 348, // BurkinaFaso + 360, // Burundi + 368, // Cambodia + 377, // Cameroon + 386, // Canada + 393, // CapeVerde + 403, // CaymanIslands + 417, // CentralAfricanRepublic + 440, // Chad + 445, // Chile + 451, // China + 457, // ChristmasIsland + 473, // CocosIslands + 486, // Colombia + 495, // Comoros + 503, // DemocraticRepublicOfCongo + 529, // PeoplesRepublicOfCongo + 552, // CookIslands + 564, // CostaRica + 574, // IvoryCoast + 585, // Croatia + 593, // Cuba + 598, // Cyprus + 605, // CzechRepublic + 619, // Denmark + 627, // Djibouti + 636, // Dominica + 645, // DominicanRepublic + 663, // EastTimor + 673, // Ecuador + 681, // Egypt + 687, // ElSalvador + 698, // EquatorialGuinea + 715, // Eritrea + 723, // Estonia + 731, // Ethiopia + 740, // FalklandIslands + 756, // FaroeIslands + 769, // Fiji + 774, // Finland + 782, // France + 789, // MetropolitanFrance + 808, // FrenchGuiana + 821, // FrenchPolynesia + 837, // FrenchSouthernTerritories + 863, // Gabon + 869, // Gambia + 876, // Georgia + 884, // Germany + 892, // Ghana + 898, // Gibraltar + 908, // Greece + 915, // Greenland + 925, // Grenada + 933, // Guadeloupe + 944, // Guam + 949, // Guatemala + 959, // Guinea + 966, // GuineaBissau + 979, // Guyana + 986, // Haiti + 992, // HeardAndMcDonaldIslands + 1016, // Honduras + 1025, // HongKong + 1034, // Hungary + 1042, // Iceland + 1050, // India + 1056, // Indonesia + 1066, // Iran + 1071, // Iraq + 1076, // Ireland + 1084, // Israel + 1091, // Italy + 1097, // Jamaica + 1105, // Japan + 1111, // Jordan + 1118, // Kazakhstan + 1129, // Kenya + 1135, // Kiribati + 1144, // DemocraticRepublicOfKorea + 1170, // RepublicOfKorea + 1186, // Kuwait + 1193, // Kyrgyzstan + 1204, // Lao + 1208, // Latvia + 1215, // Lebanon + 1223, // Lesotho + 1231, // Liberia + 1239, // LibyanArabJamahiriya + 1260, // Liechtenstein + 1274, // Lithuania + 1284, // Luxembourg + 1295, // Macau + 1301, // Macedonia + 1311, // Madagascar + 1322, // Malawi + 1329, // Malaysia + 1338, // Maldives + 1347, // Mali + 1352, // Malta + 1358, // MarshallIslands + 1374, // Martinique + 1385, // Mauritania + 1396, // Mauritius + 1406, // Mayotte + 1414, // Mexico + 1421, // Micronesia + 1432, // Moldova + 1440, // Monaco + 1447, // Mongolia + 1456, // Montserrat + 1467, // Morocco + 1475, // Mozambique + 1486, // Myanmar + 1494, // Namibia + 1502, // Nauru + 1508, // Nepal + 1514, // Netherlands + 1526, // NetherlandsAntilles + 1546, // NewCaledonia + 1559, // NewZealand + 1570, // Nicaragua + 1580, // Niger + 1586, // Nigeria + 1594, // Niue + 1599, // NorfolkIsland + 1613, // NorthernMarianaIslands + 1636, // Norway + 1643, // Oman + 1648, // Pakistan + 1657, // Palau + 1663, // PalestinianTerritory + 1684, // Panama + 1691, // PapuaNewGuinea + 1706, // Paraguay + 1715, // Peru + 1720, // Philippines + 1732, // Pitcairn + 1741, // Poland + 1748, // Portugal + 1757, // PuertoRico + 1768, // Qatar + 1774, // Reunion + 1782, // Romania + 1790, // RussianFederation + 1808, // Rwanda + 1815, // SaintKittsAndNevis + 1834, // StLucia + 1842, // StVincentAndTheGrenadines + 1868, // Samoa + 1874, // SanMarino + 1884, // SaoTomeAndPrincipe + 1903, // SaudiArabia + 1915, // Senegal + 1923, // Seychelles + 1934, // SierraLeone + 1946, // Singapore + 1956, // Slovakia + 1965, // Slovenia + 1974, // SolomonIslands + 1989, // Somalia + 1997, // SouthAfrica + 2009, // SouthGeorgiaAndTheSouthSandwichIslands + 2048, // Spain + 2054, // SriLanka + 2063, // StHelena + 2072, // StPierreAndMiquelon + 2092, // Sudan + 2098, // Suriname + 2107, // SvalbardAndJanMayenIslands + 2134, // Swaziland + 2144, // Sweden + 2151, // Switzerland + 2163, // SyrianArabRepublic + 2182, // Taiwan + 2189, // Tajikistan + 2200, // Tanzania + 2209, // Thailand + 2218, // Togo + 2223, // Tokelau + 2231, // Tonga + 2237, // TrinidadAndTobago + 2255, // Tunisia + 2263, // Turkey + 2270, // Turkmenistan + 2283, // TurksAndCaicosIslands + 2305, // Tuvalu + 2312, // Uganda + 2319, // Ukraine + 2327, // UnitedArabEmirates + 2346, // UnitedKingdom + 2360, // UnitedStates + 2373, // UnitedStatesMinorOutlyingIslands + 2406, // Uruguay + 2414, // Uzbekistan + 2425, // Vanuatu + 2433, // VaticanCityState + 2450, // Venezuela + 2460, // VietNam + 2468, // BritishVirginIslands + 2489, // USVirginIslands + 2505, // WallisAndFutunaIslands + 2528, // WesternSahara + 2542, // Yemen + 2548, // Yugoslavia + 2559, // Zambia + 2566 // Zimbabwe +}; + +static const char language_code_list[] = +" " // Unused +" " // C +"ab" // Abkhazian +"om" // Afan +"aa" // Afar +"af" // Afrikaans +"sq" // Albanian +"am" // Amharic +"ar" // Arabic +"hy" // Armenian +"as" // Assamese +"ay" // Aymara +"az" // Azerbaijani +"ba" // Bashkir +"eu" // Basque +"bn" // Bengali +"dz" // Bhutani +"bh" // Bihari +"bi" // Bislama +"br" // Breton +"bg" // Bulgarian +"my" // Burmese +"be" // Byelorussian +"km" // Cambodian +"ca" // Catalan +"zh" // Chinese +"co" // Corsican +"hr" // Croatian +"cs" // Czech +"da" // Danish +"nl" // Dutch +"en" // English +"eo" // Esperanto +"et" // Estonian +"fo" // Faroese +"fj" // Fiji +"fi" // Finnish +"fr" // French +"fy" // Frisian +"gd" // Gaelic +"gl" // Galician +"ka" // Georgian +"de" // German +"el" // Greek +"kl" // Greenlandic +"gn" // Guarani +"gu" // Gujarati +"ha" // Hausa +"he" // Hebrew +"hi" // Hindi +"hu" // Hungarian +"is" // Icelandic +"id" // Indonesian +"ia" // Interlingua +"ie" // Interlingue +"iu" // Inuktitut +"ik" // Inupiak +"ga" // Irish +"it" // Italian +"ja" // Japanese +"jv" // Javanese +"kn" // Kannada +"ks" // Kashmiri +"kk" // Kazakh +"rw" // Kinyarwanda +"ky" // Kirghiz +"ko" // Korean +"ku" // Kurdish +"rn" // Kurundi +"lo" // Laothian +"la" // Latin +"lv" // Latvian +"ln" // Lingala +"lt" // Lithuanian +"mk" // Macedonian +"mg" // Malagasy +"ms" // Malay +"ml" // Malayalam +"mt" // Maltese +"mi" // Maori +"mr" // Marathi +"mo" // Moldavian +"mn" // Mongolian +"na" // Nauru +"ne" // Nepali +"no" // Norwegian +"oc" // Occitan +"or" // Oriya +"ps" // Pashto +"fa" // Persian +"pl" // Polish +"pt" // Portuguese +"pa" // Punjabi +"qu" // Quechua +"rm" // RhaetoRomance +"ro" // Romanian +"ru" // Russian +"sm" // Samoan +"sg" // Sangho +"sa" // Sanskrit +"sr" // Serbian +"sh" // SerboCroatian +"st" // Sesotho +"tn" // Setswana +"sn" // Shona +"sd" // Sindhi +"si" // Singhalese +"ss" // Siswati +"sk" // Slovak +"sl" // Slovenian +"so" // Somali +"es" // Spanish +"su" // Sundanese +"sw" // Swahili +"sv" // Swedish +"tl" // Tagalog +"tg" // Tajik +"ta" // Tamil +"tt" // Tatar +"te" // Telugu +"th" // Thai +"bo" // Tibetan +"ti" // Tigrinya +"to" // Tonga +"ts" // Tsonga +"tr" // Turkish +"tk" // Turkmen +"tw" // Twi +"ug" // Uigur +"uk" // Ukrainian +"ur" // Urdu +"uz" // Uzbek +"vi" // Vietnamese +"vo" // Volapuk +"cy" // Welsh +"wo" // Wolof +"xh" // Xhosa +"yi" // Yiddish +"yo" // Yoruba +"za" // Zhuang +"zu" // Zulu +; + +static const char country_code_list[] = +" " // AnyLanguage +"AF" // Afghanistan +"AL" // Albania +"DZ" // Algeria +"AS" // AmericanSamoa +"AD" // Andorra +"AO" // Angola +"AI" // Anguilla +"AQ" // Antarctica +"AG" // AntiguaAndBarbuda +"AR" // Argentina +"AM" // Armenia +"AW" // Aruba +"AU" // Australia +"AT" // Austria +"AZ" // Azerbaijan +"BS" // Bahamas +"BH" // Bahrain +"BD" // Bangladesh +"BB" // Barbados +"BY" // Belarus +"BE" // Belgium +"BZ" // Belize +"BJ" // Benin +"BM" // Bermuda +"BT" // Bhutan +"BO" // Bolivia +"BA" // BosniaAndHerzegowina +"BW" // Botswana +"BV" // BouvetIsland +"BR" // Brazil +"IO" // BritishIndianOceanTerritory +"BN" // BruneiDarussalam +"BG" // Bulgaria +"BF" // BurkinaFaso +"BI" // Burundi +"KH" // Cambodia +"CM" // Cameroon +"CA" // Canada +"CV" // CapeVerde +"KY" // CaymanIslands +"CF" // CentralAfricanRepublic +"TD" // Chad +"CL" // Chile +"CN" // China +"CX" // ChristmasIsland +"CC" // CocosIslands +"CO" // Colombia +"KM" // Comoros +"CD" // DemocraticRepublicOfCongo +"CG" // PeoplesRepublicOfCongo +"CK" // CookIslands +"CR" // CostaRica +"CI" // IvoryCoast +"HR" // Croatia +"CU" // Cuba +"CY" // Cyprus +"CZ" // CzechRepublic +"DK" // Denmark +"DJ" // Djibouti +"DM" // Dominica +"DO" // DominicanRepublic +"TL" // EastTimor +"EC" // Ecuador +"EG" // Egypt +"SV" // ElSalvador +"GQ" // EquatorialGuinea +"ER" // Eritrea +"EE" // Estonia +"ET" // Ethiopia +"FK" // FalklandIslands +"FO" // FaroeIslands +"FJ" // Fiji +"FI" // Finland +"FR" // France +"FX" // MetropolitanFrance +"GF" // FrenchGuiana +"PF" // FrenchPolynesia +"TF" // FrenchSouthernTerritories +"GA" // Gabon +"GM" // Gambia +"GE" // Georgia +"DE" // Germany +"GH" // Ghana +"GI" // Gibraltar +"GR" // Greece +"GL" // Greenland +"GD" // Grenada +"GP" // Guadeloupe +"GU" // Guam +"GT" // Guatemala +"GN" // Guinea +"GW" // GuineaBissau +"GY" // Guyana +"HT" // Haiti +"HM" // HeardAndMcDonaldIslands +"HN" // Honduras +"HK" // HongKong +"HU" // Hungary +"IS" // Iceland +"IN" // India +"ID" // Indonesia +"IR" // Iran +"IQ" // Iraq +"IE" // Ireland +"IL" // Israel +"IT" // Italy +"JM" // Jamaica +"JP" // Japan +"JO" // Jordan +"KZ" // Kazakhstan +"KE" // Kenya +"KI" // Kiribati +"KP" // DemocraticRepublicOfKorea +"KR" // RepublicOfKorea +"KW" // Kuwait +"KG" // Kyrgyzstan +"LA" // Lao +"LV" // Latvia +"LB" // Lebanon +"LS" // Lesotho +"LR" // Liberia +"LY" // LibyanArabJamahiriya +"LI" // Liechtenstein +"LT" // Lithuania +"LU" // Luxembourg +"MO" // Macau +"MK" // Macedonia +"MG" // Madagascar +"MW" // Malawi +"MY" // Malaysia +"MV" // Maldives +"ML" // Mali +"MT" // Malta +"MH" // MarshallIslands +"MQ" // Martinique +"MR" // Mauritania +"MU" // Mauritius +"YT" // Mayotte +"MX" // Mexico +"FM" // Micronesia +"MD" // Moldova +"MC" // Monaco +"MN" // Mongolia +"MS" // Montserrat +"MA" // Morocco +"MZ" // Mozambique +"MM" // Myanmar +"NA" // Namibia +"NR" // Nauru +"NP" // Nepal +"NL" // Netherlands +"AN" // NetherlandsAntilles +"NC" // NewCaledonia +"NZ" // NewZealand +"NI" // Nicaragua +"NE" // Niger +"NG" // Nigeria +"NU" // Niue +"NF" // NorfolkIsland +"MP" // NorthernMarianaIslands +"NO" // Norway +"OM" // Oman +"PK" // Pakistan +"PW" // Palau +"PS" // PalestinianTerritory +"PA" // Panama +"PG" // PapuaNewGuinea +"PY" // Paraguay +"PE" // Peru +"PH" // Philippines +"PN" // Pitcairn +"PL" // Poland +"PT" // Portugal +"PR" // PuertoRico +"QA" // Qatar +"RE" // Reunion +"RO" // Romania +"RU" // RussianFederation +"RW" // Rwanda +"KN" // SaintKittsAndNevis +"LC" // StLucia +"VC" // StVincentAndTheGrenadines +"WS" // Samoa +"SM" // SanMarino +"ST" // SaoTomeAndPrincipe +"SA" // SaudiArabia +"SN" // Senegal +"SC" // Seychelles +"SL" // SierraLeone +"SG" // Singapore +"SK" // Slovakia +"SI" // Slovenia +"SB" // SolomonIslands +"SO" // Somalia +"ZA" // SouthAfrica +"GS" // SouthGeorgiaAndTheSouthSandwichIslands +"ES" // Spain +"LK" // SriLanka +"SH" // StHelena +"PM" // StPierreAndMiquelon +"SD" // Sudan +"SR" // Suriname +"SJ" // SvalbardAndJanMayenIslands +"SZ" // Swaziland +"SE" // Sweden +"CH" // Switzerland +"SY" // SyrianArabRepublic +"TW" // Taiwan +"TJ" // Tajikistan +"TZ" // Tanzania +"TH" // Thailand +"TG" // Togo +"TK" // Tokelau +"TO" // Tonga +"TT" // TrinidadAndTobago +"TN" // Tunisia +"TR" // Turkey +"TM" // Turkmenistan +"TC" // TurksAndCaicosIslands +"TV" // Tuvalu +"UG" // Uganda +"UA" // Ukraine +"AE" // UnitedArabEmirates +"GB" // UnitedKingdom +"US" // UnitedStates +"UM" // UnitedStatesMinorOutlyingIslands +"UY" // Uruguay +"UZ" // Uzbekistan +"VU" // Vanuatu +"VA" // VaticanCityState +"VE" // Venezuela +"VN" // VietNam +"VG" // BritishVirginIslands +"VI" // USVirginIslands +"WF" // WallisAndFutunaIslands +"EH" // WesternSahara +"YE" // Yemen +"YU" // Yugoslavia +"ZM" // Zambia +"ZW" // Zimbabwe +; + +static QLocale::Language codeToLanguage(const QString &code) +{ + if (code.length() != 2) + return QLocale::C; + + ushort uc1 = code.unicode()[0].unicode(); + ushort uc2 = code.unicode()[1].unicode(); + + const char *c = language_code_list; + for (; *c != 0; c += 2) { + if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1]) + return (QLocale::Language) ((c - language_code_list)/2); + } + + return QLocale::C; +} + +static QLocale::Country codeToCountry(const QString &code) +{ + if (code.length() != 2) + return QLocale::AnyCountry; + + ushort uc1 = code.unicode()[0].unicode(); + ushort uc2 = code.unicode()[1].unicode(); + + const char *c = country_code_list; + for (; *c != 0; c += 2) { + if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1]) + return (QLocale::Country) ((c - country_code_list)/2); + } + + return QLocale::AnyCountry; +} + +static QString languageToCode(QLocale::Language language) +{ + if (language == QLocale::C) + return "C"; + + QString code; + code.setLength(2); + const char *c = language_code_list + 2*(uint)language; + code[0] = c[0]; + code[1] = c[1]; + return code; +} + +static QString countryToCode(QLocale::Country country) +{ + if (country == QLocale::AnyCountry) + return QString::null; + + QString code; + code.setLength(2); + const char *c = country_code_list + 2*(uint)country; + code[0] = c[0]; + code[1] = c[1]; + return code; +} + +const QLocalePrivate *QLocale::default_d = 0; + +QString QLocalePrivate::infinity() const +{ + return QString::fromLatin1("inf"); +} + +QString QLocalePrivate::nan() const +{ + return QString::fromLatin1("nan"); +} + +const char* QLocalePrivate::systemLocaleName() +{ + static QCString lang; + lang = getenv( "LANG" ); + +#if !defined( QWS ) && defined( Q_OS_MAC ) + if ( !lang.isEmpty() ) + return lang; + + char mac_ret[255]; + if(!LocaleRefGetPartString(NULL, kLocaleLanguageMask | kLocaleRegionMask, 255, mac_ret)) + lang = mac_ret; +#endif + +#if defined(Q_WS_WIN) + if ( !lang.isEmpty() ) + return lang; + + QT_WA( { + wchar_t out[256]; + QString language; + QString sublanguage; + if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME , out, 255 ) ) + language = QString::fromUcs2( (ushort*)out ); + if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) ) + sublanguage = QString::fromUcs2( (ushort*)out ).lower(); + lang = language; + if ( sublanguage != language && !sublanguage.isEmpty() ) + lang += "_" + sublanguage; + } , { + char out[256]; + QString language; + QString sublanguage; + if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, out, 255 ) ) + language = QString::fromLocal8Bit( out ); + if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) ) + sublanguage = QString::fromLocal8Bit( out ).lower(); + lang = language; + if ( sublanguage != language && !sublanguage.isEmpty() ) + lang += "_" + sublanguage; + } ); +#endif + if ( lang.isEmpty() ) + lang = "C"; + + return lang; +} + +static const QLocalePrivate *findLocale(QLocale::Language language, + QLocale::Country country) +{ + unsigned language_id = (unsigned)language; + unsigned country_id = (unsigned)country; + + uint idx = locale_index[language_id]; + + const QLocalePrivate *d = locale_data + idx; + + if (idx == 0) // default language has no associated country + return d; + + if (country == QLocale::AnyCountry) + return d; + + Q_ASSERT(d->languageId() == language_id); + + while (d->languageId() == language_id + && d->countryId() != country_id) + ++d; + + if (d->countryId() == country_id + && d->languageId() == language_id) + return d; + + return locale_data + idx; +} + +/*! + \class QLocale + \brief The QLocale class converts between numbers and their + string representations in various languages. + + \reentrant + \ingroup text + + It is initialized with a country/language pair in its constructor + and offers number-to-string and string-to-number conversion + functions simmilar to those in QString. + + \code + QLocale egyptian(QLocale::Arabic, QLocale::Egypt); + QString s1 = egyptian.toString(1.571429E+07, 'e'); + QString s2 = egyptian.toString(10); + + double d = egyptian.toDouble(s1); + int s2 = egyptian.toInt(s2); + \endcode + + QLocale supports the concept of a default locale, which is + determined from the system's locale settings at application + startup. The default locale can be changed by calling the + static member setDefault(). The default locale has the + following effects: + + \list + \i If a QLocale object is constructed with the default constructor, + it will use the default locale's settings. + \i QString::toDouble() interprets the string according to the default + locale. If this fails, it falls back on the "C" locale. + \i QString::arg() uses the default locale to format a number when + its position specifier in the format string contains an 'L', + e.g. "%L1". + \endlist + + \code + QLocale::setDefault(QLocale::Hebrew, QLocale::Israel); + QLocale hebrew; // Constructs a default QLocale + QString s1 = hebrew.toString(15714.3, 'e'); + + bool ok; + double d; + + QLocale::setDefault(QLocale::C); + d = QString( "1234,56" ).toDouble(&ok); // ok == false + d = QString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 + + QLocale::setDefault(QLocale::German); + d = QString( "1234,56" ).toDouble(&ok); // ok == true, d == 1234.56 + d = QString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56 + + QLocale::setDefault(QLocale::English, QLocale::UnitedStates); + str = QString( "%1 %L2 %L3" ) + .arg( 12345 ) + .arg( 12345 ) + .arg( 12345, 0, 16 ); + // str == "12345 12,345 3039" + \endcode + + When a language/country pair is specified in the constructor, one + of three things can happen: + + \list + \i If the language/country pair is found in the database, it is used. + \i If the language is found but the country is not, or if the country + is \c AnyCountry, the language is used with the most + appropriate available country (for example, Germany for German), + \i If neither the language nor the country are found, QLocale + defaults to the default locale (see setDefault()). + \endlist + + The "C" locale is identical to English/UnitedStates. + + Use language() and country() to determine the actual language and + country values used. + + An alternative method for constructing a QLocale object is by + specifying the locale name. + + \code + QLocale korean("ko"); + QLocale swiss("de_CH"); + \endcode + + This constructor converts the locale name to a language/country + pair; it does not use the system locale database. + + All the methods in QLocale, with the exception of setDefault(), + are reentrant. + + \sa QString::toDouble() QString::arg() + + The double-to-string and string-to-double conversion functions are + covered by the following licenses: + + \legalese + + Copyright (c) 1991 by AT&T. + + Permission to use, copy, modify, and distribute this software for any + purpose without fee is hereby granted, provided that this entire notice + is included in all copies of any software which is or includes a copy + or modification of this software and in all copies of the supporting + documentation for such software. + + THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY + REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + + This product includes software developed by the University of + California, Berkeley and its contributors. +*/ + +/*! + \enum QLocale::Language + + This enumerated type is used to specify a language. + + \value C Identical to English/UnitedStates + \value Abkhazian + \value Afan + \value Afar + \value Afrikaans + \value Albanian + \value Amharic + \value Arabic + \value Armenian + \value Assamese + \value Aymara + \value Azerbaijani + \value Bashkir + \value Basque + \value Bengali + \value Bhutani + \value Bihari + \value Bislama + \value Breton + \value Bulgarian + \value Burmese + \value Byelorussian + \value Cambodian + \value Catalan + \value Chinese + \value Corsican + \value Croatian + \value Czech + \value Danish + \value Dutch + \value English + \value Esperanto + \value Estonian + \value Faroese + \value FijiLanguage + \value Finnish + \value French + \value Frisian + \value Gaelic + \value Galician + \value Georgian + \value German + \value Greek + \value Greenlandic + \value Guarani + \value Gujarati + \value Hausa + \value Hebrew + \value Hindi + \value Hungarian + \value Icelandic + \value Indonesian + \value Interlingua + \value Interlingue + \value Inuktitut + \value Inupiak + \value Irish + \value Italian + \value Japanese + \value Javanese + \value Kannada + \value Kashmiri + \value Kazakh + \value Kinyarwanda + \value Kirghiz + \value Korean + \value Kurdish + \value Kurundi + \value Laothian + \value Latin + \value Latvian + \value Lingala + \value Lithuanian + \value Macedonian + \value Malagasy + \value Malay + \value Malayalam + \value Maltese + \value Maori + \value Marathi + \value Moldavian + \value Mongolian + \value NauruLanguage + \value Nepali + \value Norwegian + \value Occitan + \value Oriya + \value Pashto + \value Persian + \value Polish + \value Portuguese + \value Punjabi + \value Quechua + \value RhaetoRomance + \value Romanian + \value Russian + \value Samoan + \value Sangho + \value Sanskrit + \value Serbian + \value SerboCroatian + \value Sesotho + \value Setswana + \value Shona + \value Sindhi + \value Singhalese + \value Siswati + \value Slovak + \value Slovenian + \value Somali + \value Spanish + \value Sundanese + \value Swahili + \value Swedish + \value Tagalog + \value Tajik + \value Tamil + \value Tatar + \value Telugu + \value Thai + \value Tibetan + \value Tigrinya + \value TongaLanguage + \value Tsonga + \value Turkish + \value Turkmen + \value Twi + \value Uigur + \value Ukrainian + \value Urdu + \value Uzbek + \value Vietnamese + \value Volapuk + \value Welsh + \value Wolof + \value Xhosa + \value Yiddish + \value Yoruba + \value Zhuang + \value Zulu +*/ + +/*! + \enum QLocale::Country + + This enumerated type is used to specify a country. + + \value AnyCountry + \value Afghanistan + \value Albania + \value Algeria + \value AmericanSamoa + \value Andorra + \value Angola + \value Anguilla + \value Antarctica + \value AntiguaAndBarbuda + \value Argentina + \value Armenia + \value Aruba + \value Australia + \value Austria + \value Azerbaijan + \value Bahamas + \value Bahrain + \value Bangladesh + \value Barbados + \value Belarus + \value Belgium + \value Belize + \value Benin + \value Bermuda + \value Bhutan + \value Bolivia + \value BosniaAndHerzegowina + \value Botswana + \value BouvetIsland + \value Brazil + \value BritishIndianOceanTerritory + \value BruneiDarussalam + \value Bulgaria + \value BurkinaFaso + \value Burundi + \value Cambodia + \value Cameroon + \value Canada + \value CapeVerde + \value CaymanIslands + \value CentralAfricanRepublic + \value Chad + \value Chile + \value China + \value ChristmasIsland + \value CocosIslands + \value Colombia + \value Comoros + \value DemocraticRepublicOfCongo + \value PeoplesRepublicOfCongo + \value CookIslands + \value CostaRica + \value IvoryCoast + \value Croatia + \value Cuba + \value Cyprus + \value CzechRepublic + \value Denmark + \value Djibouti + \value Dominica + \value DominicanRepublic + \value EastTimor + \value Ecuador + \value Egypt + \value ElSalvador + \value EquatorialGuinea + \value Eritrea + \value Estonia + \value Ethiopia + \value FalklandIslands + \value FaroeIslands + \value FijiCountry + \value Finland + \value France + \value MetropolitanFrance + \value FrenchGuiana + \value FrenchPolynesia + \value FrenchSouthernTerritories + \value Gabon + \value Gambia + \value Georgia + \value Germany + \value Ghana + \value Gibraltar + \value Greece + \value Greenland + \value Grenada + \value Guadeloupe + \value Guam + \value Guatemala + \value Guinea + \value GuineaBissau + \value Guyana + \value Haiti + \value HeardAndMcDonaldIslands + \value Honduras + \value HongKong + \value Hungary + \value Iceland + \value India + \value Indonesia + \value Iran + \value Iraq + \value Ireland + \value Israel + \value Italy + \value Jamaica + \value Japan + \value Jordan + \value Kazakhstan + \value Kenya + \value Kiribati + \value DemocraticRepublicOfKorea + \value RepublicOfKorea + \value Kuwait + \value Kyrgyzstan + \value Lao + \value Latvia + \value Lebanon + \value Lesotho + \value Liberia + \value LibyanArabJamahiriya + \value Liechtenstein + \value Lithuania + \value Luxembourg + \value Macau + \value Macedonia + \value Madagascar + \value Malawi + \value Malaysia + \value Maldives + \value Mali + \value Malta + \value MarshallIslands + \value Martinique + \value Mauritania + \value Mauritius + \value Mayotte + \value Mexico + \value Micronesia + \value Moldova + \value Monaco + \value Mongolia + \value Montserrat + \value Morocco + \value Mozambique + \value Myanmar + \value Namibia + \value NauruCountry + \value Nepal + \value Netherlands + \value NetherlandsAntilles + \value NewCaledonia + \value NewZealand + \value Nicaragua + \value Niger + \value Nigeria + \value Niue + \value NorfolkIsland + \value NorthernMarianaIslands + \value Norway + \value Oman + \value Pakistan + \value Palau + \value PalestinianTerritory + \value Panama + \value PapuaNewGuinea + \value Paraguay + \value Peru + \value Philippines + \value Pitcairn + \value Poland + \value Portugal + \value PuertoRico + \value Qatar + \value Reunion + \value Romania + \value RussianFederation + \value Rwanda + \value SaintKittsAndNevis + \value StLucia + \value StVincentAndTheGrenadines + \value Samoa + \value SanMarino + \value SaoTomeAndPrincipe + \value SaudiArabia + \value Senegal + \value Seychelles + \value SierraLeone + \value Singapore + \value Slovakia + \value Slovenia + \value SolomonIslands + \value Somalia + \value SouthAfrica + \value SouthGeorgiaAndTheSouthSandwichIslands + \value Spain + \value SriLanka + \value StHelena + \value StPierreAndMiquelon + \value Sudan + \value Suriname + \value SvalbardAndJanMayenIslands + \value Swaziland + \value Sweden + \value Switzerland + \value SyrianArabRepublic + \value Taiwan + \value Tajikistan + \value Tanzania + \value Thailand + \value Togo + \value Tokelau + \value TongaCountry + \value TrinidadAndTobago + \value Tunisia + \value Turkey + \value Turkmenistan + \value TurksAndCaicosIslands + \value Tuvalu + \value Uganda + \value Ukraine + \value UnitedArabEmirates + \value UnitedKingdom + \value UnitedStates + \value UnitedStatesMinorOutlyingIslands + \value Uruguay + \value Uzbekistan + \value Vanuatu + \value VaticanCityState + \value Venezuela + \value VietNam + \value BritishVirginIslands + \value USVirginIslands + \value WallisAndFutunaIslands + \value WesternSahara + \value Yemen + \value Yugoslavia + \value Zambia + \value Zimbabwe +*/ + +/*! + Constructs a QLocale object with the specified \a name, + which has the format + "language[_country][.codeset][@modifier]" or "C", where: + + \list + \i language is a lowercase, two-letter, ISO 639 language code, + \i territory is an uppercase, two-letter, ISO 3166 country code, + \i and codeset and modifier are ignored. + \endlist + + If the string violates the locale format, or language is not + a valid ISO 369 code, the "C" locale is used instead. If country + is not present, or is not a valid ISO 3166 code, the most + appropriate country is chosen for the specified language. + + The language and country codes are converted to their respective + \c Language and \c Country enums. After this conversion is + performed the constructor behaves exactly like QLocale(Country, + Language). + + This constructor is much slower than QLocale(Country, Language). + + \sa name() +*/ + +QLocale::QLocale(const QString &name) +{ + Language lang = C; + Country cntry = AnyCountry; + + uint l = name.length(); + + do { + if (l < 2) + break; + + const QChar *uc = name.unicode(); + if (l > 2 + && uc[2] != '_' + && uc[2] != '.' + && uc[2] != '@') + break; + + lang = codeToLanguage(name.mid(0, 2)); + if (lang == C) + break; + + if (l == 2 || uc[2] == '.' || uc[2] == '@') + break; + + // we have uc[2] == '_' + if (l < 5) + break; + + if (l > 5 && uc[5] != '.' && uc[5] != '@') + break; + + cntry = codeToCountry(name.mid(3, 2)); + } while (false); + + d = findLocale(lang, cntry); +} + +/*! + Constructs a QLocale object initialized with the default locale. + + \sa setDefault() +*/ + +QLocale::QLocale() +{ + if (default_d == 0) + default_d = system().d; + + d = default_d; +} + +/*! + Constructs a QLocale object with the specified \a language and \a + country. + + \list + \i If the language/country pair is found in the database, it is used. + \i If the language is found but the country is not, or if the country + is \c AnyCountry, the language is used with the most + appropriate available country (for example, Germany for German), + \i If neither the language nor the country are found, QLocale + defaults to the default locale (see setDefault()). + \endlist + + The language and country that are actually used can be queried + using language() and country(). + + \sa setDefault() language() country() +*/ + +QLocale::QLocale(Language language, Country country) +{ + d = findLocale(language, country); + + // If not found, should default to system + if (d->languageId() == QLocale::C && language != QLocale::C) { + if (default_d == 0) + default_d = system().d; + + d = default_d; + } +} + +/*! + Constructs a QLocale object as a copy of \a other. +*/ + +QLocale::QLocale(const QLocale &other) +{ + d = other.d; +} + +/*! + Assigns \a other to this QLocale object and returns a reference + to this QLocale object. +*/ + +QLocale &QLocale::operator=(const QLocale &other) +{ + d = other.d; + return *this; +} + +/*! + \nonreentrant + + Sets the global default locale to \a locale. These + values are used when a QLocale object is constructed with + no arguments. If this function is not called, the system's + locale is used. + + \warning In a multithreaded application, the default locale + should be set at application startup, before any non-GUI threads + are created. + + \sa system() c() +*/ + +void QLocale::setDefault(const QLocale &locale) +{ + default_d = locale.d; +} + +/*! + Returns the language of this locale. + + \sa QLocale() +*/ +QLocale::Language QLocale::language() const +{ + return (Language)d->languageId(); +} + +/*! + Returns the country of this locale. + + \sa QLocale() +*/ +QLocale::Country QLocale::country() const +{ + return (Country)d->countryId(); +} + +/*! + Returns the language and country of this locale as a + string of the form "language_country", where + language is a lowercase, two-letter ISO 639 language code, + and country is an uppercase, two-letter ISO 3166 country code. + + \sa QLocale() +*/ + +QString QLocale::name() const +{ + Language l = language(); + + QString result = languageToCode(l); + + if (l == C) + return result; + + Country c = country(); + if (c == AnyCountry) + return result; + + result.append('_'); + result.append(countryToCode(c)); + + return result; +} + +/*! + Returns a QString containing the name of \a language. +*/ + +QString QLocale::languageToString(Language language) +{ + if ((uint)language > (uint)QLocale::LastLanguage) + return "Unknown"; + return language_name_list + language_name_index[(uint)language]; +} + +/*! + Returns a QString containing the name of \a country. +*/ + +QString QLocale::countryToString(Country country) +{ + if ((uint)country > (uint)QLocale::LastCountry) + return "Unknown"; + return country_name_list + country_name_index[(uint)country]; +} + +/*! + Returns the short int represented by the localized string \a s, or + 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +short QLocale::toShort(const QString &s, bool *ok) const +{ + Q_LLONG i = toLongLong(s, ok); + if (i < SHRT_MIN || i > SHRT_MAX) { + if (ok != 0) + *ok = false; + return 0; + } + return (short) i; +} + +/*! + Returns the unsigned short int represented by the localized string + \a s, or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +ushort QLocale::toUShort(const QString &s, bool *ok) const +{ + Q_ULLONG i = toULongLong(s, ok); + if (i > USHRT_MAX) { + if (ok != 0) + *ok = false; + return 0; + } + return (ushort) i; +} + +/*! + Returns the int represented by the localized string \a s, or 0 if + the conversion failed. + + If \a ok is not 0, reports failure by setting *ok to false and + success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +int QLocale::toInt(const QString &s, bool *ok) const +{ + Q_LLONG i = toLongLong(s, ok); + if (i < INT_MIN || i > INT_MAX) { + if (ok != 0) + *ok = false; + return 0; + } + return (int) i; +} + +/*! + Returns the unsigned int represented by the localized string \a s, + or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +uint QLocale::toUInt(const QString &s, bool *ok) const +{ + Q_ULLONG i = toULongLong(s, ok); + if (i > UINT_MAX) { + if (ok != 0) + *ok = false; + return 0; + } + return (uint) i; +} + +/*! + Returns the long int represented by the localized string \a s, or + 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +Q_LONG QLocale::toLong(const QString &s, bool *ok) const +{ + Q_LLONG i = toLongLong(s, ok); + if (i < LONG_MIN || i > LONG_MAX) { + if (ok != 0) + *ok = false; + return 0; + } + return (Q_LONG) i; +} + +/*! + Returns the unsigned long int represented by the localized string + \a s, or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +Q_ULONG QLocale::toULong(const QString &s, bool *ok) const +{ + Q_ULLONG i = toULongLong(s, ok); + if (i > ULONG_MAX) { + if (ok != 0) + *ok = false; + return 0; + } + return (Q_ULONG) i; +} + +/*! + Returns the long long int represented by the localized string \a + s, or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + + +Q_LLONG QLocale::toLongLong(const QString &s, bool *ok) const +{ + return d->stringToLongLong(s, 0, ok, QLocalePrivate::ParseGroupSeparators); +} + +/*! + Returns the unsigned long long int represented by the localized + string \a s, or 0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + + +Q_ULLONG QLocale::toULongLong(const QString &s, bool *ok) const +{ + return d->stringToUnsLongLong(s, 0, ok, QLocalePrivate::ParseGroupSeparators); +} + +/*! + Returns the float represented by the localized string \a s, or 0.0 + if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + This function ignores leading and trailing whitespace. + + \sa toString() +*/ + +float QLocale::toFloat(const QString &s, bool *ok) const +{ + return (float) toDouble(s, ok); +} + +/*! + Returns the double represented by the localized string \a s, or + 0.0 if the conversion failed. + + If \a ok is not 0, reports failure by setting + *ok to false and success by setting *ok to true. + + Unlike QString::toDouble(), this function does not fall back to + the "C" locale if the string cannot be interpreted in this + locale. + + \code + bool ok; + double d; + + QLocale c(QLocale::C); + d = c.toDouble( "1234.56", &ok ); // ok == true, d == 1234.56 + d = c.toDouble( "1,234.56", &ok ); // ok == true, d == 1234.56 + d = c.toDouble( "1234,56", &ok ); // ok == false + + QLocale german(QLocale::German); + d = german.toDouble( "1234,56", &ok ); // ok == true, d == 1234.56 + d = german.toDouble( "1.234,56", &ok ); // ok == true, d == 1234.56 + d = german.toDouble( "1234.56", &ok ); // ok == false + + d = german.toDouble( "1.234", &ok ); // ok == true, d == 1234.0 + \endcode + + Notice that the last conversion returns 1234.0, because '.' is the + thousands group separator in the German locale. + + This function ignores leading and trailing whitespace. + + \sa toString() QString::toDouble() +*/ + +double QLocale::toDouble(const QString &s, bool *ok) const +{ + return d->stringToDouble(s, ok, QLocalePrivate::ParseGroupSeparators); +} + +/*! + Returns a localized string representation of \a i. + + \sa toLongLong() +*/ + +QString QLocale::toString(Q_LLONG i) const +{ + return d->longLongToString(i, -1, 10, QLocalePrivate::ThousandsGroup); +} + +/*! + \overload + + \sa toULongLong() +*/ + +QString QLocale::toString(Q_ULLONG i) const +{ + return d->unsLongLongToString(i, -1, 10, QLocalePrivate::ThousandsGroup); +} + +static bool qIsUpper(char c) +{ + return c >= 'A' && c <= 'Z'; +} + +static char qToLower(char c) +{ + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + else + return c; +} + +/*! + \overload + + \a f and \a prec have the same meaning as in QString::number(double, char, int). + + \sa toDouble() +*/ + +QString QLocale::toString(double i, char f, int prec) const +{ + QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal; + uint flags = 0; + + if (qIsUpper(f)) + flags = QLocalePrivate::CapitalEorX; + f = qToLower(f); + + switch (f) { + case 'f': + form = QLocalePrivate::DFDecimal; + break; + case 'e': + form = QLocalePrivate::DFExponent; + break; + case 'g': + form = QLocalePrivate::DFSignificantDigits; + break; + default: + break; + } + + flags |= QLocalePrivate::ThousandsGroup; + return d->doubleToString(i, prec, form, -1, flags); +} + +/*! + \fn QLocale QLocale::c() + + Returns a QLocale object initialized to the "C" locale. + + \sa system() +*/ + +/*! + Returns a QLocale object initialized to the system locale. +*/ + +QLocale QLocale::system() +{ +#ifdef Q_OS_UNIX + const char *s = getenv("LC_NUMERIC"); + if (s == 0) + s = getenv("LC_ALL"); + if (s != 0) + return QLocale(s); +#endif + return QLocale(QLocalePrivate::systemLocaleName()); +} + +/*! +\fn QString QLocale::toString(short i) const + +\overload + +\sa toShort() +*/ + +/*! +\fn QString QLocale::toString(ushort i) const + +\overload + +\sa toUShort() +*/ + +/*! +\fn QString QLocale::toString(int i) const + +\overload + +\sa toInt() +*/ + +/*! +\fn QString QLocale::toString(uint i) const + +\overload + +\sa toUInt() +*/ + +/*! +\fn QString QLocale::toString(Q_LONG i) const + +\overload + +\sa toLong() +*/ + +/*! +\fn QString QLocale::toString(Q_ULONG i) const + +\overload + +\sa toULong() +*/ + +/*! +\fn QString QLocale::toString(float i, char f = 'g', int prec = 6) const + +\overload + +\a f and \a prec have the same meaning as in QString::number(double, char, int). + +\sa toDouble() +*/ + + +bool QLocalePrivate::isDigit(QChar d) const +{ + return zero().unicode() <= d.unicode() + && zero().unicode() + 10 > d.unicode(); +} + +static char digitToCLocale(QChar zero, QChar d) +{ + if (zero.unicode() <= d.unicode() + && zero.unicode() + 10 > d.unicode()) + return '0' + d.unicode() - zero.unicode(); + + qWarning("QLocalePrivate::digitToCLocale(): bad digit: row=%d, cell=%d", d.row(), d.cell()); + return QChar(0); +} + +static QString qulltoa(Q_ULLONG l, int base, const QLocalePrivate &locale) +{ + QChar buff[65]; // length of MAX_ULLONG in base 2 + QChar *p = buff + 65; + + if (base != 10 || locale.zero().unicode() == '0') { + while (l != 0) { + int c = l % base; + + --p; + + if (c < 10) + *p = '0' + c; + else + *p = c - 10 + 'a'; + + l /= base; + } + } + else { + while (l != 0) { + int c = l % base; + + *(--p) = locale.zero().unicode() + c; + + l /= base; + } + } + + return QString(p, 65 - (p - buff)); +} + +static QString qlltoa(Q_LLONG l, int base, const QLocalePrivate &locale) +{ + return qulltoa(l < 0 ? -l : l, base, locale); +} + +enum PrecisionMode { + PMDecimalDigits = 0x01, + PMSignificantDigits = 0x02, + PMChopTrailingZeros = 0x03 +}; + +static QString &decimalForm(QString &digits, int decpt, uint precision, + PrecisionMode pm, + bool always_show_decpt, + bool thousands_group, + const QLocalePrivate &locale) +{ + if (decpt < 0) { + for (int i = 0; i < -decpt; ++i) + digits.prepend(locale.zero()); + decpt = 0; + } + else if ((uint)decpt > digits.length()) { + for (uint i = digits.length(); i < (uint)decpt; ++i) + digits.append(locale.zero()); + } + + if (pm == PMDecimalDigits) { + uint decimal_digits = digits.length() - decpt; + for (uint i = decimal_digits; i < precision; ++i) + digits.append(locale.zero()); + } + else if (pm == PMSignificantDigits) { + for (uint i = digits.length(); i < precision; ++i) + digits.append(locale.zero()); + } + else { // pm == PMChopTrailingZeros + } + + if (always_show_decpt || (uint)decpt < digits.length()) + digits.insert(decpt, locale.decimal()); + + if (thousands_group) { + for (int i = decpt - 3; i > 0; i -= 3) + digits.insert(i, locale.group()); + } + + if (decpt == 0) + digits.prepend(locale.zero()); + + return digits; +} + +static QString &exponentForm(QString &digits, int decpt, uint precision, + PrecisionMode pm, + bool always_show_decpt, + const QLocalePrivate &locale) +{ + int exp = decpt - 1; + + if (pm == PMDecimalDigits) { + for (uint i = digits.length(); i < precision + 1; ++i) + digits.append(locale.zero()); + } + else if (pm == PMSignificantDigits) { + for (uint i = digits.length(); i < precision; ++i) + digits.append(locale.zero()); + } + else { // pm == PMChopTrailingZeros + } + + if (always_show_decpt || digits.length() > 1) + digits.insert(1, locale.decimal()); + + digits.append(locale.exponential()); + digits.append(locale.longLongToString(exp, 2, 10, + -1, QLocalePrivate::AlwaysShowSign)); + + return digits; +} + +QString QLocalePrivate::doubleToString(double d, + int precision, + DoubleForm form, + int width, + unsigned flags) const +{ + if (precision == -1) + precision = 6; + if (width == -1) + width = 0; + + bool negative = false; + bool special_number = false; // nan, +/-inf + QString num_str; + + // Comparing directly to INFINITY gives weird results on some systems. + double tmp_infinity = INFINITY; + + // Detect special numbers (nan, +/-inf) + if (d == tmp_infinity || d == -tmp_infinity) { + num_str = infinity(); + special_number = true; + negative = d < 0; + } else if (isnan(d)) { + num_str = nan(); + special_number = true; + } + + // Handle normal numbers + if (!special_number) { + int decpt, sign; + QString digits; + +#ifdef QT_QLOCALE_USES_FCVT +#ifdef QT_THREAD_SUPPORT + static bool dummy_for_mutex; + QMutex *fcvt_mutex = qt_global_mutexpool ? qt_global_mutexpool->get( &dummy_for_mutex ) : 0; +# define FCVT_LOCK if (fcvt_mutex) fcvt_mutex->lock() +# define FCVT_UNLOCK if (fcvt_mutex) fcvt_mutex->unlock() +#else +# define FCVT_LOCK +# define FCVT_UNLOCK +#endif + if (form == DFDecimal) { + FCVT_LOCK; + digits = fcvt(d, precision, &decpt, &sign); + FCVT_UNLOCK; + } else { + int pr = precision; + if (form == DFExponent) + ++pr; + else if (form == DFSignificantDigits && pr == 0) + pr = 1; + FCVT_LOCK; + digits = ecvt(d, pr, &decpt, &sign); + FCVT_UNLOCK; + + // Chop trailing zeros + if (digits.length() > 0) { + int last_nonzero_idx = digits.length() - 1; + while (last_nonzero_idx > 0 + && digits.unicode()[last_nonzero_idx] == '0') + --last_nonzero_idx; + digits.truncate(last_nonzero_idx + 1); + } + + } + +#else + int mode; + if (form == DFDecimal) + mode = 3; + else + mode = 2; + + /* This next bit is a bit quirky. In DFExponent form, the precision + is the number of digits after decpt. So that would suggest using + mode=3 for qdtoa. But qdtoa behaves strangely when mode=3 and + precision=0. So we get around this by using mode=2 and reasoning + that we want precision+1 significant digits, since the decimal + point in this mode is always after the first digit. */ + int pr = precision; + if (form == DFExponent) + ++pr; + + char *rve = 0; + char *buff = 0; + digits = qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff); + if (buff != 0) + free(buff); +#endif // QT_QLOCALE_USES_FCVT + + if (zero().unicode() != '0') { + for (uint i = 0; i < digits.length(); ++i) + digits.ref(i).unicode() += zero().unicode() - '0'; + } + + bool always_show_decpt = flags & Alternate; + switch (form) { + case DFExponent: { + num_str = exponentForm(digits, decpt, precision, PMDecimalDigits, + always_show_decpt, *this); + break; + } + case DFDecimal: { + num_str = decimalForm(digits, decpt, precision, PMDecimalDigits, + always_show_decpt, flags & ThousandsGroup, + *this); + break; + } + case DFSignificantDigits: { + PrecisionMode mode = (flags & Alternate) ? + PMSignificantDigits : PMChopTrailingZeros; + + if (decpt != (int)digits.length() && (decpt <= -4 || decpt > (int)precision)) + num_str = exponentForm(digits, decpt, precision, mode, + always_show_decpt, *this); + else + num_str = decimalForm(digits, decpt, precision, mode, + always_show_decpt, flags & ThousandsGroup, + *this); + break; + } + } + + negative = sign != 0; + } + + // pad with zeros. LeftAdjusted overrides this flag). Also, we don't + // pad special numbers + if (flags & QLocalePrivate::ZeroPadded + && !(flags & QLocalePrivate::LeftAdjusted) + && !special_number) { + int num_pad_chars = width - (int)num_str.length(); + // leave space for the sign + if (negative + || flags & QLocalePrivate::AlwaysShowSign + || flags & QLocalePrivate::BlankBeforePositive) + --num_pad_chars; + + for (int i = 0; i < num_pad_chars; ++i) + num_str.prepend(zero()); + } + + // add sign + if (negative) + num_str.prepend(minus()); + else if (flags & QLocalePrivate::AlwaysShowSign) + num_str.prepend(plus()); + else if (flags & QLocalePrivate::BlankBeforePositive) + num_str.prepend(' '); + + if (flags & QLocalePrivate::CapitalEorX) + num_str = num_str.upper(); + + return num_str; +} + +QString QLocalePrivate::longLongToString(Q_LLONG l, int precision, + int base, int width, + unsigned flags) const +{ + bool precision_not_specified = false; + if (precision == -1) { + precision_not_specified = true; + precision = 1; + } + + bool negative = l < 0; + if (base != 10) { + // these are not suported by sprintf for octal and hex + flags &= ~AlwaysShowSign; + flags &= ~BlankBeforePositive; + negative = false; // neither are negative numbers + } + + QString num_str; + if (base == 10) + num_str = qlltoa(l, base, *this); + else + num_str = qulltoa(l, base, *this); + + uint cnt_thousand_sep = 0; + if (flags & ThousandsGroup && base == 10) { + for (int i = (int)num_str.length() - 3; i > 0; i -= 3) { + num_str.insert(i, group()); + ++cnt_thousand_sep; + } + } + + for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i) + num_str.prepend(base == 10 ? zero() : QChar('0')); + + if (flags & Alternate + && base == 8 + && (num_str.isEmpty() + || num_str[0].unicode() != '0')) + num_str.prepend('0'); + + // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds + // when precision is not specified in the format string + bool zero_padded = flags & ZeroPadded + && !(flags & LeftAdjusted) + && precision_not_specified; + + if (zero_padded) { + int num_pad_chars = width - (int)num_str.length(); + + // leave space for the sign + if (negative + || flags & AlwaysShowSign + || flags & BlankBeforePositive) + --num_pad_chars; + + // leave space for optional '0x' in hex form + if (base == 16 + && flags & Alternate + && l != 0) + num_pad_chars -= 2; + + for (int i = 0; i < num_pad_chars; ++i) + num_str.prepend(base == 10 ? zero() : QChar('0')); + } + + if (base == 16 + && flags & Alternate + && l != 0) + num_str.prepend("0x"); + + // add sign + if (negative) + num_str.prepend(minus()); + else if (flags & AlwaysShowSign) + num_str.prepend(base == 10 ? plus() : QChar('+')); + else if (flags & BlankBeforePositive) + num_str.prepend(' '); + + if (flags & CapitalEorX) + num_str = num_str.upper(); + + return num_str; +} + +QString QLocalePrivate::unsLongLongToString(Q_ULLONG l, int precision, + int base, int width, + unsigned flags) const +{ + bool precision_not_specified = false; + if (precision == -1) { + precision_not_specified = true; + precision = 1; + } + + QString num_str = qulltoa(l, base, *this); + + uint cnt_thousand_sep = 0; + if (flags & ThousandsGroup && base == 10) { + for (int i = (int)num_str.length() - 3; i > 0; i -=3) { + num_str.insert(i, group()); + ++cnt_thousand_sep; + } + } + + for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i) + num_str.prepend(base == 10 ? zero() : QChar('0')); + + if (flags & Alternate + && base == 8 + && (num_str.isEmpty() + || num_str[0].unicode() != '0')) + num_str.prepend('0'); + + // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds + // when precision is not specified in the format string + bool zero_padded = flags & ZeroPadded + && !(flags & LeftAdjusted) + && precision_not_specified; + + if (zero_padded) { + int num_pad_chars = width - (int)num_str.length(); + + // leave space for optional '0x' in hex form + if (base == 16 + && flags & Alternate + && l != 0) + num_pad_chars -= 2; + + for (int i = 0; i < num_pad_chars; ++i) + num_str.prepend(base == 10 ? zero() : QChar('0')); + } + + if (base == 16 + && flags & Alternate + && l != 0) + num_str.prepend("0x"); + + if (flags & CapitalEorX) + num_str = num_str.upper(); + + return num_str; +} + +static bool compareSubstr(const QString &s1, uint idx, const QString &s2) +{ + uint i = 0; + for (; i + idx < s1.length() && i < s2.length(); ++i) { + if (s1.unicode()[i + idx] != s2.unicode()[i]) + return false; + } + + return i == s2.length(); +} + +// Removes thousand-group separators, ie. the ',' in "1,234,567.89e-5" +bool QLocalePrivate::removeGroupSeparators(QString &num_str) const +{ + int group_cnt = 0; // counts number of group chars + int decpt_idx = -1; + + // Find the decimal point and check if there are any group chars + uint i = 0; + for (; i < num_str.length(); ++i) { + QChar c = num_str.unicode()[i]; + + if (c == group()) { + // check that there are digits before and after the separator + if (i == 0 || !isDigit(num_str.unicode()[i - 1])) + return false; + if (i == num_str.length() + 1 || !isDigit(num_str.unicode()[i + 1])) + return false; + ++group_cnt; + } + else if (c == decimal()) { + // Fail if more than one decimal points + if (decpt_idx != -1) + return false; + decpt_idx = i; + } else if (c == exponential() || c == exponential().upper()) { + // an 'e' or 'E' - if we have not encountered a decimal + // point, this is where it "is". + if (decpt_idx == -1) + decpt_idx = i; + } + } + + // If no group chars, we're done + if (group_cnt == 0) + return true; + + // No decimal point means that it "is" at the end of the string + if (decpt_idx == -1) + decpt_idx = num_str.length(); + + i = 0; + while (i < num_str.length() && group_cnt > 0) { + QChar c = num_str.unicode()[i]; + + if (c == group()) { + // Don't allow group chars after the decimal point + if ((int)i > decpt_idx) + return false; + + // Check that it is placed correctly relative to the decpt + if ((decpt_idx - i) % 4 != 0) + return false; + + // Remove it + num_str.remove(i, 1); + + --group_cnt; + --decpt_idx; // adjust decpt_idx + } else { + // Check that we are not missing a separator + if ((int)i < decpt_idx && (decpt_idx - i) % 4 == 0) + return false; + ++i; + } + } + + return true; +} + +static void stripWhiteSpaceInPlace(QString &s) +{ + uint i = 0; + while (i < s.length() && s.unicode()[i].isSpace()) + ++i; + if (i > 0) + s.remove(0, i); + + i = s.length(); + + if (i == 0) + return; + --i; + while (i > 0 && s.unicode()[i].isSpace()) + --i; + if (i + 1 < s.length()) + s.truncate(i + 1); +} + +// Converts a number in locale to its representation in the C locale. +bool QLocalePrivate::numberToCLocale(QString &l_num, + GroupSeparatorMode group_sep_mode) const +{ + stripWhiteSpaceInPlace(l_num); + + if (group_sep_mode == ParseGroupSeparators + && !removeGroupSeparators(l_num)) + return false; + + uint idx = 0; + if (compareSubstr(l_num, idx, nan())) { + idx += nan().length(); + return idx == l_num.length(); + } + else if (compareSubstr(l_num, idx, nan().upper())) { + for (uint i = idx; i < idx + nan().length(); ++i) + l_num.ref(i) = l_num.unicode()[i].lower(); + idx += nan().length(); + return idx == l_num.length(); + } + QChar &c = l_num.ref(idx); + + if (c == plus()) { + c.unicode() = '+'; + ++idx; + } + else if (c == minus()) { + c.unicode() = '-'; + ++idx; + } + + if (compareSubstr(l_num, idx, infinity())) { + idx += infinity().length(); + return idx == l_num.length(); + } + else if (compareSubstr(l_num, idx, infinity().upper())) { + for (uint i = idx; i < idx + infinity().length(); ++i) + l_num.ref(i) = l_num.unicode()[i].lower(); + idx += infinity().length(); + return idx == l_num.length(); + } + + while (idx < l_num.length()) { + QChar &c = l_num.ref(idx); + + if (isDigit(c)) + c = digitToCLocale(zero(), c); + else if (c == plus()) + c = '+'; + else if (c == minus()) + c = '-'; + else if (c == decimal()) + c = '.'; + else if (c == group()) + c = ','; + else if (c == exponential() || c == exponential().upper()) + c = 'e'; + else if (c.unicode() == 'x' || c.unicode() == 'X') // hex number + c = 'x'; + else if (c == list()) + c = ';'; + else if (c == percent()) + c = '%'; + else if (c.unicode() >= 'A' && c.unicode() <= 'F') + c = c.upper(); + else if (c.unicode() >= 'a' && c.unicode() <= 'f') + ; // do nothing + else + return false; + + ++idx; + } + + return true; +} + +double QLocalePrivate::stringToDouble(QString num, + bool *ok, + GroupSeparatorMode group_sep_mode) const +{ + if (!numberToCLocale(num, group_sep_mode)) { + if (ok != 0) + *ok = false; + return 0.0; + } + + if (ok != 0) + *ok = true; + + if (num == "nan") + return NAN; + + if (num == "+inf" + || num == "inf") + return INFINITY; + + if (num == "-inf") + return -INFINITY; + + bool _ok; + const char *num_buff = num.latin1(); + +#ifdef QT_QLOCALE_USES_FCVT + char *endptr; + double d = strtod(num_buff, &endptr); + _ok = true; +#else + const char *endptr; + double d = qstrtod(num_buff, &endptr, &_ok); +#endif + + if (!_ok || *endptr != '\0') { + if (ok != 0) + *ok = false; + return 0.0; + } + else + return d; +} + +Q_LLONG QLocalePrivate::stringToLongLong(QString num, int base, + bool *ok, + GroupSeparatorMode group_sep_mode) const +{ + if (!numberToCLocale(num, group_sep_mode)) { + if (ok != 0) + *ok = false; + return 0; + } + + bool _ok; + const char *endptr; + const char *num_buff = num.latin1(); + Q_LLONG l = qstrtoll(num_buff, &endptr, base, &_ok); + + if (!_ok || *endptr != '\0') { + if (ok != 0) + *ok = false; + return 0; + } + + if (ok != 0) + *ok = true; + return l; +} + +Q_ULLONG QLocalePrivate::stringToUnsLongLong(QString num, int base, + bool *ok, + GroupSeparatorMode group_sep_mode) const +{ + if (!numberToCLocale(num, group_sep_mode)) { + if (ok != 0) + *ok = false; + return 0; + } + + bool _ok; + const char *endptr; + const char *num_buff = num.latin1(); + Q_ULLONG l = qstrtoull(num_buff, &endptr, base, &_ok); + + if (!_ok || *endptr != '\0') { + if (ok != 0) + *ok = false; + return 0; + } + + if (ok != 0) + *ok = true; + return l; +} + +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +// static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; +// "$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $"; + +/* + * Convert a string to an Q_ULLONG integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +static Q_ULLONG qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok) +{ + register const char *s = nptr; + register Q_ULLONG acc; + register unsigned char c; + register Q_ULLONG qbase, cutoff; + register int neg, any, cutlim; + + if (ok != 0) + *ok = true; + + /* + * See strtoq for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + if (ok != 0) + *ok = false; + if (endptr != 0) + *endptr = s - 1; + return 0; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + qbase = (unsigned)base; + cutoff = (Q_ULLONG)ULLONG_MAX / qbase; + cutlim = (Q_ULLONG)ULLONG_MAX % qbase; + for (acc = 0, any = 0;; c = *s++) { + if (!isascii(c)) + break; + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= qbase; + acc += c; + } + } + if (any < 0) { + acc = ULLONG_MAX; + if (ok != 0) + *ok = false; + } + else if (neg) + acc = (~acc) + 1; + if (endptr != 0) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + + +// "$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $"; + + +/* + * Convert a string to a Q_LLONG integer. + * + * Ignores `locale' stuff. Assumes that the upper and lower case + * alphabets and digits are each contiguous. + */ +static Q_LLONG qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok) +{ + register const char *s; + register Q_ULLONG acc; + register unsigned char c; + register Q_ULLONG qbase, cutoff; + register int neg, any, cutlim; + + if (ok != 0) + *ok = true; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for quads is + * [-9223372036854775808..9223372036854775807] and the input base + * is 10, cutoff will be set to 922337203685477580 and cutlim to + * either 7 (neg==0) or 8 (neg==1), meaning that if we have + * accumulated a value > 922337203685477580, or equal but the + * next digit is > 7 (or 8), the number is too big, and we will + * return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + qbase = (unsigned)base; + cutoff = neg ? (Q_ULLONG)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX + : LLONG_MAX; + cutlim = cutoff % qbase; + cutoff /= qbase; + for (acc = 0, any = 0;; c = *s++) { + if (!isascii(c)) + break; + if (isdigit(c)) + c -= '0'; + else if (isalpha(c)) + c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= qbase; + acc += c; + } + } + if (any < 0) { + acc = neg ? LLONG_MIN : LLONG_MAX; + if (ok != 0) + *ok = false; + } else if (neg) { + acc = (~acc) + 1; + } + if (endptr != 0) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + +#ifndef QT_QLOCALE_USES_FCVT + +/* From: NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp */ +/* $FreeBSD: src/lib/libc/stdlib/netbsd_strtod.c,v 1.2.2.2 2001/03/02 17:14:15 tegge Exp $ */ + +/* Please send bug reports to + David M. Gay + AT&T Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-2070 + U.S.A. + dmg@research.att.com or research!dmg + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define Sudden_Underflow for IEEE-format machines without gradual + * underflow (i.e., that flush to zero on underflow). + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic. + * #define Unsigned_Shifts if >> does treats its left operand as unsigned. + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision + * integer arithmetic. Whether this speeds things up or slows things + * down depends on the machine and the number being converted. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp $"); +#endif /* LIBC_SCCS and not lint */ + +/* +#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ + defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \ + defined(__powerpc__) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_MACX) || \ + defined(mips) || defined(Q_OS_AIX) || defined(Q_OS_SOLARIS) +# define IEEE_BIG_OR_LITTLE_ENDIAN 1 +#endif +*/ + +// *All* of our architectures have IEEE arithmetic, don't they? +#define IEEE_BIG_OR_LITTLE_ENDIAN 1 + +#ifdef __arm32__ +/* + * Although the CPU is little endian the FP has different + * byte and word endianness. The byte order is still little endian + * but the word order is big endian. + */ +#define IEEE_BIG_OR_LITTLE_ENDIAN +#endif + +#ifdef vax +#define VAX +#endif + +#define Long Q_INT32 +#define ULong Q_UINT32 + +#define MALLOC malloc +#define CONST const + +#ifdef BSD_QDTOA_DEBUG +#include <stdio.h> +#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} +#endif + +#ifdef Unsigned_Shifts +#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; +#else +#define Sign_Extend(a,b) /*no-op*/ +#endif + +#if (defined(IEEE_BIG_OR_LITTLE_ENDIAN) + defined(VAX) + defined(IBM)) != 1 +#error Exactly one of IEEE_BIG_OR_LITTLE_ENDIAN, VAX, or IBM should be defined. +#endif + + +#define word0(x) ((volatile ULong *)&x)[ByteOrder == BigEndian ? 0 : 1] +#define word1(x) ((volatile ULong *)&x)[ByteOrder == BigEndian ? 1 : 0] + + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ + +/* +#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm32__) +#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ +((unsigned short *)a)[0] = (unsigned short)c, a++) +#else +#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ +((unsigned short *)a)[1] = (unsigned short)c, a++) +#endif +*/ + +static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c) +{ + +# if defined(VAX) + defined(__arm32__) +# define USE_LITTLE_ENDIAN 1 +# else +# define USE_LITTLE_ENDIAN 0 +# endif + +# if defined(IEEE_BIG_OR_LITTLE_ENDIAN) +# define USE_IEEE 1 +# else +# define USE_IEEE 0 +# endif + + if (ByteOrder == LittleEndian && USE_IEEE || USE_LITTLE_ENDIAN) { + ((unsigned short *)a)[1] = (unsigned short)b; + ((unsigned short *)a)[0] = (unsigned short)c; + } else { + ((unsigned short *)a)[0] = (unsigned short)b; + ((unsigned short *)a)[1] = (unsigned short)c; + } + + ++a; + +# undef USE_LITTLE_ENDIAN +# undef USE_IEEE +} + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#if defined(IEEE_BIG_OR_LITTLE_ENDIAN) +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define IEEE_Arith +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 +#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */ +#else +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Bias 65 +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Bias 129 +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif +#endif + +#ifndef IEEE_Arith +#define ROUND_BIASED +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) a = rnd_prod(a, b) +#define rounded_quotient(a,b) a = rnd_quot(a, b) +#ifdef KR_headers +extern double rnd_prod(), rnd_quot(); +#else +extern double rnd_prod(double, double), rnd_quot(double, double); +#endif +#else +#define rounded_product(a,b) a *= b +#define rounded_quotient(a,b) a /= b +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#ifndef Just_16 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#ifndef Pack_32 +#define Pack_32 +#endif +#endif + +#define Kmax 15 + +struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; + + typedef struct Bigint Bigint; + +static Bigint *Balloc(int k) +{ + int x; + Bigint *rv; + + x = 1 << k; + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)); + rv->k = k; + rv->maxwds = x; + rv->sign = rv->wds = 0; + return rv; +} + +static void Bfree(Bigint *v) +{ + free(v); +} + +#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ +y->wds*sizeof(Long) + 2*sizeof(int)) + +/* multiply by m and add a */ +static Bigint *multadd(Bigint *b, int m, int a) +{ + int i, wds; + ULong *x, y; +#ifdef Pack_32 + ULong xi, z; +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + do { +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + a; + z = (xi >> 16) * m + (y >> 16); + a = (int)(z >> 16); + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + a; + a = (int)(y >> 16); + *x++ = y & 0xffff; +#endif + } + while(++i < wds); + if (a) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = a; + b->wds = wds; + } + return b; +} + +static Bigint *s2b(CONST char *s, int nd0, int nd, ULong y9) +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; +#ifdef Pack_32 + b = Balloc(k); + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do b = multadd(b, 10, *s++ - '0'); + while(++i < nd0); + s++; + } + else + s += 10; + for(; i < nd; i++) + b = multadd(b, 10, *s++ - '0'); + return b; +} + +static int hi0bits(ULong x) +{ + int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; +} + +static int lo0bits(ULong *y) +{ + int k; + ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x & 1) + return 32; + } + *y = x; + return k; +} + +static Bigint *i2b(int i) +{ + Bigint *b; + + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; +} + +static Bigint *mult(Bigint *a, Bigint *b) +{ + Bigint *c; + int k, wa, wb, wc; + ULong carry, y, z; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; +#ifdef Pack_32 + ULong z2; +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef Pack_32 + for(; xb < xbe; xb++, xc0++) { + if ((y = *xb & 0xffff) != 0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if ((y = *xb >> 16) != 0) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#else + for(; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while(x < xae); + *xc = carry; + } + } +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; +} + +static Bigint *p5s; + +static Bigint *pow5mult(Bigint *b, int k) +{ + Bigint *b1, *p5, *p51; + int i; + static const int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3) != 0) + b = multadd(b, p05[i-1], 0); + + if (!(k >>= 2)) + return b; + if (!(p5 = p5s)) { + /* first time */ + p5 = p5s = i2b(625); + p5->next = 0; + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) + break; + if (!(p51 = p5->next)) { + p51 = p5->next = mult(p5,p5); + p51->next = 0; + } + p5 = p51; + } + return b; +} + +static Bigint *lshift(Bigint *b, int k) +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + +#ifdef Pack_32 + n = k >> 5; +#else + n = k >> 4; +#endif + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z) != 0) + ++n1; + } +#else + if (k &= 0xf) { + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) + ++n1; + } +#endif + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; +} + +static int cmp(Bigint *a, Bigint *b) +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef BSD_QDTOA_DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; +} + +static Bigint *diff(Bigint *a, Bigint *b) +{ + Bigint *c; + int i, wa, wb; + Long borrow, y; /* We need signed shifts here. */ + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef Pack_32 + Long z; +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*xa++ >> 16) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *xc++ = y & 0xffff; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *xc++ = y & 0xffff; + } +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; +} + +static double ulp(volatile double x) +{ + Long L; + double a; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + word0(a) = L; + word1(a) = 0; +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + word0(a) = 0x80000 >> L; + word1(a) = 0; + } + else { + word0(a) = 0; + L -= Exp_shift; + word1(a) = (L >= 31 ? 1U : 1U << (31 - L)); + } + } +#endif + return a; +} + +static double b2d(Bigint *a, int *e) +{ + ULong *xa, *xa0, w, y, z; + int k; + double d; +#ifdef VAX + ULong d0, d1; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef BSD_QDTOA_DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + d0 = Exp_1 | y >> (Ebits - k); + w = xa > xa0 ? *--xa : 0; + d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> (32 - k); + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> (32 - k); + } + else { + d0 = Exp_1 | y; + d1 = z; + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif + ret_d: +#ifdef VAX + word0(d) = d0 >> 16 | d0 << 16; + word1(d) = d1 >> 16 | d1 << 16; +#else +#undef d0 +#undef d1 +#endif + return d; +} + +static Bigint *d2b(double d, int *e, int *bits) +{ + Bigint *b; + int de, i, k; + ULong *x, y, z; +#ifdef VAX + ULong d0, d1; + d0 = word0(d) >> 16 | word0(d) << 16; + d1 = word1(d) >> 16 | word1(d) << 16; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + x = b->x; + + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(d0 >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if ((de = (int)(d0 >> Exp_shift)) != 0) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if ((y = d1) != 0) { + if ((k = lo0bits(&y)) != 0) { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; + i = b->wds = (x[1] = z) ? 2 : 1; + } + else { +#ifdef BSD_QDTOA_DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + x[0] = z; + i = b->wds = 1; + k += 32; + } +#else + if (y = d1) { + if (k = lo0bits(&y)) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef BSD_QDTOA_DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while(!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; +} +#undef d0 +#undef d1 + +static double ratio(Bigint *a, Bigint *b) +{ + double da, db; + int k, ka, kb; + + da = b2d(a, &ka); + db = b2d(b, &kb); +#ifdef Pack_32 + k = ka - kb + 32*(a->wds - b->wds); +#else + k = ka - kb + 16*(a->wds - b->wds); +#endif +#ifdef IBM + if (k > 0) { + word0(da) += (k >> 2)*Exp_msk1; + if (k &= 3) + da *= 1 << k; + } + else { + k = -k; + word0(db) += (k >> 2)*Exp_msk1; + if (k &= 3) + db *= 1 << k; + } +#else + if (k > 0) + word0(da) += k*Exp_msk1; + else { + k = -k; + word0(db) += k*Exp_msk1; + } +#endif + return da / db; +} + +static CONST double tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif +}; + +#ifdef IEEE_Arith +static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; +#define n_bigtens 5 +#else +#ifdef IBM +static CONST double bigtens[] = { 1e16, 1e32, 1e64 }; +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#define n_bigtens 3 +#else +static CONST double bigtens[] = { 1e16, 1e32 }; +static CONST double tinytens[] = { 1e-16, 1e-32 }; +#define n_bigtens 2 +#endif +#endif + +/* + The pre-release gcc3.3 shipped with SuSE 8.2 has a bug which causes + the comparison 1e-100 == 0.0 to return true. As a workaround, we + compare it to a global variable containing 0.0, which produces + correct assembler output. + + ### consider detecting the broken compilers and using the static + ### double for these, and use a #define for all working compilers +*/ +static double g_double_zero = 0.0; + +static double qstrtod(CONST char *s00, CONST char **se, bool *ok) +{ + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + CONST char *s, *s0, *s1; + double aadj, aadj1, adj, rv, rv0; + Long L; + ULong y, z; + Bigint *bb1, *bd0; + Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */ + + /* + #ifndef KR_headers + CONST char decimal_point = localeconv()->decimal_point[0]; + #else + CONST char decimal_point = '.'; + #endif */ + if (ok != 0) + *ok = true; + + CONST char decimal_point = '.'; + + sign = nz0 = nz = 0; + rv = 0.; + + + for(s = s00; isspace((unsigned char) *s); s++) + ; + + if (*s == '-') { + sign = 1; + s++; + } else if (*s == '+') { + s++; + } + + if (*s == '\0') { + s = s00; + goto ret; + } + + if (*s == '0') { + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; + if (c == decimal_point) { + c = *++s; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + s = s00; + goto ret; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) + s = s00; + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + rv = y; + if (k > 9) + rv = tens[k - 9] * rv + z; + bd0 = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT + && FLT_ROUNDS == 1 +#endif + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else + /* rv = */ rounded_product(rv, tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ + e -= i; + rv *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + word0(rv) -= P*Exp_msk1; + /* rv = */ rounded_product(rv, tens[e]); + if ((word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + word0(rv) += P*Exp_msk1; +#else + /* rv = */ rounded_product(rv, tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { + /* rv = */ rounded_quotient(rv, tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ((i = e1 & 15) != 0) + rv *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: + // errno = ERANGE; + if (ok != 0) + *ok = false; +#ifdef __STDC__ + rv = HUGE_VAL; +#else + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith + word0(rv) = Exp_mask; + word1(rv) = 0; +#else + word0(rv) = Big0; + word1(rv) = Big1; +#endif +#endif + if (bd0) + goto retfree; + goto ret; + } + if (e1 >>= 4) { + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + rv *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(rv) -= P*Exp_msk1; + rv *= bigtens[j]; + if ((z = word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(rv) = Big0; + word1(rv) = Big1; + } + else + word0(rv) += P*Exp_msk1; + } + + } + } + else if (e1 < 0) { + e1 = -e1; + if ((i = e1 & 15) != 0) + rv /= tens[i]; + if (e1 &= ~15) { + e1 >>= 4; + if (e1 >= 1 << n_bigtens) + goto undfl; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + rv *= tinytens[j]; + /* The last multiplication could underflow. */ + rv0 = rv; + rv *= tinytens[j]; + if (rv == g_double_zero) + { + rv = 2.*rv0; + rv *= tinytens[j]; + if (rv == g_double_zero) + { + undfl: + rv = 0.; + // errno = ERANGE; + if (ok != 0) + *ok = false; + if (bd0) + goto retfree; + goto ret; + } + word0(rv) = Tiny0; + word1(rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else + i = bbe + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j = bbe + (P-Emin); + else + j = P + 1 - bbbits; +#endif + bb2 += j; + bd2 += j; + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift(bb, bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + delta = diff(bb, bd); + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask) + break; + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((word0(rv) & Bndry_mask1) == Bndry_mask1 + && word1(rv) == 0xffffffff) { + /*boundary case -- increment exponent*/ + word0(rv) = (word0(rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ; + word1(rv) = 0; + break; + } + } + else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { + drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow + L = word0(rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else + if (L <= Exp_msk1) +#endif + goto undfl; + L -= Exp_msk1; +#else + L = (word0(rv) & Exp_mask) - Exp_msk1; +#endif + word0(rv) = L | Bndry_mask1; + word1(rv) = 0xffffffff; +#ifdef IBM + goto cont; +#else + break; +#endif + } +#ifndef ROUND_BIASED + if (!(word1(rv) & LSB)) + break; +#endif + if (dsign) + rv += ulp(rv); +#ifndef ROUND_BIASED + else { + rv -= ulp(rv); +#ifndef Sudden_Underflow + if (rv == g_double_zero) + goto undfl; +#endif + } +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = aadj1 = 1.; + else if (word1(rv) || word0(rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (word1(rv) == Tiny1 && !word0(rv)) + goto undfl; +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch(FLT_ROUNDS) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (FLT_ROUNDS == 0) + aadj1 += 0.5; +#endif + } + y = word0(rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + rv0 = rv; + word0(rv) -= P*Exp_msk1; + adj = aadj1 * ulp(rv); + rv += adj; + if ((word0(rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(rv0) == Big0 && word1(rv0) == Big1) + goto ovfl; + word0(rv) = Big0; + word1(rv) = Big1; + goto cont; + } + else + word0(rv) += P*Exp_msk1; + } + else { +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + rv0 = rv; + word0(rv) += P*Exp_msk1; + adj = aadj1 * ulp(rv); + rv += adj; +#ifdef IBM + if ((word0(rv) & Exp_mask) < P*Exp_msk1) +#else + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(rv0) == Tiny0 + && word1(rv0) == Tiny1) + goto undfl; + word0(rv) = Tiny0; + word1(rv) = Tiny1; + goto cont; + } + else + word0(rv) -= P*Exp_msk1; + } + else { + adj = aadj1 * ulp(rv); + rv += adj; + } +#else + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj >= 1.) { + aadj1 = (double)(int)(aadj + 0.5); + if (!dsign) + aadj1 = -aadj1; + } + adj = aadj1 * ulp(rv); + rv += adj; +#endif + } + z = word0(rv) & Exp_mask; + if (y == z) { + /* Can we stop now? */ + L = (Long) aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } + cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } + retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + ret: + if (se) + *se = (char *)s; + return sign ? -rv : rv; +} + +static int quorem(Bigint *b, Bigint *S) +{ + int n; + Long borrow, y; + ULong carry, q, ys; + ULong *bx, *bxe, *sx, *sxe; +#ifdef Pack_32 + Long z; + ULong si, zs; +#endif + + n = S->wds; +#ifdef BSD_QDTOA_DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef BSD_QDTOA_DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*bx >> 16) - (zs & 0xffff) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *bx++ = y & 0xffff; +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + z = (*bx >> 16) - (zs & 0xffff) + borrow; + borrow = z >> 16; + Sign_Extend(borrow, z); + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) + borrow; + borrow = y >> 16; + Sign_Extend(borrow, y); + *bx++ = y & 0xffff; +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; +} + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + + +/* This actually sometimes returns a pointer to a string literal + cast to a char*. Do NOT try to modify the return value. */ + +static char *qdtoa (volatile double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp) +{ + /* + Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4-9 should give the same return values as 2-3, i.e., + 4 <= mode <= 9 ==> same return as mode + 2 + (mode & 1). These modes are mainly for + debugging; often they run slower but sometimes + faster than modes 2-3. + 4,5,8,9 ==> left-to-right digit generation. + 6-9 ==> don't try fast floating-point estimate + (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim0, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + try_quick; + int ilim = 0, ilim1 = 0, spec_case = 0; /* pacify gcc */ + Long L; +#ifndef Sudden_Underflow + int denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mhi, *S; + Bigint *mlo = NULL; /* pacify gcc */ + volatile double d2; + double ds, eps; + char *s, *s0; + + if (word0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(d) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) + defined(VAX) +#ifdef IEEE_Arith + if ((word0(d) & Exp_mask) == Exp_mask) +#else + if (word0(d) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; + s = +#ifdef IEEE_Arith + !word1(d) && !(word0(d) & 0xfffff) ? (char*)"Infinity" : +#endif + (char*)"NaN"; + if (rve) + *rve = +#ifdef IEEE_Arith + s[3] ? s + 8 : +#endif + s + 3; + return s; + } +#endif +#ifdef IBM + d += 0; /* normalize */ +#endif + if (d == g_double_zero) + { + *decpt = 1; + s = (char*) "0"; + if (rve) + *rve = s + 1; + return s; + } + + b = d2b(d, &be, &bbits); +#ifdef Sudden_Underflow + i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { +#endif + d2 = d; + word0(d2) &= Frac_mask1; + word0(d2) |= Exp_11; +#ifdef IBM + if (j = 11 - hi0bits(word0(d2) & Frac_mask)) + d2 /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) + : word1(d) << (32 - i); + d2 = x; + word0(d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (d < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + try_quick = 1; + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + *resultp = (char *) malloc(i + 1); + s = s0 = *resultp; + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + d2 = d; + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + d /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + d /= ds; + } + else if ((j1 = -k) != 0) { + d *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + d *= bigtens[i]; + } + } + if (k_check && d < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + d *= 10.; + ieps++; + } + eps = ieps*d + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + d -= 5.; + if (d > eps) + goto one_digit; + if (d < -eps) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + eps = 0.5/tens[ilim-1] - eps; + for(i = 0;;) { + L = (Long)d; + d -= L; + *s++ = '0' + (int)L; + if (d < eps) + goto ret1; + if (1. - d < eps) + goto bump_up; + if (++i >= ilim) + break; + eps *= 10.; + d *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + eps *= tens[ilim-1]; + for(i = 1;; i++, d *= 10.) { + L = (Long)d; + d -= L; + *s++ = '0' + (int)L; + if (i == ilim) { + if (d > 0.5 + eps) + goto bump_up; + else if (d < 0.5 - eps) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + d = d2; + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || d <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++) { + L = (Long)(d / ds); + d -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (d < 0) { + L--; + d += ds; + } +#endif + *s++ = '0' + (int)L; + if (i == ilim) { + d += d; + if (d > ds || (d == ds && L & 1)) { + bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + if ((d *= 10.) == g_double_zero) + break; + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + if (mode < 2) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + } + else { + j = ilim - 1; + if (m5 >= j) + m5 -= j; + else { + s5 += j -= m5; + b5 += j; + m5 = 0; + } + if ((i = ilim) < 0) { + m2 -= i; + i = 0; + } + } + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if ((j = b5 - m5) != 0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + if (mode < 2) { + if (!word1(d) && !(word0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(d) & Exp_mask +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + else + spec_case = 0; + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0) + i = 32 - i; +#else + if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && mode > 2) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && !mode && !(word1(d) & 1)) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || (j == 0 && !mode +#ifndef ROUND_BIASED + && !(word1(d) & 1) +#endif + )) { + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || (j1 == 0 && dig & 1)) + && dig++ == '9') + goto round_9_up; + } + *s++ = dig; + goto ret; + } + if (j1 > 0) { + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || (j == 0 && dig & 1)) { + roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + while(*--s == '0'); + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: + Bfree(b); + if (s == s0) { /* don't return empty string */ + *s++ = '0'; + k = 0; + } + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; +} + +#endif // QT_QLOCALE_USES_FCVT diff --git a/qmake/tools/qsettings.cpp b/qmake/tools/qsettings.cpp index 35fc039..598e94b 100644 --- a/qmake/tools/qsettings.cpp +++ b/qmake/tools/qsettings.cpp @@ -1,3 +1,3 @@ /**************************************************************************** -** $Id$ +** ** @@ -7,3 +7,3 @@ ** -** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. +** Copyright (C) 2000-2003 Trolltech AS. All rights reserved. ** @@ -62,3 +62,5 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) #include <private/qsettings_p.h> +#ifndef NO_ERRNO_H #include <errno.h> +#endif @@ -103,3 +105,4 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) - A typical usage pattern for reading application startup: + A typical usage pattern for reading settings at application + startup: \code @@ -113,3 +116,4 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) - A typical usage pattern for application exit or 'save preferences': + A typical usage pattern for saving settings at application exit or + 'save preferences': \code @@ -123,4 +127,5 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) - QSettings can build a key prefix that is prepended to all keys. To - build the key prefix, use beginGroup() and endGroup(). + A key prefix can be prepended to all keys using beginGroup(). The + application of the prefix is stopped using endGroup(). For + example: \code @@ -156,4 +161,4 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) - Since settings for Windows are stored in the registry there are size - limits as follows: + Since settings for Windows are stored in the registry there are + some size limitations as follows: \list @@ -167,5 +172,5 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) - If you wish to use a different search path call insertSearchPath() - as often as necessary to add your preferred paths. Call - removeSearchPath() to remove any unwanted paths. + \warning Creating multiple, simultaneous instances of QSettings writing + to a text file may lead to data loss! This is a known issue which will + be fixed in a future release of Qt. @@ -173,12 +178,13 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) - Internal to the CFPreferences API it is not defined (for Mac OS 9 - support) where the settings will ultimitely be stored. However, at the - time of this writing the settings will be stored (either on a global or - user basis, preferring locally) into a plist file in - $ROOT/System/Library/Preferences (in XML format). QSettings will create - an appropriate plist file (com.<first group name>.plist) out of the - full path to a key. + The location where settings are stored is not formally defined by + the CFPreferences API. + + At the time of writing settings are stored (either on a global or + user basis, preferring locally) into a plist file in \c + $ROOT/System/Library/Preferences (in XML format). QSettings will + create an appropriate plist file (\c{com.<first group name>.plist}) + out of the full path to a key. - For further information on CFPreferences see also - \link http://developer.apple.com/techpubs/macosx/CoreFoundation/PreferenceServices/preferenceservices_carbon.html + For further information on CFPreferences see + \link http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFPreferences/index.html Apple's Specifications\endlink @@ -191,6 +197,6 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) \list 1 - \i INSTALL/etc/settings - \i /opt/MyCompany/share/etc - \i /opt/MyCompany/share/MyApplication/etc - \i $HOME/.qt + \i \c SYSCONF - the default value is \c INSTALL/etc/settings + \i \c /opt/MyCompany/share/etc + \i \c /opt/MyCompany/share/MyApplication/etc + \i \c $HOME/.qt \endlist @@ -219,4 +225,4 @@ static inline int qt_open( const char *pathname, int flags, mode_t mode ) - For cross-platform applications you should ensure that the Windows - size limitations are not exceeded. + For cross-platform applications you should ensure that the + \link #sizelimit Windows size limitations \endlink are not exceeded. */ @@ -312,41 +318,2 @@ static void closelock( HANDLE fd ) } -#elif defined(Q_WS_WIN) -#define Q_LOCKREAD 1 -#define Q_LOCKWRITE 2 - -static HANDLE openlock( const QString &name, int /*type*/ ) -{ - if ( !QFile::exists( name ) ) - return 0; - - return 0; - - HANDLE fd = 0; - - QT_WA( { - fd = CreateFileW( (TCHAR*)name.ucs2(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); - } , { - fd = CreateFileA( name.local8Bit(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); - } ); - - if ( !LockFile( fd, 0, 0, (DWORD)-1, (DWORD)-1 ) ) { // ### (DWORD)-1 ??? -#ifdef QT_CHECK_STATE - qWarning( "QSettings: openlock failed!" ); -#endif - } - return fd; -} - -static void closelock( HANDLE fd ) -{ - if ( !fd ) - return; - - if ( !UnlockFile( fd, 0, 0, (DWORD)-1, (DWORD)-1 ) ) { // ### (DWORD)-1 ??? -#ifdef QT_CHECK_STATE - qWarning( "QSettings: closelock failed!"); -#endif - } - CloseHandle( fd ); -} #endif @@ -367,3 +334,5 @@ void QSettingsHeading::read(const QString &filename) +#ifndef Q_WS_WIN HANDLE lockfd = openlock( filename, Q_LOCKREAD ); +#endif @@ -388,3 +357,5 @@ void QSettingsHeading::read(const QString &filename) +#ifndef Q_WS_WIN closelock( lockfd ); +#endif } @@ -406,3 +377,3 @@ void QSettingsHeading::parseLine(QTextStream &stream) - gname = gname.remove(0, 1); + gname = gname.remove((uint)0, 1); if (gname[(int)gname.length() - 1] == QChar(']')) @@ -528,7 +499,3 @@ QSettingsPrivate::QSettingsPrivate( QSettings::Format format ) #else -// for now -#define QSETTINGS_DEFAULT_PATH_SUFFIX "/etc/settings" - - defPath = qInstallPath(); - defPath += QSETTINGS_DEFAULT_PATH_SUFFIX; + defPath = qInstallPathSysconf(); #endif @@ -703,3 +670,3 @@ bool qt_verify_key( const QString &key ) { - if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\\\r\\\\n" ) ) ) + if ( key.isEmpty() || key[0] != '/' || key.contains( QRegExp("[=\\r\\n]" ) ) ) return FALSE; @@ -708,4 +675,5 @@ bool qt_verify_key( const QString &key ) -static inline QString groupKey( const QString &group, const QString &key ) +static QString groupKey( const QString &group, const QString &key ) { + QString grp_key; if ( group.isEmpty() || ( group.length() == 1 && group[0] == '/' ) ) { @@ -713,8 +681,11 @@ static inline QString groupKey( const QString &group, const QString &key ) if ( key.startsWith( "/" ) ) - return key; - return "/" + key; + grp_key = key; + else + grp_key = "/" + key; } else if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) { - return group + key; + grp_key = group + key; + } else { + grp_key = group + "/" + key; } - return group + "/" + key; + return grp_key; } @@ -723,3 +694,4 @@ static inline QString groupKey( const QString &group, const QString &key ) Inserts \a path into the settings search path. The semantics of \a - path depends on the system \a s. + path depends on the system \a s. It is usually easier and better to + use setPath() instead of this function. @@ -768,4 +740,5 @@ static inline QString groupKey( const QString &group, const QString &key ) \list 1 - \i INSTALL/etc - where \c INSTALL is the directory where Qt was installed. - \i $HOME/.qt/ - where \c $HOME is the user's home directory. + \i \c SYSCONF - where \c SYSCONF is a directory specified when + configuring Qt; by default it is INSTALL/etc/settings. + \i \c $HOME/.qt/ - where \c $HOME is the user's home directory. \endlist @@ -782,3 +755,3 @@ static inline QString groupKey( const QString &group, const QString &key ) \list 1 - \i INSTALL/etc + \i SYSCONF \i /opt/MyCompany/share/etc @@ -793,2 +766,5 @@ static inline QString groupKey( const QString &group, const QString &key ) + Note that paths in the file system are not created by this + function, so they must already exist to be useful. + Settings under Unix are stored in files whose names are based on the @@ -817,3 +793,3 @@ void QSettings::insertSearchPath( System s, const QString &path) #endif -#if !defined(Q_WS_WIN) +#if !defined(Q_OS_MAC) if ( s == Mac ) @@ -966,3 +942,3 @@ bool QSettings::sync() QSettingsHeading::Iterator hdit = hd.begin(); - QFile file; + QString filename; @@ -974,2 +950,7 @@ bool QSettings::sync() QFileInfo di(*pit); + if ( !di.exists() ) { + QDir dir; + dir.mkdir( *pit ); + } + QFileInfo fi((*pit++) + "/" + filebase + "rc"); @@ -977,4 +958,10 @@ bool QSettings::sync() if ((fi.exists() && fi.isFile() && fi.isWritable()) || - (! fi.exists() && di.isDir() && di.isWritable())) { - file.setName(fi.filePath()); + (! fi.exists() && di.isDir() +#ifndef Q_WS_WIN + && di.isWritable() +#else + && ((qWinVersion()&Qt::WV_NT_based) > Qt::WV_2000 || di.isWritable()) +#endif + )) { + filename = fi.filePath(); break; @@ -985,3 +972,3 @@ bool QSettings::sync() - if ( file.name().isEmpty() ) { + if ( filename.isEmpty() ) { @@ -995,4 +982,7 @@ bool QSettings::sync() - HANDLE lockfd = openlock( file.name(), Q_LOCKWRITE ); +#ifndef Q_WS_WIN + HANDLE lockfd = openlock( filename, Q_LOCKWRITE ); +#endif + QFile file( filename + ".tmp" ); if (! file.open(IO_WriteOnly)) { @@ -1049,3 +1039,22 @@ bool QSettings::sync() + if ( success ) { + QDir dir( QFileInfo( file ).dir( TRUE ) ); + if ( dir.exists( filename ) && !dir.remove( filename ) || + !dir.rename( file.name(), filename, TRUE ) ) { + +#ifdef QT_CHECK_STATE + qWarning( "QSettings::sync: error writing file '%s'", + QFile::encodeName( filename ).data() ); +#endif // QT_CHECK_STATE + + success = FALSE; + } + } + + // remove temporary file + file.remove(); + +#ifndef Q_WS_WIN closelock( lockfd ); +#endif } @@ -1074,5 +1083,6 @@ bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok ) { - if ( !qt_verify_key( key ) ) { + QString grp_key( groupKey( group(), key ) ); + if ( !qt_verify_key( grp_key ) ) { #if defined(QT_CHECK_STATE) - qWarning( "QSettings::readBoolEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); + qWarning( "QSettings::readBoolEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() ); #endif @@ -1086,3 +1096,3 @@ bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok ) if ( d->sysd ) - return d->sysReadBoolEntry( groupKey( group(), key ), def, ok ); + return d->sysReadBoolEntry( grp_key, def, ok ); #endif @@ -1125,5 +1135,6 @@ double QSettings::readDoubleEntry(const QString &key, double def, bool *ok ) { - if ( !qt_verify_key( key ) ) { + QString grp_key( groupKey( group(), key ) ); + if ( !qt_verify_key( grp_key ) ) { #if defined(QT_CHECK_STATE) - qWarning( "QSettings::readDoubleEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); + qWarning( "QSettings::readDoubleEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() ); #endif @@ -1137,3 +1148,3 @@ double QSettings::readDoubleEntry(const QString &key, double def, bool *ok ) if ( d->sysd ) - return d->sysReadDoubleEntry( groupKey( group(), key ), def, ok ); + return d->sysReadDoubleEntry( grp_key, def, ok ); #endif @@ -1170,5 +1181,6 @@ int QSettings::readNumEntry(const QString &key, int def, bool *ok ) { - if ( !qt_verify_key( key ) ) { + QString grp_key( groupKey( group(), key ) ); + if ( !qt_verify_key( grp_key ) ) { #if defined(QT_CHECK_STATE) - qWarning( "QSettings::readNumEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); + qWarning( "QSettings::readNumEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() ); #endif @@ -1181,3 +1193,3 @@ int QSettings::readNumEntry(const QString &key, int def, bool *ok ) if ( d->sysd ) - return d->sysReadNumEntry( groupKey( group(), key ), def, ok ); + return d->sysReadNumEntry( grp_key, def, ok ); #endif @@ -1214,5 +1226,6 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) { - if ( !qt_verify_key( key ) ) { + QString grp_key( groupKey( group(), key ) ); + if ( !qt_verify_key( grp_key ) ) { #if defined(QT_CHECK_STATE) - qWarning( "QSettings::readEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); + qWarning( "QSettings::readEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() ); #endif @@ -1224,7 +1237,5 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) - QString theKey = groupKey( group(), key ); - #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysReadEntry( theKey, def, ok ); + return d->sysReadEntry( grp_key, def, ok ); #endif @@ -1236,5 +1247,5 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) - if (theKey[0] == '/') { + if (grp_key[0] == '/') { // parse our key - QStringList list(QStringList::split('/', theKey)); + QStringList list(QStringList::split('/', grp_key)); @@ -1242,3 +1253,3 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) #ifdef QT_CHECK_STATE - qWarning("QSettings::readEntry: invalid key '%s'", theKey.latin1()); + qWarning("QSettings::readEntry: invalid key '%s'", grp_key.latin1()); #endif // QT_CHECK_STATE @@ -1264,4 +1275,5 @@ QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) } - } else - realkey = theKey; + } else { + realkey = grp_key; + } @@ -1292,5 +1304,6 @@ bool QSettings::writeEntry(const QString &key, bool value) { - if ( !qt_verify_key( key ) ) { + QString grp_key( groupKey( group(), key ) ); + if ( !qt_verify_key( grp_key ) ) { #if defined(QT_CHECK_STATE) - qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); + qWarning( "QSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() ); #endif @@ -1301,3 +1314,3 @@ bool QSettings::writeEntry(const QString &key, bool value) if ( d->sysd ) - return d->sysWriteEntry( groupKey( group(), key ), value ); + return d->sysWriteEntry( grp_key, value ); #endif @@ -1322,5 +1335,6 @@ bool QSettings::writeEntry(const QString &key, double value) { - if ( !qt_verify_key( key ) ) { + QString grp_key( groupKey( group(), key ) ); + if ( !qt_verify_key( grp_key ) ) { #if defined(QT_CHECK_STATE) - qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); + qWarning( "QSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() ); #endif @@ -1331,3 +1345,3 @@ bool QSettings::writeEntry(const QString &key, double value) if ( d->sysd ) - return d->sysWriteEntry( groupKey( group(), key ), value ); + return d->sysWriteEntry( grp_key, value ); #endif @@ -1351,5 +1365,6 @@ bool QSettings::writeEntry(const QString &key, int value) { - if ( !qt_verify_key( key ) ) { + QString grp_key( groupKey( group(), key ) ); + if ( !qt_verify_key( grp_key ) ) { #if defined(QT_CHECK_STATE) - qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); + qWarning( "QSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() ); #endif @@ -1360,3 +1375,3 @@ bool QSettings::writeEntry(const QString &key, int value) if ( d->sysd ) - return d->sysWriteEntry( groupKey( group(), key ), value ); + return d->sysWriteEntry( grp_key, value ); #endif @@ -1385,9 +1400,2 @@ bool QSettings::writeEntry(const QString &key, const char *value) { - if ( !qt_verify_key( key ) ) { -#if defined(QT_CHECK_STATE) - qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); -#endif - return FALSE; - } - return writeEntry(key, QString(value)); @@ -1410,5 +1418,6 @@ bool QSettings::writeEntry(const QString &key, const QString &value) { - if ( !qt_verify_key( key ) ) { + QString grp_key( groupKey( group(), key ) ); + if ( !qt_verify_key( grp_key ) ) { #if defined(QT_CHECK_STATE) - qWarning( "QSettings::writeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); + qWarning( "QSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() ); #endif @@ -1417,7 +1426,5 @@ bool QSettings::writeEntry(const QString &key, const QString &value) - QString theKey = groupKey( group(), key ); - #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysWriteEntry( theKey, value ); + return d->sysWriteEntry( grp_key, value ); #endif @@ -1427,5 +1434,5 @@ bool QSettings::writeEntry(const QString &key, const QString &value) - if (theKey[0] == '/') { + if (grp_key[0] == '/') { // parse our key - QStringList list(QStringList::split('/', theKey)); + QStringList list(QStringList::split('/', grp_key)); @@ -1433,3 +1440,3 @@ bool QSettings::writeEntry(const QString &key, const QString &value) #ifdef QT_CHECK_STATE - qWarning("QSettings::writeEntry: invalid key '%s'", theKey.latin1()); + qWarning("QSettings::writeEntry: invalid key '%s'", grp_key.latin1()); #endif // QT_CHECK_STATE @@ -1454,4 +1461,5 @@ bool QSettings::writeEntry(const QString &key, const QString &value) } - } else - realkey = theKey; + } else { + realkey = grp_key; + } @@ -1471,5 +1479,6 @@ bool QSettings::removeEntry(const QString &key) { - if ( !qt_verify_key( key ) ) { + QString grp_key( groupKey( group(), key ) ); + if ( !qt_verify_key( grp_key ) ) { #if defined(QT_CHECK_STATE) - qWarning( "QSettings::removeEntry: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); + qWarning( "QSettings::removeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() ); #endif @@ -1478,7 +1487,5 @@ bool QSettings::removeEntry(const QString &key) - QString theKey = groupKey( group(), key ); - #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysRemoveEntry( theKey ); + return d->sysRemoveEntry( grp_key ); #endif @@ -1486,6 +1493,5 @@ bool QSettings::removeEntry(const QString &key) QString realkey; - - if (theKey[0] == '/') { + if (grp_key[0] == '/') { // parse our key - QStringList list(QStringList::split('/', theKey)); + QStringList list(QStringList::split('/', grp_key)); @@ -1493,3 +1499,3 @@ bool QSettings::removeEntry(const QString &key) #ifdef QT_CHECK_STATE - qWarning("QSettings::removeEntry: invalid key '%s'", theKey.latin1()); + qWarning("QSettings::removeEntry: invalid key '%s'", grp_key.latin1()); #endif // QT_CHECK_STATE @@ -1514,4 +1520,5 @@ bool QSettings::removeEntry(const QString &key) } - } else - realkey = theKey; + } else { + realkey = grp_key; + } @@ -1550,5 +1557,6 @@ QStringList QSettings::entryList(const QString &key) const { - if ( !qt_verify_key( key ) ) { + QString grp_key( groupKey( group(), key ) ); + if ( !qt_verify_key( grp_key ) ) { #if defined(QT_CHECK_STATE) - qWarning( "QSettings::entryList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() ); + qWarning( "QSettings::entryList: Invalid key: %s", grp_key.isNull() ? "(null)" : grp_key.latin1() ); #endif @@ -1557,7 +1565,5 @@ QStringList QSettings::entryList(const QString &key) const - QString theKey = groupKey( group(), key ); - #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysEntryList( theKey ); + return d->sysEntryList( grp_key ); #endif @@ -1565,5 +1571,5 @@ QStringList QSettings::entryList(const QString &key) const QString realkey; - if (theKey[0] == '/') { + if (grp_key[0] == '/') { // parse our key - QStringList list(QStringList::split('/', theKey)); + QStringList list(QStringList::split('/', grp_key)); @@ -1571,3 +1577,3 @@ QStringList QSettings::entryList(const QString &key) const #ifdef QT_CHECK_STATE - qWarning("QSettings::listEntries: invalid key '%s'", theKey.latin1()); + qWarning("QSettings::listEntries: invalid key '%s'", grp_key.latin1()); #endif // QT_CHECK_STATE @@ -1592,3 +1598,3 @@ QStringList QSettings::entryList(const QString &key) const } else - realkey = theKey; + realkey = grp_key; @@ -1647,5 +1653,6 @@ QStringList QSettings::subkeyList(const QString &key) const { - if ( !qt_verify_key( key ) ) { + QString grp_key( groupKey( group(), key ) ); + if ( !qt_verify_key( grp_key ) ) { #if defined(QT_CHECK_STATE) - qWarning( "QSettings::subkeyList: Invalid key: %s", key.isNull() ? "(null)" : key.latin1() ); + qWarning( "QSettings::subkeyList: Invalid key: %s", grp_key.isNull() ? "(null)" : grp_key.latin1() ); #endif @@ -1654,7 +1661,5 @@ QStringList QSettings::subkeyList(const QString &key) const - QString theKey = groupKey( group(), key ); - #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysSubkeyList( theKey ); + return d->sysSubkeyList( grp_key ); #endif @@ -1663,5 +1668,5 @@ QStringList QSettings::subkeyList(const QString &key) const int subkeycount = 2; - if (theKey[0] == '/') { + if (grp_key[0] == '/') { // parse our key - QStringList list(QStringList::split('/', theKey)); + QStringList list(QStringList::split('/', grp_key)); @@ -1669,3 +1674,3 @@ QStringList QSettings::subkeyList(const QString &key) const #ifdef QT_CHECK_STATE - qWarning("QSettings::subkeyList: invalid key '%s'", theKey.latin1()); + qWarning("QSettings::subkeyList: invalid key '%s'", grp_key.latin1()); #endif // QT_CHECK_STATE @@ -1693,3 +1698,3 @@ QStringList QSettings::subkeyList(const QString &key) const } else - realkey = theKey; + realkey = grp_key; @@ -1739,7 +1744,8 @@ QStringList QSettings::subkeyList(const QString &key) const */ -QDateTime QSettings::lastModficationTime(const QString &key) +QDateTime QSettings::lastModificationTime( const QString &key ) { - if ( !qt_verify_key( key ) ) { + QString grp_key( groupKey( group(), key ) ); + if ( !qt_verify_key( grp_key ) ) { #if defined(QT_CHECK_STATE) - qWarning( "QSettings::lastModficationTime: Invalid key: '%s'", key.isNull() ? "(null)" : key.latin1() ); + qWarning( "QSettings::lastModificationTime: Invalid key '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() ); #endif @@ -1748,4 +1754,2 @@ QDateTime QSettings::lastModficationTime(const QString &key) - QString theKey = groupKey( group(), key ); - #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) @@ -1755,5 +1759,5 @@ QDateTime QSettings::lastModficationTime(const QString &key) - if (theKey[0] == '/') { + if (grp_key[0] == '/') { // parse our key - QStringList list(QStringList::split('/', theKey)); + QStringList list(QStringList::split('/', grp_key)); @@ -1761,3 +1765,3 @@ QDateTime QSettings::lastModficationTime(const QString &key) #ifdef QT_CHECK_STATE - qWarning("QSettings::lastModficationTime: invalid key '%s'", theKey.latin1()); + qWarning("QSettings::lastModificationTime: Invalid key '%s'", grp_key.latin1()); #endif // QT_CHECK_STATE @@ -1782,2 +1786,3 @@ QDateTime QSettings::lastModficationTime(const QString &key) \overload + \obsolete @@ -1798,2 +1803,3 @@ QDateTime QSettings::lastModficationTime(const QString &key) + If an error occurs the settings are left unchanged and FALSE is @@ -1801,3 +1807,3 @@ QDateTime QSettings::lastModficationTime(const QString &key) - \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() + \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry(), QStringList::join() */ @@ -1841,2 +1847,3 @@ bool QSettings::writeEntry(const QString &key, const QStringList &value) \overload QStringList QSettings::readListEntry(const QString &key, const QChar &separator, bool *ok ) const + \obsolete @@ -1844,4 +1851,4 @@ bool QSettings::writeEntry(const QString &key, const QStringList &value) is used to create a QStringList by calling QStringList::split(\a - separator, entry). If \a ok is not 0: \a *ok is set to TRUE if the - key was read, otherwise \a *ok is set to FALSE. + separator, entry). If \a ok is not 0: \a *ok is set to TRUE + if the key was read, otherwise \a *ok is set to FALSE. @@ -1853,3 +1860,2 @@ bool QSettings::writeEntry(const QString &key, const QStringList &value) - Note that if you want to iterate over the list, you should iterate @@ -1951,4 +1957,3 @@ void qt_setSettingsBasePath(const QString &); //qsettings_mac.cpp - Not all information is relevant on all systems (e.g. scoping is - currently used only if QSettings accesses the Windows registry). + Not all information is relevant on all systems. */ @@ -1982,9 +1987,15 @@ void QSettings::setPath( const QString &domain, const QString &product, Scope sc #elif !defined(QWS) && defined(Q_OS_MAC) - QString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + "."; - if ( !topLevelDomain.isEmpty() ) - qt_setSettingsBasePath( topLevelDomain ); - actualSearchPath = "/" + domain.left( lastDot ) + product; + if(lastDot != -1) { + QString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + "."; + if ( !topLevelDomain.isEmpty() ) + qt_setSettingsBasePath( topLevelDomain ); + } + actualSearchPath = "/" + domain.left( lastDot ) + "." + product; insertSearchPath( Mac, actualSearchPath ); #else - actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product; + if (scope == User) + actualSearchPath = QDir::homeDirPath() + "/."; + else + actualSearchPath = QString(qInstallPathSysconf()) + "/"; + actualSearchPath += domain.mid( 0, lastDot ) + "/" + product; insertSearchPath( Unix, actualSearchPath ); diff --git a/qmake/tools/qunicodetables.cpp b/qmake/tools/qunicodetables.cpp new file mode 100644 index 0000000..c3cad4c --- a/dev/null +++ b/qmake/tools/qunicodetables.cpp @@ -0,0 +1,13237 @@ +/**************************************************************************** +** +** +** ??? +** +** Copyright (C) 2002-2003 Trolltech AS. All rights reserved. +** +** This file is part of the kernel module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "qunicodetables_p.h" + +/* ------------------------------------------------------------------------- + * unicode information + * these tables are generated from the unicode reference file + * ftp://ftp.unicode.org/Public/3.2-Update/UnicodeData.txt + * + * Lars + * ------------------------------------------------------------------------- + */ + +/* Perl script to generate (run perl -x tools/qstringdata.cpp) + +#!perl + +sub numberize +{ + my(%r, $n, $id); + for $id ( @_ ) { + $i = $id; + $i="" if $i eq "EMPTY"; + $r{$i}=$n++; + } + return %r; +} + + +sub readUnicodeDataLine { + $code = shift @_; + for $n (qw{ + name category combining_class bidi_category + character_decomposition decimal_digit_value digit_value + numeric_value mirrored oldname comment + uppercase lowercase titlecase}) + { + $id = shift @_; + $codes = "${n}_code"; + if ( defined %$codes && defined $$codes{$id} ) { + $id = $$codes{$id}; + } + ${$n}{$code}=$id; + } + $decomp = $character_decomposition{$code}; + if ( length $decomp == 0 ) { + $decomp = "<single>"; + } + if (substr($decomp, 0, 1) ne '<') { + $decomp = "<canonical> " . $decomp; + } + @_ = split(" ", $decomp); + $tag = shift @_; + $tag = $character_decomposition_tag{$tag}; + $decomp = join( ", 0x", @_ ); + $decomp = "0x".$decomp; + $decomposition{$code} = $decomp; + $decomposition_tag{$code} = $tag; + $decomposition_pos{$code} = $position; + $len = scalar(@_); + $decomposition_len{$code} = $len; + +# we use canonical decompositions longer than 1 char +# we exlude Arabic ligatures from the table + if($len > 1 and $tag == 1) { +# ligature to add... + $start = shift @_; + $ligature{$start} = $ligature{$start}." ".$code; + } + +# adjust position + if($len != 0) { + $position += $len + 3; + } +} + + +# Code to integer mappings... +# +%category_code = numberize(qw{ + EMPTY + Mn Mc Me + Nd Nl No + Zs Zl Zp + Cc Cf Cs Co Cn + + Lu Ll Lt Lm Lo + Pc Pd Ps Pe Pi Pf Po + Sm Sc Sk So +}); +%bidi_category_code = numberize(qw{ + L R EN ES ET AN CS B S WS ON LRE LRO AL RLE RLO PDF NSM BN}); +%character_decomposition_tag = numberize(qw{ + <single> <canonical> <font> <noBreak> <initial> <medial> + <final> <isolated> <circle> <super> <sub> <vertical> + <wide> <narrow> <small> <square> <compat> <fraction> +}); +%mirrored_code = numberize(qw{N Y}); + +%joining_code = numberize(qw{U D R C}); + +# we map AI and XX to AL for now, as we can't handle them any better +%line_break_code = numberize(qw{OP CL QU GL NS EX SY + IS PR PO NU AL ID IN HY + BA BB B2 + ZW CM + SA + BK CR LF SG CB SP +}); + +# Read data into hashes... +# +open IN, "UnicodeData.txt"; +$position = 1; +while (<IN>) { + @fields = split /;/; + if ( length($fields[0]) < 5 ) { + if ( $fields[1] =~ /, First>/ ) { + $codeRangeBegin = $fields[0]; + } elsif ( $fields[1] =~ /, Last>/ ) { + for ( $i=hex($codeRangeBegin); $i<=hex($fields[0]); $i+=1 ) { + @fields2 = @fields; + $fields2[0] = sprintf "%lX", $i; + readUnicodeDataLine @fields2; + } + } else { + readUnicodeDataLine @fields; + } + } +} + +open IN2, "ArabicShaping.txt"; +$position = 1; +while (<IN2>) { + @fields = split /;/; + $code = shift @fields; + $dummy = shift @fields; + $join = shift @fields; + $join =~ s/ //g; + $join = $joining_code{$join}; + $joining{$code}=$join; +} + +open IN3, "LineBreak.txt"; +$position = 1; +while (<IN3>) { + @fields = split /;/; + $code = shift @fields; + $break = shift @fields; + if (length($break) > 0) { + chomp $break; + $break =~ s/ .*$//; + + $from = $code; + $to = $code; + if ( length($code) > 5 ) { + $from =~ s,\.\..*,,; + $to =~ s/......//; +# print "$from..$to = $break\n"; + } + if($break eq "AI") { + $break = "AL"; + } + if($break eq "XX") { + $break = "AL"; + } + for ( $i=hex($from); $i<=hex($to); $i+=1 ) { + $breaks{sprintf("%04X",$i)}=$line_break_code{$break}; + } + } +} + +# Build pages... +# +$rowtable_txt = ""; +$row_txt = ""; +$pos = 1; +for $row ( 0..255 ) { + $nonzero=0; + $txt = ""; + for $cell ( 0..255 ) { + $code = sprintf("%02X%02X",$row,$cell); + $info = $category{$code}; + $info = 0 if !defined $info; + $txt .= "\n " if $cell%8 == 0; + $txt .= "$info, "; + } + $therow = $row{$txt}; + if ( !defined $therow ) { + $therow = sprintf("%d",$pos); + $row_txt = $row_txt."$txt\n"; + $row{$txt}=$therow; + $pos += 1; + $size += 256; + } + $rowtable_txt .= "\n " if $row%8 == 0; + $rowtable_txt .= "$therow, "; +} + +print "// START OF GENERATED DATA\n\n"; +print "#ifndef QT_NO_UNICODETABLES\n\n"; + +# Print pages... +# + +print "const Q_UINT8 QUnicodeTables::unicode_info[] = {"; +print $rowtable_txt; +$size += 256; +print "\n\n"; +print $row_txt; +print "};\n\n"; +print "// $size bytes\n\n"; + +# Build decomposition tables +# +$rowtable_txt = ""; +$row_txt = ""; +$table_txt = + "const Q_UINT16 QUnicodeTables::decomposition_map[] = {\n 0,\n"; +$pos = 1; +for $row ( 0..255 ) { + $nonzero=0; + $txt = ""; + for $cell ( 0..255 ) { + $code = sprintf("%02X%02X",$row,$cell); + $txt .= "\n " if $cell%8 == 0; + if( $decomposition_tag{$code} != 0 ) { + $txt .= " $decomposition_pos{$code},"; + $table_txt .= " $decomposition_tag{$code},"; + $table_txt .= " 0x$code,"; + $table_txt .= " $decomposition{$code}, 0,\n"; + $size += 2 * $decomposition_len{$code} + 6; + } else { + $txt .= " 0,"; + } + } + $therow = $row{$txt}; + if ( !defined $therow ) { + $therow = sprintf("%d",$pos); + $row_txt = $row_txt."$txt\n"; + $row{$txt}=$therow; + $pos += 1; + $size += 512; + } + $rowtable_txt .= "\n " if $row%8 == 0; + $rowtable_txt .= "$therow, "; +} + +# Print decomposition tables +# +print "$table_txt\n};\n\n"; + +print "const Q_UINT16 QUnicodeTables::decomposition_info[] = {"; +print "$rowtable_txt\n"; +$size += 512; +print $row_txt; +print "};\n\n"; +print "// $size bytes\n\n"; + + +# build ligature tables +# +$size = 0; +$position = 1; +$pos = 1; +$rowtable_txt = ""; +$row_txt = ""; +$table_txt = + "const Q_UINT16 QUnicodeTables::ligature_map[] = {\n 0,\n"; +for $lig_row ( 0..255 ) { + $nonzero=0; + $txt = ""; + for $cell ( 0..255 ) { + $code = sprintf("%02X%02X",$lig_row,$cell); + $txt .= "\n " if $cell%8 == 0; + if( defined $ligature{$code} ) { + $txt .= " $position,"; + @ligature = split(" ", $ligature{$code}); +# we need to sort ligatures according to their length. +# long ones have to come first! + @ligature_sort = sort { $decomposition_len{$b} <=> $decomposition_len{$a} } @ligature; +# now replace each code by its position in +# the decomposition map. + undef(@lig_pos); + for $n (@ligature_sort) { + push(@lig_pos, $decomposition_pos{$n}); + } +# debug info + if( 0 ) { + print "ligatures: $ligature{$code}\n"; + $sort = join(" ", @ligature_sort); + print "sorted : $sort\n"; + } + $lig = join(", ", @lig_pos); + $table_txt .= " $lig, 0,\n"; + $size += 2 * scalar(@ligature) + 2; + $position += scalar(@ligature) + 1; + } else { + $txt .= " 0,"; + } + } + $therow = $lig_row{$txt}; + if ( !defined $therow ) { + $therow = sprintf("%d",$pos); + $row_txt = $row_txt."$txt\n"; + $lig_row{$txt}=$therow; + $pos += 1; + $size += 512; + } + $rowtable_txt .= "\n " if $lig_row%8 == 0; + $rowtable_txt .= "$therow, "; +} + +# Print ligature tables +# +print "$table_txt\n};\n\n"; +print "const Q_UINT16 QUnicodeTables::ligature_info[] = {"; +print "$rowtable_txt\n\n"; +$size+=512; +print $row_txt; +print "};\n\n"; +print "// $size bytes\n\n"; + + + +# Build direction/joining/mirrored pages... +# +$rowtable_txt = ""; +$row_txt = ""; +$pos = 1; +for $dir_row ( 0..255 ) { + $txt = ""; + for $cell ( 0..255 ) { + $code = sprintf("%02X%02X",$dir_row,$cell); + $dir = $bidi_category{$code}; + $dir = 0 if !defined $dir; + $join = $joining{$code}; + $join = 0 if !defined $join; + $mirr = $mirrored{$code}; + $mirr = 0 if !defined $mirr; + $info = $dir + 32*$join + 128*$mirr; + $txt .= "\n " if $cell%8 == 0; + $txt .= "$info, "; + } + $therow = $dir_row{$txt}; + if ( !defined $therow ) { + $therow = sprintf("%d",$pos); + $row_txt = $row_txt."$txt\n"; + $dir_row{$txt}=$therow; + $pos += 1; + $size+=256; + } + $rowtable_txt .= "\n " if $dir_row%8 == 0; + $rowtable_txt .= "$therow, "; +} + +# Print pages... +# +print "const Q_UINT8 QUnicodeTables::direction_info[] = {"; +print "$rowtable_txt\n\n"; +$size+=256; +print $row_txt; +print "};\n\n"; +print "// $size bytes\n\n"; + +# Build table of combining classes +# +$rowtable_txt = ""; +$row_txt = ""; +$pos = 1; +for $combining_row ( 0..255 ) { + $txt = ""; + for $cell ( 0..255 ) { + $code = sprintf("%02X%02X",$combining_row,$cell); + $info = $combining_class{$code}; + $info = 0 if !defined $info; + $txt .= "\n " if $cell%8 == 0; + $txt .= "$info, "; + } + $therow = $combining_row{$txt}; + if ( !defined $therow ) { + $therow = sprintf("%d",$pos); + $row_txt = $row_txt."$txt\n"; + $combining_row{$txt}=$therow; + $pos += 1; + $size += 256; + } + $rowtable_txt .= "\n " if $combining_row%8 == 0; + $rowtable_txt .= "$therow, "; +} + +# Print pages... +# +print "const Q_UINT8 QUnicodeTables::combining_info[] = {"; +print "$rowtable_txt\n\n"; +$size+=256; +print $row_txt; +print "};\n\n"; +print "// $size bytes\n\n"; + +# Build case info +# +$rowtable_txt = ""; +$row_txt = ""; +$pos = 1; +for $row ( 0..255 ) { + $nonzero=0; + $txt = ""; + for $cell ( 0..255 ) { + $code = sprintf("%02X%02X",$row,$cell); + $info = $uppercase{$code}; + if ( length( $info ) eq 0 ) { + $info = $lowercase{$code}; + } + $info =~ s/^0+//; + if ( length( $info ) eq 0 ) { + $info = "0"; + } else { + $info = "0x".lc($info); + } + if ( length( $info ) ne 1 ) { + $nonzero = 1; + } + $txt .= "\n " if $cell%8 == 0; + $txt .= "$info, "; + } + $therow = $case_row{$txt}; + if ( !defined $therow && $nonzero ne 0 ) { + $therow = sprintf("%d",$pos); + $row_txt = $row_txt."$txt\n"; + $case_row{$txt}=$therow; + $pos += 1; + $size += 512; + } + $rowtable_txt .= "\n " if $row%8 == 0; + if ( $nonzero ne 0 ) { + $rowtable_txt .= "$therow, "; + } else { + $rowtable_txt .= "0, "; + } +} + +# Print pages... +# +print "const Q_UINT16 QUnicodeTables::case_info[] = {"; +print "$rowtable_txt\n\n"; +$size+=512; +print $row_txt; +print "};\n"; +print "// $size bytes\n\n"; + +# Build decimal info +# +$rowtable_txt = ""; +$row_txt = ""; +$pos = 1; +for $row ( 0..255 ) { + $nonzero=0; + $txt = ""; + for $cell ( 0..255 ) { + $code = sprintf("%02X%02X",$row,$cell); + $info = $digit_value{$code}; + if ( length( $info ) eq 0 ) { + $info = -1; + } else { + $nonzero = 1; + } + $txt .= "\n " if $cell%8 == 0; + $txt .= "$info, "; + } + $therow = $decimal_row{$txt}; + if ( !defined $therow && $nonzero ne 0 ) { + $therow = sprintf("%d",$pos); + $row_txt = $row_txt."$txt\n"; + $decimal_row{$txt}=$therow; + $pos += 1; + $size += 256; + } + $rowtable_txt .= "\n " if $row%8 == 0; + if ( $nonzero ne 0 ) { + $rowtable_txt .= "$therow, "; + } else { + $rowtable_txt .= "0, "; + } +} + +# Print pages... +# +print "const Q_INT8 QUnicodeTables::decimal_info[] = {"; +print "$rowtable_txt\n\n"; +$size+=512; +print $row_txt; +print "};\n"; +print "// $size bytes\n\n"; + + +# Build line break info +# +$rowtable_txt = ""; +$row_txt = ""; +$pos = 1; +for $row ( 0..255 ) { + $txt = ""; + for $cell ( 0..255 ) { + $code = sprintf("%02X%02X",$row,$cell); + $info = $breaks{$code}; + if ( length( $info ) eq 0 ) { + $info = $line_break_code{"AL"}; + } + $txt .= "\n " if $cell%8 == 0; + $txt .= "$info, "; + } + $therow = $lb_row{$txt}; + if ( !defined $therow ) { + $therow = sprintf("%d",$pos); + $row_txt = $row_txt."$txt\n"; + $lb_row{$txt}=$therow; + $pos += 1; + $size += 256; + } + $rowtable_txt .= "\n " if $row%8 == 0; + $rowtable_txt .= "$therow, "; +} + +# Print pages... +# +print "const Q_UINT8 QUnicodeTables::line_break_info[] = {"; +print "$rowtable_txt\n\n"; +$size+=512; +print $row_txt; +print "};\n"; +print "// $size bytes\n\n"; + + + +print "#endif\n\n"; +print "// END OF GENERATED DATA\n\n"; + + +__END__ + +*/ + +// START OF GENERATED DATA + +#ifndef QT_NO_UNICODETABLES + +const Q_UINT8 QUnicodeTables::unicode_info[] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 9, 9, 9, 9, 9, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 30, 9, 9, 9, 38, 39, + 40, 41, 42, 43, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 44, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 45, + 22, 22, 22, 22, 46, 9, 9, 9, + 9, 9, 9, 9, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 47, + 48, 48, 48, 48, 48, 48, 48, 48, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 22, 50, 51, 22, 52, 53, 54, + + + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 7, 26, 26, 26, 28, 26, 26, 26, + 22, 23, 26, 27, 26, 21, 26, 26, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 26, 26, 27, 27, 27, 26, + 26, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 22, 26, 23, 29, 20, + 29, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 22, 27, 23, 27, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 7, 26, 28, 28, 28, 28, 30, 30, + 29, 30, 16, 24, 27, 21, 30, 29, + 30, 27, 6, 6, 29, 16, 30, 26, + 29, 6, 16, 25, 6, 6, 6, 26, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 27, + 15, 15, 15, 15, 15, 15, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 27, + 16, 16, 16, 16, 16, 16, 16, 16, + + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 16, 15, 16, 15, 16, 15, 16, 15, + 16, 15, 16, 15, 16, 15, 16, 15, + 16, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 15, 16, 15, 16, 15, 16, 16, + 16, 15, 15, 16, 15, 16, 15, 15, + 16, 15, 15, 15, 16, 16, 15, 15, + 15, 15, 16, 15, 15, 16, 15, 15, + 15, 16, 16, 16, 15, 15, 16, 15, + 15, 16, 15, 16, 15, 16, 15, 15, + 16, 15, 16, 16, 15, 16, 15, 15, + 16, 15, 15, 15, 16, 15, 16, 15, + 15, 16, 16, 19, 15, 16, 16, 16, + 19, 19, 19, 19, 15, 17, 16, 15, + 17, 16, 15, 17, 16, 15, 16, 15, + 16, 15, 16, 15, 16, 15, 16, 15, + 16, 15, 16, 15, 16, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 16, 15, 17, 16, 15, 16, 15, 15, + 15, 16, 15, 16, 15, 16, 15, 16, + + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 0, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 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, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 0, 0, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 29, 29, 18, 18, 18, 18, 18, + 18, 18, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 18, 18, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 18, 18, 18, 18, 18, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 18, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 29, 29, 0, 0, + 0, 0, 18, 0, 0, 0, 26, 0, + 0, 0, 0, 0, 29, 29, 15, 26, + 15, 15, 15, 0, 15, 0, 15, 15, + 16, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 0, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 0, + 16, 16, 15, 15, 15, 16, 16, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 16, 16, 16, 16, 15, 16, 27, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 30, 1, 1, 1, 1, 0, + 3, 3, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 15, 16, 15, 16, 15, 16, 15, + 16, 15, 16, 15, 16, 15, 16, 0, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 0, 0, + 15, 16, 0, 0, 0, 0, 0, 0, + + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 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, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 0, + 0, 18, 26, 26, 26, 26, 26, 26, + 0, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 0, 26, 21, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 1, 1, 26, 1, + 26, 1, 1, 26, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 0, 0, 0, 0, 0, + 19, 19, 19, 26, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 26, 0, 0, 0, 26, + 0, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 0, 0, 0, 0, 0, + 18, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 26, 26, 26, 26, 19, 19, + 1, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 26, 19, 1, 1, + 1, 1, 1, 1, 1, 11, 3, 1, + 1, 1, 1, 1, 1, 18, 18, 1, + 1, 30, 1, 1, 1, 1, 0, 0, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 19, 19, 19, 30, 30, 0, + + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 0, 11, + 19, 1, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 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, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 19, 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, 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, + 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, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 1, 1, 2, 0, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 0, 0, 1, 19, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 1, 0, 0, + 19, 1, 1, 1, 1, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 1, 1, 26, 26, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 2, 0, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 0, 19, + 19, 0, 0, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 0, 0, 0, 19, 19, + 19, 19, 0, 0, 1, 0, 2, 2, + 2, 1, 1, 1, 1, 0, 0, 2, + 2, 0, 0, 2, 2, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 19, 19, 0, 19, + 19, 19, 1, 1, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 19, 19, 28, 28, 6, 6, 6, 6, + 6, 6, 30, 0, 0, 0, 0, 0, + + 0, 0, 1, 0, 0, 19, 19, 19, + 19, 19, 19, 0, 0, 0, 0, 19, + 19, 0, 0, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 19, 0, 19, 19, 0, + 19, 19, 0, 0, 1, 0, 2, 2, + 2, 1, 1, 0, 0, 0, 0, 1, + 1, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 19, 19, 19, 19, 0, 19, 0, + 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 1, 1, 19, 19, 19, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 2, 0, 19, 19, 19, + 19, 19, 19, 19, 0, 19, 0, 19, + 19, 19, 0, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 19, 0, 19, 19, 19, + 19, 19, 0, 0, 1, 19, 2, 2, + 2, 1, 1, 1, 1, 1, 0, 1, + 1, 2, 0, 2, 2, 1, 0, 0, + 19, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 1, 2, 2, 0, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 0, 19, + 19, 0, 0, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 19, 0, 0, 19, 19, + 19, 19, 0, 0, 1, 19, 2, 1, + 2, 1, 1, 1, 0, 0, 0, 2, + 2, 0, 0, 2, 2, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, + 0, 0, 0, 0, 19, 19, 0, 19, + 19, 19, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 30, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 19, 0, 19, 19, 19, + 19, 19, 19, 0, 0, 0, 19, 19, + 19, 0, 19, 19, 19, 19, 0, 0, + 0, 19, 19, 0, 19, 0, 19, 19, + 0, 0, 0, 19, 19, 0, 0, 0, + 19, 19, 19, 0, 0, 0, 19, 19, + 19, 19, 19, 19, 19, 19, 0, 19, + 19, 19, 0, 0, 0, 0, 2, 2, + 1, 2, 2, 0, 0, 0, 2, 2, + 2, 0, 2, 2, 2, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 6, 6, 6, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 2, 2, 2, 0, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 0, 19, 19, 19, + 19, 19, 0, 0, 0, 0, 1, 1, + 1, 2, 2, 2, 2, 0, 1, 1, + 1, 0, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 19, 19, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 2, 0, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 0, 19, 19, 19, + 19, 19, 0, 0, 0, 0, 2, 1, + 2, 2, 2, 2, 2, 0, 1, 2, + 2, 0, 2, 2, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 0, + 0, 0, 0, 0, 0, 0, 19, 0, + 19, 19, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 2, 2, 0, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 0, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 0, 0, 0, 0, 2, 2, + 2, 1, 1, 1, 0, 0, 2, 2, + 2, 0, 2, 2, 2, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, + 19, 19, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 2, 0, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, + 0, 0, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 0, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 0, 19, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 0, + 0, 0, 1, 0, 0, 0, 0, 2, + 2, 2, 1, 1, 1, 0, 1, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 2, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 1, 19, 19, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 28, + 19, 19, 19, 19, 19, 19, 18, 1, + 1, 1, 1, 1, 1, 1, 1, 26, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 26, 26, 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, 19, 19, 0, 19, 0, 0, 19, + 19, 0, 19, 0, 0, 19, 0, 0, + 0, 0, 0, 0, 19, 19, 19, 19, + 0, 19, 19, 19, 19, 19, 19, 19, + 0, 19, 19, 19, 0, 19, 0, 19, + 0, 0, 19, 19, 0, 19, 19, 19, + 19, 1, 19, 19, 1, 1, 1, 1, + 1, 1, 0, 1, 1, 19, 0, 0, + 19, 19, 19, 19, 19, 0, 18, 0, + 1, 1, 1, 1, 1, 1, 0, 0, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 0, 19, 19, 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, + + 19, 30, 30, 30, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 30, 30, 30, 30, 30, + 1, 1, 30, 30, 30, 30, 30, 30, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 30, 1, 30, 1, + 30, 1, 22, 23, 22, 23, 2, 2, + 19, 19, 19, 19, 19, 19, 19, 19, + 0, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, + 1, 1, 1, 1, 1, 26, 1, 1, + 19, 19, 19, 19, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 30, 30, + 30, 30, 30, 30, 30, 30, 1, 30, + 30, 30, 30, 30, 30, 0, 0, 30, + 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, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 0, 19, 19, 19, 19, 19, + 0, 19, 19, 0, 2, 1, 1, 1, + 1, 2, 1, 0, 0, 0, 1, 1, + 2, 1, 0, 0, 0, 0, 0, 0, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 26, 26, 26, 26, 26, 26, + 19, 19, 19, 19, 19, 19, 2, 2, + 1, 1, 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, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 0, 0, 26, 0, 0, 0, 0, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 0, 0, 0, 0, 0, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 0, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 0, 0, 0, 0, 0, 0, + + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 0, 19, 19, 19, 19, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 0, 19, 19, 19, 19, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 0, 19, 19, 19, 19, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 0, 19, 19, 19, 19, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 0, 19, 19, 19, 19, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 0, 19, 19, 19, 19, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 0, 0, 0, 0, 0, + 0, 26, 26, 26, 26, 26, 26, 26, + 26, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 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, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 26, 26, 19, + 19, 19, 19, 19, 19, 19, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 22, 23, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 26, 26, 26, 5, 5, + 5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 19, 19, + 19, 19, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 1, 1, 1, 26, 26, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 19, 19, + 19, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, + 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 26, 26, 26, 18, + 26, 26, 26, 28, 19, 0, 0, 0, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 26, 26, 26, 26, 26, 26, 21, 26, + 26, 26, 26, 1, 1, 1, 11, 0, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 0, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 0, 0, 0, 0, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 1, 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, 0, 0, 0, 0, 0, 0, 0, + + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 16, 16, + 16, 16, 16, 16, 0, 0, 0, 0, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, + 15, 16, 0, 0, 0, 0, 0, 0, + + 16, 16, 16, 16, 16, 16, 16, 16, + 15, 15, 15, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 0, 0, + 15, 15, 15, 15, 15, 15, 0, 0, + 16, 16, 16, 16, 16, 16, 16, 16, + 15, 15, 15, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, + 15, 15, 15, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 0, 0, + 15, 15, 15, 15, 15, 15, 0, 0, + 16, 16, 16, 16, 16, 16, 16, 16, + 0, 15, 0, 15, 0, 15, 0, 15, + 16, 16, 16, 16, 16, 16, 16, 16, + 15, 15, 15, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 0, 0, + 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, + 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, + 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, + 16, 16, 16, 16, 16, 0, 16, 16, + 15, 15, 15, 15, 17, 29, 16, 29, + 29, 29, 16, 16, 16, 0, 16, 16, + 15, 15, 15, 15, 17, 29, 29, 29, + 16, 16, 16, 16, 0, 0, 16, 16, + 15, 15, 15, 15, 0, 29, 29, 29, + 16, 16, 16, 16, 16, 16, 16, 16, + 15, 15, 15, 15, 15, 29, 29, 29, + 0, 0, 16, 16, 16, 0, 16, 16, + 15, 15, 15, 15, 17, 29, 29, 0, + + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 11, 11, 11, 11, + 21, 21, 21, 21, 21, 21, 26, 26, + 24, 25, 22, 24, 24, 25, 22, 24, + 26, 26, 26, 26, 26, 26, 26, 26, + 8, 9, 11, 11, 11, 11, 11, 7, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 24, 25, 26, 26, 26, 26, 20, + 20, 26, 26, 26, 27, 22, 23, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 27, 0, 0, 0, 0, 26, + 0, 0, 0, 0, 0, 0, 0, 7, + 11, 11, 11, 11, 0, 0, 0, 0, + 0, 0, 11, 11, 11, 11, 11, 11, + 6, 16, 0, 0, 6, 6, 6, 6, + 6, 6, 27, 27, 27, 22, 23, 16, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 27, 27, 27, 22, 23, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 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, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 3, 3, + 3, 1, 3, 3, 3, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 30, 30, 15, 30, 30, 30, 30, 15, + 30, 30, 16, 15, 15, 15, 16, 16, + 15, 15, 15, 16, 30, 15, 30, 30, + 30, 15, 15, 15, 15, 15, 30, 30, + 30, 30, 30, 30, 15, 30, 15, 30, + 15, 30, 15, 15, 15, 15, 30, 16, + 15, 15, 30, 15, 16, 19, 19, 19, + 19, 16, 30, 0, 0, 16, 15, 15, + 27, 27, 27, 27, 27, 15, 16, 16, + 16, 16, 30, 27, 0, 0, 0, 0, + 0, 0, 0, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 27, 27, 27, 27, 27, 30, 30, 30, + 30, 30, 27, 27, 30, 30, 30, 30, + 27, 30, 30, 27, 30, 30, 27, 30, + 30, 30, 30, 30, 30, 30, 27, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 27, 27, + 30, 30, 27, 30, 27, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + + 30, 30, 30, 30, 30, 30, 30, 30, + 27, 27, 27, 27, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 27, 27, 30, 30, 30, 30, 30, 30, + 30, 22, 23, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 27, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 22, 23, 26, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 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, + + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 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, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 0, + + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 27, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 27, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 27, 27, 27, 27, 27, 27, 27, 27, + + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 0, 0, 30, 30, + 0, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 27, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 0, 0, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 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, 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, 30, 30, 30, 30, 0, 30, 30, + 30, 30, 0, 0, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 0, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 0, 30, 0, 30, + 30, 30, 30, 0, 0, 0, 30, 0, + 30, 30, 30, 30, 30, 30, 30, 0, + 0, 30, 30, 30, 30, 30, 30, 30, + 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 22, 23, 22, 23, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 30, 0, 0, 0, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 0, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 22, 23, + 22, 23, 22, 23, 0, 0, 0, 0, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 22, 23, 22, 23, 22, + 23, 22, 23, 22, 23, 22, 23, 22, + 23, 22, 23, 22, 23, 22, 23, 22, + 23, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 22, 23, 22, 23, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 22, 23, 27, 27, + + 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, 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, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 0, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 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, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 0, 0, 0, 0, + + 7, 26, 26, 26, 30, 18, 19, 5, + 22, 23, 22, 23, 22, 23, 22, 23, + 22, 23, 30, 30, 22, 23, 22, 23, + 22, 23, 22, 23, 21, 22, 23, 23, + 30, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 1, 1, 1, 1, 1, 1, + 21, 18, 18, 18, 18, 18, 30, 30, + 5, 5, 5, 18, 19, 26, 30, 30, + 0, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, + 0, 1, 1, 29, 29, 18, 18, 19, + 21, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 20, 18, 18, 18, 19, + + 0, 0, 0, 0, 0, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 0, 0, + 0, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, + 30, 30, 6, 6, 6, 6, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 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, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 0, 0, 0, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 0, 0, 0, 30, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 0, 0, 0, 0, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 0, + + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 0, + 0, 0, 0, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 0, 0, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 0, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 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, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 0, 0, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 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, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 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, 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, + + 16, 16, 16, 16, 16, 16, 16, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 16, 16, 16, 16, + 0, 0, 0, 0, 0, 19, 1, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 27, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, + 19, 19, 19, 19, 19, 0, 19, 0, + 19, 19, 0, 19, 19, 0, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 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, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 22, 23, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 0, 0, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 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, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 28, 0, 0, 0, + + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 26, 21, 21, 20, 20, 22, 23, 22, + 23, 22, 23, 22, 23, 22, 23, 22, + 23, 22, 23, 22, 23, 26, 26, 0, + 0, 26, 26, 26, 26, 20, 20, 20, + 26, 26, 26, 0, 26, 26, 26, 26, + 21, 22, 23, 22, 23, 22, 23, 26, + 26, 26, 27, 21, 27, 27, 27, 0, + 26, 28, 26, 26, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 0, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 0, 11, + + 0, 26, 26, 26, 28, 26, 26, 26, + 22, 23, 26, 27, 26, 21, 26, 26, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 26, 26, 27, 27, 27, 26, + 26, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 22, 26, 23, 29, 20, + 29, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 22, 27, 23, 27, 22, + 23, 26, 22, 23, 26, 20, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 18, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 18, 18, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 0, + 0, 0, 19, 19, 19, 19, 19, 19, + 0, 0, 19, 19, 19, 19, 19, 19, + 0, 0, 19, 19, 19, 19, 19, 19, + 0, 0, 19, 19, 19, 0, 0, 0, + 28, 28, 27, 29, 30, 28, 28, 0, + 30, 27, 27, 27, 27, 30, 30, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 11, 11, 11, 30, 30, 0, 0, +}; + +// 14080 bytes + +const Q_UINT16 QUnicodeTables::decomposition_map[] = { + 0, + 3, 0x00A0, 0x0020, 0, + 16, 0x00A8, 0x0020, 0x0308, 0, + 9, 0x00AA, 0x0061, 0, + 16, 0x00AF, 0x0020, 0x0304, 0, + 9, 0x00B2, 0x0032, 0, + 9, 0x00B3, 0x0033, 0, + 16, 0x00B4, 0x0020, 0x0301, 0, + 16, 0x00B5, 0x03BC, 0, + 16, 0x00B8, 0x0020, 0x0327, 0, + 9, 0x00B9, 0x0031, 0, + 9, 0x00BA, 0x006F, 0, + 17, 0x00BC, 0x0031, 0x2044, 0x0034, 0, + 17, 0x00BD, 0x0031, 0x2044, 0x0032, 0, + 17, 0x00BE, 0x0033, 0x2044, 0x0034, 0, + 1, 0x00C0, 0x0041, 0x0300, 0, + 1, 0x00C1, 0x0041, 0x0301, 0, + 1, 0x00C2, 0x0041, 0x0302, 0, + 1, 0x00C3, 0x0041, 0x0303, 0, + 1, 0x00C4, 0x0041, 0x0308, 0, + 1, 0x00C5, 0x0041, 0x030A, 0, + 1, 0x00C7, 0x0043, 0x0327, 0, + 1, 0x00C8, 0x0045, 0x0300, 0, + 1, 0x00C9, 0x0045, 0x0301, 0, + 1, 0x00CA, 0x0045, 0x0302, 0, + 1, 0x00CB, 0x0045, 0x0308, 0, + 1, 0x00CC, 0x0049, 0x0300, 0, + 1, 0x00CD, 0x0049, 0x0301, 0, + 1, 0x00CE, 0x0049, 0x0302, 0, + 1, 0x00CF, 0x0049, 0x0308, 0, + 1, 0x00D1, 0x004E, 0x0303, 0, + 1, 0x00D2, 0x004F, 0x0300, 0, + 1, 0x00D3, 0x004F, 0x0301, 0, + 1, 0x00D4, 0x004F, 0x0302, 0, + 1, 0x00D5, 0x004F, 0x0303, 0, + 1, 0x00D6, 0x004F, 0x0308, 0, + 1, 0x00D9, 0x0055, 0x0300, 0, + 1, 0x00DA, 0x0055, 0x0301, 0, + 1, 0x00DB, 0x0055, 0x0302, 0, + 1, 0x00DC, 0x0055, 0x0308, 0, + 1, 0x00DD, 0x0059, 0x0301, 0, + 1, 0x00E0, 0x0061, 0x0300, 0, + 1, 0x00E1, 0x0061, 0x0301, 0, + 1, 0x00E2, 0x0061, 0x0302, 0, + 1, 0x00E3, 0x0061, 0x0303, 0, + 1, 0x00E4, 0x0061, 0x0308, 0, + 1, 0x00E5, 0x0061, 0x030A, 0, + 1, 0x00E7, 0x0063, 0x0327, 0, + 1, 0x00E8, 0x0065, 0x0300, 0, + 1, 0x00E9, 0x0065, 0x0301, 0, + 1, 0x00EA, 0x0065, 0x0302, 0, + 1, 0x00EB, 0x0065, 0x0308, 0, + 1, 0x00EC, 0x0069, 0x0300, 0, + 1, 0x00ED, 0x0069, 0x0301, 0, + 1, 0x00EE, 0x0069, 0x0302, 0, + 1, 0x00EF, 0x0069, 0x0308, 0, + 1, 0x00F1, 0x006E, 0x0303, 0, + 1, 0x00F2, 0x006F, 0x0300, 0, + 1, 0x00F3, 0x006F, 0x0301, 0, + 1, 0x00F4, 0x006F, 0x0302, 0, + 1, 0x00F5, 0x006F, 0x0303, 0, + 1, 0x00F6, 0x006F, 0x0308, 0, + 1, 0x00F9, 0x0075, 0x0300, 0, + 1, 0x00FA, 0x0075, 0x0301, 0, + 1, 0x00FB, 0x0075, 0x0302, 0, + 1, 0x00FC, 0x0075, 0x0308, 0, + 1, 0x00FD, 0x0079, 0x0301, 0, + 1, 0x00FF, 0x0079, 0x0308, 0, + 1, 0x0100, 0x0041, 0x0304, 0, + 1, 0x0101, 0x0061, 0x0304, 0, + 1, 0x0102, 0x0041, 0x0306, 0, + 1, 0x0103, 0x0061, 0x0306, 0, + 1, 0x0104, 0x0041, 0x0328, 0, + 1, 0x0105, 0x0061, 0x0328, 0, + 1, 0x0106, 0x0043, 0x0301, 0, + 1, 0x0107, 0x0063, 0x0301, 0, + 1, 0x0108, 0x0043, 0x0302, 0, + 1, 0x0109, 0x0063, 0x0302, 0, + 1, 0x010A, 0x0043, 0x0307, 0, + 1, 0x010B, 0x0063, 0x0307, 0, + 1, 0x010C, 0x0043, 0x030C, 0, + 1, 0x010D, 0x0063, 0x030C, 0, + 1, 0x010E, 0x0044, 0x030C, 0, + 1, 0x010F, 0x0064, 0x030C, 0, + 1, 0x0112, 0x0045, 0x0304, 0, + 1, 0x0113, 0x0065, 0x0304, 0, + 1, 0x0114, 0x0045, 0x0306, 0, + 1, 0x0115, 0x0065, 0x0306, 0, + 1, 0x0116, 0x0045, 0x0307, 0, + 1, 0x0117, 0x0065, 0x0307, 0, + 1, 0x0118, 0x0045, 0x0328, 0, + 1, 0x0119, 0x0065, 0x0328, 0, + 1, 0x011A, 0x0045, 0x030C, 0, + 1, 0x011B, 0x0065, 0x030C, 0, + 1, 0x011C, 0x0047, 0x0302, 0, + 1, 0x011D, 0x0067, 0x0302, 0, + 1, 0x011E, 0x0047, 0x0306, 0, + 1, 0x011F, 0x0067, 0x0306, 0, + 1, 0x0120, 0x0047, 0x0307, 0, + 1, 0x0121, 0x0067, 0x0307, 0, + 1, 0x0122, 0x0047, 0x0327, 0, + 1, 0x0123, 0x0067, 0x0327, 0, + 1, 0x0124, 0x0048, 0x0302, 0, + 1, 0x0125, 0x0068, 0x0302, 0, + 1, 0x0128, 0x0049, 0x0303, 0, + 1, 0x0129, 0x0069, 0x0303, 0, + 1, 0x012A, 0x0049, 0x0304, 0, + 1, 0x012B, 0x0069, 0x0304, 0, + 1, 0x012C, 0x0049, 0x0306, 0, + 1, 0x012D, 0x0069, 0x0306, 0, + 1, 0x012E, 0x0049, 0x0328, 0, + 1, 0x012F, 0x0069, 0x0328, 0, + 1, 0x0130, 0x0049, 0x0307, 0, + 16, 0x0132, 0x0049, 0x004A, 0, + 16, 0x0133, 0x0069, 0x006A, 0, + 1, 0x0134, 0x004A, 0x0302, 0, + 1, 0x0135, 0x006A, 0x0302, 0, + 1, 0x0136, 0x004B, 0x0327, 0, + 1, 0x0137, 0x006B, 0x0327, 0, + 1, 0x0139, 0x004C, 0x0301, 0, + 1, 0x013A, 0x006C, 0x0301, 0, + 1, 0x013B, 0x004C, 0x0327, 0, + 1, 0x013C, 0x006C, 0x0327, 0, + 1, 0x013D, 0x004C, 0x030C, 0, + 1, 0x013E, 0x006C, 0x030C, 0, + 16, 0x013F, 0x004C, 0x00B7, 0, + 16, 0x0140, 0x006C, 0x00B7, 0, + 1, 0x0143, 0x004E, 0x0301, 0, + 1, 0x0144, 0x006E, 0x0301, 0, + 1, 0x0145, 0x004E, 0x0327, 0, + 1, 0x0146, 0x006E, 0x0327, 0, + 1, 0x0147, 0x004E, 0x030C, 0, + 1, 0x0148, 0x006E, 0x030C, 0, + 16, 0x0149, 0x02BC, 0x006E, 0, + 1, 0x014C, 0x004F, 0x0304, 0, + 1, 0x014D, 0x006F, 0x0304, 0, + 1, 0x014E, 0x004F, 0x0306, 0, + 1, 0x014F, 0x006F, 0x0306, 0, + 1, 0x0150, 0x004F, 0x030B, 0, + 1, 0x0151, 0x006F, 0x030B, 0, + 1, 0x0154, 0x0052, 0x0301, 0, + 1, 0x0155, 0x0072, 0x0301, 0, + 1, 0x0156, 0x0052, 0x0327, 0, + 1, 0x0157, 0x0072, 0x0327, 0, + 1, 0x0158, 0x0052, 0x030C, 0, + 1, 0x0159, 0x0072, 0x030C, 0, + 1, 0x015A, 0x0053, 0x0301, 0, + 1, 0x015B, 0x0073, 0x0301, 0, + 1, 0x015C, 0x0053, 0x0302, 0, + 1, 0x015D, 0x0073, 0x0302, 0, + 1, 0x015E, 0x0053, 0x0327, 0, + 1, 0x015F, 0x0073, 0x0327, 0, + 1, 0x0160, 0x0053, 0x030C, 0, + 1, 0x0161, 0x0073, 0x030C, 0, + 1, 0x0162, 0x0054, 0x0327, 0, + 1, 0x0163, 0x0074, 0x0327, 0, + 1, 0x0164, 0x0054, 0x030C, 0, + 1, 0x0165, 0x0074, 0x030C, 0, + 1, 0x0168, 0x0055, 0x0303, 0, + 1, 0x0169, 0x0075, 0x0303, 0, + 1, 0x016A, 0x0055, 0x0304, 0, + 1, 0x016B, 0x0075, 0x0304, 0, + 1, 0x016C, 0x0055, 0x0306, 0, + 1, 0x016D, 0x0075, 0x0306, 0, + 1, 0x016E, 0x0055, 0x030A, 0, + 1, 0x016F, 0x0075, 0x030A, 0, + 1, 0x0170, 0x0055, 0x030B, 0, + 1, 0x0171, 0x0075, 0x030B, 0, + 1, 0x0172, 0x0055, 0x0328, 0, + 1, 0x0173, 0x0075, 0x0328, 0, + 1, 0x0174, 0x0057, 0x0302, 0, + 1, 0x0175, 0x0077, 0x0302, 0, + 1, 0x0176, 0x0059, 0x0302, 0, + 1, 0x0177, 0x0079, 0x0302, 0, + 1, 0x0178, 0x0059, 0x0308, 0, + 1, 0x0179, 0x005A, 0x0301, 0, + 1, 0x017A, 0x007A, 0x0301, 0, + 1, 0x017B, 0x005A, 0x0307, 0, + 1, 0x017C, 0x007A, 0x0307, 0, + 1, 0x017D, 0x005A, 0x030C, 0, + 1, 0x017E, 0x007A, 0x030C, 0, + 16, 0x017F, 0x0073, 0, + 1, 0x01A0, 0x004F, 0x031B, 0, + 1, 0x01A1, 0x006F, 0x031B, 0, + 1, 0x01AF, 0x0055, 0x031B, 0, + 1, 0x01B0, 0x0075, 0x031B, 0, + 16, 0x01C4, 0x0044, 0x017D, 0, + 16, 0x01C5, 0x0044, 0x017E, 0, + 16, 0x01C6, 0x0064, 0x017E, 0, + 16, 0x01C7, 0x004C, 0x004A, 0, + 16, 0x01C8, 0x004C, 0x006A, 0, + 16, 0x01C9, 0x006C, 0x006A, 0, + 16, 0x01CA, 0x004E, 0x004A, 0, + 16, 0x01CB, 0x004E, 0x006A, 0, + 16, 0x01CC, 0x006E, 0x006A, 0, + 1, 0x01CD, 0x0041, 0x030C, 0, + 1, 0x01CE, 0x0061, 0x030C, 0, + 1, 0x01CF, 0x0049, 0x030C, 0, + 1, 0x01D0, 0x0069, 0x030C, 0, + 1, 0x01D1, 0x004F, 0x030C, 0, + 1, 0x01D2, 0x006F, 0x030C, 0, + 1, 0x01D3, 0x0055, 0x030C, 0, + 1, 0x01D4, 0x0075, 0x030C, 0, + 1, 0x01D5, 0x00DC, 0x0304, 0, + 1, 0x01D6, 0x00FC, 0x0304, 0, + 1, 0x01D7, 0x00DC, 0x0301, 0, + 1, 0x01D8, 0x00FC, 0x0301, 0, + 1, 0x01D9, 0x00DC, 0x030C, 0, + 1, 0x01DA, 0x00FC, 0x030C, 0, + 1, 0x01DB, 0x00DC, 0x0300, 0, + 1, 0x01DC, 0x00FC, 0x0300, 0, + 1, 0x01DE, 0x00C4, 0x0304, 0, + 1, 0x01DF, 0x00E4, 0x0304, 0, + 1, 0x01E0, 0x0226, 0x0304, 0, + 1, 0x01E1, 0x0227, 0x0304, 0, + 1, 0x01E2, 0x00C6, 0x0304, 0, + 1, 0x01E3, 0x00E6, 0x0304, 0, + 1, 0x01E6, 0x0047, 0x030C, 0, + 1, 0x01E7, 0x0067, 0x030C, 0, + 1, 0x01E8, 0x004B, 0x030C, 0, + 1, 0x01E9, 0x006B, 0x030C, 0, + 1, 0x01EA, 0x004F, 0x0328, 0, + 1, 0x01EB, 0x006F, 0x0328, 0, + 1, 0x01EC, 0x01EA, 0x0304, 0, + 1, 0x01ED, 0x01EB, 0x0304, 0, + 1, 0x01EE, 0x01B7, 0x030C, 0, + 1, 0x01EF, 0x0292, 0x030C, 0, + 1, 0x01F0, 0x006A, 0x030C, 0, + 16, 0x01F1, 0x0044, 0x005A, 0, + 16, 0x01F2, 0x0044, 0x007A, 0, + 16, 0x01F3, 0x0064, 0x007A, 0, + 1, 0x01F4, 0x0047, 0x0301, 0, + 1, 0x01F5, 0x0067, 0x0301, 0, + 1, 0x01F8, 0x004E, 0x0300, 0, + 1, 0x01F9, 0x006E, 0x0300, 0, + 1, 0x01FA, 0x00C5, 0x0301, 0, + 1, 0x01FB, 0x00E5, 0x0301, 0, + 1, 0x01FC, 0x00C6, 0x0301, 0, + 1, 0x01FD, 0x00E6, 0x0301, 0, + 1, 0x01FE, 0x00D8, 0x0301, 0, + 1, 0x01FF, 0x00F8, 0x0301, 0, + 1, 0x0200, 0x0041, 0x030F, 0, + 1, 0x0201, 0x0061, 0x030F, 0, + 1, 0x0202, 0x0041, 0x0311, 0, + 1, 0x0203, 0x0061, 0x0311, 0, + 1, 0x0204, 0x0045, 0x030F, 0, + 1, 0x0205, 0x0065, 0x030F, 0, + 1, 0x0206, 0x0045, 0x0311, 0, + 1, 0x0207, 0x0065, 0x0311, 0, + 1, 0x0208, 0x0049, 0x030F, 0, + 1, 0x0209, 0x0069, 0x030F, 0, + 1, 0x020A, 0x0049, 0x0311, 0, + 1, 0x020B, 0x0069, 0x0311, 0, + 1, 0x020C, 0x004F, 0x030F, 0, + 1, 0x020D, 0x006F, 0x030F, 0, + 1, 0x020E, 0x004F, 0x0311, 0, + 1, 0x020F, 0x006F, 0x0311, 0, + 1, 0x0210, 0x0052, 0x030F, 0, + 1, 0x0211, 0x0072, 0x030F, 0, + 1, 0x0212, 0x0052, 0x0311, 0, + 1, 0x0213, 0x0072, 0x0311, 0, + 1, 0x0214, 0x0055, 0x030F, 0, + 1, 0x0215, 0x0075, 0x030F, 0, + 1, 0x0216, 0x0055, 0x0311, 0, + 1, 0x0217, 0x0075, 0x0311, 0, + 1, 0x0218, 0x0053, 0x0326, 0, + 1, 0x0219, 0x0073, 0x0326, 0, + 1, 0x021A, 0x0054, 0x0326, 0, + 1, 0x021B, 0x0074, 0x0326, 0, + 1, 0x021E, 0x0048, 0x030C, 0, + 1, 0x021F, 0x0068, 0x030C, 0, + 1, 0x0226, 0x0041, 0x0307, 0, + 1, 0x0227, 0x0061, 0x0307, 0, + 1, 0x0228, 0x0045, 0x0327, 0, + 1, 0x0229, 0x0065, 0x0327, 0, + 1, 0x022A, 0x00D6, 0x0304, 0, + 1, 0x022B, 0x00F6, 0x0304, 0, + 1, 0x022C, 0x00D5, 0x0304, 0, + 1, 0x022D, 0x00F5, 0x0304, 0, + 1, 0x022E, 0x004F, 0x0307, 0, + 1, 0x022F, 0x006F, 0x0307, 0, + 1, 0x0230, 0x022E, 0x0304, 0, + 1, 0x0231, 0x022F, 0x0304, 0, + 1, 0x0232, 0x0059, 0x0304, 0, + 1, 0x0233, 0x0079, 0x0304, 0, + 9, 0x02B0, 0x0068, 0, + 9, 0x02B1, 0x0266, 0, + 9, 0x02B2, 0x006A, 0, + 9, 0x02B3, 0x0072, 0, + 9, 0x02B4, 0x0279, 0, + 9, 0x02B5, 0x027B, 0, + 9, 0x02B6, 0x0281, 0, + 9, 0x02B7, 0x0077, 0, + 9, 0x02B8, 0x0079, 0, + 16, 0x02D8, 0x0020, 0x0306, 0, + 16, 0x02D9, 0x0020, 0x0307, 0, + 16, 0x02DA, 0x0020, 0x030A, 0, + 16, 0x02DB, 0x0020, 0x0328, 0, + 16, 0x02DC, 0x0020, 0x0303, 0, + 16, 0x02DD, 0x0020, 0x030B, 0, + 9, 0x02E0, 0x0263, 0, + 9, 0x02E1, 0x006C, 0, + 9, 0x02E2, 0x0073, 0, + 9, 0x02E3, 0x0078, 0, + 9, 0x02E4, 0x0295, 0, + 1, 0x0340, 0x0300, 0, + 1, 0x0341, 0x0301, 0, + 1, 0x0343, 0x0313, 0, + 1, 0x0344, 0x0308, 0x0301, 0, + 1, 0x0374, 0x02B9, 0, + 16, 0x037A, 0x0020, 0x0345, 0, + 1, 0x037E, 0x003B, 0, + 16, 0x0384, 0x0020, 0x0301, 0, + 1, 0x0385, 0x00A8, 0x0301, 0, + 1, 0x0386, 0x0391, 0x0301, 0, + 1, 0x0387, 0x00B7, 0, + 1, 0x0388, 0x0395, 0x0301, 0, + 1, 0x0389, 0x0397, 0x0301, 0, + 1, 0x038A, 0x0399, 0x0301, 0, + 1, 0x038C, 0x039F, 0x0301, 0, + 1, 0x038E, 0x03A5, 0x0301, 0, + 1, 0x038F, 0x03A9, 0x0301, 0, + 1, 0x0390, 0x03CA, 0x0301, 0, + 1, 0x03AA, 0x0399, 0x0308, 0, + 1, 0x03AB, 0x03A5, 0x0308, 0, + 1, 0x03AC, 0x03B1, 0x0301, 0, + 1, 0x03AD, 0x03B5, 0x0301, 0, + 1, 0x03AE, 0x03B7, 0x0301, 0, + 1, 0x03AF, 0x03B9, 0x0301, 0, + 1, 0x03B0, 0x03CB, 0x0301, 0, + 1, 0x03CA, 0x03B9, 0x0308, 0, + 1, 0x03CB, 0x03C5, 0x0308, 0, + 1, 0x03CC, 0x03BF, 0x0301, 0, + 1, 0x03CD, 0x03C5, 0x0301, 0, + 1, 0x03CE, 0x03C9, 0x0301, 0, + 16, 0x03D0, 0x03B2, 0, + 16, 0x03D1, 0x03B8, 0, + 16, 0x03D2, 0x03A5, 0, + 1, 0x03D3, 0x03D2, 0x0301, 0, + 1, 0x03D4, 0x03D2, 0x0308, 0, + 16, 0x03D5, 0x03C6, 0, + 16, 0x03D6, 0x03C0, 0, + 16, 0x03F0, 0x03BA, 0, + 16, 0x03F1, 0x03C1, 0, + 16, 0x03F2, 0x03C2, 0, + 16, 0x03F4, 0x0398, 0, + 16, 0x03F5, 0x03B5, 0, + 1, 0x0400, 0x0415, 0x0300, 0, + 1, 0x0401, 0x0415, 0x0308, 0, + 1, 0x0403, 0x0413, 0x0301, 0, + 1, 0x0407, 0x0406, 0x0308, 0, + 1, 0x040C, 0x041A, 0x0301, 0, + 1, 0x040D, 0x0418, 0x0300, 0, + 1, 0x040E, 0x0423, 0x0306, 0, + 1, 0x0419, 0x0418, 0x0306, 0, + 1, 0x0439, 0x0438, 0x0306, 0, + 1, 0x0450, 0x0435, 0x0300, 0, + 1, 0x0451, 0x0435, 0x0308, 0, + 1, 0x0453, 0x0433, 0x0301, 0, + 1, 0x0457, 0x0456, 0x0308, 0, + 1, 0x045C, 0x043A, 0x0301, 0, + 1, 0x045D, 0x0438, 0x0300, 0, + 1, 0x045E, 0x0443, 0x0306, 0, + 1, 0x0476, 0x0474, 0x030F, 0, + 1, 0x0477, 0x0475, 0x030F, 0, + 1, 0x04C1, 0x0416, 0x0306, 0, + 1, 0x04C2, 0x0436, 0x0306, 0, + 1, 0x04D0, 0x0410, 0x0306, 0, + 1, 0x04D1, 0x0430, 0x0306, 0, + 1, 0x04D2, 0x0410, 0x0308, 0, + 1, 0x04D3, 0x0430, 0x0308, 0, + 1, 0x04D6, 0x0415, 0x0306, 0, + 1, 0x04D7, 0x0435, 0x0306, 0, + 1, 0x04DA, 0x04D8, 0x0308, 0, + 1, 0x04DB, 0x04D9, 0x0308, 0, + 1, 0x04DC, 0x0416, 0x0308, 0, + 1, 0x04DD, 0x0436, 0x0308, 0, + 1, 0x04DE, 0x0417, 0x0308, 0, + 1, 0x04DF, 0x0437, 0x0308, 0, + 1, 0x04E2, 0x0418, 0x0304, 0, + 1, 0x04E3, 0x0438, 0x0304, 0, + 1, 0x04E4, 0x0418, 0x0308, 0, + 1, 0x04E5, 0x0438, 0x0308, 0, + 1, 0x04E6, 0x041E, 0x0308, 0, + 1, 0x04E7, 0x043E, 0x0308, 0, + 1, 0x04EA, 0x04E8, 0x0308, 0, + 1, 0x04EB, 0x04E9, 0x0308, 0, + 1, 0x04EC, 0x042D, 0x0308, 0, + 1, 0x04ED, 0x044D, 0x0308, 0, + 1, 0x04EE, 0x0423, 0x0304, 0, + 1, 0x04EF, 0x0443, 0x0304, 0, + 1, 0x04F0, 0x0423, 0x0308, 0, + 1, 0x04F1, 0x0443, 0x0308, 0, + 1, 0x04F2, 0x0423, 0x030B, 0, + 1, 0x04F3, 0x0443, 0x030B, 0, + 1, 0x04F4, 0x0427, 0x0308, 0, + 1, 0x04F5, 0x0447, 0x0308, 0, + 1, 0x04F8, 0x042B, 0x0308, 0, + 1, 0x04F9, 0x044B, 0x0308, 0, + 16, 0x0587, 0x0565, 0x0582, 0, + 1, 0x0622, 0x0627, 0x0653, 0, + 1, 0x0623, 0x0627, 0x0654, 0, + 1, 0x0624, 0x0648, 0x0654, 0, + 1, 0x0625, 0x0627, 0x0655, 0, + 1, 0x0626, 0x064A, 0x0654, 0, + 16, 0x0675, 0x0627, 0x0674, 0, + 16, 0x0676, 0x0648, 0x0674, 0, + 16, 0x0677, 0x06C7, 0x0674, 0, + 16, 0x0678, 0x064A, 0x0674, 0, + 1, 0x06C0, 0x06D5, 0x0654, 0, + 1, 0x06C2, 0x06C1, 0x0654, 0, + 1, 0x06D3, 0x06D2, 0x0654, 0, + 1, 0x0929, 0x0928, 0x093C, 0, + 1, 0x0931, 0x0930, 0x093C, 0, + 1, 0x0934, 0x0933, 0x093C, 0, + 1, 0x0958, 0x0915, 0x093C, 0, + 1, 0x0959, 0x0916, 0x093C, 0, + 1, 0x095A, 0x0917, 0x093C, 0, + 1, 0x095B, 0x091C, 0x093C, 0, + 1, 0x095C, 0x0921, 0x093C, 0, + 1, 0x095D, 0x0922, 0x093C, 0, + 1, 0x095E, 0x092B, 0x093C, 0, + 1, 0x095F, 0x092F, 0x093C, 0, + 1, 0x09CB, 0x09C7, 0x09BE, 0, + 1, 0x09CC, 0x09C7, 0x09D7, 0, + 1, 0x09DC, 0x09A1, 0x09BC, 0, + 1, 0x09DD, 0x09A2, 0x09BC, 0, + 1, 0x09DF, 0x09AF, 0x09BC, 0, + 1, 0x0A33, 0x0A32, 0x0A3C, 0, + 1, 0x0A36, 0x0A38, 0x0A3C, 0, + 1, 0x0A59, 0x0A16, 0x0A3C, 0, + 1, 0x0A5A, 0x0A17, 0x0A3C, 0, + 1, 0x0A5B, 0x0A1C, 0x0A3C, 0, + 1, 0x0A5E, 0x0A2B, 0x0A3C, 0, + 1, 0x0B48, 0x0B47, 0x0B56, 0, + 1, 0x0B4B, 0x0B47, 0x0B3E, 0, + 1, 0x0B4C, 0x0B47, 0x0B57, 0, + 1, 0x0B5C, 0x0B21, 0x0B3C, 0, + 1, 0x0B5D, 0x0B22, 0x0B3C, 0, + 1, 0x0B94, 0x0B92, 0x0BD7, 0, + 1, 0x0BCA, 0x0BC6, 0x0BBE, 0, + 1, 0x0BCB, 0x0BC7, 0x0BBE, 0, + 1, 0x0BCC, 0x0BC6, 0x0BD7, 0, + 1, 0x0C48, 0x0C46, 0x0C56, 0, + 1, 0x0CC0, 0x0CBF, 0x0CD5, 0, + 1, 0x0CC7, 0x0CC6, 0x0CD5, 0, + 1, 0x0CC8, 0x0CC6, 0x0CD6, 0, + 1, 0x0CCA, 0x0CC6, 0x0CC2, 0, + 1, 0x0CCB, 0x0CCA, 0x0CD5, 0, + 1, 0x0D4A, 0x0D46, 0x0D3E, 0, + 1, 0x0D4B, 0x0D47, 0x0D3E, 0, + 1, 0x0D4C, 0x0D46, 0x0D57, 0, + 1, 0x0DDA, 0x0DD9, 0x0DCA, 0, + 1, 0x0DDC, 0x0DD9, 0x0DCF, 0, + 1, 0x0DDD, 0x0DDC, 0x0DCA, 0, + 1, 0x0DDE, 0x0DD9, 0x0DDF, 0, + 16, 0x0E33, 0x0E4D, 0x0E32, 0, + 16, 0x0EB3, 0x0ECD, 0x0EB2, 0, + 16, 0x0EDC, 0x0EAB, 0x0E99, 0, + 16, 0x0EDD, 0x0EAB, 0x0EA1, 0, + 3, 0x0F0C, 0x0F0B, 0, + 1, 0x0F43, 0x0F42, 0x0FB7, 0, + 1, 0x0F4D, 0x0F4C, 0x0FB7, 0, + 1, 0x0F52, 0x0F51, 0x0FB7, 0, + 1, 0x0F57, 0x0F56, 0x0FB7, 0, + 1, 0x0F5C, 0x0F5B, 0x0FB7, 0, + 1, 0x0F69, 0x0F40, 0x0FB5, 0, + 1, 0x0F73, 0x0F71, 0x0F72, 0, + 1, 0x0F75, 0x0F71, 0x0F74, 0, + 1, 0x0F76, 0x0FB2, 0x0F80, 0, + 16, 0x0F77, 0x0FB2, 0x0F81, 0, + 1, 0x0F78, 0x0FB3, 0x0F80, 0, + 16, 0x0F79, 0x0FB3, 0x0F81, 0, + 1, 0x0F81, 0x0F71, 0x0F80, 0, + 1, 0x0F93, 0x0F92, 0x0FB7, 0, + 1, 0x0F9D, 0x0F9C, 0x0FB7, 0, + 1, 0x0FA2, 0x0FA1, 0x0FB7, 0, + 1, 0x0FA7, 0x0FA6, 0x0FB7, 0, + 1, 0x0FAC, 0x0FAB, 0x0FB7, 0, + 1, 0x0FB9, 0x0F90, 0x0FB5, 0, + 1, 0x1026, 0x1025, 0x102E, 0, + 1, 0x1E00, 0x0041, 0x0325, 0, + 1, 0x1E01, 0x0061, 0x0325, 0, + 1, 0x1E02, 0x0042, 0x0307, 0, + 1, 0x1E03, 0x0062, 0x0307, 0, + 1, 0x1E04, 0x0042, 0x0323, 0, + 1, 0x1E05, 0x0062, 0x0323, 0, + 1, 0x1E06, 0x0042, 0x0331, 0, + 1, 0x1E07, 0x0062, 0x0331, 0, + 1, 0x1E08, 0x00C7, 0x0301, 0, + 1, 0x1E09, 0x00E7, 0x0301, 0, + 1, 0x1E0A, 0x0044, 0x0307, 0, + 1, 0x1E0B, 0x0064, 0x0307, 0, + 1, 0x1E0C, 0x0044, 0x0323, 0, + 1, 0x1E0D, 0x0064, 0x0323, 0, + 1, 0x1E0E, 0x0044, 0x0331, 0, + 1, 0x1E0F, 0x0064, 0x0331, 0, + 1, 0x1E10, 0x0044, 0x0327, 0, + 1, 0x1E11, 0x0064, 0x0327, 0, + 1, 0x1E12, 0x0044, 0x032D, 0, + 1, 0x1E13, 0x0064, 0x032D, 0, + 1, 0x1E14, 0x0112, 0x0300, 0, + 1, 0x1E15, 0x0113, 0x0300, 0, + 1, 0x1E16, 0x0112, 0x0301, 0, + 1, 0x1E17, 0x0113, 0x0301, 0, + 1, 0x1E18, 0x0045, 0x032D, 0, + 1, 0x1E19, 0x0065, 0x032D, 0, + 1, 0x1E1A, 0x0045, 0x0330, 0, + 1, 0x1E1B, 0x0065, 0x0330, 0, + 1, 0x1E1C, 0x0228, 0x0306, 0, + 1, 0x1E1D, 0x0229, 0x0306, 0, + 1, 0x1E1E, 0x0046, 0x0307, 0, + 1, 0x1E1F, 0x0066, 0x0307, 0, + 1, 0x1E20, 0x0047, 0x0304, 0, + 1, 0x1E21, 0x0067, 0x0304, 0, + 1, 0x1E22, 0x0048, 0x0307, 0, + 1, 0x1E23, 0x0068, 0x0307, 0, + 1, 0x1E24, 0x0048, 0x0323, 0, + 1, 0x1E25, 0x0068, 0x0323, 0, + 1, 0x1E26, 0x0048, 0x0308, 0, + 1, 0x1E27, 0x0068, 0x0308, 0, + 1, 0x1E28, 0x0048, 0x0327, 0, + 1, 0x1E29, 0x0068, 0x0327, 0, + 1, 0x1E2A, 0x0048, 0x032E, 0, + 1, 0x1E2B, 0x0068, 0x032E, 0, + 1, 0x1E2C, 0x0049, 0x0330, 0, + 1, 0x1E2D, 0x0069, 0x0330, 0, + 1, 0x1E2E, 0x00CF, 0x0301, 0, + 1, 0x1E2F, 0x00EF, 0x0301, 0, + 1, 0x1E30, 0x004B, 0x0301, 0, + 1, 0x1E31, 0x006B, 0x0301, 0, + 1, 0x1E32, 0x004B, 0x0323, 0, + 1, 0x1E33, 0x006B, 0x0323, 0, + 1, 0x1E34, 0x004B, 0x0331, 0, + 1, 0x1E35, 0x006B, 0x0331, 0, + 1, 0x1E36, 0x004C, 0x0323, 0, + 1, 0x1E37, 0x006C, 0x0323, 0, + 1, 0x1E38, 0x1E36, 0x0304, 0, + 1, 0x1E39, 0x1E37, 0x0304, 0, + 1, 0x1E3A, 0x004C, 0x0331, 0, + 1, 0x1E3B, 0x006C, 0x0331, 0, + 1, 0x1E3C, 0x004C, 0x032D, 0, + 1, 0x1E3D, 0x006C, 0x032D, 0, + 1, 0x1E3E, 0x004D, 0x0301, 0, + 1, 0x1E3F, 0x006D, 0x0301, 0, + 1, 0x1E40, 0x004D, 0x0307, 0, + 1, 0x1E41, 0x006D, 0x0307, 0, + 1, 0x1E42, 0x004D, 0x0323, 0, + 1, 0x1E43, 0x006D, 0x0323, 0, + 1, 0x1E44, 0x004E, 0x0307, 0, + 1, 0x1E45, 0x006E, 0x0307, 0, + 1, 0x1E46, 0x004E, 0x0323, 0, + 1, 0x1E47, 0x006E, 0x0323, 0, + 1, 0x1E48, 0x004E, 0x0331, 0, + 1, 0x1E49, 0x006E, 0x0331, 0, + 1, 0x1E4A, 0x004E, 0x032D, 0, + 1, 0x1E4B, 0x006E, 0x032D, 0, + 1, 0x1E4C, 0x00D5, 0x0301, 0, + 1, 0x1E4D, 0x00F5, 0x0301, 0, + 1, 0x1E4E, 0x00D5, 0x0308, 0, + 1, 0x1E4F, 0x00F5, 0x0308, 0, + 1, 0x1E50, 0x014C, 0x0300, 0, + 1, 0x1E51, 0x014D, 0x0300, 0, + 1, 0x1E52, 0x014C, 0x0301, 0, + 1, 0x1E53, 0x014D, 0x0301, 0, + 1, 0x1E54, 0x0050, 0x0301, 0, + 1, 0x1E55, 0x0070, 0x0301, 0, + 1, 0x1E56, 0x0050, 0x0307, 0, + 1, 0x1E57, 0x0070, 0x0307, 0, + 1, 0x1E58, 0x0052, 0x0307, 0, + 1, 0x1E59, 0x0072, 0x0307, 0, + 1, 0x1E5A, 0x0052, 0x0323, 0, + 1, 0x1E5B, 0x0072, 0x0323, 0, + 1, 0x1E5C, 0x1E5A, 0x0304, 0, + 1, 0x1E5D, 0x1E5B, 0x0304, 0, + 1, 0x1E5E, 0x0052, 0x0331, 0, + 1, 0x1E5F, 0x0072, 0x0331, 0, + 1, 0x1E60, 0x0053, 0x0307, 0, + 1, 0x1E61, 0x0073, 0x0307, 0, + 1, 0x1E62, 0x0053, 0x0323, 0, + 1, 0x1E63, 0x0073, 0x0323, 0, + 1, 0x1E64, 0x015A, 0x0307, 0, + 1, 0x1E65, 0x015B, 0x0307, 0, + 1, 0x1E66, 0x0160, 0x0307, 0, + 1, 0x1E67, 0x0161, 0x0307, 0, + 1, 0x1E68, 0x1E62, 0x0307, 0, + 1, 0x1E69, 0x1E63, 0x0307, 0, + 1, 0x1E6A, 0x0054, 0x0307, 0, + 1, 0x1E6B, 0x0074, 0x0307, 0, + 1, 0x1E6C, 0x0054, 0x0323, 0, + 1, 0x1E6D, 0x0074, 0x0323, 0, + 1, 0x1E6E, 0x0054, 0x0331, 0, + 1, 0x1E6F, 0x0074, 0x0331, 0, + 1, 0x1E70, 0x0054, 0x032D, 0, + 1, 0x1E71, 0x0074, 0x032D, 0, + 1, 0x1E72, 0x0055, 0x0324, 0, + 1, 0x1E73, 0x0075, 0x0324, 0, + 1, 0x1E74, 0x0055, 0x0330, 0, + 1, 0x1E75, 0x0075, 0x0330, 0, + 1, 0x1E76, 0x0055, 0x032D, 0, + 1, 0x1E77, 0x0075, 0x032D, 0, + 1, 0x1E78, 0x0168, 0x0301, 0, + 1, 0x1E79, 0x0169, 0x0301, 0, + 1, 0x1E7A, 0x016A, 0x0308, 0, + 1, 0x1E7B, 0x016B, 0x0308, 0, + 1, 0x1E7C, 0x0056, 0x0303, 0, + 1, 0x1E7D, 0x0076, 0x0303, 0, + 1, 0x1E7E, 0x0056, 0x0323, 0, + 1, 0x1E7F, 0x0076, 0x0323, 0, + 1, 0x1E80, 0x0057, 0x0300, 0, + 1, 0x1E81, 0x0077, 0x0300, 0, + 1, 0x1E82, 0x0057, 0x0301, 0, + 1, 0x1E83, 0x0077, 0x0301, 0, + 1, 0x1E84, 0x0057, 0x0308, 0, + 1, 0x1E85, 0x0077, 0x0308, 0, + 1, 0x1E86, 0x0057, 0x0307, 0, + 1, 0x1E87, 0x0077, 0x0307, 0, + 1, 0x1E88, 0x0057, 0x0323, 0, + 1, 0x1E89, 0x0077, 0x0323, 0, + 1, 0x1E8A, 0x0058, 0x0307, 0, + 1, 0x1E8B, 0x0078, 0x0307, 0, + 1, 0x1E8C, 0x0058, 0x0308, 0, + 1, 0x1E8D, 0x0078, 0x0308, 0, + 1, 0x1E8E, 0x0059, 0x0307, 0, + 1, 0x1E8F, 0x0079, 0x0307, 0, + 1, 0x1E90, 0x005A, 0x0302, 0, + 1, 0x1E91, 0x007A, 0x0302, 0, + 1, 0x1E92, 0x005A, 0x0323, 0, + 1, 0x1E93, 0x007A, 0x0323, 0, + 1, 0x1E94, 0x005A, 0x0331, 0, + 1, 0x1E95, 0x007A, 0x0331, 0, + 1, 0x1E96, 0x0068, 0x0331, 0, + 1, 0x1E97, 0x0074, 0x0308, 0, + 1, 0x1E98, 0x0077, 0x030A, 0, + 1, 0x1E99, 0x0079, 0x030A, 0, + 16, 0x1E9A, 0x0061, 0x02BE, 0, + 1, 0x1E9B, 0x017F, 0x0307, 0, + 1, 0x1EA0, 0x0041, 0x0323, 0, + 1, 0x1EA1, 0x0061, 0x0323, 0, + 1, 0x1EA2, 0x0041, 0x0309, 0, + 1, 0x1EA3, 0x0061, 0x0309, 0, + 1, 0x1EA4, 0x00C2, 0x0301, 0, + 1, 0x1EA5, 0x00E2, 0x0301, 0, + 1, 0x1EA6, 0x00C2, 0x0300, 0, + 1, 0x1EA7, 0x00E2, 0x0300, 0, + 1, 0x1EA8, 0x00C2, 0x0309, 0, + 1, 0x1EA9, 0x00E2, 0x0309, 0, + 1, 0x1EAA, 0x00C2, 0x0303, 0, + 1, 0x1EAB, 0x00E2, 0x0303, 0, + 1, 0x1EAC, 0x1EA0, 0x0302, 0, + 1, 0x1EAD, 0x1EA1, 0x0302, 0, + 1, 0x1EAE, 0x0102, 0x0301, 0, + 1, 0x1EAF, 0x0103, 0x0301, 0, + 1, 0x1EB0, 0x0102, 0x0300, 0, + 1, 0x1EB1, 0x0103, 0x0300, 0, + 1, 0x1EB2, 0x0102, 0x0309, 0, + 1, 0x1EB3, 0x0103, 0x0309, 0, + 1, 0x1EB4, 0x0102, 0x0303, 0, + 1, 0x1EB5, 0x0103, 0x0303, 0, + 1, 0x1EB6, 0x1EA0, 0x0306, 0, + 1, 0x1EB7, 0x1EA1, 0x0306, 0, + 1, 0x1EB8, 0x0045, 0x0323, 0, + 1, 0x1EB9, 0x0065, 0x0323, 0, + 1, 0x1EBA, 0x0045, 0x0309, 0, + 1, 0x1EBB, 0x0065, 0x0309, 0, + 1, 0x1EBC, 0x0045, 0x0303, 0, + 1, 0x1EBD, 0x0065, 0x0303, 0, + 1, 0x1EBE, 0x00CA, 0x0301, 0, + 1, 0x1EBF, 0x00EA, 0x0301, 0, + 1, 0x1EC0, 0x00CA, 0x0300, 0, + 1, 0x1EC1, 0x00EA, 0x0300, 0, + 1, 0x1EC2, 0x00CA, 0x0309, 0, + 1, 0x1EC3, 0x00EA, 0x0309, 0, + 1, 0x1EC4, 0x00CA, 0x0303, 0, + 1, 0x1EC5, 0x00EA, 0x0303, 0, + 1, 0x1EC6, 0x1EB8, 0x0302, 0, + 1, 0x1EC7, 0x1EB9, 0x0302, 0, + 1, 0x1EC8, 0x0049, 0x0309, 0, + 1, 0x1EC9, 0x0069, 0x0309, 0, + 1, 0x1ECA, 0x0049, 0x0323, 0, + 1, 0x1ECB, 0x0069, 0x0323, 0, + 1, 0x1ECC, 0x004F, 0x0323, 0, + 1, 0x1ECD, 0x006F, 0x0323, 0, + 1, 0x1ECE, 0x004F, 0x0309, 0, + 1, 0x1ECF, 0x006F, 0x0309, 0, + 1, 0x1ED0, 0x00D4, 0x0301, 0, + 1, 0x1ED1, 0x00F4, 0x0301, 0, + 1, 0x1ED2, 0x00D4, 0x0300, 0, + 1, 0x1ED3, 0x00F4, 0x0300, 0, + 1, 0x1ED4, 0x00D4, 0x0309, 0, + 1, 0x1ED5, 0x00F4, 0x0309, 0, + 1, 0x1ED6, 0x00D4, 0x0303, 0, + 1, 0x1ED7, 0x00F4, 0x0303, 0, + 1, 0x1ED8, 0x1ECC, 0x0302, 0, + 1, 0x1ED9, 0x1ECD, 0x0302, 0, + 1, 0x1EDA, 0x01A0, 0x0301, 0, + 1, 0x1EDB, 0x01A1, 0x0301, 0, + 1, 0x1EDC, 0x01A0, 0x0300, 0, + 1, 0x1EDD, 0x01A1, 0x0300, 0, + 1, 0x1EDE, 0x01A0, 0x0309, 0, + 1, 0x1EDF, 0x01A1, 0x0309, 0, + 1, 0x1EE0, 0x01A0, 0x0303, 0, + 1, 0x1EE1, 0x01A1, 0x0303, 0, + 1, 0x1EE2, 0x01A0, 0x0323, 0, + 1, 0x1EE3, 0x01A1, 0x0323, 0, + 1, 0x1EE4, 0x0055, 0x0323, 0, + 1, 0x1EE5, 0x0075, 0x0323, 0, + 1, 0x1EE6, 0x0055, 0x0309, 0, + 1, 0x1EE7, 0x0075, 0x0309, 0, + 1, 0x1EE8, 0x01AF, 0x0301, 0, + 1, 0x1EE9, 0x01B0, 0x0301, 0, + 1, 0x1EEA, 0x01AF, 0x0300, 0, + 1, 0x1EEB, 0x01B0, 0x0300, 0, + 1, 0x1EEC, 0x01AF, 0x0309, 0, + 1, 0x1EED, 0x01B0, 0x0309, 0, + 1, 0x1EEE, 0x01AF, 0x0303, 0, + 1, 0x1EEF, 0x01B0, 0x0303, 0, + 1, 0x1EF0, 0x01AF, 0x0323, 0, + 1, 0x1EF1, 0x01B0, 0x0323, 0, + 1, 0x1EF2, 0x0059, 0x0300, 0, + 1, 0x1EF3, 0x0079, 0x0300, 0, + 1, 0x1EF4, 0x0059, 0x0323, 0, + 1, 0x1EF5, 0x0079, 0x0323, 0, + 1, 0x1EF6, 0x0059, 0x0309, 0, + 1, 0x1EF7, 0x0079, 0x0309, 0, + 1, 0x1EF8, 0x0059, 0x0303, 0, + 1, 0x1EF9, 0x0079, 0x0303, 0, + 1, 0x1F00, 0x03B1, 0x0313, 0, + 1, 0x1F01, 0x03B1, 0x0314, 0, + 1, 0x1F02, 0x1F00, 0x0300, 0, + 1, 0x1F03, 0x1F01, 0x0300, 0, + 1, 0x1F04, 0x1F00, 0x0301, 0, + 1, 0x1F05, 0x1F01, 0x0301, 0, + 1, 0x1F06, 0x1F00, 0x0342, 0, + 1, 0x1F07, 0x1F01, 0x0342, 0, + 1, 0x1F08, 0x0391, 0x0313, 0, + 1, 0x1F09, 0x0391, 0x0314, 0, + 1, 0x1F0A, 0x1F08, 0x0300, 0, + 1, 0x1F0B, 0x1F09, 0x0300, 0, + 1, 0x1F0C, 0x1F08, 0x0301, 0, + 1, 0x1F0D, 0x1F09, 0x0301, 0, + 1, 0x1F0E, 0x1F08, 0x0342, 0, + 1, 0x1F0F, 0x1F09, 0x0342, 0, + 1, 0x1F10, 0x03B5, 0x0313, 0, + 1, 0x1F11, 0x03B5, 0x0314, 0, + 1, 0x1F12, 0x1F10, 0x0300, 0, + 1, 0x1F13, 0x1F11, 0x0300, 0, + 1, 0x1F14, 0x1F10, 0x0301, 0, + 1, 0x1F15, 0x1F11, 0x0301, 0, + 1, 0x1F18, 0x0395, 0x0313, 0, + 1, 0x1F19, 0x0395, 0x0314, 0, + 1, 0x1F1A, 0x1F18, 0x0300, 0, + 1, 0x1F1B, 0x1F19, 0x0300, 0, + 1, 0x1F1C, 0x1F18, 0x0301, 0, + 1, 0x1F1D, 0x1F19, 0x0301, 0, + 1, 0x1F20, 0x03B7, 0x0313, 0, + 1, 0x1F21, 0x03B7, 0x0314, 0, + 1, 0x1F22, 0x1F20, 0x0300, 0, + 1, 0x1F23, 0x1F21, 0x0300, 0, + 1, 0x1F24, 0x1F20, 0x0301, 0, + 1, 0x1F25, 0x1F21, 0x0301, 0, + 1, 0x1F26, 0x1F20, 0x0342, 0, + 1, 0x1F27, 0x1F21, 0x0342, 0, + 1, 0x1F28, 0x0397, 0x0313, 0, + 1, 0x1F29, 0x0397, 0x0314, 0, + 1, 0x1F2A, 0x1F28, 0x0300, 0, + 1, 0x1F2B, 0x1F29, 0x0300, 0, + 1, 0x1F2C, 0x1F28, 0x0301, 0, + 1, 0x1F2D, 0x1F29, 0x0301, 0, + 1, 0x1F2E, 0x1F28, 0x0342, 0, + 1, 0x1F2F, 0x1F29, 0x0342, 0, + 1, 0x1F30, 0x03B9, 0x0313, 0, + 1, 0x1F31, 0x03B9, 0x0314, 0, + 1, 0x1F32, 0x1F30, 0x0300, 0, + 1, 0x1F33, 0x1F31, 0x0300, 0, + 1, 0x1F34, 0x1F30, 0x0301, 0, + 1, 0x1F35, 0x1F31, 0x0301, 0, + 1, 0x1F36, 0x1F30, 0x0342, 0, + 1, 0x1F37, 0x1F31, 0x0342, 0, + 1, 0x1F38, 0x0399, 0x0313, 0, + 1, 0x1F39, 0x0399, 0x0314, 0, + 1, 0x1F3A, 0x1F38, 0x0300, 0, + 1, 0x1F3B, 0x1F39, 0x0300, 0, + 1, 0x1F3C, 0x1F38, 0x0301, 0, + 1, 0x1F3D, 0x1F39, 0x0301, 0, + 1, 0x1F3E, 0x1F38, 0x0342, 0, + 1, 0x1F3F, 0x1F39, 0x0342, 0, + 1, 0x1F40, 0x03BF, 0x0313, 0, + 1, 0x1F41, 0x03BF, 0x0314, 0, + 1, 0x1F42, 0x1F40, 0x0300, 0, + 1, 0x1F43, 0x1F41, 0x0300, 0, + 1, 0x1F44, 0x1F40, 0x0301, 0, + 1, 0x1F45, 0x1F41, 0x0301, 0, + 1, 0x1F48, 0x039F, 0x0313, 0, + 1, 0x1F49, 0x039F, 0x0314, 0, + 1, 0x1F4A, 0x1F48, 0x0300, 0, + 1, 0x1F4B, 0x1F49, 0x0300, 0, + 1, 0x1F4C, 0x1F48, 0x0301, 0, + 1, 0x1F4D, 0x1F49, 0x0301, 0, + 1, 0x1F50, 0x03C5, 0x0313, 0, + 1, 0x1F51, 0x03C5, 0x0314, 0, + 1, 0x1F52, 0x1F50, 0x0300, 0, + 1, 0x1F53, 0x1F51, 0x0300, 0, + 1, 0x1F54, 0x1F50, 0x0301, 0, + 1, 0x1F55, 0x1F51, 0x0301, 0, + 1, 0x1F56, 0x1F50, 0x0342, 0, + 1, 0x1F57, 0x1F51, 0x0342, 0, + 1, 0x1F59, 0x03A5, 0x0314, 0, + 1, 0x1F5B, 0x1F59, 0x0300, 0, + 1, 0x1F5D, 0x1F59, 0x0301, 0, + 1, 0x1F5F, 0x1F59, 0x0342, 0, + 1, 0x1F60, 0x03C9, 0x0313, 0, + 1, 0x1F61, 0x03C9, 0x0314, 0, + 1, 0x1F62, 0x1F60, 0x0300, 0, + 1, 0x1F63, 0x1F61, 0x0300, 0, + 1, 0x1F64, 0x1F60, 0x0301, 0, + 1, 0x1F65, 0x1F61, 0x0301, 0, + 1, 0x1F66, 0x1F60, 0x0342, 0, + 1, 0x1F67, 0x1F61, 0x0342, 0, + 1, 0x1F68, 0x03A9, 0x0313, 0, + 1, 0x1F69, 0x03A9, 0x0314, 0, + 1, 0x1F6A, 0x1F68, 0x0300, 0, + 1, 0x1F6B, 0x1F69, 0x0300, 0, + 1, 0x1F6C, 0x1F68, 0x0301, 0, + 1, 0x1F6D, 0x1F69, 0x0301, 0, + 1, 0x1F6E, 0x1F68, 0x0342, 0, + 1, 0x1F6F, 0x1F69, 0x0342, 0, + 1, 0x1F70, 0x03B1, 0x0300, 0, + 1, 0x1F71, 0x03AC, 0, + 1, 0x1F72, 0x03B5, 0x0300, 0, + 1, 0x1F73, 0x03AD, 0, + 1, 0x1F74, 0x03B7, 0x0300, 0, + 1, 0x1F75, 0x03AE, 0, + 1, 0x1F76, 0x03B9, 0x0300, 0, + 1, 0x1F77, 0x03AF, 0, + 1, 0x1F78, 0x03BF, 0x0300, 0, + 1, 0x1F79, 0x03CC, 0, + 1, 0x1F7A, 0x03C5, 0x0300, 0, + 1, 0x1F7B, 0x03CD, 0, + 1, 0x1F7C, 0x03C9, 0x0300, 0, + 1, 0x1F7D, 0x03CE, 0, + 1, 0x1F80, 0x1F00, 0x0345, 0, + 1, 0x1F81, 0x1F01, 0x0345, 0, + 1, 0x1F82, 0x1F02, 0x0345, 0, + 1, 0x1F83, 0x1F03, 0x0345, 0, + 1, 0x1F84, 0x1F04, 0x0345, 0, + 1, 0x1F85, 0x1F05, 0x0345, 0, + 1, 0x1F86, 0x1F06, 0x0345, 0, + 1, 0x1F87, 0x1F07, 0x0345, 0, + 1, 0x1F88, 0x1F08, 0x0345, 0, + 1, 0x1F89, 0x1F09, 0x0345, 0, + 1, 0x1F8A, 0x1F0A, 0x0345, 0, + 1, 0x1F8B, 0x1F0B, 0x0345, 0, + 1, 0x1F8C, 0x1F0C, 0x0345, 0, + 1, 0x1F8D, 0x1F0D, 0x0345, 0, + 1, 0x1F8E, 0x1F0E, 0x0345, 0, + 1, 0x1F8F, 0x1F0F, 0x0345, 0, + 1, 0x1F90, 0x1F20, 0x0345, 0, + 1, 0x1F91, 0x1F21, 0x0345, 0, + 1, 0x1F92, 0x1F22, 0x0345, 0, + 1, 0x1F93, 0x1F23, 0x0345, 0, + 1, 0x1F94, 0x1F24, 0x0345, 0, + 1, 0x1F95, 0x1F25, 0x0345, 0, + 1, 0x1F96, 0x1F26, 0x0345, 0, + 1, 0x1F97, 0x1F27, 0x0345, 0, + 1, 0x1F98, 0x1F28, 0x0345, 0, + 1, 0x1F99, 0x1F29, 0x0345, 0, + 1, 0x1F9A, 0x1F2A, 0x0345, 0, + 1, 0x1F9B, 0x1F2B, 0x0345, 0, + 1, 0x1F9C, 0x1F2C, 0x0345, 0, + 1, 0x1F9D, 0x1F2D, 0x0345, 0, + 1, 0x1F9E, 0x1F2E, 0x0345, 0, + 1, 0x1F9F, 0x1F2F, 0x0345, 0, + 1, 0x1FA0, 0x1F60, 0x0345, 0, + 1, 0x1FA1, 0x1F61, 0x0345, 0, + 1, 0x1FA2, 0x1F62, 0x0345, 0, + 1, 0x1FA3, 0x1F63, 0x0345, 0, + 1, 0x1FA4, 0x1F64, 0x0345, 0, + 1, 0x1FA5, 0x1F65, 0x0345, 0, + 1, 0x1FA6, 0x1F66, 0x0345, 0, + 1, 0x1FA7, 0x1F67, 0x0345, 0, + 1, 0x1FA8, 0x1F68, 0x0345, 0, + 1, 0x1FA9, 0x1F69, 0x0345, 0, + 1, 0x1FAA, 0x1F6A, 0x0345, 0, + 1, 0x1FAB, 0x1F6B, 0x0345, 0, + 1, 0x1FAC, 0x1F6C, 0x0345, 0, + 1, 0x1FAD, 0x1F6D, 0x0345, 0, + 1, 0x1FAE, 0x1F6E, 0x0345, 0, + 1, 0x1FAF, 0x1F6F, 0x0345, 0, + 1, 0x1FB0, 0x03B1, 0x0306, 0, + 1, 0x1FB1, 0x03B1, 0x0304, 0, + 1, 0x1FB2, 0x1F70, 0x0345, 0, + 1, 0x1FB3, 0x03B1, 0x0345, 0, + 1, 0x1FB4, 0x03AC, 0x0345, 0, + 1, 0x1FB6, 0x03B1, 0x0342, 0, + 1, 0x1FB7, 0x1FB6, 0x0345, 0, + 1, 0x1FB8, 0x0391, 0x0306, 0, + 1, 0x1FB9, 0x0391, 0x0304, 0, + 1, 0x1FBA, 0x0391, 0x0300, 0, + 1, 0x1FBB, 0x0386, 0, + 1, 0x1FBC, 0x0391, 0x0345, 0, + 16, 0x1FBD, 0x0020, 0x0313, 0, + 1, 0x1FBE, 0x03B9, 0, + 16, 0x1FBF, 0x0020, 0x0313, 0, + 16, 0x1FC0, 0x0020, 0x0342, 0, + 1, 0x1FC1, 0x00A8, 0x0342, 0, + 1, 0x1FC2, 0x1F74, 0x0345, 0, + 1, 0x1FC3, 0x03B7, 0x0345, 0, + 1, 0x1FC4, 0x03AE, 0x0345, 0, + 1, 0x1FC6, 0x03B7, 0x0342, 0, + 1, 0x1FC7, 0x1FC6, 0x0345, 0, + 1, 0x1FC8, 0x0395, 0x0300, 0, + 1, 0x1FC9, 0x0388, 0, + 1, 0x1FCA, 0x0397, 0x0300, 0, + 1, 0x1FCB, 0x0389, 0, + 1, 0x1FCC, 0x0397, 0x0345, 0, + 1, 0x1FCD, 0x1FBF, 0x0300, 0, + 1, 0x1FCE, 0x1FBF, 0x0301, 0, + 1, 0x1FCF, 0x1FBF, 0x0342, 0, + 1, 0x1FD0, 0x03B9, 0x0306, 0, + 1, 0x1FD1, 0x03B9, 0x0304, 0, + 1, 0x1FD2, 0x03CA, 0x0300, 0, + 1, 0x1FD3, 0x0390, 0, + 1, 0x1FD6, 0x03B9, 0x0342, 0, + 1, 0x1FD7, 0x03CA, 0x0342, 0, + 1, 0x1FD8, 0x0399, 0x0306, 0, + 1, 0x1FD9, 0x0399, 0x0304, 0, + 1, 0x1FDA, 0x0399, 0x0300, 0, + 1, 0x1FDB, 0x038A, 0, + 1, 0x1FDD, 0x1FFE, 0x0300, 0, + 1, 0x1FDE, 0x1FFE, 0x0301, 0, + 1, 0x1FDF, 0x1FFE, 0x0342, 0, + 1, 0x1FE0, 0x03C5, 0x0306, 0, + 1, 0x1FE1, 0x03C5, 0x0304, 0, + 1, 0x1FE2, 0x03CB, 0x0300, 0, + 1, 0x1FE3, 0x03B0, 0, + 1, 0x1FE4, 0x03C1, 0x0313, 0, + 1, 0x1FE5, 0x03C1, 0x0314, 0, + 1, 0x1FE6, 0x03C5, 0x0342, 0, + 1, 0x1FE7, 0x03CB, 0x0342, 0, + 1, 0x1FE8, 0x03A5, 0x0306, 0, + 1, 0x1FE9, 0x03A5, 0x0304, 0, + 1, 0x1FEA, 0x03A5, 0x0300, 0, + 1, 0x1FEB, 0x038E, 0, + 1, 0x1FEC, 0x03A1, 0x0314, 0, + 1, 0x1FED, 0x00A8, 0x0300, 0, + 1, 0x1FEE, 0x0385, 0, + 1, 0x1FEF, 0x0060, 0, + 1, 0x1FF2, 0x1F7C, 0x0345, 0, + 1, 0x1FF3, 0x03C9, 0x0345, 0, + 1, 0x1FF4, 0x03CE, 0x0345, 0, + 1, 0x1FF6, 0x03C9, 0x0342, 0, + 1, 0x1FF7, 0x1FF6, 0x0345, 0, + 1, 0x1FF8, 0x039F, 0x0300, 0, + 1, 0x1FF9, 0x038C, 0, + 1, 0x1FFA, 0x03A9, 0x0300, 0, + 1, 0x1FFB, 0x038F, 0, + 1, 0x1FFC, 0x03A9, 0x0345, 0, + 1, 0x1FFD, 0x00B4, 0, + 16, 0x1FFE, 0x0020, 0x0314, 0, + 1, 0x2000, 0x2002, 0, + 1, 0x2001, 0x2003, 0, + 16, 0x2002, 0x0020, 0, + 16, 0x2003, 0x0020, 0, + 16, 0x2004, 0x0020, 0, + 16, 0x2005, 0x0020, 0, + 16, 0x2006, 0x0020, 0, + 3, 0x2007, 0x0020, 0, + 16, 0x2008, 0x0020, 0, + 16, 0x2009, 0x0020, 0, + 16, 0x200A, 0x0020, 0, + 3, 0x2011, 0x2010, 0, + 16, 0x2017, 0x0020, 0x0333, 0, + 16, 0x2024, 0x002E, 0, + 16, 0x2025, 0x002E, 0x002E, 0, + 16, 0x2026, 0x002E, 0x002E, 0x002E, 0, + 3, 0x202F, 0x0020, 0, + 16, 0x2033, 0x2032, 0x2032, 0, + 16, 0x2034, 0x2032, 0x2032, 0x2032, 0, + 16, 0x2036, 0x2035, 0x2035, 0, + 16, 0x2037, 0x2035, 0x2035, 0x2035, 0, + 16, 0x203C, 0x0021, 0x0021, 0, + 16, 0x203E, 0x0020, 0x0305, 0, + 16, 0x2047, 0x003F, 0x003F, 0, + 16, 0x2048, 0x003F, 0x0021, 0, + 16, 0x2049, 0x0021, 0x003F, 0, + 16, 0x2057, 0x2032, 0x2032, 0x2032, 0x2032, 0, + 16, 0x205F, 0x0020, 0, + 9, 0x2070, 0x0030, 0, + 9, 0x2071, 0x0069, 0, + 9, 0x2074, 0x0034, 0, + 9, 0x2075, 0x0035, 0, + 9, 0x2076, 0x0036, 0, + 9, 0x2077, 0x0037, 0, + 9, 0x2078, 0x0038, 0, + 9, 0x2079, 0x0039, 0, + 9, 0x207A, 0x002B, 0, + 9, 0x207B, 0x2212, 0, + 9, 0x207C, 0x003D, 0, + 9, 0x207D, 0x0028, 0, + 9, 0x207E, 0x0029, 0, + 9, 0x207F, 0x006E, 0, + 10, 0x2080, 0x0030, 0, + 10, 0x2081, 0x0031, 0, + 10, 0x2082, 0x0032, 0, + 10, 0x2083, 0x0033, 0, + 10, 0x2084, 0x0034, 0, + 10, 0x2085, 0x0035, 0, + 10, 0x2086, 0x0036, 0, + 10, 0x2087, 0x0037, 0, + 10, 0x2088, 0x0038, 0, + 10, 0x2089, 0x0039, 0, + 10, 0x208A, 0x002B, 0, + 10, 0x208B, 0x2212, 0, + 10, 0x208C, 0x003D, 0, + 10, 0x208D, 0x0028, 0, + 10, 0x208E, 0x0029, 0, + 16, 0x20A8, 0x0052, 0x0073, 0, + 16, 0x2100, 0x0061, 0x002F, 0x0063, 0, + 16, 0x2101, 0x0061, 0x002F, 0x0073, 0, + 2, 0x2102, 0x0043, 0, + 16, 0x2103, 0x00B0, 0x0043, 0, + 16, 0x2105, 0x0063, 0x002F, 0x006F, 0, + 16, 0x2106, 0x0063, 0x002F, 0x0075, 0, + 16, 0x2107, 0x0190, 0, + 16, 0x2109, 0x00B0, 0x0046, 0, + 2, 0x210A, 0x0067, 0, + 2, 0x210B, 0x0048, 0, + 2, 0x210C, 0x0048, 0, + 2, 0x210D, 0x0048, 0, + 2, 0x210E, 0x0068, 0, + 2, 0x210F, 0x0127, 0, + 2, 0x2110, 0x0049, 0, + 2, 0x2111, 0x0049, 0, + 2, 0x2112, 0x004C, 0, + 2, 0x2113, 0x006C, 0, + 2, 0x2115, 0x004E, 0, + 16, 0x2116, 0x004E, 0x006F, 0, + 2, 0x2119, 0x0050, 0, + 2, 0x211A, 0x0051, 0, + 2, 0x211B, 0x0052, 0, + 2, 0x211C, 0x0052, 0, + 2, 0x211D, 0x0052, 0, + 9, 0x2120, 0x0053, 0x004D, 0, + 16, 0x2121, 0x0054, 0x0045, 0x004C, 0, + 9, 0x2122, 0x0054, 0x004D, 0, + 2, 0x2124, 0x005A, 0, + 1, 0x2126, 0x03A9, 0, + 2, 0x2128, 0x005A, 0, + 1, 0x212A, 0x004B, 0, + 1, 0x212B, 0x00C5, 0, + 2, 0x212C, 0x0042, 0, + 2, 0x212D, 0x0043, 0, + 2, 0x212F, 0x0065, 0, + 2, 0x2130, 0x0045, 0, + 2, 0x2131, 0x0046, 0, + 2, 0x2133, 0x004D, 0, + 2, 0x2134, 0x006F, 0, + 16, 0x2135, 0x05D0, 0, + 16, 0x2136, 0x05D1, 0, + 16, 0x2137, 0x05D2, 0, + 16, 0x2138, 0x05D3, 0, + 2, 0x2139, 0x0069, 0, + 2, 0x213D, 0x03B3, 0, + 2, 0x213E, 0x0393, 0, + 2, 0x213F, 0x03A0, 0, + 2, 0x2140, 0x2211, 0, + 2, 0x2145, 0x0044, 0, + 2, 0x2146, 0x0064, 0, + 2, 0x2147, 0x0065, 0, + 2, 0x2148, 0x0069, 0, + 2, 0x2149, 0x006A, 0, + 17, 0x2153, 0x0031, 0x2044, 0x0033, 0, + 17, 0x2154, 0x0032, 0x2044, 0x0033, 0, + 17, 0x2155, 0x0031, 0x2044, 0x0035, 0, + 17, 0x2156, 0x0032, 0x2044, 0x0035, 0, + 17, 0x2157, 0x0033, 0x2044, 0x0035, 0, + 17, 0x2158, 0x0034, 0x2044, 0x0035, 0, + 17, 0x2159, 0x0031, 0x2044, 0x0036, 0, + 17, 0x215A, 0x0035, 0x2044, 0x0036, 0, + 17, 0x215B, 0x0031, 0x2044, 0x0038, 0, + 17, 0x215C, 0x0033, 0x2044, 0x0038, 0, + 17, 0x215D, 0x0035, 0x2044, 0x0038, 0, + 17, 0x215E, 0x0037, 0x2044, 0x0038, 0, + 17, 0x215F, 0x0031, 0x2044, 0, + 16, 0x2160, 0x0049, 0, + 16, 0x2161, 0x0049, 0x0049, 0, + 16, 0x2162, 0x0049, 0x0049, 0x0049, 0, + 16, 0x2163, 0x0049, 0x0056, 0, + 16, 0x2164, 0x0056, 0, + 16, 0x2165, 0x0056, 0x0049, 0, + 16, 0x2166, 0x0056, 0x0049, 0x0049, 0, + 16, 0x2167, 0x0056, 0x0049, 0x0049, 0x0049, 0, + 16, 0x2168, 0x0049, 0x0058, 0, + 16, 0x2169, 0x0058, 0, + 16, 0x216A, 0x0058, 0x0049, 0, + 16, 0x216B, 0x0058, 0x0049, 0x0049, 0, + 16, 0x216C, 0x004C, 0, + 16, 0x216D, 0x0043, 0, + 16, 0x216E, 0x0044, 0, + 16, 0x216F, 0x004D, 0, + 16, 0x2170, 0x0069, 0, + 16, 0x2171, 0x0069, 0x0069, 0, + 16, 0x2172, 0x0069, 0x0069, 0x0069, 0, + 16, 0x2173, 0x0069, 0x0076, 0, + 16, 0x2174, 0x0076, 0, + 16, 0x2175, 0x0076, 0x0069, 0, + 16, 0x2176, 0x0076, 0x0069, 0x0069, 0, + 16, 0x2177, 0x0076, 0x0069, 0x0069, 0x0069, 0, + 16, 0x2178, 0x0069, 0x0078, 0, + 16, 0x2179, 0x0078, 0, + 16, 0x217A, 0x0078, 0x0069, 0, + 16, 0x217B, 0x0078, 0x0069, 0x0069, 0, + 16, 0x217C, 0x006C, 0, + 16, 0x217D, 0x0063, 0, + 16, 0x217E, 0x0064, 0, + 16, 0x217F, 0x006D, 0, + 1, 0x219A, 0x2190, 0x0338, 0, + 1, 0x219B, 0x2192, 0x0338, 0, + 1, 0x21AE, 0x2194, 0x0338, 0, + 1, 0x21CD, 0x21D0, 0x0338, 0, + 1, 0x21CE, 0x21D4, 0x0338, 0, + 1, 0x21CF, 0x21D2, 0x0338, 0, + 1, 0x2204, 0x2203, 0x0338, 0, + 1, 0x2209, 0x2208, 0x0338, 0, + 1, 0x220C, 0x220B, 0x0338, 0, + 1, 0x2224, 0x2223, 0x0338, 0, + 1, 0x2226, 0x2225, 0x0338, 0, + 16, 0x222C, 0x222B, 0x222B, 0, + 16, 0x222D, 0x222B, 0x222B, 0x222B, 0, + 16, 0x222F, 0x222E, 0x222E, 0, + 16, 0x2230, 0x222E, 0x222E, 0x222E, 0, + 1, 0x2241, 0x223C, 0x0338, 0, + 1, 0x2244, 0x2243, 0x0338, 0, + 1, 0x2247, 0x2245, 0x0338, 0, + 1, 0x2249, 0x2248, 0x0338, 0, + 1, 0x2260, 0x003D, 0x0338, 0, + 1, 0x2262, 0x2261, 0x0338, 0, + 1, 0x226D, 0x224D, 0x0338, 0, + 1, 0x226E, 0x003C, 0x0338, 0, + 1, 0x226F, 0x003E, 0x0338, 0, + 1, 0x2270, 0x2264, 0x0338, 0, + 1, 0x2271, 0x2265, 0x0338, 0, + 1, 0x2274, 0x2272, 0x0338, 0, + 1, 0x2275, 0x2273, 0x0338, 0, + 1, 0x2278, 0x2276, 0x0338, 0, + 1, 0x2279, 0x2277, 0x0338, 0, + 1, 0x2280, 0x227A, 0x0338, 0, + 1, 0x2281, 0x227B, 0x0338, 0, + 1, 0x2284, 0x2282, 0x0338, 0, + 1, 0x2285, 0x2283, 0x0338, 0, + 1, 0x2288, 0x2286, 0x0338, 0, + 1, 0x2289, 0x2287, 0x0338, 0, + 1, 0x22AC, 0x22A2, 0x0338, 0, + 1, 0x22AD, 0x22A8, 0x0338, 0, + 1, 0x22AE, 0x22A9, 0x0338, 0, + 1, 0x22AF, 0x22AB, 0x0338, 0, + 1, 0x22E0, 0x227C, 0x0338, 0, + 1, 0x22E1, 0x227D, 0x0338, 0, + 1, 0x22E2, 0x2291, 0x0338, 0, + 1, 0x22E3, 0x2292, 0x0338, 0, + 1, 0x22EA, 0x22B2, 0x0338, 0, + 1, 0x22EB, 0x22B3, 0x0338, 0, + 1, 0x22EC, 0x22B4, 0x0338, 0, + 1, 0x22ED, 0x22B5, 0x0338, 0, + 1, 0x2329, 0x3008, 0, + 1, 0x232A, 0x3009, 0, + 8, 0x2460, 0x0031, 0, + 8, 0x2461, 0x0032, 0, + 8, 0x2462, 0x0033, 0, + 8, 0x2463, 0x0034, 0, + 8, 0x2464, 0x0035, 0, + 8, 0x2465, 0x0036, 0, + 8, 0x2466, 0x0037, 0, + 8, 0x2467, 0x0038, 0, + 8, 0x2468, 0x0039, 0, + 8, 0x2469, 0x0031, 0x0030, 0, + 8, 0x246A, 0x0031, 0x0031, 0, + 8, 0x246B, 0x0031, 0x0032, 0, + 8, 0x246C, 0x0031, 0x0033, 0, + 8, 0x246D, 0x0031, 0x0034, 0, + 8, 0x246E, 0x0031, 0x0035, 0, + 8, 0x246F, 0x0031, 0x0036, 0, + 8, 0x2470, 0x0031, 0x0037, 0, + 8, 0x2471, 0x0031, 0x0038, 0, + 8, 0x2472, 0x0031, 0x0039, 0, + 8, 0x2473, 0x0032, 0x0030, 0, + 16, 0x2474, 0x0028, 0x0031, 0x0029, 0, + 16, 0x2475, 0x0028, 0x0032, 0x0029, 0, + 16, 0x2476, 0x0028, 0x0033, 0x0029, 0, + 16, 0x2477, 0x0028, 0x0034, 0x0029, 0, + 16, 0x2478, 0x0028, 0x0035, 0x0029, 0, + 16, 0x2479, 0x0028, 0x0036, 0x0029, 0, + 16, 0x247A, 0x0028, 0x0037, 0x0029, 0, + 16, 0x247B, 0x0028, 0x0038, 0x0029, 0, + 16, 0x247C, 0x0028, 0x0039, 0x0029, 0, + 16, 0x247D, 0x0028, 0x0031, 0x0030, 0x0029, 0, + 16, 0x247E, 0x0028, 0x0031, 0x0031, 0x0029, 0, + 16, 0x247F, 0x0028, 0x0031, 0x0032, 0x0029, 0, + 16, 0x2480, 0x0028, 0x0031, 0x0033, 0x0029, 0, + 16, 0x2481, 0x0028, 0x0031, 0x0034, 0x0029, 0, + 16, 0x2482, 0x0028, 0x0031, 0x0035, 0x0029, 0, + 16, 0x2483, 0x0028, 0x0031, 0x0036, 0x0029, 0, + 16, 0x2484, 0x0028, 0x0031, 0x0037, 0x0029, 0, + 16, 0x2485, 0x0028, 0x0031, 0x0038, 0x0029, 0, + 16, 0x2486, 0x0028, 0x0031, 0x0039, 0x0029, 0, + 16, 0x2487, 0x0028, 0x0032, 0x0030, 0x0029, 0, + 16, 0x2488, 0x0031, 0x002E, 0, + 16, 0x2489, 0x0032, 0x002E, 0, + 16, 0x248A, 0x0033, 0x002E, 0, + 16, 0x248B, 0x0034, 0x002E, 0, + 16, 0x248C, 0x0035, 0x002E, 0, + 16, 0x248D, 0x0036, 0x002E, 0, + 16, 0x248E, 0x0037, 0x002E, 0, + 16, 0x248F, 0x0038, 0x002E, 0, + 16, 0x2490, 0x0039, 0x002E, 0, + 16, 0x2491, 0x0031, 0x0030, 0x002E, 0, + 16, 0x2492, 0x0031, 0x0031, 0x002E, 0, + 16, 0x2493, 0x0031, 0x0032, 0x002E, 0, + 16, 0x2494, 0x0031, 0x0033, 0x002E, 0, + 16, 0x2495, 0x0031, 0x0034, 0x002E, 0, + 16, 0x2496, 0x0031, 0x0035, 0x002E, 0, + 16, 0x2497, 0x0031, 0x0036, 0x002E, 0, + 16, 0x2498, 0x0031, 0x0037, 0x002E, 0, + 16, 0x2499, 0x0031, 0x0038, 0x002E, 0, + 16, 0x249A, 0x0031, 0x0039, 0x002E, 0, + 16, 0x249B, 0x0032, 0x0030, 0x002E, 0, + 16, 0x249C, 0x0028, 0x0061, 0x0029, 0, + 16, 0x249D, 0x0028, 0x0062, 0x0029, 0, + 16, 0x249E, 0x0028, 0x0063, 0x0029, 0, + 16, 0x249F, 0x0028, 0x0064, 0x0029, 0, + 16, 0x24A0, 0x0028, 0x0065, 0x0029, 0, + 16, 0x24A1, 0x0028, 0x0066, 0x0029, 0, + 16, 0x24A2, 0x0028, 0x0067, 0x0029, 0, + 16, 0x24A3, 0x0028, 0x0068, 0x0029, 0, + 16, 0x24A4, 0x0028, 0x0069, 0x0029, 0, + 16, 0x24A5, 0x0028, 0x006A, 0x0029, 0, + 16, 0x24A6, 0x0028, 0x006B, 0x0029, 0, + 16, 0x24A7, 0x0028, 0x006C, 0x0029, 0, + 16, 0x24A8, 0x0028, 0x006D, 0x0029, 0, + 16, 0x24A9, 0x0028, 0x006E, 0x0029, 0, + 16, 0x24AA, 0x0028, 0x006F, 0x0029, 0, + 16, 0x24AB, 0x0028, 0x0070, 0x0029, 0, + 16, 0x24AC, 0x0028, 0x0071, 0x0029, 0, + 16, 0x24AD, 0x0028, 0x0072, 0x0029, 0, + 16, 0x24AE, 0x0028, 0x0073, 0x0029, 0, + 16, 0x24AF, 0x0028, 0x0074, 0x0029, 0, + 16, 0x24B0, 0x0028, 0x0075, 0x0029, 0, + 16, 0x24B1, 0x0028, 0x0076, 0x0029, 0, + 16, 0x24B2, 0x0028, 0x0077, 0x0029, 0, + 16, 0x24B3, 0x0028, 0x0078, 0x0029, 0, + 16, 0x24B4, 0x0028, 0x0079, 0x0029, 0, + 16, 0x24B5, 0x0028, 0x007A, 0x0029, 0, + 8, 0x24B6, 0x0041, 0, + 8, 0x24B7, 0x0042, 0, + 8, 0x24B8, 0x0043, 0, + 8, 0x24B9, 0x0044, 0, + 8, 0x24BA, 0x0045, 0, + 8, 0x24BB, 0x0046, 0, + 8, 0x24BC, 0x0047, 0, + 8, 0x24BD, 0x0048, 0, + 8, 0x24BE, 0x0049, 0, + 8, 0x24BF, 0x004A, 0, + 8, 0x24C0, 0x004B, 0, + 8, 0x24C1, 0x004C, 0, + 8, 0x24C2, 0x004D, 0, + 8, 0x24C3, 0x004E, 0, + 8, 0x24C4, 0x004F, 0, + 8, 0x24C5, 0x0050, 0, + 8, 0x24C6, 0x0051, 0, + 8, 0x24C7, 0x0052, 0, + 8, 0x24C8, 0x0053, 0, + 8, 0x24C9, 0x0054, 0, + 8, 0x24CA, 0x0055, 0, + 8, 0x24CB, 0x0056, 0, + 8, 0x24CC, 0x0057, 0, + 8, 0x24CD, 0x0058, 0, + 8, 0x24CE, 0x0059, 0, + 8, 0x24CF, 0x005A, 0, + 8, 0x24D0, 0x0061, 0, + 8, 0x24D1, 0x0062, 0, + 8, 0x24D2, 0x0063, 0, + 8, 0x24D3, 0x0064, 0, + 8, 0x24D4, 0x0065, 0, + 8, 0x24D5, 0x0066, 0, + 8, 0x24D6, 0x0067, 0, + 8, 0x24D7, 0x0068, 0, + 8, 0x24D8, 0x0069, 0, + 8, 0x24D9, 0x006A, 0, + 8, 0x24DA, 0x006B, 0, + 8, 0x24DB, 0x006C, 0, + 8, 0x24DC, 0x006D, 0, + 8, 0x24DD, 0x006E, 0, + 8, 0x24DE, 0x006F, 0, + 8, 0x24DF, 0x0070, 0, + 8, 0x24E0, 0x0071, 0, + 8, 0x24E1, 0x0072, 0, + 8, 0x24E2, 0x0073, 0, + 8, 0x24E3, 0x0074, 0, + 8, 0x24E4, 0x0075, 0, + 8, 0x24E5, 0x0076, 0, + 8, 0x24E6, 0x0077, 0, + 8, 0x24E7, 0x0078, 0, + 8, 0x24E8, 0x0079, 0, + 8, 0x24E9, 0x007A, 0, + 8, 0x24EA, 0x0030, 0, + 16, 0x2A0C, 0x222B, 0x222B, 0x222B, 0x222B, 0, + 16, 0x2A74, 0x003A, 0x003A, 0x003D, 0, + 16, 0x2A75, 0x003D, 0x003D, 0, + 16, 0x2A76, 0x003D, 0x003D, 0x003D, 0, + 1, 0x2ADC, 0x2ADD, 0x0338, 0, + 16, 0x2E9F, 0x6BCD, 0, + 16, 0x2EF3, 0x9F9F, 0, + 16, 0x2F00, 0x4E00, 0, + 16, 0x2F01, 0x4E28, 0, + 16, 0x2F02, 0x4E36, 0, + 16, 0x2F03, 0x4E3F, 0, + 16, 0x2F04, 0x4E59, 0, + 16, 0x2F05, 0x4E85, 0, + 16, 0x2F06, 0x4E8C, 0, + 16, 0x2F07, 0x4EA0, 0, + 16, 0x2F08, 0x4EBA, 0, + 16, 0x2F09, 0x513F, 0, + 16, 0x2F0A, 0x5165, 0, + 16, 0x2F0B, 0x516B, 0, + 16, 0x2F0C, 0x5182, 0, + 16, 0x2F0D, 0x5196, 0, + 16, 0x2F0E, 0x51AB, 0, + 16, 0x2F0F, 0x51E0, 0, + 16, 0x2F10, 0x51F5, 0, + 16, 0x2F11, 0x5200, 0, + 16, 0x2F12, 0x529B, 0, + 16, 0x2F13, 0x52F9, 0, + 16, 0x2F14, 0x5315, 0, + 16, 0x2F15, 0x531A, 0, + 16, 0x2F16, 0x5338, 0, + 16, 0x2F17, 0x5341, 0, + 16, 0x2F18, 0x535C, 0, + 16, 0x2F19, 0x5369, 0, + 16, 0x2F1A, 0x5382, 0, + 16, 0x2F1B, 0x53B6, 0, + 16, 0x2F1C, 0x53C8, 0, + 16, 0x2F1D, 0x53E3, 0, + 16, 0x2F1E, 0x56D7, 0, + 16, 0x2F1F, 0x571F, 0, + 16, 0x2F20, 0x58EB, 0, + 16, 0x2F21, 0x5902, 0, + 16, 0x2F22, 0x590A, 0, + 16, 0x2F23, 0x5915, 0, + 16, 0x2F24, 0x5927, 0, + 16, 0x2F25, 0x5973, 0, + 16, 0x2F26, 0x5B50, 0, + 16, 0x2F27, 0x5B80, 0, + 16, 0x2F28, 0x5BF8, 0, + 16, 0x2F29, 0x5C0F, 0, + 16, 0x2F2A, 0x5C22, 0, + 16, 0x2F2B, 0x5C38, 0, + 16, 0x2F2C, 0x5C6E, 0, + 16, 0x2F2D, 0x5C71, 0, + 16, 0x2F2E, 0x5DDB, 0, + 16, 0x2F2F, 0x5DE5, 0, + 16, 0x2F30, 0x5DF1, 0, + 16, 0x2F31, 0x5DFE, 0, + 16, 0x2F32, 0x5E72, 0, + 16, 0x2F33, 0x5E7A, 0, + 16, 0x2F34, 0x5E7F, 0, + 16, 0x2F35, 0x5EF4, 0, + 16, 0x2F36, 0x5EFE, 0, + 16, 0x2F37, 0x5F0B, 0, + 16, 0x2F38, 0x5F13, 0, + 16, 0x2F39, 0x5F50, 0, + 16, 0x2F3A, 0x5F61, 0, + 16, 0x2F3B, 0x5F73, 0, + 16, 0x2F3C, 0x5FC3, 0, + 16, 0x2F3D, 0x6208, 0, + 16, 0x2F3E, 0x6236, 0, + 16, 0x2F3F, 0x624B, 0, + 16, 0x2F40, 0x652F, 0, + 16, 0x2F41, 0x6534, 0, + 16, 0x2F42, 0x6587, 0, + 16, 0x2F43, 0x6597, 0, + 16, 0x2F44, 0x65A4, 0, + 16, 0x2F45, 0x65B9, 0, + 16, 0x2F46, 0x65E0, 0, + 16, 0x2F47, 0x65E5, 0, + 16, 0x2F48, 0x66F0, 0, + 16, 0x2F49, 0x6708, 0, + 16, 0x2F4A, 0x6728, 0, + 16, 0x2F4B, 0x6B20, 0, + 16, 0x2F4C, 0x6B62, 0, + 16, 0x2F4D, 0x6B79, 0, + 16, 0x2F4E, 0x6BB3, 0, + 16, 0x2F4F, 0x6BCB, 0, + 16, 0x2F50, 0x6BD4, 0, + 16, 0x2F51, 0x6BDB, 0, + 16, 0x2F52, 0x6C0F, 0, + 16, 0x2F53, 0x6C14, 0, + 16, 0x2F54, 0x6C34, 0, + 16, 0x2F55, 0x706B, 0, + 16, 0x2F56, 0x722A, 0, + 16, 0x2F57, 0x7236, 0, + 16, 0x2F58, 0x723B, 0, + 16, 0x2F59, 0x723F, 0, + 16, 0x2F5A, 0x7247, 0, + 16, 0x2F5B, 0x7259, 0, + 16, 0x2F5C, 0x725B, 0, + 16, 0x2F5D, 0x72AC, 0, + 16, 0x2F5E, 0x7384, 0, + 16, 0x2F5F, 0x7389, 0, + 16, 0x2F60, 0x74DC, 0, + 16, 0x2F61, 0x74E6, 0, + 16, 0x2F62, 0x7518, 0, + 16, 0x2F63, 0x751F, 0, + 16, 0x2F64, 0x7528, 0, + 16, 0x2F65, 0x7530, 0, + 16, 0x2F66, 0x758B, 0, + 16, 0x2F67, 0x7592, 0, + 16, 0x2F68, 0x7676, 0, + 16, 0x2F69, 0x767D, 0, + 16, 0x2F6A, 0x76AE, 0, + 16, 0x2F6B, 0x76BF, 0, + 16, 0x2F6C, 0x76EE, 0, + 16, 0x2F6D, 0x77DB, 0, + 16, 0x2F6E, 0x77E2, 0, + 16, 0x2F6F, 0x77F3, 0, + 16, 0x2F70, 0x793A, 0, + 16, 0x2F71, 0x79B8, 0, + 16, 0x2F72, 0x79BE, 0, + 16, 0x2F73, 0x7A74, 0, + 16, 0x2F74, 0x7ACB, 0, + 16, 0x2F75, 0x7AF9, 0, + 16, 0x2F76, 0x7C73, 0, + 16, 0x2F77, 0x7CF8, 0, + 16, 0x2F78, 0x7F36, 0, + 16, 0x2F79, 0x7F51, 0, + 16, 0x2F7A, 0x7F8A, 0, + 16, 0x2F7B, 0x7FBD, 0, + 16, 0x2F7C, 0x8001, 0, + 16, 0x2F7D, 0x800C, 0, + 16, 0x2F7E, 0x8012, 0, + 16, 0x2F7F, 0x8033, 0, + 16, 0x2F80, 0x807F, 0, + 16, 0x2F81, 0x8089, 0, + 16, 0x2F82, 0x81E3, 0, + 16, 0x2F83, 0x81EA, 0, + 16, 0x2F84, 0x81F3, 0, + 16, 0x2F85, 0x81FC, 0, + 16, 0x2F86, 0x820C, 0, + 16, 0x2F87, 0x821B, 0, + 16, 0x2F88, 0x821F, 0, + 16, 0x2F89, 0x826E, 0, + 16, 0x2F8A, 0x8272, 0, + 16, 0x2F8B, 0x8278, 0, + 16, 0x2F8C, 0x864D, 0, + 16, 0x2F8D, 0x866B, 0, + 16, 0x2F8E, 0x8840, 0, + 16, 0x2F8F, 0x884C, 0, + 16, 0x2F90, 0x8863, 0, + 16, 0x2F91, 0x897E, 0, + 16, 0x2F92, 0x898B, 0, + 16, 0x2F93, 0x89D2, 0, + 16, 0x2F94, 0x8A00, 0, + 16, 0x2F95, 0x8C37, 0, + 16, 0x2F96, 0x8C46, 0, + 16, 0x2F97, 0x8C55, 0, + 16, 0x2F98, 0x8C78, 0, + 16, 0x2F99, 0x8C9D, 0, + 16, 0x2F9A, 0x8D64, 0, + 16, 0x2F9B, 0x8D70, 0, + 16, 0x2F9C, 0x8DB3, 0, + 16, 0x2F9D, 0x8EAB, 0, + 16, 0x2F9E, 0x8ECA, 0, + 16, 0x2F9F, 0x8F9B, 0, + 16, 0x2FA0, 0x8FB0, 0, + 16, 0x2FA1, 0x8FB5, 0, + 16, 0x2FA2, 0x9091, 0, + 16, 0x2FA3, 0x9149, 0, + 16, 0x2FA4, 0x91C6, 0, + 16, 0x2FA5, 0x91CC, 0, + 16, 0x2FA6, 0x91D1, 0, + 16, 0x2FA7, 0x9577, 0, + 16, 0x2FA8, 0x9580, 0, + 16, 0x2FA9, 0x961C, 0, + 16, 0x2FAA, 0x96B6, 0, + 16, 0x2FAB, 0x96B9, 0, + 16, 0x2FAC, 0x96E8, 0, + 16, 0x2FAD, 0x9751, 0, + 16, 0x2FAE, 0x975E, 0, + 16, 0x2FAF, 0x9762, 0, + 16, 0x2FB0, 0x9769, 0, + 16, 0x2FB1, 0x97CB, 0, + 16, 0x2FB2, 0x97ED, 0, + 16, 0x2FB3, 0x97F3, 0, + 16, 0x2FB4, 0x9801, 0, + 16, 0x2FB5, 0x98A8, 0, + 16, 0x2FB6, 0x98DB, 0, + 16, 0x2FB7, 0x98DF, 0, + 16, 0x2FB8, 0x9996, 0, + 16, 0x2FB9, 0x9999, 0, + 16, 0x2FBA, 0x99AC, 0, + 16, 0x2FBB, 0x9AA8, 0, + 16, 0x2FBC, 0x9AD8, 0, + 16, 0x2FBD, 0x9ADF, 0, + 16, 0x2FBE, 0x9B25, 0, + 16, 0x2FBF, 0x9B2F, 0, + 16, 0x2FC0, 0x9B32, 0, + 16, 0x2FC1, 0x9B3C, 0, + 16, 0x2FC2, 0x9B5A, 0, + 16, 0x2FC3, 0x9CE5, 0, + 16, 0x2FC4, 0x9E75, 0, + 16, 0x2FC5, 0x9E7F, 0, + 16, 0x2FC6, 0x9EA5, 0, + 16, 0x2FC7, 0x9EBB, 0, + 16, 0x2FC8, 0x9EC3, 0, + 16, 0x2FC9, 0x9ECD, 0, + 16, 0x2FCA, 0x9ED1, 0, + 16, 0x2FCB, 0x9EF9, 0, + 16, 0x2FCC, 0x9EFD, 0, + 16, 0x2FCD, 0x9F0E, 0, + 16, 0x2FCE, 0x9F13, 0, + 16, 0x2FCF, 0x9F20, 0, + 16, 0x2FD0, 0x9F3B, 0, + 16, 0x2FD1, 0x9F4A, 0, + 16, 0x2FD2, 0x9F52, 0, + 16, 0x2FD3, 0x9F8D, 0, + 16, 0x2FD4, 0x9F9C, 0, + 16, 0x2FD5, 0x9FA0, 0, + 12, 0x3000, 0x0020, 0, + 16, 0x3036, 0x3012, 0, + 16, 0x3038, 0x5341, 0, + 16, 0x3039, 0x5344, 0, + 16, 0x303A, 0x5345, 0, + 1, 0x304C, 0x304B, 0x3099, 0, + 1, 0x304E, 0x304D, 0x3099, 0, + 1, 0x3050, 0x304F, 0x3099, 0, + 1, 0x3052, 0x3051, 0x3099, 0, + 1, 0x3054, 0x3053, 0x3099, 0, + 1, 0x3056, 0x3055, 0x3099, 0, + 1, 0x3058, 0x3057, 0x3099, 0, + 1, 0x305A, 0x3059, 0x3099, 0, + 1, 0x305C, 0x305B, 0x3099, 0, + 1, 0x305E, 0x305D, 0x3099, 0, + 1, 0x3060, 0x305F, 0x3099, 0, + 1, 0x3062, 0x3061, 0x3099, 0, + 1, 0x3065, 0x3064, 0x3099, 0, + 1, 0x3067, 0x3066, 0x3099, 0, + 1, 0x3069, 0x3068, 0x3099, 0, + 1, 0x3070, 0x306F, 0x3099, 0, + 1, 0x3071, 0x306F, 0x309A, 0, + 1, 0x3073, 0x3072, 0x3099, 0, + 1, 0x3074, 0x3072, 0x309A, 0, + 1, 0x3076, 0x3075, 0x3099, 0, + 1, 0x3077, 0x3075, 0x309A, 0, + 1, 0x3079, 0x3078, 0x3099, 0, + 1, 0x307A, 0x3078, 0x309A, 0, + 1, 0x307C, 0x307B, 0x3099, 0, + 1, 0x307D, 0x307B, 0x309A, 0, + 1, 0x3094, 0x3046, 0x3099, 0, + 16, 0x309B, 0x0020, 0x3099, 0, + 16, 0x309C, 0x0020, 0x309A, 0, + 1, 0x309E, 0x309D, 0x3099, 0, + 11, 0x309F, 0x3088, 0x308A, 0, + 1, 0x30AC, 0x30AB, 0x3099, 0, + 1, 0x30AE, 0x30AD, 0x3099, 0, + 1, 0x30B0, 0x30AF, 0x3099, 0, + 1, 0x30B2, 0x30B1, 0x3099, 0, + 1, 0x30B4, 0x30B3, 0x3099, 0, + 1, 0x30B6, 0x30B5, 0x3099, 0, + 1, 0x30B8, 0x30B7, 0x3099, 0, + 1, 0x30BA, 0x30B9, 0x3099, 0, + 1, 0x30BC, 0x30BB, 0x3099, 0, + 1, 0x30BE, 0x30BD, 0x3099, 0, + 1, 0x30C0, 0x30BF, 0x3099, 0, + 1, 0x30C2, 0x30C1, 0x3099, 0, + 1, 0x30C5, 0x30C4, 0x3099, 0, + 1, 0x30C7, 0x30C6, 0x3099, 0, + 1, 0x30C9, 0x30C8, 0x3099, 0, + 1, 0x30D0, 0x30CF, 0x3099, 0, + 1, 0x30D1, 0x30CF, 0x309A, 0, + 1, 0x30D3, 0x30D2, 0x3099, 0, + 1, 0x30D4, 0x30D2, 0x309A, 0, + 1, 0x30D6, 0x30D5, 0x3099, 0, + 1, 0x30D7, 0x30D5, 0x309A, 0, + 1, 0x30D9, 0x30D8, 0x3099, 0, + 1, 0x30DA, 0x30D8, 0x309A, 0, + 1, 0x30DC, 0x30DB, 0x3099, 0, + 1, 0x30DD, 0x30DB, 0x309A, 0, + 1, 0x30F4, 0x30A6, 0x3099, 0, + 1, 0x30F7, 0x30EF, 0x3099, 0, + 1, 0x30F8, 0x30F0, 0x3099, 0, + 1, 0x30F9, 0x30F1, 0x3099, 0, + 1, 0x30FA, 0x30F2, 0x3099, 0, + 1, 0x30FE, 0x30FD, 0x3099, 0, + 11, 0x30FF, 0x30B3, 0x30C8, 0, + 16, 0x3131, 0x1100, 0, + 16, 0x3132, 0x1101, 0, + 16, 0x3133, 0x11AA, 0, + 16, 0x3134, 0x1102, 0, + 16, 0x3135, 0x11AC, 0, + 16, 0x3136, 0x11AD, 0, + 16, 0x3137, 0x1103, 0, + 16, 0x3138, 0x1104, 0, + 16, 0x3139, 0x1105, 0, + 16, 0x313A, 0x11B0, 0, + 16, 0x313B, 0x11B1, 0, + 16, 0x313C, 0x11B2, 0, + 16, 0x313D, 0x11B3, 0, + 16, 0x313E, 0x11B4, 0, + 16, 0x313F, 0x11B5, 0, + 16, 0x3140, 0x111A, 0, + 16, 0x3141, 0x1106, 0, + 16, 0x3142, 0x1107, 0, + 16, 0x3143, 0x1108, 0, + 16, 0x3144, 0x1121, 0, + 16, 0x3145, 0x1109, 0, + 16, 0x3146, 0x110A, 0, + 16, 0x3147, 0x110B, 0, + 16, 0x3148, 0x110C, 0, + 16, 0x3149, 0x110D, 0, + 16, 0x314A, 0x110E, 0, + 16, 0x314B, 0x110F, 0, + 16, 0x314C, 0x1110, 0, + 16, 0x314D, 0x1111, 0, + 16, 0x314E, 0x1112, 0, + 16, 0x314F, 0x1161, 0, + 16, 0x3150, 0x1162, 0, + 16, 0x3151, 0x1163, 0, + 16, 0x3152, 0x1164, 0, + 16, 0x3153, 0x1165, 0, + 16, 0x3154, 0x1166, 0, + 16, 0x3155, 0x1167, 0, + 16, 0x3156, 0x1168, 0, + 16, 0x3157, 0x1169, 0, + 16, 0x3158, 0x116A, 0, + 16, 0x3159, 0x116B, 0, + 16, 0x315A, 0x116C, 0, + 16, 0x315B, 0x116D, 0, + 16, 0x315C, 0x116E, 0, + 16, 0x315D, 0x116F, 0, + 16, 0x315E, 0x1170, 0, + 16, 0x315F, 0x1171, 0, + 16, 0x3160, 0x1172, 0, + 16, 0x3161, 0x1173, 0, + 16, 0x3162, 0x1174, 0, + 16, 0x3163, 0x1175, 0, + 16, 0x3164, 0x1160, 0, + 16, 0x3165, 0x1114, 0, + 16, 0x3166, 0x1115, 0, + 16, 0x3167, 0x11C7, 0, + 16, 0x3168, 0x11C8, 0, + 16, 0x3169, 0x11CC, 0, + 16, 0x316A, 0x11CE, 0, + 16, 0x316B, 0x11D3, 0, + 16, 0x316C, 0x11D7, 0, + 16, 0x316D, 0x11D9, 0, + 16, 0x316E, 0x111C, 0, + 16, 0x316F, 0x11DD, 0, + 16, 0x3170, 0x11DF, 0, + 16, 0x3171, 0x111D, 0, + 16, 0x3172, 0x111E, 0, + 16, 0x3173, 0x1120, 0, + 16, 0x3174, 0x1122, 0, + 16, 0x3175, 0x1123, 0, + 16, 0x3176, 0x1127, 0, + 16, 0x3177, 0x1129, 0, + 16, 0x3178, 0x112B, 0, + 16, 0x3179, 0x112C, 0, + 16, 0x317A, 0x112D, 0, + 16, 0x317B, 0x112E, 0, + 16, 0x317C, 0x112F, 0, + 16, 0x317D, 0x1132, 0, + 16, 0x317E, 0x1136, 0, + 16, 0x317F, 0x1140, 0, + 16, 0x3180, 0x1147, 0, + 16, 0x3181, 0x114C, 0, + 16, 0x3182, 0x11F1, 0, + 16, 0x3183, 0x11F2, 0, + 16, 0x3184, 0x1157, 0, + 16, 0x3185, 0x1158, 0, + 16, 0x3186, 0x1159, 0, + 16, 0x3187, 0x1184, 0, + 16, 0x3188, 0x1185, 0, + 16, 0x3189, 0x1188, 0, + 16, 0x318A, 0x1191, 0, + 16, 0x318B, 0x1192, 0, + 16, 0x318C, 0x1194, 0, + 16, 0x318D, 0x119E, 0, + 16, 0x318E, 0x11A1, 0, + 9, 0x3192, 0x4E00, 0, + 9, 0x3193, 0x4E8C, 0, + 9, 0x3194, 0x4E09, 0, + 9, 0x3195, 0x56DB, 0, + 9, 0x3196, 0x4E0A, 0, + 9, 0x3197, 0x4E2D, 0, + 9, 0x3198, 0x4E0B, 0, + 9, 0x3199, 0x7532, 0, + 9, 0x319A, 0x4E59, 0, + 9, 0x319B, 0x4E19, 0, + 9, 0x319C, 0x4E01, 0, + 9, 0x319D, 0x5929, 0, + 9, 0x319E, 0x5730, 0, + 9, 0x319F, 0x4EBA, 0, + 16, 0x3200, 0x0028, 0x1100, 0x0029, 0, + 16, 0x3201, 0x0028, 0x1102, 0x0029, 0, + 16, 0x3202, 0x0028, 0x1103, 0x0029, 0, + 16, 0x3203, 0x0028, 0x1105, 0x0029, 0, + 16, 0x3204, 0x0028, 0x1106, 0x0029, 0, + 16, 0x3205, 0x0028, 0x1107, 0x0029, 0, + 16, 0x3206, 0x0028, 0x1109, 0x0029, 0, + 16, 0x3207, 0x0028, 0x110B, 0x0029, 0, + 16, 0x3208, 0x0028, 0x110C, 0x0029, 0, + 16, 0x3209, 0x0028, 0x110E, 0x0029, 0, + 16, 0x320A, 0x0028, 0x110F, 0x0029, 0, + 16, 0x320B, 0x0028, 0x1110, 0x0029, 0, + 16, 0x320C, 0x0028, 0x1111, 0x0029, 0, + 16, 0x320D, 0x0028, 0x1112, 0x0029, 0, + 16, 0x320E, 0x0028, 0x1100, 0x1161, 0x0029, 0, + 16, 0x320F, 0x0028, 0x1102, 0x1161, 0x0029, 0, + 16, 0x3210, 0x0028, 0x1103, 0x1161, 0x0029, 0, + 16, 0x3211, 0x0028, 0x1105, 0x1161, 0x0029, 0, + 16, 0x3212, 0x0028, 0x1106, 0x1161, 0x0029, 0, + 16, 0x3213, 0x0028, 0x1107, 0x1161, 0x0029, 0, + 16, 0x3214, 0x0028, 0x1109, 0x1161, 0x0029, 0, + 16, 0x3215, 0x0028, 0x110B, 0x1161, 0x0029, 0, + 16, 0x3216, 0x0028, 0x110C, 0x1161, 0x0029, 0, + 16, 0x3217, 0x0028, 0x110E, 0x1161, 0x0029, 0, + 16, 0x3218, 0x0028, 0x110F, 0x1161, 0x0029, 0, + 16, 0x3219, 0x0028, 0x1110, 0x1161, 0x0029, 0, + 16, 0x321A, 0x0028, 0x1111, 0x1161, 0x0029, 0, + 16, 0x321B, 0x0028, 0x1112, 0x1161, 0x0029, 0, + 16, 0x321C, 0x0028, 0x110C, 0x116E, 0x0029, 0, + 16, 0x3220, 0x0028, 0x4E00, 0x0029, 0, + 16, 0x3221, 0x0028, 0x4E8C, 0x0029, 0, + 16, 0x3222, 0x0028, 0x4E09, 0x0029, 0, + 16, 0x3223, 0x0028, 0x56DB, 0x0029, 0, + 16, 0x3224, 0x0028, 0x4E94, 0x0029, 0, + 16, 0x3225, 0x0028, 0x516D, 0x0029, 0, + 16, 0x3226, 0x0028, 0x4E03, 0x0029, 0, + 16, 0x3227, 0x0028, 0x516B, 0x0029, 0, + 16, 0x3228, 0x0028, 0x4E5D, 0x0029, 0, + 16, 0x3229, 0x0028, 0x5341, 0x0029, 0, + 16, 0x322A, 0x0028, 0x6708, 0x0029, 0, + 16, 0x322B, 0x0028, 0x706B, 0x0029, 0, + 16, 0x322C, 0x0028, 0x6C34, 0x0029, 0, + 16, 0x322D, 0x0028, 0x6728, 0x0029, 0, + 16, 0x322E, 0x0028, 0x91D1, 0x0029, 0, + 16, 0x322F, 0x0028, 0x571F, 0x0029, 0, + 16, 0x3230, 0x0028, 0x65E5, 0x0029, 0, + 16, 0x3231, 0x0028, 0x682A, 0x0029, 0, + 16, 0x3232, 0x0028, 0x6709, 0x0029, 0, + 16, 0x3233, 0x0028, 0x793E, 0x0029, 0, + 16, 0x3234, 0x0028, 0x540D, 0x0029, 0, + 16, 0x3235, 0x0028, 0x7279, 0x0029, 0, + 16, 0x3236, 0x0028, 0x8CA1, 0x0029, 0, + 16, 0x3237, 0x0028, 0x795D, 0x0029, 0, + 16, 0x3238, 0x0028, 0x52B4, 0x0029, 0, + 16, 0x3239, 0x0028, 0x4EE3, 0x0029, 0, + 16, 0x323A, 0x0028, 0x547C, 0x0029, 0, + 16, 0x323B, 0x0028, 0x5B66, 0x0029, 0, + 16, 0x323C, 0x0028, 0x76E3, 0x0029, 0, + 16, 0x323D, 0x0028, 0x4F01, 0x0029, 0, + 16, 0x323E, 0x0028, 0x8CC7, 0x0029, 0, + 16, 0x323F, 0x0028, 0x5354, 0x0029, 0, + 16, 0x3240, 0x0028, 0x796D, 0x0029, 0, + 16, 0x3241, 0x0028, 0x4F11, 0x0029, 0, + 16, 0x3242, 0x0028, 0x81EA, 0x0029, 0, + 16, 0x3243, 0x0028, 0x81F3, 0x0029, 0, + 8, 0x3251, 0x0032, 0x0031, 0, + 8, 0x3252, 0x0032, 0x0032, 0, + 8, 0x3253, 0x0032, 0x0033, 0, + 8, 0x3254, 0x0032, 0x0034, 0, + 8, 0x3255, 0x0032, 0x0035, 0, + 8, 0x3256, 0x0032, 0x0036, 0, + 8, 0x3257, 0x0032, 0x0037, 0, + 8, 0x3258, 0x0032, 0x0038, 0, + 8, 0x3259, 0x0032, 0x0039, 0, + 8, 0x325A, 0x0033, 0x0030, 0, + 8, 0x325B, 0x0033, 0x0031, 0, + 8, 0x325C, 0x0033, 0x0032, 0, + 8, 0x325D, 0x0033, 0x0033, 0, + 8, 0x325E, 0x0033, 0x0034, 0, + 8, 0x325F, 0x0033, 0x0035, 0, + 8, 0x3260, 0x1100, 0, + 8, 0x3261, 0x1102, 0, + 8, 0x3262, 0x1103, 0, + 8, 0x3263, 0x1105, 0, + 8, 0x3264, 0x1106, 0, + 8, 0x3265, 0x1107, 0, + 8, 0x3266, 0x1109, 0, + 8, 0x3267, 0x110B, 0, + 8, 0x3268, 0x110C, 0, + 8, 0x3269, 0x110E, 0, + 8, 0x326A, 0x110F, 0, + 8, 0x326B, 0x1110, 0, + 8, 0x326C, 0x1111, 0, + 8, 0x326D, 0x1112, 0, + 8, 0x326E, 0x1100, 0x1161, 0, + 8, 0x326F, 0x1102, 0x1161, 0, + 8, 0x3270, 0x1103, 0x1161, 0, + 8, 0x3271, 0x1105, 0x1161, 0, + 8, 0x3272, 0x1106, 0x1161, 0, + 8, 0x3273, 0x1107, 0x1161, 0, + 8, 0x3274, 0x1109, 0x1161, 0, + 8, 0x3275, 0x110B, 0x1161, 0, + 8, 0x3276, 0x110C, 0x1161, 0, + 8, 0x3277, 0x110E, 0x1161, 0, + 8, 0x3278, 0x110F, 0x1161, 0, + 8, 0x3279, 0x1110, 0x1161, 0, + 8, 0x327A, 0x1111, 0x1161, 0, + 8, 0x327B, 0x1112, 0x1161, 0, + 8, 0x3280, 0x4E00, 0, + 8, 0x3281, 0x4E8C, 0, + 8, 0x3282, 0x4E09, 0, + 8, 0x3283, 0x56DB, 0, + 8, 0x3284, 0x4E94, 0, + 8, 0x3285, 0x516D, 0, + 8, 0x3286, 0x4E03, 0, + 8, 0x3287, 0x516B, 0, + 8, 0x3288, 0x4E5D, 0, + 8, 0x3289, 0x5341, 0, + 8, 0x328A, 0x6708, 0, + 8, 0x328B, 0x706B, 0, + 8, 0x328C, 0x6C34, 0, + 8, 0x328D, 0x6728, 0, + 8, 0x328E, 0x91D1, 0, + 8, 0x328F, 0x571F, 0, + 8, 0x3290, 0x65E5, 0, + 8, 0x3291, 0x682A, 0, + 8, 0x3292, 0x6709, 0, + 8, 0x3293, 0x793E, 0, + 8, 0x3294, 0x540D, 0, + 8, 0x3295, 0x7279, 0, + 8, 0x3296, 0x8CA1, 0, + 8, 0x3297, 0x795D, 0, + 8, 0x3298, 0x52B4, 0, + 8, 0x3299, 0x79D8, 0, + 8, 0x329A, 0x7537, 0, + 8, 0x329B, 0x5973, 0, + 8, 0x329C, 0x9069, 0, + 8, 0x329D, 0x512A, 0, + 8, 0x329E, 0x5370, 0, + 8, 0x329F, 0x6CE8, 0, + 8, 0x32A0, 0x9805, 0, + 8, 0x32A1, 0x4F11, 0, + 8, 0x32A2, 0x5199, 0, + 8, 0x32A3, 0x6B63, 0, + 8, 0x32A4, 0x4E0A, 0, + 8, 0x32A5, 0x4E2D, 0, + 8, 0x32A6, 0x4E0B, 0, + 8, 0x32A7, 0x5DE6, 0, + 8, 0x32A8, 0x53F3, 0, + 8, 0x32A9, 0x533B, 0, + 8, 0x32AA, 0x5B97, 0, + 8, 0x32AB, 0x5B66, 0, + 8, 0x32AC, 0x76E3, 0, + 8, 0x32AD, 0x4F01, 0, + 8, 0x32AE, 0x8CC7, 0, + 8, 0x32AF, 0x5354, 0, + 8, 0x32B0, 0x591C, 0, + 8, 0x32B1, 0x0033, 0x0036, 0, + 8, 0x32B2, 0x0033, 0x0037, 0, + 8, 0x32B3, 0x0033, 0x0038, 0, + 8, 0x32B4, 0x0033, 0x0039, 0, + 8, 0x32B5, 0x0034, 0x0030, 0, + 8, 0x32B6, 0x0034, 0x0031, 0, + 8, 0x32B7, 0x0034, 0x0032, 0, + 8, 0x32B8, 0x0034, 0x0033, 0, + 8, 0x32B9, 0x0034, 0x0034, 0, + 8, 0x32BA, 0x0034, 0x0035, 0, + 8, 0x32BB, 0x0034, 0x0036, 0, + 8, 0x32BC, 0x0034, 0x0037, 0, + 8, 0x32BD, 0x0034, 0x0038, 0, + 8, 0x32BE, 0x0034, 0x0039, 0, + 8, 0x32BF, 0x0035, 0x0030, 0, + 16, 0x32C0, 0x0031, 0x6708, 0, + 16, 0x32C1, 0x0032, 0x6708, 0, + 16, 0x32C2, 0x0033, 0x6708, 0, + 16, 0x32C3, 0x0034, 0x6708, 0, + 16, 0x32C4, 0x0035, 0x6708, 0, + 16, 0x32C5, 0x0036, 0x6708, 0, + 16, 0x32C6, 0x0037, 0x6708, 0, + 16, 0x32C7, 0x0038, 0x6708, 0, + 16, 0x32C8, 0x0039, 0x6708, 0, + 16, 0x32C9, 0x0031, 0x0030, 0x6708, 0, + 16, 0x32CA, 0x0031, 0x0031, 0x6708, 0, + 16, 0x32CB, 0x0031, 0x0032, 0x6708, 0, + 8, 0x32D0, 0x30A2, 0, + 8, 0x32D1, 0x30A4, 0, + 8, 0x32D2, 0x30A6, 0, + 8, 0x32D3, 0x30A8, 0, + 8, 0x32D4, 0x30AA, 0, + 8, 0x32D5, 0x30AB, 0, + 8, 0x32D6, 0x30AD, 0, + 8, 0x32D7, 0x30AF, 0, + 8, 0x32D8, 0x30B1, 0, + 8, 0x32D9, 0x30B3, 0, + 8, 0x32DA, 0x30B5, 0, + 8, 0x32DB, 0x30B7, 0, + 8, 0x32DC, 0x30B9, 0, + 8, 0x32DD, 0x30BB, 0, + 8, 0x32DE, 0x30BD, 0, + 8, 0x32DF, 0x30BF, 0, + 8, 0x32E0, 0x30C1, 0, + 8, 0x32E1, 0x30C4, 0, + 8, 0x32E2, 0x30C6, 0, + 8, 0x32E3, 0x30C8, 0, + 8, 0x32E4, 0x30CA, 0, + 8, 0x32E5, 0x30CB, 0, + 8, 0x32E6, 0x30CC, 0, + 8, 0x32E7, 0x30CD, 0, + 8, 0x32E8, 0x30CE, 0, + 8, 0x32E9, 0x30CF, 0, + 8, 0x32EA, 0x30D2, 0, + 8, 0x32EB, 0x30D5, 0, + 8, 0x32EC, 0x30D8, 0, + 8, 0x32ED, 0x30DB, 0, + 8, 0x32EE, 0x30DE, 0, + 8, 0x32EF, 0x30DF, 0, + 8, 0x32F0, 0x30E0, 0, + 8, 0x32F1, 0x30E1, 0, + 8, 0x32F2, 0x30E2, 0, + 8, 0x32F3, 0x30E4, 0, + 8, 0x32F4, 0x30E6, 0, + 8, 0x32F5, 0x30E8, 0, + 8, 0x32F6, 0x30E9, 0, + 8, 0x32F7, 0x30EA, 0, + 8, 0x32F8, 0x30EB, 0, + 8, 0x32F9, 0x30EC, 0, + 8, 0x32FA, 0x30ED, 0, + 8, 0x32FB, 0x30EF, 0, + 8, 0x32FC, 0x30F0, 0, + 8, 0x32FD, 0x30F1, 0, + 8, 0x32FE, 0x30F2, 0, + 15, 0x3300, 0x30A2, 0x30D1, 0x30FC, 0x30C8, 0, + 15, 0x3301, 0x30A2, 0x30EB, 0x30D5, 0x30A1, 0, + 15, 0x3302, 0x30A2, 0x30F3, 0x30DA, 0x30A2, 0, + 15, 0x3303, 0x30A2, 0x30FC, 0x30EB, 0, + 15, 0x3304, 0x30A4, 0x30CB, 0x30F3, 0x30B0, 0, + 15, 0x3305, 0x30A4, 0x30F3, 0x30C1, 0, + 15, 0x3306, 0x30A6, 0x30A9, 0x30F3, 0, + 15, 0x3307, 0x30A8, 0x30B9, 0x30AF, 0x30FC, 0x30C9, 0, + 15, 0x3308, 0x30A8, 0x30FC, 0x30AB, 0x30FC, 0, + 15, 0x3309, 0x30AA, 0x30F3, 0x30B9, 0, + 15, 0x330A, 0x30AA, 0x30FC, 0x30E0, 0, + 15, 0x330B, 0x30AB, 0x30A4, 0x30EA, 0, + 15, 0x330C, 0x30AB, 0x30E9, 0x30C3, 0x30C8, 0, + 15, 0x330D, 0x30AB, 0x30ED, 0x30EA, 0x30FC, 0, + 15, 0x330E, 0x30AC, 0x30ED, 0x30F3, 0, + 15, 0x330F, 0x30AC, 0x30F3, 0x30DE, 0, + 15, 0x3310, 0x30AE, 0x30AC, 0, + 15, 0x3311, 0x30AE, 0x30CB, 0x30FC, 0, + 15, 0x3312, 0x30AD, 0x30E5, 0x30EA, 0x30FC, 0, + 15, 0x3313, 0x30AE, 0x30EB, 0x30C0, 0x30FC, 0, + 15, 0x3314, 0x30AD, 0x30ED, 0, + 15, 0x3315, 0x30AD, 0x30ED, 0x30B0, 0x30E9, 0x30E0, 0, + 15, 0x3316, 0x30AD, 0x30ED, 0x30E1, 0x30FC, 0x30C8, 0x30EB, 0, + 15, 0x3317, 0x30AD, 0x30ED, 0x30EF, 0x30C3, 0x30C8, 0, + 15, 0x3318, 0x30B0, 0x30E9, 0x30E0, 0, + 15, 0x3319, 0x30B0, 0x30E9, 0x30E0, 0x30C8, 0x30F3, 0, + 15, 0x331A, 0x30AF, 0x30EB, 0x30BC, 0x30A4, 0x30ED, 0, + 15, 0x331B, 0x30AF, 0x30ED, 0x30FC, 0x30CD, 0, + 15, 0x331C, 0x30B1, 0x30FC, 0x30B9, 0, + 15, 0x331D, 0x30B3, 0x30EB, 0x30CA, 0, + 15, 0x331E, 0x30B3, 0x30FC, 0x30DD, 0, + 15, 0x331F, 0x30B5, 0x30A4, 0x30AF, 0x30EB, 0, + 15, 0x3320, 0x30B5, 0x30F3, 0x30C1, 0x30FC, 0x30E0, 0, + 15, 0x3321, 0x30B7, 0x30EA, 0x30F3, 0x30B0, 0, + 15, 0x3322, 0x30BB, 0x30F3, 0x30C1, 0, + 15, 0x3323, 0x30BB, 0x30F3, 0x30C8, 0, + 15, 0x3324, 0x30C0, 0x30FC, 0x30B9, 0, + 15, 0x3325, 0x30C7, 0x30B7, 0, + 15, 0x3326, 0x30C9, 0x30EB, 0, + 15, 0x3327, 0x30C8, 0x30F3, 0, + 15, 0x3328, 0x30CA, 0x30CE, 0, + 15, 0x3329, 0x30CE, 0x30C3, 0x30C8, 0, + 15, 0x332A, 0x30CF, 0x30A4, 0x30C4, 0, + 15, 0x332B, 0x30D1, 0x30FC, 0x30BB, 0x30F3, 0x30C8, 0, + 15, 0x332C, 0x30D1, 0x30FC, 0x30C4, 0, + 15, 0x332D, 0x30D0, 0x30FC, 0x30EC, 0x30EB, 0, + 15, 0x332E, 0x30D4, 0x30A2, 0x30B9, 0x30C8, 0x30EB, 0, + 15, 0x332F, 0x30D4, 0x30AF, 0x30EB, 0, + 15, 0x3330, 0x30D4, 0x30B3, 0, + 15, 0x3331, 0x30D3, 0x30EB, 0, + 15, 0x3332, 0x30D5, 0x30A1, 0x30E9, 0x30C3, 0x30C9, 0, + 15, 0x3333, 0x30D5, 0x30A3, 0x30FC, 0x30C8, 0, + 15, 0x3334, 0x30D6, 0x30C3, 0x30B7, 0x30A7, 0x30EB, 0, + 15, 0x3335, 0x30D5, 0x30E9, 0x30F3, 0, + 15, 0x3336, 0x30D8, 0x30AF, 0x30BF, 0x30FC, 0x30EB, 0, + 15, 0x3337, 0x30DA, 0x30BD, 0, + 15, 0x3338, 0x30DA, 0x30CB, 0x30D2, 0, + 15, 0x3339, 0x30D8, 0x30EB, 0x30C4, 0, + 15, 0x333A, 0x30DA, 0x30F3, 0x30B9, 0, + 15, 0x333B, 0x30DA, 0x30FC, 0x30B8, 0, + 15, 0x333C, 0x30D9, 0x30FC, 0x30BF, 0, + 15, 0x333D, 0x30DD, 0x30A4, 0x30F3, 0x30C8, 0, + 15, 0x333E, 0x30DC, 0x30EB, 0x30C8, 0, + 15, 0x333F, 0x30DB, 0x30F3, 0, + 15, 0x3340, 0x30DD, 0x30F3, 0x30C9, 0, + 15, 0x3341, 0x30DB, 0x30FC, 0x30EB, 0, + 15, 0x3342, 0x30DB, 0x30FC, 0x30F3, 0, + 15, 0x3343, 0x30DE, 0x30A4, 0x30AF, 0x30ED, 0, + 15, 0x3344, 0x30DE, 0x30A4, 0x30EB, 0, + 15, 0x3345, 0x30DE, 0x30C3, 0x30CF, 0, + 15, 0x3346, 0x30DE, 0x30EB, 0x30AF, 0, + 15, 0x3347, 0x30DE, 0x30F3, 0x30B7, 0x30E7, 0x30F3, 0, + 15, 0x3348, 0x30DF, 0x30AF, 0x30ED, 0x30F3, 0, + 15, 0x3349, 0x30DF, 0x30EA, 0, + 15, 0x334A, 0x30DF, 0x30EA, 0x30D0, 0x30FC, 0x30EB, 0, + 15, 0x334B, 0x30E1, 0x30AC, 0, + 15, 0x334C, 0x30E1, 0x30AC, 0x30C8, 0x30F3, 0, + 15, 0x334D, 0x30E1, 0x30FC, 0x30C8, 0x30EB, 0, + 15, 0x334E, 0x30E4, 0x30FC, 0x30C9, 0, + 15, 0x334F, 0x30E4, 0x30FC, 0x30EB, 0, + 15, 0x3350, 0x30E6, 0x30A2, 0x30F3, 0, + 15, 0x3351, 0x30EA, 0x30C3, 0x30C8, 0x30EB, 0, + 15, 0x3352, 0x30EA, 0x30E9, 0, + 15, 0x3353, 0x30EB, 0x30D4, 0x30FC, 0, + 15, 0x3354, 0x30EB, 0x30FC, 0x30D6, 0x30EB, 0, + 15, 0x3355, 0x30EC, 0x30E0, 0, + 15, 0x3356, 0x30EC, 0x30F3, 0x30C8, 0x30B2, 0x30F3, 0, + 15, 0x3357, 0x30EF, 0x30C3, 0x30C8, 0, + 16, 0x3358, 0x0030, 0x70B9, 0, + 16, 0x3359, 0x0031, 0x70B9, 0, + 16, 0x335A, 0x0032, 0x70B9, 0, + 16, 0x335B, 0x0033, 0x70B9, 0, + 16, 0x335C, 0x0034, 0x70B9, 0, + 16, 0x335D, 0x0035, 0x70B9, 0, + 16, 0x335E, 0x0036, 0x70B9, 0, + 16, 0x335F, 0x0037, 0x70B9, 0, + 16, 0x3360, 0x0038, 0x70B9, 0, + 16, 0x3361, 0x0039, 0x70B9, 0, + 16, 0x3362, 0x0031, 0x0030, 0x70B9, 0, + 16, 0x3363, 0x0031, 0x0031, 0x70B9, 0, + 16, 0x3364, 0x0031, 0x0032, 0x70B9, 0, + 16, 0x3365, 0x0031, 0x0033, 0x70B9, 0, + 16, 0x3366, 0x0031, 0x0034, 0x70B9, 0, + 16, 0x3367, 0x0031, 0x0035, 0x70B9, 0, + 16, 0x3368, 0x0031, 0x0036, 0x70B9, 0, + 16, 0x3369, 0x0031, 0x0037, 0x70B9, 0, + 16, 0x336A, 0x0031, 0x0038, 0x70B9, 0, + 16, 0x336B, 0x0031, 0x0039, 0x70B9, 0, + 16, 0x336C, 0x0032, 0x0030, 0x70B9, 0, + 16, 0x336D, 0x0032, 0x0031, 0x70B9, 0, + 16, 0x336E, 0x0032, 0x0032, 0x70B9, 0, + 16, 0x336F, 0x0032, 0x0033, 0x70B9, 0, + 16, 0x3370, 0x0032, 0x0034, 0x70B9, 0, + 15, 0x3371, 0x0068, 0x0050, 0x0061, 0, + 15, 0x3372, 0x0064, 0x0061, 0, + 15, 0x3373, 0x0041, 0x0055, 0, + 15, 0x3374, 0x0062, 0x0061, 0x0072, 0, + 15, 0x3375, 0x006F, 0x0056, 0, + 15, 0x3376, 0x0070, 0x0063, 0, + 15, 0x337B, 0x5E73, 0x6210, 0, + 15, 0x337C, 0x662D, 0x548C, 0, + 15, 0x337D, 0x5927, 0x6B63, 0, + 15, 0x337E, 0x660E, 0x6CBB, 0, + 15, 0x337F, 0x682A, 0x5F0F, 0x4F1A, 0x793E, 0, + 15, 0x3380, 0x0070, 0x0041, 0, + 15, 0x3381, 0x006E, 0x0041, 0, + 15, 0x3382, 0x03BC, 0x0041, 0, + 15, 0x3383, 0x006D, 0x0041, 0, + 15, 0x3384, 0x006B, 0x0041, 0, + 15, 0x3385, 0x004B, 0x0042, 0, + 15, 0x3386, 0x004D, 0x0042, 0, + 15, 0x3387, 0x0047, 0x0042, 0, + 15, 0x3388, 0x0063, 0x0061, 0x006C, 0, + 15, 0x3389, 0x006B, 0x0063, 0x0061, 0x006C, 0, + 15, 0x338A, 0x0070, 0x0046, 0, + 15, 0x338B, 0x006E, 0x0046, 0, + 15, 0x338C, 0x03BC, 0x0046, 0, + 15, 0x338D, 0x03BC, 0x0067, 0, + 15, 0x338E, 0x006D, 0x0067, 0, + 15, 0x338F, 0x006B, 0x0067, 0, + 15, 0x3390, 0x0048, 0x007A, 0, + 15, 0x3391, 0x006B, 0x0048, 0x007A, 0, + 15, 0x3392, 0x004D, 0x0048, 0x007A, 0, + 15, 0x3393, 0x0047, 0x0048, 0x007A, 0, + 15, 0x3394, 0x0054, 0x0048, 0x007A, 0, + 15, 0x3395, 0x03BC, 0x2113, 0, + 15, 0x3396, 0x006D, 0x2113, 0, + 15, 0x3397, 0x0064, 0x2113, 0, + 15, 0x3398, 0x006B, 0x2113, 0, + 15, 0x3399, 0x0066, 0x006D, 0, + 15, 0x339A, 0x006E, 0x006D, 0, + 15, 0x339B, 0x03BC, 0x006D, 0, + 15, 0x339C, 0x006D, 0x006D, 0, + 15, 0x339D, 0x0063, 0x006D, 0, + 15, 0x339E, 0x006B, 0x006D, 0, + 15, 0x339F, 0x006D, 0x006D, 0x00B2, 0, + 15, 0x33A0, 0x0063, 0x006D, 0x00B2, 0, + 15, 0x33A1, 0x006D, 0x00B2, 0, + 15, 0x33A2, 0x006B, 0x006D, 0x00B2, 0, + 15, 0x33A3, 0x006D, 0x006D, 0x00B3, 0, + 15, 0x33A4, 0x0063, 0x006D, 0x00B3, 0, + 15, 0x33A5, 0x006D, 0x00B3, 0, + 15, 0x33A6, 0x006B, 0x006D, 0x00B3, 0, + 15, 0x33A7, 0x006D, 0x2215, 0x0073, 0, + 15, 0x33A8, 0x006D, 0x2215, 0x0073, 0x00B2, 0, + 15, 0x33A9, 0x0050, 0x0061, 0, + 15, 0x33AA, 0x006B, 0x0050, 0x0061, 0, + 15, 0x33AB, 0x004D, 0x0050, 0x0061, 0, + 15, 0x33AC, 0x0047, 0x0050, 0x0061, 0, + 15, 0x33AD, 0x0072, 0x0061, 0x0064, 0, + 15, 0x33AE, 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0, + 15, 0x33AF, 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0x00B2, 0, + 15, 0x33B0, 0x0070, 0x0073, 0, + 15, 0x33B1, 0x006E, 0x0073, 0, + 15, 0x33B2, 0x03BC, 0x0073, 0, + 15, 0x33B3, 0x006D, 0x0073, 0, + 15, 0x33B4, 0x0070, 0x0056, 0, + 15, 0x33B5, 0x006E, 0x0056, 0, + 15, 0x33B6, 0x03BC, 0x0056, 0, + 15, 0x33B7, 0x006D, 0x0056, 0, + 15, 0x33B8, 0x006B, 0x0056, 0, + 15, 0x33B9, 0x004D, 0x0056, 0, + 15, 0x33BA, 0x0070, 0x0057, 0, + 15, 0x33BB, 0x006E, 0x0057, 0, + 15, 0x33BC, 0x03BC, 0x0057, 0, + 15, 0x33BD, 0x006D, 0x0057, 0, + 15, 0x33BE, 0x006B, 0x0057, 0, + 15, 0x33BF, 0x004D, 0x0057, 0, + 15, 0x33C0, 0x006B, 0x03A9, 0, + 15, 0x33C1, 0x004D, 0x03A9, 0, + 15, 0x33C2, 0x0061, 0x002E, 0x006D, 0x002E, 0, + 15, 0x33C3, 0x0042, 0x0071, 0, + 15, 0x33C4, 0x0063, 0x0063, 0, + 15, 0x33C5, 0x0063, 0x0064, 0, + 15, 0x33C6, 0x0043, 0x2215, 0x006B, 0x0067, 0, + 15, 0x33C7, 0x0043, 0x006F, 0x002E, 0, + 15, 0x33C8, 0x0064, 0x0042, 0, + 15, 0x33C9, 0x0047, 0x0079, 0, + 15, 0x33CA, 0x0068, 0x0061, 0, + 15, 0x33CB, 0x0048, 0x0050, 0, + 15, 0x33CC, 0x0069, 0x006E, 0, + 15, 0x33CD, 0x004B, 0x004B, 0, + 15, 0x33CE, 0x004B, 0x004D, 0, + 15, 0x33CF, 0x006B, 0x0074, 0, + 15, 0x33D0, 0x006C, 0x006D, 0, + 15, 0x33D1, 0x006C, 0x006E, 0, + 15, 0x33D2, 0x006C, 0x006F, 0x0067, 0, + 15, 0x33D3, 0x006C, 0x0078, 0, + 15, 0x33D4, 0x006D, 0x0062, 0, + 15, 0x33D5, 0x006D, 0x0069, 0x006C, 0, + 15, 0x33D6, 0x006D, 0x006F, 0x006C, 0, + 15, 0x33D7, 0x0050, 0x0048, 0, + 15, 0x33D8, 0x0070, 0x002E, 0x006D, 0x002E, 0, + 15, 0x33D9, 0x0050, 0x0050, 0x004D, 0, + 15, 0x33DA, 0x0050, 0x0052, 0, + 15, 0x33DB, 0x0073, 0x0072, 0, + 15, 0x33DC, 0x0053, 0x0076, 0, + 15, 0x33DD, 0x0057, 0x0062, 0, + 16, 0x33E0, 0x0031, 0x65E5, 0, + 16, 0x33E1, 0x0032, 0x65E5, 0, + 16, 0x33E2, 0x0033, 0x65E5, 0, + 16, 0x33E3, 0x0034, 0x65E5, 0, + 16, 0x33E4, 0x0035, 0x65E5, 0, + 16, 0x33E5, 0x0036, 0x65E5, 0, + 16, 0x33E6, 0x0037, 0x65E5, 0, + 16, 0x33E7, 0x0038, 0x65E5, 0, + 16, 0x33E8, 0x0039, 0x65E5, 0, + 16, 0x33E9, 0x0031, 0x0030, 0x65E5, 0, + 16, 0x33EA, 0x0031, 0x0031, 0x65E5, 0, + 16, 0x33EB, 0x0031, 0x0032, 0x65E5, 0, + 16, 0x33EC, 0x0031, 0x0033, 0x65E5, 0, + 16, 0x33ED, 0x0031, 0x0034, 0x65E5, 0, + 16, 0x33EE, 0x0031, 0x0035, 0x65E5, 0, + 16, 0x33EF, 0x0031, 0x0036, 0x65E5, 0, + 16, 0x33F0, 0x0031, 0x0037, 0x65E5, 0, + 16, 0x33F1, 0x0031, 0x0038, 0x65E5, 0, + 16, 0x33F2, 0x0031, 0x0039, 0x65E5, 0, + 16, 0x33F3, 0x0032, 0x0030, 0x65E5, 0, + 16, 0x33F4, 0x0032, 0x0031, 0x65E5, 0, + 16, 0x33F5, 0x0032, 0x0032, 0x65E5, 0, + 16, 0x33F6, 0x0032, 0x0033, 0x65E5, 0, + 16, 0x33F7, 0x0032, 0x0034, 0x65E5, 0, + 16, 0x33F8, 0x0032, 0x0035, 0x65E5, 0, + 16, 0x33F9, 0x0032, 0x0036, 0x65E5, 0, + 16, 0x33FA, 0x0032, 0x0037, 0x65E5, 0, + 16, 0x33FB, 0x0032, 0x0038, 0x65E5, 0, + 16, 0x33FC, 0x0032, 0x0039, 0x65E5, 0, + 16, 0x33FD, 0x0033, 0x0030, 0x65E5, 0, + 16, 0x33FE, 0x0033, 0x0031, 0x65E5, 0, + 1, 0xF900, 0x8C48, 0, + 1, 0xF901, 0x66F4, 0, + 1, 0xF902, 0x8ECA, 0, + 1, 0xF903, 0x8CC8, 0, + 1, 0xF904, 0x6ED1, 0, + 1, 0xF905, 0x4E32, 0, + 1, 0xF906, 0x53E5, 0, + 1, 0xF907, 0x9F9C, 0, + 1, 0xF908, 0x9F9C, 0, + 1, 0xF909, 0x5951, 0, + 1, 0xF90A, 0x91D1, 0, + 1, 0xF90B, 0x5587, 0, + 1, 0xF90C, 0x5948, 0, + 1, 0xF90D, 0x61F6, 0, + 1, 0xF90E, 0x7669, 0, + 1, 0xF90F, 0x7F85, 0, + 1, 0xF910, 0x863F, 0, + 1, 0xF911, 0x87BA, 0, + 1, 0xF912, 0x88F8, 0, + 1, 0xF913, 0x908F, 0, + 1, 0xF914, 0x6A02, 0, + 1, 0xF915, 0x6D1B, 0, + 1, 0xF916, 0x70D9, 0, + 1, 0xF917, 0x73DE, 0, + 1, 0xF918, 0x843D, 0, + 1, 0xF919, 0x916A, 0, + 1, 0xF91A, 0x99F1, 0, + 1, 0xF91B, 0x4E82, 0, + 1, 0xF91C, 0x5375, 0, + 1, 0xF91D, 0x6B04, 0, + 1, 0xF91E, 0x721B, 0, + 1, 0xF91F, 0x862D, 0, + 1, 0xF920, 0x9E1E, 0, + 1, 0xF921, 0x5D50, 0, + 1, 0xF922, 0x6FEB, 0, + 1, 0xF923, 0x85CD, 0, + 1, 0xF924, 0x8964, 0, + 1, 0xF925, 0x62C9, 0, + 1, 0xF926, 0x81D8, 0, + 1, 0xF927, 0x881F, 0, + 1, 0xF928, 0x5ECA, 0, + 1, 0xF929, 0x6717, 0, + 1, 0xF92A, 0x6D6A, 0, + 1, 0xF92B, 0x72FC, 0, + 1, 0xF92C, 0x90CE, 0, + 1, 0xF92D, 0x4F86, 0, + 1, 0xF92E, 0x51B7, 0, + 1, 0xF92F, 0x52DE, 0, + 1, 0xF930, 0x64C4, 0, + 1, 0xF931, 0x6AD3, 0, + 1, 0xF932, 0x7210, 0, + 1, 0xF933, 0x76E7, 0, + 1, 0xF934, 0x8001, 0, + 1, 0xF935, 0x8606, 0, + 1, 0xF936, 0x865C, 0, + 1, 0xF937, 0x8DEF, 0, + 1, 0xF938, 0x9732, 0, + 1, 0xF939, 0x9B6F, 0, + 1, 0xF93A, 0x9DFA, 0, + 1, 0xF93B, 0x788C, 0, + 1, 0xF93C, 0x797F, 0, + 1, 0xF93D, 0x7DA0, 0, + 1, 0xF93E, 0x83C9, 0, + 1, 0xF93F, 0x9304, 0, + 1, 0xF940, 0x9E7F, 0, + 1, 0xF941, 0x8AD6, 0, + 1, 0xF942, 0x58DF, 0, + 1, 0xF943, 0x5F04, 0, + 1, 0xF944, 0x7C60, 0, + 1, 0xF945, 0x807E, 0, + 1, 0xF946, 0x7262, 0, + 1, 0xF947, 0x78CA, 0, + 1, 0xF948, 0x8CC2, 0, + 1, 0xF949, 0x96F7, 0, + 1, 0xF94A, 0x58D8, 0, + 1, 0xF94B, 0x5C62, 0, + 1, 0xF94C, 0x6A13, 0, + 1, 0xF94D, 0x6DDA, 0, + 1, 0xF94E, 0x6F0F, 0, + 1, 0xF94F, 0x7D2F, 0, + 1, 0xF950, 0x7E37, 0, + 1, 0xF951, 0x964B, 0, + 1, 0xF952, 0x52D2, 0, + 1, 0xF953, 0x808B, 0, + 1, 0xF954, 0x51DC, 0, + 1, 0xF955, 0x51CC, 0, + 1, 0xF956, 0x7A1C, 0, + 1, 0xF957, 0x7DBE, 0, + 1, 0xF958, 0x83F1, 0, + 1, 0xF959, 0x9675, 0, + 1, 0xF95A, 0x8B80, 0, + 1, 0xF95B, 0x62CF, 0, + 1, 0xF95C, 0x6A02, 0, + 1, 0xF95D, 0x8AFE, 0, + 1, 0xF95E, 0x4E39, 0, + 1, 0xF95F, 0x5BE7, 0, + 1, 0xF960, 0x6012, 0, + 1, 0xF961, 0x7387, 0, + 1, 0xF962, 0x7570, 0, + 1, 0xF963, 0x5317, 0, + 1, 0xF964, 0x78FB, 0, + 1, 0xF965, 0x4FBF, 0, + 1, 0xF966, 0x5FA9, 0, + 1, 0xF967, 0x4E0D, 0, + 1, 0xF968, 0x6CCC, 0, + 1, 0xF969, 0x6578, 0, + 1, 0xF96A, 0x7D22, 0, + 1, 0xF96B, 0x53C3, 0, + 1, 0xF96C, 0x585E, 0, + 1, 0xF96D, 0x7701, 0, + 1, 0xF96E, 0x8449, 0, + 1, 0xF96F, 0x8AAA, 0, + 1, 0xF970, 0x6BBA, 0, + 1, 0xF971, 0x8FB0, 0, + 1, 0xF972, 0x6C88, 0, + 1, 0xF973, 0x62FE, 0, + 1, 0xF974, 0x82E5, 0, + 1, 0xF975, 0x63A0, 0, + 1, 0xF976, 0x7565, 0, + 1, 0xF977, 0x4EAE, 0, + 1, 0xF978, 0x5169, 0, + 1, 0xF979, 0x51C9, 0, + 1, 0xF97A, 0x6881, 0, + 1, 0xF97B, 0x7CE7, 0, + 1, 0xF97C, 0x826F, 0, + 1, 0xF97D, 0x8AD2, 0, + 1, 0xF97E, 0x91CF, 0, + 1, 0xF97F, 0x52F5, 0, + 1, 0xF980, 0x5442, 0, + 1, 0xF981, 0x5973, 0, + 1, 0xF982, 0x5EEC, 0, + 1, 0xF983, 0x65C5, 0, + 1, 0xF984, 0x6FFE, 0, + 1, 0xF985, 0x792A, 0, + 1, 0xF986, 0x95AD, 0, + 1, 0xF987, 0x9A6A, 0, + 1, 0xF988, 0x9E97, 0, + 1, 0xF989, 0x9ECE, 0, + 1, 0xF98A, 0x529B, 0, + 1, 0xF98B, 0x66C6, 0, + 1, 0xF98C, 0x6B77, 0, + 1, 0xF98D, 0x8F62, 0, + 1, 0xF98E, 0x5E74, 0, + 1, 0xF98F, 0x6190, 0, + 1, 0xF990, 0x6200, 0, + 1, 0xF991, 0x649A, 0, + 1, 0xF992, 0x6F23, 0, + 1, 0xF993, 0x7149, 0, + 1, 0xF994, 0x7489, 0, + 1, 0xF995, 0x79CA, 0, + 1, 0xF996, 0x7DF4, 0, + 1, 0xF997, 0x806F, 0, + 1, 0xF998, 0x8F26, 0, + 1, 0xF999, 0x84EE, 0, + 1, 0xF99A, 0x9023, 0, + 1, 0xF99B, 0x934A, 0, + 1, 0xF99C, 0x5217, 0, + 1, 0xF99D, 0x52A3, 0, + 1, 0xF99E, 0x54BD, 0, + 1, 0xF99F, 0x70C8, 0, + 1, 0xF9A0, 0x88C2, 0, + 1, 0xF9A1, 0x8AAA, 0, + 1, 0xF9A2, 0x5EC9, 0, + 1, 0xF9A3, 0x5FF5, 0, + 1, 0xF9A4, 0x637B, 0, + 1, 0xF9A5, 0x6BAE, 0, + 1, 0xF9A6, 0x7C3E, 0, + 1, 0xF9A7, 0x7375, 0, + 1, 0xF9A8, 0x4EE4, 0, + 1, 0xF9A9, 0x56F9, 0, + 1, 0xF9AA, 0x5BE7, 0, + 1, 0xF9AB, 0x5DBA, 0, + 1, 0xF9AC, 0x601C, 0, + 1, 0xF9AD, 0x73B2, 0, + 1, 0xF9AE, 0x7469, 0, + 1, 0xF9AF, 0x7F9A, 0, + 1, 0xF9B0, 0x8046, 0, + 1, 0xF9B1, 0x9234, 0, + 1, 0xF9B2, 0x96F6, 0, + 1, 0xF9B3, 0x9748, 0, + 1, 0xF9B4, 0x9818, 0, + 1, 0xF9B5, 0x4F8B, 0, + 1, 0xF9B6, 0x79AE, 0, + 1, 0xF9B7, 0x91B4, 0, + 1, 0xF9B8, 0x96B8, 0, + 1, 0xF9B9, 0x60E1, 0, + 1, 0xF9BA, 0x4E86, 0, + 1, 0xF9BB, 0x50DA, 0, + 1, 0xF9BC, 0x5BEE, 0, + 1, 0xF9BD, 0x5C3F, 0, + 1, 0xF9BE, 0x6599, 0, + 1, 0xF9BF, 0x6A02, 0, + 1, 0xF9C0, 0x71CE, 0, + 1, 0xF9C1, 0x7642, 0, + 1, 0xF9C2, 0x84FC, 0, + 1, 0xF9C3, 0x907C, 0, + 1, 0xF9C4, 0x9F8D, 0, + 1, 0xF9C5, 0x6688, 0, + 1, 0xF9C6, 0x962E, 0, + 1, 0xF9C7, 0x5289, 0, + 1, 0xF9C8, 0x677B, 0, + 1, 0xF9C9, 0x67F3, 0, + 1, 0xF9CA, 0x6D41, 0, + 1, 0xF9CB, 0x6E9C, 0, + 1, 0xF9CC, 0x7409, 0, + 1, 0xF9CD, 0x7559, 0, + 1, 0xF9CE, 0x786B, 0, + 1, 0xF9CF, 0x7D10, 0, + 1, 0xF9D0, 0x985E, 0, + 1, 0xF9D1, 0x516D, 0, + 1, 0xF9D2, 0x622E, 0, + 1, 0xF9D3, 0x9678, 0, + 1, 0xF9D4, 0x502B, 0, + 1, 0xF9D5, 0x5D19, 0, + 1, 0xF9D6, 0x6DEA, 0, + 1, 0xF9D7, 0x8F2A, 0, + 1, 0xF9D8, 0x5F8B, 0, + 1, 0xF9D9, 0x6144, 0, + 1, 0xF9DA, 0x6817, 0, + 1, 0xF9DB, 0x7387, 0, + 1, 0xF9DC, 0x9686, 0, + 1, 0xF9DD, 0x5229, 0, + 1, 0xF9DE, 0x540F, 0, + 1, 0xF9DF, 0x5C65, 0, + 1, 0xF9E0, 0x6613, 0, + 1, 0xF9E1, 0x674E, 0, + 1, 0xF9E2, 0x68A8, 0, + 1, 0xF9E3, 0x6CE5, 0, + 1, 0xF9E4, 0x7406, 0, + 1, 0xF9E5, 0x75E2, 0, + 1, 0xF9E6, 0x7F79, 0, + 1, 0xF9E7, 0x88CF, 0, + 1, 0xF9E8, 0x88E1, 0, + 1, 0xF9E9, 0x91CC, 0, + 1, 0xF9EA, 0x96E2, 0, + 1, 0xF9EB, 0x533F, 0, + 1, 0xF9EC, 0x6EBA, 0, + 1, 0xF9ED, 0x541D, 0, + 1, 0xF9EE, 0x71D0, 0, + 1, 0xF9EF, 0x7498, 0, + 1, 0xF9F0, 0x85FA, 0, + 1, 0xF9F1, 0x96A3, 0, + 1, 0xF9F2, 0x9C57, 0, + 1, 0xF9F3, 0x9E9F, 0, + 1, 0xF9F4, 0x6797, 0, + 1, 0xF9F5, 0x6DCB, 0, + 1, 0xF9F6, 0x81E8, 0, + 1, 0xF9F7, 0x7ACB, 0, + 1, 0xF9F8, 0x7B20, 0, + 1, 0xF9F9, 0x7C92, 0, + 1, 0xF9FA, 0x72C0, 0, + 1, 0xF9FB, 0x7099, 0, + 1, 0xF9FC, 0x8B58, 0, + 1, 0xF9FD, 0x4EC0, 0, + 1, 0xF9FE, 0x8336, 0, + 1, 0xF9FF, 0x523A, 0, + 1, 0xFA00, 0x5207, 0, + 1, 0xFA01, 0x5EA6, 0, + 1, 0xFA02, 0x62D3, 0, + 1, 0xFA03, 0x7CD6, 0, + 1, 0xFA04, 0x5B85, 0, + 1, 0xFA05, 0x6D1E, 0, + 1, 0xFA06, 0x66B4, 0, + 1, 0xFA07, 0x8F3B, 0, + 1, 0xFA08, 0x884C, 0, + 1, 0xFA09, 0x964D, 0, + 1, 0xFA0A, 0x898B, 0, + 1, 0xFA0B, 0x5ED3, 0, + 1, 0xFA0C, 0x5140, 0, + 1, 0xFA0D, 0x55C0, 0, + 1, 0xFA10, 0x585A, 0, + 1, 0xFA12, 0x6674, 0, + 1, 0xFA15, 0x51DE, 0, + 1, 0xFA16, 0x732A, 0, + 1, 0xFA17, 0x76CA, 0, + 1, 0xFA18, 0x793C, 0, + 1, 0xFA19, 0x795E, 0, + 1, 0xFA1A, 0x7965, 0, + 1, 0xFA1B, 0x798F, 0, + 1, 0xFA1C, 0x9756, 0, + 1, 0xFA1D, 0x7CBE, 0, + 1, 0xFA1E, 0x7FBD, 0, + 1, 0xFA20, 0x8612, 0, + 1, 0xFA22, 0x8AF8, 0, + 1, 0xFA25, 0x9038, 0, + 1, 0xFA26, 0x90FD, 0, + 1, 0xFA2A, 0x98EF, 0, + 1, 0xFA2B, 0x98FC, 0, + 1, 0xFA2C, 0x9928, 0, + 1, 0xFA2D, 0x9DB4, 0, + 1, 0xFA30, 0x4FAE, 0, + 1, 0xFA31, 0x50E7, 0, + 1, 0xFA32, 0x514D, 0, + 1, 0xFA33, 0x52C9, 0, + 1, 0xFA34, 0x52E4, 0, + 1, 0xFA35, 0x5351, 0, + 1, 0xFA36, 0x559D, 0, + 1, 0xFA37, 0x5606, 0, + 1, 0xFA38, 0x5668, 0, + 1, 0xFA39, 0x5840, 0, + 1, 0xFA3A, 0x58A8, 0, + 1, 0xFA3B, 0x5C64, 0, + 1, 0xFA3C, 0x5C6E, 0, + 1, 0xFA3D, 0x6094, 0, + 1, 0xFA3E, 0x6168, 0, + 1, 0xFA3F, 0x618E, 0, + 1, 0xFA40, 0x61F2, 0, + 1, 0xFA41, 0x654F, 0, + 1, 0xFA42, 0x65E2, 0, + 1, 0xFA43, 0x6691, 0, + 1, 0xFA44, 0x6885, 0, + 1, 0xFA45, 0x6D77, 0, + 1, 0xFA46, 0x6E1A, 0, + 1, 0xFA47, 0x6F22, 0, + 1, 0xFA48, 0x716E, 0, + 1, 0xFA49, 0x722B, 0, + 1, 0xFA4A, 0x7422, 0, + 1, 0xFA4B, 0x7891, 0, + 1, 0xFA4C, 0x793E, 0, + 1, 0xFA4D, 0x7949, 0, + 1, 0xFA4E, 0x7948, 0, + 1, 0xFA4F, 0x7950, 0, + 1, 0xFA50, 0x7956, 0, + 1, 0xFA51, 0x795D, 0, + 1, 0xFA52, 0x798D, 0, + 1, 0xFA53, 0x798E, 0, + 1, 0xFA54, 0x7A40, 0, + 1, 0xFA55, 0x7A81, 0, + 1, 0xFA56, 0x7BC0, 0, + 1, 0xFA57, 0x7DF4, 0, + 1, 0xFA58, 0x7E09, 0, + 1, 0xFA59, 0x7E41, 0, + 1, 0xFA5A, 0x7F72, 0, + 1, 0xFA5B, 0x8005, 0, + 1, 0xFA5C, 0x81ED, 0, + 1, 0xFA5D, 0x8279, 0, + 1, 0xFA5E, 0x8279, 0, + 1, 0xFA5F, 0x8457, 0, + 1, 0xFA60, 0x8910, 0, + 1, 0xFA61, 0x8996, 0, + 1, 0xFA62, 0x8B01, 0, + 1, 0xFA63, 0x8B39, 0, + 1, 0xFA64, 0x8CD3, 0, + 1, 0xFA65, 0x8D08, 0, + 1, 0xFA66, 0x8FB6, 0, + 1, 0xFA67, 0x9038, 0, + 1, 0xFA68, 0x96E3, 0, + 1, 0xFA69, 0x97FF, 0, + 1, 0xFA6A, 0x983B, 0, + 16, 0xFB00, 0x0066, 0x0066, 0, + 16, 0xFB01, 0x0066, 0x0069, 0, + 16, 0xFB02, 0x0066, 0x006C, 0, + 16, 0xFB03, 0x0066, 0x0066, 0x0069, 0, + 16, 0xFB04, 0x0066, 0x0066, 0x006C, 0, + 16, 0xFB05, 0x017F, 0x0074, 0, + 16, 0xFB06, 0x0073, 0x0074, 0, + 16, 0xFB13, 0x0574, 0x0576, 0, + 16, 0xFB14, 0x0574, 0x0565, 0, + 16, 0xFB15, 0x0574, 0x056B, 0, + 16, 0xFB16, 0x057E, 0x0576, 0, + 16, 0xFB17, 0x0574, 0x056D, 0, + 1, 0xFB1D, 0x05D9, 0x05B4, 0, + 1, 0xFB1F, 0x05F2, 0x05B7, 0, + 2, 0xFB20, 0x05E2, 0, + 2, 0xFB21, 0x05D0, 0, + 2, 0xFB22, 0x05D3, 0, + 2, 0xFB23, 0x05D4, 0, + 2, 0xFB24, 0x05DB, 0, + 2, 0xFB25, 0x05DC, 0, + 2, 0xFB26, 0x05DD, 0, + 2, 0xFB27, 0x05E8, 0, + 2, 0xFB28, 0x05EA, 0, + 2, 0xFB29, 0x002B, 0, + 1, 0xFB2A, 0x05E9, 0x05C1, 0, + 1, 0xFB2B, 0x05E9, 0x05C2, 0, + 1, 0xFB2C, 0xFB49, 0x05C1, 0, + 1, 0xFB2D, 0xFB49, 0x05C2, 0, + 1, 0xFB2E, 0x05D0, 0x05B7, 0, + 1, 0xFB2F, 0x05D0, 0x05B8, 0, + 1, 0xFB30, 0x05D0, 0x05BC, 0, + 1, 0xFB31, 0x05D1, 0x05BC, 0, + 1, 0xFB32, 0x05D2, 0x05BC, 0, + 1, 0xFB33, 0x05D3, 0x05BC, 0, + 1, 0xFB34, 0x05D4, 0x05BC, 0, + 1, 0xFB35, 0x05D5, 0x05BC, 0, + 1, 0xFB36, 0x05D6, 0x05BC, 0, + 1, 0xFB38, 0x05D8, 0x05BC, 0, + 1, 0xFB39, 0x05D9, 0x05BC, 0, + 1, 0xFB3A, 0x05DA, 0x05BC, 0, + 1, 0xFB3B, 0x05DB, 0x05BC, 0, + 1, 0xFB3C, 0x05DC, 0x05BC, 0, + 1, 0xFB3E, 0x05DE, 0x05BC, 0, + 1, 0xFB40, 0x05E0, 0x05BC, 0, + 1, 0xFB41, 0x05E1, 0x05BC, 0, + 1, 0xFB43, 0x05E3, 0x05BC, 0, + 1, 0xFB44, 0x05E4, 0x05BC, 0, + 1, 0xFB46, 0x05E6, 0x05BC, 0, + 1, 0xFB47, 0x05E7, 0x05BC, 0, + 1, 0xFB48, 0x05E8, 0x05BC, 0, + 1, 0xFB49, 0x05E9, 0x05BC, 0, + 1, 0xFB4A, 0x05EA, 0x05BC, 0, + 1, 0xFB4B, 0x05D5, 0x05B9, 0, + 1, 0xFB4C, 0x05D1, 0x05BF, 0, + 1, 0xFB4D, 0x05DB, 0x05BF, 0, + 1, 0xFB4E, 0x05E4, 0x05BF, 0, + 16, 0xFB4F, 0x05D0, 0x05DC, 0, + 7, 0xFB50, 0x0671, 0, + 6, 0xFB51, 0x0671, 0, + 7, 0xFB52, 0x067B, 0, + 6, 0xFB53, 0x067B, 0, + 4, 0xFB54, 0x067B, 0, + 5, 0xFB55, 0x067B, 0, + 7, 0xFB56, 0x067E, 0, + 6, 0xFB57, 0x067E, 0, + 4, 0xFB58, 0x067E, 0, + 5, 0xFB59, 0x067E, 0, + 7, 0xFB5A, 0x0680, 0, + 6, 0xFB5B, 0x0680, 0, + 4, 0xFB5C, 0x0680, 0, + 5, 0xFB5D, 0x0680, 0, + 7, 0xFB5E, 0x067A, 0, + 6, 0xFB5F, 0x067A, 0, + 4, 0xFB60, 0x067A, 0, + 5, 0xFB61, 0x067A, 0, + 7, 0xFB62, 0x067F, 0, + 6, 0xFB63, 0x067F, 0, + 4, 0xFB64, 0x067F, 0, + 5, 0xFB65, 0x067F, 0, + 7, 0xFB66, 0x0679, 0, + 6, 0xFB67, 0x0679, 0, + 4, 0xFB68, 0x0679, 0, + 5, 0xFB69, 0x0679, 0, + 7, 0xFB6A, 0x06A4, 0, + 6, 0xFB6B, 0x06A4, 0, + 4, 0xFB6C, 0x06A4, 0, + 5, 0xFB6D, 0x06A4, 0, + 7, 0xFB6E, 0x06A6, 0, + 6, 0xFB6F, 0x06A6, 0, + 4, 0xFB70, 0x06A6, 0, + 5, 0xFB71, 0x06A6, 0, + 7, 0xFB72, 0x0684, 0, + 6, 0xFB73, 0x0684, 0, + 4, 0xFB74, 0x0684, 0, + 5, 0xFB75, 0x0684, 0, + 7, 0xFB76, 0x0683, 0, + 6, 0xFB77, 0x0683, 0, + 4, 0xFB78, 0x0683, 0, + 5, 0xFB79, 0x0683, 0, + 7, 0xFB7A, 0x0686, 0, + 6, 0xFB7B, 0x0686, 0, + 4, 0xFB7C, 0x0686, 0, + 5, 0xFB7D, 0x0686, 0, + 7, 0xFB7E, 0x0687, 0, + 6, 0xFB7F, 0x0687, 0, + 4, 0xFB80, 0x0687, 0, + 5, 0xFB81, 0x0687, 0, + 7, 0xFB82, 0x068D, 0, + 6, 0xFB83, 0x068D, 0, + 7, 0xFB84, 0x068C, 0, + 6, 0xFB85, 0x068C, 0, + 7, 0xFB86, 0x068E, 0, + 6, 0xFB87, 0x068E, 0, + 7, 0xFB88, 0x0688, 0, + 6, 0xFB89, 0x0688, 0, + 7, 0xFB8A, 0x0698, 0, + 6, 0xFB8B, 0x0698, 0, + 7, 0xFB8C, 0x0691, 0, + 6, 0xFB8D, 0x0691, 0, + 7, 0xFB8E, 0x06A9, 0, + 6, 0xFB8F, 0x06A9, 0, + 4, 0xFB90, 0x06A9, 0, + 5, 0xFB91, 0x06A9, 0, + 7, 0xFB92, 0x06AF, 0, + 6, 0xFB93, 0x06AF, 0, + 4, 0xFB94, 0x06AF, 0, + 5, 0xFB95, 0x06AF, 0, + 7, 0xFB96, 0x06B3, 0, + 6, 0xFB97, 0x06B3, 0, + 4, 0xFB98, 0x06B3, 0, + 5, 0xFB99, 0x06B3, 0, + 7, 0xFB9A, 0x06B1, 0, + 6, 0xFB9B, 0x06B1, 0, + 4, 0xFB9C, 0x06B1, 0, + 5, 0xFB9D, 0x06B1, 0, + 7, 0xFB9E, 0x06BA, 0, + 6, 0xFB9F, 0x06BA, 0, + 7, 0xFBA0, 0x06BB, 0, + 6, 0xFBA1, 0x06BB, 0, + 4, 0xFBA2, 0x06BB, 0, + 5, 0xFBA3, 0x06BB, 0, + 7, 0xFBA4, 0x06C0, 0, + 6, 0xFBA5, 0x06C0, 0, + 7, 0xFBA6, 0x06C1, 0, + 6, 0xFBA7, 0x06C1, 0, + 4, 0xFBA8, 0x06C1, 0, + 5, 0xFBA9, 0x06C1, 0, + 7, 0xFBAA, 0x06BE, 0, + 6, 0xFBAB, 0x06BE, 0, + 4, 0xFBAC, 0x06BE, 0, + 5, 0xFBAD, 0x06BE, 0, + 7, 0xFBAE, 0x06D2, 0, + 6, 0xFBAF, 0x06D2, 0, + 7, 0xFBB0, 0x06D3, 0, + 6, 0xFBB1, 0x06D3, 0, + 7, 0xFBD3, 0x06AD, 0, + 6, 0xFBD4, 0x06AD, 0, + 4, 0xFBD5, 0x06AD, 0, + 5, 0xFBD6, 0x06AD, 0, + 7, 0xFBD7, 0x06C7, 0, + 6, 0xFBD8, 0x06C7, 0, + 7, 0xFBD9, 0x06C6, 0, + 6, 0xFBDA, 0x06C6, 0, + 7, 0xFBDB, 0x06C8, 0, + 6, 0xFBDC, 0x06C8, 0, + 7, 0xFBDD, 0x0677, 0, + 7, 0xFBDE, 0x06CB, 0, + 6, 0xFBDF, 0x06CB, 0, + 7, 0xFBE0, 0x06C5, 0, + 6, 0xFBE1, 0x06C5, 0, + 7, 0xFBE2, 0x06C9, 0, + 6, 0xFBE3, 0x06C9, 0, + 7, 0xFBE4, 0x06D0, 0, + 6, 0xFBE5, 0x06D0, 0, + 4, 0xFBE6, 0x06D0, 0, + 5, 0xFBE7, 0x06D0, 0, + 4, 0xFBE8, 0x0649, 0, + 5, 0xFBE9, 0x0649, 0, + 7, 0xFBEA, 0x0626, 0x0627, 0, + 6, 0xFBEB, 0x0626, 0x0627, 0, + 7, 0xFBEC, 0x0626, 0x06D5, 0, + 6, 0xFBED, 0x0626, 0x06D5, 0, + 7, 0xFBEE, 0x0626, 0x0648, 0, + 6, 0xFBEF, 0x0626, 0x0648, 0, + 7, 0xFBF0, 0x0626, 0x06C7, 0, + 6, 0xFBF1, 0x0626, 0x06C7, 0, + 7, 0xFBF2, 0x0626, 0x06C6, 0, + 6, 0xFBF3, 0x0626, 0x06C6, 0, + 7, 0xFBF4, 0x0626, 0x06C8, 0, + 6, 0xFBF5, 0x0626, 0x06C8, 0, + 7, 0xFBF6, 0x0626, 0x06D0, 0, + 6, 0xFBF7, 0x0626, 0x06D0, 0, + 4, 0xFBF8, 0x0626, 0x06D0, 0, + 7, 0xFBF9, 0x0626, 0x0649, 0, + 6, 0xFBFA, 0x0626, 0x0649, 0, + 4, 0xFBFB, 0x0626, 0x0649, 0, + 7, 0xFBFC, 0x06CC, 0, + 6, 0xFBFD, 0x06CC, 0, + 4, 0xFBFE, 0x06CC, 0, + 5, 0xFBFF, 0x06CC, 0, + 7, 0xFC00, 0x0626, 0x062C, 0, + 7, 0xFC01, 0x0626, 0x062D, 0, + 7, 0xFC02, 0x0626, 0x0645, 0, + 7, 0xFC03, 0x0626, 0x0649, 0, + 7, 0xFC04, 0x0626, 0x064A, 0, + 7, 0xFC05, 0x0628, 0x062C, 0, + 7, 0xFC06, 0x0628, 0x062D, 0, + 7, 0xFC07, 0x0628, 0x062E, 0, + 7, 0xFC08, 0x0628, 0x0645, 0, + 7, 0xFC09, 0x0628, 0x0649, 0, + 7, 0xFC0A, 0x0628, 0x064A, 0, + 7, 0xFC0B, 0x062A, 0x062C, 0, + 7, 0xFC0C, 0x062A, 0x062D, 0, + 7, 0xFC0D, 0x062A, 0x062E, 0, + 7, 0xFC0E, 0x062A, 0x0645, 0, + 7, 0xFC0F, 0x062A, 0x0649, 0, + 7, 0xFC10, 0x062A, 0x064A, 0, + 7, 0xFC11, 0x062B, 0x062C, 0, + 7, 0xFC12, 0x062B, 0x0645, 0, + 7, 0xFC13, 0x062B, 0x0649, 0, + 7, 0xFC14, 0x062B, 0x064A, 0, + 7, 0xFC15, 0x062C, 0x062D, 0, + 7, 0xFC16, 0x062C, 0x0645, 0, + 7, 0xFC17, 0x062D, 0x062C, 0, + 7, 0xFC18, 0x062D, 0x0645, 0, + 7, 0xFC19, 0x062E, 0x062C, 0, + 7, 0xFC1A, 0x062E, 0x062D, 0, + 7, 0xFC1B, 0x062E, 0x0645, 0, + 7, 0xFC1C, 0x0633, 0x062C, 0, + 7, 0xFC1D, 0x0633, 0x062D, 0, + 7, 0xFC1E, 0x0633, 0x062E, 0, + 7, 0xFC1F, 0x0633, 0x0645, 0, + 7, 0xFC20, 0x0635, 0x062D, 0, + 7, 0xFC21, 0x0635, 0x0645, 0, + 7, 0xFC22, 0x0636, 0x062C, 0, + 7, 0xFC23, 0x0636, 0x062D, 0, + 7, 0xFC24, 0x0636, 0x062E, 0, + 7, 0xFC25, 0x0636, 0x0645, 0, + 7, 0xFC26, 0x0637, 0x062D, 0, + 7, 0xFC27, 0x0637, 0x0645, 0, + 7, 0xFC28, 0x0638, 0x0645, 0, + 7, 0xFC29, 0x0639, 0x062C, 0, + 7, 0xFC2A, 0x0639, 0x0645, 0, + 7, 0xFC2B, 0x063A, 0x062C, 0, + 7, 0xFC2C, 0x063A, 0x0645, 0, + 7, 0xFC2D, 0x0641, 0x062C, 0, + 7, 0xFC2E, 0x0641, 0x062D, 0, + 7, 0xFC2F, 0x0641, 0x062E, 0, + 7, 0xFC30, 0x0641, 0x0645, 0, + 7, 0xFC31, 0x0641, 0x0649, 0, + 7, 0xFC32, 0x0641, 0x064A, 0, + 7, 0xFC33, 0x0642, 0x062D, 0, + 7, 0xFC34, 0x0642, 0x0645, 0, + 7, 0xFC35, 0x0642, 0x0649, 0, + 7, 0xFC36, 0x0642, 0x064A, 0, + 7, 0xFC37, 0x0643, 0x0627, 0, + 7, 0xFC38, 0x0643, 0x062C, 0, + 7, 0xFC39, 0x0643, 0x062D, 0, + 7, 0xFC3A, 0x0643, 0x062E, 0, + 7, 0xFC3B, 0x0643, 0x0644, 0, + 7, 0xFC3C, 0x0643, 0x0645, 0, + 7, 0xFC3D, 0x0643, 0x0649, 0, + 7, 0xFC3E, 0x0643, 0x064A, 0, + 7, 0xFC3F, 0x0644, 0x062C, 0, + 7, 0xFC40, 0x0644, 0x062D, 0, + 7, 0xFC41, 0x0644, 0x062E, 0, + 7, 0xFC42, 0x0644, 0x0645, 0, + 7, 0xFC43, 0x0644, 0x0649, 0, + 7, 0xFC44, 0x0644, 0x064A, 0, + 7, 0xFC45, 0x0645, 0x062C, 0, + 7, 0xFC46, 0x0645, 0x062D, 0, + 7, 0xFC47, 0x0645, 0x062E, 0, + 7, 0xFC48, 0x0645, 0x0645, 0, + 7, 0xFC49, 0x0645, 0x0649, 0, + 7, 0xFC4A, 0x0645, 0x064A, 0, + 7, 0xFC4B, 0x0646, 0x062C, 0, + 7, 0xFC4C, 0x0646, 0x062D, 0, + 7, 0xFC4D, 0x0646, 0x062E, 0, + 7, 0xFC4E, 0x0646, 0x0645, 0, + 7, 0xFC4F, 0x0646, 0x0649, 0, + 7, 0xFC50, 0x0646, 0x064A, 0, + 7, 0xFC51, 0x0647, 0x062C, 0, + 7, 0xFC52, 0x0647, 0x0645, 0, + 7, 0xFC53, 0x0647, 0x0649, 0, + 7, 0xFC54, 0x0647, 0x064A, 0, + 7, 0xFC55, 0x064A, 0x062C, 0, + 7, 0xFC56, 0x064A, 0x062D, 0, + 7, 0xFC57, 0x064A, 0x062E, 0, + 7, 0xFC58, 0x064A, 0x0645, 0, + 7, 0xFC59, 0x064A, 0x0649, 0, + 7, 0xFC5A, 0x064A, 0x064A, 0, + 7, 0xFC5B, 0x0630, 0x0670, 0, + 7, 0xFC5C, 0x0631, 0x0670, 0, + 7, 0xFC5D, 0x0649, 0x0670, 0, + 7, 0xFC5E, 0x0020, 0x064C, 0x0651, 0, + 7, 0xFC5F, 0x0020, 0x064D, 0x0651, 0, + 7, 0xFC60, 0x0020, 0x064E, 0x0651, 0, + 7, 0xFC61, 0x0020, 0x064F, 0x0651, 0, + 7, 0xFC62, 0x0020, 0x0650, 0x0651, 0, + 7, 0xFC63, 0x0020, 0x0651, 0x0670, 0, + 6, 0xFC64, 0x0626, 0x0631, 0, + 6, 0xFC65, 0x0626, 0x0632, 0, + 6, 0xFC66, 0x0626, 0x0645, 0, + 6, 0xFC67, 0x0626, 0x0646, 0, + 6, 0xFC68, 0x0626, 0x0649, 0, + 6, 0xFC69, 0x0626, 0x064A, 0, + 6, 0xFC6A, 0x0628, 0x0631, 0, + 6, 0xFC6B, 0x0628, 0x0632, 0, + 6, 0xFC6C, 0x0628, 0x0645, 0, + 6, 0xFC6D, 0x0628, 0x0646, 0, + 6, 0xFC6E, 0x0628, 0x0649, 0, + 6, 0xFC6F, 0x0628, 0x064A, 0, + 6, 0xFC70, 0x062A, 0x0631, 0, + 6, 0xFC71, 0x062A, 0x0632, 0, + 6, 0xFC72, 0x062A, 0x0645, 0, + 6, 0xFC73, 0x062A, 0x0646, 0, + 6, 0xFC74, 0x062A, 0x0649, 0, + 6, 0xFC75, 0x062A, 0x064A, 0, + 6, 0xFC76, 0x062B, 0x0631, 0, + 6, 0xFC77, 0x062B, 0x0632, 0, + 6, 0xFC78, 0x062B, 0x0645, 0, + 6, 0xFC79, 0x062B, 0x0646, 0, + 6, 0xFC7A, 0x062B, 0x0649, 0, + 6, 0xFC7B, 0x062B, 0x064A, 0, + 6, 0xFC7C, 0x0641, 0x0649, 0, + 6, 0xFC7D, 0x0641, 0x064A, 0, + 6, 0xFC7E, 0x0642, 0x0649, 0, + 6, 0xFC7F, 0x0642, 0x064A, 0, + 6, 0xFC80, 0x0643, 0x0627, 0, + 6, 0xFC81, 0x0643, 0x0644, 0, + 6, 0xFC82, 0x0643, 0x0645, 0, + 6, 0xFC83, 0x0643, 0x0649, 0, + 6, 0xFC84, 0x0643, 0x064A, 0, + 6, 0xFC85, 0x0644, 0x0645, 0, + 6, 0xFC86, 0x0644, 0x0649, 0, + 6, 0xFC87, 0x0644, 0x064A, 0, + 6, 0xFC88, 0x0645, 0x0627, 0, + 6, 0xFC89, 0x0645, 0x0645, 0, + 6, 0xFC8A, 0x0646, 0x0631, 0, + 6, 0xFC8B, 0x0646, 0x0632, 0, + 6, 0xFC8C, 0x0646, 0x0645, 0, + 6, 0xFC8D, 0x0646, 0x0646, 0, + 6, 0xFC8E, 0x0646, 0x0649, 0, + 6, 0xFC8F, 0x0646, 0x064A, 0, + 6, 0xFC90, 0x0649, 0x0670, 0, + 6, 0xFC91, 0x064A, 0x0631, 0, + 6, 0xFC92, 0x064A, 0x0632, 0, + 6, 0xFC93, 0x064A, 0x0645, 0, + 6, 0xFC94, 0x064A, 0x0646, 0, + 6, 0xFC95, 0x064A, 0x0649, 0, + 6, 0xFC96, 0x064A, 0x064A, 0, + 4, 0xFC97, 0x0626, 0x062C, 0, + 4, 0xFC98, 0x0626, 0x062D, 0, + 4, 0xFC99, 0x0626, 0x062E, 0, + 4, 0xFC9A, 0x0626, 0x0645, 0, + 4, 0xFC9B, 0x0626, 0x0647, 0, + 4, 0xFC9C, 0x0628, 0x062C, 0, + 4, 0xFC9D, 0x0628, 0x062D, 0, + 4, 0xFC9E, 0x0628, 0x062E, 0, + 4, 0xFC9F, 0x0628, 0x0645, 0, + 4, 0xFCA0, 0x0628, 0x0647, 0, + 4, 0xFCA1, 0x062A, 0x062C, 0, + 4, 0xFCA2, 0x062A, 0x062D, 0, + 4, 0xFCA3, 0x062A, 0x062E, 0, + 4, 0xFCA4, 0x062A, 0x0645, 0, + 4, 0xFCA5, 0x062A, 0x0647, 0, + 4, 0xFCA6, 0x062B, 0x0645, 0, + 4, 0xFCA7, 0x062C, 0x062D, 0, + 4, 0xFCA8, 0x062C, 0x0645, 0, + 4, 0xFCA9, 0x062D, 0x062C, 0, + 4, 0xFCAA, 0x062D, 0x0645, 0, + 4, 0xFCAB, 0x062E, 0x062C, 0, + 4, 0xFCAC, 0x062E, 0x0645, 0, + 4, 0xFCAD, 0x0633, 0x062C, 0, + 4, 0xFCAE, 0x0633, 0x062D, 0, + 4, 0xFCAF, 0x0633, 0x062E, 0, + 4, 0xFCB0, 0x0633, 0x0645, 0, + 4, 0xFCB1, 0x0635, 0x062D, 0, + 4, 0xFCB2, 0x0635, 0x062E, 0, + 4, 0xFCB3, 0x0635, 0x0645, 0, + 4, 0xFCB4, 0x0636, 0x062C, 0, + 4, 0xFCB5, 0x0636, 0x062D, 0, + 4, 0xFCB6, 0x0636, 0x062E, 0, + 4, 0xFCB7, 0x0636, 0x0645, 0, + 4, 0xFCB8, 0x0637, 0x062D, 0, + 4, 0xFCB9, 0x0638, 0x0645, 0, + 4, 0xFCBA, 0x0639, 0x062C, 0, + 4, 0xFCBB, 0x0639, 0x0645, 0, + 4, 0xFCBC, 0x063A, 0x062C, 0, + 4, 0xFCBD, 0x063A, 0x0645, 0, + 4, 0xFCBE, 0x0641, 0x062C, 0, + 4, 0xFCBF, 0x0641, 0x062D, 0, + 4, 0xFCC0, 0x0641, 0x062E, 0, + 4, 0xFCC1, 0x0641, 0x0645, 0, + 4, 0xFCC2, 0x0642, 0x062D, 0, + 4, 0xFCC3, 0x0642, 0x0645, 0, + 4, 0xFCC4, 0x0643, 0x062C, 0, + 4, 0xFCC5, 0x0643, 0x062D, 0, + 4, 0xFCC6, 0x0643, 0x062E, 0, + 4, 0xFCC7, 0x0643, 0x0644, 0, + 4, 0xFCC8, 0x0643, 0x0645, 0, + 4, 0xFCC9, 0x0644, 0x062C, 0, + 4, 0xFCCA, 0x0644, 0x062D, 0, + 4, 0xFCCB, 0x0644, 0x062E, 0, + 4, 0xFCCC, 0x0644, 0x0645, 0, + 4, 0xFCCD, 0x0644, 0x0647, 0, + 4, 0xFCCE, 0x0645, 0x062C, 0, + 4, 0xFCCF, 0x0645, 0x062D, 0, + 4, 0xFCD0, 0x0645, 0x062E, 0, + 4, 0xFCD1, 0x0645, 0x0645, 0, + 4, 0xFCD2, 0x0646, 0x062C, 0, + 4, 0xFCD3, 0x0646, 0x062D, 0, + 4, 0xFCD4, 0x0646, 0x062E, 0, + 4, 0xFCD5, 0x0646, 0x0645, 0, + 4, 0xFCD6, 0x0646, 0x0647, 0, + 4, 0xFCD7, 0x0647, 0x062C, 0, + 4, 0xFCD8, 0x0647, 0x0645, 0, + 4, 0xFCD9, 0x0647, 0x0670, 0, + 4, 0xFCDA, 0x064A, 0x062C, 0, + 4, 0xFCDB, 0x064A, 0x062D, 0, + 4, 0xFCDC, 0x064A, 0x062E, 0, + 4, 0xFCDD, 0x064A, 0x0645, 0, + 4, 0xFCDE, 0x064A, 0x0647, 0, + 5, 0xFCDF, 0x0626, 0x0645, 0, + 5, 0xFCE0, 0x0626, 0x0647, 0, + 5, 0xFCE1, 0x0628, 0x0645, 0, + 5, 0xFCE2, 0x0628, 0x0647, 0, + 5, 0xFCE3, 0x062A, 0x0645, 0, + 5, 0xFCE4, 0x062A, 0x0647, 0, + 5, 0xFCE5, 0x062B, 0x0645, 0, + 5, 0xFCE6, 0x062B, 0x0647, 0, + 5, 0xFCE7, 0x0633, 0x0645, 0, + 5, 0xFCE8, 0x0633, 0x0647, 0, + 5, 0xFCE9, 0x0634, 0x0645, 0, + 5, 0xFCEA, 0x0634, 0x0647, 0, + 5, 0xFCEB, 0x0643, 0x0644, 0, + 5, 0xFCEC, 0x0643, 0x0645, 0, + 5, 0xFCED, 0x0644, 0x0645, 0, + 5, 0xFCEE, 0x0646, 0x0645, 0, + 5, 0xFCEF, 0x0646, 0x0647, 0, + 5, 0xFCF0, 0x064A, 0x0645, 0, + 5, 0xFCF1, 0x064A, 0x0647, 0, + 5, 0xFCF2, 0x0640, 0x064E, 0x0651, 0, + 5, 0xFCF3, 0x0640, 0x064F, 0x0651, 0, + 5, 0xFCF4, 0x0640, 0x0650, 0x0651, 0, + 7, 0xFCF5, 0x0637, 0x0649, 0, + 7, 0xFCF6, 0x0637, 0x064A, 0, + 7, 0xFCF7, 0x0639, 0x0649, 0, + 7, 0xFCF8, 0x0639, 0x064A, 0, + 7, 0xFCF9, 0x063A, 0x0649, 0, + 7, 0xFCFA, 0x063A, 0x064A, 0, + 7, 0xFCFB, 0x0633, 0x0649, 0, + 7, 0xFCFC, 0x0633, 0x064A, 0, + 7, 0xFCFD, 0x0634, 0x0649, 0, + 7, 0xFCFE, 0x0634, 0x064A, 0, + 7, 0xFCFF, 0x062D, 0x0649, 0, + 7, 0xFD00, 0x062D, 0x064A, 0, + 7, 0xFD01, 0x062C, 0x0649, 0, + 7, 0xFD02, 0x062C, 0x064A, 0, + 7, 0xFD03, 0x062E, 0x0649, 0, + 7, 0xFD04, 0x062E, 0x064A, 0, + 7, 0xFD05, 0x0635, 0x0649, 0, + 7, 0xFD06, 0x0635, 0x064A, 0, + 7, 0xFD07, 0x0636, 0x0649, 0, + 7, 0xFD08, 0x0636, 0x064A, 0, + 7, 0xFD09, 0x0634, 0x062C, 0, + 7, 0xFD0A, 0x0634, 0x062D, 0, + 7, 0xFD0B, 0x0634, 0x062E, 0, + 7, 0xFD0C, 0x0634, 0x0645, 0, + 7, 0xFD0D, 0x0634, 0x0631, 0, + 7, 0xFD0E, 0x0633, 0x0631, 0, + 7, 0xFD0F, 0x0635, 0x0631, 0, + 7, 0xFD10, 0x0636, 0x0631, 0, + 6, 0xFD11, 0x0637, 0x0649, 0, + 6, 0xFD12, 0x0637, 0x064A, 0, + 6, 0xFD13, 0x0639, 0x0649, 0, + 6, 0xFD14, 0x0639, 0x064A, 0, + 6, 0xFD15, 0x063A, 0x0649, 0, + 6, 0xFD16, 0x063A, 0x064A, 0, + 6, 0xFD17, 0x0633, 0x0649, 0, + 6, 0xFD18, 0x0633, 0x064A, 0, + 6, 0xFD19, 0x0634, 0x0649, 0, + 6, 0xFD1A, 0x0634, 0x064A, 0, + 6, 0xFD1B, 0x062D, 0x0649, 0, + 6, 0xFD1C, 0x062D, 0x064A, 0, + 6, 0xFD1D, 0x062C, 0x0649, 0, + 6, 0xFD1E, 0x062C, 0x064A, 0, + 6, 0xFD1F, 0x062E, 0x0649, 0, + 6, 0xFD20, 0x062E, 0x064A, 0, + 6, 0xFD21, 0x0635, 0x0649, 0, + 6, 0xFD22, 0x0635, 0x064A, 0, + 6, 0xFD23, 0x0636, 0x0649, 0, + 6, 0xFD24, 0x0636, 0x064A, 0, + 6, 0xFD25, 0x0634, 0x062C, 0, + 6, 0xFD26, 0x0634, 0x062D, 0, + 6, 0xFD27, 0x0634, 0x062E, 0, + 6, 0xFD28, 0x0634, 0x0645, 0, + 6, 0xFD29, 0x0634, 0x0631, 0, + 6, 0xFD2A, 0x0633, 0x0631, 0, + 6, 0xFD2B, 0x0635, 0x0631, 0, + 6, 0xFD2C, 0x0636, 0x0631, 0, + 4, 0xFD2D, 0x0634, 0x062C, 0, + 4, 0xFD2E, 0x0634, 0x062D, 0, + 4, 0xFD2F, 0x0634, 0x062E, 0, + 4, 0xFD30, 0x0634, 0x0645, 0, + 4, 0xFD31, 0x0633, 0x0647, 0, + 4, 0xFD32, 0x0634, 0x0647, 0, + 4, 0xFD33, 0x0637, 0x0645, 0, + 5, 0xFD34, 0x0633, 0x062C, 0, + 5, 0xFD35, 0x0633, 0x062D, 0, + 5, 0xFD36, 0x0633, 0x062E, 0, + 5, 0xFD37, 0x0634, 0x062C, 0, + 5, 0xFD38, 0x0634, 0x062D, 0, + 5, 0xFD39, 0x0634, 0x062E, 0, + 5, 0xFD3A, 0x0637, 0x0645, 0, + 5, 0xFD3B, 0x0638, 0x0645, 0, + 6, 0xFD3C, 0x0627, 0x064B, 0, + 7, 0xFD3D, 0x0627, 0x064B, 0, + 4, 0xFD50, 0x062A, 0x062C, 0x0645, 0, + 6, 0xFD51, 0x062A, 0x062D, 0x062C, 0, + 4, 0xFD52, 0x062A, 0x062D, 0x062C, 0, + 4, 0xFD53, 0x062A, 0x062D, 0x0645, 0, + 4, 0xFD54, 0x062A, 0x062E, 0x0645, 0, + 4, 0xFD55, 0x062A, 0x0645, 0x062C, 0, + 4, 0xFD56, 0x062A, 0x0645, 0x062D, 0, + 4, 0xFD57, 0x062A, 0x0645, 0x062E, 0, + 6, 0xFD58, 0x062C, 0x0645, 0x062D, 0, + 4, 0xFD59, 0x062C, 0x0645, 0x062D, 0, + 6, 0xFD5A, 0x062D, 0x0645, 0x064A, 0, + 6, 0xFD5B, 0x062D, 0x0645, 0x0649, 0, + 4, 0xFD5C, 0x0633, 0x062D, 0x062C, 0, + 4, 0xFD5D, 0x0633, 0x062C, 0x062D, 0, + 6, 0xFD5E, 0x0633, 0x062C, 0x0649, 0, + 6, 0xFD5F, 0x0633, 0x0645, 0x062D, 0, + 4, 0xFD60, 0x0633, 0x0645, 0x062D, 0, + 4, 0xFD61, 0x0633, 0x0645, 0x062C, 0, + 6, 0xFD62, 0x0633, 0x0645, 0x0645, 0, + 4, 0xFD63, 0x0633, 0x0645, 0x0645, 0, + 6, 0xFD64, 0x0635, 0x062D, 0x062D, 0, + 4, 0xFD65, 0x0635, 0x062D, 0x062D, 0, + 6, 0xFD66, 0x0635, 0x0645, 0x0645, 0, + 6, 0xFD67, 0x0634, 0x062D, 0x0645, 0, + 4, 0xFD68, 0x0634, 0x062D, 0x0645, 0, + 6, 0xFD69, 0x0634, 0x062C, 0x064A, 0, + 6, 0xFD6A, 0x0634, 0x0645, 0x062E, 0, + 4, 0xFD6B, 0x0634, 0x0645, 0x062E, 0, + 6, 0xFD6C, 0x0634, 0x0645, 0x0645, 0, + 4, 0xFD6D, 0x0634, 0x0645, 0x0645, 0, + 6, 0xFD6E, 0x0636, 0x062D, 0x0649, 0, + 6, 0xFD6F, 0x0636, 0x062E, 0x0645, 0, + 4, 0xFD70, 0x0636, 0x062E, 0x0645, 0, + 6, 0xFD71, 0x0637, 0x0645, 0x062D, 0, + 4, 0xFD72, 0x0637, 0x0645, 0x062D, 0, + 4, 0xFD73, 0x0637, 0x0645, 0x0645, 0, + 6, 0xFD74, 0x0637, 0x0645, 0x064A, 0, + 6, 0xFD75, 0x0639, 0x062C, 0x0645, 0, + 6, 0xFD76, 0x0639, 0x0645, 0x0645, 0, + 4, 0xFD77, 0x0639, 0x0645, 0x0645, 0, + 6, 0xFD78, 0x0639, 0x0645, 0x0649, 0, + 6, 0xFD79, 0x063A, 0x0645, 0x0645, 0, + 6, 0xFD7A, 0x063A, 0x0645, 0x064A, 0, + 6, 0xFD7B, 0x063A, 0x0645, 0x0649, 0, + 6, 0xFD7C, 0x0641, 0x062E, 0x0645, 0, + 4, 0xFD7D, 0x0641, 0x062E, 0x0645, 0, + 6, 0xFD7E, 0x0642, 0x0645, 0x062D, 0, + 6, 0xFD7F, 0x0642, 0x0645, 0x0645, 0, + 6, 0xFD80, 0x0644, 0x062D, 0x0645, 0, + 6, 0xFD81, 0x0644, 0x062D, 0x064A, 0, + 6, 0xFD82, 0x0644, 0x062D, 0x0649, 0, + 4, 0xFD83, 0x0644, 0x062C, 0x062C, 0, + 6, 0xFD84, 0x0644, 0x062C, 0x062C, 0, + 6, 0xFD85, 0x0644, 0x062E, 0x0645, 0, + 4, 0xFD86, 0x0644, 0x062E, 0x0645, 0, + 6, 0xFD87, 0x0644, 0x0645, 0x062D, 0, + 4, 0xFD88, 0x0644, 0x0645, 0x062D, 0, + 4, 0xFD89, 0x0645, 0x062D, 0x062C, 0, + 4, 0xFD8A, 0x0645, 0x062D, 0x0645, 0, + 6, 0xFD8B, 0x0645, 0x062D, 0x064A, 0, + 4, 0xFD8C, 0x0645, 0x062C, 0x062D, 0, + 4, 0xFD8D, 0x0645, 0x062C, 0x0645, 0, + 4, 0xFD8E, 0x0645, 0x062E, 0x062C, 0, + 4, 0xFD8F, 0x0645, 0x062E, 0x0645, 0, + 4, 0xFD92, 0x0645, 0x062C, 0x062E, 0, + 4, 0xFD93, 0x0647, 0x0645, 0x062C, 0, + 4, 0xFD94, 0x0647, 0x0645, 0x0645, 0, + 4, 0xFD95, 0x0646, 0x062D, 0x0645, 0, + 6, 0xFD96, 0x0646, 0x062D, 0x0649, 0, + 6, 0xFD97, 0x0646, 0x062C, 0x0645, 0, + 4, 0xFD98, 0x0646, 0x062C, 0x0645, 0, + 6, 0xFD99, 0x0646, 0x062C, 0x0649, 0, + 6, 0xFD9A, 0x0646, 0x0645, 0x064A, 0, + 6, 0xFD9B, 0x0646, 0x0645, 0x0649, 0, + 6, 0xFD9C, 0x064A, 0x0645, 0x0645, 0, + 4, 0xFD9D, 0x064A, 0x0645, 0x0645, 0, + 6, 0xFD9E, 0x0628, 0x062E, 0x064A, 0, + 6, 0xFD9F, 0x062A, 0x062C, 0x064A, 0, + 6, 0xFDA0, 0x062A, 0x062C, 0x0649, 0, + 6, 0xFDA1, 0x062A, 0x062E, 0x064A, 0, + 6, 0xFDA2, 0x062A, 0x062E, 0x0649, 0, + 6, 0xFDA3, 0x062A, 0x0645, 0x064A, 0, + 6, 0xFDA4, 0x062A, 0x0645, 0x0649, 0, + 6, 0xFDA5, 0x062C, 0x0645, 0x064A, 0, + 6, 0xFDA6, 0x062C, 0x062D, 0x0649, 0, + 6, 0xFDA7, 0x062C, 0x0645, 0x0649, 0, + 6, 0xFDA8, 0x0633, 0x062E, 0x0649, 0, + 6, 0xFDA9, 0x0635, 0x062D, 0x064A, 0, + 6, 0xFDAA, 0x0634, 0x062D, 0x064A, 0, + 6, 0xFDAB, 0x0636, 0x062D, 0x064A, 0, + 6, 0xFDAC, 0x0644, 0x062C, 0x064A, 0, + 6, 0xFDAD, 0x0644, 0x0645, 0x064A, 0, + 6, 0xFDAE, 0x064A, 0x062D, 0x064A, 0, + 6, 0xFDAF, 0x064A, 0x062C, 0x064A, 0, + 6, 0xFDB0, 0x064A, 0x0645, 0x064A, 0, + 6, 0xFDB1, 0x0645, 0x0645, 0x064A, 0, + 6, 0xFDB2, 0x0642, 0x0645, 0x064A, 0, + 6, 0xFDB3, 0x0646, 0x062D, 0x064A, 0, + 4, 0xFDB4, 0x0642, 0x0645, 0x062D, 0, + 4, 0xFDB5, 0x0644, 0x062D, 0x0645, 0, + 6, 0xFDB6, 0x0639, 0x0645, 0x064A, 0, + 6, 0xFDB7, 0x0643, 0x0645, 0x064A, 0, + 4, 0xFDB8, 0x0646, 0x062C, 0x062D, 0, + 6, 0xFDB9, 0x0645, 0x062E, 0x064A, 0, + 4, 0xFDBA, 0x0644, 0x062C, 0x0645, 0, + 6, 0xFDBB, 0x0643, 0x0645, 0x0645, 0, + 6, 0xFDBC, 0x0644, 0x062C, 0x0645, 0, + 6, 0xFDBD, 0x0646, 0x062C, 0x062D, 0, + 6, 0xFDBE, 0x062C, 0x062D, 0x064A, 0, + 6, 0xFDBF, 0x062D, 0x062C, 0x064A, 0, + 6, 0xFDC0, 0x0645, 0x062C, 0x064A, 0, + 6, 0xFDC1, 0x0641, 0x0645, 0x064A, 0, + 6, 0xFDC2, 0x0628, 0x062D, 0x064A, 0, + 4, 0xFDC3, 0x0643, 0x0645, 0x0645, 0, + 4, 0xFDC4, 0x0639, 0x062C, 0x0645, 0, + 4, 0xFDC5, 0x0635, 0x0645, 0x0645, 0, + 6, 0xFDC6, 0x0633, 0x062E, 0x064A, 0, + 6, 0xFDC7, 0x0646, 0x062C, 0x064A, 0, + 7, 0xFDF0, 0x0635, 0x0644, 0x06D2, 0, + 7, 0xFDF1, 0x0642, 0x0644, 0x06D2, 0, + 7, 0xFDF2, 0x0627, 0x0644, 0x0644, 0x0647, 0, + 7, 0xFDF3, 0x0627, 0x0643, 0x0628, 0x0631, 0, + 7, 0xFDF4, 0x0645, 0x062D, 0x0645, 0x062F, 0, + 7, 0xFDF5, 0x0635, 0x0644, 0x0639, 0x0645, 0, + 7, 0xFDF6, 0x0631, 0x0633, 0x0648, 0x0644, 0, + 7, 0xFDF7, 0x0639, 0x0644, 0x064A, 0x0647, 0, + 7, 0xFDF8, 0x0648, 0x0633, 0x0644, 0x0645, 0, + 7, 0xFDF9, 0x0635, 0x0644, 0x0649, 0, + 7, 0xFDFA, 0x0635, 0x0644, 0x0649, 0x0020, 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, 0x0639, 0x0644, 0x064A, 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, 0x0645, 0, + 7, 0xFDFB, 0x062C, 0x0644, 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, 0x0647, 0, + 7, 0xFDFC, 0x0631, 0x06CC, 0x0627, 0x0644, 0, + 11, 0xFE30, 0x2025, 0, + 11, 0xFE31, 0x2014, 0, + 11, 0xFE32, 0x2013, 0, + 11, 0xFE33, 0x005F, 0, + 11, 0xFE34, 0x005F, 0, + 11, 0xFE35, 0x0028, 0, + 11, 0xFE36, 0x0029, 0, + 11, 0xFE37, 0x007B, 0, + 11, 0xFE38, 0x007D, 0, + 11, 0xFE39, 0x3014, 0, + 11, 0xFE3A, 0x3015, 0, + 11, 0xFE3B, 0x3010, 0, + 11, 0xFE3C, 0x3011, 0, + 11, 0xFE3D, 0x300A, 0, + 11, 0xFE3E, 0x300B, 0, + 11, 0xFE3F, 0x3008, 0, + 11, 0xFE40, 0x3009, 0, + 11, 0xFE41, 0x300C, 0, + 11, 0xFE42, 0x300D, 0, + 11, 0xFE43, 0x300E, 0, + 11, 0xFE44, 0x300F, 0, + 16, 0xFE49, 0x203E, 0, + 16, 0xFE4A, 0x203E, 0, + 16, 0xFE4B, 0x203E, 0, + 16, 0xFE4C, 0x203E, 0, + 16, 0xFE4D, 0x005F, 0, + 16, 0xFE4E, 0x005F, 0, + 16, 0xFE4F, 0x005F, 0, + 14, 0xFE50, 0x002C, 0, + 14, 0xFE51, 0x3001, 0, + 14, 0xFE52, 0x002E, 0, + 14, 0xFE54, 0x003B, 0, + 14, 0xFE55, 0x003A, 0, + 14, 0xFE56, 0x003F, 0, + 14, 0xFE57, 0x0021, 0, + 14, 0xFE58, 0x2014, 0, + 14, 0xFE59, 0x0028, 0, + 14, 0xFE5A, 0x0029, 0, + 14, 0xFE5B, 0x007B, 0, + 14, 0xFE5C, 0x007D, 0, + 14, 0xFE5D, 0x3014, 0, + 14, 0xFE5E, 0x3015, 0, + 14, 0xFE5F, 0x0023, 0, + 14, 0xFE60, 0x0026, 0, + 14, 0xFE61, 0x002A, 0, + 14, 0xFE62, 0x002B, 0, + 14, 0xFE63, 0x002D, 0, + 14, 0xFE64, 0x003C, 0, + 14, 0xFE65, 0x003E, 0, + 14, 0xFE66, 0x003D, 0, + 14, 0xFE68, 0x005C, 0, + 14, 0xFE69, 0x0024, 0, + 14, 0xFE6A, 0x0025, 0, + 14, 0xFE6B, 0x0040, 0, + 7, 0xFE70, 0x0020, 0x064B, 0, + 5, 0xFE71, 0x0640, 0x064B, 0, + 7, 0xFE72, 0x0020, 0x064C, 0, + 7, 0xFE74, 0x0020, 0x064D, 0, + 7, 0xFE76, 0x0020, 0x064E, 0, + 5, 0xFE77, 0x0640, 0x064E, 0, + 7, 0xFE78, 0x0020, 0x064F, 0, + 5, 0xFE79, 0x0640, 0x064F, 0, + 7, 0xFE7A, 0x0020, 0x0650, 0, + 5, 0xFE7B, 0x0640, 0x0650, 0, + 7, 0xFE7C, 0x0020, 0x0651, 0, + 5, 0xFE7D, 0x0640, 0x0651, 0, + 7, 0xFE7E, 0x0020, 0x0652, 0, + 5, 0xFE7F, 0x0640, 0x0652, 0, + 7, 0xFE80, 0x0621, 0, + 7, 0xFE81, 0x0622, 0, + 6, 0xFE82, 0x0622, 0, + 7, 0xFE83, 0x0623, 0, + 6, 0xFE84, 0x0623, 0, + 7, 0xFE85, 0x0624, 0, + 6, 0xFE86, 0x0624, 0, + 7, 0xFE87, 0x0625, 0, + 6, 0xFE88, 0x0625, 0, + 7, 0xFE89, 0x0626, 0, + 6, 0xFE8A, 0x0626, 0, + 4, 0xFE8B, 0x0626, 0, + 5, 0xFE8C, 0x0626, 0, + 7, 0xFE8D, 0x0627, 0, + 6, 0xFE8E, 0x0627, 0, + 7, 0xFE8F, 0x0628, 0, + 6, 0xFE90, 0x0628, 0, + 4, 0xFE91, 0x0628, 0, + 5, 0xFE92, 0x0628, 0, + 7, 0xFE93, 0x0629, 0, + 6, 0xFE94, 0x0629, 0, + 7, 0xFE95, 0x062A, 0, + 6, 0xFE96, 0x062A, 0, + 4, 0xFE97, 0x062A, 0, + 5, 0xFE98, 0x062A, 0, + 7, 0xFE99, 0x062B, 0, + 6, 0xFE9A, 0x062B, 0, + 4, 0xFE9B, 0x062B, 0, + 5, 0xFE9C, 0x062B, 0, + 7, 0xFE9D, 0x062C, 0, + 6, 0xFE9E, 0x062C, 0, + 4, 0xFE9F, 0x062C, 0, + 5, 0xFEA0, 0x062C, 0, + 7, 0xFEA1, 0x062D, 0, + 6, 0xFEA2, 0x062D, 0, + 4, 0xFEA3, 0x062D, 0, + 5, 0xFEA4, 0x062D, 0, + 7, 0xFEA5, 0x062E, 0, + 6, 0xFEA6, 0x062E, 0, + 4, 0xFEA7, 0x062E, 0, + 5, 0xFEA8, 0x062E, 0, + 7, 0xFEA9, 0x062F, 0, + 6, 0xFEAA, 0x062F, 0, + 7, 0xFEAB, 0x0630, 0, + 6, 0xFEAC, 0x0630, 0, + 7, 0xFEAD, 0x0631, 0, + 6, 0xFEAE, 0x0631, 0, + 7, 0xFEAF, 0x0632, 0, + 6, 0xFEB0, 0x0632, 0, + 7, 0xFEB1, 0x0633, 0, + 6, 0xFEB2, 0x0633, 0, + 4, 0xFEB3, 0x0633, 0, + 5, 0xFEB4, 0x0633, 0, + 7, 0xFEB5, 0x0634, 0, + 6, 0xFEB6, 0x0634, 0, + 4, 0xFEB7, 0x0634, 0, + 5, 0xFEB8, 0x0634, 0, + 7, 0xFEB9, 0x0635, 0, + 6, 0xFEBA, 0x0635, 0, + 4, 0xFEBB, 0x0635, 0, + 5, 0xFEBC, 0x0635, 0, + 7, 0xFEBD, 0x0636, 0, + 6, 0xFEBE, 0x0636, 0, + 4, 0xFEBF, 0x0636, 0, + 5, 0xFEC0, 0x0636, 0, + 7, 0xFEC1, 0x0637, 0, + 6, 0xFEC2, 0x0637, 0, + 4, 0xFEC3, 0x0637, 0, + 5, 0xFEC4, 0x0637, 0, + 7, 0xFEC5, 0x0638, 0, + 6, 0xFEC6, 0x0638, 0, + 4, 0xFEC7, 0x0638, 0, + 5, 0xFEC8, 0x0638, 0, + 7, 0xFEC9, 0x0639, 0, + 6, 0xFECA, 0x0639, 0, + 4, 0xFECB, 0x0639, 0, + 5, 0xFECC, 0x0639, 0, + 7, 0xFECD, 0x063A, 0, + 6, 0xFECE, 0x063A, 0, + 4, 0xFECF, 0x063A, 0, + 5, 0xFED0, 0x063A, 0, + 7, 0xFED1, 0x0641, 0, + 6, 0xFED2, 0x0641, 0, + 4, 0xFED3, 0x0641, 0, + 5, 0xFED4, 0x0641, 0, + 7, 0xFED5, 0x0642, 0, + 6, 0xFED6, 0x0642, 0, + 4, 0xFED7, 0x0642, 0, + 5, 0xFED8, 0x0642, 0, + 7, 0xFED9, 0x0643, 0, + 6, 0xFEDA, 0x0643, 0, + 4, 0xFEDB, 0x0643, 0, + 5, 0xFEDC, 0x0643, 0, + 7, 0xFEDD, 0x0644, 0, + 6, 0xFEDE, 0x0644, 0, + 4, 0xFEDF, 0x0644, 0, + 5, 0xFEE0, 0x0644, 0, + 7, 0xFEE1, 0x0645, 0, + 6, 0xFEE2, 0x0645, 0, + 4, 0xFEE3, 0x0645, 0, + 5, 0xFEE4, 0x0645, 0, + 7, 0xFEE5, 0x0646, 0, + 6, 0xFEE6, 0x0646, 0, + 4, 0xFEE7, 0x0646, 0, + 5, 0xFEE8, 0x0646, 0, + 7, 0xFEE9, 0x0647, 0, + 6, 0xFEEA, 0x0647, 0, + 4, 0xFEEB, 0x0647, 0, + 5, 0xFEEC, 0x0647, 0, + 7, 0xFEED, 0x0648, 0, + 6, 0xFEEE, 0x0648, 0, + 7, 0xFEEF, 0x0649, 0, + 6, 0xFEF0, 0x0649, 0, + 7, 0xFEF1, 0x064A, 0, + 6, 0xFEF2, 0x064A, 0, + 4, 0xFEF3, 0x064A, 0, + 5, 0xFEF4, 0x064A, 0, + 7, 0xFEF5, 0x0644, 0x0622, 0, + 6, 0xFEF6, 0x0644, 0x0622, 0, + 7, 0xFEF7, 0x0644, 0x0623, 0, + 6, 0xFEF8, 0x0644, 0x0623, 0, + 7, 0xFEF9, 0x0644, 0x0625, 0, + 6, 0xFEFA, 0x0644, 0x0625, 0, + 7, 0xFEFB, 0x0644, 0x0627, 0, + 6, 0xFEFC, 0x0644, 0x0627, 0, + 12, 0xFF01, 0x0021, 0, + 12, 0xFF02, 0x0022, 0, + 12, 0xFF03, 0x0023, 0, + 12, 0xFF04, 0x0024, 0, + 12, 0xFF05, 0x0025, 0, + 12, 0xFF06, 0x0026, 0, + 12, 0xFF07, 0x0027, 0, + 12, 0xFF08, 0x0028, 0, + 12, 0xFF09, 0x0029, 0, + 12, 0xFF0A, 0x002A, 0, + 12, 0xFF0B, 0x002B, 0, + 12, 0xFF0C, 0x002C, 0, + 12, 0xFF0D, 0x002D, 0, + 12, 0xFF0E, 0x002E, 0, + 12, 0xFF0F, 0x002F, 0, + 12, 0xFF10, 0x0030, 0, + 12, 0xFF11, 0x0031, 0, + 12, 0xFF12, 0x0032, 0, + 12, 0xFF13, 0x0033, 0, + 12, 0xFF14, 0x0034, 0, + 12, 0xFF15, 0x0035, 0, + 12, 0xFF16, 0x0036, 0, + 12, 0xFF17, 0x0037, 0, + 12, 0xFF18, 0x0038, 0, + 12, 0xFF19, 0x0039, 0, + 12, 0xFF1A, 0x003A, 0, + 12, 0xFF1B, 0x003B, 0, + 12, 0xFF1C, 0x003C, 0, + 12, 0xFF1D, 0x003D, 0, + 12, 0xFF1E, 0x003E, 0, + 12, 0xFF1F, 0x003F, 0, + 12, 0xFF20, 0x0040, 0, + 12, 0xFF21, 0x0041, 0, + 12, 0xFF22, 0x0042, 0, + 12, 0xFF23, 0x0043, 0, + 12, 0xFF24, 0x0044, 0, + 12, 0xFF25, 0x0045, 0, + 12, 0xFF26, 0x0046, 0, + 12, 0xFF27, 0x0047, 0, + 12, 0xFF28, 0x0048, 0, + 12, 0xFF29, 0x0049, 0, + 12, 0xFF2A, 0x004A, 0, + 12, 0xFF2B, 0x004B, 0, + 12, 0xFF2C, 0x004C, 0, + 12, 0xFF2D, 0x004D, 0, + 12, 0xFF2E, 0x004E, 0, + 12, 0xFF2F, 0x004F, 0, + 12, 0xFF30, 0x0050, 0, + 12, 0xFF31, 0x0051, 0, + 12, 0xFF32, 0x0052, 0, + 12, 0xFF33, 0x0053, 0, + 12, 0xFF34, 0x0054, 0, + 12, 0xFF35, 0x0055, 0, + 12, 0xFF36, 0x0056, 0, + 12, 0xFF37, 0x0057, 0, + 12, 0xFF38, 0x0058, 0, + 12, 0xFF39, 0x0059, 0, + 12, 0xFF3A, 0x005A, 0, + 12, 0xFF3B, 0x005B, 0, + 12, 0xFF3C, 0x005C, 0, + 12, 0xFF3D, 0x005D, 0, + 12, 0xFF3E, 0x005E, 0, + 12, 0xFF3F, 0x005F, 0, + 12, 0xFF40, 0x0060, 0, + 12, 0xFF41, 0x0061, 0, + 12, 0xFF42, 0x0062, 0, + 12, 0xFF43, 0x0063, 0, + 12, 0xFF44, 0x0064, 0, + 12, 0xFF45, 0x0065, 0, + 12, 0xFF46, 0x0066, 0, + 12, 0xFF47, 0x0067, 0, + 12, 0xFF48, 0x0068, 0, + 12, 0xFF49, 0x0069, 0, + 12, 0xFF4A, 0x006A, 0, + 12, 0xFF4B, 0x006B, 0, + 12, 0xFF4C, 0x006C, 0, + 12, 0xFF4D, 0x006D, 0, + 12, 0xFF4E, 0x006E, 0, + 12, 0xFF4F, 0x006F, 0, + 12, 0xFF50, 0x0070, 0, + 12, 0xFF51, 0x0071, 0, + 12, 0xFF52, 0x0072, 0, + 12, 0xFF53, 0x0073, 0, + 12, 0xFF54, 0x0074, 0, + 12, 0xFF55, 0x0075, 0, + 12, 0xFF56, 0x0076, 0, + 12, 0xFF57, 0x0077, 0, + 12, 0xFF58, 0x0078, 0, + 12, 0xFF59, 0x0079, 0, + 12, 0xFF5A, 0x007A, 0, + 12, 0xFF5B, 0x007B, 0, + 12, 0xFF5C, 0x007C, 0, + 12, 0xFF5D, 0x007D, 0, + 12, 0xFF5E, 0x007E, 0, + 12, 0xFF5F, 0x2985, 0, + 12, 0xFF60, 0x2986, 0, + 13, 0xFF61, 0x3002, 0, + 13, 0xFF62, 0x300C, 0, + 13, 0xFF63, 0x300D, 0, + 13, 0xFF64, 0x3001, 0, + 13, 0xFF65, 0x30FB, 0, + 13, 0xFF66, 0x30F2, 0, + 13, 0xFF67, 0x30A1, 0, + 13, 0xFF68, 0x30A3, 0, + 13, 0xFF69, 0x30A5, 0, + 13, 0xFF6A, 0x30A7, 0, + 13, 0xFF6B, 0x30A9, 0, + 13, 0xFF6C, 0x30E3, 0, + 13, 0xFF6D, 0x30E5, 0, + 13, 0xFF6E, 0x30E7, 0, + 13, 0xFF6F, 0x30C3, 0, + 13, 0xFF70, 0x30FC, 0, + 13, 0xFF71, 0x30A2, 0, + 13, 0xFF72, 0x30A4, 0, + 13, 0xFF73, 0x30A6, 0, + 13, 0xFF74, 0x30A8, 0, + 13, 0xFF75, 0x30AA, 0, + 13, 0xFF76, 0x30AB, 0, + 13, 0xFF77, 0x30AD, 0, + 13, 0xFF78, 0x30AF, 0, + 13, 0xFF79, 0x30B1, 0, + 13, 0xFF7A, 0x30B3, 0, + 13, 0xFF7B, 0x30B5, 0, + 13, 0xFF7C, 0x30B7, 0, + 13, 0xFF7D, 0x30B9, 0, + 13, 0xFF7E, 0x30BB, 0, + 13, 0xFF7F, 0x30BD, 0, + 13, 0xFF80, 0x30BF, 0, + 13, 0xFF81, 0x30C1, 0, + 13, 0xFF82, 0x30C4, 0, + 13, 0xFF83, 0x30C6, 0, + 13, 0xFF84, 0x30C8, 0, + 13, 0xFF85, 0x30CA, 0, + 13, 0xFF86, 0x30CB, 0, + 13, 0xFF87, 0x30CC, 0, + 13, 0xFF88, 0x30CD, 0, + 13, 0xFF89, 0x30CE, 0, + 13, 0xFF8A, 0x30CF, 0, + 13, 0xFF8B, 0x30D2, 0, + 13, 0xFF8C, 0x30D5, 0, + 13, 0xFF8D, 0x30D8, 0, + 13, 0xFF8E, 0x30DB, 0, + 13, 0xFF8F, 0x30DE, 0, + 13, 0xFF90, 0x30DF, 0, + 13, 0xFF91, 0x30E0, 0, + 13, 0xFF92, 0x30E1, 0, + 13, 0xFF93, 0x30E2, 0, + 13, 0xFF94, 0x30E4, 0, + 13, 0xFF95, 0x30E6, 0, + 13, 0xFF96, 0x30E8, 0, + 13, 0xFF97, 0x30E9, 0, + 13, 0xFF98, 0x30EA, 0, + 13, 0xFF99, 0x30EB, 0, + 13, 0xFF9A, 0x30EC, 0, + 13, 0xFF9B, 0x30ED, 0, + 13, 0xFF9C, 0x30EF, 0, + 13, 0xFF9D, 0x30F3, 0, + 13, 0xFF9E, 0x3099, 0, + 13, 0xFF9F, 0x309A, 0, + 13, 0xFFA0, 0x3164, 0, + 13, 0xFFA1, 0x3131, 0, + 13, 0xFFA2, 0x3132, 0, + 13, 0xFFA3, 0x3133, 0, + 13, 0xFFA4, 0x3134, 0, + 13, 0xFFA5, 0x3135, 0, + 13, 0xFFA6, 0x3136, 0, + 13, 0xFFA7, 0x3137, 0, + 13, 0xFFA8, 0x3138, 0, + 13, 0xFFA9, 0x3139, 0, + 13, 0xFFAA, 0x313A, 0, + 13, 0xFFAB, 0x313B, 0, + 13, 0xFFAC, 0x313C, 0, + 13, 0xFFAD, 0x313D, 0, + 13, 0xFFAE, 0x313E, 0, + 13, 0xFFAF, 0x313F, 0, + 13, 0xFFB0, 0x3140, 0, + 13, 0xFFB1, 0x3141, 0, + 13, 0xFFB2, 0x3142, 0, + 13, 0xFFB3, 0x3143, 0, + 13, 0xFFB4, 0x3144, 0, + 13, 0xFFB5, 0x3145, 0, + 13, 0xFFB6, 0x3146, 0, + 13, 0xFFB7, 0x3147, 0, + 13, 0xFFB8, 0x3148, 0, + 13, 0xFFB9, 0x3149, 0, + 13, 0xFFBA, 0x314A, 0, + 13, 0xFFBB, 0x314B, 0, + 13, 0xFFBC, 0x314C, 0, + 13, 0xFFBD, 0x314D, 0, + 13, 0xFFBE, 0x314E, 0, + 13, 0xFFC2, 0x314F, 0, + 13, 0xFFC3, 0x3150, 0, + 13, 0xFFC4, 0x3151, 0, + 13, 0xFFC5, 0x3152, 0, + 13, 0xFFC6, 0x3153, 0, + 13, 0xFFC7, 0x3154, 0, + 13, 0xFFCA, 0x3155, 0, + 13, 0xFFCB, 0x3156, 0, + 13, 0xFFCC, 0x3157, 0, + 13, 0xFFCD, 0x3158, 0, + 13, 0xFFCE, 0x3159, 0, + 13, 0xFFCF, 0x315A, 0, + 13, 0xFFD2, 0x315B, 0, + 13, 0xFFD3, 0x315C, 0, + 13, 0xFFD4, 0x315D, 0, + 13, 0xFFD5, 0x315E, 0, + 13, 0xFFD6, 0x315F, 0, + 13, 0xFFD7, 0x3160, 0, + 13, 0xFFDA, 0x3161, 0, + 13, 0xFFDB, 0x3162, 0, + 13, 0xFFDC, 0x3163, 0, + 12, 0xFFE0, 0x00A2, 0, + 12, 0xFFE1, 0x00A3, 0, + 12, 0xFFE2, 0x00AC, 0, + 12, 0xFFE3, 0x00AF, 0, + 12, 0xFFE4, 0x00A6, 0, + 12, 0xFFE5, 0x00A5, 0, + 12, 0xFFE6, 0x20A9, 0, + 13, 0xFFE8, 0x2502, 0, + 13, 0xFFE9, 0x2190, 0, + 13, 0xFFEA, 0x2191, 0, + 13, 0xFFEB, 0x2192, 0, + 13, 0xFFEC, 0x2193, 0, + 13, 0xFFED, 0x25A0, 0, + 13, 0xFFEE, 0x25CB, 0, + +}; + +const Q_UINT16 QUnicodeTables::decomposition_info[] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 17, 18, + 19, 20, 21, 22, 23, 8, 8, 8, + 8, 8, 24, 8, 8, 8, 25, 26, + 27, 28, 29, 30, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 31, 32, 33, 34, 35, 36, 37, + + 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, 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, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 10, 0, 0, 0, 0, 14, + 0, 0, 19, 23, 27, 32, 0, 0, + 36, 41, 45, 0, 49, 55, 61, 0, + 67, 72, 77, 82, 87, 92, 0, 97, + 102, 107, 112, 117, 122, 127, 132, 137, + 0, 142, 147, 152, 157, 162, 167, 0, + 0, 172, 177, 182, 187, 192, 0, 0, + 197, 202, 207, 212, 217, 222, 0, 227, + 232, 237, 242, 247, 252, 257, 262, 267, + 0, 272, 277, 282, 287, 292, 297, 0, + 0, 302, 307, 312, 317, 322, 0, 327, + + 332, 337, 342, 347, 352, 357, 362, 367, + 372, 377, 382, 387, 392, 397, 402, 407, + 0, 0, 412, 417, 422, 427, 432, 437, + 442, 447, 452, 457, 462, 467, 472, 477, + 482, 487, 492, 497, 502, 507, 0, 0, + 512, 517, 522, 527, 532, 537, 542, 547, + 552, 0, 557, 562, 567, 572, 577, 582, + 0, 587, 592, 597, 602, 607, 612, 617, + 622, 0, 0, 627, 632, 637, 642, 647, + 652, 657, 0, 0, 662, 667, 672, 677, + 682, 687, 0, 0, 692, 697, 702, 707, + 712, 717, 722, 727, 732, 737, 742, 747, + 752, 757, 762, 767, 772, 777, 0, 0, + 782, 787, 792, 797, 802, 807, 812, 817, + 822, 827, 832, 837, 842, 847, 852, 857, + 862, 867, 872, 877, 882, 887, 892, 897, + 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, + 901, 906, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 911, + 916, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 921, 926, 931, 936, + 941, 946, 951, 956, 961, 966, 971, 976, + 981, 986, 991, 996, 1001, 1006, 1011, 1016, + 1021, 1026, 1031, 1036, 1041, 0, 1046, 1051, + 1056, 1061, 1066, 1071, 0, 0, 1076, 1081, + 1086, 1091, 1096, 1101, 1106, 1111, 1116, 1121, + 1126, 1131, 1136, 1141, 1146, 1151, 0, 0, + 1156, 1161, 1166, 1171, 1176, 1181, 1186, 1191, + + 1196, 1201, 1206, 1211, 1216, 1221, 1226, 1231, + 1236, 1241, 1246, 1251, 1256, 1261, 1266, 1271, + 1276, 1281, 1286, 1291, 1296, 1301, 1306, 1311, + 1316, 1321, 1326, 1331, 0, 0, 1336, 1341, + 0, 0, 0, 0, 0, 0, 1346, 1351, + 1356, 1361, 1366, 1371, 1376, 1381, 1386, 1391, + 1396, 1401, 1406, 1411, 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, 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, + 1416, 1420, 1424, 1428, 1432, 1436, 1440, 1444, + 1448, 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, + 1452, 1457, 1462, 1467, 1472, 1477, 0, 0, + 1482, 1486, 1490, 1494, 1498, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1502, 1506, 0, 1510, 1514, 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, 1519, 0, 0, 0, + 0, 0, 1523, 0, 0, 0, 1528, 0, + 0, 0, 0, 0, 1532, 1537, 1542, 1547, + 1551, 1556, 1561, 0, 1566, 0, 1571, 1576, + 1581, 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, 1586, 1591, 1596, 1601, 1606, 1611, + 1616, 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, 1621, 1626, 1631, 1636, 1641, 0, + 1646, 1650, 1654, 1658, 1663, 1668, 1672, 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, + 1676, 1680, 1684, 0, 1688, 1692, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 1696, 1701, 0, 1706, 0, 0, 0, 1711, + 0, 0, 0, 0, 1716, 1721, 1726, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1731, 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, 1736, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1741, 1746, 0, 1751, 0, 0, 0, 1756, + 0, 0, 0, 0, 1761, 1766, 1771, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1776, 1781, + 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, 1786, 1791, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1796, 1801, 1806, 1811, 0, 0, 1816, 1821, + 0, 0, 1826, 1831, 1836, 1841, 1846, 1851, + 0, 0, 1856, 1861, 1866, 1871, 1876, 1881, + 0, 0, 1886, 1891, 1896, 1901, 1906, 1911, + 1916, 1921, 1926, 1931, 1936, 1941, 0, 0, + 1946, 1951, 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, 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, 1956, + 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, 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, 1961, 1966, 1971, 1976, 1981, 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, 1986, 1991, 1996, + 2001, 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, + 2006, 0, 2011, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2016, 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, 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, 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, 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, + 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, 2021, 0, 0, 0, 0, 0, 0, + 0, 2026, 0, 0, 2031, 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, + 2036, 2041, 2046, 2051, 2056, 2061, 2066, 2071, + 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, 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, 2076, 2081, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2086, 2091, 0, 2096, + 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, 0, + 0, 0, 0, 2101, 0, 0, 2106, 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, 2111, 2116, 2121, 0, 0, 2126, 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, 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, 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, + 2131, 0, 0, 2136, 2141, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2146, 2151, 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, 2156, 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, 2161, 2166, 2171, 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, 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, + 2176, 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, + 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, + 2181, 0, 0, 0, 0, 0, 0, 2186, + 2191, 0, 2196, 2201, 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, 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, 2206, 2211, 2216, 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, 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, 2221, 0, 2226, 2231, 2236, 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, 0, 0, + 0, 0, 0, 2241, 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, 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, 2246, 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, 2251, 2256, 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, 2261, 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, 2265, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2270, 0, 0, + 0, 0, 2275, 0, 0, 0, 0, 2280, + 0, 0, 0, 0, 2285, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2290, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2295, 0, 2300, 2305, 2310, + 2315, 2320, 0, 0, 0, 0, 0, 0, + 0, 2325, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2330, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2335, 0, 0, + 0, 0, 2340, 0, 0, 0, 0, 2345, + 0, 0, 0, 0, 2350, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2355, 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, 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, 2360, 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, 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, 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, + + 2365, 2370, 2375, 2380, 2385, 2390, 2395, 2400, + 2405, 2410, 2415, 2420, 2425, 2430, 2435, 2440, + 2445, 2450, 2455, 2460, 2465, 2470, 2475, 2480, + 2485, 2490, 2495, 2500, 2505, 2510, 2515, 2520, + 2525, 2530, 2535, 2540, 2545, 2550, 2555, 2560, + 2565, 2570, 2575, 2580, 2585, 2590, 2595, 2600, + 2605, 2610, 2615, 2620, 2625, 2630, 2635, 2640, + 2645, 2650, 2655, 2660, 2665, 2670, 2675, 2680, + 2685, 2690, 2695, 2700, 2705, 2710, 2715, 2720, + 2725, 2730, 2735, 2740, 2745, 2750, 2755, 2760, + 2765, 2770, 2775, 2780, 2785, 2790, 2795, 2800, + 2805, 2810, 2815, 2820, 2825, 2830, 2835, 2840, + 2845, 2850, 2855, 2860, 2865, 2870, 2875, 2880, + 2885, 2890, 2895, 2900, 2905, 2910, 2915, 2920, + 2925, 2930, 2935, 2940, 2945, 2950, 2955, 2960, + 2965, 2970, 2975, 2980, 2985, 2990, 2995, 3000, + 3005, 3010, 3015, 3020, 3025, 3030, 3035, 3040, + 3045, 3050, 3055, 3060, 3065, 3070, 3075, 3080, + 3085, 3090, 3095, 3100, 3105, 3110, 3115, 3120, + 3125, 3130, 3135, 3140, 0, 0, 0, 0, + 3145, 3150, 3155, 3160, 3165, 3170, 3175, 3180, + 3185, 3190, 3195, 3200, 3205, 3210, 3215, 3220, + 3225, 3230, 3235, 3240, 3245, 3250, 3255, 3260, + 3265, 3270, 3275, 3280, 3285, 3290, 3295, 3300, + 3305, 3310, 3315, 3320, 3325, 3330, 3335, 3340, + 3345, 3350, 3355, 3360, 3365, 3370, 3375, 3380, + 3385, 3390, 3395, 3400, 3405, 3410, 3415, 3420, + 3425, 3430, 3435, 3440, 3445, 3450, 3455, 3460, + 3465, 3470, 3475, 3480, 3485, 3490, 3495, 3500, + 3505, 3510, 3515, 3520, 3525, 3530, 3535, 3540, + 3545, 3550, 3555, 3560, 3565, 3570, 3575, 3580, + 3585, 3590, 0, 0, 0, 0, 0, 0, + + 3595, 3600, 3605, 3610, 3615, 3620, 3625, 3630, + 3635, 3640, 3645, 3650, 3655, 3660, 3665, 3670, + 3675, 3680, 3685, 3690, 3695, 3700, 0, 0, + 3705, 3710, 3715, 3720, 3725, 3730, 0, 0, + 3735, 3740, 3745, 3750, 3755, 3760, 3765, 3770, + 3775, 3780, 3785, 3790, 3795, 3800, 3805, 3810, + 3815, 3820, 3825, 3830, 3835, 3840, 3845, 3850, + 3855, 3860, 3865, 3870, 3875, 3880, 3885, 3890, + 3895, 3900, 3905, 3910, 3915, 3920, 0, 0, + 3925, 3930, 3935, 3940, 3945, 3950, 0, 0, + 3955, 3960, 3965, 3970, 3975, 3980, 3985, 3990, + 0, 3995, 0, 4000, 0, 4005, 0, 4010, + 4015, 4020, 4025, 4030, 4035, 4040, 4045, 4050, + 4055, 4060, 4065, 4070, 4075, 4080, 4085, 4090, + 4095, 4100, 4104, 4109, 4113, 4118, 4122, 4127, + 4131, 4136, 4140, 4145, 4149, 4154, 0, 0, + 4158, 4163, 4168, 4173, 4178, 4183, 4188, 4193, + 4198, 4203, 4208, 4213, 4218, 4223, 4228, 4233, + 4238, 4243, 4248, 4253, 4258, 4263, 4268, 4273, + 4278, 4283, 4288, 4293, 4298, 4303, 4308, 4313, + 4318, 4323, 4328, 4333, 4338, 4343, 4348, 4353, + 4358, 4363, 4368, 4373, 4378, 4383, 4388, 4393, + 4398, 4403, 4408, 4413, 4418, 0, 4423, 4428, + 4433, 4438, 4443, 4448, 4452, 4457, 4462, 4466, + 4471, 4476, 4481, 4486, 4491, 0, 4496, 4501, + 4506, 4511, 4515, 4520, 4524, 4529, 4534, 4539, + 4544, 4549, 4554, 4559, 0, 0, 4563, 4568, + 4573, 4578, 4583, 4588, 0, 4592, 4597, 4602, + 4607, 4612, 4617, 4622, 4626, 4631, 4636, 4641, + 4646, 4651, 4656, 4661, 4665, 4670, 4675, 4679, + 0, 0, 4683, 4688, 4693, 0, 4698, 4703, + 4708, 4713, 4717, 4722, 4726, 4731, 4735, 0, + + 4740, 4744, 4748, 4752, 4756, 4760, 4764, 4768, + 4772, 4776, 4780, 0, 0, 0, 0, 0, + 0, 4784, 0, 0, 0, 0, 0, 4788, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4793, 4797, 4802, 0, + 0, 0, 0, 0, 0, 0, 0, 4808, + 0, 0, 0, 4812, 4817, 0, 4823, 4828, + 0, 0, 0, 0, 4834, 0, 4839, 0, + 0, 0, 0, 0, 0, 0, 0, 4844, + 4849, 4854, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4859, + 0, 0, 0, 0, 0, 0, 0, 4866, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4870, 4874, 0, 0, 4878, 4882, 4886, 4890, + 4894, 4898, 4902, 4906, 4910, 4914, 4918, 4922, + 4926, 4930, 4934, 4938, 4942, 4946, 4950, 4954, + 4958, 4962, 4966, 4970, 4974, 4978, 4982, 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, + 4986, 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, + 0, 0, 0, 0, 0, 0, 0, 0, + + 4991, 4997, 5003, 5007, 0, 5012, 5018, 5024, + 0, 5028, 5033, 5037, 5041, 5045, 5049, 5053, + 5057, 5061, 5065, 5069, 0, 5073, 5077, 0, + 0, 5082, 5086, 5090, 5094, 5098, 0, 0, + 5102, 5107, 5113, 0, 5118, 0, 5122, 0, + 5126, 0, 5130, 5134, 5138, 5142, 0, 5146, + 5150, 5154, 0, 5158, 5162, 5166, 5170, 5174, + 5178, 5182, 0, 0, 0, 5186, 5190, 5194, + 5198, 0, 0, 0, 0, 5202, 5206, 5210, + 5214, 5218, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5222, 5228, 5234, 5240, 5246, + 5252, 5258, 5264, 5270, 5276, 5282, 5288, 5294, + 5299, 5303, 5308, 5314, 5319, 5323, 5328, 5334, + 5341, 5346, 5350, 5355, 5361, 5365, 5369, 5373, + 5377, 5381, 5386, 5392, 5397, 5401, 5406, 5412, + 5419, 5424, 5428, 5433, 5439, 5443, 5447, 5451, + 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, 5455, 5460, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5465, 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, 5470, 5475, 5480, + 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, 5485, 0, 0, 0, + 0, 5490, 0, 0, 5495, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5500, 0, 5505, 0, + 0, 0, 0, 0, 5510, 5515, 0, 5521, + 5526, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5532, 0, 0, 5537, 0, 0, 5542, + 0, 5547, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5552, 0, 5557, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5562, 5567, 5572, + 5577, 5582, 0, 0, 5587, 5592, 0, 0, + 5597, 5602, 0, 0, 0, 0, 0, 0, + 5607, 5612, 0, 0, 5617, 5622, 0, 0, + 5627, 5632, 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, 5637, 5642, 5647, 5652, + 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, + 5657, 5662, 5667, 5672, 0, 0, 0, 0, + 0, 0, 5677, 5682, 5687, 5692, 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, 5697, 5701, 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, 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, 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, + 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, + 5705, 5709, 5713, 5717, 5721, 5725, 5729, 5733, + 5737, 5741, 5746, 5751, 5756, 5761, 5766, 5771, + 5776, 5781, 5786, 5791, 5796, 5802, 5808, 5814, + 5820, 5826, 5832, 5838, 5844, 5850, 5857, 5864, + 5871, 5878, 5885, 5892, 5899, 5906, 5913, 5920, + 5927, 5932, 5937, 5942, 5947, 5952, 5957, 5962, + 5967, 5972, 5978, 5984, 5990, 5996, 6002, 6008, + 6014, 6020, 6026, 6032, 6038, 6044, 6050, 6056, + 6062, 6068, 6074, 6080, 6086, 6092, 6098, 6104, + 6110, 6116, 6122, 6128, 6134, 6140, 6146, 6152, + 6158, 6164, 6170, 6176, 6182, 6188, 6194, 6198, + 6202, 6206, 6210, 6214, 6218, 6222, 6226, 6230, + 6234, 6238, 6242, 6246, 6250, 6254, 6258, 6262, + 6266, 6270, 6274, 6278, 6282, 6286, 6290, 6294, + 6298, 6302, 6306, 6310, 6314, 6318, 6322, 6326, + 6330, 6334, 6338, 6342, 6346, 6350, 6354, 6358, + 6362, 6366, 6370, 6374, 6378, 6382, 6386, 6390, + 6394, 6398, 6402, 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, 6406, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6413, 6419, 6424, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6430, 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, 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, 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, 6435, + 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, 0, + 0, 0, 0, 6439, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 6443, 6447, 6451, 6455, 6459, 6463, 6467, 6471, + 6475, 6479, 6483, 6487, 6491, 6495, 6499, 6503, + 6507, 6511, 6515, 6519, 6523, 6527, 6531, 6535, + 6539, 6543, 6547, 6551, 6555, 6559, 6563, 6567, + 6571, 6575, 6579, 6583, 6587, 6591, 6595, 6599, + 6603, 6607, 6611, 6615, 6619, 6623, 6627, 6631, + 6635, 6639, 6643, 6647, 6651, 6655, 6659, 6663, + 6667, 6671, 6675, 6679, 6683, 6687, 6691, 6695, + 6699, 6703, 6707, 6711, 6715, 6719, 6723, 6727, + 6731, 6735, 6739, 6743, 6747, 6751, 6755, 6759, + 6763, 6767, 6771, 6775, 6779, 6783, 6787, 6791, + 6795, 6799, 6803, 6807, 6811, 6815, 6819, 6823, + 6827, 6831, 6835, 6839, 6843, 6847, 6851, 6855, + 6859, 6863, 6867, 6871, 6875, 6879, 6883, 6887, + 6891, 6895, 6899, 6903, 6907, 6911, 6915, 6919, + 6923, 6927, 6931, 6935, 6939, 6943, 6947, 6951, + 6955, 6959, 6963, 6967, 6971, 6975, 6979, 6983, + 6987, 6991, 6995, 6999, 7003, 7007, 7011, 7015, + 7019, 7023, 7027, 7031, 7035, 7039, 7043, 7047, + 7051, 7055, 7059, 7063, 7067, 7071, 7075, 7079, + 7083, 7087, 7091, 7095, 7099, 7103, 7107, 7111, + 7115, 7119, 7123, 7127, 7131, 7135, 7139, 7143, + 7147, 7151, 7155, 7159, 7163, 7167, 7171, 7175, + 7179, 7183, 7187, 7191, 7195, 7199, 7203, 7207, + 7211, 7215, 7219, 7223, 7227, 7231, 7235, 7239, + 7243, 7247, 7251, 7255, 7259, 7263, 7267, 7271, + 7275, 7279, 7283, 7287, 7291, 7295, 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, + + 7299, 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, 7303, 0, + 7307, 7311, 7315, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7319, 0, 7324, 0, + 7329, 0, 7334, 0, 7339, 0, 7344, 0, + 7349, 0, 7354, 0, 7359, 0, 7364, 0, + 7369, 0, 7374, 0, 0, 7379, 0, 7384, + 0, 7389, 0, 0, 0, 0, 0, 0, + 7394, 7399, 0, 7404, 7409, 0, 7414, 7419, + 0, 7424, 7429, 0, 7434, 7439, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7444, 0, 0, 0, + 0, 0, 0, 7449, 7454, 0, 7459, 7464, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7469, 0, 7474, 0, + 7479, 0, 7484, 0, 7489, 0, 7494, 0, + 7499, 0, 7504, 0, 7509, 0, 7514, 0, + 7519, 0, 7524, 0, 0, 7529, 0, 7534, + 0, 7539, 0, 0, 0, 0, 0, 0, + 7544, 7549, 0, 7554, 7559, 0, 7564, 7569, + 0, 7574, 7579, 0, 7584, 7589, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7594, 0, 0, 7599, + 7604, 7609, 7614, 0, 0, 0, 7619, 7624, + + 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, 7629, 7633, 7637, 7641, 7645, 7649, 7653, + 7657, 7661, 7665, 7669, 7673, 7677, 7681, 7685, + 7689, 7693, 7697, 7701, 7705, 7709, 7713, 7717, + 7721, 7725, 7729, 7733, 7737, 7741, 7745, 7749, + 7753, 7757, 7761, 7765, 7769, 7773, 7777, 7781, + 7785, 7789, 7793, 7797, 7801, 7805, 7809, 7813, + 7817, 7821, 7825, 7829, 7833, 7837, 7841, 7845, + 7849, 7853, 7857, 7861, 7865, 7869, 7873, 7877, + 7881, 7885, 7889, 7893, 7897, 7901, 7905, 7909, + 7913, 7917, 7921, 7925, 7929, 7933, 7937, 7941, + 7945, 7949, 7953, 7957, 7961, 7965, 7969, 7973, + 7977, 7981, 7985, 7989, 7993, 7997, 8001, 0, + 0, 0, 8005, 8009, 8013, 8017, 8021, 8025, + 8029, 8033, 8037, 8041, 8045, 8049, 8053, 8057, + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 8061, 8067, 8073, 8079, 8085, 8091, 8097, 8103, + 8109, 8115, 8121, 8127, 8133, 8139, 8145, 8152, + 8159, 8166, 8173, 8180, 8187, 8194, 8201, 8208, + 8215, 8222, 8229, 8236, 8243, 0, 0, 0, + 8250, 8256, 8262, 8268, 8274, 8280, 8286, 8292, + 8298, 8304, 8310, 8316, 8322, 8328, 8334, 8340, + 8346, 8352, 8358, 8364, 8370, 8376, 8382, 8388, + 8394, 8400, 8406, 8412, 8418, 8424, 8430, 8436, + 8442, 8448, 8454, 8460, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8466, 8471, 8476, 8481, 8486, 8491, 8496, + 8501, 8506, 8511, 8516, 8521, 8526, 8531, 8536, + 8541, 8545, 8549, 8553, 8557, 8561, 8565, 8569, + 8573, 8577, 8581, 8585, 8589, 8593, 8597, 8602, + 8607, 8612, 8617, 8622, 8627, 8632, 8637, 8642, + 8647, 8652, 8657, 8662, 0, 0, 0, 0, + 8667, 8671, 8675, 8679, 8683, 8687, 8691, 8695, + 8699, 8703, 8707, 8711, 8715, 8719, 8723, 8727, + 8731, 8735, 8739, 8743, 8747, 8751, 8755, 8759, + 8763, 8767, 8771, 8775, 8779, 8783, 8787, 8791, + 8795, 8799, 8803, 8807, 8811, 8815, 8819, 8823, + 8827, 8831, 8835, 8839, 8843, 8847, 8851, 8855, + 8859, 8863, 8868, 8873, 8878, 8883, 8888, 8893, + 8898, 8903, 8908, 8913, 8918, 8923, 8928, 8933, + 8938, 8943, 8948, 8953, 8958, 8963, 8968, 8973, + 8978, 8983, 8989, 8995, 0, 0, 0, 0, + 9001, 9005, 9009, 9013, 9017, 9021, 9025, 9029, + 9033, 9037, 9041, 9045, 9049, 9053, 9057, 9061, + 9065, 9069, 9073, 9077, 9081, 9085, 9089, 9093, + 9097, 9101, 9105, 9109, 9113, 9117, 9121, 9125, + 9129, 9133, 9137, 9141, 9145, 9149, 9153, 9157, + 9161, 9165, 9169, 9173, 9177, 9181, 9185, 0, + + 9189, 9196, 9203, 9210, 9216, 9223, 9229, 9235, + 9243, 9250, 9256, 9262, 9268, 9275, 9282, 9288, + 9294, 9299, 9305, 9312, 9319, 9324, 9332, 9341, + 9349, 9355, 9363, 9371, 9378, 9384, 9390, 9396, + 9403, 9411, 9418, 9424, 9430, 9436, 9441, 9446, + 9451, 9456, 9462, 9468, 9476, 9482, 9489, 9497, + 9503, 9508, 9513, 9521, 9528, 9536, 9542, 9550, + 9555, 9561, 9567, 9573, 9579, 9585, 9592, 9598, + 9603, 9609, 9615, 9621, 9628, 9634, 9640, 9646, + 9654, 9661, 9666, 9674, 9679, 9686, 9693, 9699, + 9705, 9711, 9718, 9723, 9729, 9736, 9741, 9749, + 9755, 9760, 9765, 9770, 9775, 9780, 9785, 9790, + 9795, 9800, 9805, 9811, 9817, 9823, 9829, 9835, + 9841, 9847, 9853, 9859, 9865, 9871, 9877, 9883, + 9889, 9895, 9901, 9906, 9911, 9917, 9922, 0, + 0, 0, 0, 9927, 9932, 9937, 9942, 9947, + 9954, 9959, 9964, 9969, 9974, 9979, 9984, 9989, + 9994, 10000, 10007, 10012, 10017, 10022, 10027, 10032, + 10037, 10042, 10048, 10054, 10060, 10066, 10071, 10076, + 10081, 10086, 10091, 10096, 10101, 10106, 10111, 10116, + 10122, 10128, 10133, 10139, 10145, 10151, 10156, 10162, + 10168, 10175, 10180, 10186, 10192, 10198, 10204, 10212, + 10221, 10226, 10231, 10236, 10241, 10246, 10251, 10256, + 10261, 10266, 10271, 10276, 10281, 10286, 10291, 10296, + 10301, 10306, 10311, 10318, 10323, 10328, 10333, 10340, + 10346, 10351, 10356, 10361, 10366, 10371, 10376, 10381, + 10386, 10391, 10396, 10402, 10407, 10412, 10418, 10424, + 10429, 10436, 10442, 10447, 10452, 10457, 0, 0, + 10462, 10467, 10472, 10477, 10482, 10487, 10492, 10497, + 10502, 10507, 10513, 10519, 10525, 10531, 10537, 10543, + 10549, 10555, 10561, 10567, 10573, 10579, 10585, 10591, + 10597, 10603, 10609, 10615, 10621, 10627, 10633, 0, + + 10639, 10643, 10647, 10651, 10655, 10659, 10663, 10667, + 10671, 10675, 10679, 10683, 10687, 10691, 10695, 10699, + 10703, 10707, 10711, 10715, 10719, 10723, 10727, 10731, + 10735, 10739, 10743, 10747, 10751, 10755, 10759, 10763, + 10767, 10771, 10775, 10779, 10783, 10787, 10791, 10795, + 10799, 10803, 10807, 10811, 10815, 10819, 10823, 10827, + 10831, 10835, 10839, 10843, 10847, 10851, 10855, 10859, + 10863, 10867, 10871, 10875, 10879, 10883, 10887, 10891, + 10895, 10899, 10903, 10907, 10911, 10915, 10919, 10923, + 10927, 10931, 10935, 10939, 10943, 10947, 10951, 10955, + 10959, 10963, 10967, 10971, 10975, 10979, 10983, 10987, + 10991, 10995, 10999, 11003, 11007, 11011, 11015, 11019, + 11023, 11027, 11031, 11035, 11039, 11043, 11047, 11051, + 11055, 11059, 11063, 11067, 11071, 11075, 11079, 11083, + 11087, 11091, 11095, 11099, 11103, 11107, 11111, 11115, + 11119, 11123, 11127, 11131, 11135, 11139, 11143, 11147, + 11151, 11155, 11159, 11163, 11167, 11171, 11175, 11179, + 11183, 11187, 11191, 11195, 11199, 11203, 11207, 11211, + 11215, 11219, 11223, 11227, 11231, 11235, 11239, 11243, + 11247, 11251, 11255, 11259, 11263, 11267, 11271, 11275, + 11279, 11283, 11287, 11291, 11295, 11299, 11303, 11307, + 11311, 11315, 11319, 11323, 11327, 11331, 11335, 11339, + 11343, 11347, 11351, 11355, 11359, 11363, 11367, 11371, + 11375, 11379, 11383, 11387, 11391, 11395, 11399, 11403, + 11407, 11411, 11415, 11419, 11423, 11427, 11431, 11435, + 11439, 11443, 11447, 11451, 11455, 11459, 11463, 11467, + 11471, 11475, 11479, 11483, 11487, 11491, 11495, 11499, + 11503, 11507, 11511, 11515, 11519, 11523, 11527, 11531, + 11535, 11539, 11543, 11547, 11551, 11555, 11559, 11563, + 11567, 11571, 11575, 11579, 11583, 11587, 11591, 11595, + 11599, 11603, 11607, 11611, 11615, 11619, 11623, 11627, + 11631, 11635, 11639, 11643, 11647, 11651, 11655, 11659, + + 11663, 11667, 11671, 11675, 11679, 11683, 11687, 11691, + 11695, 11699, 11703, 11707, 11711, 11715, 0, 0, + 11719, 0, 11723, 0, 0, 11727, 11731, 11735, + 11739, 11743, 11747, 11751, 11755, 11759, 11763, 0, + 11767, 0, 11771, 0, 0, 11775, 11779, 0, + 0, 0, 11783, 11787, 11791, 11795, 0, 0, + 11799, 11803, 11807, 11811, 11815, 11819, 11823, 11827, + 11831, 11835, 11839, 11843, 11847, 11851, 11855, 11859, + 11863, 11867, 11871, 11875, 11879, 11883, 11887, 11891, + 11895, 11899, 11903, 11907, 11911, 11915, 11919, 11923, + 11927, 11931, 11935, 11939, 11943, 11947, 11951, 11955, + 11959, 11963, 11967, 11971, 11975, 11979, 11983, 11987, + 11991, 11995, 11999, 12003, 12007, 12011, 12015, 12019, + 12023, 12027, 12031, 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, 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, + + 12035, 12040, 12045, 12050, 12056, 12062, 12067, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 12072, 12077, 12082, 12087, 12092, + 0, 0, 0, 0, 0, 12097, 0, 12102, + 12107, 12111, 12115, 12119, 12123, 12127, 12131, 12135, + 12139, 12143, 12147, 12152, 12157, 12162, 12167, 12172, + 12177, 12182, 12187, 12192, 12197, 12202, 12207, 0, + 12212, 12217, 12222, 12227, 12232, 0, 12237, 0, + 12242, 12247, 0, 12252, 12257, 0, 12262, 12267, + 12272, 12277, 12282, 12287, 12292, 12297, 12302, 12307, + 12312, 12316, 12320, 12324, 12328, 12332, 12336, 12340, + 12344, 12348, 12352, 12356, 12360, 12364, 12368, 12372, + 12376, 12380, 12384, 12388, 12392, 12396, 12400, 12404, + 12408, 12412, 12416, 12420, 12424, 12428, 12432, 12436, + 12440, 12444, 12448, 12452, 12456, 12460, 12464, 12468, + 12472, 12476, 12480, 12484, 12488, 12492, 12496, 12500, + 12504, 12508, 12512, 12516, 12520, 12524, 12528, 12532, + 12536, 12540, 12544, 12548, 12552, 12556, 12560, 12564, + 12568, 12572, 12576, 12580, 12584, 12588, 12592, 12596, + 12600, 12604, 12608, 12612, 12616, 12620, 12624, 12628, + 12632, 12636, 12640, 12644, 12648, 12652, 12656, 12660, + 12664, 12668, 12672, 12676, 12680, 12684, 12688, 12692, + 12696, 12700, 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, 12704, 12708, 12712, 12716, 12720, + 12724, 12728, 12732, 12736, 12740, 12744, 12748, 12752, + 12756, 12760, 12764, 12768, 12772, 12776, 12780, 12784, + 12788, 12792, 12796, 12801, 12806, 12811, 12816, 12821, + 12826, 12831, 12836, 12841, 12846, 12851, 12856, 12861, + 12866, 12871, 12876, 12881, 12886, 12890, 12894, 12898, + + 12902, 12907, 12912, 12917, 12922, 12927, 12932, 12937, + 12942, 12947, 12952, 12957, 12962, 12967, 12972, 12977, + 12982, 12987, 12992, 12997, 13002, 13007, 13012, 13017, + 13022, 13027, 13032, 13037, 13042, 13047, 13052, 13057, + 13062, 13067, 13072, 13077, 13082, 13087, 13092, 13097, + 13102, 13107, 13112, 13117, 13122, 13127, 13132, 13137, + 13142, 13147, 13152, 13157, 13162, 13167, 13172, 13177, + 13182, 13187, 13192, 13197, 13202, 13207, 13212, 13217, + 13222, 13227, 13232, 13237, 13242, 13247, 13252, 13257, + 13262, 13267, 13272, 13277, 13282, 13287, 13292, 13297, + 13302, 13307, 13312, 13317, 13322, 13327, 13332, 13337, + 13342, 13347, 13352, 13357, 13362, 13367, 13372, 13378, + 13384, 13390, 13396, 13402, 13408, 13413, 13418, 13423, + 13428, 13433, 13438, 13443, 13448, 13453, 13458, 13463, + 13468, 13473, 13478, 13483, 13488, 13493, 13498, 13503, + 13508, 13513, 13518, 13523, 13528, 13533, 13538, 13543, + 13548, 13553, 13558, 13563, 13568, 13573, 13578, 13583, + 13588, 13593, 13598, 13603, 13608, 13613, 13618, 13623, + 13628, 13633, 13638, 13643, 13648, 13653, 13658, 13663, + 13668, 13673, 13678, 13683, 13688, 13693, 13698, 13703, + 13708, 13713, 13718, 13723, 13728, 13733, 13738, 13743, + 13748, 13753, 13758, 13763, 13768, 13773, 13778, 13783, + 13788, 13793, 13798, 13803, 13808, 13813, 13818, 13823, + 13828, 13833, 13838, 13843, 13848, 13853, 13858, 13863, + 13868, 13873, 13878, 13883, 13888, 13893, 13898, 13903, + 13908, 13913, 13918, 13923, 13928, 13933, 13938, 13943, + 13948, 13953, 13958, 13963, 13968, 13973, 13978, 13983, + 13988, 13993, 13998, 14003, 14008, 14013, 14018, 14023, + 14028, 14033, 14038, 14043, 14048, 14053, 14058, 14063, + 14068, 14073, 14078, 14083, 14088, 14093, 14098, 14103, + 14108, 14113, 14118, 14124, 14130, 14136, 14141, 14146, + 14151, 14156, 14161, 14166, 14171, 14176, 14181, 14186, + + 14191, 14196, 14201, 14206, 14211, 14216, 14221, 14226, + 14231, 14236, 14241, 14246, 14251, 14256, 14261, 14266, + 14271, 14276, 14281, 14286, 14291, 14296, 14301, 14306, + 14311, 14316, 14321, 14326, 14331, 14336, 14341, 14346, + 14351, 14356, 14361, 14366, 14371, 14376, 14381, 14386, + 14391, 14396, 14401, 14406, 14411, 14416, 14421, 14426, + 14431, 14436, 14441, 14446, 14451, 14456, 14461, 14466, + 14471, 14476, 14481, 14486, 14491, 14496, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 14501, 14507, 14513, 14519, 14525, 14531, 14537, 14543, + 14549, 14555, 14561, 14567, 14573, 14579, 14585, 14591, + 14597, 14603, 14609, 14615, 14621, 14627, 14633, 14639, + 14645, 14651, 14657, 14663, 14669, 14675, 14681, 14687, + 14693, 14699, 14705, 14711, 14717, 14723, 14729, 14735, + 14741, 14747, 14753, 14759, 14765, 14771, 14777, 14783, + 14789, 14795, 14801, 14807, 14813, 14819, 14825, 14831, + 14837, 14843, 14849, 14855, 14861, 14867, 14873, 14879, + 0, 0, 14885, 14891, 14897, 14903, 14909, 14915, + 14921, 14927, 14933, 14939, 14945, 14951, 14957, 14963, + 14969, 14975, 14981, 14987, 14993, 14999, 15005, 15011, + 15017, 15023, 15029, 15035, 15041, 15047, 15053, 15059, + 15065, 15071, 15077, 15083, 15089, 15095, 15101, 15107, + 15113, 15119, 15125, 15131, 15137, 15143, 15149, 15155, + 15161, 15167, 15173, 15179, 15185, 15191, 15197, 15203, + 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, + 15209, 15215, 15221, 15228, 15235, 15242, 15249, 15256, + 15263, 15270, 15276, 15297, 15308, 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, + 15315, 15319, 15323, 15327, 15331, 15335, 15339, 15343, + 15347, 15351, 15355, 15359, 15363, 15367, 15371, 15375, + 15379, 15383, 15387, 15391, 15395, 0, 0, 0, + 0, 15399, 15403, 15407, 15411, 15415, 15419, 15423, + 15427, 15431, 15435, 0, 15439, 15443, 15447, 15451, + 15455, 15459, 15463, 15467, 15471, 15475, 15479, 15483, + 15487, 15491, 15495, 15499, 15503, 15507, 15511, 0, + 15515, 15519, 15523, 15527, 0, 0, 0, 0, + 15531, 15536, 15541, 0, 15546, 0, 15551, 15556, + 15561, 15566, 15571, 15576, 15581, 15586, 15591, 15596, + 15601, 15605, 15609, 15613, 15617, 15621, 15625, 15629, + 15633, 15637, 15641, 15645, 15649, 15653, 15657, 15661, + 15665, 15669, 15673, 15677, 15681, 15685, 15689, 15693, + 15697, 15701, 15705, 15709, 15713, 15717, 15721, 15725, + 15729, 15733, 15737, 15741, 15745, 15749, 15753, 15757, + 15761, 15765, 15769, 15773, 15777, 15781, 15785, 15789, + 15793, 15797, 15801, 15805, 15809, 15813, 15817, 15821, + 15825, 15829, 15833, 15837, 15841, 15845, 15849, 15853, + 15857, 15861, 15865, 15869, 15873, 15877, 15881, 15885, + 15889, 15893, 15897, 15901, 15905, 15909, 15913, 15917, + 15921, 15925, 15929, 15933, 15937, 15941, 15945, 15949, + 15953, 15957, 15961, 15965, 15969, 15973, 15977, 15981, + 15985, 15989, 15993, 15997, 16001, 16005, 16009, 16013, + 16017, 16021, 16025, 16029, 16033, 16037, 16041, 16045, + 16049, 16053, 16057, 16061, 16065, 16069, 16074, 16079, + 16084, 16089, 16094, 16099, 16104, 0, 0, 0, + + 0, 16109, 16113, 16117, 16121, 16125, 16129, 16133, + 16137, 16141, 16145, 16149, 16153, 16157, 16161, 16165, + 16169, 16173, 16177, 16181, 16185, 16189, 16193, 16197, + 16201, 16205, 16209, 16213, 16217, 16221, 16225, 16229, + 16233, 16237, 16241, 16245, 16249, 16253, 16257, 16261, + 16265, 16269, 16273, 16277, 16281, 16285, 16289, 16293, + 16297, 16301, 16305, 16309, 16313, 16317, 16321, 16325, + 16329, 16333, 16337, 16341, 16345, 16349, 16353, 16357, + 16361, 16365, 16369, 16373, 16377, 16381, 16385, 16389, + 16393, 16397, 16401, 16405, 16409, 16413, 16417, 16421, + 16425, 16429, 16433, 16437, 16441, 16445, 16449, 16453, + 16457, 16461, 16465, 16469, 16473, 16477, 16481, 16485, + 16489, 16493, 16497, 16501, 16505, 16509, 16513, 16517, + 16521, 16525, 16529, 16533, 16537, 16541, 16545, 16549, + 16553, 16557, 16561, 16565, 16569, 16573, 16577, 16581, + 16585, 16589, 16593, 16597, 16601, 16605, 16609, 16613, + 16617, 16621, 16625, 16629, 16633, 16637, 16641, 16645, + 16649, 16653, 16657, 16661, 16665, 16669, 16673, 16677, + 16681, 16685, 16689, 16693, 16697, 16701, 16705, 16709, + 16713, 16717, 16721, 16725, 16729, 16733, 16737, 16741, + 16745, 16749, 16753, 16757, 16761, 16765, 16769, 16773, + 16777, 16781, 16785, 16789, 16793, 16797, 16801, 16805, + 16809, 16813, 16817, 16821, 16825, 16829, 16833, 16837, + 16841, 16845, 16849, 16853, 16857, 16861, 16865, 0, + 0, 0, 16869, 16873, 16877, 16881, 16885, 16889, + 0, 0, 16893, 16897, 16901, 16905, 16909, 16913, + 0, 0, 16917, 16921, 16925, 16929, 16933, 16937, + 0, 0, 16941, 16945, 16949, 0, 0, 0, + 16953, 16957, 16961, 16965, 16969, 16973, 16977, 0, + 16981, 16985, 16989, 16993, 16997, 17001, 17005, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +// 67552 bytes + +const Q_UINT16 QUnicodeTables::ligature_map[] = { + 0, + 5567, 0, + 5552, 0, + 5572, 0, + 67, 72, 77, 82, 87, 92, 332, 342, 352, 966, 1196, 1206, 1346, 2365, 3145, 3155, 0, + 2375, 2385, 2395, 0, + 97, 362, 372, 382, 392, 0, + 402, 2415, 2425, 2435, 2445, 2455, 0, + 102, 107, 112, 117, 412, 422, 432, 442, 452, 1216, 1226, 1356, 2485, 2495, 3265, 3275, 3285, 0, + 2515, 0, + 462, 472, 482, 492, 1076, 1146, 2525, 0, + 502, 1336, 2535, 2545, 2555, 2565, 2575, 0, + 122, 127, 132, 137, 512, 522, 532, 542, 552, 976, 1236, 1246, 2585, 3345, 3355, 0, + 567, 0, + 577, 1086, 2605, 2615, 2625, 0, + 587, 597, 607, 2635, 2655, 2665, 0, + 2675, 2685, 2695, 0, + 142, 627, 637, 647, 1156, 2705, 2715, 2725, 2735, 0, + 147, 152, 157, 162, 167, 662, 672, 682, 901, 986, 1096, 1256, 1266, 1386, 3365, 3375, 0, + 2785, 2795, 0, + 692, 702, 712, 1276, 1286, 2805, 2815, 2835, 0, + 722, 732, 742, 752, 1316, 2845, 2855, 0, + 762, 772, 1326, 2895, 2905, 2915, 2925, 0, + 172, 177, 182, 187, 782, 792, 802, 812, 822, 832, 911, 996, 1296, 1306, 2935, 2945, 2955, 3485, 3495, 0, + 2985, 2995, 0, + 842, 3005, 3015, 3025, 3035, 3045, 0, + 3055, 3065, 0, + 192, 852, 862, 1406, 3075, 3555, 3565, 3575, 3585, 0, + 867, 877, 887, 3085, 3095, 3105, 0, + 197, 202, 207, 212, 217, 222, 337, 347, 357, 971, 1201, 1211, 1351, 2370, 3150, 3160, 0, + 2380, 2390, 2400, 0, + 227, 367, 377, 387, 397, 0, + 407, 2420, 2430, 2440, 2450, 2460, 0, + 232, 237, 242, 247, 417, 427, 437, 447, 457, 1221, 1231, 1361, 2490, 2500, 3270, 3280, 3290, 0, + 2520, 0, + 467, 477, 487, 497, 1081, 1151, 2530, 0, + 507, 1341, 2540, 2550, 2560, 2570, 2580, 3115, 0, + 252, 257, 262, 267, 517, 527, 537, 547, 981, 1241, 1251, 2590, 3350, 3360, 0, + 572, 1126, 0, + 582, 1091, 2610, 2620, 2630, 0, + 592, 602, 612, 2640, 2660, 2670, 0, + 2680, 2690, 2700, 0, + 272, 632, 642, 652, 1161, 2710, 2720, 2730, 2740, 0, + 277, 282, 287, 292, 297, 667, 677, 687, 906, 991, 1101, 1261, 1271, 1391, 3370, 3380, 0, + 2790, 2800, 0, + 697, 707, 717, 1281, 1291, 2810, 2820, 2840, 0, + 727, 737, 747, 757, 1321, 2850, 2860, 0, + 767, 777, 1331, 2900, 2910, 2920, 2930, 3120, 0, + 302, 307, 312, 317, 787, 797, 807, 817, 827, 837, 916, 1001, 1301, 1311, 2940, 2950, 2960, 3490, 3500, 0, + 2990, 3000, 0, + 847, 3010, 3020, 3030, 3040, 3050, 3125, 0, + 3060, 3070, 0, + 322, 327, 857, 1411, 3080, 3130, 3560, 3570, 3580, 3590, 0, + 872, 882, 892, 3090, 3100, 3110, 0, + 1537, 4476, 4670, 0, + 3165, 3175, 3185, 3195, 0, + 1046, 0, + 1166, 0, + 1066, 1176, 0, + 2405, 0, + 3295, 3305, 3315, 3325, 0, + 2595, 0, + 3385, 3395, 3405, 3415, 0, + 1376, 2745, 2755, 0, + 1366, 0, + 1186, 0, + 1006, 1016, 1026, 1036, 0, + 3170, 3180, 3190, 3200, 0, + 1051, 0, + 1171, 0, + 1071, 1181, 0, + 2410, 0, + 3300, 3310, 3320, 3330, 0, + 2600, 0, + 3390, 3400, 3410, 3420, 0, + 1381, 2750, 2760, 0, + 1371, 0, + 1191, 0, + 1011, 1021, 1031, 1041, 0, + 3215, 3225, 3235, 3245, 0, + 3220, 3230, 3240, 3250, 0, + 2465, 2475, 0, + 2470, 2480, 0, + 2765, 2775, 0, + 2770, 2780, 0, + 2865, 0, + 2870, 0, + 2875, 0, + 2880, 0, + 2965, 0, + 2970, 0, + 2975, 0, + 2980, 0, + 3140, 0, + 3435, 3445, 3455, 3465, 3475, 0, + 3440, 3450, 3460, 3470, 3480, 0, + 3505, 3515, 3525, 3535, 3545, 0, + 3510, 3520, 3530, 3540, 3550, 0, + 1116, 0, + 1106, 0, + 1111, 0, + 1056, 0, + 1061, 0, + 2505, 0, + 2510, 0, + 1396, 0, + 1401, 0, + 1121, 0, + 1514, 0, + 1542, 3635, 3640, 4433, 4438, 4443, 4452, 0, + 1551, 3705, 3710, 4506, 0, + 1556, 3775, 3780, 4515, 4524, 0, + 1561, 1586, 3855, 3860, 4573, 4578, 4583, 0, + 1566, 3925, 3930, 4708, 0, + 4665, 0, + 1571, 1591, 3995, 4646, 4651, 4656, 0, + 1576, 4055, 4060, 4717, 4726, 0, + 4418, 0, + 4491, 0, + 1596, 3595, 3600, 4095, 4398, 4403, 4413, 4423, 0, + 1601, 3675, 3680, 4104, 0, + 1606, 3735, 3740, 4113, 4486, 4496, 0, + 1611, 1621, 3815, 3820, 4122, 4544, 4549, 4563, 0, + 1631, 3895, 3900, 4131, 0, + 4626, 4631, 0, + 1626, 1636, 3955, 3960, 4140, 4607, 4612, 4636, 0, + 1641, 4015, 4020, 4149, 4688, 4698, 0, + 1581, 4554, 4568, 0, + 1616, 4617, 4641, 0, + 4693, 0, + 1658, 1663, 0, + 1711, 0, + 1796, 1806, 0, + 1706, 0, + 1696, 1701, 1816, 0, + 1786, 1836, 0, + 1846, 0, + 1721, 1731, 1856, 1866, 0, + 1716, 0, + 1876, 0, + 1726, 1906, 1916, 1926, 0, + 1936, 0, + 1946, 0, + 1896, 0, + 1801, 1811, 0, + 1751, 0, + 1741, 1746, 1821, 0, + 1791, 1841, 0, + 1851, 0, + 1736, 1766, 1861, 1871, 0, + 1761, 0, + 1881, 0, + 1771, 1911, 1921, 1931, 0, + 1941, 0, + 1951, 0, + 1901, 0, + 1756, 0, + 1776, 0, + 1781, 0, + 1826, 0, + 1831, 0, + 1886, 0, + 1891, 0, + 12167, 12172, 12177, 0, + 12182, 12292, 0, + 12187, 0, + 12192, 0, + 12197, 0, + 12202, 12287, 0, + 12207, 0, + 12212, 0, + 12097, 12217, 0, + 12222, 0, + 12227, 12297, 0, + 12232, 0, + 12237, 0, + 12242, 0, + 12247, 0, + 12252, 0, + 12257, 12302, 0, + 12262, 0, + 12267, 0, + 12272, 0, + 12147, 12152, 12277, 0, + 12282, 0, + 12102, 0, + 1961, 1966, 1976, 0, + 1971, 0, + 1981, 0, + 2011, 0, + 2016, 0, + 2006, 0, + 2036, 0, + 2041, 0, + 2046, 0, + 2051, 0, + 2056, 0, + 2061, 0, + 2021, 0, + 2066, 0, + 2071, 0, + 2026, 0, + 2031, 0, + 2086, 0, + 2091, 0, + 2096, 0, + 2076, 2081, 0, + 2111, 0, + 2116, 0, + 2121, 0, + 2126, 0, + 2101, 0, + 2106, 0, + 2146, 0, + 2151, 0, + 2131, 2136, 2141, 0, + 2156, 0, + 2161, 2171, 0, + 2166, 0, + 2176, 0, + 2181, 0, + 2186, 2191, 2196, 0, + 2201, 0, + 2206, 2216, 0, + 2211, 0, + 2221, 2226, 2236, 0, + 2231, 0, + 2290, 0, + 2265, 0, + 2270, 0, + 2275, 0, + 2280, 0, + 2285, 0, + 2295, 2300, 2325, 0, + 2355, 0, + 2330, 0, + 2335, 0, + 2340, 0, + 2345, 0, + 2350, 0, + 2305, 0, + 2315, 0, + 2360, 0, + 2645, 0, + 2650, 0, + 2825, 0, + 2830, 0, + 2885, 0, + 2890, 0, + 3205, 3255, 0, + 3210, 3260, 0, + 3335, 0, + 3340, 0, + 3425, 0, + 3430, 0, + 3605, 3615, 3625, 4158, 0, + 3610, 3620, 3630, 4163, 0, + 4168, 0, + 4173, 0, + 4178, 0, + 4183, 0, + 4188, 0, + 4193, 0, + 3645, 3655, 3665, 4198, 0, + 3650, 3660, 3670, 4203, 0, + 4208, 0, + 4213, 0, + 4218, 0, + 4223, 0, + 4228, 0, + 4233, 0, + 3685, 3695, 0, + 3690, 3700, 0, + 3715, 3725, 0, + 3720, 3730, 0, + 3745, 3755, 3765, 4238, 0, + 3750, 3760, 3770, 4243, 0, + 4248, 0, + 4253, 0, + 4258, 0, + 4263, 0, + 4268, 0, + 4273, 0, + 3785, 3795, 3805, 4278, 0, + 3790, 3800, 3810, 4283, 0, + 4288, 0, + 4293, 0, + 4298, 0, + 4303, 0, + 4308, 0, + 4313, 0, + 3825, 3835, 3845, 0, + 3830, 3840, 3850, 0, + 3865, 3875, 3885, 0, + 3870, 3880, 3890, 0, + 3905, 3915, 0, + 3910, 3920, 0, + 3935, 3945, 0, + 3940, 3950, 0, + 3965, 3975, 3985, 0, + 3970, 3980, 3990, 0, + 4000, 4005, 4010, 0, + 4025, 4035, 4045, 4318, 0, + 4030, 4040, 4050, 4323, 0, + 4328, 0, + 4333, 0, + 4338, 0, + 4343, 0, + 4348, 0, + 4353, 0, + 4065, 4075, 4085, 4358, 0, + 4070, 4080, 4090, 4363, 0, + 4368, 0, + 4373, 0, + 4378, 0, + 4383, 0, + 4388, 0, + 4393, 0, + 4408, 0, + 4481, 0, + 4683, 0, + 4428, 0, + 4529, 4534, 4539, 0, + 4501, 0, + 4703, 0, + 4592, 4597, 4602, 0, + 5455, 0, + 5460, 0, + 5465, 0, + 5470, 0, + 5480, 0, + 5475, 0, + 5485, 0, + 5490, 0, + 5495, 0, + 5500, 0, + 5505, 0, + 5532, 0, + 5537, 0, + 5542, 0, + 5547, 0, + 5562, 0, + 5557, 0, + 5577, 0, + 5582, 0, + 5587, 0, + 5592, 0, + 5597, 0, + 5602, 0, + 5607, 0, + 5612, 0, + 5657, 0, + 5662, 0, + 5617, 0, + 5622, 0, + 5627, 0, + 5632, 0, + 5667, 0, + 5672, 0, + 5637, 0, + 5642, 0, + 5647, 0, + 5652, 0, + 5677, 0, + 5682, 0, + 5687, 0, + 5692, 0, + 6430, 0, + 7444, 0, + 7319, 0, + 7324, 0, + 7329, 0, + 7334, 0, + 7339, 0, + 7344, 0, + 7349, 0, + 7354, 0, + 7359, 0, + 7364, 0, + 7369, 0, + 7374, 0, + 7379, 0, + 7384, 0, + 7389, 0, + 7394, 7399, 0, + 7404, 7409, 0, + 7414, 7419, 0, + 7424, 7429, 0, + 7434, 7439, 0, + 7459, 0, + 7594, 0, + 7469, 0, + 7474, 0, + 7479, 0, + 7484, 0, + 7489, 0, + 7494, 0, + 7499, 0, + 7504, 0, + 7509, 0, + 7514, 0, + 7519, 0, + 7524, 0, + 7529, 0, + 7534, 0, + 7539, 0, + 7544, 7549, 0, + 7554, 7559, 0, + 7564, 7569, 0, + 7574, 7579, 0, + 7584, 7589, 0, + 7599, 0, + 7604, 0, + 7609, 0, + 7614, 0, + 7619, 0, + 12157, 12162, 0, + +}; + +const Q_UINT16 QUnicodeTables::ligature_info[] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 8, 9, 10, 11, 12, 13, 8, 14, + 15, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 16, 17, + 8, 18, 19, 8, 8, 8, 8, 8, + 8, 8, 20, 8, 8, 8, 8, 8, + 21, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 22, 8, 8, 8, 8, + + + 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, 1, 3, 5, 0, + 0, 7, 24, 28, 34, 41, 59, 61, + 69, 77, 93, 95, 101, 108, 112, 122, + 139, 0, 142, 151, 159, 167, 187, 190, + 197, 200, 210, 0, 0, 0, 0, 0, + 0, 217, 234, 238, 244, 251, 269, 271, + 279, 288, 303, 306, 312, 319, 323, 333, + 350, 0, 353, 362, 370, 379, 399, 402, + 410, 413, 424, 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, + 431, 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, 435, 0, 440, 442, 444, 447, + 0, 0, 449, 0, 0, 0, 0, 454, + 0, 0, 0, 0, 456, 461, 465, 0, + 467, 0, 0, 0, 469, 0, 0, 0, + 0, 0, 474, 0, 479, 481, 483, 486, + 0, 0, 488, 0, 0, 0, 0, 493, + 0, 0, 0, 0, 495, 500, 504, 0, + 506, 0, 0, 0, 508, 0, 0, 0, + + 0, 0, 513, 518, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 523, 526, 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, 529, 532, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 535, 537, 0, 0, 0, 0, + 539, 541, 0, 0, 0, 0, 0, 0, + 543, 545, 547, 549, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 551, + 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, + 553, 559, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 565, + 571, 0, 0, 0, 0, 0, 0, 577, + 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, 579, 581, 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, 583, 585, + 587, 589, 0, 0, 0, 0, 591, 593, + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 595, 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, 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, + 597, 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, + 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, 599, 0, 0, 0, 607, 0, 612, + 0, 618, 0, 0, 0, 0, 0, 626, + 0, 631, 0, 0, 0, 633, 0, 0, + 0, 640, 0, 0, 646, 0, 648, 0, + 0, 650, 0, 0, 0, 659, 0, 664, + 0, 671, 0, 0, 0, 0, 0, 680, + 0, 685, 0, 0, 0, 688, 0, 0, + 0, 697, 704, 708, 0, 0, 712, 0, + 0, 0, 714, 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, 717, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 719, 0, 0, 722, 0, 724, 728, 731, + 733, 0, 738, 0, 0, 0, 740, 0, + 0, 0, 0, 742, 0, 0, 0, 747, + 0, 0, 0, 749, 0, 751, 0, 0, + 753, 0, 0, 756, 0, 758, 762, 765, + 767, 0, 772, 0, 0, 0, 774, 0, + 0, 0, 0, 776, 0, 0, 0, 781, + 0, 0, 0, 783, 0, 785, 0, 0, + 0, 0, 0, 0, 0, 0, 787, 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, 789, 791, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 793, 795, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 797, 799, 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, 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, + 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, + 801, 805, 808, 810, 812, 814, 817, 0, + 819, 821, 824, 826, 829, 0, 831, 0, + 833, 835, 0, 837, 839, 0, 842, 844, + 846, 848, 852, 0, 0, 0, 0, 0, + 0, 0, 854, 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, 856, + 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, + 860, 0, 862, 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, 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, 864, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 866, 0, 0, 868, 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, 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, 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, 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, 0, 0, 0, 870, 872, 874, + 0, 0, 0, 0, 876, 0, 0, 0, + 0, 878, 880, 0, 0, 0, 0, 0, + 882, 0, 0, 884, 0, 0, 0, 886, + 888, 0, 0, 890, 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, 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, 892, 894, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 896, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 898, + 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, 901, 903, + 0, 0, 0, 0, 905, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 907, 0, 0, 0, 0, + 0, 0, 909, 0, 0, 0, 0, 0, + 911, 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, + 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, 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, 913, 915, 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, 917, + 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, 921, 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, 923, 926, + 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, 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, 928, 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, 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, 930, + 0, 0, 0, 0, 0, 0, 932, 0, + 0, 0, 936, 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, 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, 938, 941, + 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, 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, 943, 0, 0, 947, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 949, 0, 951, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 953, 0, 0, 0, + 0, 955, 0, 0, 0, 0, 957, 0, + 0, 0, 0, 959, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 961, 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, + 965, 0, 967, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 969, 0, 0, 0, + 0, 971, 0, 0, 0, 0, 973, 0, + 0, 0, 0, 975, 0, 0, 0, 0, + 0, 0, 977, 979, 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, 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, 981, 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, 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, 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, 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, 983, 985, + 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, 987, 989, 0, 0, 0, 0, + 0, 0, 991, 993, 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, + 995, 998, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1001, 1003, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1005, 1007, 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, + + 1009, 1014, 1019, 1021, 1023, 1025, 1027, 1029, + 1031, 1036, 1041, 1043, 1045, 1047, 1049, 1051, + 1053, 1056, 0, 0, 0, 0, 0, 0, + 1059, 1062, 0, 0, 0, 0, 0, 0, + 1065, 1070, 1075, 1077, 1079, 1081, 1083, 1085, + 1087, 1092, 1097, 1099, 1101, 1103, 1105, 1107, + 1109, 1113, 0, 0, 0, 0, 0, 0, + 1117, 1121, 0, 0, 0, 0, 0, 0, + 1125, 1128, 0, 0, 0, 0, 0, 0, + 1131, 1134, 0, 0, 0, 0, 0, 0, + 1137, 1141, 0, 0, 0, 0, 0, 0, + 0, 1145, 0, 0, 0, 0, 0, 0, + 1149, 1154, 1159, 1161, 1163, 1165, 1167, 1169, + 1171, 1176, 1181, 1183, 1185, 1187, 1189, 1191, + 1193, 0, 0, 0, 1195, 0, 0, 0, + 0, 0, 0, 0, 1197, 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, 1199, 0, + 0, 0, 0, 0, 0, 0, 0, 1201, + 0, 0, 0, 0, 0, 0, 1205, 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, 1207, 0, + 0, 0, 0, 0, 0, 0, 1209, 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, 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, + 1213, 0, 1215, 0, 1217, 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, + 1219, 0, 1221, 0, 1223, 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, 1225, 0, 0, 0, 0, + 1227, 0, 0, 1229, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1231, 0, 1233, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1235, 0, 0, 0, + 0, 0, 0, 1237, 0, 1239, 0, 0, + 1241, 0, 0, 0, 0, 1243, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1245, 0, 0, 1247, 1249, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1251, 1253, 0, 0, 1255, 1257, + 0, 0, 1259, 1261, 1263, 1265, 0, 0, + 0, 0, 1267, 1269, 0, 0, 1271, 1273, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1275, 1277, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1279, 0, 0, 0, 0, 0, + 1281, 1283, 0, 1285, 0, 0, 0, 0, + 0, 0, 1287, 1289, 1291, 1293, 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, 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, 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, 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, 1295, 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, 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, 1297, 0, + 0, 0, 0, 1299, 0, 1301, 0, 1303, + 0, 1305, 0, 1307, 0, 1309, 0, 1311, + 0, 1313, 0, 1315, 0, 1317, 0, 1319, + 0, 1321, 0, 0, 1323, 0, 1325, 0, + 1327, 0, 0, 0, 0, 0, 0, 1329, + 0, 0, 1332, 0, 0, 1335, 0, 0, + 1338, 0, 0, 1341, 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, 1344, 0, 0, + 0, 0, 0, 0, 0, 0, 1346, 0, + 0, 0, 0, 1348, 0, 1350, 0, 1352, + 0, 1354, 0, 1356, 0, 1358, 0, 1360, + 0, 1362, 0, 1364, 0, 1366, 0, 1368, + 0, 1370, 0, 0, 1372, 0, 1374, 0, + 1376, 0, 0, 0, 0, 0, 0, 1378, + 0, 0, 1381, 0, 0, 1384, 0, 0, + 1387, 0, 0, 1390, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1393, + 1395, 1397, 1399, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1401, 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, 1403, 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, 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +// 14586 bytes + +const Q_UINT8 QUnicodeTables::direction_info[] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 2, 9, 10, 11, 12, 13, 14, 15, + 16, 2, 2, 2, 2, 2, 17, 18, + 19, 2, 2, 2, 2, 2, 2, 20, + 21, 22, 23, 24, 25, 26, 27, 28, + 26, 29, 30, 2, 2, 2, 31, 32, + 33, 2, 34, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 35, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 36, 37, 38, 39, 40, + + + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 8, 7, 8, 9, 7, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 7, 7, 7, 8, + 9, 10, 10, 4, 4, 4, 10, 10, + 138, 138, 10, 4, 6, 4, 6, 3, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 6, 10, 138, 10, 138, 10, + 10, 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, 138, 10, 138, 10, 10, + 10, 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, 138, 10, 138, 10, 18, + 18, 18, 18, 18, 18, 7, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 6, 10, 4, 4, 4, 4, 10, 10, + 10, 10, 0, 138, 10, 10, 10, 10, + 4, 4, 2, 2, 10, 0, 10, 10, + 10, 2, 0, 138, 10, 10, 10, 10, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 10, + 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, 10, + 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, 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, 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, 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, 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, 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, 10, 10, 0, 0, 0, 0, 0, + 0, 0, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 0, 0, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 0, 0, 0, 0, 0, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 0, 0, 10, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 10, 10, 0, 10, + 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, 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, 10, 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, 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, 17, 17, 17, 17, 0, + 17, 17, 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, 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, + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 0, 0, 0, 0, + 0, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 0, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 0, 17, 17, 17, 1, 17, + 1, 17, 17, 1, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 13, 0, 0, 0, 13, + 0, 13, 77, 77, 77, 77, 45, 77, + 45, 77, 45, 45, 45, 45, 45, 77, + 77, 77, 77, 45, 45, 45, 45, 45, + 45, 45, 45, 0, 0, 0, 0, 0, + 109, 45, 45, 45, 45, 45, 45, 45, + 77, 45, 45, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 4, 5, 5, 13, 45, 45, + 17, 77, 77, 77, 13, 77, 77, 77, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 77, 45, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 45, 77, 45, 77, + 45, 45, 77, 77, 13, 77, 17, 17, + 17, 17, 17, 17, 17, 13, 17, 17, + 17, 17, 17, 17, 17, 13, 13, 17, + 17, 10, 17, 17, 17, 17, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 45, 45, 45, 13, 13, 0, + + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 0, 18, + 77, 17, 45, 45, 45, 77, 77, 77, + 77, 77, 45, 45, 45, 45, 77, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 77, 45, 77, 45, 77, 0, 0, 0, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 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, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 13, 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, 17, 17, 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, 17, 0, 0, 0, + 0, 17, 17, 17, 17, 17, 17, 17, + 17, 0, 0, 0, 0, 17, 0, 0, + 0, 17, 17, 17, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 17, 17, 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, 17, 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, 17, 0, 0, 0, + 0, 17, 17, 17, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 17, 17, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 17, 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, 17, 0, 0, 0, + 0, 17, 17, 0, 0, 0, 0, 17, + 17, 0, 0, 17, 17, 17, 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, + 17, 17, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 17, 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, 17, 0, 0, 0, + 0, 17, 17, 17, 17, 17, 0, 17, + 17, 0, 0, 0, 0, 17, 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, 17, 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, 17, 0, 0, 17, + 0, 17, 17, 17, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 0, 0, + 0, 0, 0, 0, 0, 0, 17, 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, 17, 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, + 17, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 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, 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, 17, 17, + 17, 0, 0, 0, 0, 0, 17, 17, + 17, 0, 17, 17, 17, 17, 0, 0, + 0, 0, 0, 0, 0, 17, 17, 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, 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, 17, + 0, 0, 0, 0, 0, 0, 17, 0, + 0, 0, 0, 0, 17, 17, 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, 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, 17, 17, 17, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 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, 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, 17, 0, 0, 0, 0, 0, + 0, 0, 17, 17, 17, 0, 17, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 0, 0, 17, 17, 17, 17, + 17, 17, 17, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 17, + 17, 17, 17, 17, 17, 17, 17, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 0, 0, 17, 17, 17, 17, + 17, 17, 0, 17, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 17, 17, 17, 17, 17, 17, 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, + 17, 17, 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, 17, 0, 17, + 0, 17, 10, 10, 10, 10, 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, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 0, + 17, 17, 17, 17, 17, 0, 17, 17, + 0, 0, 0, 0, 0, 0, 0, 0, + 17, 17, 17, 17, 17, 17, 17, 17, + 0, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 17, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 17, 17, + 17, 0, 17, 0, 0, 0, 17, 17, + 0, 17, 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, + 17, 17, 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, 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, + 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, 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, + 9, 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, 10, 10, 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, 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, 17, 17, 17, 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, 17, 17, 17, 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, 17, 17, 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, 17, 17, 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, 17, + 17, 17, 17, 17, 17, 17, 0, 0, + 0, 0, 0, 0, 0, 0, 17, 0, + 0, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 0, 0, 0, 0, + 0, 0, 0, 4, 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, + + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 17, 17, 17, 18, 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, 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, 17, 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, 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, + 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, 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, 10, 0, 10, + 10, 10, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10, 10, 10, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10, 10, 10, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10, 10, 10, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10, 10, 0, + + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 18, 18, 114, 0, 1, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 9, 7, 11, 14, 16, 12, 15, 9, + 4, 4, 4, 4, 4, 10, 10, 10, + 10, 138, 138, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 138, 138, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 0, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 0, 9, + 18, 18, 18, 18, 0, 0, 0, 0, + 0, 0, 18, 18, 18, 18, 18, 18, + 2, 0, 0, 0, 2, 2, 2, 2, + 2, 2, 4, 4, 10, 138, 138, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 4, 4, 10, 138, 138, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 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, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 10, 10, 0, 10, 10, 10, 10, 0, + 10, 10, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 0, 10, 10, + 10, 0, 0, 0, 0, 0, 10, 10, + 10, 10, 10, 10, 0, 10, 0, 10, + 0, 10, 0, 0, 0, 0, 4, 0, + 0, 0, 10, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 0, 0, 0, 0, + 138, 10, 10, 10, 10, 0, 0, 0, + 0, 0, 10, 10, 0, 0, 0, 0, + 0, 0, 0, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 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, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + + 10, 138, 138, 138, 138, 10, 10, 10, + 138, 138, 138, 138, 138, 138, 10, 10, + 10, 138, 4, 4, 10, 138, 138, 10, + 10, 10, 138, 138, 138, 138, 10, 138, + 138, 138, 138, 10, 138, 10, 138, 10, + 10, 10, 10, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 10, 10, 10, 10, + 10, 138, 10, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 10, 10, 10, + 10, 10, 138, 138, 138, 138, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 138, + 138, 10, 138, 10, 138, 138, 138, 138, + 138, 138, 138, 138, 10, 10, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 10, 10, 138, + 138, 138, 138, 10, 10, 10, 10, 10, + 138, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 138, 138, 10, 10, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 10, 10, 10, 10, 10, 138, 138, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 138, 138, 138, 138, 138, 10, 10, + 138, 138, 10, 10, 10, 10, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 10, 10, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + + 10, 10, 10, 10, 10, 10, 10, 10, + 138, 138, 138, 138, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 138, 138, 10, 10, 10, 10, 10, 10, + 10, 138, 138, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 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, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 0, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 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, + + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 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, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 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, 2, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 0, + + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 0, 0, 10, 10, + 0, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 0, 0, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 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, 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, 10, 10, 10, 10, 0, 10, 10, + 10, 10, 0, 0, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 0, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 0, 10, 0, 10, + 10, 10, 10, 0, 0, 0, 10, 0, + 10, 10, 10, 10, 10, 10, 10, 0, + 0, 10, 10, 10, 10, 10, 10, 10, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 0, 0, 0, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 0, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 10, 10, 10, 138, 138, 138, 138, 10, + 10, 10, 10, 10, 138, 138, 138, 10, + 10, 10, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 0, 0, 0, 0, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 10, 10, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 10, 10, 10, 10, 10, 10, 10, 10, + 138, 10, 10, 10, 10, 10, 10, 10, + 138, 138, 138, 138, 138, 138, 10, 10, + 10, 138, 10, 10, 10, 10, 138, 138, + 138, 138, 138, 10, 138, 138, 10, 10, + 138, 138, 138, 138, 138, 10, 10, 10, + 10, 138, 10, 138, 138, 138, 10, 10, + 138, 138, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 138, 138, 138, 138, + 138, 138, 10, 10, 138, 138, 10, 10, + + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 10, 138, 138, + 138, 138, 10, 10, 138, 10, 138, 10, + 10, 138, 10, 138, 138, 138, 138, 10, + 10, 10, 10, 10, 138, 138, 10, 10, + 10, 10, 10, 10, 138, 138, 138, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 138, + 138, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 138, 138, 10, 10, + 10, 10, 138, 138, 138, 138, 10, 138, + 138, 10, 10, 138, 138, 10, 10, 10, + 10, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 10, 10, 138, 138, + 138, 138, 138, 138, 138, 138, 10, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 10, + 10, 10, 10, 10, 138, 10, 138, 10, + 10, 10, 138, 138, 138, 138, 138, 10, + 10, 10, 10, 10, 138, 138, 138, 10, + 10, 10, 10, 138, 10, 10, 10, 138, + 138, 138, 138, 138, 10, 138, 10, 10, + + 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, 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, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 0, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 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, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 0, 0, 0, 0, + + 9, 10, 10, 10, 10, 0, 0, 0, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 10, 10, 138, 138, 138, 138, + 138, 138, 138, 138, 10, 10, 10, 10, + 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 17, 17, 17, 17, 17, 17, + 10, 0, 0, 0, 0, 0, 10, 10, + 0, 0, 0, 0, 0, 10, 10, 10, + 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17, 17, 10, 10, 0, 0, 0, + 10, 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 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, 0, 0, 0, 0, 0, + 0, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 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, 0, + 0, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 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, 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, 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, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 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, 0, 0, + 0, 0, 0, 0, 0, 1, 17, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, 1, 0, + 1, 1, 0, 1, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 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, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 10, 10, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 0, 0, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 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, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 0, 0, 0, + + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 17, 17, 17, 17, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 0, + 0, 10, 10, 10, 10, 10, 10, 10, + 6, 10, 6, 0, 10, 6, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 4, + 10, 10, 4, 4, 10, 10, 10, 0, + 10, 4, 4, 10, 0, 0, 0, 0, + 13, 13, 13, 13, 13, 0, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 0, 0, 18, + + 0, 10, 10, 4, 4, 4, 10, 10, + 138, 138, 10, 4, 6, 4, 6, 3, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 6, 10, 138, 10, 138, 10, + 10, 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, 138, 10, 138, 10, 10, + 10, 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, 138, 10, 138, 10, 138, + 138, 10, 138, 138, 10, 10, 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, 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, + 4, 4, 10, 10, 10, 4, 4, 0, + 10, 10, 10, 10, 10, 10, 10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 18, 18, 10, 10, 0, 0, +}; + +// 25082 bytes + +const Q_UINT8 QUnicodeTables::combining_info[] = { + 1, 1, 1, 2, 3, 4, 5, 6, + 1, 7, 8, 9, 10, 11, 12, 13, + 14, 1, 1, 1, 1, 1, 1, 15, + 16, 1, 1, 1, 1, 1, 1, 1, + 17, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 18, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 19, 1, 1, 20, 1, + + + 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, 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, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 232, 220, 220, + 220, 220, 232, 216, 220, 220, 220, 220, + 220, 202, 202, 220, 220, 220, 220, 202, + 202, 220, 220, 220, 220, 220, 220, 220, + 220, 220, 220, 220, 1, 1, 1, 1, + 1, 220, 220, 220, 220, 230, 230, 230, + 230, 230, 230, 230, 230, 240, 230, 220, + 220, 220, 230, 230, 230, 220, 220, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 234, 234, 233, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 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, 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, 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, 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, 230, 230, 230, 230, 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, 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, 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, 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, 220, 230, 230, 230, 230, 220, 230, + 230, 230, 222, 220, 230, 230, 230, 230, + 230, 230, 0, 220, 220, 220, 220, 220, + 230, 230, 220, 230, 230, 222, 228, 230, + 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 0, 20, 21, 22, 0, 23, + 0, 24, 25, 0, 230, 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, 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, 27, 28, 29, 30, 31, + 32, 33, 34, 230, 230, 220, 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, + 35, 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, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 230, 230, + 230, 230, 230, 230, 230, 0, 0, 230, + 230, 230, 230, 220, 230, 0, 0, 230, + 230, 0, 220, 230, 230, 220, 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, 36, 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, + 230, 220, 230, 230, 220, 230, 230, 220, + 220, 220, 230, 220, 220, 230, 220, 230, + 230, 230, 220, 230, 220, 230, 220, 230, + 220, 230, 230, 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, 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, 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, + 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, + 0, 230, 220, 230, 230, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 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, 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, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 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, 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, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 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, 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, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 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, 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, 9, 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, 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, 9, 0, 0, + 0, 0, 0, 0, 0, 84, 91, 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, 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, 9, 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, 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, 9, 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, 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, 9, 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, 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, + 103, 103, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 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, 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, + 118, 118, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 122, 122, 122, 122, 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, + 220, 220, 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, 220, 0, 220, + 0, 216, 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, 129, 130, 0, 132, 0, 0, 0, + 0, 0, 130, 130, 130, 130, 0, 0, + 130, 0, 230, 230, 9, 0, 230, 230, + 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, 220, 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, 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, 7, + 0, 9, 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, 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, + 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, 9, 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, 9, 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, 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, 9, 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, 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, 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, 228, 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, 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, + 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, 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, + 230, 230, 1, 1, 230, 230, 230, 230, + 1, 1, 1, 230, 230, 0, 0, 0, + 0, 230, 0, 0, 0, 1, 1, 230, + 220, 230, 1, 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, 218, 228, 232, 222, 224, 224, + 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, 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, 8, 8, 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, 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, 26, 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, 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, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 230, 230, 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, 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, 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, +}; + +// 30458 bytes + +const Q_UINT16 QUnicodeTables::case_info[] = { + 1, 2, 3, 4, 5, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 7, 8, + 0, 9, 0, 0, 10, 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, 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, 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, 11, + + + 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, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0, + 0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 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, 0x39c, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x178, + + 0x101, 0x100, 0x103, 0x102, 0x105, 0x104, 0x107, 0x106, + 0x109, 0x108, 0x10b, 0x10a, 0x10d, 0x10c, 0x10f, 0x10e, + 0x111, 0x110, 0x113, 0x112, 0x115, 0x114, 0x117, 0x116, + 0x119, 0x118, 0x11b, 0x11a, 0x11d, 0x11c, 0x11f, 0x11e, + 0x121, 0x120, 0x123, 0x122, 0x125, 0x124, 0x127, 0x126, + 0x129, 0x128, 0x12b, 0x12a, 0x12d, 0x12c, 0x12f, 0x12e, + 0x69, 0x49, 0x133, 0x132, 0x135, 0x134, 0x137, 0x136, + 0, 0x13a, 0x139, 0x13c, 0x13b, 0x13e, 0x13d, 0x140, + 0x13f, 0x142, 0x141, 0x144, 0x143, 0x146, 0x145, 0x148, + 0x147, 0, 0x14b, 0x14a, 0x14d, 0x14c, 0x14f, 0x14e, + 0x151, 0x150, 0x153, 0x152, 0x155, 0x154, 0x157, 0x156, + 0x159, 0x158, 0x15b, 0x15a, 0x15d, 0x15c, 0x15f, 0x15e, + 0x161, 0x160, 0x163, 0x162, 0x165, 0x164, 0x167, 0x166, + 0x169, 0x168, 0x16b, 0x16a, 0x16d, 0x16c, 0x16f, 0x16e, + 0x171, 0x170, 0x173, 0x172, 0x175, 0x174, 0x177, 0x176, + 0xff, 0x17a, 0x179, 0x17c, 0x17b, 0x17e, 0x17d, 0x53, + 0, 0x253, 0x183, 0x182, 0x185, 0x184, 0x254, 0x188, + 0x187, 0x256, 0x257, 0x18c, 0x18b, 0, 0x1dd, 0x259, + 0x25b, 0x192, 0x191, 0x260, 0x263, 0x1f6, 0x269, 0x268, + 0x199, 0x198, 0, 0, 0x26f, 0x272, 0x220, 0x275, + 0x1a1, 0x1a0, 0x1a3, 0x1a2, 0x1a5, 0x1a4, 0x280, 0x1a8, + 0x1a7, 0x283, 0, 0, 0x1ad, 0x1ac, 0x288, 0x1b0, + 0x1af, 0x28a, 0x28b, 0x1b4, 0x1b3, 0x1b6, 0x1b5, 0x292, + 0x1b9, 0x1b8, 0, 0, 0x1bd, 0x1bc, 0, 0x1f7, + 0, 0, 0, 0, 0x1c6, 0x1c4, 0x1c4, 0x1c9, + 0x1c7, 0x1c7, 0x1cc, 0x1ca, 0x1ca, 0x1ce, 0x1cd, 0x1d0, + 0x1cf, 0x1d2, 0x1d1, 0x1d4, 0x1d3, 0x1d6, 0x1d5, 0x1d8, + 0x1d7, 0x1da, 0x1d9, 0x1dc, 0x1db, 0x18e, 0x1df, 0x1de, + 0x1e1, 0x1e0, 0x1e3, 0x1e2, 0x1e5, 0x1e4, 0x1e7, 0x1e6, + 0x1e9, 0x1e8, 0x1eb, 0x1ea, 0x1ed, 0x1ec, 0x1ef, 0x1ee, + 0, 0x1f3, 0x1f1, 0x1f1, 0x1f5, 0x1f4, 0x195, 0x1bf, + 0x1f9, 0x1f8, 0x1fb, 0x1fa, 0x1fd, 0x1fc, 0x1ff, 0x1fe, + + 0x201, 0x200, 0x203, 0x202, 0x205, 0x204, 0x207, 0x206, + 0x209, 0x208, 0x20b, 0x20a, 0x20d, 0x20c, 0x20f, 0x20e, + 0x211, 0x210, 0x213, 0x212, 0x215, 0x214, 0x217, 0x216, + 0x219, 0x218, 0x21b, 0x21a, 0x21d, 0x21c, 0x21f, 0x21e, + 0x19e, 0, 0x223, 0x222, 0x225, 0x224, 0x227, 0x226, + 0x229, 0x228, 0x22b, 0x22a, 0x22d, 0x22c, 0x22f, 0x22e, + 0x231, 0x230, 0x233, 0x232, 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, 0x181, 0x186, 0, 0x189, 0x18a, + 0, 0x18f, 0, 0x190, 0, 0, 0, 0, + 0x193, 0, 0, 0x194, 0, 0, 0, 0, + 0x197, 0x196, 0, 0, 0, 0, 0, 0x19c, + 0, 0, 0x19d, 0, 0, 0x19f, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0x1a6, 0, 0, 0x1a9, 0, 0, 0, 0, + 0x1ae, 0, 0x1b1, 0x1b2, 0, 0, 0, 0, + 0, 0, 0x1b7, 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, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0x399, 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, 0x3ac, 0, + 0x3ad, 0x3ae, 0x3af, 0, 0x3cc, 0, 0x3cd, 0x3ce, + 0, 0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b7, + 0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bc, 0x3bd, 0x3be, 0x3bf, + 0x3c0, 0x3c1, 0, 0x3c3, 0x3c4, 0x3c5, 0x3c6, 0x3c7, + 0x3c8, 0x3c9, 0x3ca, 0x3cb, 0x386, 0x388, 0x389, 0x38a, + 0, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, + 0x398, 0x399, 0x39a, 0x39b, 0x39c, 0x39d, 0x39e, 0x39f, + 0x3a0, 0x3a1, 0x3a3, 0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7, + 0x3a8, 0x3a9, 0x3aa, 0x3ab, 0x38c, 0x38e, 0x38f, 0, + 0x392, 0x398, 0, 0, 0, 0x3a6, 0x3a0, 0, + 0x3d9, 0x3d8, 0x3db, 0x3da, 0x3dd, 0x3dc, 0x3df, 0x3de, + 0x3e1, 0x3e0, 0x3e3, 0x3e2, 0x3e5, 0x3e4, 0x3e7, 0x3e6, + 0x3e9, 0x3e8, 0x3eb, 0x3ea, 0x3ed, 0x3ec, 0x3ef, 0x3ee, + 0x39a, 0x3a1, 0x3a3, 0, 0x3b8, 0x395, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0x450, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, + 0x458, 0x459, 0x45a, 0x45b, 0x45c, 0x45d, 0x45e, 0x45f, + 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, + 0x438, 0x439, 0x43a, 0x43b, 0x43c, 0x43d, 0x43e, 0x43f, + 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, + 0x448, 0x449, 0x44a, 0x44b, 0x44c, 0x44d, 0x44e, 0x44f, + 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, + 0x418, 0x419, 0x41a, 0x41b, 0x41c, 0x41d, 0x41e, 0x41f, + 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, + 0x428, 0x429, 0x42a, 0x42b, 0x42c, 0x42d, 0x42e, 0x42f, + 0x400, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, + 0x408, 0x409, 0x40a, 0x40b, 0x40c, 0x40d, 0x40e, 0x40f, + 0x461, 0x460, 0x463, 0x462, 0x465, 0x464, 0x467, 0x466, + 0x469, 0x468, 0x46b, 0x46a, 0x46d, 0x46c, 0x46f, 0x46e, + 0x471, 0x470, 0x473, 0x472, 0x475, 0x474, 0x477, 0x476, + 0x479, 0x478, 0x47b, 0x47a, 0x47d, 0x47c, 0x47f, 0x47e, + 0x481, 0x480, 0, 0, 0, 0, 0, 0, + 0, 0, 0x48b, 0x48a, 0x48d, 0x48c, 0x48f, 0x48e, + 0x491, 0x490, 0x493, 0x492, 0x495, 0x494, 0x497, 0x496, + 0x499, 0x498, 0x49b, 0x49a, 0x49d, 0x49c, 0x49f, 0x49e, + 0x4a1, 0x4a0, 0x4a3, 0x4a2, 0x4a5, 0x4a4, 0x4a7, 0x4a6, + 0x4a9, 0x4a8, 0x4ab, 0x4aa, 0x4ad, 0x4ac, 0x4af, 0x4ae, + 0x4b1, 0x4b0, 0x4b3, 0x4b2, 0x4b5, 0x4b4, 0x4b7, 0x4b6, + 0x4b9, 0x4b8, 0x4bb, 0x4ba, 0x4bd, 0x4bc, 0x4bf, 0x4be, + 0, 0x4c2, 0x4c1, 0x4c4, 0x4c3, 0x4c6, 0x4c5, 0x4c8, + 0x4c7, 0x4ca, 0x4c9, 0x4cc, 0x4cb, 0x4ce, 0x4cd, 0, + 0x4d1, 0x4d0, 0x4d3, 0x4d2, 0x4d5, 0x4d4, 0x4d7, 0x4d6, + 0x4d9, 0x4d8, 0x4db, 0x4da, 0x4dd, 0x4dc, 0x4df, 0x4de, + 0x4e1, 0x4e0, 0x4e3, 0x4e2, 0x4e5, 0x4e4, 0x4e7, 0x4e6, + 0x4e9, 0x4e8, 0x4eb, 0x4ea, 0x4ed, 0x4ec, 0x4ef, 0x4ee, + 0x4f1, 0x4f0, 0x4f3, 0x4f2, 0x4f5, 0x4f4, 0, 0, + 0x4f9, 0x4f8, 0, 0, 0, 0, 0, 0, + + 0x501, 0x500, 0x503, 0x502, 0x505, 0x504, 0x507, 0x506, + 0x509, 0x508, 0x50b, 0x50a, 0x50d, 0x50c, 0x50f, 0x50e, + 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, 0x561, 0x562, 0x563, 0x564, 0x565, 0x566, 0x567, + 0x568, 0x569, 0x56a, 0x56b, 0x56c, 0x56d, 0x56e, 0x56f, + 0x570, 0x571, 0x572, 0x573, 0x574, 0x575, 0x576, 0x577, + 0x578, 0x579, 0x57a, 0x57b, 0x57c, 0x57d, 0x57e, 0x57f, + 0x580, 0x581, 0x582, 0x583, 0x584, 0x585, 0x586, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0x531, 0x532, 0x533, 0x534, 0x535, 0x536, 0x537, + 0x538, 0x539, 0x53a, 0x53b, 0x53c, 0x53d, 0x53e, 0x53f, + 0x540, 0x541, 0x542, 0x543, 0x544, 0x545, 0x546, 0x547, + 0x548, 0x549, 0x54a, 0x54b, 0x54c, 0x54d, 0x54e, 0x54f, + 0x550, 0x551, 0x552, 0x553, 0x554, 0x555, 0x556, 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, 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, + + 0x1e01, 0x1e00, 0x1e03, 0x1e02, 0x1e05, 0x1e04, 0x1e07, 0x1e06, + 0x1e09, 0x1e08, 0x1e0b, 0x1e0a, 0x1e0d, 0x1e0c, 0x1e0f, 0x1e0e, + 0x1e11, 0x1e10, 0x1e13, 0x1e12, 0x1e15, 0x1e14, 0x1e17, 0x1e16, + 0x1e19, 0x1e18, 0x1e1b, 0x1e1a, 0x1e1d, 0x1e1c, 0x1e1f, 0x1e1e, + 0x1e21, 0x1e20, 0x1e23, 0x1e22, 0x1e25, 0x1e24, 0x1e27, 0x1e26, + 0x1e29, 0x1e28, 0x1e2b, 0x1e2a, 0x1e2d, 0x1e2c, 0x1e2f, 0x1e2e, + 0x1e31, 0x1e30, 0x1e33, 0x1e32, 0x1e35, 0x1e34, 0x1e37, 0x1e36, + 0x1e39, 0x1e38, 0x1e3b, 0x1e3a, 0x1e3d, 0x1e3c, 0x1e3f, 0x1e3e, + 0x1e41, 0x1e40, 0x1e43, 0x1e42, 0x1e45, 0x1e44, 0x1e47, 0x1e46, + 0x1e49, 0x1e48, 0x1e4b, 0x1e4a, 0x1e4d, 0x1e4c, 0x1e4f, 0x1e4e, + 0x1e51, 0x1e50, 0x1e53, 0x1e52, 0x1e55, 0x1e54, 0x1e57, 0x1e56, + 0x1e59, 0x1e58, 0x1e5b, 0x1e5a, 0x1e5d, 0x1e5c, 0x1e5f, 0x1e5e, + 0x1e61, 0x1e60, 0x1e63, 0x1e62, 0x1e65, 0x1e64, 0x1e67, 0x1e66, + 0x1e69, 0x1e68, 0x1e6b, 0x1e6a, 0x1e6d, 0x1e6c, 0x1e6f, 0x1e6e, + 0x1e71, 0x1e70, 0x1e73, 0x1e72, 0x1e75, 0x1e74, 0x1e77, 0x1e76, + 0x1e79, 0x1e78, 0x1e7b, 0x1e7a, 0x1e7d, 0x1e7c, 0x1e7f, 0x1e7e, + 0x1e81, 0x1e80, 0x1e83, 0x1e82, 0x1e85, 0x1e84, 0x1e87, 0x1e86, + 0x1e89, 0x1e88, 0x1e8b, 0x1e8a, 0x1e8d, 0x1e8c, 0x1e8f, 0x1e8e, + 0x1e91, 0x1e90, 0x1e93, 0x1e92, 0x1e95, 0x1e94, 0, 0, + 0, 0, 0, 0x1e60, 0, 0, 0, 0, + 0x1ea1, 0x1ea0, 0x1ea3, 0x1ea2, 0x1ea5, 0x1ea4, 0x1ea7, 0x1ea6, + 0x1ea9, 0x1ea8, 0x1eab, 0x1eaa, 0x1ead, 0x1eac, 0x1eaf, 0x1eae, + 0x1eb1, 0x1eb0, 0x1eb3, 0x1eb2, 0x1eb5, 0x1eb4, 0x1eb7, 0x1eb6, + 0x1eb9, 0x1eb8, 0x1ebb, 0x1eba, 0x1ebd, 0x1ebc, 0x1ebf, 0x1ebe, + 0x1ec1, 0x1ec0, 0x1ec3, 0x1ec2, 0x1ec5, 0x1ec4, 0x1ec7, 0x1ec6, + 0x1ec9, 0x1ec8, 0x1ecb, 0x1eca, 0x1ecd, 0x1ecc, 0x1ecf, 0x1ece, + 0x1ed1, 0x1ed0, 0x1ed3, 0x1ed2, 0x1ed5, 0x1ed4, 0x1ed7, 0x1ed6, + 0x1ed9, 0x1ed8, 0x1edb, 0x1eda, 0x1edd, 0x1edc, 0x1edf, 0x1ede, + 0x1ee1, 0x1ee0, 0x1ee3, 0x1ee2, 0x1ee5, 0x1ee4, 0x1ee7, 0x1ee6, + 0x1ee9, 0x1ee8, 0x1eeb, 0x1eea, 0x1eed, 0x1eec, 0x1eef, 0x1eee, + 0x1ef1, 0x1ef0, 0x1ef3, 0x1ef2, 0x1ef5, 0x1ef4, 0x1ef7, 0x1ef6, + 0x1ef9, 0x1ef8, 0, 0, 0, 0, 0, 0, + + 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, + 0x1f00, 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, + 0x1f18, 0x1f19, 0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0, 0, + 0x1f10, 0x1f11, 0x1f12, 0x1f13, 0x1f14, 0x1f15, 0, 0, + 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, + 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 0x1f25, 0x1f26, 0x1f27, + 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, 0x1f3e, 0x1f3f, + 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, 0x1f37, + 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0, 0, + 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0, 0, + 0, 0x1f59, 0, 0x1f5b, 0, 0x1f5d, 0, 0x1f5f, + 0, 0x1f51, 0, 0x1f53, 0, 0x1f55, 0, 0x1f57, + 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f, + 0x1f60, 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, + 0x1fba, 0x1fbb, 0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fda, 0x1fdb, + 0x1ff8, 0x1ff9, 0x1fea, 0x1feb, 0x1ffa, 0x1ffb, 0, 0, + 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, + 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, + 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, + 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, + 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, + 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, + 0x1fb8, 0x1fb9, 0, 0x1fbc, 0, 0, 0, 0, + 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x1fb3, 0, 0x399, 0, + 0, 0, 0, 0x1fcc, 0, 0, 0, 0, + 0x1f72, 0x1f73, 0x1f74, 0x1f75, 0x1fc3, 0, 0, 0, + 0x1fd8, 0x1fd9, 0, 0, 0, 0, 0, 0, + 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0, 0, 0, 0, + 0x1fe8, 0x1fe9, 0, 0, 0, 0x1fec, 0, 0, + 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0, 0, 0, + 0, 0, 0, 0x1ffc, 0, 0, 0, 0, + 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x1ff3, 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, 0x3c9, 0, + 0, 0, 0x6b, 0xe5, 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, + 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, + 0x2178, 0x2179, 0x217a, 0x217b, 0x217c, 0x217d, 0x217e, 0x217f, + 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, + 0x2168, 0x2169, 0x216a, 0x216b, 0x216c, 0x216d, 0x216e, 0x216f, + 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, 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, 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, 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, 0x24d0, 0x24d1, + 0x24d2, 0x24d3, 0x24d4, 0x24d5, 0x24d6, 0x24d7, 0x24d8, 0x24d9, + 0x24da, 0x24db, 0x24dc, 0x24dd, 0x24de, 0x24df, 0x24e0, 0x24e1, + 0x24e2, 0x24e3, 0x24e4, 0x24e5, 0x24e6, 0x24e7, 0x24e8, 0x24e9, + 0x24b6, 0x24b7, 0x24b8, 0x24b9, 0x24ba, 0x24bb, 0x24bc, 0x24bd, + 0x24be, 0x24bf, 0x24c0, 0x24c1, 0x24c2, 0x24c3, 0x24c4, 0x24c5, + 0x24c6, 0x24c7, 0x24c8, 0x24c9, 0x24ca, 0x24cb, 0x24cc, 0x24cd, + 0x24ce, 0x24cf, 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, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, + 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, + 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, + 0xff58, 0xff59, 0xff5a, 0, 0, 0, 0, 0, + 0, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, + 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, + 0xff30, 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, + 0xff38, 0xff39, 0xff3a, 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, 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, 0, 0, 0, 0, 0, 0, 0, +}; +// 36602 bytes + +const Q_INT8 QUnicodeTables::decimal_info[] = { + 1, 0, 0, 0, 0, 0, 2, 0, + 0, 3, 3, 4, 3, 5, 6, 7, + 8, 0, 0, 9, 0, 0, 0, 10, + 11, 0, 0, 0, 0, 0, 0, 0, + 12, 0, 0, 0, 13, 0, 0, 14, + 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, 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, 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, 11, + + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 2, 3, -1, -1, -1, -1, + -1, 1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 1, + 2, 3, 4, 5, 6, 7, 8, 9, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1, 2, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 0, -1, -1, -1, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 1, 2, 3, 4, 5, 6, 7, 8, + 9, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 1, 2, 3, 4, + 5, 6, 7, 8, 9, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 1, 2, 3, 4, 5, 6, 7, 8, + 9, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1, 2, 3, + 4, 5, 6, 7, 8, 9, -1, -1, + + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 1, 2, + 3, 4, 5, 6, 7, 8, 9, -1, + 1, 2, 3, 4, 5, 6, 7, 8, + 9, -1, 1, 2, 3, 4, 5, 6, + 7, 8, 9, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, +}; +// 40698 bytes + +#endif + +#ifdef QT_NO_UNICODETABLES + +const Q_UINT8 QUnicodeTables::latin1_line_break_info[] = { + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 15, 23, 19, 21, 22, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 26, 5, 2, 11, 8, 9, 11, 2, + 0, 1, 11, 8, 7, 14, 7, 6, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 7, 7, 11, 11, 11, 5, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 0, 8, 1, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 0, 15, 1, 11, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 3, 11, 9, 8, 8, 8, 11, 11, + 11, 11, 11, 2, 11, 15, 11, 11, + 9, 8, 11, 11, 16, 11, 11, 11, + 11, 11, 11, 2, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, +}; + +#else + +const Q_UINT8 QUnicodeTables::line_break_info[] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 2, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 2, 18, 2, 2, 19, 20, + 21, 2, 2, 2, 2, 2, 2, 2, + 22, 23, 24, 25, 2, 2, 2, 26, + 2, 27, 2, 2, 2, 2, 28, 29, + 30, 31, 32, 33, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 35, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 36, + 34, 34, 34, 34, 37, 2, 2, 2, + 2, 2, 2, 2, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 38, + 39, 39, 39, 39, 39, 39, 39, 39, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 34, 40, 41, 2, 42, 43, 44, + + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 15, 23, 19, 21, 22, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 26, 5, 2, 11, 8, 9, 11, 2, + 0, 1, 11, 8, 7, 14, 7, 6, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 7, 7, 11, 11, 11, 5, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 0, 8, 1, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 0, 15, 1, 11, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 3, 11, 9, 8, 8, 8, 11, 11, + 11, 11, 11, 2, 11, 15, 11, 11, + 9, 8, 11, 11, 16, 11, 11, 11, + 11, 11, 11, 2, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 16, 11, 11, 11, 16, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 19, 19, 19, 19, 11, + 19, 19, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 7, 15, 11, 11, 11, 11, 11, + 11, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 11, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 11, 19, 19, 19, 11, 19, + 11, 19, 19, 11, 19, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 11, + 19, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 11, 11, 19, + 19, 11, 19, 19, 19, 19, 11, 11, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 19, + 11, 19, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 19, 19, 19, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 19, 11, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 11, 11, + 11, 19, 19, 19, 19, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 19, 19, 11, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 19, 19, 19, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 19, 11, 19, 19, + 19, 19, 19, 19, 19, 11, 11, 19, + 19, 11, 11, 19, 19, 19, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 19, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 19, 19, 11, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 8, 8, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 19, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 19, 11, 19, 19, + 19, 19, 19, 11, 11, 11, 11, 19, + 19, 11, 11, 19, 19, 19, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 19, 19, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 19, 19, 19, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 19, 11, 19, 19, + 19, 19, 19, 19, 19, 19, 11, 19, + 19, 19, 11, 19, 19, 19, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 19, 19, 19, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 19, 11, 19, 19, + 19, 19, 19, 19, 11, 11, 11, 19, + 19, 11, 11, 19, 19, 19, 11, 11, + 11, 11, 11, 11, 11, 11, 19, 19, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 19, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 19, 19, + 19, 19, 19, 11, 11, 11, 19, 19, + 19, 11, 19, 19, 19, 19, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 19, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 19, 19, 19, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 19, 19, + 19, 19, 19, 19, 19, 11, 19, 19, + 19, 11, 19, 19, 19, 19, 11, 11, + 11, 11, 11, 11, 11, 19, 19, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 19, 19, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 19, 19, + 19, 19, 19, 19, 19, 11, 19, 19, + 19, 11, 19, 19, 19, 19, 11, 11, + 11, 11, 11, 11, 11, 19, 19, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 19, 19, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 19, 19, + 19, 19, 19, 19, 11, 11, 19, 19, + 19, 11, 19, 19, 19, 19, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 19, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 19, 19, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 19, 11, 11, 11, 11, 19, + 19, 19, 19, 19, 19, 11, 19, 11, + 19, 19, 19, 19, 19, 19, 19, 19, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 19, 19, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 19, 20, 20, 19, 19, 19, 19, + 19, 19, 19, 11, 11, 11, 11, 8, + 20, 20, 20, 20, 20, 20, 20, 19, + 19, 19, 19, 19, 19, 19, 19, 11, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 4, 4, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 20, 20, 11, 20, 11, 11, 20, + 20, 11, 20, 11, 11, 20, 11, 11, + 11, 11, 11, 11, 20, 20, 20, 20, + 11, 20, 20, 20, 20, 20, 20, 20, + 11, 20, 20, 20, 11, 20, 11, 20, + 11, 11, 20, 20, 11, 20, 20, 20, + 20, 19, 20, 20, 19, 19, 19, 19, + 19, 19, 11, 19, 19, 20, 11, 11, + 20, 20, 20, 20, 20, 11, 20, 11, + 19, 19, 19, 19, 19, 19, 11, 11, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 20, 20, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 15, 3, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 19, 19, 11, 11, 11, 11, 11, 11, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 19, 11, 19, + 11, 19, 0, 1, 0, 1, 19, 19, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 11, 19, 19, + 11, 11, 11, 11, 11, 11, 11, 11, + 19, 19, 19, 19, 19, 19, 19, 19, + 11, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 19, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 11, 20, 20, 20, 20, 20, + 11, 20, 20, 11, 19, 19, 19, 19, + 19, 19, 19, 11, 11, 11, 19, 19, + 19, 19, 11, 11, 11, 11, 11, 11, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 11, + 20, 20, 20, 20, 20, 20, 19, 19, + 19, 19, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 11, 11, 11, 11, 11, 12, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 11, 11, 11, 11, 11, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 15, 11, 11, 11, 11, 11, 11, + 11, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 15, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 0, 1, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 19, 19, 19, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 19, 19, 19, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 19, 19, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 19, 19, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 4, 15, 4, 4, + 4, 4, 4, 8, 11, 11, 11, 11, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 16, 11, + 11, 11, 11, 19, 19, 19, 19, 11, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 19, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 15, 15, 15, 15, 15, 15, 15, 3, + 15, 15, 15, 18, 19, 19, 19, 19, + 15, 3, 15, 15, 17, 11, 11, 11, + 2, 2, 0, 2, 2, 2, 0, 2, + 11, 11, 11, 11, 13, 13, 13, 15, + 21, 21, 19, 19, 19, 19, 19, 3, + 9, 9, 9, 9, 9, 9, 9, 9, + 11, 2, 2, 11, 4, 11, 11, 11, + 11, 11, 11, 11, 4, 0, 1, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 15, + 3, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 19, 19, 19, 19, 19, 19, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 0, 1, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 0, 1, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 8, 8, 8, 8, 8, 8, 8, 9, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 9, 11, 11, 11, 11, + 11, 9, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 8, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 9, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 8, 8, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 0, 1, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 0, 1, 2, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 2, 2, 2, 2, 11, + 11, 11, 5, 5, 11, 11, 11, 11, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 0, 1, + 0, 1, 0, 1, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 0, 1, 0, 1, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 0, 1, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 11, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 11, 11, 11, 11, + + 12, 1, 1, 12, 12, 4, 12, 12, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 12, 12, 0, 1, 0, 1, + 0, 1, 0, 1, 4, 0, 1, 1, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 19, 19, 19, 19, 19, 19, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 4, 4, 12, 12, 12, + 11, 4, 12, 4, 12, 4, 12, 4, + 12, 4, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 4, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 4, 12, 4, 12, 4, + 12, 12, 12, 12, 12, 12, 4, 12, + 12, 12, 12, 12, 12, 4, 4, 11, + 11, 19, 19, 4, 4, 4, 4, 12, + 4, 4, 12, 4, 12, 4, 12, 4, + 12, 4, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 4, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 4, 12, 4, 12, 4, + 12, 12, 12, 12, 12, 12, 4, 12, + 12, 12, 12, 12, 12, 4, 4, 12, + 12, 12, 12, 4, 12, 4, 12, 12, + + 11, 11, 11, 11, 11, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 11, 11, 11, + 11, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 11, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 11, 11, 11, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 11, + + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 11, + 11, 11, 11, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 11, + + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 19, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 0, 1, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 9, 11, 11, 11, + + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 19, 19, 19, 19, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 12, 12, 11, + 11, 12, 12, 12, 12, 12, 12, 12, + 1, 12, 1, 11, 4, 4, 5, 5, + 12, 0, 1, 0, 1, 0, 1, 12, + 12, 12, 12, 12, 12, 12, 12, 11, + 12, 8, 9, 12, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 3, + + 11, 5, 12, 12, 8, 9, 12, 12, + 0, 1, 12, 12, 1, 12, 1, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 4, 4, 12, 12, 12, 5, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 0, 12, 1, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 0, 12, 1, 12, 0, + 1, 1, 0, 1, 1, 4, 11, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 4, 4, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 9, 8, 12, 12, 12, 8, 8, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 19, 19, 19, 25, 11, 11, 11, +}; +// 52474 bytes + +// END OF GENERATED DATA +#endif + + + +#ifndef QT_NO_UNICODETABLES +const Q_UINT16 QUnicodeTables::symmetricPairs[] = { + 0x0028, 0x0029, 0x003C, 0x003E, 0x005B, 0x005D, 0x007B, 0x007D, + 0x00AB, 0x00BB, 0x2039, 0x203A, 0x2045, 0x2046, 0x207D, 0x207E, + 0x208D, 0x208E, 0x2208, 0x220B, 0x2209, 0x220C, 0x220A, 0x220D, + 0x2215, 0x29F5, 0x223C, 0x223D, 0x2243, 0x22CD, 0x2252, 0x2253, + 0x2254, 0x2255, 0x2264, 0x2265, 0x2266, 0x2267, 0x2268, 0x2269, + 0x226A, 0x226B, 0x226E, 0x226F, 0x2270, 0x2271, 0x2272, 0x2273, + 0x2274, 0x2275, 0x2276, 0x2277, 0x2278, 0x2279, 0x227A, 0x227B, + 0x227C, 0x227D, 0x227E, 0x227F, 0x2280, 0x2281, 0x2282, 0x2283, + 0x2284, 0x2285, 0x2286, 0x2287, 0x2288, 0x2289, 0x228A, 0x228B, + 0x228F, 0x2290, 0x2291, 0x2292, 0x2298, 0x29B8, 0x22A2, 0x22A3, + 0x22A6, 0x2ADE, 0x22A8, 0x2AE4, 0x22A9, 0x2AE3, 0x22AB, 0x2AE5, + 0x22B0, 0x22B1, 0x22B2, 0x22B3, 0x22B4, 0x22B5, 0x22B6, 0x22B7, + 0x22C9, 0x22CA, 0x22CB, 0x22CC, 0x22D0, 0x22D1, 0x22D6, 0x22D7, + 0x22D8, 0x22D9, 0x22DA, 0x22DB, 0x22DC, 0x22DD, 0x22DE, 0x22DF, + 0x22E0, 0x22E1, 0x22E2, 0x22E3, 0x22E4, 0x22E5, 0x22E6, 0x22E7, + 0x22E8, 0x22E9, 0x22EA, 0x22EB, 0x22EC, 0x22ED, 0x22F0, 0x22F1, + 0x22F2, 0x22FA, 0x22F3, 0x22FB, 0x22F4, 0x22FC, 0x22F6, 0x22FD, + 0x22F7, 0x22FE, 0x2308, 0x2309, 0x230A, 0x230B, 0x2329, 0x232A, + 0x2768, 0x2769, 0x276A, 0x276B, 0x276C, 0x276D, 0x276E, 0x276F, + 0x2770, 0x2771, 0x2772, 0x2773, 0x2774, 0x2775, 0x27D5, 0x27D6, + 0x27DD, 0x27DE, 0x27E2, 0x27E3, 0x27E4, 0x27E5, 0x27E6, 0x27E7, + 0x27E8, 0x27E9, 0x27EA, 0x27EB, 0x2983, 0x2984, 0x2985, 0x2986, + 0x2987, 0x2988, 0x2989, 0x298A, 0x298B, 0x298C, 0x298D, 0x2990, + 0x298E, 0x298F, 0x2991, 0x2992, 0x2993, 0x2994, 0x2995, 0x2996, + 0x2997, 0x2998, 0x29C0, 0x29C1, 0x29C4, 0x29C5, 0x29CF, 0x29D0, + 0x29D1, 0x29D2, 0x29D4, 0x29D5, 0x29D8, 0x29D9, 0x29DA, 0x29DB, + 0x29F8, 0x29F9, 0x29FC, 0x29FD, 0x2A2B, 0x2A2C, 0x2A34, 0x2A35, + 0x2A3C, 0x2A3D, 0x2A64, 0x2A65, 0x2A79, 0x2A7A, 0x2A7D, 0x2A7E, + 0x2A7F, 0x2A80, 0x2A81, 0x2A82, 0x2A83, 0x2A84, 0x2A8B, 0x2A8C, + 0x2A91, 0x2A92, 0x2A93, 0x2A94, 0x2A95, 0x2A96, 0x2A97, 0x2A98, + 0x2A99, 0x2A9A, 0x2A9B, 0x2A9C, 0x2AA1, 0x2AA2, 0x2AA6, 0x2AA7, + 0x2AA8, 0x2AA9, 0x2AAA, 0x2AAB, 0x2AAC, 0x2AAD, 0x2AAF, 0x2AB0, + 0x2AB3, 0x2AB4, 0x2ABB, 0x2ABC, 0x2ABD, 0x2ABE, 0x2ABF, 0x2AC0, + 0x2AC1, 0x2AC2, 0x2AC3, 0x2AC4, 0x2AC5, 0x2AC6, 0x2ACD, 0x2ACE, + 0x2ACF, 0x2AD0, 0x2AD1, 0x2AD2, 0x2AD3, 0x2AD4, 0x2AD5, 0x2AD6, + 0x2AEC, 0x2AED, 0x2AF7, 0x2AF8, 0x2AF9, 0x2AFA, 0x3008, 0x3009, + 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, 0x300F, 0x3010, 0x3011, + 0x3014, 0x3015, 0x3016, 0x3017, 0x3018, 0x3019, 0x301A, 0x301B, + 0xFF08, 0xFF09, 0xFF1C, 0xFF1E, 0xFF3B, 0xFF3D, 0xFF5B, 0xFF5D, + 0xFF5F, 0xFF60, 0xFF62, 0xFF63, +}; + +// ### shouldn't this be const? +const int QUnicodeTables::symmetricPairsSize = + sizeof(symmetricPairs)/sizeof(symmetricPairs[0]); + +#else + +/* + only include info for the first unicode range (latin1) when building + without unicode tables. +*/ +const Q_UINT8 QUnicodeTables::unicode_info[] = { + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 7, 26, 26, 26, 28, 26, 26, 26, + 22, 23, 26, 27, 26, 21, 26, 26, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 26, 26, 27, 27, 27, 26, + 26, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 22, 26, 23, 29, 20, + 29, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 22, 27, 23, 27, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 7, 26, 28, 28, 28, 28, 30, 30, + 29, 30, 16, 24, 27, 21, 30, 29, + 30, 27, 6, 6, 29, 16, 30, 26, + 29, 6, 16, 25, 6, 6, 6, 26, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 27, + 15, 15, 15, 15, 15, 15, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 27, + 16, 16, 16, 16, 16, 16, 16, 16 +}; + +#endif + +/* + * ---------------------------------------------------------------------- + * End of unicode tables + * ---------------------------------------------------------------------- + */ + +enum Script { + // European Alphabetic Scripts + Latin, + Greek, + Cyrillic, + Armenian, + Georgian, + Runic, + Ogham, + SpacingModifiers, + CombiningMarks, + + // Middle Eastern Scripts + Hebrew, + Arabic, + Syriac, + Thaana, + + // South and Southeast Asian Scripts + Devanagari, + Bengali, + Gurmukhi, + Gujarati, + Oriya, + Tamil, + Telugu, + Kannada, + Malayalam, + Sinhala, + Thai, + Lao, + Tibetan, + Myanmar, + Khmer, + + // East Asian Scripts + Han, + Hiragana, + Katakana, + Hangul, + Bopomofo, + Yi, + + // Additional Scripts + Ethiopic, + Cherokee, + CanadianAboriginal, + Mongolian, + + // Symbols + CurrencySymbols, + LetterlikeSymbols, + NumberForms, + MathematicalOperators, + TechnicalSymbols, + GeometricSymbols, + MiscellaneousSymbols, + EnclosedAndSquare, + Braille, + + Unicode, + + // some scripts added in Unicode 3.2 + Tagalog, + Hanunoo, + Buhid, + Tagbanwa, + + KatakanaHalfWidth, // from JIS X 0201 + + // from Unicode 4.0 + Limbu, + TaiLe, + + // End + NScripts, + UnknownScript = NScripts +}; + +// copied form qfont.h, as we can't include it in tools. Do not modify without +// changing the script enum in qfont.h aswell. +const unsigned char QUnicodeTables::otherScripts [128] = { +#define SCRIPTS_02 0 + 0xaf, Latin, 0xff, SpacingModifiers, // row 0x02, index 0 +#define SCRIPTS_03 4 + 0x6f, CombiningMarks, 0xff, Greek, // row 0x03, index 4 +#define SCRIPTS_05 8 + 0x2f, Cyrillic, 0x8f, Armenian, 0xff, Hebrew, // row 0x05, index 8 +#define SCRIPTS_07 14 + 0x4f, Syriac, 0x7f, Unicode, 0xbf, Thaana, + 0xff, Unicode, // row 0x07, index 14 +#define SCRIPTS_10 22 + 0x9f, Myanmar, 0xff, Georgian, // row 0x10, index 20 +#define SCRIPTS_13 26 + 0x7f, Ethiopic, 0x9f, Unicode, 0xff, Cherokee, // row 0x13, index 24 +#define SCRIPTS_16 32 + 0x7f, CanadianAboriginal, 0x9f, Ogham, + 0xff, Runic, // row 0x16 index 30 +#define SCRIPTS_17 38 + 0x1f, Tagalog, 0x3f, Hanunoo, 0x5f, Buhid, + 0x7f, Tagbanwa, 0xff, Khmer, // row 0x17, index 36 +#define SCRIPTS_18 48 + 0xaf, Mongolian, 0xff, Unicode, // row 0x18, index 46 +#define SCRIPTS_19 52 + 0x4f, Limbu, 0x7f, TaiLe, 0xdf, Unicode, 0xff, Khmer, +#define SCRIPTS_20 60 + 0x0b, Unicode, 0x0d, UnknownScript, 0x6f, Unicode, 0x9f, NumberForms, + 0xab, CurrencySymbols, 0xac, Latin, + 0xcf, CurrencySymbols, 0xff, CombiningMarks, // row 0x20, index 50 +#define SCRIPTS_21 76 + 0x4f, LetterlikeSymbols, 0x8f, NumberForms, + 0xff, MathematicalOperators, // row 0x21, index 62 +#define SCRIPTS_24 82 + 0x5f, TechnicalSymbols, 0xff, EnclosedAndSquare, // row 0x24, index 68 +#define SCRIPTS_2e 86 + 0x7f, Unicode, 0xff, Han, // row 0x2e, index 72 +#define SCRIPTS_30 90 + 0x3f, Han, 0x9f, Hiragana, 0xff, Katakana, // row 0x30, index 76 +#define SCRIPTS_31 96 + 0x2f, Bopomofo, 0x8f, Hangul, 0x9f, Han, + 0xff, Unicode, // row 0x31, index 82 +#define SCRIPTS_fb 104 + 0x06, Latin, 0x1c, Unicode, 0x4f, Hebrew, + 0xff, Arabic, // row 0xfb, index 90 +#define SCRIPTS_fe 112 + 0x1f, Unicode, 0x2f, CombiningMarks, 0x6f, Unicode, + 0xff, Arabic, // row 0xfe, index 98 +#define SCRIPTS_ff 120 + 0x5e, Katakana, 0x60, Unicode, // row 0xff, index 106 + 0x9f, KatakanaHalfWidth, 0xff, Unicode +}; + +// (uc-0x0900)>>7 +const unsigned char QUnicodeTables::indicScripts [] = +{ + Devanagari, Bengali, + Gurmukhi, Gujarati, + Oriya, Tamil, + Telugu, Kannada, + Malayalam, Sinhala, + Thai, Lao +}; + + +// 0x80 + x: x is the offset into the otherScripts table +const unsigned char QUnicodeTables::scriptTable[256] = +{ + Latin, Latin, 0x80+SCRIPTS_02, 0x80+SCRIPTS_03, + Cyrillic, 0x80+SCRIPTS_05, Arabic, 0x80+SCRIPTS_07, + Unicode, SCRIPTS_INDIC, SCRIPTS_INDIC, SCRIPTS_INDIC, + SCRIPTS_INDIC, SCRIPTS_INDIC, SCRIPTS_INDIC, Tibetan, + + 0x80+SCRIPTS_10, Hangul, Ethiopic, 0x80+SCRIPTS_13, + CanadianAboriginal, CanadianAboriginal, 0x80+SCRIPTS_16, 0x80+SCRIPTS_17, + 0x80+SCRIPTS_18, 0x80+SCRIPTS_19, Unicode, Unicode, + Unicode, Unicode, Latin, Greek, + + 0x80+SCRIPTS_20, 0x80+SCRIPTS_21, MathematicalOperators, TechnicalSymbols, + 0x80+SCRIPTS_24, GeometricSymbols, MiscellaneousSymbols, MiscellaneousSymbols, + Braille, Unicode, Unicode, Unicode, + Unicode, Unicode, 0x80+SCRIPTS_2e, Han, + + 0x80+SCRIPTS_30, 0x80+SCRIPTS_31, EnclosedAndSquare, EnclosedAndSquare, + Han, Han, Han, Han, + Han, Han, Han, Han, + Han, Han, Han, Han, + + Han, Han, Han, Han, Han, Han, Han, Han, + Han, Han, Han, Han, Han, Han, Han, Han, + + Han, Han, Han, Han, Han, Han, Han, Han, + Han, Han, Han, Han, Han, Han, Han, Han, + + Han, Han, Han, Han, Han, Han, Han, Han, + Han, Han, Han, Han, Han, Han, Han, Han, + + Han, Han, Han, Han, Han, Han, Han, Han, + Han, Han, Han, Han, Han, Han, Han, Han, + + + Han, Han, Han, Han, Han, Han, Han, Han, + Han, Han, Han, Han, Han, Han, Han, Han, + + Han, Han, Han, Han, Han, Han, Han, Han, + Han, Han, Han, Han, Han, Han, Han, Han, + + Yi, Yi, Yi, Yi, Yi, Unicode, Unicode, Unicode, + Unicode, Unicode, Unicode, Unicode, Hangul, Hangul, Hangul, Hangul, + + Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, + Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, + + Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, + Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, + + Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, + Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, + + Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, + Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, + + Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, + Unicode, Han, Han, 0x80+SCRIPTS_fb, Arabic, Arabic, 0x80+SCRIPTS_fe, 0x80+SCRIPTS_ff +}; + diff --git a/qmake/tools/quuid.cpp b/qmake/tools/quuid.cpp index fd99abf..199bfa5 100644 --- a/qmake/tools/quuid.cpp +++ b/qmake/tools/quuid.cpp @@ -1,3 +1,3 @@ /**************************************************************************** -** $Id$ +** ** @@ -37,21 +37,27 @@ -#include <qdatastream.h> +#include "qdatastream.h" /*! - \class QUuid quuid.h - \reentrant - \brief The QUuid class defines a Universally Unique Identifier (UUID). + \class QUuid quuid.h + \brief The QUuid class defines a Universally Unique Identifier (UUID). - \internal + \reentrant - For objects or declarations that need to be identified uniquely, UUIDs (also known as GUIDs) are widely - used in order to assign a fixed and easy to compare value to this object or declaration. The 128bit value - of an UUID is generated by an algorithm that guarantees a value that is unique in time and space. + For objects or declarations that must be uniquely identified, + UUIDs (also known as GUIDs) are widely used in order to assign a + fixed and easy to compare value to the object or declaration. The + 128-bit value of a UUID is generated by an algorithm that + guarantees that the value is unique. - In Qt, UUIDs are wrapped by the QUuid struct which provides convenience functions for comparing and coping - this value. The QUuid struct is used in Qt's component model to identify interfaces. Most platforms provide a tool to - generate new UUIDs (uuidgen, guidgen), and the Qt distribution includes a graphical tool \e quuidgen that generates - the UUIDs in a programmer friendly format. + In Qt, UUIDs are wrapped by the QUuid struct which provides + convenience functions for handling UUIDs. Most platforms provide a + tool to generate new UUIDs, for example, uuidgen and guidgen. - \sa QUnknownInterface + UUIDs generated by QUuid, are based on the \c Random version of the + \c DCE (Distributed Computing Environment) standard. + + UUIDs can be constructed from numeric values or from strings, or + using the static createUuid() function. They can be converted to a + string with toString(). UUIDs have a variant() and a version(), + and null UUIDs return TRUE from isNull(). */ @@ -59,5 +65,5 @@ /*! - \fn QUuid::QUuid() + \fn QUuid::QUuid() - Creates the null UUID {00000000-0000-0000-0000-000000000000}. + Creates the null UUID {00000000-0000-0000-0000-000000000000}. */ @@ -65,12 +71,13 @@ /*! - \fn QUuid::QUuid( uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3, uchar b4, uchar b5, uchar b6, uchar b7, uchar b8 ) + \fn QUuid::QUuid( uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3, uchar b4, uchar b5, uchar b6, uchar b7, uchar b8 ) - Creates an UUID with the value specified by the parameters, \a l, \a - w1, \a w2, \a b1, \a b2, \a b3, \a b4, \a b5, \a b6, \a b7, \a b8. + Creates a UUID with the value specified by the parameters, \a l, + \a w1, \a w2, \a b1, \a b2, \a b3, \a b4, \a b5, \a b6, \a b7, \a + b8. - Example: - \code - // {67C8770B-44F1-410A-AB9A-F9B5446F13EE} - QUuid IID_MyInterface( 0x67c8770b, 0x44f1, 0x410a, 0xab, 0x9a, 0xf9, 0xb5, 0x44, 0x6f, 0x13, 0xee ) - \endcode + Example: + \code + // {67C8770B-44F1-410A-AB9A-F9B5446F13EE} + QUuid IID_MyInterface( 0x67c8770b, 0x44f1, 0x410a, 0xab, 0x9a, 0xf9, 0xb5, 0x44, 0x6f, 0x13, 0xee ) + \endcode */ @@ -78,5 +85,5 @@ /*! - \fn QUuid::QUuid( const QUuid &orig ) + \fn QUuid::QUuid( const QUuid &orig ) - Creates a copy of the QUuid \a orig. + Creates a copy of the QUuid \a orig. */ @@ -84,5 +91,6 @@ /*! - Creates a QUuid object from the string \a text. Right now, the function - can only convert the format {12345678-1234-1234-1234-123456789ABC} and - will create the null UUID when the conversion fails. + Creates a QUuid object from the string \a text. The function can + only convert a string in the format + {HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH} (where 'H' stands for a hex + digit). If the conversion fails a null UUID is created. */ @@ -91,3 +99,11 @@ QUuid::QUuid( const QString &text ) bool ok; + if ( text.isEmpty() ) { + *this = QUuid(); + return; + } QString temp = text.upper(); + if ( temp[0] != '{' ) + temp = "{" + text; + if ( text[(int)text.length()-1] != '}' ) + temp += "}"; @@ -129,3 +145,3 @@ QUuid::QUuid( const QString &text ) /*! - \overload + \internal */ @@ -137,5 +153,5 @@ QUuid::QUuid( const char *text ) /*! - \fn QUuid QUuid::operator=(const QUuid &uuid ) + \fn QUuid QUuid::operator=(const QUuid &uuid ) - Assigns the value of \a uuid to this QUuid object. + Assigns the value of \a uuid to this QUuid object. */ @@ -143,5 +159,6 @@ QUuid::QUuid( const char *text ) /*! - \fn bool QUuid::operator==(const QUuid &other) const + \fn bool QUuid::operator==(const QUuid &other) const - Returns TRUE if this QUuid and the \a other QUuid are identical, otherwise returns FALSE. + Returns TRUE if this QUuid and the \a other QUuid are identical; + otherwise returns FALSE. */ @@ -149,5 +166,6 @@ QUuid::QUuid( const char *text ) /*! - \fn bool QUuid::operator!=(const QUuid &other) const + \fn bool QUuid::operator!=(const QUuid &other) const - Returns TRUE if this QUuid and the \a other QUuid are different, otherwise returns FALSE. + Returns TRUE if this QUuid and the \a other QUuid are different; + otherwise returns FALSE. */ @@ -155,7 +173,7 @@ QUuid::QUuid( const char *text ) /*! - \fn QUuid::operator QString() const + \fn QUuid::operator QString() const - Returns the string representation of the uuid. + Returns the string representation of the uuid. - \sa toString() + \sa toString() */ @@ -163,5 +181,5 @@ QUuid::QUuid( const char *text ) /*! - QString QUuid::toString() const + QString QUuid::toString() const - Returns the string representation of the uuid. + Returns the string representation of the uuid. */ @@ -185,4 +203,4 @@ QString QUuid::toString() const /*! - \relates QUuid - Writes the \a id to the datastream \a s. + \relates QUuid + Writes the uuid \a id to the datastream \a s. */ @@ -199,4 +217,4 @@ QDataStream &operator<<( QDataStream &s, const QUuid &id ) /*! - \relates QUuid - Reads a universally unique id from from the stream \a s into \a id. + \relates QUuid + Reads uuid from from the stream \a s into \a id. */ @@ -222,3 +240,4 @@ QDataStream &operator>>( QDataStream &s, QUuid &id ) /*! - Returns TRUE if this is the null UUID {00000000-0000-0000-0000-000000000000}, otherwise returns FALSE. + Returns TRUE if this is the null UUID + {00000000-0000-0000-0000-000000000000}; otherwise returns FALSE. */ @@ -230 +249,170 @@ bool QUuid::isNull() const } + +/*! + \enum QUuid::Variant + + This enum defines the variant of the UUID, which is the scheme + which defines the layout of the 128-bits value. + + \value VarUnknown Variant is unknown + \value NCS Reserved for NCS (Network Computing System) backward compatibility + \value DCE Distributed Computing Environment, the scheme used by QUuid + \value Microsoft Reserved for Microsoft backward compatibility (GUID) + \value Reserved Reserved for future definition +*/ + +/*! + \enum QUuid::Version + + This enum defines the version of the UUID. + + \value VerUnknown Version is unknown + \value Time Time-based, by using timestamp, clock sequence, and + MAC network card address (if available) for the node sections + \value EmbeddedPOSIX DCE Security version, with embedded POSIX UUIDs + \value Name Name-based, by using values from a name for all sections + \value Random Random-based, by using random numbers for all sections +*/ + +/*! + \fn QUuid::Variant QUuid::variant() const + + Returns the variant of the UUID. + The null UUID is considered to be of an unknown variant. + + \sa version() +*/ +QUuid::Variant QUuid::variant() const +{ + if ( isNull() ) + return VarUnknown; + // Check the 3 MSB of data4[0] + if ( (data4[0] & 0x80) == 0x00 ) return NCS; + else if ( (data4[0] & 0xC0) == 0x80 ) return DCE; + else if ( (data4[0] & 0xE0) == 0xC0 ) return Microsoft; + else if ( (data4[0] & 0xE0) == 0xE0 ) return Reserved; + return VarUnknown; +} + +/*! + \fn QUuid::Version QUuid::version() const + + Returns the version of the UUID, if the UUID is of the DCE + variant; otherwise returns VerUnknown. + + \sa variant() +*/ +QUuid::Version QUuid::version() const +{ + // Check the 4 MSB of data3 + Version ver = (Version)(data3>>12); + if ( isNull() + || (variant() != DCE) + || ver < Time + || ver > Random ) + return VerUnknown; + return ver; +} + +/*! + \fn bool QUuid::operator<(const QUuid &other) const + + Returns TRUE if this QUuid is of the same variant, + and lexicographically before the \a other QUuid; + otherwise returns FALSE. + + \sa variant() +*/ +#define ISLESS(f1, f2) if (f1!=f2) return (f1<f2); +bool QUuid::operator<(const QUuid &other ) const +{ + if ( variant() != other.variant() ) + return FALSE; + + ISLESS( data1, other.data1 ); + ISLESS( data2, other.data2 ); + ISLESS( data3, other.data3 ); + for ( int n = 0; n < 8; n++ ) { + ISLESS( data4[n], other.data4[n] ); + } + return FALSE; +} + +/*! + \fn bool QUuid::operator>(const QUuid &other) const + + Returns TRUE if this QUuid is of the same variant, + and lexicographically after the \a other QUuid; + otherwise returns FALSE. + + \sa variant() +*/ +#define ISMORE(f1, f2) if (f1!=f2) return (f1>f2); +bool QUuid::operator>(const QUuid &other ) const +{ + if ( variant() != other.variant() ) + return FALSE; + + ISMORE( data1, other.data1 ); + ISMORE( data2, other.data2 ); + ISMORE( data3, other.data3 ); + for ( int n = 0; n < 8; n++ ) { + ISMORE( data4[n], other.data4[n] ); + } + return FALSE; +} + +/*! + \fn QUuid QUuid::createUuid() + + Returns a new UUID of \c DCE variant, and \c Random type. The + UUIDs generated are based on the platform specific pseudo-random + generator, which is usually not a cryptographic-quality random + number generator. Therefore, a UUID is not guaranteed to be unique + cross application instances. + + On Windows, the new UUID is extremely likely to be unique on the + same or any other system, networked or not. + + \sa variant(), version() +*/ +#if defined(Q_OS_WIN32) +#include <objbase.h> // For CoCreateGuid +QUuid QUuid::createUuid() +{ + GUID guid; + CoCreateGuid( &guid ); + QUuid result = guid; + return result; +} +#else // !Q_OS_WIN32 +#include "qdatetime.h" +#include "stdlib.h" // For srand/rand +QUuid QUuid::createUuid() +{ + static const int intbits = sizeof(int)*8; + static int randbits = 0; + if ( !randbits ) { + int max = RAND_MAX; + do { ++randbits; } while ( (max=max>>1) ); + srand( (uint)QDateTime::currentDateTime().toTime_t() ); + rand(); // Skip first + } + + QUuid result; + uint *data = &(result.data1); + int chunks = 16 / sizeof(uint); + while ( chunks-- ) { + uint randNumber = 0; + for ( int filled = 0; filled < intbits; filled += randbits ) + randNumber |= rand()<<filled; + *(data+chunks) = randNumber; + } + + result.data4[0] = (result.data4[0] & 0x3F) | 0x80; // UV_DCE + result.data3 = (result.data3 & 0x0FFF) | 0x4000; // UV_Random + + return result; +} +#endif // !Q_OS_WIN32 + |