author | zecke <zecke> | 2004-07-15 17:36:57 (UTC) |
---|---|---|
committer | zecke <zecke> | 2004-07-15 17:36:57 (UTC) |
commit | 323e9a7472a110b4befba7320540263147505bae (patch) (side-by-side diff) | |
tree | 14c810bdb9c0603a30356b17b4bdf9ccb72741c6 /qmake | |
parent | aa292b322f1ecb43dd8f4e3cd295855730dd9f59 (diff) | |
download | opie-323e9a7472a110b4befba7320540263147505bae.zip opie-323e9a7472a110b4befba7320540263147505bae.tar.gz opie-323e9a7472a110b4befba7320540263147505bae.tar.bz2 |
Manually updatet to qmake1.06a which includes support for precompiled
headers.
Opies 'PRO' keyword was already reintroduced
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,40 +1,68 @@ +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 - subdirs supports multiple project files in a single directory. 1.03a - New function $$system() to extract the value of a shell call. 1.02a - - 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. The parser has been improved to cover more error cases, as well as more forgiving qmake now includes a special else scope to invert the previous test Ability to add user defined targets to UnixMakefiles. 1.01a - New system for library linking. This system allows a user several different features: - 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 automatically build that other library (unix makefiles only) 3) automatic detection of configurations for Qt, if CONFIG qt is specified it will find the settings for the most recent Qt itself. Project Builder for Mac OS X is now a supported backend for qmake. qmake now offers a 'make uninstall' feature, to reverse the actions of a 'make install'. qmake can now do recursive searches in project-file mode (-r option). 1.00a - First release, shipped with Qt 3.0. qmake ships with support for Unix make, MSVC (both dsp and nmake), Borland make. diff --git a/qmake/Makefile b/qmake/Makefile index 01bb1a1..5a72210 100644 --- a/qmake/Makefile +++ b/qmake/Makefile @@ -1,178 +1,220 @@ QMAKESPECSDIR=$(OPIEDIR)/mkspecs -######################################################################## -## This file was autogenerated by configure, all changes will be lost ## -######################################################################## CC = gcc 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 #qt code QOBJS=qstring.o qtextstream.o qiodevice.o qglobal.o qgdict.o qcstring.o \ qdatastream.o qgarray.o qbuffer.o qglist.o qptrcollection.o qfile.o \ qfile_unix.o qregexp.o qgvector.o qgcache.o qbitarray.o qdir.o quuid.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= qmake: $(OBJS) $(QOBJS) $(CXX) -o $@ $(OBJS) $(QOBJS) $(LFLAGS) $(if $(OPIEDIR),rm -f $(OPIEDIR)/bin/$@) $(if $(OPIEDIR),ln -s ../qmake/$@ $(OPIEDIR)/bin/$@) install: qmake [ -d $(INSTALL_ROOT)$(QTDIR)/bin ] || mkdir -p $(INSTALL_ROOT)$(QTDIR)/bin -cp -f $(QTDIR)/bin/qmake $(INSTALL_ROOT)$(QTDIR)/bin [ -d $(INSTALL_ROOT)$(QTDIR) ] || mkdir -p $(INSTALL_ROOT)$(QTDIR) -cp -r -f $(QMAKESPECSDIR) $(INSTALL_ROOT)$(QTDIR) clean:: rm -f $(OBJS) $(QOBJS) distclean:: clean rm -rf qmake .deps + # don't use optimization for these qtextstream.o: $(OPIEDIR)/qmake/tools/qtextstream.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qtextstream.cpp qiodevice.o: $(OPIEDIR)/qmake/tools/qiodevice.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qiodevice.cpp qglobal.o: $(OPIEDIR)/qmake/tools/qglobal.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qglobal.cpp qgdict.o: $(OPIEDIR)/qmake/tools/qgdict.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qgdict.cpp qcstring.o: $(OPIEDIR)/qmake/tools/qcstring.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(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 $(CXX) -c -o $@ $(CXXFLAGS) $(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 $(CXX) -c -o $@ $(CXXFLAGS) $(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 $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qgarray.cpp qbuffer.o: $(OPIEDIR)/qmake/tools/qbuffer.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qbuffer.cpp qglist.o: $(OPIEDIR)/qmake/tools/qglist.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qglist.cpp qptrcollection.o: $(OPIEDIR)/qmake/tools/qptrcollection.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qptrcollection.cpp qfile.o: $(OPIEDIR)/qmake/tools/qfile.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qfile.cpp qfile_unix.o: $(OPIEDIR)/qmake/tools/qfile_unix.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qfile_unix.cpp qregexp.o: $(OPIEDIR)/qmake/tools/qregexp.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qregexp.cpp qgvector.o: $(OPIEDIR)/qmake/tools/qgvector.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qgvector.cpp qgcache.o: $(OPIEDIR)/qmake/tools/qgcache.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qgcache.cpp qbitarray.o: $(OPIEDIR)/qmake/tools/qbitarray.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qbitarray.cpp qdir.o: $(OPIEDIR)/qmake/tools/qdir.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qdir.cpp quuid.o: $(OPIEDIR)/qmake/tools/quuid.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/quuid.cpp qfileinfo_unix.o: $(OPIEDIR)/qmake/tools/qfileinfo_unix.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qfileinfo_unix.cpp qdir_unix.o: $(OPIEDIR)/qmake/tools/qdir_unix.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qdir_unix.cpp qfileinfo.o: $(OPIEDIR)/qmake/tools/qfileinfo.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qfileinfo.cpp qdatetime.o: $(OPIEDIR)/qmake/tools/qdatetime.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qdatetime.cpp qstringlist.o: $(OPIEDIR)/qmake/tools/qstringlist.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qstringlist.cpp qmap.o: $(OPIEDIR)/qmake/tools/qmap.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qmap.cpp qconfig.o: $(OPIEDIR)/qmake/tools/qconfig.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(OPIEDIR)/qmake/tools/qconfig.cpp winmakefile.o: generators/win32/winmakefile.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/winmakefile.cpp project.o: project.cpp project.h option.h $(CXX) -c -o $@ $(CXXFLAGS) project.cpp +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 $(CXX) -c -o $@ $(CXXFLAGS) main.cpp option.o: option.cpp option.h $(CXX) -c -o $@ $(CXXFLAGS) option.cpp +qtmd5.o: qtmd5.cpp + $(CXX) -c -o $@ $(CXXFLAGS) qtmd5.cpp + makefile.o: generators/makefile.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/makefile.cpp unixmake.o: generators/unix/unixmake.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/unix/unixmake.cpp unixmake2.o: generators/unix/unixmake2.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/unix/unixmake2.cpp borland_bmake.o: generators/win32/borland_bmake.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/borland_bmake.cpp mingw_make.o: generators/win32/mingw_make.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/mingw_make.cpp msvc_objectmodel.o: generators/win32/msvc_objectmodel.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/msvc_objectmodel.cpp msvc_vcproj.o: generators/win32/msvc_vcproj.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/msvc_vcproj.cpp msvc_nmake.o: generators/win32/msvc_nmake.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/msvc_nmake.cpp metrowerks_xml.o: generators/mac/metrowerks_xml.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/mac/metrowerks_xml.cpp pbuilder_pbx.o: generators/mac/pbuilder_pbx.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/mac/pbuilder_pbx.cpp msvc_dsp.o: generators/win32/msvc_dsp.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/msvc_dsp.cpp projectgenerator.o: generators/projectgenerator.cpp $(CXX) -c -o $@ $(CXXFLAGS) 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,115 +1,112 @@ /**************************************************************************** -** $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. ** ** 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 "metrowerks_xml.h" #include "option.h" #include <qdir.h> #include <qdict.h> #include <qregexp.h> #include <stdlib.h> #include <time.h> -#ifdef Q_OS_MAC +#if !defined(QWS) && defined(Q_OS_MAC) #include <Carbon/Carbon.h> #include <sys/types.h> #include <sys/stat.h> #endif - MetrowerksMakefileGenerator::MetrowerksMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE) { } bool MetrowerksMakefileGenerator::writeMakefile(QTextStream &t) { if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { /* for now just dump, I need to generated an empty xml or something.. */ fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", var("QMAKE_FAILED_REQUIREMENTS").latin1()); return TRUE; } if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") { return writeMakeParts(t); } else if(project->first("TEMPLATE") == "subdirs") { writeHeader(t); qDebug("Not supported!"); return TRUE; } return FALSE; } bool MetrowerksMakefileGenerator::writeMakeParts(QTextStream &t) { //..grrr.. libs! QStringList extra_objs; bool do_libs = TRUE; if(project->first("TEMPLATE") == "app") extra_objs += project->variables()["QMAKE_CRT_OBJECTS"]; else if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) do_libs = FALSE; if(do_libs) extra_objs += project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator val_it = extra_objs.begin(); val_it != extra_objs.end(); ++val_it) { if((*val_it).startsWith("-L")) { QString dir((*val_it).right((*val_it).length() - 2)); fixEnvVariables(dir); if(project->variables()["DEPENDPATH"].findIndex(dir) == -1 && project->variables()["INCLUDEPATH"].findIndex(dir) == -1) project->variables()["INCLUDEPATH"].append(dir); } else if((*val_it).startsWith("-l")) { QString lib("lib" + (*val_it).right((*val_it).length() - 2) + "." + project->first("QMAKE_EXTENSION_SHLIB")); if(project->variables()["LIBRARIES"].findIndex(lib) == -1) project->variables()["LIBRARIES"].append(lib); } else if((*val_it) == "-framework") { ++val_it; if(val_it == extra_objs.end()) break; QString frmwrk = (*val_it) + ".framework"; if(project->variables()["FRAMEWORKS"].findIndex(frmwrk) == -1) project->variables()["FRAMEWORKS"].append(frmwrk); } else if((*val_it).left(1) != "-") { QString lib=(*val_it); int s = lib.findRev('/'); if(s != -1) { @@ -546,273 +543,273 @@ MetrowerksMakefileGenerator::init() ver << "0" << "0"; //make sure there are three project->variables()["VER_MAJ"].append(ver[0]); project->variables()["VER_MIN"].append(ver[1]); project->variables()["VER_PAT"].append(ver[2]); if( !project->isEmpty("LIBS") ) project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; if( project->variables()["QMAKE_EXTENSION_SHLIB"].isEmpty() ) project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dylib" ); if ( project->isActiveConfig("moc") ) { QString mocfile = project->first("TARGET"); if(project->first("TEMPLATE") == "lib") mocfile += project->isActiveConfig("staticlib") ? "_static" : "_shared"; project->variables()["MOCS"].append(mocfile + ".mocs"); setMocAware(TRUE); } if(!project->isEmpty("FORMS")) { QString uicfile = project->first("TARGET"); if(project->first("TEMPLATE") == "lib") uicfile += project->isActiveConfig("staticlib") ? "_static" : "_shared"; project->variables()["UICS"].append(uicfile + ".uics"); } if(project->isEmpty("DESTDIR")) project->variables()["DESTDIR"].append(QDir::currentDirPath()); MakefileGenerator::init(); if ( project->isActiveConfig("opengl") ) { project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"]; if ( (project->first("TARGET") == "qt") || (project->first("TARGET") == "qte") || (project->first("TARGET") == "qt-mt") ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL_QT"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; } if(project->isActiveConfig("qt")) project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; if(project->isEmpty("FRAMEWORKPATH")) project->variables()["FRAMEWORKPATH"].append("/System/Library/Frameworks/"); //set the target up project->variables()["TARGET_STEM"] = project->variables()["TARGET"]; if(project->first("TEMPLATE") == "lib") { if(project->isActiveConfig("staticlib")) project->variables()["TARGET"].first() = "lib" + project->first("TARGET") + ".lib"; else project->variables()["TARGET"].first() = "lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB"); project->variables()["CODEWARRIOR_VERSION"].append(project->first("VER_MAJ") + project->first("VER_MIN") + project->first("VER_PAT")); } else { project->variables()["CODEWARRIOR_VERSION"].append("0"); if(project->isEmpty("QMAKE_ENTRYPOINT")) project->variables()["QMAKE_ENTRYPOINT"].append("start"); project->variables()["CODEWARRIOR_ENTRYPOINT"].append( project->first("QMAKE_ENTRYPOINT")); } } QString -MetrowerksMakefileGenerator::findTemplate(QString file) +MetrowerksMakefileGenerator::findTemplate(const QString &file) { QString ret; if(!QFile::exists(ret = file) && !QFile::exists((ret = Option::mkfile::qmakespec + QDir::separator() + file)) && !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/mac-mwerks/" + file)) && !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file)))) return ""; return ret; } bool MetrowerksMakefileGenerator::createFork(const QString &f) { -#if defined(Q_OS_MACX) +#if !defined(QWS) && defined(Q_OS_MACX) FSRef fref; FSSpec fileSpec; if(QFile::exists(f)) { mode_t perms = 0; { struct stat s; stat(f.latin1(), &s); if(!(s.st_mode & S_IWUSR)) { perms = s.st_mode; chmod(f.latin1(), perms | S_IWUSR); } } FILE *o = fopen(f.latin1(), "a"); if(!o) return FALSE; if(FSPathMakeRef((const UInt8 *)f.latin1(), &fref, NULL) == noErr) { if(FSGetCatalogInfo(&fref, kFSCatInfoNone, NULL, NULL, &fileSpec, NULL) == noErr) FSpCreateResFile(&fileSpec, 'CUTE', 'TEXT', smSystemScript); else qDebug("bogus %d", __LINE__); } else qDebug("bogus %d", __LINE__); fclose(o); if(perms) chmod(f.latin1(), perms); } #else Q_UNUSED(f) #endif return TRUE; } bool MetrowerksMakefileGenerator::fixifyToMacPath(QString &p, QString &v, bool ) { v = "Absolute"; if(p.find(':') != -1) //guess its macish already return TRUE; static QString st_volume; if(st_volume.isEmpty()) { st_volume = var("QMAKE_VOLUMENAME"); -#ifdef Q_OS_MAC +#if !defined(QWS) && defined(Q_OS_MACX) if(st_volume.isEmpty()) { uchar foo[512]; HVolumeParam pb; memset(&pb, '\0', sizeof(pb)); pb.ioVRefNum = 0; pb.ioNamePtr = foo; if(PBHGetVInfoSync((HParmBlkPtr)&pb) == noErr) { int len = foo[0]; memcpy(foo,foo+1, len); foo[len] = '\0'; st_volume = (char *)foo; } } #endif } QString volume = st_volume; fixEnvVariables(p); if(p.startsWith("\"") && p.endsWith("\"")) p = p.mid(1, p.length() - 2); if(p.isEmpty()) return FALSE; if(!p.endsWith("/")) p += "/"; if(QDir::isRelativePath(p)) { if(p.startsWith("{")) { int eoc = p.find('}'); if(eoc == -1) return FALSE; volume = p.mid(1, eoc - 1); p = p.right(p.length() - eoc - 1); } else { QFileInfo fi(p); if(fi.convertToAbs()) //strange return FALSE; p = fi.filePath(); } } p = QDir::cleanDirPath(p); if(!volume.isEmpty()) v = volume; p.replace("/", ":"); if(p.right(1) != ":") p += ':'; return TRUE; } void MetrowerksMakefileGenerator::processPrlFiles() { QPtrList<MakefileDependDir> libdirs; libdirs.setAutoDelete(TRUE); const QString lflags[] = { "QMAKE_LIBS", QString::null }; for(int i = 0; !lflags[i].isNull(); i++) { for(bool ret = FALSE; TRUE; ret = FALSE) { QStringList l_out; QStringList &l = project->variables()[lflags[i]]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString opt = (*it); if(opt.startsWith("-")) { if(opt.startsWith("-L")) { QString r = opt.right(opt.length() - 2), l = r; fixEnvVariables(l); libdirs.append(new MakefileDependDir(r.replace( "\"", ""), l.replace( "\"", ""))); } else if(opt.left(2) == "-l") { QString lib = opt.right(opt.length() - 2), prl; 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)) { if(prl.startsWith(mdd->local_dir)) prl.replace(0, mdd->local_dir.length(), mdd->real_dir); QRegExp reg("^.*lib(" + lib + "[^.]*)\\." + project->first("QMAKE_EXTENSION_SHLIB") + "$"); if(reg.exactMatch(prl)) prl = "-l" + reg.cap(1); opt = prl; ret = TRUE; break; } } } else if(opt == "-framework") { l_out.append(opt); ++it; opt = (*it); QString prl = "/System/Library/Frameworks/" + opt + - ".framework/" + opt + Option::prl_ext; + ".framework/" + opt; if(processPrlFile(prl)) ret = TRUE; } if(!opt.isEmpty()) l_out.append(opt); } else { if(processPrlFile(opt)) ret = TRUE; if(!opt.isEmpty()) l_out.append(opt); } } if(ret) l = l_out; else break; } } } void MetrowerksMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l) { if(var == "QMAKE_PRL_LIBS") { QStringList &out = project->variables()["QMAKE_LIBS"]; for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { bool append = TRUE; if((*it).startsWith("-")) { if((*it).startsWith("-l") || (*it).startsWith("-L")) { append = out.findIndex((*it)) == -1; } else if((*it).startsWith("-framework")) { ++it; for(QStringList::ConstIterator outit = out.begin(); outit != out.end(); ++it) { if((*outit) == "-framework") { ++outit; if((*outit) == (*it)) { append = FALSE; break; } } } } } else if(QFile::exists((*it))) { append = out.findIndex((*it)); } if(append) out.append((*it)); } } else { MakefileGenerator::processPrlVariable(var, l); } } bool MetrowerksMakefileGenerator::openOutput(QFile &file) const { QString outdir; if(!file.name().isEmpty()) { QFileInfo fi(file); if(fi.isDir()) outdir = file.name() + QDir::separator(); } 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,69 +1,68 @@ /**************************************************************************** -** $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. ** ** 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 __METROWERKSMAKE_H__ -#define __METROWERKSMAKE_H__ + +#ifndef __METROWERKS_XML_H__ +#define __METROWERKS_XML_H__ #include "makefile.h" class MetrowerksMakefileGenerator : public MakefileGenerator { bool createFork(const QString &f); bool fixifyToMacPath(QString &c, QString &v, bool exists=TRUE); bool init_flag; bool writeMakeParts(QTextStream &); bool writeSubDirs(QTextStream &); bool writeMakefile(QTextStream &); - QString findTemplate(QString file); + QString findTemplate(const QString &file); void init(); public: MetrowerksMakefileGenerator(QMakeProject *p); ~MetrowerksMakefileGenerator(); bool openOutput(QFile &file) const; protected: virtual void processPrlFiles(); virtual void processPrlVariable(const QString &var, const QStringList &l); virtual bool doDepends() const { return FALSE; } //never necesary }; 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,983 +1,1396 @@ /**************************************************************************** -** $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. ** ** 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 "pbuilder_pbx.h" #include "option.h" +#include "meta.h" #include <qdir.h> #include <qdict.h> #include <qregexp.h> #include <stdlib.h> #include <time.h> +#include "qtmd5.h" #ifdef Q_OS_UNIX # include <sys/types.h> # include <sys/stat.h> #endif // Note: this is fairly hacky, but it does the job... - ProjectBuilderMakefileGenerator::ProjectBuilderMakefileGenerator(QMakeProject *p) : UnixMakefileGenerator(p) { } bool ProjectBuilderMakefileGenerator::writeMakefile(QTextStream &t) { if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { /* for now just dump, I need to generated an empty xml or something.. */ fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", var("QMAKE_FAILED_REQUIREMENTS").latin1()); return TRUE; } project->variables()["MAKEFILE"].clear(); 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; } 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) { int i; QStringList tmp; bool did_preprocess = FALSE; //HEADER t << "// !$*UTF8*$!" << "\n" << "{" << "\n" << "\t" << "archiveVersion = 1;" << "\n" << "\t" << "classes = {" << "\n" << "\t" << "};" << "\n" << "\t" << "objectVersion = " << pbuilderVersion() << ";" << "\n" << "\t" << "objects = {" << endl; //MAKE QMAKE equivlant if(!project->isActiveConfig("no_autoqmake") && project->projectFile() != "(stdin)") { QString mkfile = pbx_dir + Option::dir_sep + "qt_makeqmake.mak"; QFile mkf(mkfile); if(mkf.open(IO_WriteOnly | IO_Translate)) { debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1()); QTextStream mkt(&mkf); writeHeader(mkt); mkt << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("$(QTDIR)/bin/qmake") : var("QMAKE_QMAKE")) << endl; writeMakeQmake(mkt); mkf.close(); } QString phase_key = keyFor("QMAKE_PBX_MAKEQMAKE_BUILDPHASE"); 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" << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" << "\t\t\t" << "files = (" << "\n" << "\t\t\t" << ");" << "\n" << "\t\t\t" << "generatedFileNames = (" << "\n" << "\t\t\t" << ");" << "\n" << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n" << "\t\t\t" << "name = \"Qt Qmake\";" << "\n" << "\t\t\t" << "neededFileNames = (" << "\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"; } //DUMP SOURCES 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") { if(project->first("TEMPLATE") == "app" && !project->isEmpty("RC_FILE")) { //Icon QString icns_file = keyFor("ICNS_FILE"); src_list.append(icns_file); t << "\t\t" << icns_file << " = {" << "\n" << "\t\t\t" << "isa = PBXFileReference;" << "\n" << "\t\t\t" << "path = \"" << project->first("RC_FILE") << "\";" << "\n" << "\t\t\t" << "refType = " << reftypeForFile(project->first("RC_FILE")) << ";" << "\n" << "\t\t" << "};" << "\n"; t << "\t\t" << keyFor("ICNS_FILE_REFERENCE") << " = {" << "\n" << "\t\t\t" << "fileRef = " << icns_file << ";" << "\n" << "\t\t\t" << "isa = PBXBuildFile;" << "\n" << "\t\t\t" << "settings = {" << "\n" << "\t\t\t" << "};" << "\n" << "\t\t" << "};" << "\n"; } - 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" << "\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"; } //PREPROCESS BUILDPHASE (just a makefile) if(!project->isEmpty("UICIMPLS") || !project->isEmpty("SRCMOC") || !project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES")) { QString mkfile = pbx_dir + Option::dir_sep + "qt_preprocess.mak"; QFile mkf(mkfile); if(mkf.open(IO_WriteOnly | IO_Translate)) { did_preprocess = TRUE; debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1()); QTextStream mkt(&mkf); 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; mkt << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl; mkt << "YACC = " << var("QMAKE_YACC") << endl; mkt << "YACCFLAGS = " << var("QMAKE_YACCFLAGS") << endl; mkt << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; mkt << "MOVE = " << var("QMAKE_MOVE") << endl << endl; mkt << "FORMS = " << varList("UICIMPLS") << endl; + mkt << "IMAGES = " << varList("QMAKE_IMAGE_COLLECTION") << endl; mkt << "MOCS = " << varList("SRCMOC") << endl; mkt << "PARSERS ="; if(!project->isEmpty("YACCSOURCES")) { QStringList &yaccs = project->variables()["YACCSOURCES"]; for(QStringList::Iterator yit = yaccs.begin(); yit != yaccs.end(); ++yit) { QFileInfo fi((*yit)); mkt << " " << fi.dirPath() << Option::dir_sep << fi.baseName(TRUE) << Option::yacc_mod << Option::cpp_ext.first(); } } if(!project->isEmpty("LEXSOURCES")) { QStringList &lexs = project->variables()["LEXSOURCES"]; for(QStringList::Iterator lit = lexs.begin(); lit != lexs.end(); ++lit) { QFileInfo fi((*lit)); mkt << " " << fi.dirPath() << Option::dir_sep << fi.baseName(TRUE) << Option::lex_mod << Option::cpp_ext.first(); } } 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"; if(!project->isEmpty("SRCMOC")) mkt << "\t-rm -f $(MOCS)" << "\n"; mkt << "uiclean:" << "\n"; if(!project->isEmpty("UICIMPLS")) mkt << "\t-rm -f $(FORMS)" << "\n"; + if(!project->isEmpty("QMAKE_IMAGE_COLLECTION")) + mkt << "\t-rm -f $(IMAGES)" << "\n"; mkt << "parser_clean:" << "\n"; if(!project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES")) mkt << "\t-rm -f $(PARSERS)" << "\n"; writeUicSrc(mkt, "FORMS"); writeMocSrc(mkt, "HEADERS"); writeMocSrc(mkt, "SOURCES"); writeMocSrc(mkt, "UICDECLS"); writeYaccSrc(mkt, "YACCSOURCES"); 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 if(!project->isEmpty("QMAKE_PBX_OBJ")) { QString grp = "Build Sources", key = keyFor(grp); project->variables()["QMAKE_PBX_BUILDPHASES"].append(key); t << "\t\t" << key << " = {" << "\n" << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" << "\t\t\t" << "files = (" << "\n" << varGlue("QMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n") << "\t\t\t" << ");" << "\n" << "\t\t\t" << "isa = PBXSourcesBuildPhase;" << "\n" << "\t\t\t" << "name = \"" << grp << "\";" << "\n" << "\t\t" << "};" << "\n"; } if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES 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++) { tmp = project->variables()[libs[i]]; for(QStringList::Iterator it = tmp.begin(); it != tmp.end();) { bool remove = FALSE; 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")) { QString r = opt.right(opt.length() - 2); fixEnvVariables(r); libdirs.append(r); + } else if(opt == "-prebind") { + project->variables()["QMAKE_DO_PREBINDING"].append("TRUE"); + remove = TRUE; } else if(opt.startsWith("-l")) { name = opt.right(opt.length() - 2); QString lib("lib" + name); for(QStringList::Iterator lit = libdirs.begin(); lit != libdirs.end(); ++lit) { 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 in the ProjectFile. If the prl format ever changes (not likely) then this will not really work. However, more concerning is that it will encode the version number in the Project file which might be a bad things in days to come? --Sam */ - 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; } } - } } if(!remove) { QString extns[] = { ".dylib", ".so", ".a", QString::null }; for(int n = 0; !remove && !extns[n].isNull(); n++) { QString tmp = (*lit) + Option::dir_sep + lib + extns[n]; if(QFile::exists(tmp)) { library = tmp; debug_msg(1, "pbuilder: Found library (%s) via %s", opt.latin1(), library.latin1()); remove = TRUE; } } } } } else if(opt == "-framework") { ++it; if(it == tmp.end()) break; QStringList &fdirs = project->variables()["QMAKE_FRAMEWORKDIR"]; if(fdirs.isEmpty()) fdirs.append("/System/Library/Frameworks/"); for(QStringList::Iterator fit = fdirs.begin(); fit != fdirs.end(); ++fit) { if(QFile::exists((*fit) + QDir::separator() + (*it) + ".framework")) { --it; it = tmp.remove(it); remove = TRUE; library = (*fit) + Option::dir_sep + (*it) + ".framework"; break; } } + } else if(opt == "-undefined") { + ++it; //the next option is not a library.. } else if(opt.left(1) != "-") { remove = TRUE; library = opt; } if(!library.isEmpty()) { if(name.isEmpty()) { int slsh = library.findRev(Option::dir_sep); if(slsh != -1) name = library.right(library.length() - slsh - 1); } library = fileFixify(library); QString key = keyFor(library); bool is_frmwrk = (library.endsWith(".framework")); t << "\t\t" << key << " = {" << "\n" << "\t\t\t" << "isa = " << (is_frmwrk ? "PBXFrameworkReference" : "PBXFileReference") << ";" << "\n" << "\t\t\t" << "name = \"" << name << "\";" << "\n" << "\t\t\t" << "path = \"" << library << "\";" << "\n" << "\t\t\t" << "refType = " << reftypeForFile(library) << ";" << "\n" << "\t\t" << "};" << "\n"; project->variables()["QMAKE_PBX_LIBRARIES"].append(key); QString obj_key = library + ".o"; obj_key = keyFor(obj_key); t << "\t\t" << obj_key << " = {" << "\n" << "\t\t\t" << "fileRef = " << key << ";" << "\n" << "\t\t\t" << "isa = PBXBuildFile;" << "\n" << "\t\t\t" << "settings = {" << "\n" << "\t\t\t" << "};" << "\n" << "\t\t" << "};" << "\n"; project->variables()["QMAKE_PBX_BUILD_LIBRARIES"].append(obj_key); } if(remove) it = tmp.remove(it); else ++it; } project->variables()[libs[i]] = tmp; } } //SUBLIBS BUILDPHASE (just another makefile) if(!project->isEmpty("SUBLIBS")) { QString mkfile = pbx_dir + Option::dir_sep + "qt_sublibs.mak"; QFile mkf(mkfile); if(mkf.open(IO_WriteOnly | IO_Translate)) { debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1()); QTextStream mkt(&mkf); writeHeader(mkt); mkt << "SUBLIBS= "; tmp = project->variables()["SUBLIBS"]; QStringList::Iterator it; for(it = tmp.begin(); it != tmp.end(); ++it) t << "tmp/lib" << (*it) << ".a "; t << endl << endl; mkt << "sublibs: $(SUBLIBS)" << endl << endl; tmp = project->variables()["SUBLIBS"]; for(it = tmp.begin(); it != tmp.end(); ++it) t << "tmp/lib" << (*it) << ".a" << ":\n\t" << var(QString("MAKELIB") + (*it)) << endl << endl; mkf.close(); } QString phase_key = keyFor("QMAKE_PBX_SUBLIBS_BUILDPHASE"); 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" << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" << "\t\t\t" << "files = (" << "\n" << "\t\t\t" << ");" << "\n" << "\t\t\t" << "generatedFileNames = (" << "\n" << "\t\t\t" << ");" << "\n" << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n" << "\t\t\t" << "name = \"Qt Sublibs\";" << "\n" << "\t\t\t" << "neededFileNames = (" << "\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"; } //LIBRARY BUILDPHASE if(!project->isEmpty("QMAKE_PBX_LIBRARIES")) { tmp = project->variables()["QMAKE_PBX_LIBRARIES"]; if(!tmp.isEmpty()) { QString grp("External Frameworks and Libraries"), key = keyFor(grp); project->variables()["QMAKE_PBX_GROUPS"].append(key); t << "\t\t" << key << " = {" << "\n" << "\t\t\t" << "children = (" << "\n" << varGlue("QMAKE_PBX_LIBRARIES", "\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" << "path = \"\";" << "\n" << "\t\t\t" << "refType = 4;" << "\n" << "\t\t" << "};" << "\n"; } } { QString grp("Frameworks & Libraries"), key = keyFor(grp); project->variables()["QMAKE_PBX_BUILDPHASES"].append(key); t << "\t\t" << key << " = {" << "\n" << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" << "\t\t\t" << "files = (" << "\n" << varGlue("QMAKE_PBX_BUILD_LIBRARIES", "\t\t\t\t", ",\n\t\t\t\t", "\n") << "\t\t\t" << ");" << "\n" << "\t\t\t" << "isa = PBXFrameworksBuildPhase;" << "\n" << "\t\t\t" << "name = \"" << grp << "\";" << "\n" << "\t\t" << "};" << "\n"; } - 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); project->variables()["QMAKE_PBX_BUILDPHASES"].append(key); t << "\t\t" << key << " = {" << "\n" << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" << "\t\t\t" << "files = (" << "\n" << (!project->isEmpty("RC_FILE") ? keyFor("ICNS_FILE_REFERENCE") : QString("")) << "\t\t\t" << ");" << "\n" << "\t\t\t" << "isa = PBXResourcesBuildPhase;" << "\n" << "\t\t\t" << "name = \"" << grp << "\";" << "\n" << "\t\t" << "};" << "\n"; } - - //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) QString targ = project->first("TARGET"); if(project->first("TEMPLATE") == "app" || (project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && project->isActiveConfig("frameworklib"))) targ = project->first("QMAKE_ORIG_TARGET"); int slsh = targ.findRev(Option::dir_sep); if(slsh != -1) targ = targ.right(targ.length() - slsh - 1); fixEnvVariables(targ); QStringList links; if(project->first("TEMPLATE") == "app") { if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) targ += ".app"; - } else if(!project->isActiveConfig("staticlib") && + } else if(!project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin") && !project->isActiveConfig("frameworklib")) { QString li[] = { "TARGET_", "TARGET_x", "TARGET_x.y", QString::null }; for(int n = 0; !li[n].isNull(); n++) { QString t = project->first(li[n]); slsh = t.findRev(Option::dir_sep); if(slsh != -1) t = t.right(t.length() - slsh); fixEnvVariables(t); links << t; } } QString script = pbx_dir + Option::dir_sep + "qt_install.sh"; QFile shf(script); if(shf.open(IO_WriteOnly | IO_Translate)) { debug_msg(1, "pbuilder: Creating file: %s", script.latin1()); QString targ = project->first("QMAKE_ORIG_TARGET"), cpflags; if(project->first("TEMPLATE") == "app") { targ = project->first("TARGET"); - if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { + if(!project->isActiveConfig("console")) { targ += ".app"; cpflags += "-r "; } } else if(!project->isActiveConfig("frameworklib")) { if(project->isActiveConfig("staticlib")) targ = project->first("TARGET"); else 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"); fixEnvVariables(dstdir); + 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; //create all the version symlinks (just to be like unixmake) for(QStringList::Iterator it = links.begin(); it != links.end(); ++it) { if(targ != (*it)) sht << "ln -sf \"" << targ << "\" " << "\"" << dstdir << (*it) << "\"" << endl; } shf.close(); #ifdef Q_OS_UNIX chmod(script.latin1(), S_IRWXU | S_IRWXG); #endif QString phase_key = keyFor("QMAKE_PBX_INSTALL_BUILDPHASE"); script = fileFixify(script, QDir::currentDirPath()); project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key); 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" << "\t\t\t" << ");" << "\n" << "\t\t\t" << "generatedFileNames = (" << "\n" << "\t\t\t" << ");" << "\n" << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n" << "\t\t\t" << "name = \"Qt Install\";" << "\n" << "\t\t\t" << "neededFileNames = (" << "\n" << "\t\t\t" << ");" << "\n" << "\t\t\t" << "shellPath = /bin/sh;" << "\n" << "\t\t\t" << "shellScript = \"" << script << "\";" << "\n" << "\t\t" << "};" << "\n"; } } + 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 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" << "name = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n" << "\t\t\t" << "path = \"\";" << "\n" << "\t\t\t" << "refType = 4;" << "\n" << "\t\t" << "};" << "\n"; //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") { QString targ = project->first("QMAKE_ORIG_TARGET"); if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { targ += ".app"; t << "\t\t\t" << "isa = PBXApplicationReference;" << "\n"; } else { t << "\t\t\t" << "isa = PBXExecutableFileReference;" << "\n"; } QString app = (!project->isEmpty("DESTDIR") ? project->first("DESTDIR") + project->first("QMAKE_ORIG_TARGET") : QDir::currentDirPath()) + Option::dir_sep + targ; t << "\t\t\t" << "name = " << targ << ";" << "\n" << "\t\t\t" << "path = \"" << targ << "\";" << "\n" << "\t\t\t" << "refType = " << reftypeForFile(app) << ";" << "\n"; } else { QString lib = project->first("QMAKE_ORIG_TARGET"); if(project->isActiveConfig("staticlib")) { lib = project->first("TARGET"); } else 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); 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") << "\t\t\t" << ");" << "\n" << "\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" << "\t\t\t\t" << "HEADER_SEARCH_PATHS = \"" << fixEnvsList("INCLUDEPATH") << " " << fixEnvs(specdir()) << "\";" << "\n" << "\t\t\t\t" << "LIBRARY_SEARCH_PATHS = \"" << var("QMAKE_PBX_LIBPATHS") << "\";" << "\n" << "\t\t\t\t" << "OPTIMIZATION_CFLAGS = \"\";" << "\n" << "\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" << "\t\t\t\t" << "YACCFLAGS = \"" << var("QMAKE_YACCFLAGS") << "\";" << "\n" << "\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 t << "\t\t\t\t" << "BUILD_ROOT = \"" << QDir::currentDirPath() << "\";" << "\n"; #endif if(!project->isActiveConfig("staticlib")) t << "\t\t\t\t" << "OTHER_LDFLAGS = \"" << fixEnvsList("SUBLIBS") << " " << fixEnvsList("QMAKE_LFLAGS") << " " << fixEnvsList("QMAKE_LIBDIR_FLAGS") << " " << 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"; t << "\t\t\t\t" << "PRODUCT_NAME = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n"; } 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"; } 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" << "\t\t\t" << "conditionalBuildSettings = {" << "\n" << "\t\t\t" << "};" << "\n" << "\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" << "\t\t\t" << "productName = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n"; } else { 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")) t << "\t\t\t" << "productInstallPath = \"" << project->first("DESTDIR") << "\";" << "\n"; t << "\t\t" << "};" << "\n"; //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); 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) + 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" << "\t\t\t" << "isa = PBXBuildStyle;" << "\n" << "\t\t\t" << "name = " << (as_release ? "Deployment" : "Development") << ";" << "\n" << "\t\t" << "};" << "\n"; } //ROOT t << "\t\t" << keyFor("QMAKE_PBX_ROOT") << " = {" << "\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" << "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" << "\t\t" << "};" << "\n"; //FOOTER t << "\t" << "};" << "\n" << "\t" << "rootObject = " << keyFor("QMAKE_PBX_ROOT") << ";" << "\n" << "}" << endl; - 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; + } } return TRUE; } 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) { QRegExp reg_var("\\$\\((.*)\\)"); for(int rep = 0; (rep = reg_var.search(file, rep)) != -1; ) { if(project->variables()["QMAKE_PBX_VARS"].findIndex(reg_var.cap(1)) == -1) project->variables()["QMAKE_PBX_VARS"].append(reg_var.cap(1)); rep += reg_var.matchedLength(); } return file; } QString -ProjectBuilderMakefileGenerator::fixEnvsList(QString where) +ProjectBuilderMakefileGenerator::fixEnvsList(const QString &where) { QString ret; const QStringList &l = project->variables()[where]; for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { fixEnvs((*it)); if(!ret.isEmpty()) ret += " "; ret += (*it); } return ret; } 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); } else { ret = keys[block]; } return ret; } bool 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; } /* This function is such a hack it is almost pointless, but it eliminates the warning message from ProjectBuilder that the project file is for an older version. I guess this could be used someday if the format of the output is dependant upon the version of ProjectBuilder as well. */ int ProjectBuilderMakefileGenerator::pbuilderVersion() const { QString ret; if(project->isEmpty("QMAKE_PBUILDER_VERSION")) { 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); if(version_file.open(IO_ReadOnly)) { debug_msg(1, "pbuilder: version.plist: Reading file: %s", version_plist.latin1()); QTextStream plist(&version_file); bool in_dict = FALSE; QString current_key; QRegExp keyreg("^<key>(.*)</key>$"), stringreg("^<string>(.*)</string>$"); while(!plist.eof()) { QString line = plist.readLine().stripWhiteSpace(); if(line == "<dict>") in_dict = TRUE; else if(line == "</dict>") in_dict = FALSE; else if(in_dict) { if(keyreg.exactMatch(line)) current_key = keyreg.cap(1); else if(current_key == "CFBundleShortVersionString" && stringreg.exactMatch(line)) version = stringreg.cap(1); } } 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 { ret = project->first("QMAKE_PBUILDER_VERSION"); } if(!ret.isEmpty()) { bool ok; int int_ret = ret.toInt(&ok); if(ok) { debug_msg(1, "pbuilder: version.plist: Got version: %d", int_ret); return int_ret; } } debug_msg(1, "pbuilder: version.plist: Fallback to default version"); return 34; //my fallback } -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,68 +1,75 @@ /**************************************************************************** -** $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. ** ** 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 __PBUILDERMAKE_H__ -#define __PBUILDERMAKE_H__ + +#ifndef __PBUILDER_PBX_H__ +#define __PBUILDER_PBX_H__ #include "unixmake.h" class ProjectBuilderMakefileGenerator : public UnixMakefileGenerator { QString pbx_dir; int pbuilderVersion() const; + bool writeSubdirs(QTextStream &, bool); bool writeMakeParts(QTextStream &); bool writeMakefile(QTextStream &); + 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; public: ProjectBuilderMakefileGenerator(QMakeProject *p); ~ProjectBuilderMakefileGenerator(); virtual bool openOutput(QFile &) const; protected: + bool doPrecompiledHeaders() const { return FALSE; } virtual bool doDepends() const { return FALSE; } //never necesary }; 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,1841 +1,2038 @@ /**************************************************************************** -** $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. ** ** 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 "makefile.h" #include "option.h" +#include "meta.h" #include <qdir.h> #include <qfile.h> #include <qtextstream.h> #include <qregexp.h> #include <qdict.h> #if defined(Q_OS_UNIX) #include <unistd.h> #else #include <io.h> #endif #include <stdio.h> #include <stdlib.h> #include <time.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> // Well, Windows doesn't have this, so here's the macro #ifndef S_ISDIR #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif +#define QMAKE_EOL(x) (x == '\r' || x == '\n') -static QString mkdir_p_asstring(const QString &dir) +QString mkdir_p_asstring(const QString &dir) { QString ret = "@$(CHK_DIR_EXISTS) \"" + dir + "\" "; if(Option::target_mode == Option::TARG_WIN_MODE) ret += "$(MKDIR)"; else ret += "|| $(MKDIR)"; ret += " \"" + dir + "\""; return ret; } static bool createDir(const QString& fullPath) { if(QFile::exists(fullPath)) return FALSE; - QDir dirTmp; bool ret = TRUE; QString pathComponent, tmpPath; QStringList hierarchy = QStringList::split(QString(Option::dir_sep), fullPath, TRUE); for(QStringList::Iterator it = hierarchy.begin(); it != hierarchy.end(); ++it) { pathComponent = *it + QDir::separator(); tmpPath += pathComponent; if(!dirTmp.mkdir(tmpPath)) { ret = FALSE; // break; } } return ret; } MakefileGenerator::MakefileGenerator(QMakeProject *p) : init_opath_already(FALSE), init_already(FALSE), moc_aware(FALSE), no_io(FALSE), project(p) { } static char *gimme_buffer(off_t s) { static char *big_buffer = NULL; static int big_buffer_size = 0; if(!big_buffer || big_buffer_size < s) big_buffer = (char *)realloc(big_buffer, s); return big_buffer; } bool MakefileGenerator::generateMocList(const QString &fn_target) { if(!findMocDestination(fn_target).isEmpty()) return TRUE; QString fn_local = Option::fixPathToLocalOS(fileFixify(fn_target, QDir::currentDirPath(), Option::output_dir)); int file = open(fn_local.latin1(), O_RDONLY); if(file == -1) return FALSE; struct stat fst; if(fstat(file, &fst) || S_ISDIR(fst.st_mode)) return FALSE; //shouldn't happen char *big_buffer = gimme_buffer(fst.st_size); int total_size_read; for(int have_read = total_size_read = 0; (have_read = read(file, big_buffer + total_size_read, fst.st_size - total_size_read)); total_size_read += have_read); close(file); bool ignore_qobject = FALSE; int line_count = 1; /* qmake ignore Q_OBJECT */ #define COMP_LEN 8 //strlen("Q_OBJECT") #define OBJ_LEN 8 //strlen("Q_OBJECT") #define DIS_LEN 10 //strlen("Q_DISPATCH") int x; for(x = 0; x < (total_size_read-COMP_LEN); x++) { if(*(big_buffer + x) == '/') { x++; if(total_size_read >= x) { 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++; } else if(*(big_buffer + x) == '*') { //c style comment for( ;x < total_size_read; x++) { if(*(big_buffer + x) == 't' || *(big_buffer + x) == 'q') { //ignore if(total_size_read >= (x + 20)) { if(!strncmp(big_buffer + x + 1, "make ignore Q_OBJECT", 20)) { debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_OBJECT\"", fn_target.latin1(), line_count); x += 20; ignore_qobject = TRUE; } } } else if(*(big_buffer + x) == '*') { if(total_size_read >= (x+1) && *(big_buffer + (x+1)) == '/') { x += 2; break; } - } else if(*(big_buffer + x) == '\n') { + } else if(QMAKE_EOL(*(big_buffer + x))) { line_count++; } } } } } #define SYMBOL_CHAR(x) ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z') || \ (x <= '0' && x >= '9') || x == '_') bool interesting = *(big_buffer+x) == 'Q' && (!strncmp(big_buffer+x, "Q_OBJECT", OBJ_LEN) || !strncmp(big_buffer+x, "Q_DISPATCH", DIS_LEN)); if(interesting) { int len = 0; if(!strncmp(big_buffer+x, "Q_OBJECT", OBJ_LEN)) { if(ignore_qobject) { debug_msg(2, "Mocgen: %s:%d Ignoring Q_OBJECT", fn_target.latin1(), line_count); interesting = FALSE; } len=OBJ_LEN; } else if(!strncmp(big_buffer+x, "Q_DISPATCH", DIS_LEN)) { len=DIS_LEN; } if(SYMBOL_CHAR(*(big_buffer+x+len))) interesting = FALSE; if(interesting) { *(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); int ext_pos = fn_target.findRev('.'); int ext_len = fn_target.length() - ext_pos; int dir_pos = fn_target.findRev(Option::dir_sep, ext_pos); QString mocFile; if(!project->isEmpty("MOC_DIR")) mocFile = project->first("MOC_DIR"); else if(dir_pos != -1) mocFile = fn_target.left(dir_pos+1); 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) { if((cpp_ext = (fn_target.right(ext_len) == (*cppit)))) break; } 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"); project->variables()["_HDRMOC"].append(mocFile); break; } } } if(!mocFile.isEmpty()) { mocFile = Option::fixPathToTargetOS(mocFile); mocablesToMOC[cleanFilePath(fn_target)] = mocFile; mocablesFromMOC[cleanFilePath(mocFile)] = fn_target; } break; } } while(x < total_size_read && SYMBOL_CHAR(*(big_buffer+x))) x++; - if(*(big_buffer+x) == '\n') + if(QMAKE_EOL(*(big_buffer+x))) line_count++; } #undef OBJ_LEN #undef DIS_LEN return TRUE; } bool MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const QString &f, bool recurse) { - 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); fn = Option::fixPathToLocalOS(fn, FALSE); QString fix_env_fn = Option::fixPathToLocalOS(fn); int file = open(fix_env_fn.latin1(), O_RDONLY); if(file == -1) return FALSE; struct stat fst; if(fstat(file, &fst) || S_ISDIR(fst.st_mode)) return FALSE; //shouldn't happen QString fndir, fix_env_fndir; int dl = fn.findRev(Option::dir_sep); if(dl != -1) fndir = fn.left(dl+1); dl = fix_env_fn.findRev(Option::dir_sep); if(dl != -1) fix_env_fndir = fix_env_fn.left(dl + 1); int line_count = 1; char *big_buffer = gimme_buffer(fst.st_size); int total_size_read; for(int have_read = total_size_read = 0; (have_read = read(file, big_buffer + total_size_read, fst.st_size - total_size_read)); total_size_read += have_read); close(file); bool ui_file = fn.endsWith(Option::ui_ext); for(int x = 0; x < total_size_read; x++) { QStringList *outdeps=&fndeps; QString inc; if(!ui_file) { if(*(big_buffer + x) == '/') { x++; if(total_size_read >= x) { 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 for( ; x < total_size_read; x++) { if(*(big_buffer + x) == '*') { if(total_size_read >= (x+1) && *(big_buffer + (x+1)) == '/') { x += 2; break; } - } else if(*(big_buffer + x) == '\n') { + } else if(QMAKE_EOL(*(big_buffer + x))) { line_count++; } } } } } + while(x < total_size_read && //Skip spaces + (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t')) + x++; if(*(big_buffer + x) == '#') { x++; while(x < total_size_read && //Skip spaces after hash (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t')) x++; if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include", 7) && (*(big_buffer + x + 7) == ' ' || *(big_buffer + x + 7) == '\t' || *(big_buffer + x + 7) == '<' || *(big_buffer + x + 7) == '"')) { for(x+=7; //skip spaces after keyword x < total_size_read && (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t'); x++); char term = *(big_buffer + x); if(term == '"'); else if(term == '<') term = '>'; else continue; //wtf? x++; 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'; inc = big_buffer + x; } else if(total_size_read >= x + 14 && !strncmp(big_buffer + x, "qmake_warning ", 14)) { for(x+=14; //skip spaces after keyword x < total_size_read && (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t'); x++); - char term = '\n'; + char term = 0; if(*(big_buffer + x) == '"') term = '"'; if(*(big_buffer + x) == '\'') term = '\''; - if(term != '\n') + if(term) x++; 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'; QString msg = big_buffer + x; debug_msg(0, "%s:%d qmake_warning -- %s", fix_env_fn.latin1(), line_count, msg.latin1()); - *(big_buffer + x + msg_len) = term; //put it back + *(big_buffer + x + msg_len) = saved_term; //put it back } } } else if(ui_file) { // skip whitespaces while(x < total_size_read && (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t')) x++; if(*(big_buffer + x) == '<') { x++; if(total_size_read >= x + 12 && !strncmp(big_buffer + x, "includehint", 11) && (*(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; for(x += 1 ; *(big_buffer + x + inc_len) != '<'; inc_len++); *(big_buffer + x + inc_len) = '\0'; 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) && (*(big_buffer + x + 7) == ' ' || *(big_buffer + x + 7) == '>')) { for(x += 8; *(big_buffer + x) != '>'; x++) { if(total_size_read >= x + 9 && *(big_buffer + x) == 'i' && !strncmp(big_buffer + x, "impldecl", 8)) { for(x += 8; *(big_buffer + x) != '='; x++); if(*(big_buffer + x) != '=') continue; for(x++; *(big_buffer+x) == '\t' || *(big_buffer+x) == ' '; x++); char quote = 0; if(*(big_buffer+x) == '\'' || *(big_buffer+x) == '"') { quote = *(big_buffer + x); x++; } int val_len; for(val_len = 0; TRUE; val_len++) { if(quote) { if(*(big_buffer+x+val_len) == quote) break; } else if(*(big_buffer + x + val_len) == '>' || *(big_buffer + x + val_len) == ' ') { break; } } char saved = *(big_buffer + x + val_len); *(big_buffer + x + val_len) = '\0'; QString where = big_buffer + x; *(big_buffer + x + val_len) = saved; if(where == "in implementation") { QString cpp = fn.left(fn.length() - Option::ui_ext.length()) + Option::cpp_ext.first(); outdeps = &findDependencies(cpp); } } } int inc_len = 0; for(x += 1 ; *(big_buffer + x + inc_len) != '<'; inc_len++); *(big_buffer + x + inc_len) = '\0'; inc = big_buffer + x; } } } if(!inc.isEmpty()) { bool from_source_dir = TRUE; debug_msg(5, "%s:%d Found dependency to %s", fix_env_fn.latin1(), line_count, inc.latin1()); if(!project->isEmpty("SKIP_DEPENDS")) { bool found = FALSE; QStringList &nodeplist = project->values("SKIP_DEPENDS"); for(QStringList::Iterator it = nodeplist.begin(); it != nodeplist.end(); ++it) { QRegExp regx((*it)); if(regx.search(inc) != -1) { found = TRUE; break; } } if(found) continue; } - QString fqn; if(project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH") && !stat(fix_env_fndir + inc, &fst) && !S_ISDIR(fst.st_mode)) { fqn = fndir + inc; 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 { if((Option::target_mode == Option::TARG_MAC9_MODE && inc.find(':')) || (Option::target_mode == Option::TARG_WIN_MODE && inc[1] != ':') || ((Option::target_mode == Option::TARG_UNIX_MODE || Option::target_mode == Option::TARG_QNX6_MODE || Option::target_mode == Option::TARG_MACX_MODE) && inc[0] != '/')) { for(MakefileDependDir *mdd = dirs.first(); mdd; mdd = dirs.next() ) { if(!stat(mdd->local_dir + QDir::separator() + inc, &fst) && !S_ISDIR(fst.st_mode)) { fqn = mdd->real_dir + QDir::separator() + inc; goto handle_fqn; } } } } if(fqn.isEmpty() && Option::mkfile::do_dep_heuristics) { //these are some hacky heuristics it will try to do on an include //however these can be turned off at runtime, I'm not sure how //reliable these will be, most likely when problems arise turn it off //and see if they go away.. if(depHeuristics.contains(inc)) { fqn = depHeuristics[inc]; + from_source_dir = FALSE; } else if(Option::mkfile::do_dep_heuristics) { //some heuristics.. //is it a file from a .ui? QString inc_file = inc.section(Option::dir_sep, -1); int extn = inc_file.findRev('.'); if(extn != -1 && (inc_file.right(inc_file.length()-extn) == Option::cpp_ext.first() || inc_file.right(inc_file.length()-extn) == Option::h_ext.first())) { QString uip = inc_file.left(extn) + Option::ui_ext; QStringList uil = project->variables()["FORMS"]; for(QStringList::Iterator it = uil.begin(); it != uil.end(); ++it) { if((*it).section(Option::dir_sep, -1) == uip) { if(!project->isEmpty("UI_DIR")) fqn = project->first("UI_DIR"); else if(!project->isEmpty("UI_HEADERS_DIR")) fqn = project->first("UI_HEADERS_DIR"); else fqn = (*it).section(Option::dir_sep, 0, -2); if(!fqn.isEmpty() && !fqn.endsWith(Option::dir_sep)) fqn += Option::dir_sep; 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; } } } if(project->isActiveConfig("lex_included")) { //is this the lex file? QString rhs = Option::lex_mod + Option::cpp_ext.first(); if(inc.endsWith(rhs)) { QString lhs = inc.left(inc.length() - rhs.length()) + Option::lex_ext; QStringList ll = project->variables()["LEXSOURCES"]; for(QStringList::Iterator it = ll.begin(); it != ll.end(); ++it) { QString s = (*it), d; int slsh = s.findRev(Option::dir_sep); if(slsh != -1) { d = s.left(slsh + 1); s = s.right(s.length() - slsh - 1); } if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) d = project->first("QMAKE_ABSOLUTE_SOURCE_PATH"); if(s == lhs) { 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; } } } } { //is it from a .y? QString rhs = Option::yacc_mod + Option::h_ext.first(); if(inc.endsWith(rhs)) { QString lhs = inc.left(inc.length() - rhs.length()) + Option::yacc_ext; QStringList yl = project->variables()["YACCSOURCES"]; for(QStringList::Iterator it = yl.begin(); it != yl.end(); ++it) { QString s = (*it), d; int slsh = s.findRev(Option::dir_sep); if(slsh != -1) { d = s.left(slsh + 1); s = s.right(s.length() - slsh - 1); } if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) d = project->first("QMAKE_ABSOLUTE_SOURCE_PATH"); if(s == lhs) { 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; } } } } - 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 }; for(int moc = 0; !mocs[moc].isNull(); moc++) { QStringList &l = project->variables()[mocs[moc]]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString file = Option::fixPathToTargetOS((*it)); if(file.section(Option::dir_sep, -(inc.contains('/')+1)) == inc) { fqn = (*it); if(mocs[moc] == "_HDRMOC") { //Since it is include, no need to link it in as well project->variables()["_SRCMOC"].append((*it)); 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 previously didn't even allow this the test is mostly accurate) */ warn_msg(WarnLogic, "Found potential multiple MOC include %s (%s) in '%s'", inc.latin1(), fqn.latin1(), fix_env_fn.latin1()); } from_source_dir = FALSE; //mocs go in the output_dir (so don't fix them) - goto handle_fqn; + goto cache_fqn; } } } } + fqn = findDependency(inc); //all else fails.. + cache_fqn: + if(from_source_dir) { + fqn = fileFixify(fqn); + from_source_dir = FALSE; + } depHeuristics.insert(inc, fqn); } } handle_fqn: if(fqn.isEmpty()) //I give up continue; fqn = Option::fixPathToTargetOS(fqn, FALSE); if(from_source_dir) fqn = fileFixify(fqn); debug_msg(4, "Resolved dependency of %s to %s", inc.latin1(), fqn.latin1()); if(outdeps && outdeps->findIndex(fqn) == -1) outdeps->append(fqn); } //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++; } if(recurse) { for(QStringList::Iterator fnit = fndeps.begin(); fnit != fndeps.end(); ++fnit) { generateDependencies(dirs, (*fnit), recurse); 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)); } } debug_msg(2, "Dependencies: %s -> %s", fn.latin1(), fndeps.join(" :: ").latin1()); return TRUE; } void MakefileGenerator::initOutPaths() { if(init_opath_already) return; init_opath_already = TRUE; QMap<QString, QStringList> &v = project->variables(); if(!v.contains("QMAKE_ABSOLUTE_SOURCE_PATH")) { if(Option::mkfile::do_cache && !Option::mkfile::cachefile.isEmpty() && v.contains("QMAKE_ABSOLUTE_SOURCE_ROOT")) { QString root = v["QMAKE_ABSOLUTE_SOURCE_ROOT"].first(); root = Option::fixPathToTargetOS( root ); if(!root.isEmpty()) { QFileInfo fi(Option::mkfile::cachefile); if(!fi.convertToAbs()) { QString cache_r = fi.dirPath(), pwd = Option::output_dir; if ( pwd.startsWith(cache_r) && !pwd.startsWith(root) ) { pwd = Option::fixPathToTargetOS(root + pwd.mid(cache_r.length())); if(QFile::exists(pwd)) v.insert("QMAKE_ABSOLUTE_SOURCE_PATH", pwd); } } } } } if(!v["QMAKE_ABSOLUTE_SOURCE_PATH"].isEmpty()) { QString &asp = v["QMAKE_ABSOLUTE_SOURCE_PATH"].first(); asp = Option::fixPathToTargetOS( asp ); if(asp.isEmpty() || asp == Option::output_dir) //if they're the same, why bother? v["QMAKE_ABSOLUTE_SOURCE_PATH"].clear(); } QString currentDir = QDir::currentDirPath(); QString dirs[] = { QString("OBJECTS_DIR"), QString("MOC_DIR"), QString("UI_HEADERS_DIR"), 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++) { if ( !v[dirs[x]].isEmpty() ) { 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 { QString &path = v[dirs[x]].first(); path = fileFixify(path, Option::output_dir, Option::output_dir); if(path.right(Option::dir_sep.length()) != Option::dir_sep) path += Option::dir_sep; } if(noIO()) continue; QString path = project->first(dirs[x]); //not to be changed any further path = Option::fixPathToTargetOS(fileFixify(path, QDir::currentDirPath(), Option::output_dir)); debug_msg(3, "Fixed output_dir %s (%s) into %s (%s)", dirs[x].latin1(), orig_path.latin1(), v[dirs[x]].join("::").latin1(), path.latin1()); QDir d; if(path.startsWith(Option::dir_sep)) { d.cd(Option::dir_sep); path = path.right(path.length() - 1); } #ifdef Q_WS_WIN bool driveExists = TRUE; if ( !QDir::isRelativePath( path ) ) { if ( QFile::exists( path.left( 3 ) ) ) { d.cd( path.left( 3 ) ); path = path.right( path.length() - 3 ); } else { warn_msg(WarnLogic, "%s: Cannot access drive '%s' (%s)", dirs[x].latin1(), path.left( 3 ).latin1(), path.latin1() ); driveExists = FALSE; } } if ( driveExists ) { #endif QStringList subs = QStringList::split(Option::dir_sep, path); for(QStringList::Iterator subit = subs.begin(); subit != subs.end(); ++subit) { if(!d.cd(*subit)) { d.mkdir((*subit)); if ( d.exists( (*subit) ) ) d.cd((*subit)); else { warn_msg(WarnLogic, "%s: Cannot access directory '%s' (%s)", dirs[x].latin1(), (*subit).latin1(), path.latin1() ); break; } } } #ifdef Q_WS_WIN } #endif } } + 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 ); } void MakefileGenerator::init() { initOutPaths(); if(init_already) return; init_already = TRUE; QMap<QString, QStringList> &v = project->variables(); 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)); + } } /* get deps and mocables */ QDict<void> cache_found_files; QString cache_file(".qmake.internal.cache"); if(!project->isEmpty("QMAKE_INTERNAL_CACHE_FILE")) cache_file = Option::fixPathToLocalOS(project->first("QMAKE_INTERNAL_CACHE_FILE")); if(cache_file.find(QDir::separator()) == -1) //guess they know what they are doing.. cache_file.prepend(Option::output_dir + QDir::separator()); if((Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || Option::mkfile::do_deps || Option::mkfile::do_mocs) && !noIO()) { QPtrList<MakefileDependDir> deplist; deplist.setAutoDelete(TRUE); if((Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || Option::mkfile::do_deps) && doDepends()) { QStringList incDirs = v["DEPENDPATH"] + v["QMAKE_ABSOLUTE_SOURCE_PATH"]; if(project->isActiveConfig("depend_includepath")) incDirs += v["INCLUDEPATH"]; for(QStringList::Iterator it = incDirs.begin(); it != incDirs.end(); ++it) { QString r = (*it), l = Option::fixPathToLocalOS((*it)); deplist.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } debug_msg(1, "Dependency Directories: %s", incDirs.join(" :: ").latin1()); if(Option::output.name() != "-" && project->isActiveConfig("qmake_cache")) { QFile cachef(cache_file); if(cachef.open(IO_ReadOnly | IO_Translate)) { QFileInfo cachefi(cache_file); debug_msg(2, "Trying internal cache information: %s", cache_file.latin1()); QTextStream cachet(&cachef); QString line, file; enum { CacheInfo, CacheDepend, CacheMoc } state = CacheInfo; while (!cachet.eof()) { line = cachet.readLine().stripWhiteSpace(); int sep = line.find('='); if(line == "[depend]") { state = CacheDepend; } else if(line == "[mocable]") { state = CacheMoc; } else if(line == "[check]") { state = CacheInfo; } else if(!line.isEmpty() && sep != -1) { file = line.left(sep).stripWhiteSpace(); line = line.right(line.length() - sep - 1).stripWhiteSpace(); if(state == CacheInfo) { if(file == "QMAKE_CACHE_VERSION") { if(line != qmake_version()) break; } else { const QStringList &l = project->variables()[file]; if(!l.isEmpty() && !line.isEmpty() && l.join(" ") != line) break; } } else if(state == CacheDepend) { bool found = (bool)cache_found_files[file]; QStringList files = QStringList::split(" ", line); if(!found) { QFileInfo fi(fileFixify(file, QDir::currentDirPath(), Option::output_dir)); if(fi.exists() && fi.lastModified() < cachefi.lastModified()) { cache_found_files.insert(file, (void *)1); found = TRUE; } } if(found) { for(QStringList::Iterator dep_it = files.begin(); dep_it != files.end(); ++dep_it) { if(!cache_found_files[(*dep_it)]) { QFileInfo fi(fileFixify((*dep_it), QDir::currentDirPath(), Option::output_dir)); if(fi.exists() && fi.lastModified() < cachefi.lastModified()) { cache_found_files.insert((*dep_it), (void *)1); } else { found = FALSE; break; } } } if(found) { debug_msg(2, "Dependencies (cached): %s -> %s", file.latin1(), files.join(" :: ").latin1()); findDependencies(file) = files; + setProcessedDependencies(file, TRUE); } } } else { void *found = cache_found_files[file]; if(found != (void *)2) { if(found) { cache_found_files.replace(file, (void *)2); } else { QFileInfo fi(fileFixify(file, QDir::currentDirPath(), Option::output_dir)); if(fi.exists() && fi.lastModified() < cachefi.lastModified()) { cache_found_files.insert(file, (void *)2); found = (void*)1; } } } if(found && line != "*qmake_ignore*") { int ext_len = file.length() - file.findRev('.'); bool cpp_ext = FALSE; for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { if((cpp_ext = (file.right(ext_len) == (*cppit)))) break; } if(cpp_ext) { project->variables()["_SRCMOC"].append(line); } else if(project->variables()["HEADERS"].findIndex(file) != -1) { for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) { if((file.right(ext_len) == (*hit))) { project->variables()["_HDRMOC"].append(line); break; } } } debug_msg(2, "Mocgen (cached): %s -> %s", file.latin1(), line.latin1()); mocablesToMOC[file] = line; mocablesFromMOC[line] = file; } } } } cachef.close(); } } } if(!noIO()) { 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]]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { 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()) vpath = v["VPATH_" + sources[x]] + v["VPATH"] + v["QMAKE_ABSOLUTE_SOURCE_PATH"] + v["DEPENDPATH"]; for(QStringList::Iterator vpath_it = vpath.begin(); vpath_it != vpath.end(); ++vpath_it) { QString real_dir = Option::fixPathToLocalOS((*vpath_it)); if(QFile::exists(real_dir + QDir::separator() + (*val_it))) { QString dir = (*vpath_it); if(dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; (*val_it) = fileFixify(dir + (*val_it)); found = TRUE; debug_msg(1, "Found file through vpath %s -> %s", file.latin1(), (*val_it).latin1()); break; } } } if(!found) { QString dir, regex = (*val_it), real_dir; if(regex.findRev(Option::dir_sep) != -1) { dir = regex.left(regex.findRev(Option::dir_sep) + 1); real_dir = fileFixify(Option::fixPathToLocalOS(dir), QDir::currentDirPath(), Option::output_dir); regex = regex.right(regex.length() - dir.length()); } if(real_dir.isEmpty() || QFile::exists(real_dir)) { QDir d(real_dir, regex); if(!d.count()) { debug_msg(1, "%s:%d Failure to find %s in vpath (%s)", __FILE__, __LINE__, (*val_it).latin1(), vpath.join("::").latin1()); warn_msg(WarnLogic, "Failure to find: %s", (*val_it).latin1()); continue; } 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); } } } else { debug_msg(1, "%s:%d Cannot match %s%c%s, as %s does not exist.", __FILE__, __LINE__, real_dir.latin1(), QDir::separator(), regex.latin1(), real_dir.latin1()); warn_msg(WarnLogic, "Failure to find: %s", (*val_it).latin1()); } } } - 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()); } } } if(project->isActiveConfig("qmake_cache") && (write_cache || !read_cache)) { QFile cachef(cache_file); if(cachef.open(IO_WriteOnly | IO_Translate)) { debug_msg(2, "Writing internal cache information: %s", cache_file.latin1()); QTextStream cachet(&cachef); cachet << "[check]" << "\n" << "QMAKE_CACHE_VERSION = " << qmake_version() << "\n" << "QMAKE_ABSOLUTE_SOURCE_PATH = " << var("QMAKE_ABSOLUTE_SOURCE_PATH") << "\n" << "MOC_DIR = " << var("MOC_DIR") << "\n" << "UI_DIR = " << var("UI_DIR") << "\n" << "UI_HEADERS_DIR = " << var("UI_HEADERS_DIR") << "\n" << "UI_SOURCES_DIR = " << var("UI_SOURCES_DIR") << "\n"; cachet << "[depend]" << endl; for(QMap<QString, QStringList>::Iterator it = depends.begin(); it != depends.end(); ++it) - cachet << depKeyMap[it.key()] << " = " << it.data().join(" ") << endl; + cachet << dependencyKey(it.key()) << " = " << it.data().join(" ") << endl; cachet << "[mocable]" << endl; QString mc, moc_sources[] = { QString("HEADERS"), QString("SOURCES"), QString::null }; for(int x = 0; moc_sources[x] != QString::null; x++) { QStringList &l = v[moc_sources[x]]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { QString f = fileFixify((*val_it)); if(!f.isEmpty()) { mc = mocablesToMOC[f]; if(mc.isEmpty()) mc = "*qmake_ignore*"; cachet << f << " = " << mc << endl; } } } cachef.close(); } } } } v["OBJECTS"] = createObjectList("SOURCES") + v["OBJECTS"]; // init variables //lex files { QStringList &impls = v["LEXIMPLS"]; QStringList &l = v["LEXSOURCES"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString dir; QFileInfo fi((*it)); if(fi.dirPath() != ".") dir = fi.dirPath() + Option::dir_sep; dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; QString impl = dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first(); logicWarn(impl, "SOURCES"); logicWarn(impl, "SOURCES"); impls.append(impl); if( ! project->isActiveConfig("lex_included")) { v["SOURCES"].append(impl); // attribute deps of lex file to impl file QStringList &lexdeps = findDependencies((*it)); QStringList &impldeps = findDependencies(impl); for(QStringList::ConstIterator d = lexdeps.begin(); d != lexdeps.end(); ++d) { if(!impldeps.contains(*d)) impldeps.append(*d); } lexdeps.clear(); } } if( ! project->isActiveConfig("lex_included")) v["OBJECTS"] += (v["LEXOBJECTS"] = createObjectList("LEXIMPLS")); } //yacc files { QStringList &decls = v["YACCCDECLS"], &impls = v["YACCIMPLS"]; QStringList &l = v["YACCSOURCES"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString dir; QFileInfo fi((*it)); if(fi.dirPath() != ".") dir = fi.dirPath() + Option::dir_sep; dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; QString impl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first(); logicWarn(impl, "SOURCES"); QString decl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first(); logicWarn(decl, "HEADERS"); decls.append(decl); impls.append(impl); v["SOURCES"].append(impl); QStringList &impldeps = findDependencies(impl); impldeps.append(decl); // attribute deps of yacc file to impl file QStringList &yaccdeps = findDependencies((*it)); for(QStringList::ConstIterator d = yaccdeps.begin(); d != yaccdeps.end(); ++d) { if(!impldeps.contains(*d)) impldeps.append(*d); } if( project->isActiveConfig("lex_included")) { // is there a matching lex file ? Transfer its dependencies. QString lexsrc = fi.baseName(TRUE) + Option::lex_ext; if(fi.dirPath() != ".") lexsrc.prepend(fi.dirPath() + Option::dir_sep); if(v["LEXSOURCES"].findIndex(lexsrc) != -1) { QString trg = dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first(); impldeps.append(trg); impldeps += findDependencies(lexsrc); depends[lexsrc].clear(); } } yaccdeps.clear(); } v["OBJECTS"] += (v["YACCOBJECTS"] = createObjectList("YACCIMPLS")); } //UI files { QStringList &includepath = project->variables()["INCLUDEPATH"]; if(!project->isEmpty("UI_DIR")) includepath.append(project->first("UI_DIR")); else if(!project->isEmpty("UI_HEADERS_DIR")) includepath.append(project->first("UI_HEADERS_DIR")); QStringList &decls = v["UICDECLS"], &impls = v["UICIMPLS"]; QStringList &l = v["FORMS"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString impl, decl; QFileInfo fi(Option::fixPathToLocalOS((*it))); if ( !project->isEmpty("UI_DIR") ) { impl = decl = project->first("UI_DIR"); QString d = fi.dirPath(); if( d == ".") d = QDir::currentDirPath(); d = fileFixify(d, QDir::currentDirPath(), Option::output_dir); if(!includepath.contains(d)) includepath.append(d); } else { if(decl.isEmpty() && !project->isEmpty("UI_HEADERS_DIR")) 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")) ) { QString d = fi.dirPath(); if( d == ".") d = QDir::currentDirPath(); d = fileFixify(d, QDir::currentDirPath(), Option::output_dir); if(includepath.contains(d)) includepath.append(d); } if(impl.isEmpty() && !project->isEmpty("UI_SOURCES_DIR")) impl = project->first("UI_SOURCES_DIR"); if(fi.dirPath() != ".") { if(impl.isEmpty()) impl = fi.dirPath() + Option::dir_sep; if(decl.isEmpty()) decl = fi.dirPath() + Option::dir_sep; } } 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")) { QString decl_fixed = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); if(!includepath.contains(decl_fixed)) includepath.append(decl_fixed); if(!includepath.contains(decl)) project->variables()["INCLUDEPATH"].append(decl); } decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); - if(!decl.isEmpty()) + if(!decl.isEmpty() && !decl.endsWith(Option::dir_sep)) decl += Option::dir_sep; decl += fi.baseName(TRUE) + Option::h_ext.first(); logicWarn(impl, "SOURCES"); logicWarn(decl, "HEADERS"); decls.append(decl); impls.append(impl); findDependencies(impl).append(decl); - 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()) mocable.prepend(v["MOC_DIR"].first()); else if(fi.dirPath() != ".") mocable.prepend(fi.dirPath() + Option::dir_sep); logicWarn(mocable, "SOURCES"); mocablesToMOC[cleanFilePath(decl)] = mocable; mocablesFromMOC[cleanFilePath(mocable)] = decl; v["_UIMOC"].append(mocable); } v["OBJECTS"] += (v["UICOBJECTS"] = createObjectList("UICDECLS")); } + //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 if(!project->isEmpty("IMAGES")) { if(project->isEmpty("QMAKE_IMAGE_COLLECTION")) v["QMAKE_IMAGE_COLLECTION"].append("qmake_image_collection" + Option::cpp_ext.first()); QString imgfile = project->first("QMAKE_IMAGE_COLLECTION"); Option::fixPathToTargetOS(imgfile); if(!project->isEmpty("UI_DIR") || !project->isEmpty("UI_SOURCES_DIR")) { if(imgfile.find(Option::dir_sep) != -1) imgfile = imgfile.right(imgfile.findRev(Option::dir_sep) + 1); imgfile.prepend( (project->isEmpty("UI_DIR") ? project->first("UI_SOURCES_DIR") : project->first("UI_DIR")) ); v["QMAKE_IMAGE_COLLECTION"] = QStringList(imgfile); } logicWarn(imgfile, "SOURCES"); if(!noIO()) { QStringList &l = v["IMAGES"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { if(!QFile::exists((*it))) { warn_msg(WarnLogic, "Failure to open: %s", (*it).latin1()); continue; } findDependencies(imgfile).append(fileFixify((*it))); } } v["OBJECTS"] += (v["IMAGEOBJECTS"] = createObjectList("QMAKE_IMAGE_COLLECTION")); } - if(Option::output_dir != QDir::currentDirPath()) + if(Option::output_dir != QDir::currentDirPath()) project->variables()["INCLUDEPATH"].append(fileFixify(Option::output_dir, Option::output_dir, Option::output_dir)); //moc files if ( mocAware() ) { if(!project->isEmpty("MOC_DIR")) 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"); QStringList &l = v["SRCMOC"]; l = v["_HDRMOC"] + v["_UIMOC"] + v["_SRCMOC"]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { if(!(*val_it).isEmpty()) (*val_it) = Option::fixPathToTargetOS((*val_it), FALSE); } } + + 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; + } } bool 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 = ""; } else { QString tmp = file; int ext = tmp.findRev('.'); if(ext != -1) 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; if(slsh != -1) { dir = stem.left(slsh + 1); stem = stem.right(stem.length() - slsh - 1); } if(stem.startsWith("lib")) { hadlib = 1; stem = stem.right(stem.length() - 3); } int dot = stem.find('.'); if(dot != -1) { extn = stem.right(stem.length() - dot); stem = stem.left(dot); } if(stem == "qt" || stem == "qte" || stem == "qte-mt" || stem == "qt-mt") { if(stem.endsWith("-mt")) stem = stem.left(stem.length() - 3); //lose the -mt else 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; } } - 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; } return ret; } void MakefileGenerator::processPrlVariable(const QString &var, const QStringList &l) { if(var == "QMAKE_PRL_LIBS") { QString where = "QMAKE_LIBS"; if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) where = project->first("QMAKE_INTERNAL_PRL_LIBS"); QStringList &out = project->variables()[where]; for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { if( out.findIndex((*it)) == -1) out.append((*it)); } } else if(var == "QMAKE_PRL_DEFINES") { QStringList &out = project->variables()["DEFINES"]; for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { if(out.findIndex((*it)) == -1 && project->variables()["PRL_EXPORT_DEFINES"].findIndex((*it)) == -1) out.append((*it)); } } } void MakefileGenerator::processPrlFiles() { QDict<void> processed; for(bool ret = FALSE; TRUE; ret = FALSE) { //read in any prl files included.. QStringList l_out; QString where = "QMAKE_LIBS"; if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) where = project->first("QMAKE_INTERNAL_PRL_LIBS"); QStringList &l = project->variables()[where]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString file = (*it); if(!processed[file] && processPrlFile(file)) { processed.insert(file, (void*)1); ret = TRUE; } if(!file.isEmpty()) l_out.append(file); } if(ret) l = l_out; else break; } } void MakefileGenerator::writePrlFile(QTextStream &t) { QString target = project->first("TARGET"); int slsh = target.findRev(Option::dir_sep); if(slsh != -1) target = target.right(target.length() - slsh - 1); QString bdir = Option::output_dir; if(bdir.isEmpty()) bdir = QDir::currentDirPath(); t << "QMAKE_PRL_BUILD_DIR = " << bdir << endl; if(!project->projectFile().isEmpty() && project->projectFile() != "-") t << "QMAKE_PRO_INPUT = " << project->projectFile().section('/', -1) << endl; if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) t << "QMAKE_PRL_SOURCE_DIR = " << project->first("QMAKE_ABSOLUTE_SOURCE_PATH") << endl; t << "QMAKE_PRL_TARGET = " << target << endl; if(!project->isEmpty("PRL_EXPORT_DEFINES")) 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")) t << "QMAKE_PRL_CONFIG = " << project->variables()["CONFIG"].join(" ") << endl; if(!project->isEmpty("VERSION")) t << "QMAKE_PRL_VERSION = " << project->first("VERSION") << endl; if(project->isActiveConfig("staticlib") || project->isActiveConfig("explicitlib")) { QStringList libs; if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) libs = project->variables()["QMAKE_INTERNAL_PRL_LIBS"]; else libs << "QMAKE_LIBS"; //obvious one t << "QMAKE_PRL_LIBS = "; for(QStringList::Iterator it = libs.begin(); it != libs.end(); ++it) t << project->variables()[(*it)].join(" ") << " "; t << endl; } } bool MakefileGenerator::write() { + usePlatformDir(); init(); findLibraries(); if((Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || //write prl Option::qmake_mode == Option::QMAKE_GENERATE_PRL) && + project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty() && project->isActiveConfig("create_prl") && project->first("TEMPLATE") == "lib" && !project->isActiveConfig("plugin")) { QString prl = var("TARGET"); int slsh = prl.findRev(Option::dir_sep); if(slsh != -1) prl = prl.right(prl.length() - slsh); int dot = prl.find('.'); if(dot != -1) prl = prl.left(dot); prl += Option::prl_ext; if(!project->isEmpty("DESTDIR")) prl.prepend(var("DESTDIR")); QString local_prl = Option::fixPathToLocalOS(fileFixify(prl, QDir::currentDirPath(), Option::output_dir)); QFile ft(local_prl); if(ft.open(IO_WriteOnly)) { project->variables()["ALL_DEPS"].append(prl); project->variables()["QMAKE_INTERNAL_PRL_FILE"].append(prl); QTextStream t(&ft); writePrlFile(t); ft.close(); } } if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE && project->isActiveConfig("link_prl")) //load up prl's' processPrlFiles(); - 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) { QTextStream t(&Option::output); writeMakefile(t); } return TRUE; } +// 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 MakefileGenerator::writeObj(QTextStream &t, const QString &obj, const QString &src) { QStringList &objl = project->variables()[obj]; QStringList &srcl = project->variables()[src]; QStringList::Iterator oit = objl.begin(); QStringList::Iterator sit = srcl.begin(); QString stringSrc("$src"); QString stringObj("$obj"); for( ;sit != srcl.end() && oit != objl.end(); oit++, sit++) { if((*sit).isEmpty()) continue; if(!doDepends()) { QString sdep, odep = (*sit) + " "; QStringList deps = findDependencies((*sit)); 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) + " "; else sdep += (*dit) + " "; } t << (*sit) << ": " << sdep << endl << (*oit) << ": " << odep ; } else { t << (*oit) << ": " << (*sit) << " " << findDependencies((*sit)).join(" \\\n\t\t"); } QString comp, cimp; for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { if((*sit).endsWith((*cppit))) { comp = "QMAKE_RUN_CXX"; cimp = "QMAKE_RUN_CXX_IMP"; break; } } if(comp.isEmpty()) { comp = "QMAKE_RUN_CC"; cimp = "QMAKE_RUN_CC_IMP"; } bool use_implicit_rule = !project->isEmpty(cimp); if(use_implicit_rule) { if(!project->isEmpty("OBJECTS_DIR")) { use_implicit_rule = FALSE; } else { int dot = (*sit).findRev('.'); if(dot == -1 || ((*sit).left(dot) + Option::obj_ext != (*oit))) use_implicit_rule = FALSE; } } 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)); t << "\n\t" << p; } t << endl << endl; } } void MakefileGenerator::writeUicSrc(QTextStream &t, const QString &ui) { QStringList &uil = project->variables()[ui]; for(QStringList::Iterator it = uil.begin(); it != uil.end(); it++) { - QString deps = findDependencies((*it)).join(" \\\n\t\t"), decl, impl; + QString decl, impl; { QString tmp = (*it), impl_dir, decl_dir; 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")) { impl_dir = project->first("UI_DIR"); decl = project->first("UI_DIR") + decl.right(decl.length() - dlen); impl = project->first("UI_DIR") + impl.right(impl.length() - ilen); } else { if(!project->isEmpty("UI_HEADERS_DIR")) { decl_dir = project->first("UI_HEADERS_DIR"); decl = project->first("UI_HEADERS_DIR") + decl.right(decl.length() - dlen); } if(!project->isEmpty("UI_SOURCES_DIR")) { impl_dir = project->first("UI_SOURCES_DIR"); impl = project->first("UI_SOURCES_DIR") + impl.right(impl.length() - ilen); } - } - 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; 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; } } void MakefileGenerator::writeMocObj(QTextStream &t, const QString &obj, const QString &src) { QStringList &objl = project->variables()[obj], &srcl = project->variables()[src]; QStringList::Iterator oit = objl.begin(), sit = srcl.begin(); QString stringSrc("$src"), stringObj("$obj"); for( ;sit != srcl.end() && oit != objl.end(); oit++, sit++) { QString hdr = findMocSource((*sit)); - t << (*oit) << ": " << (*sit) << " " + t << (*oit) << ": " + << (*sit) << " " << findDependencies((*sit)).join(" \\\n\t\t") << " " << hdr << " " << findDependencies(hdr).join(" \\\n\t\t"); bool use_implicit_rule = !project->isEmpty("QMAKE_RUN_CXX_IMP"); if(use_implicit_rule) { if(!project->isEmpty("OBJECTS_DIR") || !project->isEmpty("MOC_DIR")) { use_implicit_rule = FALSE; } else { int dot = (*sit).findRev('.'); if(dot == -1 || ((*sit).left(dot) + Option::obj_ext != (*oit))) use_implicit_rule = FALSE; } } 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)); t << "\n\t" << p; } t << endl << endl; } } void MakefileGenerator::writeMocSrc(QTextStream &t, const QString &src) { QStringList &l = project->variables()[src]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString m = Option::fixPathToTargetOS(findMocDestination(*it)); if ( !m.isEmpty()) { QString deps; if(!project->isActiveConfig("no_mocdepend")) deps += "$(MOC) "; deps += (*it); t << m << ": " << deps << "\n\t" - << "$(MOC) " << (*it) << " -o " << m << endl << endl; + << "$(MOC)"; + t << " " << (*it) << " -o " << m << endl << endl; } } } void MakefileGenerator::writeYaccSrc(QTextStream &t, const QString &src) { QStringList &l = project->variables()[src]; if(project->isActiveConfig("yacc_no_name_mangle") && l.count() > 1) warn_msg(WarnLogic, "yacc_no_name_mangle specified, but multiple parsers expected." "This can lead to link problems.\n"); QString default_out_h = "y.tab.h", default_out_c = "y.tab.c"; if(!project->isEmpty("QMAKE_YACC_HEADER")) default_out_h = project->first("QMAKE_YACC_HEADER"); if(!project->isEmpty("QMAKE_YACC_SOURCE")) default_out_c = project->first("QMAKE_YACC_SOURCE"); QString stringBase("$base"); for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QFileInfo fi((*it)); QString dir; if(fi.dirPath() != ".") dir = fi.dirPath() + Option::dir_sep; dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; QString impl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first(); QString decl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first(); QString yaccflags = "$(YACCFLAGS)", mangle = "y"; if(!project->isActiveConfig("yacc_no_name_mangle")) { 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; } QString out_h = default_out_h, out_c = default_out_c; if(!mangle.isEmpty()) { out_h.replace(stringBase, mangle); out_c.replace(stringBase, mangle); } t << impl << ": " << (*it) << "\n\t" << "$(YACC) " << yaccflags << " " << (*it) << "\n\t" << "-$(DEL_FILE) " << impl << " " << decl << "\n\t" << "-$(MOVE) " << out_h << " " << decl << "\n\t" << "-$(MOVE) " << out_c << " " << impl << endl << endl; t << decl << ": " << impl << endl << endl; } } void MakefileGenerator::writeLexSrc(QTextStream &t, const QString &src) { QStringList &l = project->variables()[src]; if(project->isActiveConfig("yacc_no_name_mangle") && l.count() > 1) warn_msg(WarnLogic, "yacc_no_name_mangle specified, but multiple parsers expected.\n" "This can lead to link problems.\n"); QString default_out_c = "lex.$base.c"; if(!project->isEmpty("QMAKE_LEX_SOURCE")) default_out_c = project->first("QMAKE_LEX_SOURCE"); QString stringBase("$base"); for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QFileInfo fi((*it)); QString dir; if(fi.dirPath() != ".") dir = fi.dirPath() + Option::dir_sep; dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; QString impl = dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first(); QString lexflags = "$(LEXFLAGS)", stub="yy"; if(!project->isActiveConfig("yacc_no_name_mangle")) { stub = fi.baseName(TRUE); lexflags += " -P" + stub; } QString out_c = default_out_c; if(!stub.isEmpty()) out_c.replace(stringBase, stub); t << impl << ": " << (*it) << " " << findDependencies((*it)).join(" \\\n\t\t") << "\n\t" << ( "$(LEX) " + lexflags + " " ) << (*it) << "\n\t" << "-$(DEL_FILE) " << impl << " " << "\n\t" << "-$(MOVE) " << out_c << " " << impl << endl << endl; } } void MakefileGenerator::writeImageObj(QTextStream &t, const QString &obj) { QStringList &objl = project->variables()[obj]; QString stringSrc("$src"); QString stringObj("$obj"); QString uidir; for(QStringList::Iterator oit = objl.begin(); oit != objl.end(); oit++) { QString src(project->first("QMAKE_IMAGE_COLLECTION")); t << (*oit) << ": " << src; bool use_implicit_rule = !project->isEmpty("QMAKE_RUN_CXX_IMP"); if(use_implicit_rule) { if(!project->isEmpty("OBJECTS_DIR") || !project->isEmpty("UI_DIR") || !project->isEmpty("UI_SOURCES_DIR")) { use_implicit_rule = FALSE; } else { int dot = src.findRev('.'); if(dot == -1 || (src.left(dot) + Option::obj_ext != (*oit))) use_implicit_rule = FALSE; } } 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; } t << endl << endl; } } void MakefileGenerator::writeImageSrc(QTextStream &t, const QString &src) { QStringList &l = project->variables()[src]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString gen = project->first("MAKEFILE_GENERATOR"); if ( gen == "MSVC" ) { t << (*it) << ": " << findDependencies((*it)).join(" \\\n\t\t") << "\n\t" << "$(UIC) -o " << (*it) << " -embed " << project->first("QMAKE_ORIG_TARGET") << " -f <<\n" << findDependencies((*it)).join(" ") << "\n<<" << endl << endl; } else if ( gen == "BMAKE" ) { t << (*it) << ": " << findDependencies((*it)).join(" \\\n\t\t") << "\n\t" << "$(UIC) " << " -embed " << project->first("QMAKE_ORIG_TARGET") << " -f &&|\n" << findDependencies((*it)).join(" ") << "\n| -o " << (*it) << endl << endl; } else { t << (*it) << ": " << findDependencies((*it)).join(" \\\n\t\t") << "\n\t" << "$(UIC) " << " -embed " << project->first("QMAKE_ORIG_TARGET") << " " << findDependencies((*it)).join(" ") << " -o " << (*it) << endl << endl; } } } void MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) { QString all_installs, all_uninstalls; QStringList &l = project->variables()[installs]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { 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()); continue; } bool do_default = TRUE; const QString root = "$(INSTALL_ROOT)"; 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()) { do_default = FALSE; if(!target.isEmpty()) target += "\n\t"; target += tmp.join(" "); } //masks tmp = project->variables()[(*it) + ".files"]; if(!tmp.isEmpty()) { if(!target.isEmpty()) target += "\n"; do_default = FALSE; for(QStringList::Iterator wild_it = tmp.begin(); wild_it != tmp.end(); ++wild_it) { QString wild = Option::fixPathToLocalOS((*wild_it), FALSE), wild_var = fileFixify(wild); QString dirstr = QDir::currentDirPath(), filestr = wild; int slsh = filestr.findRev(Option::dir_sep); if(slsh != -1) { dirstr = filestr.left(slsh+1); filestr = filestr.right(filestr.length() - slsh - 1); } if(dirstr.right(Option::dir_sep.length()) != Option::dir_sep) dirstr += Option::dir_sep; if(QFile::exists(wild)) { //real file QString file = wild; QFileInfo fi(wild); if(!target.isEmpty()) 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()) uninst.append("\n\t"); uninst.append( #ifdef Q_WS_WIN QString("-$(DEL_FILE)") #else QString("-$(DEL_FILE) -r") #endif - + " \"" + root + fileFixify(dst + filestr) + "\""); + + " \"" + root + fileFixify(dst + filestr, QString::null, QString::null, FALSE, FALSE) + "\""); continue; } + fixEnvVariables(dirstr); QDir dir(dirstr, filestr); //wild for(uint x = 0; x < dir.count(); x++) { QString file = dir[x]; if(file == "." || file == "..") //blah continue; if(!uninst.isEmpty()) uninst.append("\n\t"); uninst.append( #ifdef Q_WS_WIN QString("-$(DEL_FILE)") #else QString("-$(DEL_FILE) -r") #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"; } } } //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]; for(QStringList::ConstIterator pit = dirs.begin(); pit != dirs.end(); ++pit) { QString tmp_dst = fileFixify((*pit)); #ifndef Q_WS_WIN if(tmp_dst.right(1) != Option::dir_sep) tmp_dst += Option::dir_sep; #endif t << mkdir_p_asstring(root+tmp_dst) << "\n\t"; } t << target << endl << endl; - all_installs += QString("install_") + (*it) + " "; if(!uninst.isEmpty()) { t << "uninstall_" << (*it) << ": " << "\n\t" << uninst.join("") << "\n\t" << "-$(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 { debug_msg(1, "no definition for install %s: install target not created",(*it).latin1()); } } - 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"; } QString MakefileGenerator::var(const QString &var) { return val(project->variables()[var]); } QString MakefileGenerator::val(const QStringList &varList) { return valGlue(varList, "", " ", ""); } QString MakefileGenerator::varGlue(const QString &var, const QString &before, const QString &glue, const QString &after) { return valGlue(project->variables()[var], before, glue, after); } QString MakefileGenerator::valGlue(const QStringList &varList, const QString &before, const QString &glue, const QString &after) { QString ret; for(QStringList::ConstIterator it = varList.begin(); it != varList.end(); ++it) { if(!(*it).isEmpty()) { if(!ret.isEmpty()) ret += glue; ret += (*it); } } return ret.isEmpty() ? QString("") : before + ret + after; } QString MakefileGenerator::varList(const QString &var) { return valList(project->variables()[var]); } QString MakefileGenerator::valList(const QStringList &varList) { return valGlue(varList, "", " \\\n\t\t", ""); } QStringList MakefileGenerator::createObjectList(const QString &var) { QStringList &l = project->variables()[var], ret; QString objdir, dir; if(!project->variables()["OBJECTS_DIR"].isEmpty()) objdir = project->first("OBJECTS_DIR"); for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QFileInfo fi(Option::fixPathToLocalOS((*it))); if(objdir.isEmpty() && project->isActiveConfig("object_with_source")) { QString fName = Option::fixPathToTargetOS((*it), FALSE); int dl = fName.findRev(Option::dir_sep); if(dl != -1) dir = fName.left(dl + 1); } else { dir = objdir; @@ -1910,338 +2107,375 @@ QString MakefileGenerator::buildArgs() } } } return ret; } //could get stored argv, but then it would have more options than are //probably necesary this will try to guess the bare minimum.. QString MakefileGenerator::build_args() { static QString ret; if(ret.isEmpty()) { ret = "$(QMAKE)"; // general options and arguments ret += buildArgs(); //output QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.name())); if (!ofile.isEmpty() && ofile != project->first("QMAKE_MAKEFILE")) ret += " -o " + ofile; //inputs QStringList files = fileFixify(Option::mkfile::project_files); ret += " " + files.join(" "); } return ret; } bool MakefileGenerator::writeHeader(QTextStream &t) { time_t foo = time(NULL); t << "#############################################################################" << endl; t << "# Makefile for building: " << var("TARGET") << endl; t << "# Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: " << ctime(&foo); t << "# Project: " << fileFixify(project->projectFile()) << endl; t << "# Template: " << var("TEMPLATE") << endl; t << "# Command: " << build_args() << endl; t << "#############################################################################" << endl; t << endl; return TRUE; } //makes my life easier.. bool MakefileGenerator::writeMakeQmake(QTextStream &t) { QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.name())); if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isActiveConfig("no_autoqmake") && !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) { QStringList files = fileFixify(Option::mkfile::project_files); t << project->first("QMAKE_INTERNAL_PRL_FILE") << ": " << "\n\t" << "@$(QMAKE) -prl " << buildArgs() << " " << files.join(" ") << endl; } QString pfile = project->projectFile(); if(pfile != "(stdin)") { QString qmake = build_args(); if(!ofile.isEmpty() && !project->isActiveConfig("no_autoqmake")) { t << ofile << ": " << fileFixify(pfile) << " "; if(Option::mkfile::do_cache) 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" << qmake <<endl; } if(project->first("QMAKE_ORIG_TARGET") != "qmake") { t << "qmake: " << project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].join(" \\\n\t\t") << "\n\t" << "@" << qmake << endl << endl; } } return TRUE; } 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 { if(files.isEmpty()) return files; QStringList ret; for(QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) { if(!(*it).isEmpty()) - ret << fileFixify((*it), out_dir, in_dir, force_fix); + ret << fileFixify((*it), out_dir, in_dir, force_fix, canon); } return ret; } 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]; QString file = file0; int depth = 4; if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { if(project && !project->isEmpty("QMAKE_PROJECT_DEPTH")) depth = project->first("QMAKE_PROJECT_DEPTH").toInt(); else if(Option::mkfile::cachefile_depth != -1) depth = Option::mkfile::cachefile_depth; } QChar quote; if((file.startsWith("'") || file.startsWith("\"")) && file.startsWith(file.right(1))) { quote = file.at(0); file = file.mid(1, file.length() - 2); } QString orig_file = file; if(!force_fix && project->isActiveConfig("no_fixpath")) { 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 QFileInfo fi(qfile); if(!fi.convertToAbs()) //strange file = fi.filePath(); } } } 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)) { QFileInfo in_fi(in_dir); if(!in_fi.convertToAbs()) in_dir = in_fi.filePath(); QFileInfo out_fi(out_dir); if(!out_fi.convertToAbs()) out_dir = out_fi.filePath(); } QString in_canonical_dir = QDir(in_dir).canonicalPath(), out_canonical_dir = QDir(out_dir).canonicalPath(); if(!in_canonical_dir.isEmpty()) in_dir = in_canonical_dir; if(!out_canonical_dir.isEmpty()) out_dir = out_canonical_dir; } if(out_dir != in_dir || !QDir::isRelativePath(qfile)) { if(QDir::isRelativePath(qfile)) { if(file.left(Option::dir_sep.length()) != Option::dir_sep && in_dir.right(Option::dir_sep.length()) != Option::dir_sep) file.prepend(Option::dir_sep); file.prepend(in_dir); } - 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(); if(!real_file.isEmpty()) file = real_file; } - QString match_dir = Option::fixPathToTargetOS(out_dir, FALSE); + QString match_dir = Option::fixPathToTargetOS(out_dir, FALSE, canon); if(file == match_dir) { file = ""; } else if(file.startsWith(match_dir) && file.mid(match_dir.length(), Option::dir_sep.length()) == Option::dir_sep) { file = file.right(file.length() - (match_dir.length() + 1)); } else { for(int i = 1; i <= depth; i++) { int sl = match_dir.findRev(Option::dir_sep); if(sl == -1) break; match_dir = match_dir.left(sl); if(match_dir.isEmpty()) break; if(file.startsWith(match_dir) && file.mid(match_dir.length(), Option::dir_sep.length()) == Option::dir_sep) { //concat int remlen = file.length() - (match_dir.length() + 1); if (remlen < 0) remlen = 0; file = file.right(remlen); //prepend for(int o = 0; o < i; o++) file.prepend(".." + Option::dir_sep); } } } } } - file = Option::fixPathToTargetOS(file, FALSE); + file = Option::fixPathToTargetOS(file, FALSE, canon); if(file.isEmpty()) file = "."; if(!quote.isNull()) 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); return file; } QString MakefileGenerator::cleanFilePath(const QString &file) const { return fileFixify(Option::fixPathToTargetOS(file)); } void MakefileGenerator::logicWarn(const QString &f, const QString &w) { if(!(Option::warn_level & WarnLogic)) return; QString file = f; int slsh = f.findRev(Option::dir_sep); if(slsh != -1) file = file.right(file.length() - slsh - 1); QStringList &l = project->variables()[w]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { QString file2((*val_it)); slsh = file2.findRev(Option::dir_sep); if(slsh != -1) file2 = file2.right(file2.length() - slsh - 1); if(file2 == file) { warn_msg(WarnLogic, "Found potential symbol conflict of %s (%s) in %s", file.latin1(), (*val_it).latin1(), w.latin1()); break; } } } +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 &MakefileGenerator::findDependencies(const QString &file) { - 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)]; } QString MakefileGenerator::specdir() { if(!spec.isEmpty()) return spec; 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)); if(qdir.endsWith(QString(QChar(QDir::separator())))) qdir.truncate(qdir.length()-1); //fix path QFileInfo fi(spec); QString absSpec(fi.absFilePath()); absSpec = Option::fixPathToTargetOS(absSpec); //replace what you can if(absSpec.startsWith(qdir)) { absSpec.replace(0, qdir.length(), "$(QTDIR)"); spec = absSpec; } } +#else + spec = Option::fixPathToTargetOS(spec); +#endif return spec; } bool MakefileGenerator::openOutput(QFile &file) const { { QString outdir; if(!file.name().isEmpty()) { + if(QDir::isRelativePath(file.name())) + file.setName(Option::output_dir + file.name()); //pwd when qmake was run QFileInfo fi(file); if(fi.isDir()) outdir = file.name() + QDir::separator(); } if(!outdir.isEmpty() || file.name().isEmpty()) { QString fname = "Makefile"; if(!project->isEmpty("MAKEFILE")) fname = project->first("MAKEFILE"); file.setName(outdir + fname); } } if(QDir::isRelativePath(file.name())) file.setName(Option::output_dir + file.name()); //pwd when qmake was run if(project->isEmpty("QMAKE_MAKEFILE")) project->variables()["QMAKE_MAKEFILE"].append(file.name()); int slsh = file.name().findRev(Option::dir_sep); if(slsh != -1) createDir(file.name().left(slsh)); if(file.open(IO_WriteOnly | IO_Translate)) { QFileInfo fi(Option::output); QString od = Option::fixPathToTargetOS((fi.isSymLink() ? fi.readLink() : fi.dirPath()) ); if(QDir::isRelativePath(od)) od.prepend(Option::output_dir); Option::output_dir = od; return TRUE; } return FALSE; } //Factory thing #include "unixmake.h" #include "msvc_nmake.h" #include "borland_bmake.h" #include "mingw_make.h" #include "msvc_dsp.h" #include "msvc_vcproj.h" #include "metrowerks_xml.h" #include "pbuilder_pbx.h" #include "projectgenerator.h" MakefileGenerator * MakefileGenerator::create(QMakeProject *proj) { if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) return new ProjectGenerator(proj); MakefileGenerator *mkfile = NULL; QString gen = proj->first("MAKEFILE_GENERATOR"); if(gen.isEmpty()) { fprintf(stderr, "No generator specified in config file: %s\n", proj->projectFile().latin1()); } else if(gen == "UNIX") { mkfile = new UnixMakefileGenerator(proj); } else if(gen == "MSVC") { // Visual Studio =< v6.0 if(proj->first("TEMPLATE").find(QRegExp("^vc.*")) != -1) mkfile = new DspMakefileGenerator(proj); else mkfile = new NmakeMakefileGenerator(proj); } else if(gen == "MSVC.NET") { // Visual Studio >= v7.0 if(proj->first("TEMPLATE").find(QRegExp("^vc.*")) != -1) 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,173 +1,190 @@ /**************************************************************************** -** $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. ** ** 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 __MAKEFILE_H__ #define __MAKEFILE_H__ #include "option.h" #include "project.h" #include <qtextstream.h> +#ifdef Q_OS_WIN32 +#define QT_POPEN _popen +#else +#define QT_POPEN popen +#endif + class MakefileGenerator { QString spec; bool init_opath_already, init_already, moc_aware, no_io; QStringList createObjectList(const QString &var); 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; QMap<QString, QStringList> depends; protected: void writeObj(QTextStream &, const QString &obj, const QString &src); void writeUicSrc(QTextStream &, const QString &ui); void writeMocObj(QTextStream &, const QString &obj, const QString &src); void writeMocSrc(QTextStream &, const QString &src); void writeLexSrc(QTextStream &, const QString &lex); void writeYaccSrc(QTextStream &, const QString &yac); void writeInstalls(QTextStream &t, const QString &installs); void writeImageObj(QTextStream &t, const QString &obj); void writeImageSrc(QTextStream &t, const QString &images); protected: QMakeProject *project; class MakefileDependDir { public: MakefileDependDir(const QString &r, const QString &l) : real_dir(r), local_dir(l) { } QString real_dir, local_dir; }; bool generateDependencies(QPtrList<MakefileDependDir> &dirs, const QString &x, bool recurse); QString buildArgs(); QString specdir(); QString cleanFilePath(const QString &file) const; bool generateMocList(const QString &fn); QString findMocSource(const QString &moc_file) const; QString findMocDestination(const QString &src_file) const; - QStringList &findDependencies(const QString &file); + virtual QStringList &findDependencies(const QString &file); void setNoIO(bool o); bool noIO() const; void setMocAware(bool o); bool mocAware() const; void logicWarn(const QString &, const QString &); virtual bool doDepends() const { return Option::mkfile::do_deps; } bool writeHeader(QTextStream &); virtual bool writeMakefile(QTextStream &); virtual bool writeMakeQmake(QTextStream &); void initOutPaths(); virtual void init(); + //for cross-platform dependent directories + virtual void usePlatformDir(); + //for installs virtual QString defaultInstall(const QString &); //for prl bool processPrlFile(QString &); virtual void processPrlVariable(const QString &, const QStringList &); virtual void processPrlFiles(); virtual void writePrlFile(QTextStream &); //make sure libraries are found 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); QString varList(const QString &var); QString val(const QStringList &varList); QString valGlue(const QStringList &varList, const QString &before, const QString &glue, const QString &after); QString valList(const QStringList &varList); 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: MakefileGenerator(QMakeProject *p); virtual ~MakefileGenerator(); static MakefileGenerator *create(QMakeProject *); - bool write(); + virtual bool write(); virtual bool openOutput(QFile &) const; }; inline QString MakefileGenerator::findMocSource(const QString &moc_file) const { QString tmp = cleanFilePath(moc_file); if (mocablesFromMOC.contains(tmp)) return mocablesFromMOC[tmp]; else return QString(""); } inline QString MakefileGenerator::findMocDestination(const QString &src_file) const { QString tmp = cleanFilePath(src_file); if (mocablesToMOC.contains(tmp)) return mocablesToMOC[tmp]; else return QString(""); } inline void MakefileGenerator::setMocAware(bool o) { moc_aware = o; } inline bool MakefileGenerator::mocAware() const { return moc_aware; } inline void MakefileGenerator::setNoIO(bool o) { no_io = o; } inline bool MakefileGenerator::noIO() const { return no_io; } inline QString MakefileGenerator::defaultInstall(const QString &) { return QString(""); } inline bool MakefileGenerator::findLibraries() { return TRUE; } +inline QString MakefileGenerator::findDependency(const QString &) +{ return QString(""); } + inline MakefileGenerator::~MakefileGenerator() { } +QString mkdir_p_asstring(const QString &dir); #endif /* __MAKEFILE_H__ */ 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,74 +1,72 @@ /**************************************************************************** -** $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. ** ** 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 "projectgenerator.h" #include "option.h" #include <qdir.h> #include <qfile.h> #include <qfileinfo.h> #include <qregexp.h> QString project_builtin_regx() //calculate the builtin regular expression.. { QString ret; QStringList builtin_exts(".c"); builtin_exts << Option::ui_ext << Option::yacc_ext << Option::lex_ext << ".ts"; builtin_exts += Option::h_ext + Option::cpp_ext; for(QStringList::Iterator ext_it = builtin_exts.begin(); ext_it != builtin_exts.end(); ++ext_it) { if(!ret.isEmpty()) ret += "; "; ret += QString("*") + (*ext_it); } return ret; } ProjectGenerator::ProjectGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE) { } void ProjectGenerator::init() { if(init_flag) return; int file_count = 0; init_flag = TRUE; QMap<QString, QStringList> &v = project->variables(); @@ -96,148 +94,152 @@ ProjectGenerator::init() bool add_depend = FALSE; if(QFile::exists((*pd))) { QFileInfo fi((*pd)); if(fi.isDir()) { dir = (*pd); add_depend = TRUE; if(dir.right(1) != Option::dir_sep) dir += Option::dir_sep; if(Option::projfile::do_recursive) { QDir d(dir); d.setFilter(QDir::Dirs); for(int i = 0; i < (int)d.count(); i++) { if(d[i] != "." && d[i] != "..") dirs.append(dir + d[i] + QDir::separator() + builtin_regex); } } regex = builtin_regex; } else { QString file = (*pd); int s = file.findRev(Option::dir_sep); if(s != -1) dir = file.left(s+1); if(addFile(file)) { add_depend = TRUE; file_count++; } } } else { //regexp regex = (*pd); } if(!regex.isEmpty()) { int s = regex.findRev(Option::dir_sep); if(s != -1) { dir = regex.left(s+1); regex = regex.right(regex.length() - (s+1)); } if(Option::projfile::do_recursive) { QDir d(dir); d.setFilter(QDir::Dirs); for(int i = 0; i < (int)d.count(); i++) { if(d[i] != "." && d[i] != "..") dirs.append(dir + d[i] + QDir::separator() + regex); } } QDir d(dir, regex); for(int i = 0; i < (int)d.count(); i++) { QString file = dir + d[i]; if (addFile(file)) { add_depend = TRUE; file_count++; } } } if(add_depend && !dir.isEmpty() && !v["DEPENDPATH"].contains(dir)) { QFileInfo fi(dir); if(fi.absFilePath() != QDir::currentDirPath()) v["DEPENDPATH"] += fileFixify(dir); } } } if(!file_count) { //shall we try a subdir? QStringList dirs = Option::projfile::project_dirs; if(Option::projfile::do_pwd) dirs.prepend("."); + const QString out_file = fileFixify(Option::output.name()); for(QStringList::Iterator pd = dirs.begin(); pd != dirs.end(); pd++) { if(QFile::exists((*pd))) { QString newdir = (*pd); QFileInfo fi(newdir); if(fi.isDir()) { newdir = fileFixify(newdir); QStringList &subdirs = v["SUBDIRS"]; if(QFile::exists(fi.filePath() + QDir::separator() + fi.fileName() + ".pro") && !subdirs.contains(newdir)) { subdirs.append(newdir); } else { QDir d(newdir, "*.pro"); d.setFilter(QDir::Files); 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); } } if(Option::projfile::do_recursive) { QDir d(newdir); d.setFilter(QDir::Dirs); for(int i = 0; i < (int)d.count(); i++) { QString nd = fileFixify(newdir + QDir::separator() + d[i]); if(d[i] != "." && d[i] != ".." && !dirs.contains(nd)) dirs.append(nd); } } } } else { //regexp QString regx = (*pd), dir; int s = regx.findRev(Option::dir_sep); if(s != -1) { dir = regx.left(s+1); regx = regx.right(regx.length() - (s+1)); } QDir d(dir, regx); d.setFilter(QDir::Dirs); QStringList &subdirs = v["SUBDIRS"]; for(int i = 0; i < (int)d.count(); i++) { QString newdir(dir + d[i]); QFileInfo fi(newdir); if(fi.fileName() != "." && fi.fileName() != "..") { newdir = fileFixify(newdir); if(QFile::exists(fi.filePath() + QDir::separator() + fi.fileName() + ".pro") && !subdirs.contains(newdir)) { subdirs.append(newdir); } else { QDir d(newdir, "*.pro"); d.setFilter(QDir::Files); for(int i = 0; i < (int)d.count(); i++) { QString nd = newdir + QDir::separator() + 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(Option::projfile::do_recursive && !dirs.contains(newdir)) dirs.append(newdir); } } } } v["TEMPLATE_ASSIGN"] = "subdirs"; return; } QPtrList<MakefileDependDir> deplist; deplist.setAutoDelete(TRUE); { QStringList &d = v["DEPENDPATH"]; for(QStringList::Iterator it = d.begin(); it != d.end(); ++it) { QString r = (*it), l = Option::fixPathToLocalOS((*it)); deplist.append(new MakefileDependDir(r, l)); } } QStringList &h = v["HEADERS"]; bool no_qt_files = TRUE; QString srcs[] = { "SOURCES", "YACCSOURCES", "LEXSOURCES", "INTERFACES", QString::null }; @@ -263,220 +265,224 @@ ProjectGenerator::init() hit != Option::h_ext.end(); ++hit) { if((*dep_it).endsWith((*hit))) { h_ext = (*hit); break; } } if(!h_ext.isEmpty()) { if((*dep_it).left(1).lower() == "q") { QString qhdr = (*dep_it).lower(); if(file_no_path == "qthread.h") addConfig("thread"); } for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { QString src((*dep_it).left((*dep_it).length() - h_ext.length()) + (*cppit)); if(QFile::exists(src)) { bool exists = FALSE; QStringList &srcl = v["SOURCES"]; for(QStringList::Iterator src_it = srcl.begin(); src_it != srcl.end(); ++src_it) { if((*src_it).lower() == src.lower()) { exists = TRUE; break; } } if(!exists) srcl.append(src); } } } else if((*dep_it).endsWith(Option::lex_ext) && file_no_path.startsWith(Option::lex_mod)) { addConfig("lex_included"); } if(!h.contains((*dep_it))) { if(generateMocList((*dep_it)) && !findMocDestination((*dep_it)).isEmpty()) h += (*dep_it); } } } } } } if(h.isEmpty()) addConfig("moc", FALSE); //if we find a file that matches an forms it needn't be included in the project QStringList &u = v["INTERFACES"]; QString no_ui[] = { "SOURCES", "HEADERS", QString::null }; { for(int i = 0; !no_ui[i].isNull(); i++) { QStringList &l = v[no_ui[i]]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ) { bool found = FALSE; for(QStringList::Iterator ui_it = u.begin(); ui_it != u.end(); ++ui_it) { QString s1 = (*val_it).right((*val_it).length() - ((*val_it).findRev(Option::dir_sep) + 1)); if(s1.findRev('.') != -1) s1 = s1.left(s1.findRev('.')) + Option::ui_ext; QString u1 = (*ui_it).right((*ui_it).length() - ((*ui_it).findRev(Option::dir_sep) + 1)); if(s1 == u1) { found = TRUE; break; } } - if(!found && (*val_it).endsWith(Option::moc_ext)) + if(!found && (*val_it).endsWith(Option::cpp_moc_ext)) found = TRUE; if(found) val_it = l.remove(val_it); else ++val_it; } } } } bool ProjectGenerator::writeMakefile(QTextStream &t) { t << "######################################################################" << endl; t << "# Automatically generated by qmake (" << qmake_version() << ") " << QDateTime::currentDateTime().toString() << endl; t << "######################################################################" << endl << endl; QStringList::Iterator it; for(it = Option::before_user_vars.begin(); it != Option::before_user_vars.end(); ++it) t << (*it) << endl; t << getWritableVar("TEMPLATE_ASSIGN", FALSE); if(project->first("TEMPLATE_ASSIGN") == "subdirs") { t << endl << "# Directories" << "\n" << getWritableVar("SUBDIRS"); } else { t << getWritableVar("TARGET") << getWritableVar("CONFIG", FALSE) << getWritableVar("CONFIG_REMOVE", FALSE) << getWritableVar("DEPENDPATH") << getWritableVar("INCLUDEPATH") << endl; t << "# Input" << "\n"; t << getWritableVar("HEADERS") << getWritableVar("INTERFACES") << getWritableVar("LEXSOURCES") << getWritableVar("YACCSOURCES") << getWritableVar("SOURCES") << getWritableVar("TRANSLATIONS"); } for(it = Option::after_user_vars.begin(); it != Option::after_user_vars.end(); ++it) t << (*it) << endl; return TRUE; } bool ProjectGenerator::addConfig(const QString &cfg, bool add) { QString where = "CONFIG"; if(!add) where = "CONFIG_REMOVE"; if(!project->variables()[where].contains(cfg)) { project->variables()[where] += cfg; return TRUE; } return FALSE; } bool ProjectGenerator::addFile(QString file) { file = fileFixify(file, QDir::currentDirPath()); QString dir; int s = file.findRev(Option::dir_sep); if(s != -1) 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; QString where; for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { if(file.endsWith((*cppit))) { if(QFile::exists(file.left(file.length() - (*cppit).length()) + Option::ui_ext)) return FALSE; else where = "SOURCES"; break; } } if(where.isEmpty()) { for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) { if(file.endsWith((*hit))) { where = "HEADERS"; break; } } } if(where.isEmpty()) { if(file.endsWith(Option::ui_ext)) where = "INTERFACES"; else if(file.endsWith(".c")) where = "SOURCES"; else if(file.endsWith(Option::lex_ext)) where = "LEXSOURCES"; else if(file.endsWith(Option::yacc_ext)) where = "YACCSOURCES"; else if(file.endsWith(".ts")) where = "TRANSLATIONS"; } QString newfile = fileFixify(file); if(!where.isEmpty() && !project->variables()[where].contains(file)) { project->variables()[where] += newfile; return TRUE; } return FALSE; } QString -ProjectGenerator::getWritableVar(const QString &v, bool /*fixPath*/) +ProjectGenerator::getWritableVar(const QString &v, bool fixPath) { QStringList &vals = project->variables()[v]; if(vals.isEmpty()) return ""; QString ret; if(v.endsWith("_REMOVE")) ret = v.left(v.length() - 7) + " -= "; else if(v.endsWith("_ASSIGN")) ret = v.left(v.length() - 7) + " = "; else ret = v + " += "; QString join = vals.join(" "); if(ret.length() + join.length() > 80) { QString spaces; for(unsigned int i = 0; i < ret.length(); i++) spaces += " "; join = vals.join(" \\\n" + spaces); } +#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"; } bool ProjectGenerator::openOutput(QFile &file) const { QString outdir; if(!file.name().isEmpty()) { QFileInfo fi(file); if(fi.isDir()) outdir = fi.dirPath() + QDir::separator(); } if(!outdir.isEmpty() || file.name().isEmpty()) { QString dir = QDir::currentDirPath(); int s = dir.findRev('/'); if(s != -1) dir = dir.right(dir.length() - (s + 1)); file.setName(outdir + dir + ".pro"); } return MakefileGenerator::openOutput(file); } 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,61 +1,59 @@ /**************************************************************************** -** $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. ** ** 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 __PROJECTGENERATOR_H__ #define __PROJECTGENERATOR_H__ #include "makefile.h" class ProjectGenerator : public MakefileGenerator { bool init_flag; bool addFile(QString); bool addConfig(const QString &, bool add=TRUE); QString getWritableVar(const QString &, bool fixPath=TRUE); protected: virtual void init(); virtual bool writeMakefile(QTextStream &); public: ProjectGenerator(QMakeProject *p); ~ProjectGenerator(); virtual bool openOutput(QFile &) const; }; inline ProjectGenerator::~ProjectGenerator() { } #endif /* __PROJECTGENERATOR_H__ */ 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,604 +1,877 @@ /**************************************************************************** -** $Id$ +** ** -** Definition of ________ class. -** -** Created : 970521 +** Implementation of UnixMakefileGenerator class. ** ** 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. ** ** 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 "unixmake.h" #include "option.h" #include <qregexp.h> #include <qfile.h> #include <qdict.h> #include <qdir.h> #include <time.h> void UnixMakefileGenerator::init() { if(init_flag) return; init_flag = TRUE; if(!project->isEmpty("QMAKE_FAILED_REQUIREMENTS")) /* no point */ return; QStringList &configs = project->variables()["CONFIG"]; /* 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->isEmpty("MAKEFILE")) project->variables()["MAKEFILE"].append("Makefile"); if(project->isEmpty("QMAKE")) project->variables()["QMAKE"].append("qmake"); if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].findIndex("qmake_all") == -1) project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all"); return; /* subdirs is done */ } if( project->isEmpty("QMAKE_EXTENSION_SHLIB") ) { if ( project->isEmpty("QMAKE_CYGWIN_SHLIB") ) { project->variables()["QMAKE_EXTENSION_SHLIB"].append( "so" ); } else { project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dll" ); } } + 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 if(!project->isEmpty("TARGET")) { QString targ = project->first("TARGET"); int slsh = QMAX(targ.findRev('/'), targ.findRev(Option::dir_sep)); if(slsh != -1) { if(project->isEmpty("DESTDIR")) project->values("DESTDIR").append(""); else if(project->first("DESTDIR").right(1) != Option::dir_sep) project->variables()["DESTDIR"] = project->first("DESTDIR") + Option::dir_sep; project->variables()["DESTDIR"] = project->first("DESTDIR") + targ.left(slsh+1); project->variables()["TARGET"] = targ.mid(slsh+1); } } project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; bool is_qt = (project->first("TARGET") == "qt" || project->first("TARGET") == "qte" || project->first("TARGET") == "qt-mt" || project->first("TARGET") == "qte-mt"); bool extern_libs = !project->isEmpty("QMAKE_APP_FLAG") || (!project->isEmpty("QMAKE_LIB_FLAG") && 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") ) || (project->isActiveConfig("qt") && project->isActiveConfig( "plugin" ) )) { if(configs.findIndex("dll") == -1) configs.append("dll"); } else if ( !project->isEmpty("QMAKE_APP_FLAG") || project->isActiveConfig("dll") ) { configs.remove("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") ) { 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 { 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->isEmpty("QMAKE_INCREMENTAL")) project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_INCREMENTAL"]; else if(!project->isEmpty("QMAKE_LFLAGS_PREBIND") && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() && project->isActiveConfig("dll")) project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PREBIND"]; if(!project->isEmpty("QMAKE_INCDIR")) project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"]; if(!project->isEmpty("QMAKE_LIBDIR")) { 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"]; } if ( project->isActiveConfig("qt") ) { 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(configs.findIndex("moc")) configs.append("moc"); project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; if ( !project->isActiveConfig("debug") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG"); 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"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; } } - if ( project->isActiveConfig("opengl") ) { + if ( project->isActiveConfig("opengl") && !project->isActiveConfig("dlopen_opengl")) { project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"]; if(!project->isEmpty("QMAKE_LIBDIR_OPENGL")) project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_OPENGL", "-L", " -L", ""); if ( is_qt ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL_QT"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; } - 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") ) project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_X11"]; if ( project->isActiveConfig("x11lib") ) { if(!project->isEmpty("QMAKE_LIBDIR_X11")) project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_X11", "-L", " -L", ""); project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11"]; } if ( project->isActiveConfig("x11sm") ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11SM"]; if ( project->isActiveConfig("dylib") ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_DYNLOAD"]; if ( project->isActiveConfig("thread") ) { if(project->isActiveConfig("qt")) 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"]; project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_THREAD"]; if(!project->isEmpty("QMAKE_LFLAGS_THREAD")) project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_THREAD"]; } if ( project->isActiveConfig("moc") ) 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); project->variables()["SOURCES"].prepend(allmoc); project->variables()["HEADERS_ORIG"] = project->variables()["HEADERS"]; project->variables()["HEADERS"].clear(); } + 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 MakefileGenerator::init(); if ( project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { if(!project->isEmpty("QMAKE_APP_FLAG")) { if(project->isEmpty("DESTDIR")) project->values("DESTDIR").append(""); project->variables()["DESTDIR"].first() += project->variables()["TARGET"].first() + ".app/Contents/MacOS/"; project->variables()["QMAKE_PKGINFO"].append(project->first("DESTDIR") + "../PkgInfo"); project->variables()["ALL_DEPS"] += project->first("QMAKE_PKGINFO"); - 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") + "../Info.plist"); project->variables()["ALL_DEPS"] += project->first("QMAKE_INFO_PLIST_OUT"); if(!project->isEmpty("RC_FILE")) project->variables()["ALL_DEPS"] += project->first("DESTDIR") + "../Resources/application.icns"; } } } if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES")) project->variables()["DISTFILES"] += project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"]; project->variables()["DISTFILES"] += Option::mkfile::project_files; init2(); project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "QMAKE_LIBDIR_FLAGS" << "QMAKE_LIBS"; if(!project->isEmpty("QMAKE_MAX_FILES_PER_AR")) { bool ok; int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(&ok); QStringList ar_sublibs, objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"]; if(ok && max_files > 5 && max_files < (int)objs.count()) { int obj_cnt = 0, lib_cnt = 0; QString lib; for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) { if((++obj_cnt) >= max_files) { if(lib_cnt) { lib.sprintf("lib%s-tmp%d.a", project->first("QMAKE_ORIG_TARGET").latin1(), lib_cnt); ar_sublibs << lib; obj_cnt = 0; } lib_cnt++; } } } if(!ar_sublibs.isEmpty()) { project->variables()["QMAKE_AR_SUBLIBS"] = ar_sublibs; project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "QMAKE_AR_SUBLIBS"; } } + + 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; + } + } + } } 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) { ret.append("-framework " + framework_in); } else { ret.append("-framework"); ret.append(framework_in); } } + } 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)); } return ret; } - void UnixMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l) { 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 MakefileGenerator::processPrlVariable(var, l); } +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 UnixMakefileGenerator::findLibraries() { QPtrList<MakefileDependDir> libdirs; libdirs.setAutoDelete(TRUE); const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null }; for(int i = 0; !lflags[i].isNull(); i++) { QStringList &l = project->variables()[lflags[i]]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString stub, dir, extn, opt = (*it).stripWhiteSpace(); if(opt.startsWith("-")) { if(opt.startsWith("-L")) { QString r = opt.right(opt.length() - 2), l = r; fixEnvVariables(l); libdirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } else if(opt.startsWith("-l")) { stub = opt.mid(2); } else if(project->isActiveConfig("macx") && opt.startsWith("-framework")) { if(opt.length() > 11) { opt = opt.mid(11); } else { ++it; opt = (*it); } extn = ""; dir = "/System/Library/Frameworks/" + opt + ".framework/"; stub = opt; } } else { extn = dir = ""; stub = opt; int slsh = opt.findRev(Option::dir_sep); if(slsh != -1) { dir = opt.left(slsh); stub = opt.mid(slsh+1); } QRegExp stub_reg("^.*lib(" + stub + "[^./=]*)\\.(.*)$"); if(stub_reg.exactMatch(stub)) { stub = stub_reg.cap(1); extn = stub_reg.cap(2); } } if(!stub.isEmpty()) { - const QString modifs[] = { "-mt", QString::null }; + const QString modifs[] = { "", "-mt", QString::null }; for(int modif = 0; !modifs[modif].isNull(); modif++) { bool found = FALSE; QStringList extens; if(!extn.isNull()) extens << extn; else extens << project->variables()["QMAKE_EXTENSION_SHLIB"].first() << "a"; for(QStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) { if(dir.isNull()) { QString lib_stub; for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { if(QFile::exists(mdd->local_dir + Option::dir_sep + "lib" + stub + modifs[modif] + "." + (*extit))) { lib_stub = stub + modifs[modif]; break; } } if(!lib_stub.isNull()) { (*it) = "-l" + lib_stub; found = TRUE; break; } } else { if(QFile::exists("lib" + stub + modifs[modif] + "." + (*extit))) { (*it) = "lib" + stub + modifs[modif] + "." + (*extit); found = TRUE; break; } } } + 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; + } } } } return FALSE; } +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 UnixMakefileGenerator::processPrlFiles() { QDict<void> processed; QPtrList<MakefileDependDir> libdirs; libdirs.setAutoDelete(TRUE); const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null }; for(int i = 0; !lflags[i].isNull(); i++) { for(bool ret = FALSE; TRUE; ret = FALSE) { QStringList l_out; QStringList &l = project->variables()[lflags[i]]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { project->variables()["QMAKE_CURRENT_PRL_LIBS"].clear(); - QString opt = (*it).stripWhiteSpace();; + QString opt = (*it).stripWhiteSpace(); if(opt.startsWith("-")) { if(opt.startsWith("-L")) { QString r = opt.right(opt.length() - 2), l = r; fixEnvVariables(l); libdirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } 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)) { if(prl.startsWith(mdd->local_dir)) 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); ret = TRUE; break; } } } else if(project->isActiveConfig("macx") && opt.startsWith("-framework")) { if(opt.length() > 11) { opt = opt.mid(11); } else { ++it; opt = (*it); } QString prl = "/System/Library/Frameworks/" + opt + - ".framework/" + opt + Option::prl_ext; + ".framework/" + opt; if(processPrlFile(prl)) ret = TRUE; l_out.append("-framework"); } if(!opt.isEmpty()) 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"]); } } if(ret && l != l_out) l = l_out; else break; } } } QString UnixMakefileGenerator::defaultInstall(const QString &t) { if(t != "target" || project->first("TEMPLATE") == "subdirs") return QString(); bool resource = FALSE; const QString root = "$(INSTALL_ROOT)"; QStringList &uninst = project->variables()[t + ".uninstall"]; QString ret, destdir=project->first("DESTDIR"); QString targetdir = Option::fixPathToTargetOS(project->first("target.path"), FALSE); if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep) destdir += Option::dir_sep; targetdir = fileFixify(targetdir); if(targetdir.right(1) != Option::dir_sep) targetdir += Option::dir_sep; QStringList links; QString target="$(TARGET)"; if(project->first("TEMPLATE") == "app") { target = "$(QMAKE_TARGET)"; if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { destdir += "../../../"; target += ".app"; resource = TRUE; } } 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"); int slsh = dst_prl.findRev('/'); if(slsh != -1) dst_prl = dst_prl.right(dst_prl.length() - slsh - 1); 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()) uninst.append("\n\t"); uninst.append("-$(DEL_FILE) \"" + dst_prl + "\""); } + 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") ) { if ( !project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin") ) { if ( project->isEmpty("QMAKE_HPUX_SHLIB") ) { links << "$(TARGET0)" << "$(TARGET1)" << "$(TARGET2)"; } else { links << "$(TARGET0)"; } } } } - 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 + "\""); + } } } } return ret; } - 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,72 +1,82 @@ /**************************************************************************** -** $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. ** ** 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 __UNIXMAKE_H__ #define __UNIXMAKE_H__ #include "makefile.h" class UnixMakefileGenerator : public MakefileGenerator { bool init_flag, include_deps; 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 &); public: UnixMakefileGenerator(QMakeProject *p); ~UnixMakefileGenerator(); protected: + virtual bool doPrecompiledHeaders() const { return project->isActiveConfig("precompile_header"); } virtual bool doDepends() const { return !include_deps && MakefileGenerator::doDepends(); } virtual QString defaultInstall(const QString &); virtual void processPrlVariable(const QString &, const QStringList &); virtual void processPrlFiles(); virtual bool findLibraries(); + virtual QString findDependency(const QString &); + virtual QStringList &findDependencies(const QString &); virtual void init(); void writeMakeParts(QTextStream &); void writeSubdirs(QTextStream &, bool=TRUE); private: void init2(); }; inline UnixMakefileGenerator::~UnixMakefileGenerator() { } #endif /* __UNIXMAKE_H__ */ 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,1110 +1,1588 @@ /**************************************************************************** -** $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. ** ** 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 "unixmake.h" #include "option.h" +#include "meta.h" #include <qregexp.h> #include <qfile.h> #include <qdir.h> #include <time.h> +QString mkdir_p_asstring(const QString &dir); UnixMakefileGenerator::UnixMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE), include_deps(FALSE) { } +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 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 (" << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t" << "@echo \"Skipped.\"" << endl << endl; writeMakeQmake(t); return TRUE; } if (project->variables()["TEMPLATE"].first() == "app" || project->variables()["TEMPLATE"].first() == "lib") { writeMakeParts(t); return MakefileGenerator::writeMakefile(t); } else if(project->variables()["TEMPLATE"].first() == "subdirs") { writeSubdirs(t); return TRUE; } return FALSE; } 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") && !project->variables()["QMAKE_INCREMENTAL"].isEmpty() && (!project->variables()["QMAKE_APP_FLAG"].isEmpty() || - !project->isActiveConfig("staticlib"))), + !project->isActiveConfig("staticlib"))), src_incremental=FALSE, moc_incremental=FALSE; t << "####### Compiler, tools and options" << endl << endl; t << "CC = "; if (project->isActiveConfig("thread") && ! project->variables()["QMAKE_CC_THREAD"].isEmpty()) t << var("QMAKE_CC_THREAD") << endl; else t << var("QMAKE_CC") << endl; t << "CXX = "; if (project->isActiveConfig("thread") && ! project->variables()["QMAKE_CXX_THREAD"].isEmpty()) t << var("QMAKE_CXX_THREAD") << endl; else t << 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 = " << "-I" << specdir(); if(!project->isActiveConfig("no_include_pwd")) { QString pwd = fileFixify(QDir::currentDirPath()); if(pwd.isEmpty()) pwd = "."; t << " -I" << pwd; } t << varGlue("INCLUDEPATH"," -I", " -I", "") << endl; if(!project->isActiveConfig("staticlib")) { t << "LINK = "; if (project->isActiveConfig("thread") && ! project->variables()["QMAKE_LINK_THREAD"].isEmpty()) t << var("QMAKE_LINK_THREAD") << endl; else t << var("QMAKE_LINK") << endl; t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl; t << "LIBS = " << "$(SUBLIBS) " << var("QMAKE_LIBDIR_FLAGS") << " " << var("QMAKE_LIBS") << endl; } t << "AR = " << var("QMAKE_AR") << endl; t << "RANLIB = " << var("QMAKE_RANLIB") << endl; t << "MOC = " << var("QMAKE_MOC") << endl; t << "UIC = " << var("QMAKE_UIC") << endl; t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; t << "TAR = " << var("QMAKE_TAR") << endl; t << "GZIP = " << var("QMAKE_GZIP") << endl; + if(project->isActiveConfig("compile_libtool")) + t << "LIBTOOL = " << var("QMAKE_LIBTOOL") << endl; t << "COPY = " << var("QMAKE_COPY") << endl; t << "COPY_FILE= " << var("QMAKE_COPY_FILE") << endl; 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; t << "SYMLINK = " << var("QMAKE_SYMBOLIC_LINK") << endl; t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; t << "MOVE = " << var("QMAKE_MOVE") << endl; t << "PRO = " << fileFixify(project->projectFile() )<< 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") << endl; else t << "OBJECTS_DIR = ./" << endl; t << endl; /* files */ t << "####### Files" << endl << endl; t << "HEADERS = " << varList("HEADERS") << endl; t << "SOURCES = " << varList("SOURCES") << endl; if(do_incremental) { QStringList &objs = project->variables()["OBJECTS"], &incrs = project->variables()["QMAKE_INCREMENTAL"], incrs_out; t << "OBJECTS = "; for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) { bool increment = FALSE; for(QStringList::Iterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) { if((*objit).find(QRegExp((*incrit), TRUE, TRUE)) != -1) { increment = TRUE; incrs_out.append((*objit)); break; } } if(!increment) t << "\\\n\t\t" << (*objit); } if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done! t << incrs_out.join(" \\\n\t\t") << endl; } else if(!incrs_out.count()) { t << endl; } else { src_incremental = TRUE; t << endl; t << "INCREMENTAL_OBJECTS = " << incrs_out.join(" \\\n\t\t") << endl; } } else { t << "OBJECTS = " << varList("OBJECTS") << endl; } t << "FORMS = " << varList("FORMS") << endl; t << "UICDECLS = " << varList("UICDECLS") << endl; t << "UICIMPLS = " << varList("UICIMPLS") << endl; QString srcMoc = varList("SRCMOC"), objMoc = varList("OBJMOC"); t << "SRCMOC = " << srcMoc << endl; if(do_incremental) { QStringList &objs = project->variables()["OBJMOC"], &incrs = project->variables()["QMAKE_INCREMENTAL"], incrs_out; t << "OBJMOC = "; for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) { bool increment = FALSE; for(QStringList::Iterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) { if((*objit).find(QRegExp((*incrit), TRUE, TRUE)) != -1) { increment = TRUE; incrs_out.append((*objit)); break; } } if(!increment) t << "\\\n\t\t" << (*objit); } if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done! t << incrs_out.join(" \\\n\t\t") << endl; } else if(!incrs_out.count()) { t << endl; } else { moc_incremental = TRUE; t << endl; t << "INCREMENTAL_OBJMOC = " << incrs_out.join(" \\\n\t\t") << endl; } } else { t << "OBJMOC = " << objMoc << endl; } if(do_incremental && !moc_incremental && !src_incremental) 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; t << "QMAKE_TARGET = " << var("QMAKE_ORIG_TARGET") << endl; t << "DESTDIR = " << var("DESTDIR") << endl; + if(project->isActiveConfig("compile_libtool")) + t << "TARGETL = " << var("TARGET_la") << endl; t << "TARGET = " << var("TARGET") << endl; if(project->isActiveConfig("plugin") ) { t << "TARGETD = " << var("TARGET") << endl; } else if (!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty()) { t << "TARGETA = " << var("TARGETA") << endl; if (project->isEmpty("QMAKE_HPUX_SHLIB")) { t << "TARGETD = " << var("TARGET_x.y.z") << endl; t << "TARGET0 = " << var("TARGET_") << endl; t << "TARGET1 = " << var("TARGET_x") << endl; t << "TARGET2 = " << var("TARGET_x.y") << endl; } else { t << "TARGETD = " << var("TARGET_x") << endl; t << "TARGET0 = " << var("TARGET_") << endl; } } + writeExtraVariables(t); t << endl; - // blasted incldues + // blasted includes QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"]; QStringList::Iterator it; for( it = qeui.begin(); it != qeui.end(); ++it) t << "include " << (*it) << endl; /* rules */ t << "first: all" << endl; t << "####### Implicit rules" << endl << endl; - t << ".SUFFIXES: .c"; + t << ".SUFFIXES: .c " << Option::obj_ext; QStringList::Iterator cppit; for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) t << " " << (*cppit); t << endl << endl; 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; if(include_deps) { QString cmd=var("QMAKE_CFLAGS_DEPS") + " "; cmd += varGlue("DEFINES","-D"," -D","") + varGlue("PRL_EXPORT_DEFINES"," -D"," -D",""); if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) cmd += " -I" + project->first("QMAKE_ABSOLUTE_SOURCE_PATH") + " "; cmd += " $(INCPATH) " + varGlue("DEPENDPATH", "-I", " -I", ""); QString odir; if(!project->variables()["OBJECTS_DIR"].isEmpty()) odir = project->first("OBJECTS_DIR"); t << "###### Dependencies" << endl << endl; t << odir << ".deps/%.d: %.cpp\n\t" << "@echo Creating depend for $<" << "\n\t" << "@test -d $(@D) || mkdir -p $(@D)" << "\n\t" << "@$(CXX) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl; t << odir << ".deps/%.d: %.c\n\t" << "@echo Creating depend for $<" << "\n\t" << "@test -d $(@D) || mkdir -p $(@D)" << "\n\t" << "@$(CC) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl; - QString src[] = { "SOURCES", "UICIMPLS", "SRCMOC", QString::null }; for(int x = 0; !src[x].isNull(); x++) { QStringList &l = project->variables()[src[x]]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { if(!(*it).isEmpty()) { QString d_file; if((*it).endsWith(".c")) { d_file = (*it).left((*it).length() - 2); } else { for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { if((*it).endsWith((*cppit))) { d_file = (*it).left((*it).length() - (*cppit).length()); break; } } } if(!d_file.isEmpty()) { 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; } } } } } t << "####### Build rules" << endl << endl; if(!project->variables()["SUBLIBS"].isEmpty()) { QString libdir = "tmp/"; if(!project->isEmpty("SUBLIBS_DIR")) libdir = project->first("SUBLIBS_DIR"); t << "SUBLIBS= "; QStringList &l = project->variables()["SUBLIBS"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) t << libdir << "lib" << (*it) << ".a "; t << endl << endl; } if(project->isActiveConfig("depend_prl") && !project->isEmpty("QMAKE_PRL_INTERNAL_FILES")) { QStringList &l = project->variables()["QMAKE_PRL_INTERNAL_FILES"]; QStringList::Iterator it; 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; int slsh = (*it).findRev(Option::dir_sep); if(slsh != -1) dir = (*it).left(slsh + 1); - QString targ = dir + proj.first("QMAKE_PRL_TARGET"); + QString targ = dir + libinfo.first("QMAKE_PRL_TARGET"); deps += " " + targ; t << targ << ":" << "\n\t" << "@echo \"Creating '" << targ << "'\"" << "\n\t" - << "(cd " << proj.first("QMAKE_PRL_BUILD_DIR") << ";" + << "(cd " << libinfo.first("QMAKE_PRL_BUILD_DIR") << ";" << "$(MAKE) )" << endl; } } } if(!project->variables()["QMAKE_APP_FLAG"].isEmpty()) { QString destdir = project->first("DESTDIR"); if(do_incremental) { //incremental target QString incr_target = var("TARGET") + "_incremental"; if(incr_target.find(Option::dir_sep) != -1) incr_target = incr_target.right(incr_target.length() - (incr_target.findRev(Option::dir_sep) + 1)); QString incr_deps, incr_objs; if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") { QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext; //actual target t << incr_target_dir << ": $(OBJECTS)" << "\n\t" << "ld -r -o "<< incr_target_dir << " $(OBJECTS)" << endl; //communicated below deps.prepend(incr_target_dir + " "); incr_deps = "$(UICDECLS) $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC) $(OBJMOC)"; if(!incr_objs.isEmpty()) incr_objs += " "; incr_objs += incr_target_dir; } else { //actual target QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." + project->variables()["QMAKE_EXTENSION_SHLIB"].first(); QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " "; if(project->isActiveConfig("debug")) incr_lflags += var("QMAKE_LFLAGS_DEBUG"); else incr_lflags += var("QMAKE_LFLAGS_RELEASE"); t << incr_target_dir << ": $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << "\n\t"; if(!destdir.isEmpty()) t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << endl; //communicated below if(!destdir.isEmpty()) { if(!incr_objs.isEmpty()) incr_objs += " "; incr_objs += "-L" + destdir; } else { if(!incr_objs.isEmpty()) incr_objs += " "; incr_objs += "-L" + QDir::currentDirPath(); } if(!incr_objs.isEmpty()) incr_objs += " "; incr_objs += " -l" + incr_target; deps.prepend(incr_target_dir + " "); incr_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)"; } t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl; //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"; if(!destdir.isEmpty()) t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; if(!project->isEmpty("QMAKE_PRE_LINK")) 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")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } else { t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl; - 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()) t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; if(!project->isEmpty("QMAKE_PRE_LINK")) 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")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } } else if(!project->isActiveConfig("staticlib")) { QString destdir = project->first("DESTDIR"), incr_deps; if(do_incremental) { QString s_ext = project->variables()["QMAKE_EXTENSION_SHLIB"].first(); QString incr_target = var("QMAKE_ORIG_TARGET").replace( QRegExp("\\." + s_ext), "").replace(QRegExp("^lib"), "") + "_incremental"; if(incr_target.find(Option::dir_sep) != -1) incr_target = incr_target.right(incr_target.length() - (incr_target.findRev(Option::dir_sep) + 1)); if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") { QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext; //actual target const QString link_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)"; t << incr_target_dir << ": " << link_deps << "\n\t" << "ld -r -o " << incr_target_dir << " " << link_deps << endl; //communicated below QStringList &cmd = project->variables()["QMAKE_LINK_SHLIB_CMD"]; cmd.first().replace("$(OBJECTS) $(OBJMOC)", "$(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"); //ick cmd.append(incr_target_dir); deps.prepend(incr_target_dir + " "); incr_deps = "$(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"; } else { //actual target QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." + s_ext; QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " "; if(!project->isEmpty("QMAKE_LFLAGS_INCREMENTAL")) incr_lflags += var("QMAKE_LFLAGS_INCREMENTAL") + " "; if(project->isActiveConfig("debug")) incr_lflags += var("QMAKE_LFLAGS_DEBUG"); else incr_lflags += var("QMAKE_LFLAGS_RELEASE"); t << incr_target_dir << ": $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << "\n\t"; if(!destdir.isEmpty()) t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << endl; //communicated below QStringList &cmd = project->variables()["QMAKE_LINK_SHLIB_CMD"]; if(!destdir.isEmpty()) cmd.append(" -L" + destdir); cmd.append(" -l" + incr_target); deps.prepend(incr_target_dir + " "); incr_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)"; } t << "all: " << " " << deps << " " << varGlue("ALL_DEPS",""," ","") << " " << var("DESTDIR_TARGET") << endl << endl; //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 { t << "all: " << deps << " " << varGlue("ALL_DEPS",""," ","") << " " << 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"); } if(!destdir.isEmpty()) t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir; if(!project->isEmpty("QMAKE_PRE_LINK")) t << "\n\t" << var("QMAKE_PRE_LINK"); - 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" << "-$(DEL_FILE) $(TARGET)" << "\n\t" << var("QMAKE_LINK_SHLIB_CMD"); if(!destdir.isEmpty()) t << "\n\t" << "-$(MOVE) $(TARGET) " << var("DESTDIR"); if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK") << "\n\t"; t << endl << endl; } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) { t << "\n\t" << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)" << "\n\t" << var("QMAKE_LINK_SHLIB_CMD") << "\n\t"; t << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)") << "\n\t" << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t" << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)"); if(!destdir.isEmpty()) t << "\n\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)\n\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET0)\n\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET1)\n\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET2)\n\t" << "-$(MOVE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2) " << var("DESTDIR"); if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } else { t << "\n\t" << "-$(DEL_FILE) $(TARGET) $(TARGET0)" << "\n\t" << var("QMAKE_LINK_SHLIB_CMD") << "\n\t"; t << varGlue("QMAKE_LN_SHLIB",""," "," $(TARGET) $(TARGET0)"); if(!destdir.isEmpty()) t << "\n\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)\n\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET0)\n\t" << "-$(MOVE) $(TARGET) $(TARGET0) " << var("DESTDIR"); if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } t << endl << endl; if (! project->isActiveConfig("plugin")) { 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) t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"; t << var("POST_TARGETDEPS") << "\n\t" << "-$(DEL_FILE) $(TARGETA) " << "\n\t" << var("QMAKE_AR_CMD"); if(do_incremental) t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"; if(!project->isEmpty("QMAKE_RANLIB")) t << "\n\t" << "$(RANLIB) $(TARGETA)"; t << endl << endl; } } 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" << "staticlib: " << var("DESTDIR") << "$(TARGET)" << "\n\n"; 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")) { QString destdir = project->first("DESTDIR"); t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; } t << "-$(DEL_FILE) $(TARGET)" << "\n\t" << var("QMAKE_AR_CMD") << "\n"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\t" << var("QMAKE_POST_LINK") << "\n"; if(!project->isEmpty("QMAKE_RANLIB")) t << "\t" << "$(RANLIB) $(TARGET)" << "\n"; - if(!project->isEmpty("DESTDIR")) + if(!project->isEmpty("DESTDIR")) t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)" << "\n" << "\t" << "-$(MOVE) $(TARGET) " << var("DESTDIR") << "\n"; } else { 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); QString ar; 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(" ")); } else { t << (*libit) << ": " << valList(build) << "\n\t"; ar = "$(AR) " + (*libit) + " " + build.join(" "); } if(!project->isEmpty("DESTDIR")) { QString destdir = project->first("DESTDIR"); t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; } t << "-$(DEL_FILE) " << (*libit) << "\n\t" << ar << "\n"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\t" << var("QMAKE_POST_LINK") << "\n"; if(!project->isEmpty("QMAKE_RANLIB")) t << "\t" << "$(RANLIB) " << (*libit) << "\n"; - if(!project->isEmpty("DESTDIR")) + if(!project->isEmpty("DESTDIR")) t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << (*libit) << "\n" << "\t" << "-$(MOVE) " << (*libit) << " " << var("DESTDIR") << "\n"; } } t << endl << endl; } - t << "mocables: $(SRCMOC)" << endl << endl; + t << "mocables: $(SRCMOC)" << endl + << "uicables: $(UICDECLS) $(UICIMPLS)" << endl << endl; if(!project->isActiveConfig("no_mocdepend")) { //this is an implicity depend on moc, so it will be built if necesary, however //moc itself shouldn't have this dependency - this is a little kludgy but it is //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; } 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; + } + } if(!project->first("QMAKE_PKGINFO").isEmpty()) { QString pkginfo = project->first("QMAKE_PKGINFO"); QString destdir = project->first("DESTDIR"); t << pkginfo << ": " << "\n\t"; if(!destdir.isEmpty()) t << "@test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; t << "@$(DEL_FILE) " << pkginfo << "\n\t" << "@echo \"APPL????\" >" << pkginfo << endl; } if(!project->first("QMAKE_INFO_PLIST").isEmpty()) { 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"); t << info_plist_out << ": " << "\n\t"; if(!destdir.isEmpty()) t << "@test -d " << destdir << " || mkdir -p " << destdir << "\n\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; } } QString ddir = project->isEmpty("QMAKE_DISTDIR") ? project->first("QMAKE_ORIG_TARGET") : project->first("QMAKE_DISTDIR"); QString ddir_c = fileFixify((project->isEmpty("OBJECTS_DIR") ? QString(".tmp/") : project->first("OBJECTS_DIR")) + ddir); t << "dist: " << "\n\t" << "@mkdir -p " << ddir_c << " && " << "$(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) " << ddir_c << Option::dir_sep << " && "; if(!project->isEmpty("TRANSLATIONS")) 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")) { QStringList &forms = project->variables()["FORMS"], ui_headers; for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) { QString ui_h = fileFixify((*formit) + Option::h_ext.first()); - if(QFile::exists(ui_h) ) + if(QFile::exists(ui_h) ) ui_headers << ui_h; } if(!ui_headers.isEmpty()) t << "$(COPY_FILE) --parents " << val(ui_headers) << " " << ddir_c << Option::dir_sep << " && "; } t << "( cd `dirname " << ddir_c << "` && " << "$(TAR) " << var("QMAKE_ORIG_TARGET") << ".tar " << ddir << " && " << "$(GZIP) " << var("QMAKE_ORIG_TARGET") << ".tar ) && " << "$(MOVE) `dirname " << ddir_c << "`" << Option::dir_sep << var("QMAKE_ORIG_TARGET") << ".tar.gz . && " << "$(DEL_FILE) -r " << ddir_c << endl << endl; QString clean_targets; + t << "mocclean:" << "\n"; if(mocAware()) { - t << "mocclean:" << "\n"; if(!objMoc.isEmpty() || !srcMoc.isEmpty() || moc_incremental) { if(!objMoc.isEmpty()) t << "\t-$(DEL_FILE) $(OBJMOC)" << '\n'; if(!srcMoc.isEmpty()) t << "\t-$(DEL_FILE) $(SRCMOC)" << '\n'; if(moc_incremental) t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJMOC)" << '\n'; clean_targets += " mocclean"; } t << endl; } t << "uiclean:" << "\n"; if (!var("UICIMPLS").isEmpty() || !var("UICDECLS").isEmpty()) { t << "\t-$(DEL_FILE) $(UICIMPLS) $(UICDECLS)" << "\n"; clean_targets += " uiclean"; } t << endl; t << "yaccclean:" << "\n"; if(!var("YACCSOURCES").isEmpty()) { QStringList clean, &l = project->variables()["YACCSOURCES"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QFileInfo fi((*it)); QString dir; if(fi.dirPath() != ".") dir = fi.dirPath() + Option::dir_sep; dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) 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() ); } if(!clean.isEmpty()) { t << "\t-$(DEL_FILE) " << clean.join(" ") << "\n"; clean_targets += " yaccclean"; } } t << "lexclean:" << "\n"; if(!var("LEXSOURCES").isEmpty()) { QStringList clean, &l = project->variables()["LEXSOURCES"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QFileInfo fi((*it)); QString dir; if(fi.dirPath() != ".") dir = fi.dirPath() + Option::dir_sep; dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) 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() ); } if(!clean.isEmpty()) { t << "\t-$(DEL_FILE) " << clean.join(" ") << "\n"; clean_targets += " lexclean"; } } if(do_incremental) { t << "incrclean:" << "\n"; if(src_incremental) t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n"; if(moc_incremental) t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJMOC)" << '\n'; t << endl; } 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")) t << varGlue("QMAKE_IMAGE_COLLECTION", "\t-$(DEL_FILE) ", " ", "") << "\n\t"; if(src_incremental) t << "-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n\t"; t << varGlue("QMAKE_CLEAN","-$(DEL_FILE) "," ","\n\t") << "-$(DEL_FILE) *~ core *.core" << "\n" << varGlue("CLEAN_FILES","\t-$(DEL_FILE) "," ","") << endl << endl; t << "####### Sub-libraries" << endl << endl; if ( !project->variables()["SUBLIBS"].isEmpty() ) { QString libdir = "tmp/"; if(!project->isEmpty("SUBLIBS_DIR")) libdir = project->first("SUBLIBS_DIR"); QStringList &l = project->variables()["SUBLIBS"]; for(it = l.begin(); it != l.end(); ++it) t << libdir << "lib" << (*it) << ".a" << ":\n\t" << var(QString("MAKELIB") + (*it)) << endl << endl; } QString destdir = project->first("DESTDIR"); if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep) destdir += Option::dir_sep; t << "distclean: " << "clean\n"; if(project->first("TEMPLATE") == "app" && project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) 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 t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << "$(TARGET)" << "\n"; 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) " << destdir << "$(TARGET2) $(TARGETA)" << "\n"; t << endl << endl; - 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; } - // blasted user defined targets + // user defined targets QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_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; } + if(project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; t << targ << ":" << deps << "\n\t" << cmd << endl << endl; } + // 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; } struct SubDir { QString directory, profile, target, makefile; }; void 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; { QStringList subdirs_in = project->variables()["SUBDIRS"]; for(QStringList::Iterator it = subdirs_in.begin(); it != subdirs_in.end(); ++it) { QString file = (*it); fileFixify(file); SubDir *sd = new SubDir; subdirs.append(sd); sd->makefile = "$(MAKEFILE)"; if((*it).right(4) == ".pro") { int slsh = file.findRev(Option::dir_sep); if(slsh != -1) { sd->directory = file.left(slsh+1); sd->profile = file.mid(slsh+1); } else { sd->profile = file; } } else { + if(!file.isEmpty()) + sd->profile = file.section(Option::dir_sep, -1) + ".pro"; sd->directory = file; } while(sd->directory.right(1) == Option::dir_sep) sd->directory = sd->directory.left(sd->directory.length() - 1); if(!sd->profile.isEmpty()) { QString basename = sd->directory; int new_slsh = basename.findRev(Option::dir_sep); if(new_slsh != -1) basename = basename.mid(new_slsh+1); if(sd->profile != basename + ".pro") sd->makefile += "." + sd->profile.left(sd->profile.length() - 4); //no need for the .pro } sd->target = "sub-" + (*it); sd->target.replace('/', '-'); sd->target.replace('.', '_'); } } QPtrListIterator<SubDir> it(subdirs); QString ofile = Option::output.name(); if(ofile.findRev(Option::dir_sep) != -1) ofile = ofile.right(ofile.length() - ofile.findRev(Option::dir_sep) -1); t << "MAKEFILE = " << var("MAKEFILE") << endl; t << "QMAKE = " << var("QMAKE") << endl; 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; t << endl << endl; t << "first: all\n\nall: " << ofile << " $(SUBTARGETS)" << endl << endl; // generate target rules for( it.toFirst(); it.current(); ++it) { bool have_dir = !(*it)->directory.isEmpty(); QString mkfile = (*it)->makefile, out; if(have_dir) mkfile.prepend((*it)->directory + Option::dir_sep); if(direct || (*it)->makefile != "$(MAKEFILE)") out = " -o " + (*it)->makefile; //qmake it t << mkfile << ": " << "\n\t"; 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 t << (*it)->target << ": " << mkfile << " FORCE" << "\n\t"; if(have_dir) t << "cd " << (*it)->directory << " && "; t << "$(MAKE) -f " << (*it)->makefile << endl << endl; } if (project->isActiveConfig("ordered")) { // generate dependencies for( it.toFirst(); it.current(); ) { QString tar = it.current()->target; ++it; - if (it.current()) + if (it.current()) t << it.current()->target << ": " << tar << endl; } t << endl; } writeMakeQmake(t); 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 { t << "all: $(SUBTARGETS)" << endl; t << "qmake_all:"; for( it.toFirst(); it.current(); ++it) { t << " "; if(!(*it)->directory.isEmpty()) t << (*it)->directory << Option::dir_sep; t << (*it)->makefile; } for( it.toFirst(); it.current(); ++it) { t << "\n\t ( "; if(!(*it)->directory.isEmpty()) 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"; } 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) { t << "\n\t ( "; if(!(*it)->directory.isEmpty()) t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; "; t << "$(MAKE) -f " << (*it)->makefile << " $@" << "; ) || true"; } 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"; 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 << " $@; $(DEL_FILE) " << (*it)->makefile << "; ) || true"; } t << endl << endl; } + + //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; } void UnixMakefileGenerator::init2() { //version handling if(project->variables()["VERSION"].isEmpty()) project->variables()["VERSION"].append("1.0." + (project->isEmpty("VER_PAT") ? QString("0") : project->first("VER_PAT")) ); QStringList l = QStringList::split('.', project->first("VERSION")); l << "0" << "0"; //make sure there are three project->variables()["VER_MAJ"].append(l[0]); project->variables()["VER_MIN"].append(l[1]); project->variables()["VER_PAT"].append(l[2]); if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { #if 0 if ( project->isActiveConfig("dll") ) { project->variables()["TARGET"] += project->variables()["TARGET.so"]; if(project->variables()["QMAKE_LFLAGS_SHAPP"].isEmpty()) project->variables()["QMAKE_LFLAGS_SHAPP"] += project->variables()["QMAKE_LFLAGS_SHLIB"]; if(!project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty()) project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET"); } #endif project->variables()["TARGET"].first().prepend(project->first("DESTDIR")); if ( !project->variables()["QMAKE_CYGWIN_EXE"].isEmpty() ) project->variables()["TARGET_EXT"].append(".exe"); } else if ( project->isActiveConfig("staticlib") ) { project->variables()["TARGET"].first().prepend("lib"); project->variables()["TARGET"].first() += ".a"; if(project->variables()["QMAKE_AR_CMD"].isEmpty()) project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGET) $(OBJECTS) $(OBJMOC)"); } else { 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() ) project->variables()["QMAKE_AR_CMD"].first().replace("(TARGET)","(TARGETA)"); else 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")); project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"]; if(project->isActiveConfig("qt")) project->variables()["DEFINES"].append("QT_PLUGIN"); } else if ( !project->isEmpty("QMAKE_HPUX_SHLIB") ) { project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".sl"); 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")); project->variables()["TARGET"] = project->variables()["TARGET_x"]; } else if ( !project->isEmpty("QMAKE_AIX_SHLIB") ) { project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".a"); 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->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("QMAKE_EXTENSION_SHLIB")); project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("VER_PAT") + "." + project->first("QMAKE_EXTENSION_SHLIB")); } else { project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ")); project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN")); project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("VER_PAT")); } project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"]; } else { project->variables()["TARGET_"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB")); 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->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("QMAKE_EXTENSION_SHLIB")); project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("VER_PAT") + "." + project->variables()["QMAKE_EXTENSION_SHLIB"].first()); } else { project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ")); project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN")); project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." + project->variables()[ "QMAKE_EXTENSION_SHLIB"].first() + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("VER_PAT")); } project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"]; } if(project->isEmpty("QMAKE_LN_SHLIB")) project->variables()["QMAKE_LN_SHLIB"].append("ln -s"); project->variables()["DESTDIR_TARGET"].append("$(TARGET)"); if ( !project->variables()["DESTDIR"].isEmpty() ) project->variables()["DESTDIR_TARGET"].first().prepend(project->first("DESTDIR")); if ( !project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty()) { if(project->isActiveConfig("plugin")) { if(!project->variables()["TARGET"].isEmpty() ) project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET"); } else { if(!project->variables()["TARGET_x"].isEmpty() ) project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET_x"); } } if ( project->variables()["QMAKE_LINK_SHLIB_CMD"].isEmpty() ) project->variables()["QMAKE_LINK_SHLIB_CMD"].append( - "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)"); + "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) $(OBJCOMP)"); } if(project->isEmpty("QMAKE_SYMBOLIC_LINK")) project->variables()["QMAKE_SYMBOLIC_LINK"].append("ln -sf"); 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"]; } else { 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"]; } QString destdir = project->first("DESTDIR"); if ( !destdir.isEmpty() && !project->variables()["QMAKE_RPATH"].isEmpty() ) { QString rpath_destdir = destdir; if(QDir::isRelativePath(rpath_destdir)) { QFileInfo fi(Option::fixPathToLocalOS(rpath_destdir)); if(fi.convertToAbs()) //strange, shouldn't really happen rpath_destdir = Option::fixPathToTargetOS(rpath_destdir, FALSE); else rpath_destdir = fi.filePath(); } else { rpath_destdir = Option::fixPathToTargetOS(rpath_destdir, FALSE); } project->variables()["QMAKE_LFLAGS"] += project->first("QMAKE_RPATH") + rpath_destdir; } } + 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,509 +1,661 @@ /**************************************************************************** -** $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. ** ** 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 "borland_bmake.h" #include "option.h" #include <qdir.h> #include <qregexp.h> #include <time.h> #include <stdlib.h> BorlandMakefileGenerator::BorlandMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) { } bool BorlandMakefileGenerator::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; return TRUE; } if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") { writeBorlandParts(t); return MakefileGenerator::writeMakefile(t); } else if(project->first("TEMPLATE") == "subdirs") { writeSubDirs(t); return TRUE; } return FALSE; } void BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) { t << "!if !$d(BCB)" << endl; t << "BCB = $(MAKEDIR)\\.." << endl; t << "!endif" << endl << endl; 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") << " " + 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","") << " " << 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("\"", ""); 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") << endl; } else { t << "LIB = " << var("QMAKE_LIB") << endl; } - 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; 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 << "RES_FILE = " << varList("RES_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 << "####### Files" << endl << endl; t << "HEADERS = " << varList("HEADERS") << endl; t << "SOURCES = " << varList("SOURCES") << 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; + + 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 = " << varGlue("TARGET",project->first("DESTDIR"),"",project->first("TARGET_EXT")) << endl; t << endl; t << "####### Implicit rules" << endl << endl; t << ".SUFFIXES: .c"; QStringList::Iterator cppit; for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) t << " " << (*cppit); t << endl << endl; for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) 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; 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()) { t << "\n\t" << "$(LINK) @&&|" << "\n\t" << "$(LFLAGS) $(OBJECTS) $(OBJMOC),$(TARGET),,$(LIBS),$(DEF_FILE),$(RES_FILE)"; } else { - t << "\n\t-del $(TARGET)" + t << "\n\t-$(DEL_FILE) $(TARGET)" << "\n\t" << "$(LIB) $(TARGET) @&&|" << " \n+" << project->variables()["OBJECTS"].join(" \\\n+") << " \\\n+" << project->variables()["OBJMOC"].join(" \\\n+"); } + t << extraCompilerDeps; t << endl << "|" << endl; if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) t << "\t" <<var("QMAKE_POST_LINK") << endl; 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; + 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 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"); } } t << endl << endl; if(!project->variables()["RC_FILE"].isEmpty()) { t << var("RES_FILE") << ": " << var("RC_FILE") << "\n\t" << var("QMAKE_RC") << " " << var("RC_FILE") << endl << endl; } - t << "mocables: $(SRCMOC)" << endl << endl; + t << "mocables: $(SRCMOC)" << endl + << "uicables: $(UICIMPLS) $(UICDECLS)" << endl << endl; writeMakeQmake(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"), 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; } + if(!project->variables()["QMAKE_NOFORCE"].isEmpty() && + project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; 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; + t << "distclean: clean" - << "\n\t-del $(TARGET)" + << "\n\t-$(DEL_FILE) $(TARGET)" << endl << endl; } void BorlandMakefileGenerator::init() { if(init_flag) return; init_flag = TRUE; project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; - + /* 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") == "qtmt"QTDLL_POSTFIX); QStringList &configs = project->variables()["CONFIG"]; if (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("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); + } if ( project->isActiveConfig("qt") ) { if ( project->isActiveConfig("plugin") ) { project->variables()["CONFIG"].append("dll"); 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("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("qt")) { - if ( project->isActiveConfig("thread") ) + 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("debug") ) { if ( project->isActiveConfig("thread") ) { 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"]; 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->isActiveConfig("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("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") ) { 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") ) + 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"), "qtmt"); if(hver != -1) { QString ver; ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "mt" : ""), hver); QStringList &libs = project->variables()["QMAKE_LIBS"]; 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(".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("stl") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"]; } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"]; } 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("thread") ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_RTMT"]; } else { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_RT"]; } if ( project->isActiveConfig("moc") ) { setMocAware(TRUE); } 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(' ', "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::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->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",".res"); project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["CLEAN_FILES"] += 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_APP_FLAG"].isEmpty() ) { // bcc does not generate a .tds file for static libs QString tdsPostfix; if ( !project->variables()["VERSION"].isEmpty() ) { tdsPostfix = QStringList::split( '.', project->first("VERSION") ).join("") + ".tds"; } else { tdsPostfix = ".tds"; } project->variables()["QMAKE_CLEAN"].append( project->first("DESTDIR") + project->first("TARGET") + tdsPostfix ); } + + 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,58 +1,57 @@ /**************************************************************************** -** $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. ** ** 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 __BORLAND_BMAKE_H__ #define __BORLAND_BMAKE_H__ #include "winmakefile.h" class BorlandMakefileGenerator : public Win32MakefileGenerator { bool init_flag; void writeBorlandParts(QTextStream &); bool writeMakefile(QTextStream &); void init(); public: BorlandMakefileGenerator(QMakeProject *p); ~BorlandMakefileGenerator(); }; inline BorlandMakefileGenerator::~BorlandMakefileGenerator() { } #endif /* __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,998 +1,1136 @@ /**************************************************************************** -** $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. ** ** 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 "msvc_dsp.h" #include "option.h" #include <qdir.h> #include <qregexp.h> #include <stdlib.h> #include <time.h> DspMakefileGenerator::DspMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) { } bool DspMakefileGenerator::writeMakefile(QTextStream &t) { if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { /* for now just dump, I need to generated an empty dsp or something.. */ fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", var("QMAKE_FAILED_REQUIREMENTS").latin1()); return TRUE; } if(project->first("TEMPLATE") == "vcapp" || project->first("TEMPLATE") == "vclib") { return writeDspParts(t); } else if(project->first("TEMPLATE") == "subdirs") { writeHeader(t); writeSubDirs(t); return TRUE; } return FALSE; } bool DspMakefileGenerator::writeDspParts(QTextStream &t) { QString dspfile; if ( !project->variables()["DSP_TEMPLATE"].isEmpty() ) { dspfile = project->first("DSP_TEMPLATE"); } else { dspfile = project->first("MSVCDSP_TEMPLATE"); } + if (dspfile.startsWith("\"") && dspfile.endsWith("\"")) + dspfile = dspfile.mid(1, dspfile.length() - 2); QString dspfile_loc = findTemplate(dspfile); QFile file(dspfile_loc); if(!file.open(IO_ReadOnly)) { fprintf(stderr, "Cannot open dsp file: %s\n", dspfile.latin1()); return FALSE; } QTextStream dsp(&file); + 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; QString line; while ( !dsp.eof() ) { line = dsp.readLine(); while((rep = line.find(QRegExp("\\$\\$[a-zA-Z0-9_-]*"))) != -1) { QString torep = line.mid(rep, line.find(QRegExp("[^\\$a-zA-Z0-9_-]"), rep) - rep); QString variable = torep.right(torep.length()-2); t << line.left(rep); //output the left side line = line.right(line.length() - (rep + torep.length())); //now past the variable if(variable == "MSVCDSP_SOURCES") { if(project->variables()["SOURCES"].isEmpty()) continue; QString mocpath = var( "QMAKE_MOC" ); mocpath = mocpath.replace( QRegExp( "\\..*$" ), "" ) + " "; QStringList list = project->variables()["SOURCES"] + project->variables()["DEF_FILE"]; if(!project->isActiveConfig("flat")) list.sort(); QStringList::Iterator it; for( it = list.begin(); it != list.end(); ++it) { beginGroupForFile((*it), 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); base.replace(QRegExp("\\..*$"), "").upper(); base.replace(QRegExp("[^a-zA-Z]"), "_"); QString build = "\n\n# Begin Custom Build - Moc'ing " + findMocSource((*it)) + "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + (*it) + "\"" " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n" "\t" + mocpath + findMocSource((*it)) + " -o " + (*it) + "\n\n" "# End Custom Build\n\n"; t << "USERDEP_" << base << "=\".\\" << findMocSource((*it)) << "\" \"$(QTDIR)\\bin\\moc.exe\"" << endl << endl; - 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; } t << "# End Source File" << endl; } endGroups(t); } else if(variable == "MSVCDSP_IMAGES") { if(project->variables()["IMAGES"].isEmpty()) continue; t << "# Begin Source File\n\nSOURCE=" << project->first("QMAKE_IMAGE_COLLECTION") << endl; t << "# End Source File" << endl; } else if(variable == "MSVCDSP_HEADERS") { if(project->variables()["HEADERS"].isEmpty()) continue; QStringList list = project->variables()["HEADERS"]; if(!project->isActiveConfig("flat")) list.sort(); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { // beginGroupForFile((*it), 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; } t << "# End Source File" << endl; } // endGroups(t); } else if(variable == "MSVCDSP_FORMSOURCES" || variable == "MSVCDSP_FORMHEADERS") { if(project->variables()["FORMS"].isEmpty()) continue; QString uiSourcesDir; QString uiHeadersDir; if(!project->variables()["UI_DIR"].isEmpty()) { uiSourcesDir = project->first("UI_DIR"); uiHeadersDir = project->first("UI_DIR"); } else { if ( !project->variables()["UI_SOURCES_DIR"].isEmpty() ) uiSourcesDir = project->first("UI_SOURCES_DIR"); else uiSourcesDir = ""; if ( !project->variables()["UI_HEADERS_DIR"].isEmpty() ) uiHeadersDir = project->first("UI_HEADERS_DIR"); else uiHeadersDir = ""; } QStringList list = project->variables()["FORMS"]; if(!project->isActiveConfig("flat")) list.sort(); QString ext = variable == "MSVCDSP_FORMSOURCES" ? ".cpp" : ".h"; for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { QString base = (*it); int dot = base.findRev("."); base.replace( dot, base.length() - dot, ext ); QString fname = base; int lbs = fname.findRev( "\\" ); QString fpath; if ( lbs != -1 ) fpath = fname.left( lbs + 1 ); fname = fname.right( fname.length() - lbs - 1 ); if ( ext == ".cpp" && !uiSourcesDir.isEmpty() ) fname.prepend(uiSourcesDir); else if ( ext == ".h" && !uiHeadersDir.isEmpty() ) fname.prepend(uiHeadersDir); else fname = base; // beginGroupForFile(fname, t); t << "# Begin Source File\n\nSOURCE=" << fname << "\n# End Source File" << endl; } // endGroups(t); } else if(variable == "MSVCDSP_TRANSLATIONS" ) { if(project->variables()["TRANSLATIONS"].isEmpty()) continue; t << "# Begin Group \"Translations\"\n"; t << "# Prop Default_Filter \"ts\"\n"; QStringList list = project->variables()["TRANSLATIONS"]; if(!project->isActiveConfig("flat")) list.sort(); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { QString sify = *it; sify.replace('/', '\\' ); QString base = (*it); base.replace(QRegExp("\\..*$"), "").upper(); base.replace(QRegExp("[^a-zA-Z]"), "_"); // beginGroupForFile(sify, t); t << "# Begin Source File\n\nSOURCE=" << sify << endl; t << "\n# End Source File" << endl; } // endGroups(t); t << "\n# End Group\n"; } else if (variable == "MSVCDSP_MOCSOURCES" && project->isActiveConfig("moc")) { if ( project->variables()["SRCMOC"].isEmpty()) continue; QString mocpath = var( "QMAKE_MOC" ); mocpath = mocpath.replace( QRegExp( "\\..*$" ), "" ) + " "; QStringList list = project->variables()["SRCMOC"]; if(!project->isActiveConfig("flat")) list.sort(); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { // beginGroupForFile((*it), 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); base.replace(QRegExp("\\..*$"), "").upper(); base.replace(QRegExp("[^a-zA-Z]"), "_"); QString build = "\n\n# Begin Custom Build - Moc'ing " + findMocSource((*it)) + "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + (*it) + "\"" " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n" "\t" + mocpath + findMocSource((*it)) + " -o " + (*it) + "\n\n" "# End Custom Build\n\n"; t << "USERDEP_" << base << "=\".\\" << findMocSource((*it)) << "\" \"$(QTDIR)\\bin\\moc.exe\"" << endl << endl; - 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; } t << "# End Source File" << endl; } // endGroups(t); } else if(variable == "MSVCDSP_PICTURES") { if(project->variables()["IMAGES"].isEmpty()) continue; t << "# Begin Group \"Images\"\n" << "# Prop Default_Filter \"png jpeg bmp xpm\"\n"; QStringList list = project->variables()["IMAGES"]; if(!project->isActiveConfig("flat")) list.sort(); QStringList::Iterator it; // dump the image list to a file UIC can read. QFile f( "images.tmp" ); f.open( IO_WriteOnly ); QTextStream ts( &f ); for( it = list.begin(); it != list.end(); ++it ) ts << " " << *it; f.close(); // create an output step for images not more than once bool imagesBuildDone = FALSE; for( it = list.begin(); it != list.end(); ++it ) { // beginGroupForFile((*it), t); t << "# Begin Source File\n\nSOURCE=" << (*it) << endl; QString base = (*it); QString uicpath = var("QMAKE_UIC"); uicpath = uicpath.replace(QRegExp("\\..*$"), "") + " "; if ( !imagesBuildDone ) { imagesBuildDone = TRUE; QString build = "\n\n# Begin Custom Build - Creating image collection...\n" "InputPath=.\\" + base + "\n\n"; build += "\"" + project->first("QMAKE_IMAGE_COLLECTION") + "\" : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n"; build += "\t" + uicpath + "-embed " + project->first("QMAKE_ORIG_TARGET") + " -f images.tmp -o " + project->first("QMAKE_IMAGE_COLLECTION") + "\n\n"; build.append("# End Custom Build\n\n"); t << "USERDEP_" << base << "="; QStringList::Iterator it2 = list.begin(); while ( it2 != list.end() ) { t << "\"" << (*it2) << "\""; it2++; if ( it2 != list.end() ) t << "\\\n"; } t << endl << endl; t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build << "!ENDIF \n\n" << endl; } t << "# End Source File" << endl; } // endGroups(t); t << "\n# End Group\n"; } else if(variable == "MSVCDSP_FORMS") { if(project->variables()["FORMS"].isEmpty()) continue; t << "# Begin Group \"Forms\"\n" << "# Prop Default_Filter \"ui\"\n"; QString uicpath = var("QMAKE_UIC"); uicpath = uicpath.replace(QRegExp("\\..*$"), "") + " "; QString mocpath = var( "QMAKE_MOC" ); mocpath = mocpath.replace( QRegExp( "\\..*$" ), "" ) + " "; QStringList list = project->variables()["FORMS"]; if(!project->isActiveConfig("flat")) list.sort(); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { QString base = (*it); // beginGroupForFile(base, t); t << "# Begin Source File\n\nSOURCE=" << base << endl; QString fname = base; fname.replace(".ui", ""); int lbs = fname.findRev( "\\" ); QString fpath; if ( lbs != -1 ) fpath = fname.left( lbs + 1 ); fname = fname.right( fname.length() - lbs - 1 ); QString mocFile; if(!project->variables()["MOC_DIR"].isEmpty()) mocFile = project->first("MOC_DIR"); else mocFile = fpath; QString uiSourcesDir; QString uiHeadersDir; if(!project->variables()["UI_DIR"].isEmpty()) { uiSourcesDir = project->first("UI_DIR"); uiHeadersDir = project->first("UI_DIR"); } else { if ( !project->variables()["UI_SOURCES_DIR"].isEmpty() ) uiSourcesDir = project->first("UI_SOURCES_DIR"); else uiSourcesDir = fpath; if ( !project->variables()["UI_HEADERS_DIR"].isEmpty() ) uiHeadersDir = project->first("UI_HEADERS_DIR"); else uiHeadersDir = fpath; } t << "USERDEP_" << base << "=\"$(QTDIR)\\bin\\moc.exe\" \"$(QTDIR)\\bin\\uic.exe\"" << endl << endl; QString build = "\n\n# Begin Custom Build - Uic'ing " + base + "...\n" "InputPath=.\\" + base + "\n\n" "BuildCmds= \\\n\t" + uicpath + base + " -o " + uiHeadersDir + fname + ".h \\\n" "\t" + uicpath + base + " -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"; build.append("\n\"" + uiHeadersDir + fname + ".h\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" "\t$(BuildCmds)\n\n" "\"" + uiSourcesDir + fname + ".cpp\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" "\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"); build.append("# 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" << "# End Source File" << endl; } // endGroups(t); t << "\n# End Group\n"; } else if(variable == "MSVCDSP_LEXSOURCES") { if(project->variables()["LEXSOURCES"].isEmpty()) continue; t << "# Begin Group \"Lexables\"\n" << "# Prop Default_Filter \"l\"\n"; QString lexpath = var("QMAKE_LEX") + varGlue("QMAKE_LEXFLAGS", " ", " ", "") + " "; QStringList list = project->variables()["LEXSOURCES"]; if(!project->isActiveConfig("flat")) list.sort(); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { QString fname = (*it); // beginGroupForFile(fname, t); t << "# Begin Source File\n\nSOURCE=" << fname << endl; fname.replace(".l", Option::lex_mod + Option::cpp_ext.first()); QString build = "\n\n# Begin Custom Build - Lex'ing " + (*it) + "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + fname + "\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" "\t" + lexpath + (*it) + "\\\n" "\tdel " + fname + "\\\n" "\tcopy lex.yy.c " + fname + "\n\n" + "# 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 << "# End Source File" << endl; } // endGroups(t); t << "\n# End Group\n"; } else if(variable == "MSVCDSP_YACCSOURCES") { if(project->variables()["YACCSOURCES"].isEmpty()) continue; t << "# Begin Group \"Yaccables\"\n" << "# Prop Default_Filter \"y\"\n"; QString yaccpath = var("QMAKE_YACC") + varGlue("QMAKE_YACCFLAGS", " ", " ", "") + " "; QStringList list = project->variables()["YACCSOURCES"]; if(!project->isActiveConfig("flat")) list.sort(); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { QString fname = (*it); // beginGroupForFile(fname, t); t << "# Begin Source File\n\nSOURCE=" << fname << endl; fname.replace(".y", Option::yacc_mod); QString build = "\n\n# Begin Custom Build - Yacc'ing " + (*it) + "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + fname + Option::cpp_ext.first() + "\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" "\t" + yaccpath + (*it) + "\\\n" "\tdel " + fname + Option::h_ext.first() + "\\\n" "\tmove y.tab.h " + fname + Option::h_ext.first() + "\n\n" + "\tdel " + fname + Option::cpp_ext.first() + "\\\n" "\tmove y.tab.c " + fname + Option::cpp_ext.first() + "\n\n" + "# 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" << "# End Source File" << endl; } // endGroups(t); t << "\n# End Group\n"; } else if( variable == "MSVCDSP_CONFIGMODE" ) { if( project->isActiveConfig( "debug" ) ) t << "Debug"; else t << "Release"; } else if( variable == "MSVCDSP_IDLSOURCES" ) { QStringList list = project->variables()["MSVCDSP_IDLSOURCES"]; if(!project->isActiveConfig("flat")) list.sort(); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { t << "# Begin Source File" << endl << endl; t << "SOURCE=" << (*it) << endl; t << "# PROP Exclude_From_Build 1" << endl; t << "# End Source File" << endl << endl; } } else t << var(variable); } t << line << endl; } t << endl; file.close(); return TRUE; } void DspMakefileGenerator::init() { if(init_flag) return; QStringList::Iterator it; init_flag = TRUE; const bool thread = project->isActiveConfig("thread"); if ( project->isActiveConfig("stl") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"]; } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"]; } 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"]; } + /* this should probably not be here, but I'm using it to wrap the .t files */ if(project->first("TEMPLATE") == "vcapp" ) project->variables()["QMAKE_APP_FLAG"].append("1"); else if(project->first("TEMPLATE") == "vclib") project->variables()["QMAKE_LIB_FLAG"].append("1"); if ( project->variables()["QMAKESPEC"].isEmpty() ) project->variables()["QMAKESPEC"].append( getenv("QMAKESPEC") ); bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX); project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; QStringList &configs = project->variables()["CONFIG"]; if (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("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); + } if ( project->isActiveConfig("qt") ) { if ( project->isActiveConfig( "plugin" ) ) { project->variables()["CONFIG"].append("dll"); 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("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("qt") || project->isActiveConfig("opengl") ) { project->variables()["CONFIG"].append("windows"); } 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()["MSVCDSP_VERSION"].append( "/VERSION:" + major + "." + minor ); } + 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") ) { project->variables()["CONFIG"].append("moc"); project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"]; 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"].append("/base:\"0x39D00000\""); } } else { if( 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("qt%s" QTDLL_POSTFIX "%d.lib", (thread ? "-mt" : ""), hver); QStringList &libs = project->variables()["QMAKE_LIBS"]; 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("debug") ) { if ( !project->first("OBJECTS_DIR").isEmpty() ) project->variables()["MSVCDSP_OBJECTSDIRDEB"] = project->first("OBJECTS_DIR"); else project->variables()["MSVCDSP_OBJECTSDIRDEB"] = "Debug"; project->variables()["MSVCDSP_OBJECTSDIRREL"] = "Release"; if ( !project->first("DESTDIR").isEmpty() ) project->variables()["MSVCDSP_TARGETDIRDEB"] = project->first("DESTDIR"); else project->variables()["MSVCDSP_TARGETDIRDEB"] = "Debug"; project->variables()["MSVCDSP_TARGETDIRREL"] = "Release"; } else { if ( !project->first("OBJECTS_DIR").isEmpty() ) project->variables()["MSVCDSP_OBJECTSDIRREL"] = project->first("OBJECTS_DIR"); + else + project->variables()["MSVCDSP_OBJECTSDIRREL"] = "Release"; project->variables()["MSVCDSP_OBJECTSDIRDEB"] = "Debug"; if ( !project->first("DESTDIR").isEmpty() ) project->variables()["MSVCDSP_TARGETDIRREL"] = project->first("DESTDIR"); else project->variables()["MSVCDSP_TARGETDIRREL"] = "Release"; project->variables()["MSVCDSP_TARGETDIRDEB"] = "Debug"; } if ( project->isActiveConfig("opengl") ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"]; } if ( thread ) { if(project->isActiveConfig("qt")) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT" ); if ( project->isActiveConfig("dll") || project->first("TARGET") == "qtmain" || !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { project->variables()["MSVCDSP_MTDEFD"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"]; project->variables()["MSVCDSP_MTDEF"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"]; } else { // YES we want to use the DLL even in a static build project->variables()["MSVCDSP_MTDEFD"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"]; project->variables()["MSVCDSP_MTDEF"] += project->variables()["QMAKE_CXXFLAGS_MT"]; } if ( !project->variables()["DEFINES"].contains("QT_DLL") && is_qt && project->first("TARGET") != "qtmain" ) project->variables()["QMAKE_LFLAGS"].append("/NODEFAULTLIB:\"libc\""); } if(project->isActiveConfig("qt")) { 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_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() ) { QString ver_xyz(project->first("VERSION")); ver_xyz.replace(".", ""); project->variables()["TARGET_EXT"].append(ver_xyz + ".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(".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"]; + } + project->variables()["MSVCDSP_VER"] = "6.00"; project->variables()["MSVCDSP_DEBUG_OPT"] = "/GZ /ZI"; if(!project->isActiveConfig("incremental")) { project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no")); if ( is_qt ) project->variables()["MSVCDSP_DEBUG_OPT"] = "/GZ /Zi"; } QString msvcdsp_project; if ( project->variables()["TARGET"].count() ) msvcdsp_project = project->variables()["TARGET"].first(); QString targetfilename = project->variables()["TARGET"].first(); project->variables()["TARGET"].first() += project->first("TARGET_EXT"); if ( project->isActiveConfig("moc") ) setMocAware(TRUE); project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; 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(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); } MakefileGenerator::init(); if ( msvcdsp_project.isEmpty() ) msvcdsp_project = Option::output.name(); msvcdsp_project = msvcdsp_project.right( msvcdsp_project.length() - msvcdsp_project.findRev( "\\" ) - 1 ); msvcdsp_project = msvcdsp_project.left( msvcdsp_project.findRev( "." ) ); msvcdsp_project.replace("-", ""); project->variables()["MSVCDSP_PROJECT"].append(msvcdsp_project); QStringList &proj = project->variables()["MSVCDSP_PROJECT"]; for(it = proj.begin(); it != proj.end(); ++it) (*it).replace(QRegExp("\\.[a-zA-Z0-9_]*$"), ""); if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { project->variables()["MSVCDSP_TEMPLATE"].append("win32app" + project->first( "DSP_EXTENSION" ) ); if ( project->isActiveConfig("console") ) { project->variables()["MSVCDSP_CONSOLE"].append("Console"); project->variables()["MSVCDSP_WINCONDEF"].append("_CONSOLE"); project->variables()["MSVCDSP_DSPTYPE"].append("0x0103"); - project->variables()["MSVCDSP_SUBSYSTEM"].append("console"); } else { project->variables()["MSVCDSP_CONSOLE"].clear(); project->variables()["MSVCDSP_WINCONDEF"].append("_WINDOWS"); project->variables()["MSVCDSP_DSPTYPE"].append("0x0101"); - project->variables()["MSVCDSP_SUBSYSTEM"].append("windows"); } } else { if ( project->isActiveConfig("dll") ) { project->variables()["MSVCDSP_TEMPLATE"].append("win32dll" + project->first( "DSP_EXTENSION" ) ); } else { project->variables()["MSVCDSP_TEMPLATE"].append("win32lib" + project->first( "DSP_EXTENSION" ) ); } } 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"]; if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) project->variables()["MSVCDSP_LFLAGS" ].append(varGlue("QMAKE_LIBDIR","/LIBPATH:\"","\" /LIBPATH:\"","\"")); project->variables()["MSVCDSP_CXXFLAGS" ] += project->variables()["QMAKE_CXXFLAGS"]; project->variables()["MSVCDSP_DEFINES"].append(varGlue("DEFINES","/D ","" " /D ","")); project->variables()["MSVCDSP_DEFINES"].append(varGlue("PRL_EXPORT_DEFINES","/D ","" " /D ","")); - processPrlFiles(); + if (!project->variables()["RES_FILE"].isEmpty()) + project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"]; + QStringList &libs = project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) { QString lib = (*libit); lib.replace(QRegExp("\""), ""); project->variables()["MSVCDSP_LIBS"].append(" \"" + lib + "\""); } QStringList &incs = project->variables()["INCLUDEPATH"]; for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) { QString inc = (*incit); inc.replace("\"", ""); + if(inc.endsWith("\\")) // Remove trailing \'s from paths + inc.truncate(inc.length()-1); project->variables()["MSVCDSP_INCPATH"].append("/I \"" + inc + "\""); } project->variables()["MSVCDSP_INCPATH"].append("/I \"" + specdir() + "\""); if ( project->isActiveConfig("qt") ) { project->variables()["MSVCDSP_RELDEFS"].append("/D \"QT_NO_DEBUG\""); } else { project->variables()["MSVCDSP_RELDEFS"].clear(); } QString dest; QString postLinkStep; QString copyDllStep; QString activeQtStepPreCopyDll; QString activeQtStepPostCopyDll; QString activeQtStepPreCopyDllDebug; QString activeQtStepPostCopyDllDebug; QString activeQtStepPreCopyDllRelease; QString activeQtStepPostCopyDllRelease; if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) postLinkStep += var("QMAKE_POST_LINK"); if ( !project->variables()["DESTDIR"].isEmpty() ) { project->variables()["TARGET"].first().prepend(project->first("DESTDIR")); Option::fixPathToTargetOS(project->first("TARGET")); dest = project->first("TARGET"); if ( project->first("TARGET").startsWith("$(QTDIR)") ) dest.replace( "$(QTDIR)", getenv("QTDIR") ); project->variables()["MSVCDSP_TARGET"].append( QString("/out:\"") + dest + "\""); if ( project->isActiveConfig("dll") ) { QString imp = dest; imp.replace(".dll", ".lib"); project->variables()["MSVCDSP_TARGET"].append(QString(" /implib:\"") + imp + "\""); } } if ( project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty() ) { QStringList dlldirs = project->variables()["DLLDESTDIR"]; if ( dlldirs.count() ) copyDllStep += "\t"; for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { copyDllStep += "copy \"$(TargetPath)\" \"" + *dlldir + "\"\t"; } } if ( project->isActiveConfig("activeqt") ) { QString idl = project->variables()["QMAKE_IDL"].first(); QString idc = project->variables()["QMAKE_IDC"].first(); QString version = project->variables()["VERSION"].first(); if ( version.isEmpty() ) 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 += "\t" + idc + " %1 /regserver\n"; QString executable = project->variables()["MSVCDSP_TARGETDIRREL"].first() + "\\" + targetfilename + ".dll"; activeQtStepPreCopyDllRelease = activeQtStepPreCopyDll.arg(executable).arg(executable); activeQtStepPostCopyDllRelease = activeQtStepPostCopyDll.arg(executable); executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + targetfilename + ".dll"; activeQtStepPreCopyDllDebug = activeQtStepPreCopyDll.arg(executable).arg(executable); activeQtStepPostCopyDllDebug = activeQtStepPostCopyDll.arg(executable); } else { 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 += "\t%1 -regserver\n"; QString executable = project->variables()["MSVCDSP_TARGETDIRREL"].first() + "\\" + targetfilename + ".exe"; activeQtStepPreCopyDllRelease = activeQtStepPreCopyDll.arg(executable).arg(executable); activeQtStepPostCopyDllRelease = activeQtStepPostCopyDll.arg(executable); executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + targetfilename + ".exe"; activeQtStepPreCopyDllDebug = activeQtStepPreCopyDll.arg(executable).arg(executable); activeQtStepPostCopyDllDebug = activeQtStepPostCopyDll.arg(executable); } } if ( !postLinkStep.isEmpty() || !copyDllStep.isEmpty() || !activeQtStepPreCopyDllDebug.isEmpty() || !activeQtStepPreCopyDllRelease.isEmpty() ) { project->variables()["MSVCDSP_POST_LINK_DBG"].append( "# Begin Special Build Tool\n" "SOURCE=$(InputPath)\n" "PostBuild_Desc=Post Build Step\n" "PostBuild_Cmds=" + postLinkStep + activeQtStepPreCopyDllDebug + copyDllStep + activeQtStepPostCopyDllDebug + "\n" "# End Special Build Tool\n" ); project->variables()["MSVCDSP_POST_LINK_REL"].append( "# Begin Special Build Tool\n" "SOURCE=$(InputPath)\n" "PostBuild_Desc=Post Build Step\n" "PostBuild_Cmds=" + postLinkStep + activeQtStepPreCopyDllRelease + copyDllStep + activeQtStepPostCopyDllRelease + "\n" "# End Special Build Tool\n" ); } if ( !project->variables()["SOURCES"].isEmpty() || !project->variables()["RC_FILE"].isEmpty() ) { project->variables()["SOURCES"] += project->variables()["RC_FILE"]; } QStringList &list = project->variables()["FORMS"]; for( it = list.begin(); it != list.end(); ++it ) { if ( QFile::exists( *it + ".h" ) ) project->variables()["SOURCES"].append( *it + ".h" ); } - project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCDSP_LIBS"; + project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCDSP_LIBS"; } QString DspMakefileGenerator::findTemplate(const QString &file) { QString ret; if(!QFile::exists((ret = file)) && !QFile::exists((ret = QString(Option::mkfile::qmakespec + "/" + file))) && !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/win32-msvc/" + file)) && !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file)))) return ""; return ret; } void DspMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l) { if(var == "QMAKE_PRL_DEFINES") { QStringList &out = project->variables()["MSVCDSP_DEFINES"]; for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { if(out.findIndex((*it)) == -1) out.append((" /D \"" + *it + "\"")); } } else { MakefileGenerator::processPrlVariable(var, l); } } void DspMakefileGenerator::beginGroupForFile(QString file, QTextStream &t, const QString& filter) { if(project->isActiveConfig("flat")) return; - fileFixify(file, QDir::currentDirPath(), QDir::currentDirPath(), TRUE); file = file.section(Option::dir_sep, 0, -2); if(file.right(Option::dir_sep.length()) != Option::dir_sep) file += Option::dir_sep; if(file == currentGroup) return; if(file.isEmpty() || !QDir::isRelativePath(file)) { endGroups(t); return; } - 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"; } if ( !file.startsWith( currentGroup ) ) { t << "\n# End Group\n"; currentGroup = ""; } + QStringList dirs = QStringList::split(Option::dir_sep, file.right( file.length() - currentGroup.length() ) ); for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { t << "# Begin Group \"" << (*dir_it) << "\"\n" << "# Prop Default_Filter \"" << filter << "\"\n"; } currentGroup = file; } void DspMakefileGenerator::endGroups(QTextStream &t) { if(project->isActiveConfig("flat")) return; else if(currentGroup.isEmpty()) return; QStringList dirs = QStringList::split(Option::dir_sep, currentGroup); for(QStringList::Iterator dir_it = dirs.end(); dir_it != dirs.begin(); --dir_it) { t << "\n# End Group\n"; } currentGroup = ""; } bool DspMakefileGenerator::openOutput(QFile &file) const { QString outdir; if(!file.name().isEmpty()) { + if(QDir::isRelativePath(file.name())) + file.setName(Option::output_dir + file.name()); //pwd when qmake was run QFileInfo fi(file); if(fi.isDir()) outdir = file.name() + QDir::separator(); } if(!outdir.isEmpty() || file.name().isEmpty()) file.setName(outdir + project->first("TARGET") + project->first("DSP_EXTENSION")); if(QDir::isRelativePath(file.name())) { QString ofile; ofile = file.name(); int slashfind = ofile.findRev('\\'); if (slashfind == -1) { ofile = ofile.replace(QRegExp("-"), "_"); } else { int hypenfind = ofile.find('-', slashfind); while (hypenfind != -1 && slashfind < hypenfind) { ofile = ofile.replace(hypenfind, 1, "_"); hypenfind = ofile.find('-', hypenfind + 1); } } file.setName(Option::fixPathToLocalOS(QDir::currentDirPath() + Option::dir_sep + ofile)); } return Win32MakefileGenerator::openOutput(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,73 +1,76 @@ /**************************************************************************** -** $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. ** ** 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 __MSVC_DSP_H__ #define __MSVC_DSP_H__ #include "winmakefile.h" #include <qvaluestack.h> class DspMakefileGenerator : public Win32MakefileGenerator { QString currentGroup; void beginGroupForFile(QString file, QTextStream &, const QString& filter=""); void endGroups(QTextStream &); bool init_flag; bool writeDspParts(QTextStream &); bool writeMakefile(QTextStream &); QString findTemplate(const QString &file); void init(); public: DspMakefileGenerator(QMakeProject *p); ~DspMakefileGenerator(); bool openOutput(QFile &file) const; protected: virtual void processPrlVariable(const QString &, const QStringList &); virtual bool findLibraries(); + + QString precompH, + precompObj, precompPch; + bool usePCH; }; inline DspMakefileGenerator::~DspMakefileGenerator() { } inline bool DspMakefileGenerator::findLibraries() { return Win32MakefileGenerator::findLibraries("MSVCDSP_LIBS"); } #endif /* __MSVC_DSP_H__ */ 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,562 +1,787 @@ /**************************************************************************** -** $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. ** ** 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 "msvc_nmake.h" #include "option.h" #include <qregexp.h> #include <qdict.h> #include <qdir.h> #include <stdlib.h> #include <time.h> - NmakeMakefileGenerator::NmakeMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) { } bool NmakeMakefileGenerator::writeMakefile(QTextStream &t) { writeHeader(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" << "@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") { writeNmakeParts(t); return MakefileGenerator::writeMakefile(t); } else if(project->first("TEMPLATE") == "subdirs") { writeSubDirs(t); return TRUE; } return FALSE; } +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 NmakeMakefileGenerator::writeNmakeParts(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("\"", ""); + if (inc.endsWith("\\")) + inc.truncate(inc.length()-1); 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"); if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) t << " " << varGlue("QMAKE_LIBDIR","/LIBPATH:\"","\" /LIBPATH:\"","\""); t << endl; t << "LIBS = "; QStringList &libs = project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) { QString lib = (*libit); - lib.replace(QRegExp("\\\\$"), "\\\\"); - lib.replace(QRegExp("\""), ""); + if (lib.endsWith("\\")) + lib.truncate(lib.length()-1); t << " \"" << lib << "\""; } t << 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 << "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 << "####### Files" << endl << endl; t << "HEADERS = " << varList("HEADERS") << endl; t << "SOURCES = " << varList("SOURCES") << 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; + + 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: .c"; QStringList::Iterator cppit; for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) t << " " << (*cppit); t << endl << endl; + if(!project->isActiveConfig("no_batch")) { // Batchmode doesn't use the non implicit rules QMAKE_RUN_CXX & QMAKE_RUN_CC project->variables().remove("QMAKE_RUN_CXX"); project->variables().remove("QMAKE_RUN_CC"); QDict<void> source_directories; 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 }; for(int x = 0; !srcs[x].isNull(); x++) { QStringList &l = project->variables()[srcs[x]]; for(QStringList::Iterator sit = l.begin(); sit != l.end(); ++sit) { QString sep = "\\"; if((*sit).find(sep) == -1) sep = "/"; QString dir = (*sit).section(sep, 0, -2); if(!dir.isEmpty() && !source_directories[dir]) source_directories.insert(dir, (void*)1); } } for(QDictIterator<void> it(source_directories); it.current(); ++it) { if(it.currentKey().isEmpty()) continue; for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) t << "{" << it.currentKey() << "}" << (*cppit) << "{" << var("OBJECTS_DIR") << "}" << Option::obj_ext << "::\n\t" << var("QMAKE_RUN_CXX_IMP_BATCH").replace( QRegExp( "\\$@" ), var("OBJECTS_DIR") ) << endl << "\t$<" << endl << "<<" << endl << endl; t << "{" << it.currentKey() << "}" << ".c{" << var("OBJECTS_DIR") << "}" << Option::obj_ext << "::\n\t" << var("QMAKE_RUN_CC_IMP_BATCH").replace( QRegExp( "\\$@" ), var("OBJECTS_DIR") ) << endl << "\t$<" << endl << "<<" << endl << endl; } } else { for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) 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; } 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()) { t << "\n\t" << "$(LINK) $(LFLAGS) /OUT:$(TARGET) @<< " << "\n\t " << "$(OBJECTS) $(OBJMOC) $(LIBS)"; } else { t << "\n\t" << "$(LIB) /OUT:$(TARGET) @<<" << "\n\t " << "$(OBJECTS) $(OBJMOC)"; } + t << extraCompilerDeps; t << endl << "<<" << endl; if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) t << "\t" << var( "QMAKE_POST_LINK" ) << endl; 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; + 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 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"; } } t << endl << endl; if(!project->variables()["RC_FILE"].isEmpty()) { t << var("RES_FILE") << ": " << var("RC_FILE") << "\n\t" << var("QMAKE_RC") << " " << var("RC_FILE") << endl << endl; } - t << "mocables: $(SRCMOC)" << endl << endl; + t << "mocables: $(SRCMOC)" << endl + << "uicables: $(UICIMPLS) $(UICDECLS)" << endl << endl; writeMakeQmake(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"), 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; } + if(!project->variables()["QMAKE_NOFORCE"].isEmpty() && + project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; 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; + + 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); +} void NmakeMakefileGenerator::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"]; 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("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); + } 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->isActiveConfig("thread") && !project->variables()["DEFINES"].contains("QT_DLL") && !is_qt && project->first("TARGET") != "qtmain") { project->variables()["QMAKE_LFLAGS"].append("/NODEFAULTLIB:\"libc\""); } 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("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") ) { 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("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "-mt" : ""), hver); QStringList &libs = project->variables()["QMAKE_LIBS"]; 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(".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("stl") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"]; } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"]; } 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); 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(' ', "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::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->variables()["DEF_FILE"].isEmpty() ) project->variables()["QMAKE_LFLAGS"].append(QString("/DEF:") + project->first("DEF_FILE")); if(!project->isActiveConfig("incremental")) project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no")); 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 ); } 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",".res"); 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"]; + // 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()) { QStringList l = QStringList::split('.', project->first("VERSION")); project->variables()["VER_MAJ"].append(l[0]); project->variables()["VER_MIN"].append(l[1]); } QString version = QStringList::split('.', project->first("VERSION")).join(""); if(project->isActiveConfig("dll")) { project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + version + ".exp"); } if(project->isActiveConfig("debug")) { project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + version + ".pdb"); project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + version + ".ilk"); 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,59 +1,64 @@ /**************************************************************************** -** $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. ** ** 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 __MSVC_NMAKE_H__ #define __MSVC_NMAKE_H__ #include "winmakefile.h" class NmakeMakefileGenerator : public Win32MakefileGenerator { bool init_flag; void writeNmakeParts(QTextStream &); bool writeMakefile(QTextStream &); void init(); +protected: + QStringList &findDependencies(const QString &file); + QString var(const QString &value); + QString precompH, precompObj, precompPch; + bool usePCH; + public: NmakeMakefileGenerator(QMakeProject *p); ~NmakeMakefileGenerator(); }; inline NmakeMakefileGenerator::~NmakeMakefileGenerator() { } #endif /* __MSVC_NMAKE_H__ */ 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,118 +1,104 @@ /**************************************************************************** -** $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. ** ** 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 "msvc_objectmodel.h" #include "msvc_vcproj.h" #include <qtextstream.h> #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> // XML Tags --------------------------------------------------------- const char* _xmlInit = "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>"; const char* _begConfiguration = "\n\t\t<Configuration"; const char* _begConfigurations = "\n\t<Configurations>"; const char* _begFile = "\n\t\t\t<File"; const char* _begFileConfiguration = "\n\t\t\t\t<FileConfiguration"; const char* _begFiles = "\n\t<Files>"; const char* _begFilter = "\n\t\t<Filter"; const char* _begGlobals = "\n\t<Globals>"; const char* _begPlatform = "\n\t\t<Platform"; const char* _begPlatforms = "\n\t<Platforms>"; const char* _begTool3 = "\n\t\t\t<Tool"; const char* _begTool5 = "\n\t\t\t\t\t<Tool"; const char* _begVisualStudioProject = "\n<VisualStudioProject"; const char* _endConfiguration = "\n\t\t</Configuration>"; const char* _endConfigurations = "\n\t</Configurations>"; const char* _endFile = "\n\t\t\t</File>"; const char* _endFileConfiguration = "\n\t\t\t\t</FileConfiguration>"; const char* _endFiles = "\n\t</Files>"; const char* _endFilter = "\n\t\t</Filter>"; const char* _endGlobals = "\n\t</Globals>"; const char* _endPlatforms = "\n\t</Platforms>"; const char* _endVisualStudioProject = "\n</VisualStudioProject>"; // XML Properties --------------------------------------------------- const char* _AddModuleNamesToAssembly = "\n\t\t\t\tAddModuleNamesToAssembly=\""; const char* _AdditionalDependencies4 = "\n\t\t\t\tAdditionalDependencies=\""; const char* _AdditionalDependencies6 = "\n\t\t\t\t\t\tAdditionalDependencies=\""; const char* _AdditionalIncludeDirectories = "\n\t\t\t\tAdditionalIncludeDirectories=\""; const char* _AdditionalLibraryDirectories = "\n\t\t\t\tAdditionalLibraryDirectories=\""; const char* _AdditionalOptions = "\n\t\t\t\tAdditionalOptions=\""; const char* _AdditionalUsingDirectories = "\n\t\t\t\tAdditionalUsingDirectories=\""; const char* _AssemblerListingLocation = "\n\t\t\t\tAssemblerListingLocation=\""; const char* _AssemblerOutput = "\n\t\t\t\tAssemblerOutput=\""; const char* _ATLMinimizesCRunTimeLibraryUsage = "\n\t\t\tATLMinimizesCRunTimeLibraryUsage=\""; const char* _BaseAddress = "\n\t\t\t\tBaseAddress=\""; const char* _BasicRuntimeChecks = "\n\t\t\t\tBasicRuntimeChecks=\""; const char* _BrowseInformation = "\n\t\t\t\tBrowseInformation=\""; const char* _BrowseInformationFile = "\n\t\t\t\tBrowseInformationFile=\""; const char* _BufferSecurityCheck = "\n\t\t\t\tBufferSecurityCheck=\""; const char* _BuildBrowserInformation = "\n\t\t\tBuildBrowserInformation=\""; const char* _CPreprocessOptions = "\n\t\t\t\tCPreprocessOptions=\""; const char* _CallingConvention = "\n\t\t\t\tCallingConvention=\""; const char* _CharacterSet = "\n\t\t\tCharacterSet=\""; const char* _CommandLine4 = "\n\t\t\t\tCommandLine=\""; const char* _CommandLine6 = "\n\t\t\t\t\t\tCommandLine=\""; const char* _CompileAs = "\n\t\t\t\tCompileAs=\""; const char* _CompileAsManaged = "\n\t\t\t\tCompileAsManaged=\""; const char* _CompileOnly = "\n\t\t\t\tCompileOnly=\""; const char* _ConfigurationType = "\n\t\t\tConfigurationType=\""; const char* _Culture = "\n\t\t\t\tCulture=\""; const char* _DLLDataFileName = "\n\t\t\t\tDLLDataFileName=\""; const char* _DebugInformationFormat = "\n\t\t\t\tDebugInformationFormat=\""; const char* _DefaultCharIsUnsigned = "\n\t\t\t\tDefaultCharIsUnsigned=\""; const char* _DefaultCharType = "\n\t\t\t\tDefaultCharType=\""; const char* _DelayLoadDLLs = "\n\t\t\t\tDelayLoadDLLs=\""; const char* _DeleteExtensionsOnClean = "\n\t\t\tDeleteExtensionsOnClean=\""; const char* _Description4 = "\n\t\t\t\tDescription=\""; const char* _Description6 = "\n\t\t\t\t\t\tDescription=\""; const char* _Detect64BitPortabilityProblems = "\n\t\t\t\tDetect64BitPortabilityProblems=\""; const char* _DisableLanguageExtensions = "\n\t\t\t\tDisableLanguageExtensions=\""; const char* _DisableSpecificWarnings = "\n\t\t\t\tDisableSpecificWarnings=\""; const char* _EnableCOMDATFolding = "\n\t\t\t\tEnableCOMDATFolding=\""; @@ -220,438 +206,448 @@ const char* _StripPrivateSymbols = "\n\t\t\t\tStripPrivateSymbols=\""; const char* _StructMemberAlignment = "\n\t\t\t\tStructMemberAlignment=\""; const char* _SubSystem = "\n\t\t\t\tSubSystem=\""; const char* _SupportUnloadOfDelayLoadedDLL = "\n\t\t\t\tSupportUnloadOfDelayLoadedDLL=\""; const char* _SuppressStartupBanner = "\n\t\t\t\tSuppressStartupBanner=\""; const char* _SwapRunFromCD = "\n\t\t\t\tSwapRunFromCD=\""; const char* _SwapRunFromNet = "\n\t\t\t\tSwapRunFromNet=\""; const char* _TargetEnvironment = "\n\t\t\t\tTargetEnvironment=\""; const char* _TargetMachine = "\n\t\t\t\tTargetMachine=\""; const char* _TerminalServerAware = "\n\t\t\t\tTerminalServerAware=\""; const char* _ToolName = "\n\t\t\t\tName=\""; const char* _ToolPath = "\n\t\t\t\tPath=\""; const char* _TreatWChar_tAsBuiltInType = "\n\t\t\t\tTreatWChar_tAsBuiltInType=\""; const char* _TurnOffAssemblyGeneration = "\n\t\t\t\tTurnOffAssemblyGeneration=\""; const char* _TypeLibraryFile = "\n\t\t\t\tTypeLibraryFile=\""; const char* _TypeLibraryName = "\n\t\t\t\tTypeLibraryName=\""; const char* _TypeLibraryResourceID = "\n\t\t\t\tTypeLibraryResourceID=\""; const char* _UndefineAllPreprocessorDefinitions = "\n\t\t\t\tUndefineAllPreprocessorDefinitions=\""; const char* _UndefinePreprocessorDefinitions = "\n\t\t\t\tUndefinePreprocessorDefinitions=\""; const char* _UseOfATL = "\n\t\t\tUseOfATL=\""; const char* _UseOfMfc = "\n\t\t\tUseOfMfc=\""; const char* _UsePrecompiledHeader = "\n\t\t\t\tUsePrecompiledHeader=\""; const char* _ValidateParameters = "\n\t\t\t\tValidateParameters=\""; const char* _VCCLCompilerToolName = "\n\t\t\t\tName=\"VCCLCompilerTool\""; const char* _VCCustomBuildTool = "\n\t\t\t\t\t\tName=\"VCCustomBuildTool\""; const char* _VCLinkerToolName = "\n\t\t\t\tName=\"VCLinkerTool\""; const char* _VCResourceCompilerToolName = "\n\t\t\t\tName=\"VCResourceCompilerTool\""; const char* _VCMIDLToolName = "\n\t\t\t\tName=\"VCMIDLTool\""; const char* _Version1 = "\n\tVersion=\""; const char* _Version4 = "\n\t\t\t\tVersion=\""; const char* _WarnAsError = "\n\t\t\t\tWarnAsError=\""; const char* _WarnLevel = "\n\t\t\t\tWarnLevel=\""; const char* _WarningLevel = "\n\t\t\t\tWarningLevel=\""; const char* _WholeProgramOptimization = "\n\t\t\t\tWholeProgramOptimization=\""; // Property name and value as Pairs --------------------------------- struct TPair { TPair( const char* n, const triState v ) : name(n), value(v) {}; const char* name; const triState value; }; struct EPair { EPair( const char* n, const int v ) : name(n), value(v) {}; const char* name; const int value; }; struct LPair { LPair( const char* n, const long v ) : name(n), value(v) {}; const char* name; const long value; }; struct SPair { SPair( const char* n, const QString& v ) : name(n), value(v) {}; const char* name; const QString& value; }; struct XPair { XPair( const char* n, const QStringList& v, const char* s = "," ) : name(n), value(v), sep(s) {}; const char* name; const QStringList& value; const char* sep; }; // void streamSPair( QTextStream &strm, const char *n, const QString &s ) - // Streaming operators for property Pairs --------------------------- QTextStream &operator<<( QTextStream &strm, const TPair &prop ) { switch( prop.value ) { case _False: strm << prop.name << "FALSE\""; break; case _True: strm << prop.name << "TRUE\""; break; case unset: default: break; } return strm; } /* Be sure to check that each enum is not set to default before streaming it out. Defaults seem to not be in the XML file. */ QTextStream &operator<<( QTextStream &strm, const EPair &prop ) { strm << prop.name << prop.value << "\""; return strm; } QTextStream &operator<<( QTextStream &strm, const LPair &prop ) { strm << prop.name << prop.value << "\""; return strm; } 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; } QTextStream &operator<<( QTextStream &strm, const XPair &prop ) { if ( !prop.value.isEmpty() ) strm << prop.name << prop.value.join(prop.sep).latin1() << "\""; return strm; } // VCCLCompilerTool ------------------------------------------------- VCCLCompilerTool::VCCLCompilerTool() : AssemblerOutput( asmListingNone ), BasicRuntimeChecks( runtimeBasicCheckNone ), BrowseInformation( brInfoNone ), - BufferSecurityCheck( unset ), + BufferSecurityCheck( _False ), CallingConvention( callConventionDefault ), CompileAs( compileAsDefault ), CompileAsManaged( managedDefault ), CompileOnly( unset ), DebugInformationFormat( debugDisabled ), DefaultCharIsUnsigned( unset ), Detect64BitPortabilityProblems( unset ), DisableLanguageExtensions( unset ), EnableFiberSafeOptimizations( unset ), EnableFunctionLevelLinking( unset ), EnableIntrinsicFunctions( unset ), - ExceptionHandling( unset ), + ExceptionHandling( _False ), ExpandAttributedSource( unset ), FavorSizeOrSpeed( favorNone ), ForceConformanceInForLoopScope( unset ), GeneratePreprocessedFile( preprocessNo ), GlobalOptimizations( unset ), IgnoreStandardIncludePath( unset ), ImproveFloatingPointConsistency( unset ), - InlineFunctionExpansion( expandOnlyInline ), + InlineFunctionExpansion( expandDefault ), KeepComments( unset ), MinimalRebuild( unset ), OmitFramePointers( unset ), - Optimization( optimizeDisabled ), + Optimization( optimizeCustom ), OptimizeForProcessor( procOptimizeBlended ), OptimizeForWindowsApplication( unset ), + ProgramDataBaseFileName( "" ), RuntimeLibrary( rtMultiThreaded ), RuntimeTypeInfo( unset ), ShowIncludes( unset ), SmallerTypeCheck( unset ), StringPooling( unset ), StructMemberAlignment( alignNotSet ), SuppressStartupBanner( unset ), TreatWChar_tAsBuiltInType( unset ), TurnOffAssemblyGeneration( unset ), UndefineAllPreprocessorDefinitions( unset ), - UsePrecompiledHeader( pchGenerateAuto ), + UsePrecompiledHeader( pchNone ), WarnAsError( unset ), WarningLevel( warningLevel_0 ), WholeProgramOptimization( unset ) { } QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) { strm << _begTool3; strm << _VCCLCompilerToolName; strm << XPair( _AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories ); strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); strm << XPair( _AdditionalUsingDirectories, tool.AdditionalUsingDirectories ); strm << SPair( _AssemblerListingLocation, tool.AssemblerListingLocation ); if ( tool.AssemblerOutput != asmListingNone ) strm << EPair( _AssemblerOutput, tool.AssemblerOutput ); if ( tool.BasicRuntimeChecks != runtimeBasicCheckNone ) strm << EPair( _BasicRuntimeChecks, tool.BasicRuntimeChecks ); if ( tool.BrowseInformation != brInfoNone ) strm << EPair( _BrowseInformation, tool.BrowseInformation ); strm << SPair( _BrowseInformationFile, tool.BrowseInformationFile ); strm << TPair( _BufferSecurityCheck, tool.BufferSecurityCheck ); if ( tool.CallingConvention != callConventionDefault ) strm << EPair( _CallingConvention, tool.CallingConvention ); if ( tool.CompileAs != compileAsDefault ) strm << EPair( _CompileAs, tool.CompileAs ); if ( tool.CompileAsManaged != managedDefault ) strm << EPair( _CompileAsManaged, tool.CompileAsManaged ); strm << TPair( _CompileOnly, tool.CompileOnly ); - strm << EPair( _DebugInformationFormat, tool.DebugInformationFormat ); + if ( tool.DebugInformationFormat != debugUnknown ) strm << EPair( _DebugInformationFormat, tool.DebugInformationFormat ); strm << TPair( _DefaultCharIsUnsigned, tool.DefaultCharIsUnsigned ); strm << TPair( _Detect64BitPortabilityProblems, tool.Detect64BitPortabilityProblems ); strm << TPair( _DisableLanguageExtensions, tool.DisableLanguageExtensions ); strm << XPair( _DisableSpecificWarnings, tool.DisableSpecificWarnings ); strm << TPair( _EnableFiberSafeOptimizations, tool.EnableFiberSafeOptimizations ); strm << TPair( _EnableFunctionLevelLinking, tool.EnableFunctionLevelLinking ); strm << TPair( _EnableIntrinsicFunctions, tool.EnableIntrinsicFunctions ); strm << TPair( _ExceptionHandling, tool.ExceptionHandling ); strm << TPair( _ExpandAttributedSource, tool.ExpandAttributedSource ); if ( tool.FavorSizeOrSpeed != favorNone ) strm << EPair( _FavorSizeOrSpeed, tool.FavorSizeOrSpeed ); strm << TPair( _ForceConformanceInForLoopScope, tool.ForceConformanceInForLoopScope ); strm << XPair( _ForcedIncludeFiles, tool.ForcedIncludeFiles ); strm << XPair( _ForcedUsingFiles, tool.ForcedUsingFiles ); - strm << EPair( _GeneratePreprocessedFile, tool.GeneratePreprocessedFile ); + if ( tool.GeneratePreprocessedFile != preprocessUnknown)strm << EPair( _GeneratePreprocessedFile, tool.GeneratePreprocessedFile ); strm << TPair( _GlobalOptimizations, tool.GlobalOptimizations ); strm << TPair( _IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath ); strm << TPair( _ImproveFloatingPointConsistency, tool.ImproveFloatingPointConsistency ); - strm << EPair( _InlineFunctionExpansion, tool.InlineFunctionExpansion ); + if ( tool.InlineFunctionExpansion != expandDefault ) strm << EPair( _InlineFunctionExpansion, tool.InlineFunctionExpansion ); strm << TPair( _KeepComments, tool.KeepComments ); strm << TPair( _MinimalRebuild, tool.MinimalRebuild ); strm << SPair( _ObjectFile, tool.ObjectFile ); 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 ); strm << TPair( _OptimizeForWindowsApplication, tool.OptimizeForWindowsApplication ); strm << SPair( _OutputFile, tool.OutputFile ); strm << SPair( _PrecompiledHeaderFile, tool.PrecompiledHeaderFile ); strm << SPair( _PrecompiledHeaderThrough, tool.PrecompiledHeaderThrough ); 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 ); strm << TPair( _ShowIncludes, tool.ShowIncludes ); strm << TPair( _SmallerTypeCheck, tool.SmallerTypeCheck ); strm << TPair( _StringPooling, tool.StringPooling ); if ( tool.StructMemberAlignment != alignNotSet ) strm << EPair( _StructMemberAlignment, tool.StructMemberAlignment ); strm << TPair( _SuppressStartupBanner, tool.SuppressStartupBanner ); strm << TPair( _TreatWChar_tAsBuiltInType, tool.TreatWChar_tAsBuiltInType ); strm << TPair( _TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration ); strm << TPair( _UndefineAllPreprocessorDefinitions, tool.UndefineAllPreprocessorDefinitions ); strm << XPair( _UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions ); if ( !tool.PrecompiledHeaderFile.isEmpty() || !tool.PrecompiledHeaderThrough.isEmpty() ) strm << EPair( _UsePrecompiledHeader, tool.UsePrecompiledHeader ); strm << TPair( _WarnAsError, tool.WarnAsError ); - strm << EPair( _WarningLevel, tool.WarningLevel ); + if ( tool.WarningLevel != warningLevelUnknown ) strm << EPair( _WarningLevel, tool.WarningLevel ); strm << TPair( _WholeProgramOptimization, tool.WholeProgramOptimization ); strm << "/>"; return strm; } bool VCCLCompilerTool::parseOption( const char* option ) { // skip index 0 ('/' or '-') char first = option[1]; char second = option[2]; char third = option[3]; char fourth = option[4]; bool found = TRUE; switch ( first ) { case '?': case 'h': qWarning( "Generator: Option '/?', '/help': MSVC.NET projects do not support outputting help info" ); found = FALSE; break; case '@': qWarning( "Generator: Option '/@': MSVC.NET projects do not support the use of a response file" ); found = FALSE; break; case 'l': qWarning( "Generator: Option '/link': qmake generator does not support passing link options through the compiler tool" ); found = FALSE; break; case 'A': if ( second != 'I' ) { found = FALSE; break; } - AdditionalUsingDirectories += option+2; + AdditionalUsingDirectories += option+3; break; case 'C': KeepComments = _True; break; case 'D': - PreprocessorDefinitions += option+1; + PreprocessorDefinitions += option+2; break; case 'E': 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 // with an /EHsc option ExceptionHandling = _False; AdditionalOptions += option; break; + } else if ( (third == 'c' && fourth == 's') + || (third == 's' && fourth == 'c') ) { + ExceptionHandling = _True; + AdditionalOptions += option; + break; } found = FALSE; break; } GeneratePreprocessedFile = preprocessYes; break; case 'F': if ( second <= '9' && second >= '0' ) { AdditionalOptions += option; break; } else { switch ( second ) { case 'A': if ( third == 'c' ) { AssemblerOutput = asmListingAsmMachine; if ( fourth == 's' ) AssemblerOutput = asmListingAsmMachineSrc; } else if ( third == 's' ) { AssemblerOutput = asmListingAsmSrc; } else { AssemblerOutput = asmListingAssemblyOnly; } break; case 'a': AssemblerListingLocation = option+3; break; case 'I': ForcedIncludeFiles += option+3; break; case 'R': BrowseInformation = brAllInfo; BrowseInformationFile = option+3; break; case 'r': BrowseInformation = brNoLocalSymbols; BrowseInformationFile = option+3; break; case 'U': ForcedUsingFiles += option+3; break; case 'd': ProgramDataBaseFileName = option+3; break; case 'e': OutputFile = option+3; break; case 'm': AdditionalOptions += option; break; case 'o': ObjectFile = option+3; break; case 'p': PrecompiledHeaderFile = option+3; break; case 'x': ExpandAttributedSource = _True; break; default: found = FALSE; break; } } break; case 'G': switch ( second ) { case '3': case '4': qWarning( "Option '/G3' and '/G4' were phased out in Visual C++ 5.0" ); found = FALSE; break; case '5': OptimizeForProcessor = procOptimizePentium; break; case '6': case 'B': OptimizeForProcessor = procOptimizePentiumProAndAbove; break; case 'A': OptimizeForWindowsApplication = _True; break; case 'F': StringPooling = _True; break; case 'H': AdditionalOptions += option; break; case 'L': WholeProgramOptimization = _True; if ( third == '-' ) WholeProgramOptimization = _False; break; case 'R': RuntimeTypeInfo = _True; if ( third == '-' ) RuntimeTypeInfo = _False; break; case 'S': BufferSecurityCheck = _True; break; case 'T': EnableFiberSafeOptimizations = _True; break; case 'X': + // ExceptionHandling == true will override with + // an /EHsc option, which is correct with /GX + ExceptionHandling = _True; // Fall-through case 'Z': case 'e': case 'h': AdditionalOptions += option; break; case 'd': CallingConvention = callConventionCDecl; break; case 'f': StringPooling = _True; AdditionalOptions += option; break; case 'm': MinimalRebuild = _True; if ( third == '-' ) MinimalRebuild = _False; break; case 'r': CallingConvention = callConventionFastCall; break; case 's': // Warning: following [num] is not used, // were should we put it? BufferSecurityCheck = _True; break; case 'y': EnableFunctionLevelLinking = _True; break; case 'z': CallingConvention = callConventionStdCall; break; default: found = FALSE; break; } break; case 'H': AdditionalOptions += option; break; case 'I': AdditionalIncludeDirectories += option+2; break; case 'L': if ( second == 'D' ) { AdditionalOptions += option; break; } found = FALSE; break; case 'M': if ( second == 'D' ) { RuntimeLibrary = rtMultiThreadedDLL; if ( third == 'd' ) RuntimeLibrary = rtMultiThreadedDebugDLL; break; } else if ( second == 'L' ) { RuntimeLibrary = rtSingleThreaded; if ( third == 'd' ) RuntimeLibrary = rtSingleThreadedDebug; break; } else if ( second == 'T' ) { RuntimeLibrary = rtMultiThreaded; if ( third == 'd' ) RuntimeLibrary = rtMultiThreadedDebug; break; } @@ -893,194 +889,194 @@ bool VCCLCompilerTool::parseOption( const char* option ) } else { found = FALSE; break; } break; case 'd': if ( second != 'r' ) { found = FALSE; break; } CompileAsManaged = managedAssembly; break; case 'n': if ( second == 'o' && third == 'B' && fourth == 'o' ) { AdditionalOptions += "/noBool"; break; } if ( second == 'o' && third == 'l' && fourth == 'o' ) { SuppressStartupBanner = _True; break; } found = FALSE; break; case 's': if ( second == 'h' && third == 'o' && fourth == 'w' ) { ShowIncludes = _True; break; } found = FALSE; break; case 'u': UndefineAllPreprocessorDefinitions = _True; break; case 'v': if ( second == 'd' || second == 'm' ) { AdditionalOptions += option; break; } found = FALSE; break; case 'w': switch ( second ) { case '\0': WarningLevel = warningLevel_0; break; case 'd': DisableSpecificWarnings += option+3; break; default: AdditionalOptions += option; } break; default: found = FALSE; break; } if( !found ) warn_msg( WarnLogic, "Could not parse Compiler option: %s", option ); return TRUE; } // VCLinkerTool ----------------------------------------------------- VCLinkerTool::VCLinkerTool() : EnableCOMDATFolding( optFoldingDefault ), GenerateDebugInformation( unset ), GenerateMapFile( unset ), HeapCommitSize( -1 ), HeapReserveSize( -1 ), IgnoreAllDefaultLibraries( unset ), IgnoreEmbeddedIDL( unset ), - IgnoreImportLibrary( unset ), + IgnoreImportLibrary( _True ), LargeAddressAware( addrAwareDefault ), LinkDLL( unset ), - LinkIncremental( linkIncrementalYes ), + LinkIncremental( linkIncrementalDefault ), LinkTimeCodeGeneration( unset ), MapExports( unset ), MapLines( unset ), OptimizeForWindows98( optWin98Default ), OptimizeReferences( optReferencesDefault ), RegisterOutput( unset ), ResourceOnlyDLL( unset ), SetChecksum( unset ), ShowProgress( linkProgressNotSet ), StackCommitSize( -1 ), StackReserveSize( -1 ), SubSystem( subSystemNotSet ), SupportUnloadOfDelayLoadedDLL( unset ), SuppressStartupBanner( unset ), SwapRunFromCD( unset ), SwapRunFromNet( unset ), TargetMachine( machineNotSet ), TerminalServerAware( termSvrAwareDefault ), TurnOffAssemblyGeneration( unset ), TypeLibraryResourceID( 0 ) { } QTextStream &operator<<( QTextStream &strm, const VCLinkerTool &tool ) { strm << _begTool3; strm << _VCLinkerToolName; strm << XPair( _AdditionalDependencies4, tool.AdditionalDependencies, " " ); strm << XPair( _AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories ); strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); strm << XPair( _AddModuleNamesToAssembly, tool.AddModuleNamesToAssembly ); strm << SPair( _BaseAddress, tool.BaseAddress ); strm << XPair( _DelayLoadDLLs, tool.DelayLoadDLLs ); if ( tool.EnableCOMDATFolding != optFoldingDefault ) strm << EPair( _EnableCOMDATFolding, tool.EnableCOMDATFolding ); strm << SPair( _EntryPointSymbol, tool.EntryPointSymbol ); strm << XPair( _ForceSymbolReferences, tool.ForceSymbolReferences ); strm << SPair( _FunctionOrder, tool.FunctionOrder ); strm << TPair( _GenerateDebugInformation, tool.GenerateDebugInformation ); strm << TPair( _GenerateMapFile, tool.GenerateMapFile ); if ( tool.HeapCommitSize != -1 ) strm << LPair( _HeapCommitSize, tool.HeapCommitSize ); if ( tool.HeapReserveSize != -1 ) strm << LPair( _HeapReserveSize, tool.HeapReserveSize ); strm << TPair( _IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries ); strm << XPair( _IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames ); strm << TPair( _IgnoreEmbeddedIDL, tool.IgnoreEmbeddedIDL ); strm << TPair( _IgnoreImportLibrary, tool.IgnoreImportLibrary ); strm << SPair( _ImportLibrary, tool.ImportLibrary ); if ( tool.LargeAddressAware != addrAwareDefault ) strm << EPair( _LargeAddressAware, tool.LargeAddressAware ); strm << TPair( _LinkDLL, tool.LinkDLL ); if ( tool.LinkIncremental != linkIncrementalDefault ) strm << EPair( _LinkIncremental, tool.LinkIncremental ); strm << TPair( _LinkTimeCodeGeneration, tool.LinkTimeCodeGeneration ); strm << SPair( _LinkToManagedResourceFile, tool.LinkToManagedResourceFile ); strm << TPair( _MapExports, tool.MapExports ); strm << SPair( _MapFileName, tool.MapFileName ); strm << TPair( _MapLines, tool.MapLines ); strm << SPair( _MergedIDLBaseFileName, tool.MergedIDLBaseFileName ); strm << SPair( _MergeSections, tool.MergeSections ); strm << SPair( _MidlCommandFile, tool.MidlCommandFile ); strm << SPair( _ModuleDefinitionFile, tool.ModuleDefinitionFile ); if ( tool.OptimizeForWindows98 != optWin98Default ) strm << EPair( _OptimizeForWindows98, tool.OptimizeForWindows98 ); if ( tool.OptimizeReferences != optReferencesDefault ) strm << EPair( _OptimizeReferences, tool.OptimizeReferences ); strm << SPair( _OutputFile, tool.OutputFile ); - strm << SPair( _ProgramDatabaseFile, tool.ProgramDatabaseFile ); + strm << _ProgramDatabaseFile << tool.ProgramDatabaseFile << "\""; strm << TPair( _RegisterOutput, tool.RegisterOutput ); strm << TPair( _ResourceOnlyDLL, tool.ResourceOnlyDLL ); strm << TPair( _SetChecksum, tool.SetChecksum ); if ( tool.ShowProgress != linkProgressNotSet ) strm << EPair( _ShowProgress, tool.ShowProgress ); if ( tool.StackCommitSize != -1 ) strm << LPair( _StackCommitSize, tool.StackCommitSize ); if ( tool.StackReserveSize != -1 ) strm << LPair( _StackReserveSize, tool.StackReserveSize ); strm << SPair( _StripPrivateSymbols, tool.StripPrivateSymbols ); strm << EPair( _SubSystem, tool.SubSystem ); strm << TPair( _SupportUnloadOfDelayLoadedDLL, tool.SupportUnloadOfDelayLoadedDLL ); strm << TPair( _SuppressStartupBanner, tool.SuppressStartupBanner ); strm << TPair( _SwapRunFromCD, tool.SwapRunFromCD ); strm << TPair( _SwapRunFromNet, tool.SwapRunFromNet ); if ( tool.TargetMachine != machineNotSet ) strm << EPair( _TargetMachine, tool.TargetMachine ); if ( tool.TerminalServerAware != termSvrAwareDefault ) strm << EPair( _TerminalServerAware, tool.TerminalServerAware ); strm << TPair( _TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration ); strm << SPair( _TypeLibraryFile, tool.TypeLibraryFile ); if ( tool.TypeLibraryResourceID != rcUseDefault ) strm << LPair( _TypeLibraryResourceID, tool.TypeLibraryResourceID ); strm << SPair( _Version4, tool.Version ); strm << "/>"; return strm; } // Hashing routine to do fast option lookups ---- // Slightly rewritten to stop on ':' ',' and '\0' // Original routine in qtranslator.cpp ---------- static uint elfHash( const char* name ) { const uchar *k; uint h = 0; uint g; if ( name ) { k = (const uchar *) name; while ( (*k) && (*k)!= ':' && (*k)!=',' && (*k)!=' ' ) { h = ( h << 4 ) + *k++; if ( (g = (h & 0xf0000000)) != 0 ) h ^= g >> 24; h &= ~g; } } if ( !h ) h = 1; return h; } //#define USE_DISPLAY_HASH #ifdef USE_DISPLAY_HASH static void displayHash( const char* str ) { printf( "case 0x%07x: // %s\n break;\n", elfHash(str), str ); } #endif bool VCLinkerTool::parseOption( const char* option ) { #ifdef USE_DISPLAY_HASH // Main options displayHash( "/ALIGN" ); displayHash( "/ALLOWBIND" ); displayHash( "/ASSEMBLYMODULE" ); displayHash( "/ASSEMBLYRESOURCE" ); displayHash( "/BASE" ); displayHash( "/DEBUG" ); displayHash( "/DEF" ); displayHash( "/DEFAULTLIB" ); displayHash( "/DELAY" ); displayHash( "/DELAYLOAD" ); displayHash( "/DLL" ); displayHash( "/DRIVER" ); @@ -1646,347 +1642,472 @@ bool VCMIDLTool::parseOption( const char* option ) if ( *(option+1) == 'W' ) { switch ( *(option+2) ) { case '0': WarningLevel = midlWarningLevel_0; break; case '1': WarningLevel = midlWarningLevel_1; break; case '2': WarningLevel = midlWarningLevel_2; break; case '3': WarningLevel = midlWarningLevel_3; break; case '4': WarningLevel = midlWarningLevel_4; break; default: found = FALSE; } } break; } if( !found ) warn_msg( WarnLogic, "Could not parse MIDL option: %s", option ); return TRUE; } // VCLibrarianTool -------------------------------------------------- VCLibrarianTool::VCLibrarianTool() : IgnoreAllDefaultLibraries( unset ), SuppressStartupBanner( _True ) { } QTextStream &operator<<( QTextStream &strm, const VCLibrarianTool &tool ) { strm << _begTool3; strm << SPair( _ToolName, QString( "VCLibrarianTool" ) ); strm << XPair( _AdditionalDependencies4, tool.AdditionalDependencies ); strm << XPair( _AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories ); strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); strm << XPair( _ExportNamedFunctions, tool.ExportNamedFunctions ); strm << XPair( _ForceSymbolReferences, tool.ForceSymbolReferences ); strm << TPair( _IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries ); strm << XPair( _IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames ); strm << SPair( _ModuleDefinitionFile, tool.ModuleDefinitionFile ); strm << SPair( _OutputFile, tool.OutputFile ); strm << TPair( _SuppressStartupBanner, tool.SuppressStartupBanner ); strm << "/>"; return strm; } // VCCustomBuildTool ------------------------------------------------ VCCustomBuildTool::VCCustomBuildTool() { ToolName = "VCCustomBuildTool"; } QTextStream &operator<<( QTextStream &strm, const VCCustomBuildTool &tool ) { strm << _begTool3; strm << SPair( _ToolName, tool.ToolName ); 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 ); strm << "/>"; return strm; } // VCResourceCompilerTool ------------------------------------------- VCResourceCompilerTool::VCResourceCompilerTool() : Culture( rcUseDefault ), IgnoreStandardIncludePath( unset ), ShowProgress( linkProgressNotSet ) { PreprocessorDefinitions = "NDEBUG"; } QTextStream &operator<<( QTextStream &strm, const VCResourceCompilerTool &tool ) { strm << _begTool3; strm << _VCResourceCompilerToolName; strm << SPair( _ToolPath, tool.ToolPath ); strm << XPair( _AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories ); strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); if ( tool.Culture != rcUseDefault ) strm << EPair( _Culture, tool.Culture ); strm << XPair( _FullIncludePath, tool.FullIncludePath ); strm << TPair( _IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath ); strm << XPair( _PreprocessorDefinitions, tool.PreprocessorDefinitions ); strm << SPair( _ResourceOutputFileName, tool.ResourceOutputFileName ); if ( tool.ShowProgress != linkProgressNotSet ) strm << EPair( _ShowProgress, tool.ShowProgress ); strm << "/>"; return strm; } // VCEventTool ------------------------------------------------- QTextStream &operator<<( QTextStream &strm, const VCEventTool &tool ) { strm << _begTool3; strm << SPair( _ToolName, tool.ToolName ); strm << SPair( _ToolPath, tool.ToolPath ); strm << SPair( _CommandLine4, tool.CommandLine ); strm << SPair( _Description4, tool.Description ); strm << TPair( _ExcludedFromBuild, tool.ExcludedFromBuild ); strm << "/>"; return strm; } // VCPostBuildEventTool --------------------------------------------- VCPostBuildEventTool::VCPostBuildEventTool() { ToolName = "VCPostBuildEventTool"; } // VCPreBuildEventTool ---------------------------------------------- VCPreBuildEventTool::VCPreBuildEventTool() { ToolName = "VCPreBuildEventTool"; } // VCPreLinkEventTool ----------------------------------------------- VCPreLinkEventTool::VCPreLinkEventTool() { ToolName = "VCPreLinkEventTool"; } // VCConfiguration -------------------------------------------------- VCConfiguration::VCConfiguration() : ATLMinimizesCRunTimeLibraryUsage( unset ), BuildBrowserInformation( unset ), CharacterSet( charSetNotSet ), ConfigurationType( typeApplication ), RegisterOutput( unset ), UseOfATL( useATLNotSet ), UseOfMfc( useMfcStdWin ), WholeProgramOptimization( unset ) { compiler.config = this; linker.config = this; idl.config = this; } QTextStream &operator<<( QTextStream &strm, const VCConfiguration &tool ) { strm << _begConfiguration; strm << SPair( _Name3, tool.Name ); strm << SPair( _OutputDirectory3, tool.OutputDirectory ); strm << TPair( _ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage ); strm << TPair( _BuildBrowserInformation, tool.BuildBrowserInformation ); if ( tool.CharacterSet != charSetNotSet) strm << EPair( _CharacterSet, tool.CharacterSet ); strm << EPair( _ConfigurationType, tool.ConfigurationType ); strm << SPair( _DeleteExtensionsOnClean, tool.DeleteExtensionsOnClean ); strm << SPair( _ImportLibrary, tool.ImportLibrary ); strm << SPair( _IntermediateDirectory, tool.IntermediateDirectory ); strm << SPair( _PrimaryOutput, tool.PrimaryOutput ); strm << SPair( _ProgramDatabase, tool.ProgramDatabase ); strm << TPair( _RegisterOutput, tool.RegisterOutput ); if ( tool.UseOfATL != useATLNotSet) strm << EPair( _UseOfATL, tool.UseOfATL ); strm << EPair( _UseOfMfc, tool.UseOfMfc ); strm << TPair( _WholeProgramOptimization, tool.WholeProgramOptimization ); strm << ">"; strm << tool.compiler; strm << tool.custom; if ( tool.ConfigurationType == typeStaticLibrary ) strm << tool.librarian; else strm << tool.linker; strm << tool.idl; strm << tool.postBuild; strm << tool.preBuild; strm << tool.preLink; strm << tool.resource; strm << _endConfiguration; return strm; } // VCFilter --------------------------------------------------------- VCFilter::VCFilter() : ParseFiles( unset ) { + 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"); QString mocApp = Project->var( "QMAKE_MOC" ); QString fname = str.section( '\\', -1 ); QString mocDir = Project->var( "MOC_DIR" ); QString uiDir = Project->var( "UI_DIR" ); QString uiHeaders; QString uiSources; // Determining the paths for the output files. int slash = str.findRev( '\\' ); QString pname = ( slash != -1 ) ? str.left( slash+1 ) : QString( ".\\" ); if( !uiDir.isEmpty() ) { uiHeaders = uiDir; uiSources = uiDir; } else { uiHeaders = Project->var( "UI_HEADERS_DIR" ); uiSources = Project->var( "UI_SOURCES_DIR" ); if( uiHeaders.isEmpty() ) uiHeaders = pname; if( uiSources.isEmpty() ) uiSources = pname; } if( !uiHeaders.endsWith( "\\" ) ) uiHeaders += "\\"; if( !uiSources.endsWith( "\\" ) ) uiSources += "\\"; // Determine the file name. int dot = fname.findRev( '.' ); if( dot != -1 ) fname.truncate( dot ); - 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 ) { if ( tool.Files.count() == 0 ) return strm; strm << _begFilter; strm << SPair( _Name3, tool.Name ); strm << TPair( _ParseFiles, tool.ParseFiles ); strm << SPair( _Filter, tool.Filter ); 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; strm << SPair( _RelativePath, *it ); 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; return strm; } // VCProject -------------------------------------------------------- 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 } QTextStream &operator<<( QTextStream &strm, const VCProject &tool ) { strm << _xmlInit; strm << _begVisualStudioProject; strm << _ProjectType; strm << SPair( _Version1, tool.Version ); strm << SPair( _Name1, tool.Name ); strm << SPair( _ProjectGUID, tool.ProjectGUID ); strm << SPair( _SccProjectName, tool.SccProjectName ); strm << SPair( _SccLocalPath, tool.SccLocalPath ); strm << ">"; strm << _begPlatforms; strm << _begPlatform; strm << SPair( _Name3, tool.PlatformName ); strm << "/>"; strm << _endPlatforms; 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; strm << _begGlobals; strm << _endGlobals; strm << _endVisualStudioProject; return strm; } 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,445 +1,453 @@ /**************************************************************************** -** $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. ** ** 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 __MSVC_OBJECTMODEL_H__ #define __MSVC_OBJECTMODEL_H__ #include "project.h" #include <qstring.h> #include <qstringlist.h> /* This Object model is of course VERY simplyfied, and does not actually follow the original MSVC object model. However, it fulfilles the basic needs for qmake */ /* If a triState value is 'unset' then the corresponding property is not in the output, forcing the tool to utilize default values. False/True values will be in the output... */ enum customBuildCheck { none, moc, uic, - lexyacc + lexyacc, + resource }; enum triState { unset = -1, _False = 0, _True = 1 }; enum addressAwarenessType { addrAwareDefault, addrAwareNoLarge, addrAwareLarge }; enum asmListingOption { asmListingNone, asmListingAssemblyOnly, asmListingAsmMachineSrc, asmListingAsmMachine, asmListingAsmSrc }; enum basicRuntimeCheckOption { runtimeBasicCheckNone, runtimeCheckStackFrame, runtimeCheckUninitVariables, runtimeBasicCheckAll }; enum browseInfoOption { brInfoNone, brAllInfo, brNoLocalSymbols }; enum callingConventionOption { callConventionDefault = -1, callConventionCDecl, callConventionFastCall, callConventionStdCall }; enum charSet { charSetNotSet, charSetUnicode, charSetMBCS }; enum compileAsManagedOptions { managedDefault = -1, managedAssembly = 2 }; enum CompileAsOptions{ compileAsDefault, compileAsC, compileAsCPlusPlus }; enum ConfigurationTypes { typeUnknown = 0, typeApplication = 1, typeDynamicLibrary = 2, typeStaticLibrary = 4, typeGeneric = 10 }; enum debugOption { + debugUnknown = -1, debugDisabled, debugOldStyleInfo, debugLineInfoOnly, debugEnabled, debugEditAndContinue }; enum eAppProtectionOption { eAppProtectUnchanged, eAppProtectLow, eAppProtectMedium, eAppProtectHigh }; enum enumResourceLangID { rcUseDefault = 0, rcAfrikaans = 1078, rcAlbanian = 1052, rcArabicAlgeria = 5121, rcArabicBahrain = 15361, rcArabicEgypt = 3073, rcArabicIraq = 2049, rcArabicJordan = 11265, rcArabicKuwait = 13313, rcArabicLebanon = 12289, rcArabicLibya = 4097, rcArabicMorocco = 6145, rcArabicOman = 8193, rcArabicQatar = 16385, rcArabicSaudi = 1025, rcArabicSyria = 10241, rcArabicTunisia = 7169, rcArabicUnitedArabEmirates = 14337, rcArabicYemen = 9217, rcBasque = 1069, rcBulgarian = 1026, rcByelorussian = 1059, rcCatalan = 1027, rcChineseHongKong = 3076, rcChinesePRC = 2052, rcChineseSingapore = 4100, rcChineseTaiwan = 1028, rcCroatian = 1050, rcCzech = 1029, rcDanish = 1030, rcDutchBelgium = 2067, rcDutchStandard = 1043, rcEnglishAustralia = 3081, rcEnglishBritain = 2057, rcEnglishCanada = 4105, RcEnglishCaribbean = 9225, rcEnglishIreland = 6153, rcEnglishJamaica = 8201, rcEnglishNewZealand = 5129, rcEnglishSouthAfrica = 7177, rcEnglishUS = 1033, rcEstonian = 1061, rcFarsi = 1065, rcFinnish = 1035, rcFrenchBelgium = 2060, rcFrenchCanada = 3084, rcFrenchLuxembourg = 5132, rcFrenchStandard = 1036, rcFrenchSwitzerland = 4108, rcGermanAustria = 3079, rcGermanLichtenstein = 5127, rcGermanLuxembourg = 4103, rcGermanStandard = 1031, rcGermanSwitzerland = 2055, rcGreek = 1032, rcHebrew = 1037, rcHungarian = 1038, rcIcelandic = 1039, rcIndonesian = 1057, rcItalianStandard = 1040, rcItalianSwitzerland = 2064, rcJapanese = 1041, rcKorean = 1042, rcKoreanJohab = 2066, rcLatvian = 1062, rcLithuanian = 1063, rcNorwegianBokmal = 1044, rcNorwegianNynorsk = 2068, rcPolish = 1045, rcPortugueseBrazilian = 1046, rcPortugueseStandard = 2070, rcRomanian = 1048, rcRussian = 1049, rcSerbian = 2074, rcSlovak = 1051, rcSpanishArgentina = 11274, rcSpanishBolivia = 16394, rcSpanishChile = 13322, rcSpanishColombia = 9226, rcSpanishCostaRica = 5130, rcSpanishDominicanRepublic = 7178, rcSpanishEcuador = 12298, rcSpanishGuatemala = 4106, rcSpanishMexico = 2058, rcSpanishModern = 3082, rcSpanishPanama = 6154, rcSpanishParaguay = 15370, rcSpanishPeru = 10250, rcSpanishTraditional = 1034, rcSpanishUruguay = 14346, rcSpanishVenezuela = 8202, rcSwedish = 1053, rcThai = 1054, rcTurkish = 1055, rcUkrainian = 1058, rcUrdu = 1056 }; enum enumSccEvent { eProjectInScc, ePreDirtyNotification }; enum favorSizeOrSpeedOption { favorNone, favorSpeed, favorSize }; enum genProxyLanguage { genProxyNative, genProxyManaged }; enum inlineExpansionOption { expandDisable, expandOnlyInline, - expandAnySuitable + expandAnySuitable, + expandDefault // Not useful number, but stops the output }; enum linkIncrementalType { linkIncrementalDefault, linkIncrementalNo, linkIncrementalYes }; enum linkProgressOption { linkProgressNotSet, linkProgressAll, linkProgressLibs }; enum machineTypeOption { machineNotSet, machineX86 }; enum midlCharOption { midlCharUnsigned, midlCharSigned, midlCharAscii7 }; enum midlErrorCheckOption { midlEnableCustom, midlDisableAll, midlEnableAll }; enum midlStructMemberAlignOption { midlAlignNotSet, midlAlignSingleByte, midlAlignTwoBytes, midlAlignFourBytes, midlAlignEightBytes, midlAlignSixteenBytes }; enum midlTargetEnvironment { midlTargetNotSet, midlTargetWin32, midlTargetWin64 }; enum midlWarningLevelOption { midlWarningLevel_0, midlWarningLevel_1, midlWarningLevel_2, midlWarningLevel_3, midlWarningLevel_4 }; enum optFoldingType { optFoldingDefault, optNoFolding, optFolding }; enum optimizeOption { optimizeDisabled, optimizeMinSpace, optimizeMaxSpeed, optimizeFull, - optimizeCustom + optimizeCustom, + optimizeDefault // Not useful number, but stops the output }; enum optRefType { optReferencesDefault, optNoReferences, optReferences }; enum optWin98Type { optWin98Default, optWin98No, optWin98Yes }; enum pchOption { pchNone, pchCreateUsingSpecific, pchGenerateAuto, pchUseUsingSpecific }; enum preprocessOption { + preprocessUnknown = -1, preprocessNo, preprocessYes, preprocessNoLineNumbers }; enum ProcessorOptimizeOption { procOptimizeBlended, procOptimizePentium, procOptimizePentiumProAndAbove }; enum RemoteDebuggerType { DbgLocal, DbgRemote, DbgRemoteTCPIP }; enum runtimeLibraryOption { + rtUnknown = -1, rtMultiThreaded, rtMultiThreadedDebug, rtMultiThreadedDLL, rtMultiThreadedDebugDLL, rtSingleThreaded, rtSingleThreadedDebug }; enum structMemberAlignOption { alignNotSet, alignSingleByte, alignTwoBytes, alignFourBytes, alignEightBytes, alignSixteenBytes }; enum subSystemOption { subSystemNotSet, subSystemConsole, subSystemWindows }; enum termSvrAwarenessType { termSvrAwareDefault, termSvrAwareNo, termSvrAwareYes }; enum toolSetType { toolSetUtility, toolSetMakefile, toolSetLinker, toolSetLibrarian, toolSetAll }; enum TypeOfDebugger { DbgNativeOnly, DbgManagedOnly, DbgMixed, DbgAuto }; enum useOfATL { useATLNotSet, useATLStatic, useATLDynamic }; enum useOfMfc { useMfcStdWin, useMfcStatic, useMfcDynamic }; enum warningLevelOption { + warningLevelUnknown = -1, warningLevel_0, warningLevel_1, warningLevel_2, warningLevel_3, warningLevel_4 }; class VCToolBase { protected: // Functions VCToolBase(){}; virtual ~VCToolBase(){} virtual bool parseOption( const char* option ) = 0; public: void parseOptions( QStringList& options ) { for ( QStringList::ConstIterator it=options.begin(); (it!=options.end()); it++ ) parseOption( (*it).latin1() ); } }; class VCConfiguration; class VCProject; class VCCLCompilerTool : public VCToolBase { public: // Functions VCCLCompilerTool(); virtual ~VCCLCompilerTool(){} bool parseOption( const char* option ); // Variables QStringList AdditionalIncludeDirectories; QStringList AdditionalOptions; QStringList AdditionalUsingDirectories; QString AssemblerListingLocation; asmListingOption AssemblerOutput; basicRuntimeCheckOption BasicRuntimeChecks; browseInfoOption BrowseInformation; QString BrowseInformationFile; triState BufferSecurityCheck; callingConventionOption CallingConvention; CompileAsOptions CompileAs; compileAsManagedOptions CompileAsManaged; triState CompileOnly; debugOption DebugInformationFormat; triState DefaultCharIsUnsigned; triState Detect64BitPortabilityProblems; triState DisableLanguageExtensions; QStringList DisableSpecificWarnings; triState EnableFiberSafeOptimizations; triState EnableFunctionLevelLinking; triState EnableIntrinsicFunctions; triState ExceptionHandling; triState ExpandAttributedSource; favorSizeOrSpeedOption FavorSizeOrSpeed; triState ForceConformanceInForLoopScope; QStringList ForcedIncludeFiles; QStringList ForcedUsingFiles; preprocessOption GeneratePreprocessedFile; triState GlobalOptimizations; triState IgnoreStandardIncludePath; triState ImproveFloatingPointConsistency; inlineExpansionOption InlineFunctionExpansion; @@ -550,224 +558,231 @@ public: QStringList AdditionalIncludeDirectories; QStringList AdditionalOptions; QStringList CPreprocessOptions; midlCharOption DefaultCharType; QString DLLDataFileName; // Should be list? midlErrorCheckOption EnableErrorChecks; triState ErrorCheckAllocations; triState ErrorCheckBounds; triState ErrorCheckEnumRange; triState ErrorCheckRefPointers; triState ErrorCheckStubData; QStringList FullIncludePath; triState GenerateStublessProxies; triState GenerateTypeLibrary; QString HeaderFileName; triState IgnoreStandardIncludePath; QString InterfaceIdentifierFileName; triState MkTypLibCompatible; QString OutputDirectory; QStringList PreprocessorDefinitions; QString ProxyFileName; QString RedirectOutputAndErrors; midlStructMemberAlignOption StructMemberAlignment; triState SuppressStartupBanner; midlTargetEnvironment TargetEnvironment; QString TypeLibraryName; QStringList UndefinePreprocessorDefinitions; triState ValidateParameters; triState WarnAsError; midlWarningLevelOption WarningLevel; VCConfiguration* config; }; class VCLibrarianTool : public VCToolBase { public: // Functions VCLibrarianTool(); virtual ~VCLibrarianTool(){} bool parseOption( const char* ){ return FALSE; }; // Variables QStringList AdditionalDependencies; QStringList AdditionalLibraryDirectories; QStringList AdditionalOptions; QStringList ExportNamedFunctions; QStringList ForceSymbolReferences; triState IgnoreAllDefaultLibraries; QStringList IgnoreDefaultLibraryNames; QString ModuleDefinitionFile; QString OutputFile; triState SuppressStartupBanner; }; class VCCustomBuildTool : public VCToolBase { public: // Functions VCCustomBuildTool(); virtual ~VCCustomBuildTool(){} bool parseOption( const char* ){ return FALSE; }; // Variables QStringList AdditionalDependencies; - QString CommandLine; + QStringList CommandLine; QString Description; - QString Outputs; + QStringList Outputs; QString ToolName; QString ToolPath; }; class VCResourceCompilerTool : public VCToolBase { public: // Functions VCResourceCompilerTool(); virtual ~VCResourceCompilerTool(){} bool parseOption( const char* ){ return FALSE; }; // Variables QStringList AdditionalIncludeDirectories; QStringList AdditionalOptions; enumResourceLangID Culture; QStringList FullIncludePath; triState IgnoreStandardIncludePath; QStringList PreprocessorDefinitions; QString ResourceOutputFileName; linkProgressOption ShowProgress; QString ToolPath; }; class VCEventTool : public VCToolBase { protected: // Functions VCEventTool() : ExcludedFromBuild( unset ){}; virtual ~VCEventTool(){} bool parseOption( const char* ){ return FALSE; }; public: // Variables QString CommandLine; QString Description; triState ExcludedFromBuild; QString ToolName; QString ToolPath; }; class VCPostBuildEventTool : public VCEventTool { public: VCPostBuildEventTool(); ~VCPostBuildEventTool(){} }; class VCPreBuildEventTool : public VCEventTool { public: VCPreBuildEventTool(); ~VCPreBuildEventTool(){} }; class VCPreLinkEventTool : public VCEventTool { public: VCPreLinkEventTool(); ~VCPreLinkEventTool(){} }; class VCConfiguration { public: // Functions VCConfiguration(); ~VCConfiguration(){} // Variables triState ATLMinimizesCRunTimeLibraryUsage; triState BuildBrowserInformation; charSet CharacterSet; ConfigurationTypes ConfigurationType; QString DeleteExtensionsOnClean; QString ImportLibrary; QString IntermediateDirectory; QString Name; QString OutputDirectory; QString PrimaryOutput; QString ProgramDatabase; triState RegisterOutput; useOfATL UseOfATL; useOfMfc UseOfMfc; triState WholeProgramOptimization; // XML sub-parts VCCLCompilerTool compiler; VCLinkerTool linker; VCLibrarianTool librarian; VCCustomBuildTool custom; VCMIDLTool idl; VCPostBuildEventTool postBuild; VCPreBuildEventTool preBuild; VCPreLinkEventTool preLink; VCResourceCompilerTool resource; }; class VcprojGenerator; class VCFilter { public: // Functions VCFilter(); ~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 ); // Variables QString Name; QString Filter; triState ParseFiles; QStringList Files; VcprojGenerator* Project; - VCConfiguration* Config; + QValueList<VCConfiguration> *Config; customBuildCheck CustomBuild; + bool useCustomBuildTool; + VCCustomBuildTool CustomBuildTool; + bool useCompilerTool; + VCCLCompilerTool CompilerTool; + bool flat_files; }; class VCProject { public: // Functions VCProject(); ~VCProject(){} // Variables QString Name; QString Version; QString ProjectGUID; QString SccProjectName; QString SccLocalPath; QString PlatformName; // XML sub-parts - VCConfiguration Configuration; + QValueList<VCConfiguration> Configuration; VCFilter SourceFiles; VCFilter HeaderFiles; VCFilter MOCFiles; VCFilter UICFiles; VCFilter FormFiles; VCFilter TranslationFiles; VCFilter LexYaccFiles; VCFilter ResourceFiles; }; QTextStream &operator<<( QTextStream &, const VCCLCompilerTool & ); QTextStream &operator<<( QTextStream &, const VCLinkerTool & ); QTextStream &operator<<( QTextStream &, const VCMIDLTool & ); QTextStream &operator<<( QTextStream &, const VCCustomBuildTool & ); QTextStream &operator<<( QTextStream &, const VCLibrarianTool & ); QTextStream &operator<<( QTextStream &, const VCResourceCompilerTool & ); QTextStream &operator<<( QTextStream &, const VCEventTool & ); QTextStream &operator<<( QTextStream &, const VCConfiguration & ); -QTextStream &operator<<( QTextStream &, const VCFilter & ); +QTextStream &operator<<( QTextStream &, VCFilter & ); QTextStream &operator<<( QTextStream &, const VCProject & ); #endif //__MSVC_OBJECTMODEL_H__ 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,801 +1,1042 @@ /**************************************************************************** -** $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. ** ** 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 "msvc_vcproj.h" #include "option.h" +#include "qtmd5.h" // SG's MD5 addon #include <qdir.h> #include <qregexp.h> #include <qdict.h> #include <quuid.h> #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... // If so we need to search through the registry at // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects // to find the subkey that contains a "PossibleProjectExtension" // containing "vcproj"... // Use the hardcoded value for now so projects generated on other // 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" "\n\tGlobalSection(ExtensibilityAddIns) = postSolution" "\n\tEndGlobalSection"; // ------------------------------------------------------------------ VcprojGenerator::VcprojGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) { } /* \internal Generates a project file for the given profile. Options are either a Visual Studio projectfiles, or solutionfiles by parsing recursive projectdirectories. */ bool VcprojGenerator::writeMakefile(QTextStream &t) { // Check if all requirements are fullfilled if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", var("QMAKE_FAILED_REQUIREMENTS").latin1()); return TRUE; } // Generate project file if(project->first("TEMPLATE") == "vcapp" || project->first("TEMPLATE") == "vclib") { debug_msg(1, "Generator: MSVC.NET: Writing project file" ); t << vcProject; return TRUE; } // Generate solution file else if(project->first("TEMPLATE") == "vcsubdirs") { debug_msg(1, "Generator: MSVC.NET: Writing solution file" ); writeSubDirs(t); return TRUE; } return FALSE; } struct VcsolutionDepend { QString uuid; QString vcprojFile, orig_target, target; ::target targetType; + bool debugBuild; QStringList dependencies; }; +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 ) { QUuid result( id ); Q_LONG dataFirst = (result.data4[0] << 24) + (result.data4[1] << 16) + (result.data4[2] << 8) + result.data4[3]; Q_LONG dataLast = (result.data4[4] << 24) + (result.data4[5] << 16) + (result.data4[6] << 8) + result.data4[7]; if ( !(dataLast++) ) dataFirst++; result.data4[0] = uchar((dataFirst >> 24) & 0xff); result.data4[1] = uchar((dataFirst >> 16) & 0xff); result.data4[2] = uchar((dataFirst >> 8) & 0xff); result.data4[3] = uchar( dataFirst & 0xff); result.data4[4] = uchar((dataLast >> 24) & 0xff); result.data4[5] = uchar((dataLast >> 16) & 0xff); result.data4[6] = uchar((dataLast >> 8) & 0xff); result.data4[7] = uchar( dataLast & 0xff); return result; } void VcprojGenerator::writeSubDirs(QTextStream &t) { if(project->first("TEMPLATE") == "subdirs") { writeHeader(t); Win32MakefileGenerator::writeSubDirs(t); return; } - 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) { 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(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") { // Initialize a 'fake' project to get the correct variables // and to be able to extract all the dependencies VcprojGenerator tmp_vcproj(&tmp_proj); tmp_vcproj.setNoIO(TRUE); tmp_vcproj.init(); 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()); } } // We assume project filename is [QMAKE_ORIG_TARGET].vcproj QString vcproj = fixFilename(tmp_vcproj.project->first("QMAKE_ORIG_TARGET")) + project->first("VCPROJ_EXTENSION"); // If file doesn't exsist, then maybe the users configuration // doesn't allow it to be created. Skip to next... 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! } VcsolutionDepend *newDep = new VcsolutionDepend; newDep->vcprojFile = fileFixify(vcproj); 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); } } } +#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; } } nextfile: QDir::setCurrent(oldpwd); } } } - 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; for(QStringList::iterator dit = solution_cleanup.current()->dependencies.begin(); 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; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void VcprojGenerator::init() { if( init_flag ) return; if(project->first("TEMPLATE") == "vcsubdirs") { //too much work for subdirs init_flag = TRUE; return; } debug_msg(1, "Generator: MSVC.NET: Initializing variables" ); /* // Once to be nice and clean code... // Wouldn't life be great? // Are we building Qt? bool is_qt = ( project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX ); // Are we using Qt? bool isQtActive = project->isActiveConfig("qt"); if ( isQtActive ) { project->variables()["CONFIG"] += "moc"; project->variables()["CONFIG"] += "windows"; project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"]; if( projectTarget == SharedLib ) project->variables()["DEFINES"] += "QT_DLL"; if( project->isActiveConfig("accessibility" ) ) project->variables()["DEFINES"] += "QT_ACCESSIBILITY_SUPPORT"; if ( project->isActiveConfig("plugin")) { project->variables()["DEFINES"] += "QT_PLUGIN"; project->variables()["CONFIG"] += "dll"; } if( project->isActiveConfig("thread") ) { project->variables()["DEFINES"] += "QT_THREAD_SUPPORT"; project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; } else { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; } } if ( project->isActiveConfig("opengl") ) { project->variables()["CONFIG"] += "windows"; // <-- Also in 'qt' above project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"]; } */ initOld(); // Currently calling old DSP code to set variables. CLEAN UP! // Figure out what we're trying to build if ( project->first("TEMPLATE") == "vcapp" ) { projectTarget = Application; } else if ( project->first("TEMPLATE") == "vclib") { if ( project->isActiveConfig( "staticlib" ) ) projectTarget = StaticLib; else projectTarget = SharedLib; } + + // 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 } void VcprojGenerator::initProject() { // Initialize XML sub elements // - Do this first since project elements may need // - to know of certain configuration options initConfiguration(); initSourceFiles(); initHeaderFiles(); initMOCFiles(); initUICFiles(); initFormsFiles(); initTranslationFiles(); initLexYaccFiles(); initResourceFiles(); // Own elements ----------------------------- 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 vcProject.SccProjectName = project->first("SCCPROJECTNAME"); vcProject.SccLocalPath = project->first("SCCLOCALPATH"); } void VcprojGenerator::initConfiguration() { // Initialize XML sub elements // - Do this first since main configuration elements may need // - to know of certain compiler/linker options initCompilerTool(); if ( projectTarget == StaticLib ) initLibrarianTool(); else initLinkerTool(); initIDLTool(); // Own elements ----------------------------- QString temp = project->first("BuildBrowserInformation"); switch ( projectTarget ) { case SharedLib: - vcProject.Configuration.ConfigurationType = typeDynamicLibrary; + vcProject.Configuration[0].ConfigurationType = typeDynamicLibrary; break; case StaticLib: - vcProject.Configuration.ConfigurationType = typeStaticLibrary; + vcProject.Configuration[0].ConfigurationType = typeStaticLibrary; break; case Application: 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() ); // Configuration does not need parameters from // these sub XML items; initCustomBuildTool(); initPreBuildEventTools(); initPostBuildEventTools(); 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; } void VcprojGenerator::initCompilerTool() { QString placement = project->first("OBJECTS_DIR"); if ( placement.isEmpty() ) placement = ".\\"; - 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"); + } if ( project->isActiveConfig("debug") ){ // 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"] ); } } else { // 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"] ); } } // Common for both release and debug 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"]; // Can this be set for ALL configs? // If so, use qmake.conf! 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"] ); } 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"); } 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"]; switch ( projectTarget ) { 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; case StaticLib: //unhandled - added to remove warnings.. break; } - 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"] ); } if ( project->isActiveConfig("dll") ){ - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_QT_DLL"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_QT_DLL"] ); } 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"] ); } } void VcprojGenerator::initIDLTool() { } void VcprojGenerator::initCustomBuildTool() { } 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; - - } } 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"); } if( project->isActiveConfig( "activeqt" ) ) { QString name = project->first( "QMAKE_ORIG_TARGET" ); QString nameext = project->first( "TARGET" ); QString objdir = project->first( "OBJECTS_DIR" ); QString idc = project->first( "QMAKE_IDC" ); - 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"; } } } 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"; vcProject.SourceFiles.Filter = "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"; vcProject.SourceFiles.Files += project->variables()["SOURCES"]; - vcProject.SourceFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.SourceFiles.Files, + vcProject.SourceFiles.flat_files ); vcProject.SourceFiles.Project = this; vcProject.SourceFiles.Config = &(vcProject.Configuration); vcProject.SourceFiles.CustomBuild = none; } void VcprojGenerator::initHeaderFiles() { + vcProject.HeaderFiles.flat_files = project->isActiveConfig("flat"); vcProject.HeaderFiles.Name = "Header Files"; vcProject.HeaderFiles.Filter = "h;hpp;hxx;hm;inl"; 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; vcProject.HeaderFiles.Config = &(vcProject.Configuration); vcProject.HeaderFiles.CustomBuild = moc; } void VcprojGenerator::initMOCFiles() { + vcProject.MOCFiles.flat_files = project->isActiveConfig("flat"); vcProject.MOCFiles.Name = "Generated MOC Files"; vcProject.MOCFiles.Filter = "cpp;c;cxx;moc"; vcProject.MOCFiles.Files += project->variables()["SRCMOC"]; - vcProject.MOCFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.MOCFiles.Files, + vcProject.MOCFiles.flat_files ); vcProject.MOCFiles.Project = this; vcProject.MOCFiles.Config = &(vcProject.Configuration); vcProject.MOCFiles.CustomBuild = moc; } 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;"; vcProject.UICFiles.Project = this; vcProject.UICFiles.Files += project->variables()["UICDECLS"]; vcProject.UICFiles.Files += project->variables()["UICIMPLS"]; - vcProject.UICFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.UICFiles.Files, + vcProject.UICFiles.flat_files ); vcProject.UICFiles.Config = &(vcProject.Configuration); vcProject.UICFiles.CustomBuild = none; } void VcprojGenerator::initFormsFiles() { + vcProject.FormFiles.flat_files = project->isActiveConfig("flat"); vcProject.FormFiles.Name = "Forms"; vcProject.FormFiles.ParseFiles = _False; vcProject.FormFiles.Filter = "ui"; vcProject.FormFiles.Files += project->variables()["FORMS"]; - vcProject.FormFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.FormFiles.Files, + vcProject.FormFiles.flat_files ); vcProject.FormFiles.Project = this; vcProject.FormFiles.Config = &(vcProject.Configuration); vcProject.FormFiles.CustomBuild = uic; } void VcprojGenerator::initTranslationFiles() { + vcProject.TranslationFiles.flat_files = project->isActiveConfig("flat"); vcProject.TranslationFiles.Name = "Translations Files"; vcProject.TranslationFiles.ParseFiles = _False; vcProject.TranslationFiles.Filter = "ts"; vcProject.TranslationFiles.Files += project->variables()["TRANSLATIONS"]; - vcProject.TranslationFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.TranslationFiles.Files, + vcProject.TranslationFiles.flat_files ); vcProject.TranslationFiles.Project = this; vcProject.TranslationFiles.Config = &(vcProject.Configuration); vcProject.TranslationFiles.CustomBuild = none; } void VcprojGenerator::initLexYaccFiles() { + vcProject.LexYaccFiles.flat_files = project->isActiveConfig("flat"); vcProject.LexYaccFiles.Name = "Lex / Yacc Files"; vcProject.LexYaccFiles.ParseFiles = _False; vcProject.LexYaccFiles.Filter = "l;y"; vcProject.LexYaccFiles.Files += project->variables()["LEXSOURCES"]; 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; } void VcprojGenerator::initResourceFiles() { + vcProject.ResourceFiles.flat_files = project->isActiveConfig("flat"); vcProject.ResourceFiles.Name = "Resources"; vcProject.ResourceFiles.ParseFiles = _False; vcProject.ResourceFiles.Filter = "cpp;ico;png;jpg;jpeg;gif;xpm;bmp;rc;ts"; vcProject.ResourceFiles.Files += project->variables()["RC_FILE"]; vcProject.ResourceFiles.Files += project->variables()["QMAKE_IMAGE_COLLECTION"]; vcProject.ResourceFiles.Files += project->variables()["IMAGES"]; 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; } /* \internal Sets up all needed variables from the environment and all the different caches and .conf files */ void VcprojGenerator::initOld() { if( init_flag ) return; init_flag = TRUE; QStringList::Iterator it; if ( project->isActiveConfig("stl") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"]; } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"]; } 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"]; } // this should probably not be here, but I'm using it to wrap the .t files if(project->first("TEMPLATE") == "vcapp" ) project->variables()["QMAKE_APP_FLAG"].append("1"); else if(project->first("TEMPLATE") == "vclib") project->variables()["QMAKE_LIB_FLAG"].append("1"); if ( project->variables()["QMAKESPEC"].isEmpty() ) project->variables()["QMAKESPEC"].append( getenv("QMAKESPEC") ); bool is_qt = ( project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX ); QStringList &configs = project->variables()["CONFIG"]; if ( project->isActiveConfig( "shared" ) ) project->variables()["DEFINES"].append( "QT_DLL" ); if ( project->isActiveConfig( "qt_dll" ) && configs.findIndex("qt") == -1 ) configs.append("qt"); if ( project->isActiveConfig( "qt" ) ) { if ( project->isActiveConfig( "plugin" ) ) { project->variables()["CONFIG"].append( "dll" ); project->variables()["DEFINES"].append( "QT_PLUGIN" ); } if ( ( project->variables()["DEFINES"].findIndex( "QT_NODLL" ) == -1 ) && (( project->variables()["DEFINES"].findIndex( "QT_MAKEDLL" ) != -1 || @@ -804,389 +1045,396 @@ void VcprojGenerator::initOld() project->variables()["QMAKE_QT_DLL"].append( "1" ); if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) project->variables()["CONFIG"].append( "dll" ); } } // If we are a dll, then we cannot be a staticlib at the same time... 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 we need 'qt' and/or 'opengl', then we need windows and not console if ( project->isActiveConfig( "qt" ) || project->isActiveConfig( "opengl" ) ) { project->variables()["CONFIG"].append( "windows" ); } // Decode version, and add it to $$MSVCPROJ_VERSION -------------- 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( QRegExp( "\\." ), "" ); project->variables()["MSVCPROJ_VERSION"].append( "/VERSION:" + major + "." + minor ); } // QT ------------------------------------------------------------ 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 ( 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"].append("/BASE:0x39D00000"); } } 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("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "-mt" : ""), hver); QStringList &libs = project->variables()["QMAKE_LIBS"]; 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"]; - project->variables()["MSVCPROJ_LFLAGS"].append("/DEF:"+project->first("DEF_FILE")); } } if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) { project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"]; } } } // Set target directories ---------------------------------------- // if ( !project->first("OBJECTS_DIR").isEmpty() ) //project->variables()["MSVCPROJ_OBJECTSDIR"] = project->first("OBJECTS_DIR"); // else //project->variables()["MSVCPROJ_OBJECTSDIR"] = project->isActiveConfig( "release" )?"Release":"Debug"; // if ( !project->first("DESTDIR").isEmpty() ) //project->variables()["MSVCPROJ_TARGETDIR"] = project->first("DESTDIR"); // else //project->variables()["MSVCPROJ_TARGETDIR"] = project->isActiveConfig( "release" )?"Release":"Debug"; // OPENGL -------------------------------------------------------- if ( project->isActiveConfig("opengl") ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"]; } // THREAD -------------------------------------------------------- if ( project->isActiveConfig("thread") ) { if(project->isActiveConfig("qt")) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT" ); if ( !project->variables()["DEFINES"].contains("QT_DLL") && is_qt && project->first("TARGET") != "qtmain" ) project->variables()["QMAKE_LFLAGS"].append("/NODEFAULTLIB:libc"); } // ACCESSIBILITY ------------------------------------------------- if(project->isActiveConfig("qt")) { 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"); } // DLL ----------------------------------------------------------- if ( project->isActiveConfig("dll") ) { if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { QString ver_xyz(project->first("VERSION")); ver_xyz.replace(QRegExp("\\."), ""); project->variables()["TARGET_EXT"].append(ver_xyz + ".dll"); } else { project->variables()["TARGET_EXT"].append(".dll"); } } // EXE / LIB ----------------------------------------------------- else { if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) project->variables()["TARGET_EXT"].append(".exe"); else project->variables()["TARGET_EXT"].append(".lib"); } project->variables()["MSVCPROJ_VER"] = "7.00"; project->variables()["MSVCPROJ_DEBUG_OPT"] = "/GZ /ZI"; // INCREMENTAL:NO ------------------------------------------------ if(!project->isActiveConfig("incremental")) { project->variables()["QMAKE_LFLAGS"].append(QString("/INCREMENTAL:no")); if ( is_qt ) project->variables()["MSVCPROJ_DEBUG_OPT"] = "/GZ /Zi"; } // MOC ----------------------------------------------------------- if ( project->isActiveConfig("moc") ) setMocAware(TRUE); + // /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 ); + } project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; // Update -lname to name.lib, and -Ldir to QStringList &libList = project->variables()["QMAKE_LIBS"]; for( it = libList.begin(); it != libList.end(); ) { QString s = *it; if( s.startsWith( "-l" ) ) { it = libList.remove( it ); it = libList.insert( it, s.mid( 2 ) + ".lib" ); } else if( s.startsWith( "-L" ) ) { + project->variables()["QMAKE_LIBDIR"] += (*it).mid(2); it = libList.remove( it ); } else { it++; } } // Run through all variables containing filepaths, and ----------- // slash-slosh them correctly depending on current OS ----------- 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(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); } // Get filename w/o extention ----------------------------------- QString msvcproj_project = ""; QString targetfilename = ""; if ( project->variables()["TARGET"].count() ) { msvcproj_project = project->variables()["TARGET"].first(); targetfilename = msvcproj_project; } // Save filename w/o extention in $$QMAKE_ORIG_TARGET ------------ project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; // TARGET (add extention to $$TARGET) //project->variables()["MSVCPROJ_DEFINES"].append(varGlue(".first() += project->first("TARGET_EXT"); // Init base class too ------------------------------------------- MakefileGenerator::init(); if ( msvcproj_project.isEmpty() ) msvcproj_project = Option::output.name(); msvcproj_project = msvcproj_project.right( msvcproj_project.length() - msvcproj_project.findRev( "\\" ) - 1 ); msvcproj_project = msvcproj_project.left( msvcproj_project.findRev( "." ) ); msvcproj_project.replace(QRegExp("-"), ""); project->variables()["MSVCPROJ_PROJECT"].append(msvcproj_project); QStringList &proj = project->variables()["MSVCPROJ_PROJECT"]; for(it = proj.begin(); it != proj.end(); ++it) (*it).replace(QRegExp("\\.[a-zA-Z0-9_]*$"), ""); // SUBSYSTEM ----------------------------------------------------- if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { project->variables()["MSVCPROJ_TEMPLATE"].append("win32app" + project->first( "VCPROJ_EXTENSION" ) ); if ( project->isActiveConfig("console") ) { project->variables()["MSVCPROJ_CONSOLE"].append("CONSOLE"); project->variables()["MSVCPROJ_WINCONDEF"].append("_CONSOLE"); project->variables()["MSVCPROJ_VCPROJTYPE"].append("0x0103"); project->variables()["MSVCPROJ_SUBSYSTEM"].append("CONSOLE"); } else { project->variables()["MSVCPROJ_CONSOLE"].clear(); project->variables()["MSVCPROJ_WINCONDEF"].append("_WINDOWS"); project->variables()["MSVCPROJ_VCPROJTYPE"].append("0x0101"); project->variables()["MSVCPROJ_SUBSYSTEM"].append("WINDOWS"); } } else { if ( project->isActiveConfig("dll") ) { project->variables()["MSVCPROJ_TEMPLATE"].append("win32dll" + project->first( "VCPROJ_EXTENSION" ) ); } else { project->variables()["MSVCPROJ_TEMPLATE"].append("win32lib" + project->first( "VCPROJ_EXTENSION" ) ); } } // $$QMAKE.. -> $$MSVCPROJ.. ------------------------------------- project->variables()["MSVCPROJ_LIBS"] += project->variables()["QMAKE_LIBS"]; project->variables()["MSVCPROJ_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"]; project->variables()["MSVCPROJ_LFLAGS" ] += project->variables()["QMAKE_LFLAGS"]; if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) { QStringList strl = project->variables()["QMAKE_LIBDIR"]; QStringList::iterator stri; for ( stri = strl.begin(); stri != strl.end(); ++stri ) { if ( !(*stri).startsWith("/LIBPATH:") ) (*stri).prepend( "/LIBPATH:" ); } project->variables()["MSVCPROJ_LFLAGS"] += strl; } project->variables()["MSVCPROJ_CXXFLAGS" ] += project->variables()["QMAKE_CXXFLAGS"]; // We don't use this... Direct manipulation of compiler object //project->variables()["MSVCPROJ_DEFINES"].append(varGlue("DEFINES","/D ","" " /D ","")); //project->variables()["MSVCPROJ_DEFINES"].append(varGlue("PRL_EXPORT_DEFINES","/D ","" " /D ","")); QStringList &incs = project->variables()["INCLUDEPATH"]; for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) { QString inc = (*incit); inc.replace(QRegExp("\""), ""); project->variables()["MSVCPROJ_INCPATH"].append("/I" + inc ); } project->variables()["MSVCPROJ_INCPATH"].append("/I" + specdir()); QString dest; project->variables()["MSVCPROJ_TARGET"] = project->first("TARGET"); Option::fixPathToTargetOS(project->first("TARGET")); dest = project->first("TARGET") + project->first( "TARGET_EXT" ); if ( project->first("TARGET").startsWith("$(QTDIR)") ) dest.replace( QRegExp("\\$\\(QTDIR\\)"), getenv("QTDIR") ); 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; - } // DLL COPY ------------------------------------------------------ if ( project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty() ) { 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 ); } // ACTIVEQT ------------------------------------------------------ if ( project->isActiveConfig("activeqt") ) { QString idl = project->variables()["QMAKE_IDL"].first(); QString idc = project->variables()["QMAKE_IDC"].first(); QString version = project->variables()["VERSION"].first(); if ( version.isEmpty() ) version = "1.0"; - 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" ) ) { QString regcmd = "# Begin Special Build Tool\n" "TargetPath=" + targetfilename + "\n" "SOURCE=$(InputPath)\n" "PostBuild_Desc=Finalizing ActiveQt server...\n" "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" "# End Special Build Tool"; QString executable = project->variables()["MSVCPROJ_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first(); project->variables()["MSVCPROJ_COPY_DLL_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) ); executable = project->variables()["MSVCPROJ_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first(); project->variables()["MSVCPROJ_COPY_DLL_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) ); } else { QString regcmd = "# Begin Special Build Tool\n" "TargetPath=" + targetfilename + "\n" "SOURCE=$(InputPath)\n" "PostBuild_Desc=Finalizing ActiveQt server...\n" "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" "# End Special Build Tool"; QString executable = project->variables()["MSVCPROJ_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first(); project->variables()["MSVCPROJ_REGSVR_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) ); executable = project->variables()["MSVCPROJ_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first(); project->variables()["MSVCPROJ_REGSVR_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) ); } - } + if ( !project->variables()["DEF_FILE"].isEmpty() ) + project->variables()["MSVCPROJ_LFLAGS"].append("/DEF:"+project->first("DEF_FILE")); + // FORMS --------------------------------------------------------- QStringList &list = project->variables()["FORMS"]; for( it = list.begin(); it != list.end(); ++it ) { if ( QFile::exists( *it + ".h" ) ) project->variables()["SOURCES"].append( *it + ".h" ); } project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCPROJ_LFLAGS" << "MSVCPROJ_LIBS"; // Verbose output if "-d -d"... outputVariables(); } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ bool VcprojGenerator::openOutput(QFile &file) const { QString outdir; if(!file.name().isEmpty()) { QFileInfo fi(file); if(fi.isDir()) outdir = file.name() + QDir::separator(); } if(!outdir.isEmpty() || file.name().isEmpty()) { QString ext = project->first("VCPROJ_EXTENSION"); if(project->first("TEMPLATE") == "vcsubdirs") ext = project->first("VCSOLUTION_EXTENSION"); file.setName(outdir + project->first("TARGET") + ext); } if(QDir::isRelativePath(file.name())) { file.setName( Option::fixPathToLocalOS(QDir::currentDirPath() + Option::dir_sep + fixFilename(file.name())) ); } return Win32MakefileGenerator::openOutput(file); } QString VcprojGenerator::fixFilename(QString ofile) const { int slashfind = ofile.findRev('\\'); if (slashfind == -1) { ofile = ofile.replace('-', '_'); } else { int hypenfind = ofile.find('-', slashfind); while (hypenfind != -1 && slashfind < hypenfind) { ofile = ofile.replace(hypenfind, 1, '_'); hypenfind = ofile.find('-', hypenfind + 1); } } return ofile; } QString VcprojGenerator::findTemplate(QString file) { QString ret; if(!QFile::exists((ret = file)) && !QFile::exists((ret = QString(Option::mkfile::qmakespec + "/" + file))) && !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/win32-msvc.net/" + file)) && !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file)))) return ""; debug_msg(1, "Generator: MSVC.NET: Found template \'%s\'", ret.latin1() ); return ret; } 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,115 +1,119 @@ + /**************************************************************************** -** $Id$ +** ** ** Definition of VcprojGenerator class. ** -** 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. ** ** 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 __MSVC_VCPROJ_H__ #define __MSVC_VCPROJ_H__ #include "winmakefile.h" #include "msvc_objectmodel.h" enum target { Application, SharedLib, StaticLib }; struct QUuid; class VcprojGenerator : public Win32MakefileGenerator { bool init_flag; bool writeVcprojParts(QTextStream &); bool writeMakefile(QTextStream &); virtual void writeSubDirs(QTextStream &t); QString findTemplate(QString file); void init(); public: VcprojGenerator(QMakeProject *p); ~VcprojGenerator(); QString defaultMakefile() const; virtual bool doDepends() const { return FALSE; } //never necesary + QString precompH, precompHFilename, + precompObj, precompPch; + bool usePCH; protected: virtual bool openOutput(QFile &file) const; virtual void processPrlVariable(const QString &, const QStringList &); virtual bool findLibraries(); virtual void outputVariables(); QString fixFilename(QString ofile) const; void initOld(); void initProject(); void initConfiguration(); void initCompilerTool(); void initLinkerTool(); void initLibrarianTool(); void initIDLTool(); void initCustomBuildTool(); void initPreBuildEventTools(); void initPostBuildEventTools(); void initPreLinkEventTools(); void initSourceFiles(); void initHeaderFiles(); void initMOCFiles(); void initUICFiles(); void initFormsFiles(); void initTranslationFiles(); void initLexYaccFiles(); void initResourceFiles(); VCProject vcProject; target projectTarget; private: + QUuid getProjectUUID(const QString &filename=QString::null); QUuid increaseUUID(const QUuid &id); friend class VCFilter; }; inline VcprojGenerator::~VcprojGenerator() { } inline QString VcprojGenerator::defaultMakefile() const { return project->first("TARGET") + project->first("VCPROJ_EXTENSION"); } inline bool VcprojGenerator::findLibraries() { return Win32MakefileGenerator::findLibraries("MSVCVCPROJ_LIBS"); } #endif /* __MSVC_VCPROJ_H__ */ 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,389 +1,464 @@ /**************************************************************************** -** $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. ** ** 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 "winmakefile.h" #include "option.h" #include "project.h" +#include "meta.h" #include <qtextstream.h> #include <qstring.h> #include <qdict.h> #include <qregexp.h> #include <qstringlist.h> #include <qdir.h> Win32MakefileGenerator::Win32MakefileGenerator(QMakeProject *p) : MakefileGenerator(p) { } struct SubDir { QString directory, profile, target, makefile; }; void Win32MakefileGenerator::writeSubDirs(QTextStream &t) { QPtrList<SubDir> subdirs; { QStringList subdirs_in = project->variables()["SUBDIRS"]; for(QStringList::Iterator it = subdirs_in.begin(); it != subdirs_in.end(); ++it) { QString file = (*it); file = fileFixify(file); SubDir *sd = new SubDir; subdirs.append(sd); sd->makefile = "$(MAKEFILE)"; if((*it).right(4) == ".pro") { int slsh = file.findRev(Option::dir_sep); if(slsh != -1) { sd->directory = file.left(slsh+1); sd->profile = file.mid(slsh+1); } else { sd->profile = file; } } else { sd->directory = file; } while(sd->directory.right(1) == Option::dir_sep) sd->directory = sd->directory.left(sd->directory.length() - 1); if(!sd->profile.isEmpty()) { QString basename = sd->directory; int new_slsh = basename.findRev(Option::dir_sep); if(new_slsh != -1) basename = basename.mid(new_slsh+1); if(sd->profile != basename + ".pro") sd->makefile += "." + sd->profile.left(sd->profile.length() - 4); //no need for the .pro } sd->target = "sub-" + (*it); sd->target.replace('/', '-'); sd->target.replace('.', '_'); } } QPtrListIterator<SubDir> it(subdirs); - 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; t << "SUBTARGETS = "; for( it.toFirst(); it.current(); ++it) t << " \\\n\t\t" << it.current()->target; t << endl << endl; - t << "all: qmake_all $(SUBTARGETS)" << endl << endl; + t << "all: $(MAKEFILE) $(SUBTARGETS)" << endl << endl; for( it.toFirst(); it.current(); ++it) { bool have_dir = !(*it)->directory.isEmpty(); //make the makefile QString mkfile = (*it)->makefile; if(have_dir) mkfile.prepend((*it)->directory + Option::dir_sep); t << mkfile << ":"; - if(project->variables()["QMAKE_NOFORCE"].isEmpty()) - t << " FORCE"; if(have_dir) t << "\n\t" << "cd " << (*it)->directory; t << "\n\t" << "$(QMAKE) " << (*it)->profile << " " << buildArgs(); t << " -o " << (*it)->makefile; if(have_dir) { int subLevels = it.current()->directory.contains(Option::dir_sep) + 1; t << "\n\t" << "@cd .."; for(int i = 1; i < subLevels; i++ ) t << Option::dir_sep << ".."; } t << endl; //now actually build t << (*it)->target << ": " << mkfile; if(project->variables()["QMAKE_NOFORCE"].isEmpty()) t << " FORCE"; if(have_dir) t << "\n\t" << "cd " << (*it)->directory; t << "\n\t" << "$(MAKE)"; t << " -f " << (*it)->makefile; if(have_dir) { int subLevels = it.current()->directory.contains(Option::dir_sep) + 1; t << "\n\t" << "@cd .."; for(int i = 1; i < subLevels; i++ ) t << Option::dir_sep << ".."; } t << endl << endl; } + 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) project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all"); writeMakeQmake(t); t << "qmake_all:"; if ( !subdirs.isEmpty() ) { for( it.toFirst(); it.current(); ++it) { QString subdir = (*it)->directory; QString profile = (*it)->profile; int subLevels = subdir.contains(Option::dir_sep) + 1; t << "\n\t" << "cd " << subdir << "\n\t"; int lastSlash = subdir.findRev(Option::dir_sep); if(lastSlash != -1) subdir = subdir.mid( lastSlash + 1 ); t << "$(QMAKE) " << ( !profile.isEmpty() ? profile : subdir + ".pro" ) << " -o " << (*it)->makefile << " " << buildArgs() << "\n\t" << "@cd .."; for(int i = 1; i < subLevels; i++ ) t << Option::dir_sep << ".."; } } else { // Borland make does not like empty an empty command section, so insert // a dummy command. t << "\n\t" << "@cd ."; } t << endl << endl; - 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()) { for( it.toFirst(); it.current(); ++it) { int subLevels = (*it)->directory.contains(Option::dir_sep) + 1; bool have_dir = !(*it)->directory.isEmpty(); if(have_dir) t << "\n\t" << "cd " << (*it)->directory; QString in_file = " -f " + (*it)->makefile; - t << "\n\t" << "$(MAKE) " << in_file << " " << targs[x]; + t << "\n\t" << "$(MAKE) " << in_file << " " << targ; if(have_dir) { t << "\n\t" << "@cd .."; for(int i = 1; i < subLevels; i++ ) t << Option::dir_sep << ".."; } } } else { // Borland make does not like empty an empty command section, so // insert a dummy command. t << "\n\t" << "@cd ."; } t << endl << endl; } + //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()) t << "FORCE:" << endl << endl; } int Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem) { QString bd = Option::fixPathToLocalOS(d, TRUE); if(!QFile::exists(bd)) return -1; if(!project->variables()["QMAKE_" + stem.upper() + "_VERSION_OVERRIDE"].isEmpty()) return project->variables()["QMAKE_" + stem.upper() + "_VERSION_OVERRIDE"].first().toInt(); QDir dir(bd); int biggest=-1; QStringList entries = dir.entryList(); QString dllStem = stem + QTDLL_POSTFIX; QRegExp regx( "(" + dllStem + "([0-9]*)).lib", FALSE ); for(QStringList::Iterator it = entries.begin(); it != entries.end(); ++it) { if(regx.exactMatch((*it))) biggest = QMAX(biggest, (regx.cap(1) == dllStem || regx.cap(2).isEmpty()) ? -1 : regx.cap(2).toInt()); } - 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()); } return biggest; } +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); +} bool Win32MakefileGenerator::findLibraries(const QString &where) { QStringList &l = project->variables()[where]; QPtrList<MakefileDependDir> dirs; { QStringList &libpaths = project->variables()["QMAKE_LIBDIR"]; for(QStringList::Iterator libpathit = libpaths.begin(); libpathit != libpaths.end(); ++libpathit) { QString r = (*libpathit), l = r; fixEnvVariables(l); dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } } dirs.setAutoDelete(TRUE); for(QStringList::Iterator it = l.begin(); it != l.end(); ) { QChar quote; bool modified_opt = FALSE, remove = FALSE; QString opt = (*it).stripWhiteSpace(); if((opt[0] == '\'' || opt[0] == '"') && opt[(int)opt.length()-1] == opt[0]) { quote = opt[0]; opt = opt.mid(1, opt.length()-2); } if(opt.startsWith("/LIBPATH:")) { QString r = opt.mid(9), l = Option::fixPathToLocalOS(r); dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } else if(opt.startsWith("-L") || opt.startsWith("/L")) { QString r = opt.mid(2), l = Option::fixPathToLocalOS(r); dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); remove = TRUE; //we eat this switch } else if(opt.startsWith("-l") || opt.startsWith("/l")) { QString lib = opt.right(opt.length() - 2), out; if(!lib.isEmpty()) { for(MakefileDependDir *mdd = dirs.first(); mdd; mdd = dirs.next() ) { QString extension; int ver = findHighestVersion(mdd->local_dir, lib); if(ver > 0) extension += QString::number(ver); 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)) { out = mdd->real_dir + Option::dir_sep + lib + extension; break; } } } if(out.isEmpty()) { remove = TRUE; //just eat it since we cannot find one.. } else { modified_opt = TRUE; (*it) = out; } } else if(!QFile::exists(Option::fixPathToLocalOS(opt))) { QPtrList<MakefileDependDir> lib_dirs; QString file = opt; int slsh = file.findRev(Option::dir_sep); if(slsh != -1) { QString r = file.left(slsh+1), l = r; fixEnvVariables(l); lib_dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); file = file.right(file.length() - slsh - 1); } else { lib_dirs = dirs; } - 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; } } } } } if(remove) { it = l.remove(it); } else { if(!quote.isNull() && modified_opt) (*it) = quote + (*it) + quote; ++it; } } return TRUE; } void Win32MakefileGenerator::processPrlFiles() { QDict<void> processed; QPtrList<MakefileDependDir> libdirs; libdirs.setAutoDelete(TRUE); { QStringList &libpaths = project->variables()["QMAKE_LIBDIR"]; for(QStringList::Iterator libpathit = libpaths.begin(); libpathit != libpaths.end(); ++libpathit) { QString r = (*libpathit), l = r; fixEnvVariables(l); libdirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } } for(bool ret = FALSE; TRUE; ret = FALSE) { //read in any prl files included.. QStringList l_out; QString where = "QMAKE_LIBS"; if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) where = project->first("QMAKE_INTERNAL_PRL_LIBS"); QStringList &l = project->variables()[where]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString opt = (*it); if(opt.startsWith("/")) { if(opt.startsWith("/LIBPATH:")) { QString r = opt.mid(9), l = r; fixEnvVariables(l); libdirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } } else { if(!processed[opt]) { if(processPrlFile(opt)) { processed.insert(opt, (void*)1); ret = TRUE; } else { for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { QString prl = mdd->local_dir + Option::dir_sep + opt; if(processed[prl]) { break; } else if(processPrlFile(prl)) { processed.insert(prl, (void*)1); ret = TRUE; 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,72 +1,72 @@ /**************************************************************************** -** $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. ** ** 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 __WINMAKEFILE_H__ #define __WINMAKEFILE_H__ #include "makefile.h" // In the Qt evaluation and educational version, we have a postfix in the // library name (e.g. qtmteval301.dll). QTDLL_POSTFIX is used for this. // A script modifies these lines when building eval/edu version, so be careful // when changing them. #ifndef QTDLL_POSTFIX #define QTDLL_POSTFIX "" #endif class Win32MakefileGenerator : public MakefileGenerator { protected: virtual void writeSubDirs(QTextStream &t); int findHighestVersion(const QString &dir, const QString &stem); bool findLibraries(const QString &); + QString findDependency(const QString &); virtual bool findLibraries(); virtual void processPrlFiles(); public: Win32MakefileGenerator(QMakeProject *p); ~Win32MakefileGenerator(); }; inline Win32MakefileGenerator::~Win32MakefileGenerator() { } inline bool Win32MakefileGenerator::findLibraries() { return findLibraries("QMAKE_LIBS"); } #endif /* __WINMAKEFILE_H__ */ 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,66 +1,66 @@ /**************************************************************************** -** $Id$ +** ** ** Definition of some private QDir functions. ** ** Created : 001106 ** ** Copyright (C) 2000 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 QDIR_P_H #define QDIR_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience // of qdir.cpp and qdir_*.cpp. // This header file may change from version to version without notice, // or even be removed. // // We mean it. // // #ifndef QT_H #include "qregexp.h" #include "qvaluelist.h" #endif // QT_H extern QValueList<QRegExp> qt_makeFilterList( const QString & ); extern bool qt_matchFilterList( const QValueList<QRegExp> &, const QString & ); extern int qt_cmp_si_sortSpec; #if defined(Q_C_CALLBACKS) extern "C" { #endif 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,133 +1,145 @@ /**************************************************************************** -** $Id$ +** ** ** Definition of QSettings related classes ** -** 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. ** ** 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_P_H #define QSETTINGS_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience // of QSettings. This header file may change from version to // version without notice, or even be removed. // // We mean it. // // #ifndef QT_H #include "qstringlist.h" #include "qmap.h" #include "qvaluestack.h" #endif // QT_H +#ifndef QT_NO_SETTINGS class QSettingsSysPrivate; // QSettingsGroup is a map of key/value pairs class QSettingsGroup : public QMap<QString,QString> { public: QSettingsGroup(); bool modified; }; // QSettingsHeading is a map of heading/group pairs class QSettingsHeading : public QMap<QString,QSettingsGroup> { public: QSettingsHeading::Iterator git; void read(const QString &); void parseLine(QTextStream &); }; class QSettingsPrivate { public: QSettingsPrivate( QSettings::Format format ); ~QSettingsPrivate(); QSettingsGroup readGroup(); void removeGroup(const QString &); void writeGroup(const QString &, const QString &); QDateTime modificationTime(); QStringList searchPaths; QMap<QString,QSettingsHeading> headings; QString group; QString heading; /*### static data brings threading trouble static QString *defProduct; static QString *defDomain; */ QValueStack<QString> groupStack; QString groupPrefix; bool groupDirty :1; bool modified :1; bool globalScope :1; #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) // system dependent implementations to use the // system specific setting database (ie. registry on Windows) QSettingsSysPrivate *sysd; void sysInit(); void sysClear(); #if !defined(Q_NO_BOOL_TYPE) bool sysWriteEntry( const QString &, bool ); #endif bool sysWriteEntry( const QString &, double ); bool sysWriteEntry( const QString &, int ); bool sysWriteEntry( const QString &, const QString & ); bool sysWriteEntry( const QString &, const QStringList & ); bool sysWriteEntry( const QString &, const QStringList &, const QChar& sep ); QStringList sysEntryList(const QString &) const; QStringList sysSubkeyList(const QString &) const; QStringList sysReadListEntry( const QString &, bool * = 0 ) const; QStringList sysReadListEntry( const QString &, const QChar& sep, bool * = 0 ) const; QString sysReadEntry( const QString &, const QString &def = QString::null, bool * = 0 ) const; int sysReadNumEntry( const QString &, int def = 0, bool * = 0 ) const; double sysReadDoubleEntry( const QString &, double def = 0, bool * = 0 ) const; bool sysReadBoolEntry( const QString &, bool def = 0, bool * = 0 ) const; bool sysRemoveEntry( const QString & ); bool sysSync(); void sysInsertSearchPath( QSettings::System, const QString & ); void sysRemoveSearchPath( QSettings::System, const QString & ); #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,520 +1,545 @@ /**************************************************************************** -** $Id$ +** ** ** Global type declarations and definitions ** ** Created : 920529 ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** 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 QGLOBAL_H #define QGLOBAL_H -#define QT_VERSION_STR "3.1.2" +#define QT_VERSION_STR "3.3.2" /* QT_VERSION is (major << 16) + (minor << 8) + patch. */ -#define QT_VERSION 0x030102 +#define QT_VERSION 0x030302 /* The operating system, must be one of: (Q_OS_x) MACX - Mac OS X MAC9 - Mac OS 9 + DARWIN - Darwin OS (Without Mac OS X) MSDOS - MS-DOS and Windows OS2 - OS/2 OS2EMX - XFree86 on OS/2 (not PM) WIN32 - Win32 (Windows 95/98/ME and Windows NT/2000/XP) CYGWIN - Cygwin SOLARIS - Sun Solaris HPUX - HP-UX ULTRIX - DEC Ultrix LINUX - Linux FREEBSD - FreeBSD NETBSD - NetBSD OPENBSD - OpenBSD BSDI - BSD/OS IRIX - SGI Irix OSF - HP Tru64 UNIX SCO - SCO OpenServer 5 UNIXWARE - UnixWare 7, Open UNIX 8 AIX - AIX HURD - GNU Hurd DGUX - DG/UX RELIANT - Reliant UNIX DYNIX - DYNIX/ptx QNX - QNX QNX6 - QNX RTP 6.1 LYNX - LynxOS BSD4 - Any BSD 4.4 system UNIX - Any UNIX BSD/SYSV system */ -#if defined(__APPLE__) && defined(__GNUC__) +#if defined(__DARWIN_X11__) +# define Q_OS_DARWIN +#elif defined(__APPLE__) && defined(__GNUC__) # define Q_OS_MACX #elif defined(__MACOSX__) # define Q_OS_MACX #elif defined(macintosh) # define Q_OS_MAC9 #elif defined(__CYGWIN__) # define Q_OS_CYGWIN #elif defined(MSDOS) || defined(_MSDOS) # define Q_OS_MSDOS #elif defined(__OS2__) # if defined(__EMX__) # define Q_OS_OS2EMX # else # define Q_OS_OS2 # endif #elif !defined(SAG_COM) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) # define Q_OS_WIN32 # define Q_OS_WIN64 #elif !defined(SAG_COM) && (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) # define Q_OS_WIN32 #elif defined(__MWERKS__) && defined(__INTEL__) # define Q_OS_WIN32 #elif defined(__sun) || defined(sun) # define Q_OS_SOLARIS #elif defined(hpux) || defined(__hpux) # define Q_OS_HPUX #elif defined(__ultrix) || defined(ultrix) # define Q_OS_ULTRIX #elif defined(sinix) # define Q_OS_RELIANT #elif defined(__linux__) || defined(__linux) # define Q_OS_LINUX -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__DragonFly__) # define Q_OS_FREEBSD # define Q_OS_BSD4 #elif defined(__NetBSD__) # define Q_OS_NETBSD # define Q_OS_BSD4 #elif defined(__OpenBSD__) # define Q_OS_OPENBSD # define Q_OS_BSD4 #elif defined(__bsdi__) # define Q_OS_BSDI # define Q_OS_BSD4 #elif defined(__sgi) # define Q_OS_IRIX #elif defined(__osf__) # define Q_OS_OSF #elif defined(_AIX) # define Q_OS_AIX #elif defined(__Lynx__) # define Q_OS_LYNX #elif defined(__GNU_HURD__) # define Q_OS_HURD #elif defined(__DGUX__) # define Q_OS_DGUX #elif defined(__QNXNTO__) # define Q_OS_QNX6 #elif defined(__QNX__) # define Q_OS_QNX #elif defined(_SEQUENT_) # define Q_OS_DYNIX #elif defined(_SCO_DS) /* SCO OpenServer 5 + GCC */ # define Q_OS_SCO #elif defined(__USLC__) /* all SCO platforms + UDK or OUDK */ # define Q_OS_UNIXWARE # define Q_OS_UNIXWARE7 #elif defined(__svr4__) && defined(i386) /* Open UNIX 8 + GCC */ # define Q_OS_UNIXWARE # define Q_OS_UNIXWARE7 +#elif defined(__MAKEDEPEND__) #else # error "Qt has not been ported to this OS - talk to qt-bugs@trolltech.com" #endif +#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 #elif !defined(Q_OS_UNIX) # define Q_OS_UNIX #endif /* The compiler, must be one of: (Q_CC_x) SYM - Symantec C++ for both PC and Macintosh MPW - MPW C++ MWERKS - Metrowerks CodeWarrior - MSVC - Microsoft Visual C/C++ + MSVC - Microsoft Visual C/C++, Intel C++ for Windows BOR - Borland/Turbo C++ WAT - Watcom C++ GNU - GNU C++ COMEAU - Comeau C++ EDG - Edison Design Group C++ OC - CenterLine C++ SUN - Sun WorkShop, Forte Developer, or Sun ONE Studio C++ MIPS - MIPSpro C++ DEC - DEC C++ HP - HPUX C++ HPACC - HPUX ANSI C++ USLC - SCO OUDK, UDK, and UnixWare 2.X C++ CDS - Reliant C++ KAI - KAI C++ - INTEL - Intel C++ + INTEL - Intel C++ for Linux, Intel C++ for Windows HIGHC - MetaWare High C/C++ PGI - Portland Group C++ GHS - Green Hills Optimizing C++ Compilers Should be sorted most to least authoritative. */ /* Symantec C++ is now Digital Mars */ #if defined(__DMC__) || defined(__SC__) # define Q_CC_SYM /* "explicit" semantics implemented in 8.1e but keyword recognized since 7.5 */ # if defined(__SC__) && __SC__ < 0x750 # define Q_NO_EXPLICIT_KEYWORD # endif # define Q_NO_USING_KEYWORD # if !defined(_CPPUNWIND) # define Q_NO_EXCEPTIONS # endif #elif defined(applec) # define Q_CC_MPW # define Q_NO_BOOL_TYPE # define Q_NO_EXPLICIT_KEYWORD # define Q_NO_USING_KEYWORD #elif defined(__MWERKS__) # define Q_CC_MWERKS /* "explicit" recognized since 4.0d1 */ # define QMAC_PASCAL pascal -# define Q_NO_USING_KEYWORD /* ### check "using" status */ #elif defined(_MSC_VER) # define Q_CC_MSVC /* proper support of bool for _MSC_VER >= 1100 */ # define Q_CANNOT_DELETE_CONSTANT # define Q_INLINE_TEMPLATES inline /* Visual C++.Net issues for _MSC_VER >= 1300 */ # if _MSC_VER >= 1300 # define Q_CC_MSVC_NET -# if _MSC_VER < 1310 +# if _MSC_VER < 1310 || defined(Q_OS_WIN64) # define Q_TYPENAME # endif # 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 #elif defined(__BORLANDC__) || defined(__TURBOC__) # define Q_CC_BOR # if __BORLANDC__ < 0x502 # define Q_NO_BOOL_TYPE # define Q_NO_EXPLICIT_KEYWORD # endif # define Q_NO_USING_KEYWORD /* ### check "using" status */ #elif defined(__WATCOMC__) # define Q_CC_WAT # if defined(Q_OS_QNX4) /* compiler flags */ # define Q_TYPENAME # define Q_NO_BOOL_TYPE # define Q_CANNOT_DELETE_CONSTANT # define mutable /* ??? */ # define Q_BROKEN_TEMPLATE_SPECIALIZATION /* no template classes in QVariant */ # define QT_NO_TEMPLATE_VARIANT /* Wcc does not fill in functions needed by valuelists, maps, and valuestacks implicitly */ # define Q_FULL_TEMPLATE_INSTANTIATION /* can we just compare the structures? */ # define Q_FULL_TEMPLATE_INSTANTIATION_MEMCMP /* these are not useful to our customers */ # define QT_QWS_NO_SHM # define QT_NO_QWS_MULTIPROCESS # define QT_NO_SQL # define QT_NO_QWS_CURSOR # endif #elif defined(__GNUC__) # define Q_CC_GNU # define Q_C_CALLBACKS # if __GNUC__ == 2 && __GNUC_MINOR__ <= 7 # define Q_FULL_TEMPLATE_INSTANTIATION # endif /* GCC 2.95 knows "using" but does not support it correctly */ # if __GNUC__ == 2 && __GNUC_MINOR__ <= 95 # define Q_NO_USING_KEYWORD # endif /* GCC 3.1 and GCC 3.2 wrongly define _SB_CTYPE_MACROS on HP-UX */ # if defined(Q_OS_HPUX) && __GNUC__ == 3 && __GNUC_MINOR__ >= 1 # define Q_WRONG_SB_CTYPE_MACROS # 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 # if !defined(__EXCEPTIONS) # define Q_NO_EXCEPTIONS # endif /* IBM compiler versions are a bit messy. There are actually two products: the C product, and the C++ product. The C++ compiler is always packaged with the latest version of the C compiler. Version numbers do not always match. This little table (I'm not sure it's accurate) should be helpful: C++ product C product C Set 3.1 C Compiler 3.0 ... ... C++ Compiler 3.6.6 C Compiler 4.3 ... ... Visual Age C++ 4.0 ... ... ... Visual Age C++ 5.0 C Compiler 5.0 + ... ... + Visual Age C++ 6.0 C Compiler 6.0 Now: __xlC__ is the version of the C compiler in hexadecimal notation is only an approximation of the C++ compiler version __IBMCPP__ is the version of the C++ compiler in decimal notation but it is not defined on older compilers like C Set 3.1 */ #elif defined(__xlC__) # define Q_CC_XLC # define Q_FULL_TEMPLATE_INSTANTIATION # if __xlC__ < 0x400 # define Q_NO_BOOL_TYPE # define Q_NO_EXPLICIT_KEYWORD # define Q_NO_USING_KEYWORD # define Q_TYPENAME # define Q_INLINE_TEMPLATES inline # define Q_BROKEN_TEMPLATE_SPECIALIZATION # define Q_CANNOT_DELETE_CONSTANT # endif /* Older versions of DEC C++ do not define __EDG__ or __EDG - observed on DEC C++ V5.5-004. New versions do define __EDG__ - observed on Compaq C++ V6.3-002. This compiler is different enough from other EDG compilers to handle it separately anyway. */ -#elif defined(__DECCXX) +#elif defined(__DECCXX) || defined(__DECC) # define Q_CC_DEC /* Compaq C++ V6 compilers are EDG-based but I'm not sure about older DEC C++ V5 compilers. */ # if defined(__EDG__) # define Q_CC_EDG # endif /* Compaq have disabled EDG's _BOOL macro and use _BOOL_EXISTS instead - observed on Compaq C++ V6.3-002. In any case versions prior to Compaq C++ V6.0-005 do not have bool. */ # if !defined(_BOOL_EXISTS) # define Q_NO_BOOL_TYPE # endif /* Spurious (?) error messages observed on Compaq C++ V6.5-014. */ # define Q_NO_USING_KEYWORD /* Apply to all versions prior to Compaq C++ V6.0-000 - observed on DEC C++ V5.5-004. */ # if __DECCXX_VER < 60060000 # define Q_TYPENAME # define Q_BROKEN_TEMPLATE_SPECIALIZATION # define Q_CANNOT_DELETE_CONSTANT # endif /* avoid undefined symbol problems with out-of-line template members */ # define Q_INLINE_TEMPLATES inline /* Compilers with EDG front end are similar. To detect them we test: __EDG documented by SGI, observed on MIPSpro 7.3.1.1 and KAI C++ 4.0b __EDG__ documented in EDG online docs, observed on Compaq C++ V6.3-002 */ #elif defined(__EDG) || defined(__EDG__) # define Q_CC_EDG /* From the EDG documentation (does not seem to apply to Compaq C++): _BOOL Defined in C++ mode when bool is a keyword. The name of this predefined macro is specified by a configuration flag. _BOOL is the default. __BOOL_DEFINED Defined in Microsoft C++ mode when bool is a keyword. */ # if !defined(_BOOL) && !defined(__BOOL_DEFINED) # define Q_NO_BOOL_TYPE # endif -/* 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__) # define Q_CC_COMEAU # define Q_C_CALLBACKS -/* 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) # define Q_CC_KAI # if !defined(_EXCEPTIONS) # define Q_NO_EXCEPTIONS # 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) # define Q_CC_INTEL # if !defined(__EXCEPTIONS) # define Q_NO_EXCEPTIONS # endif /* The Portland Group compiler is based on EDG and does define __EDG__ */ # elif defined(__PGI) # define Q_CC_PGI # if !defined(__EXCEPTIONS) # define Q_NO_EXCEPTIONS # endif /* Never tested! */ # elif defined(__ghs) # define Q_CC_GHS /* The UnixWare 7 UDK compiler is based on EDG and does define __EDG__ */ # elif defined(__USLC__) && defined(__SCO_VERSION__) # define Q_CC_USLC /* The latest UDK 7.1.1b does not need this, but previous versions do */ # if !defined(__SCO_VERSION__) || (__SCO_VERSION__ < 302200010) # define Q_INLINE_TEMPLATES inline # endif # define Q_NO_USING_KEYWORD /* ### check "using" status */ /* Never tested! */ # elif defined(CENTERLINE_CLPP) || defined(OBJECTCENTER) # define Q_CC_OC # define Q_NO_USING_KEYWORD /* CDS++ defines __EDG__ although this is not documented in the Reliant documentation. It also follows conventions like _BOOL and this documented */ # elif defined(sinix) # define Q_CC_CDS # define Q_NO_USING_KEYWORD # if defined(__cplusplus) && (__cplusplus < 2) /* Cfront C++ mode */ # define Q_NO_EXCEPTIONS # endif /* The MIPSpro compiler in o32 mode is based on EDG but disables features such as template specialization nevertheless */ # elif defined(__sgi) # define Q_CC_MIPS # if defined(_MIPS_SIM) && (_MIPS_SIM == _ABIO32) /* o32 ABI */ # define Q_TYPENAME # define Q_BROKEN_TEMPLATE_SPECIALIZATION -# define Q_STRICT_INLINING_RULES # define Q_NO_EXPLICIT_KEYWORD # define Q_INLINE_TEMPLATES inline # elif defined(_COMPILER_VERSION) && (_COMPILER_VERSION < 730) /* 7.2 */ # define Q_TYPENAME # define Q_BROKEN_TEMPLATE_SPECIALIZATION # endif # 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 /* The older UnixWare 2.X compiler? */ #elif defined(__USLC__) # define Q_CC_USLC # define Q_TYPENAME # define Q_NO_BOOL_TYPE # define Q_NO_EXPLICIT_KEYWORD # define Q_NO_USING_KEYWORD # define Q_INLINE_TEMPLATES inline /* Never tested! */ #elif defined(__HIGHC__) # define Q_CC_HIGHC -#elif defined(__SUNPRO_CC) +#elif defined(__SUNPRO_CC) || defined(__SUNPRO_C) # define Q_CC_SUN /* 5.0 compiler or better 'bool' is enabled by default but can be disabled using -features=nobool in which case _BOOL is not defined this is the default in 4.2 compatibility mode triggered by -compat=4 */ # if __SUNPRO_CC >= 0x500 # if !defined(_BOOL) # define Q_NO_BOOL_TYPE # endif # if defined(__SUNPRO_CC_COMPAT) && (__SUNPRO_CC_COMPAT <= 4) # define Q_NO_USING_KEYWORD # endif # define Q_C_CALLBACKS /* 4.2 compiler or older */ # else # define Q_NO_BOOL_TYPE # define Q_NO_EXPLICIT_KEYWORD # define Q_NO_USING_KEYWORD # endif /* CDS++ does not seem to define __EDG__ or __EDG according to Reliant documentation but nevertheless uses EDG conventions like _BOOL */ #elif defined(sinix) # define Q_CC_EDG # define Q_CC_CDS # if !defined(_BOOL) # define Q_NO_BOOL_TYPE # endif # define Q_BROKEN_TEMPLATE_SPECIALIZATION #elif defined(Q_OS_HPUX) /* __HP_aCC was not defined in first aCC releases */ # if defined(__HP_aCC) || __cplusplus >= 199707L # define Q_CC_HPACC # else # define Q_CC_HP # define Q_NO_BOOL_TYPE # define Q_FULL_TEMPLATE_INSTANTIATION # define Q_BROKEN_TEMPLATE_SPECIALIZATION # define Q_NO_EXPLICIT_KEYWORD # endif # define Q_NO_USING_KEYWORD /* ### check "using" status */ #else # error "Qt has not been tested with this compiler - talk to qt-bugs@trolltech.com" #endif #ifndef Q_PACKED # define Q_PACKED #endif /* The window system, must be one of: (Q_WS_x) MACX - Mac OS X MAC9 - Mac OS 9 QWS - Qt/Embedded WIN32 - Windows X11 - X Window System PM - unsupported WIN16 - unsupported */ @@ -544,407 +569,422 @@ # endif #endif #if defined(Q_OS_MAC) && !defined(QMAC_PASCAL) # define QMAC_PASCAL #endif #if defined(Q_WS_WIN16) || defined(Q_WS_WIN32) # define Q_WS_WIN #endif #if (defined(Q_WS_MAC9) || defined(Q_WS_MACX)) && !defined(Q_WS_QWS) && !defined(Q_WS_X11) # define Q_WS_MAC #endif /* Some classes do not permit copies to be made of an object. These classes contains a private copy constructor and operator= to disable copying (the compiler gives an error message). Undefine Q_DISABLE_COPY to turn off this checking. */ #define Q_DISABLE_COPY #if defined(__cplusplus) // // Useful type definitions for Qt // #if defined(Q_NO_BOOL_TYPE) #if defined(Q_CC_HP) // bool is an unsupported reserved keyword in later versions #define bool int #else typedef int bool; #endif #endif typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned uint; typedef unsigned long ulong; typedef char *pchar; typedef uchar *puchar; typedef const char *pcchar; // // Constant bool values // #ifndef TRUE const bool FALSE = 0; const bool TRUE = !0; #endif #if defined(__WATCOMC__) # if defined(Q_OS_QNX4) const bool false = FALSE; const bool true = TRUE; # endif #endif +// +// 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 // // Use the "explicit" keyword on platforms that support it. // #if !defined(Q_NO_EXPLICIT_KEYWORD) # define Q_EXPLICIT explicit #else # define Q_EXPLICIT #endif // // Workaround for static const members on MSVC++. // #if defined(Q_CC_MSVC) # define QT_STATIC_CONST static # define QT_STATIC_CONST_IMPL #else # define QT_STATIC_CONST static const # define QT_STATIC_CONST_IMPL const #endif // // Utility macros and inline functions // #define QMAX(a, b) ((b) < (a) ? (a) : (b)) #define QMIN(a, b) ((a) < (b) ? (a) : (b)) #define QABS(a) ((a) >= 0 ? (a) : -(a)) inline int qRound( double d ) { return d >= 0.0 ? int(d + 0.5) : int( d - ((int)d-1) + 0.5 ) + ((int)d-1); } // // Size-dependent types (architechture-dependent byte order) // #if !defined(QT_CLEAN_NAMESPACE) // source compatibility with Qt 1.x typedef signed char INT8; // 8 bit signed typedef unsigned char UINT8; // 8 bit unsigned typedef short INT16; // 16 bit signed typedef unsigned short UINT16; // 16 bit unsigned typedef int INT32; // 32 bit signed typedef unsigned int UINT32; // 32 bit unsigned #endif typedef signed char Q_INT8; // 8 bit signed typedef unsigned char Q_UINT8; // 8 bit unsigned typedef short Q_INT16; // 16 bit signed typedef unsigned short Q_UINT16; // 16 bit unsigned typedef int Q_INT32; // 32 bit signed 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 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 #if defined(Q_OS_MACX) && !defined(QT_LARGEFILE_SUPPORT) # define QT_LARGEFILE_SUPPORT 64 #endif #if defined(QT_LARGEFILE_SUPPORT) - typedef unsigned long long QtOffset; + typedef Q_ULLONG QtOffset; #else typedef Q_ULONG QtOffset; #endif // // Data stream functions is provided by many classes (defined in qdatastream.h) // class QDataStream; // // Feature subsetting // // Note that disabling some features will produce a libqt that is not // compatible with other libqt builds. Such modifications are only // supported on Qt/Embedded where reducing the library size is important // and where the application-suite is often a fixed set. // #if !defined(QT_MOC) #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 #endif #ifndef QT_BUILD_KEY #define QT_BUILD_KEY "unspecified" #endif // prune to local config #include "qmodules.h" +#ifndef QT_MODULE_DIALOGS +# define QT_NO_DIALOG +#endif #ifndef QT_MODULE_ICONVIEW # define QT_NO_ICONVIEW #endif #ifndef QT_MODULE_WORKSPACE # define QT_NO_WORKSPACE #endif #ifndef QT_MODULE_NETWORK #define QT_NO_NETWORK #endif #ifndef QT_MODULE_CANVAS # define QT_NO_CANVAS #endif #ifndef QT_MODULE_TABLE #define QT_NO_TABLE #endif #ifndef QT_MODULE_XML # define QT_NO_XML #endif #ifndef QT_MODULE_OPENGL # define QT_NO_OPENGL #endif #if !defined(QT_MODULE_SQL) # define QT_NO_SQL #endif #if defined(Q_WS_MAC9) //No need for menu merging # ifndef QMAC_QMENUBAR_NO_MERGE # define QMAC_QMENUBAR_NO_MERGE # endif //Mac9 does not use quartz # ifndef QMAC_NO_QUARTZ # define QMAC_NO_QUARTZ # endif # ifndef QMAC_QMENUBAR_NO_EVENT # define QMAC_QMENUBAR_NO_EVENT # endif #endif #if defined(Q_WS_MACX) //for no nobody uses quartz, just putting in first level hooks # ifndef QMAC_NO_QUARTZ # define QMAC_NO_QUARTZ # endif # ifndef QMAC_QMENUBAR_NO_EVENT # define QMAC_QMENUBAR_NO_EVENT # endif #endif #if !defined(Q_WS_QWS) && !defined(QT_NO_COP) # define QT_NO_COP #endif #ifndef QT_H -#include <qfeatures.h> -#endif // QT_H +#include "qfeatures.h" +#endif /* QT_H */ // // Create Qt DLL if QT_DLL is defined (Windows only) // or QT_SHARED is defined (Kylix only) // -#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) +#if defined(Q_OS_WIN) # if defined(QT_NODLL) # undef QT_MAKEDLL # undef QT_DLL # elif defined(QT_MAKEDLL) /* create a Qt DLL library */ # if defined(QT_DLL) # undef QT_DLL # endif # define Q_EXPORT __declspec(dllexport) # define Q_TEMPLATEDLL # define Q_TEMPLATE_EXTERN # undef Q_DISABLE_COPY /* avoid unresolved externals */ # elif defined(QT_DLL) /* use a Qt DLL library */ # define Q_EXPORT __declspec(dllimport) # define Q_TEMPLATEDLL # ifndef Q_TEMPLATE_EXTERN # if defined(Q_CC_MSVC_NET) # define Q_TEMPLATE_EXTERN extern # else # define Q_TEMPLATE_EXTERN # endif # endif # undef Q_DISABLE_COPY /* avoid unresolved externals */ # endif #elif defined(Q_OS_LINUX) && defined(Q_CC_BOR) # if defined(QT_SHARED) /* create a Qt shared library */ # define Q_EXPORT __declspec(dllexport) # define Q_TEMPLATEDLL # define Q_TEMPLATE_EXTERN # undef Q_DISABLE_COPY /* avoid unresolved externals */ # else # define Q_TEMPLATEDLL # define Q_TEMPLATE_EXTERN # undef Q_DISABLE_COPY /* avoid unresolved externals */ # endif #else # undef QT_MAKEDLL /* ignore these for other platforms */ # undef QT_DLL #endif #ifndef Q_EXPORT # define Q_EXPORT #endif // // Some platform specific stuff // #if defined(Q_WS_WIN) extern Q_EXPORT bool qt_winunicode; #endif // // System information // Q_EXPORT const char *qVersion(); Q_EXPORT bool qSysInfo( int *wordSize, bool *bigEndian ); +Q_EXPORT bool qSharedBuild(); #if defined(Q_OS_MAC) int qMacVersion(); #elif defined(Q_WS_WIN) Q_EXPORT int qWinVersion(); #if defined(UNICODE) #define QT_WA( uni, ansi ) if ( qt_winunicode ) { uni } else { ansi } #define QT_WA_INLINE( uni, ansi ) ( qt_winunicode ? uni : ansi ) #else #define QT_WA( uni, ansi ) ansi #define QT_WA_INLINE( uni, ansi ) ansi #endif #endif #ifdef Q_OS_TEMP #ifdef QT_WA #undef QT_WA #undef QT_WA_INLINE #endif #define QT_WA( uni, ansi ) uni #define QT_WA_INLINE( uni, ansi ) ( uni ) #endif #ifndef Q_INLINE_TEMPLATES # define Q_INLINE_TEMPLATES #endif #ifndef Q_TYPENAME # define Q_TYPENAME typename #endif // // Use to avoid "unused parameter" warnings // - #define Q_UNUSED(x) (void)x; // // Debugging and error handling // #if !defined(QT_NO_CHECK) # define QT_CHECK_STATE // check state of objects etc. # define QT_CHECK_RANGE // check range of indexes etc. # define QT_CHECK_NULL // check null pointers # define QT_CHECK_MATH // check math functions #endif #if !defined(QT_NO_DEBUG) && !defined(QT_DEBUG) # define QT_DEBUG // display debug messages # if !defined(QT_NO_COMPAT) // compatibility with Qt 2 # if !defined(NO_DEBUG) && !defined(DEBUG) # if !defined(Q_OS_MACX) // clash with MacOS X headers # define DEBUG # endif # endif # endif #endif Q_EXPORT void qDebug( const char *, ... ) // print debug message #if defined(Q_CC_GNU) && !defined(__INSURE__) __attribute__ ((format (printf, 1, 2))) #endif ; Q_EXPORT void qWarning( const char *, ... ) // print warning message #if defined(Q_CC_GNU) && !defined(__INSURE__) __attribute__ ((format (printf, 1, 2))) #endif ; Q_EXPORT void qFatal( const char *, ... ) // print fatal message and exit #if defined(Q_CC_GNU) __attribute__ ((format (printf, 1, 2))) #endif ; Q_EXPORT void qSystemWarning( const char *, int code = -1 ); #if !defined(QT_CLEAN_NAMESPACE) // compatibility with Qt 1 Q_EXPORT void debug( const char *, ... ) // print debug message #if defined(Q_CC_GNU) && !defined(__INSURE__) __attribute__ ((format (printf, 1, 2))) #endif ; Q_EXPORT void warning( const char *, ... ) // print warning message #if defined(Q_CC_GNU) && !defined(__INSURE__) __attribute__ ((format (printf, 1, 2))) #endif ; Q_EXPORT void fatal( const char *, ... ) // print fatal message and exit #if defined(Q_CC_GNU) && !defined(__INSURE__) __attribute__ ((format (printf, 1, 2))) #endif ; @@ -954,119 +994,122 @@ Q_EXPORT void fatal( const char *, ... ) // print fatal message and exit #if !defined(Q_ASSERT) # if defined(QT_CHECK_STATE) # if defined(QT_FATAL_ASSERT) # define Q_ASSERT(x) ((x) ? (void)0 : qFatal("ASSERT: \"%s\" in %s (%d)",#x,__FILE__,__LINE__)) # else # define Q_ASSERT(x) ((x) ? (void)0 : qWarning("ASSERT: \"%s\" in %s (%d)",#x,__FILE__,__LINE__)) # endif # else # define Q_ASSERT(x) # endif #endif #if !defined(QT_NO_COMPAT) // compatibility with Qt 2 # if !defined(ASSERT) # if !defined(Q_OS_TEMP) # define ASSERT(x) Q_ASSERT(x) # endif # endif #endif // QT_NO_COMPAT Q_EXPORT bool qt_check_pointer( bool c, const char *, int ); #if defined(QT_CHECK_NULL) # define Q_CHECK_PTR(p) (qt_check_pointer((p)==0,__FILE__,__LINE__)) #else # define Q_CHECK_PTR(p) #endif #if !defined(QT_NO_COMPAT) // compatibility with Qt 2 # if !defined(CHECK_PTR) # define CHECK_PTR(x) Q_CHECK_PTR(x) # endif #endif // QT_NO_COMPAT enum QtMsgType { QtDebugMsg, QtWarningMsg, QtFatalMsg }; typedef void (*QtMsgHandler)(QtMsgType, const char *); Q_EXPORT QtMsgHandler qInstallMsgHandler( QtMsgHandler ); #if !defined(QT_NO_COMPAT) // compatibility with Qt 2 typedef QtMsgHandler msg_handler; #endif // QT_NO_COMPAT Q_EXPORT void qSuppressObsoleteWarnings( bool = TRUE ); Q_EXPORT void qObsolete( const char *obj, const char *oldfunc, const char *newfunc ); Q_EXPORT void qObsolete( const char *obj, const char *oldfunc ); Q_EXPORT void qObsolete( const char *message ); // // Install paths from configure // Q_EXPORT const char *qInstallPath(); Q_EXPORT const char *qInstallPathDocs(); Q_EXPORT const char *qInstallPathHeaders(); Q_EXPORT const char *qInstallPathLibs(); Q_EXPORT const char *qInstallPathBins(); 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 # define Q_DUMMY_COMPARISON_OPERATOR(C) \ bool operator==( const C& ) const { \ qWarning( #C"::operator==( const "#C"& ) got called." ); \ return FALSE; \ } #else # define Q_DUMMY_COMPARISON_OPERATOR(C) #endif -#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" +*/ #if !defined(QT_CC_WARNINGS) # define QT_NO_WARNINGS #endif #if defined(QT_NO_WARNINGS) # if defined(Q_CC_MSVC) # pragma warning(disable: 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data # pragma warning(disable: 4275) // non - DLL-interface classkey 'identifier' used as base for DLL-interface classkey 'identifier' # pragma warning(disable: 4514) // unreferenced inline/local function has been removed # pragma warning(disable: 4800) // 'type' : forcing value to bool 'true' or 'false' (performance warning) # pragma warning(disable: 4097) // typedef-name 'identifier1' used as synonym for class-name 'identifier2' # pragma warning(disable: 4706) // assignment within conditional expression # pragma warning(disable: 4786) // truncating debug info after 255 characters # pragma warning(disable: 4660) // template-class specialization 'identifier' is already instantiated # pragma warning(disable: 4355) // 'this' : used in base member initializer list # pragma warning(disable: 4231) // nonstandard extension used : 'extern' before template explicit instantiation # pragma warning(disable: 4710) // function not inlined # elif defined(Q_CC_BOR) # pragma option -w-inl # pragma option -w-aus # pragma warn -inl # pragma warn -pia # pragma warn -ccc # pragma warn -rch # 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,168 +1,191 @@ /**************************************************************************** -** $Id$ +** ** ** Definition of QUuid class ** ** Created : 010523 ** ** 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 QUUID_H #define QUUID_H #ifndef QT_H -#include <qstring.h> +#include "qstring.h" #endif // QT_H #include <string.h> #if defined(Q_OS_WIN32) #ifndef GUID_DEFINED #define GUID_DEFINED typedef struct _GUID { ulong Data1; ushort Data2; ushort Data3; uchar Data4[ 8 ]; } GUID, *REFGUID, *LPGUID; #endif #endif + 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() { memset( this, 0, sizeof(QUuid) ); } QUuid( uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3, uchar b4, uchar b5, uchar b6, uchar b7, uchar b8 ) { data1 = l; data2 = w1; data3 = w2; data4[0] = b1; data4[1] = b2; data4[2] = b3; data4[3] = b4; data4[4] = b5; data4[5] = b6; data4[6] = b7; data4[7] = b8; } QUuid( const QUuid &uuid ) { memcpy( this, &uuid, sizeof(QUuid) ); } #ifndef QT_NO_QUUID_STRING QUuid( const QString & ); QUuid( const char * ); QString toString() const; operator QString() const { return toString(); } #endif bool isNull() const; QUuid &operator=(const QUuid &orig ) { memcpy( this, &orig, sizeof(QUuid) ); return *this; } bool operator==(const QUuid &orig ) const { uint i; if ( data1 != orig.data1 || data2 != orig.data2 || data3 != orig.data3 ) return FALSE; for( i = 0; i < 8; i++ ) if ( data4[i] != orig.data4[i] ) return FALSE; return TRUE; } bool operator!=(const QUuid &orig ) const { return !( *this == orig ); } + bool operator<(const QUuid &other ) const; + bool operator>(const QUuid &other ) const; + #if defined(Q_OS_WIN32) // On Windows we have a type GUID that is used by the platform API, so we // provide convenience operators to cast from and to this type. QUuid( const GUID &guid ) { memcpy( this, &guid, sizeof(GUID) ); } QUuid &operator=(const GUID &orig ) { memcpy( this, &orig, sizeof(QUuid) ); return *this; } operator GUID() const { GUID guid = { data1, data2, data3, { data4[0], data4[1], data4[2], data4[3], data4[4], data4[5], data4[6], data4[7] } }; return guid; } bool operator==( const GUID &guid ) const { uint i; if ( data1 != guid.Data1 || data2 != guid.Data2 || data3 != guid.Data3 ) return FALSE; for( i = 0; i < 8; i++ ) if ( data4[i] != guid.Data4[i] ) return FALSE; return TRUE; } bool operator!=( const GUID &guid ) const { return !( *this == guid ); } #endif + static QUuid createUuid(); + QUuid::Variant variant() const; + QUuid::Version version() const; uint data1; ushort data2; ushort data3; uchar data4[ 8 ]; }; #ifndef QT_NO_DATASTREAM Q_EXPORT QDataStream &operator<<( QDataStream &, const QUuid & ); Q_EXPORT QDataStream &operator>>( QDataStream &, QUuid & ); #endif #endif //QUUID_H diff --git a/qmake/main.cpp b/qmake/main.cpp index cc2d08a..a731314 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -1,158 +1,183 @@ /**************************************************************************** -** $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. ** ** 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 "project.h" +#include "property.h" #include "option.h" #include "makefile.h" #include <qnamespace.h> #include <qregexp.h> #include <qdir.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> // for Borland, main is defined to qMain which breaks qmake #undef main +#ifdef Q_OS_MAC +// for qurl +bool qt_resolve_symlinks = FALSE; +#endif int main(int argc, char **argv) { /* parse command line */ if(!Option::parseCommandLine(argc, argv)) return 666; QDir sunworkshop42workaround = QDir::current(); 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; QStringList files; if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) files << "(*hack*)"; //we don't even use files, but we do the for() body once else files = Option::mkfile::project_files; for(QStringList::Iterator pfile = files.begin(); pfile != files.end(); pfile++) { if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { - QString fn = (*pfile); + QString fn = Option::fixPathToLocalOS((*pfile)); //setup pwd properly debug_msg(1, "Resetting dir to: %s", oldpwd.latin1()); QDir::setCurrent(oldpwd); //reset the old pwd int di = fn.findRev(Option::dir_sep); if(di != -1) { 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()); fn = fn.right(fn.length() - di - 1); } /* read project.. */ if(!proj.read(fn, oldpwd)) { fprintf(stderr, "Error processing project file: %s\n", fn == "-" ? "(stdin)" : (*pfile).latin1()); exit_val = 2; continue; } if(Option::mkfile::do_preprocess) //no need to create makefile continue; /* let Option post-process */ if(!Option::postProcessProject(&proj)) { fprintf(stderr, "Error post-processing project file: %s", fn == "-" ? "(stdin)" : (*pfile).latin1()); exit_val = 8; continue; } } bool using_stdout = FALSE; MakefileGenerator *mkfile = MakefileGenerator::create(&proj); //figure out generator if(mkfile && (Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)) { //open output if(!(Option::output.state() & IO_Open)) { if(Option::output.name() == "-") { Option::output.setName(""); Option::output_dir = QDir::currentDirPath(); Option::output.open(IO_WriteOnly | IO_Translate, stdout); using_stdout = TRUE; } else { if(Option::output.name().isEmpty() && Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE) Option::output.setName(proj.first("QMAKE_MAKEFILE")); + Option::output_dir = oldpwd; if(!mkfile->openOutput(Option::output)) { fprintf(stderr, "Failure to open file: %s\n", Option::output.name().isEmpty() ? "(stdout)" : Option::output.name().latin1()); return 5; } } } } else { using_stdout = TRUE; //kind of.. } if(mkfile && !mkfile->write()) { if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) fprintf(stderr, "Unable to generate project file.\n"); else fprintf(stderr, "Unable to generate makefile for: %s\n", (*pfile).latin1()); if(!using_stdout) QFile::remove(Option::output.name()); exit_val = 6; } delete mkfile; mkfile = NULL; /* debugging */ if(Option::debug_level) { QMap<QString, QStringList> &vars = proj.variables(); 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()); } } } return exit_val; } 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,463 +1,504 @@ /**************************************************************************** -** $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. ** ** 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 "option.h" #include <qdir.h> #include <qregexp.h> #include <stdlib.h> #include <stdarg.h> //convenience 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; QString Option::obj_ext; QString Option::lex_ext; 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; QString Option::lex_mod; //mode Option::QMAKE_MODE Option::qmake_mode = Option::QMAKE_GENERATE_NOTHING; //all modes int Option::warn_level = WarnLogic; int Option::debug_level = 0; QFile Option::output; QString Option::output_dir; QStringList Option::before_user_vars; QStringList Option::after_user_vars; QString Option::user_template; QString Option::user_template_prefix; #if defined(Q_OS_WIN32) Option::TARG_MODE Option::target_mode = Option::TARG_WIN_MODE; #elif defined(Q_OS_MAC9) Option::TARG_MODE Option::target_mode = Option::TARG_MAC9_MODE; #elif defined(Q_OS_MACX) Option::TARG_MODE Option::target_mode = Option::TARG_MACX_MODE; #elif defined(Q_OS_QNX6) Option::TARG_MODE Option::target_mode = Option::TARG_QNX6_MODE; #else Option::TARG_MODE Option::target_mode = Option::TARG_UNIX_MODE; #endif +//QMAKE_*_PROPERTY stuff +QStringList Option::prop::properties; + //QMAKE_GENERATE_PROJECT stuff bool Option::projfile::do_pwd = TRUE; bool Option::projfile::do_recursive = TRUE; QStringList Option::projfile::project_dirs; //QMAKE_GENERATE_MAKEFILE stuff QString Option::mkfile::qmakespec; int Option::mkfile::cachefile_depth = -1; bool Option::mkfile::do_deps = TRUE; bool Option::mkfile::do_mocs = TRUE; bool Option::mkfile::do_dep_heuristics = TRUE; bool Option::mkfile::do_preprocess = FALSE; bool Option::mkfile::do_cache = TRUE; QString Option::mkfile::cachefile; QStringList Option::mkfile::project_files; QString Option::mkfile::qmakespec_commandline; static Option::QMAKE_MODE default_mode(QString progname) { int s = progname.findRev(Option::dir_sep); if(s != -1) progname = progname.right(progname.length() - (s + 1)); if(progname == "qmakegen") return Option::QMAKE_GENERATE_PROJECT; + else if(progname == "qt-config") + return Option::QMAKE_QUERY_PROPERTY; return Option::QMAKE_GENERATE_MAKEFILE; } QString project_builtin_regx(); bool usage(const char *a0) { fprintf(stdout, "Usage: %s [mode] [options] [files]\n" "\n" " QMake has two modes, one mode for generating project files based on\n" "some heuristics, and the other for generating makefiles. Normally you\n" "shouldn't need to specify a mode, as makefile generation is the default\n" "mode for qmake, but you may use this to test qmake on an existing project\n" "\n" "Mode:\n" "\t-project Put qmake into project file generation mode%s\n" "\t In this mode qmake interprets files as files to\n" "\t be built,\n" "\t defaults to %s\n" "\t-makefile Put qmake into makefile generation mode%s\n" "\t In this mode qmake interprets files as project files to\n" "\t be processed, if skipped qmake will try to find a project\n" "\t file in your current working directory\n" "\n" "Warnings Options:\n" "\t-Wnone Turn off all warnings\n" "\t-Wall Turn on all warnings\n" "\t-Wparser Turn on parser warnings\n" "\t-Wlogic Turn on logic warnings\n" "\n" "Options:\n" "\t * You can place any variable assignment in options and it will be *\n" "\t * processed as if it was in [files]. These assignments will be parsed *\n" "\t * before [files]. *\n" "\t-o file Write output to file\n" "\t-unix Run in unix mode\n" "\t-win32 Run in win32 mode\n" "\t-macx Run in Mac OS X mode\n" "\t-d Increase debug level\n" "\t-t templ Overrides TEMPLATE as templ\n" "\t-tp prefix Overrides TEMPLATE so that prefix is prefixed into the value\n" "\t-help This help\n" "\t-v Version information\n" "\t-after All variable assignments after this will be\n" "\t parsed after [files]\n" "\t-cache file Use file as cache [makefile mode only]\n" "\t-spec spec Use spec as QMAKESPEC [makefile mode only]\n" "\t-nocache Don't use a cache file [makefile mode only]\n" "\t-nodepend Don't generate dependencies [makefile mode only]\n" "\t-nomoc Don't generate moc targets [makefile mode only]\n" "\t-nopwd Don't look for files in pwd [ project mode only]\n" "\t-norecursive Don't do a recursive search [ project mode only]\n" ,a0, default_mode(a0) == Option::QMAKE_GENERATE_PROJECT ? " (default)" : "", project_builtin_regx().latin1(), default_mode(a0) == Option::QMAKE_GENERATE_MAKEFILE ? " (default)" : ""); return FALSE; } -bool +enum { + QMAKE_CMDLINE_SUCCESS, + QMAKE_CMDLINE_SHOW_USAGE, + QMAKE_CMDLINE_BAIL +}; +int Option::internalParseCommandLine(int argc, char **argv, int skip) { bool before = TRUE; for(int x = skip; x < argc; x++) { if(*argv[x] == '-' && strlen(argv[x]) > 1) { /* options */ QString opt = argv[x] + 1; //first param is a mode, or we default if(x == 1) { bool specified = TRUE; if(opt == "project") { Option::qmake_mode = Option::QMAKE_GENERATE_PROJECT; } else if(opt == "prl") { Option::mkfile::do_deps = FALSE; Option::mkfile::do_mocs = FALSE; 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") { Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE; } else { specified = FALSE; } if(specified) continue; } //all modes if(opt == "o" || opt == "output") { Option::output.setName(argv[++x]); } else if(opt == "after") { before = FALSE; } else if(opt == "t" || opt == "template") { Option::user_template = argv[++x]; } else if(opt == "tp" || opt == "template_prefix") { Option::user_template_prefix = argv[++x]; } else if(opt == "mac9") { Option::target_mode = TARG_MAC9_MODE; } else if(opt == "macx") { Option::target_mode = TARG_MACX_MODE; } else if(opt == "unix") { Option::target_mode = TARG_UNIX_MODE; } else if(opt == "win32") { Option::target_mode = TARG_WIN_MODE; } else if(opt == "d") { Option::debug_level++; } else if(opt == "version" || opt == "v" || opt == "-version") { fprintf(stderr, "Qmake version: %s (Qt %s)\n", qmake_version(), QT_VERSION_STR); 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") { Option::warn_level |= WarnAll; } else if(opt == "Wparser") { Option::warn_level |= WarnParser; } else if(opt == "Wlogic") { Option::warn_level |= WarnLogic; } else if(opt == "Wnone") { Option::warn_level = WarnNone; } else { if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { if(opt == "nodepend") { Option::mkfile::do_deps = FALSE; } else if(opt == "nomoc") { Option::mkfile::do_mocs = FALSE; } else if(opt == "nocache") { Option::mkfile::do_cache = FALSE; } else if(opt == "nodependheuristics") { Option::mkfile::do_dep_heuristics = FALSE; } else if(opt == "E") { Option::mkfile::do_preprocess = TRUE; } else if(opt == "cache") { Option::mkfile::cachefile = argv[++x]; } else if(opt == "platform" || opt == "spec") { Option::mkfile::qmakespec = argv[++x]; Option::mkfile::qmakespec_commandline = argv[x]; } else { fprintf(stderr, "***Unknown option -%s\n", opt.latin1()); - return usage(argv[0]); + return QMAKE_CMDLINE_SHOW_USAGE; } } else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) { if(opt == "nopwd") { Option::projfile::do_pwd = FALSE; } else if(opt == "r") { Option::projfile::do_recursive = TRUE; } else if(opt == "norecursive") { Option::projfile::do_recursive = FALSE; } else { fprintf(stderr, "***Unknown option -%s\n", opt.latin1()); - return FALSE; + return QMAKE_CMDLINE_SHOW_USAGE; } } } } else { QString arg = argv[x]; if(arg.find('=') != -1) { if(before) Option::before_user_vars.append(arg); else Option::after_user_vars.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 - 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; } } } - return TRUE; + return QMAKE_CMDLINE_SUCCESS; } bool Option::parseCommandLine(int argc, char **argv) { - Option::moc_mod = "moc_"; + Option::cpp_moc_mod = ""; + Option::h_moc_mod = "moc_"; Option::lex_mod = "_lex"; Option::yacc_mod = "_yacc"; Option::prl_ext = ".prl"; + Option::libtool_ext = ".la"; + Option::pkgcfg_ext = ".pc"; Option::prf_ext = ".prf"; Option::ui_ext = ".ui"; 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"; Option::lex_ext = ".l"; Option::yacc_ext = ".y"; if(Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING) Option::qmake_mode = default_mode(argv[0]); if(const char *envflags = getenv("QMAKEFLAGS")) { int env_argc = 0, env_size = 0, currlen=0; char quote = 0, **env_argv = NULL; for(int i = 0; envflags[i]; i++) { if(!quote && (envflags[i] == '\'' || envflags[i] == '"')) { quote = envflags[i]; } else if(envflags[i] == quote) { quote = 0; } else if(!quote && envflags[i] == ' ') { if(currlen && env_argv && env_argv[env_argc]) { env_argv[env_argc][currlen] = '\0'; currlen = 0; env_argc++; } } else { if(!env_argv || env_argc > env_size) { env_argv = (char **)realloc(env_argv, sizeof(char *)*(env_size+=10)); for(int i2 = env_argc; i2 < env_size; i2++) env_argv[i2] = NULL; } if(!env_argv[env_argc]) { currlen = 0; env_argv[env_argc] = (char*)malloc(255); } if(currlen < 255) env_argv[env_argc][currlen++] = envflags[i]; } } if(env_argv[env_argc]) { env_argv[env_argc][currlen] = '\0'; currlen = 0; env_argc++; } internalParseCommandLine(env_argc, env_argv); for(int i2 = 0; i2 < env_size; i2++) { if(env_argv[i2]) free(env_argv[i2]); } free(env_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; + } //last chance for defaults if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { if(Option::mkfile::qmakespec.isNull() || Option::mkfile::qmakespec.isEmpty()) Option::mkfile::qmakespec = getenv("QMAKESPEC"); //try REALLY hard to do it for them, lazy.. if(Option::mkfile::project_files.isEmpty()) { QString pwd = QDir::currentDirPath(), proj = pwd + "/" + pwd.right(pwd.length() - (pwd.findRev('/') + 1)) + ".pro"; if(QFile::exists(proj)) { Option::mkfile::project_files.append(proj); } else { //last try.. QDir d(pwd, "*.pro"); if(d.count() != 1) return usage(argv[0]); Option::mkfile::project_files.append(pwd + "/" + d[0]); } } } //defaults for globals if(Option::target_mode == Option::TARG_WIN_MODE) { Option::dir_sep = "\\"; Option::obj_ext = ".obj"; } else { if(Option::target_mode == Option::TARG_MAC9_MODE) Option::dir_sep = ":"; else Option::dir_sep = "/"; Option::obj_ext = ".o"; } return TRUE; } bool Option::postProcessProject(QMakeProject *project) { Option::cpp_ext = project->variables()["QMAKE_EXT_CPP"]; if(cpp_ext.isEmpty()) cpp_ext << ".cpp"; //something must be there Option::h_ext = project->variables()["QMAKE_EXT_H"]; if(h_ext.isEmpty()) h_ext << ".h"; + 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")) Option::prl_ext = project->first("QMAKE_EXT_PRL"); if(!project->isEmpty("QMAKE_EXT_PRF")) Option::prf_ext = project->first("QMAKE_EXT_PRF"); if(!project->isEmpty("QMAKE_EXT_UI")) 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")) Option::lex_ext = project->first("QMAKE_EXT_LEX"); if(!project->isEmpty("QMAKE_EXT_YACC")) Option::yacc_ext = project->first("QMAKE_EXT_YACC"); if(!project->isEmpty("QMAKE_EXT_OBJ")) 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")) Option::lex_mod = project->first("QMAKE_MOD_LEX"); if(!project->isEmpty("QMAKE_MOD_YACC")) Option::yacc_mod = project->first("QMAKE_MOD_YACC"); if(!project->isEmpty("QMAKE_DIR_SEP")) Option::dir_sep = project->first("QMAKE_DIR_SEP"); return TRUE; } void fixEnvVariables(QString &x) { int rep; QRegExp reg_var("\\$\\(.*\\)"); reg_var.setMinimal( TRUE ); while((rep = reg_var.search(x)) != -1) x.replace(rep, reg_var.matchedLength(), QString(getenv(x.mid(rep + 2, reg_var.matchedLength() - 3).latin1()))); } static QString fixPath(QString x) { #if 0 QFileInfo fi(x); if(fi.isDir()) { QDir dir(x); x = dir.canonicalPath(); } else { QString dir = fi.dir().canonicalPath(); if(!dir.isEmpty() && dir.right(1) != Option::dir_sep) dir += Option::dir_sep; x = dir + fi.fileName(); } #endif return QDir::cleanDirPath(x); } QString Option::fixPathToTargetOS(const QString& in, bool fix_env, bool canonical) { QString tmp(in); if(fix_env) fixEnvVariables(tmp); if(canonical) tmp = fixPath(tmp); QString rep; if(Option::target_mode == TARG_MAC9_MODE) tmp = tmp.replace('/', Option::dir_sep).replace('\\', Option::dir_sep); else if(Option::target_mode == TARG_WIN_MODE) tmp = tmp.replace('/', Option::dir_sep); else tmp = tmp.replace('\\', Option::dir_sep); return tmp; } QString Option::fixPathToLocalOS(const QString& in, bool fix_env, bool canonical) { QString tmp(in); if(fix_env) fixEnvVariables(tmp); if(canonical) tmp = fixPath(tmp); #if defined(Q_OS_WIN32) return tmp.replace('/', '\\'); #else diff --git a/qmake/option.h b/qmake/option.h index 8bd348e..6197605 100644 --- a/qmake/option.h +++ b/qmake/option.h @@ -1,125 +1,134 @@ /**************************************************************************** -** $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. ** ** 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 __OPTION_H__ #define __OPTION_H__ #include "project.h" #include <qstring.h> #include <qstringlist.h> #include <qfile.h> #define QMAKE_VERSION_MAJOR 1 -#define QMAKE_VERSION_MINOR 5 +#define QMAKE_VERSION_MINOR 7 #define QMAKE_VERSION_PATCH 0 const char *qmake_version(); void fixEnvVariables(QString &x); void debug_msg(int level, const char *fmt, ...); enum QMakeWarn { WarnNone = 0x00, WarnParser = 0x01, WarnLogic = 0x02, WarnAll = 0xFF }; void warn_msg(QMakeWarn t, const char *fmt, ...); struct Option { //simply global convenience + static QString libtool_ext; + static QString pkgcfg_ext; static QString prf_ext; static QString prl_ext; static QString ui_ext; static QStringList h_ext; static QStringList cpp_ext; - static QString moc_ext; + static QString h_moc_ext; + static QString cpp_moc_ext; static QString obj_ext; static QString lex_ext; static QString yacc_ext; - static QString moc_mod; + static QString h_moc_mod; + static QString cpp_moc_mod; static QString lex_mod; static QString yacc_mod; static QString dir_sep; //both of these must be called.. static bool parseCommandLine(int argc, char **argv); //parse cmdline static bool postProcessProject(QMakeProject *); //and convenience functions static QString fixPathToLocalOS(const QString& in, bool fix_env=TRUE, bool canonical=TRUE); static QString fixPathToTargetOS(const QString& in, bool fix_env=TRUE, bool canonical=TRUE); //global qmake mode, can only be in one mode per invocation! 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; //all modes static QFile output; static QString output_dir; static int debug_level; static int warn_level; static QStringList before_user_vars, after_user_vars; enum TARG_MODE { TARG_UNIX_MODE, TARG_WIN_MODE, TARG_MACX_MODE, TARG_MAC9_MODE, TARG_QNX6_MODE }; static TARG_MODE target_mode; static QString user_template, user_template_prefix; + + //QMAKE_*_PROPERTY options + struct prop { + static QStringList properties; + }; + //QMAKE_GENERATE_PROJECT options struct projfile { static bool do_pwd; static bool do_recursive; static QStringList project_dirs; }; //QMAKE_GENERATE_MAKEFILE options struct mkfile { static QString qmakespec; static bool do_cache; static bool do_deps; static bool do_mocs; static bool do_dep_heuristics; static bool do_preprocess; static QString cachefile; static int cachefile_depth; static QStringList project_files; static QString qmakespec_commandline; }; private: - static bool internalParseCommandLine(int, char **, int=0); + static int internalParseCommandLine(int, char **, int=0); }; #endif /* __OPTION_H__ */ diff --git a/qmake/project.cpp b/qmake/project.cpp index 834823d..8aa6ff7 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -1,704 +1,798 @@ /**************************************************************************** -** $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. ** ** 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 "project.h" +#include "property.h" #include "option.h" #include <qfile.h> #include <qdir.h> #include <qregexp.h> #include <qtextstream.h> #include <qvaluestack.h> #ifdef Q_OS_UNIX # include <unistd.h> #endif #include <stdio.h> #include <stdlib.h> #ifdef Q_OS_WIN32 #define QT_POPEN _popen #else #define QT_POPEN popen #endif struct parser_info { QString file; int line_no; } parser; + static void qmake_error_msg(const char *msg) { fprintf(stderr, "%s:%d: %s\n", parser.file.latin1(), parser.line_no, 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) { QString ret(x); if(ret.startsWith("TMAKE")) //tmake no more! 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; } 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--; } else if(params[x] == '(') { parens++; } else if(params[x] == quote) { quote = 0; } else if(params[x] == '\'' || params[x] == '"') { quote = params[x]; } else if(!parens && !quote && params[x] == ',') { - args << params.mid(last, x - last); + args << params.mid(last, x - last).stripWhiteSpace(); last = x+1; } } - if(last != (int)params.length()) - args << params.mid(last); return args; } static QStringList split_value_list(const QString &vals, bool do_semicolon=FALSE) { - int last = 0; + QString build; QStringList ret; QValueStack<QChar> quote; 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; } 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; } bool 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 s = s.left(hash_mark); if(s.isEmpty()) /* blank_line */ return TRUE; if(s.stripWhiteSpace().left(1) == "}") { debug_msg(1, "Project Parser: %s:%d : Leaving block %d", parser.file.latin1(), parser.line_no, scope_block); test_status = ((scope_flag & (0x01 << scope_block)) ? TestFound : TestSeek); scope_block--; s = s.mid(1).stripWhiteSpace(); if(s.isEmpty()) return TRUE; } if(!(scope_flag & (0x01 << scope_block))) { /* 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)); debug_msg(1, "Project Parser: %s:%d : Ignored due to block being false.", parser.file.latin1(), parser.line_no); return TRUE; } QString scope, var, op; QStringList val; #define SKIP_WS(d) while(*d && (*d == ' ' || *d == '\t')) d++ const char *d = s.latin1(); SKIP_WS(d); bool scope_failed = FALSE, else_line = FALSE, or_op=FALSE; int parens = 0, scope_count=0; while(*d) { if(!parens) { if(*d == '=') break; if(*d == '+' || *d == '-' || *d == '*' || *d == '~') { if(*(d+1) == '=') { break; } else if(*(d+1) == ' ') { const char *k = d + 1; SKIP_WS(k); if(*k == '=') { QString msg; qmake_error_msg(*d + "must be followed immediately by ="); return FALSE; } } } } if ( *d == '(' ) ++parens; else if ( *d == ')' ) --parens; if(!parens && (*d == ':' || *d == '{' || *d == ')' || *d == '|')) { scope_count++; scope = var.stripWhiteSpace(); if ( *d == ')' ) scope += *d; /* need this */ var = ""; bool test = scope_failed; if(scope.lower() == "else") { if(scope_count != 1 || test_status == TestNone) { qmake_error_msg("Unexpected " + scope + " ('" + s + "')"); return FALSE; } else_line = TRUE; test = (test_status == TestSeek); debug_msg(1, "Project Parser: %s:%d : Else%s %s.", parser.file.latin1(), parser.line_no, scope == "else" ? "" : QString(" (" + scope + ")").latin1(), test ? "considered" : "excluded"); } else { QString comp_scope = scope; bool invert_test = (comp_scope.left(1) == "!"); if(invert_test) comp_scope = comp_scope.right(comp_scope.length()-1); int lparen = comp_scope.find('('); if(or_op || !scope_failed) { if(lparen != -1) { /* if there is an lparen in the scope, it IS a function */ int rparen = comp_scope.findRev(')'); if(rparen == -1) { QCString error; error.sprintf("Function missing right paren: %s ('%s')", comp_scope.latin1(), s.latin1()); qmake_error_msg(error); return FALSE; } QString func = comp_scope.left(lparen); test = doProjectTest(func, comp_scope.mid(lparen+1, rparen - lparen - 1), place); if ( *d == ')' && !*(d+1) ) { if(invert_test) test = !test; test_status = (test ? TestFound : TestSeek); return TRUE; /* assume we are done */ } } else { - test = isActiveConfig(comp_scope.stripWhiteSpace(), TRUE); + test = isActiveConfig(comp_scope.stripWhiteSpace(), TRUE, &place); } if(invert_test) test = !test; } } if(!test && !scope_failed) debug_msg(1, "Project Parser: %s:%d : Test (%s) failed.", parser.file.latin1(), parser.line_no, scope.latin1()); if(test == or_op) scope_failed = !test; or_op = (*d == '|'); if(*d == '{') { /* scoping block */ if(!scope_failed) scope_flag |= (0x01 << (++scope_block)); else scope_flag &= ~(0x01 << (++scope_block)); debug_msg(1, "Project Parser: %s:%d : Entering block %d (%d).", parser.file.latin1(), parser.line_no, scope_block, !scope_failed); } + } 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 { var += *d; } d++; } + var = var.stripWhiteSpace(); if(!scope_count || (scope_count == 1 && else_line)) test_status = TestNone; else if(!else_line || test_status != TestFound) test_status = (scope_failed ? TestSeek : TestFound); if(scope_failed) return TRUE; /* oh well */ if(!*d) { - if(!var.isEmpty()) + if(!var.stripWhiteSpace().isEmpty()) qmake_error_msg("Parse Error ('" + s + "')"); return var.isEmpty(); /* allow just a scope */ } SKIP_WS(d); - for( ; *d && op.find('=') == -1; op += *(d++)); + for( ; *d && op.find('=') == -1; op += *(d++)) + ; op.replace(QRegExp("\\s"), ""); SKIP_WS(d); QString vals(d); /* vals now contains the space separated list of values */ int rbraces = vals.contains('}'), lbraces = vals.contains('{'); if(scope_block && rbraces - lbraces == 1) { debug_msg(1, "Project Parser: %s:%d : Leaving block %d", parser.file.latin1(), parser.line_no, scope_block); test_status = ((scope_flag & (0x01 << scope_block)) ? TestFound : TestSeek); scope_block--; vals.truncate(vals.length()-1); } else if(rbraces != lbraces) { warn_msg(WarnParser, "Possible braces mismatch {%s} %s:%d", vals.latin1(), parser.file.latin1(), parser.line_no); } doVariableReplace(vals, place); - var = var.stripWhiteSpace(); #undef SKIP_WS if(!var.isEmpty() && Option::mkfile::do_preprocess) { static QString last_file("*none*"); 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()); } var = varMap(var); //backwards compatability /* vallist is the broken up list of values */ QStringList vallist = split_value_list(vals, (var == "DEPENDPATH" || var == "INCLUDEPATH")); if(!vallist.grep("=").isEmpty()) warn_msg(WarnParser, "Detected possible line continuation: {%s} %s:%d", var.latin1(), parser.file.latin1(), parser.line_no); QStringList &varlist = place[var]; /* varlist is the list in the symbol table */ 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()); /* now do the operation */ if(op == "~=") { if(vallist.count() != 1) { qmake_error_msg("~= operator only accepts one right hand paramater ('" + s + "')"); return FALSE; } QString val(vallist.first()); if(val.length() < 4 || val.at(0) != 's') { qmake_error_msg("~= operator only can handle s/// function ('" + s + "')"); return FALSE; } QChar sep = val.at(1); QStringList func = QStringList::split(sep, val, TRUE); if(func.count() < 3 || func.count() > 4) { qmake_error_msg("~= operator only can handle s/// function ('" + s + "')"); return FALSE; } bool global = FALSE, case_sense = TRUE; if(func.count() == 4) { global = func[3].find('g') != -1; case_sense = func[3].find('i') == -1; } QRegExp regexp(func[1], case_sense); for(QStringList::Iterator varit = varlist.begin(); varit != varlist.end(); ++varit) { if((*varit).contains(regexp)) { (*varit) = (*varit).replace(regexp, func[2]); if(!global) break; } } } else { if(op == "=") { if(!varlist.isEmpty()) warn_msg(WarnParser, "Operator=(%s) clears variables previously set: %s:%d", var.latin1(), parser.file.latin1(), parser.line_no); varlist.clear(); } for(QStringList::Iterator valit = vallist.begin(); valit != vallist.end(); ++valit) { if((*valit).isEmpty()) continue; if((op == "*=" && !(*varlist.find((*valit)))) || op == "=" || op == "+=") varlist.append((*valit)); else if(op == "-=") varlist.remove((*valit)); } } if(var == "REQUIRES") /* special case to get communicated to backends! */ doProjectCheckReqs(vallist, place); return TRUE; } bool 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(); QString filename = Option::fixPathToLocalOS(file); doVariableReplace(filename, place); bool ret = FALSE, using_stdin = FALSE; QFile qfile; if(!strcmp(filename, "-")) { qfile.setName(""); ret = qfile.open(IO_ReadOnly, stdin); using_stdin = TRUE; } else { qfile.setName(filename); ret = qfile.open(IO_ReadOnly); } if ( ret ) { QTextStream t( &qfile ); QString s, line; parser.file = filename; parser.line_no = 0; while ( !t.eof() ) { parser.line_no++; line = t.readLine().stripWhiteSpace(); 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)) { if(s.isEmpty() && line.isEmpty()) continue; if(!line.isEmpty()) s += line; if(!s.isEmpty()) { if(!(ret = parse(s, place))) break; s = ""; } } } if(!using_stdin) qfile.close(); } parser = pi; + if(scope_block != 0) + warn_msg(WarnParser, "%s: Unterminated conditional at end of file.", + file.latin1()); return ret; } 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()) { // hack to get the Option stuff in there base_vars["QMAKE_EXT_CPP"] = Option::cpp_ext; base_vars["QMAKE_EXT_H"] = Option::h_ext; if(!Option::user_template_prefix.isEmpty()) base_vars["TEMPLATE_PREFIX"] = Option::user_template_prefix; - /* 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 QString dir = QDir::convertSeparators(Option::output_dir); while(!QFile::exists((Option::mkfile::cachefile = dir + QDir::separator() + ".qmake.cache"))) { dir = dir.left(dir.findRev(QDir::separator())); if(dir.isEmpty() || dir.find(QDir::separator()) == -1) { Option::mkfile::cachefile = ""; break; } if(Option::mkfile::cachefile_depth == -1) Option::mkfile::cachefile_depth = 1; else Option::mkfile::cachefile_depth++; } } if(!Option::mkfile::cachefile.isEmpty()) { read(Option::mkfile::cachefile, cache); if(Option::mkfile::qmakespec.isEmpty() && !cache["QMAKESPEC"].isEmpty()) Option::mkfile::qmakespec = cache["QMAKESPEC"].first(); } } - /* 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()); return FALSE; } parser.line_no++; } } - /* 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(); vars["TEMPLATE"].append(Option::user_template); } QStringList &templ = vars["TEMPLATE"]; if(templ.isEmpty()) templ.append(QString("app")); else if(vars["TEMPLATE"].first().endsWith(".t")) 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); - } if(vars["TARGET"].isEmpty()) { // ### why not simply use: // QFileInfo fi(pfile); // fi.baseName(); QString tmp = pfile; if(tmp.findRev('/') != -1) tmp = tmp.right( tmp.length() - tmp.findRev('/') - 1 ); if(tmp.findRev('.') != -1) tmp = tmp.left(tmp.findRev('.')); vars["TARGET"].append(tmp); } QString test_version = getenv("QTESTVERSION"); if (!test_version.isEmpty()) { QString s = vars["TARGET"].first(); if (s == "qt" || s == "qt-mt" || s == "qte" || s == "qte-mt") { QString &ver = vars["VERSION"].first(); // fprintf(stderr,"Current QT version number: " + ver + "\n"); if (ver != "" && ver != test_version) { ver = test_version; fprintf(stderr,"Changed QT version number to " + test_version + "!\n"); } } } return TRUE; } bool -QMakeProject::isActiveConfig(const QString &x, bool regex) +QMakeProject::isActiveConfig(const QString &x, bool regex, QMap<QString, QStringList> *place) { if(x.isEmpty()) return TRUE; if((Option::target_mode == Option::TARG_MACX_MODE || Option::target_mode == Option::TARG_QNX6_MODE || Option::target_mode == Option::TARG_UNIX_MODE) && x == "unix") return TRUE; else if(Option::target_mode == Option::TARG_MACX_MODE && x == "macx") return TRUE; else if(Option::target_mode == Option::TARG_QNX6_MODE && x == "qnx6") return TRUE; else if(Option::target_mode == Option::TARG_MAC9_MODE && x == "mac9") return TRUE; else if((Option::target_mode == Option::TARG_MAC9_MODE || Option::target_mode == Option::TARG_MACX_MODE) && x == "mac") return TRUE; else if(Option::target_mode == Option::TARG_WIN_MODE && x == "win32") return TRUE; QRegExp re(x, FALSE, TRUE); QString spec = Option::mkfile::qmakespec.right(Option::mkfile::qmakespec.length() - (Option::mkfile::qmakespec.findRev(QDir::separator())+1)); if((regex && re.exactMatch(spec)) || (!regex && spec == x)) return TRUE; #ifdef Q_OS_UNIX else if(spec == "default") { static char *buffer = NULL; if(!buffer) buffer = (char *)malloc(1024); int l = readlink(Option::mkfile::qmakespec, buffer, 1024); if(l != -1) { buffer[l] = '\0'; QString r = buffer; if(r.findRev('/') != -1) r = r.mid(r.findRev('/') + 1); if((regex && re.exactMatch(r)) || (!regex && r == x)) return TRUE; } } #endif - QStringList &configs = vars["CONFIG"]; + QStringList &configs = (place ? (*place)["CONFIG"] : vars["CONFIG"]); for(QStringList::Iterator it = configs.begin(); it != configs.end(); ++it) { if((regex && re.exactMatch((*it))) || (!regex && (*it) == x)) if(re.exactMatch((*it))) return TRUE; } return FALSE; } bool QMakeProject::doProjectTest(const QString& func, const QString ¶ms, QMap<QString, QStringList> &place) { QStringList args = split_arg_list(params); for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { QString tmp = (*arit).stripWhiteSpace(); if((tmp[0] == '\'' || tmp[0] == '"') && tmp.right(1) == tmp.left(1)) tmp = tmp.mid(1, tmp.length() - 2); } return doProjectTest(func.stripWhiteSpace(), args, place); } bool QMakeProject::doProjectTest(const QString& func, QStringList args, QMap<QString, QStringList> &place) { for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { (*arit) = (*arit).stripWhiteSpace(); // blah, get rid of space doVariableReplace((*arit), place); } debug_msg(1, "Running project test: %s( %s )", func.latin1(), args.join("::").latin1()); if(func == "requires") { return doProjectCheckReqs(args, place); } else if(func == "equals") { if(args.count() != 2) { fprintf(stderr, "%s:%d: equals(variable, value) requires two arguments.\n", parser.file.latin1(), parser.line_no); return FALSE; } QString value = args[1]; if((value.left(1) == "\"" || value.left(1) == "'") && value.right(1) == value.left(1)) value = value.mid(1, value.length()-2); return vars[args[0]].join(" ") == value; } else if(func == "exists") { if(args.count() != 1) { fprintf(stderr, "%s:%d: exists(file) requires one argument.\n", parser.file.latin1(), parser.line_no); return FALSE; } QString file = args.first(); file = Option::fixPathToLocalOS(file); doVariableReplace(file, place); if(QFile::exists(file)) return TRUE; //regular expression I guess QString dirstr = QDir::currentDirPath(); int slsh = file.findRev(Option::dir_sep); if(slsh != -1) { dirstr = file.left(slsh+1); file = file.right(file.length() - slsh - 1); } QDir dir(dirstr, file); return dir.count() != 0; } else if(func == "system") { if(args.count() != 1) { @@ -716,362 +810,582 @@ QMakeProject::doProjectTest(const QString& func, QStringList args, QMap<QString, QRegExp regx(args[1]); QStringList &l = place[args[0]]; for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { if(regx.exactMatch((*it))) return TRUE; } return FALSE; } else if(func == "infile") { if(args.count() < 2 || args.count() > 3) { fprintf(stderr, "%s:%d: infile(file, var, val) requires at least 2 arguments.\n", parser.file.latin1(), parser.line_no); return FALSE; } QMakeProject proj; QString file = args[0]; doVariableReplace(file, place); fixEnvVariables(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; bool ret = !proj.read(file, oldpwd); parser = pi; if(ret) { fprintf(stderr, "Error processing project file: %s\n", file.latin1()); QDir::setCurrent(oldpwd); return FALSE; } if(args.count() == 2) { ret = !proj.isEmpty(args[1]); } else { QRegExp regx(args[2]); QStringList &l = proj.values(args[1]); for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { if(regx.exactMatch((*it))) { ret = TRUE; break; } } } QDir::setCurrent(oldpwd); return ret; } else if(func == "count") { if(args.count() != 2) { fprintf(stderr, "%s:%d: count(var, count) requires two arguments.\n", parser.file.latin1(), parser.line_no); return FALSE; } return vars[args[0]].count() == args[1].toUInt(); } else if(func == "isEmpty") { if(args.count() != 1) { fprintf(stderr, "%s:%d: isEmpty(var) requires one argument.\n", parser.file.latin1(), parser.line_no); return FALSE; } return vars[args[0]].isEmpty(); } 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)"; if(func == "load") func_desc = "load(feature)"; fprintf(stderr, "%s:%d: %s requires one argument.\n", parser.file.latin1(), parser.line_no, func_desc.latin1()); return FALSE; } QString file = args.first(); file = Option::fixPathToLocalOS(file); file.replace("\"", ""); doVariableReplace(file, place); if(func == "load") { if(!file.endsWith(Option::prf_ext)) file += Option::prf_ext; 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; + } } } + 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; int sb = scope_block; int sf = scope_flag; 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; test_status = sc; scope_flag = sf; scope_block = sb; + QDir::setCurrent(oldpwd); return r; } else if(func == "error" || func == "message") { if(args.count() != 1) { fprintf(stderr, "%s:%d: %s(message) requires one argument.\n", parser.file.latin1(), parser.line_no, func.latin1()); return FALSE; } QString msg = args.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); - printf("Project %s: %s\n", func.upper().latin1(), msg.latin1()); + fprintf(stderr, "Project %s: %s\n", func.upper().latin1(), msg.latin1()); if(func == "message") return TRUE; exit(2); } else { fprintf(stderr, "%s:%d: Unknown test function: %s\n", parser.file.latin1(), parser.line_no, func.latin1()); } return FALSE; } bool QMakeProject::doProjectCheckReqs(const QStringList &deps, QMap<QString, QStringList> &place) { bool ret = FALSE; for(QStringList::ConstIterator it = deps.begin(); it != deps.end(); ++it) { QString chk = (*it); if(chk.isEmpty()) continue; bool invert_test = (chk.left(1) == "!"); if(invert_test) chk = chk.right(chk.length() - 1); bool test; int lparen = chk.find('('); if(lparen != -1) { /* if there is an lparen in the chk, it IS a function */ int rparen = chk.findRev(')'); if(rparen == -1) { QCString error; error.sprintf("Function (in REQUIRES) missing right paren: %s", chk.latin1()); qmake_error_msg(error); } else { QString func = chk.left(lparen); test = doProjectTest(func, chk.mid(lparen+1, rparen - lparen - 1), place); } } else { - test = isActiveConfig(chk, TRUE); + test = isActiveConfig(chk, TRUE, &place); } if(invert_test) { chk.prepend("!"); test = !test; } if(!test) { debug_msg(1, "Project Parser: %s:%d Failed test: REQUIRES = %s", parser.file.latin1(), parser.line_no, chk.latin1()); place["QMAKE_FAILED_REQUIREMENTS"].append(chk); ret = FALSE; } } return ret; } QString QMakeProject::doVariableReplace(QString &str, const QMap<QString, QStringList> &place) { 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; } else if(var_begin != 0 && str[var_begin-1] == '\\') { str.replace(var_begin-1, 1, ""); var_begin += 1; continue; } 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] == '{') { in_braces = TRUE; 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')) var_incr++; } if(str[var_incr] == '(') { as_env = TRUE; 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] == '_')) val += str[var_incr++]; if(as_env) { if(str[var_incr] != ')') { var_incr++; warn_msg(WarnParser, "%s:%d: Unterminated env-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()); + 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()); var_begin += var_incr; continue; } var_incr++; } 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] == '(') { parens++; if(parens == 1) continue; } else if(str[var_incr] == ')') { parens--; if(!parens) { var_incr++; break; } } args += str[var_incr]; } } - if(var_incr > int( str.length() ) || (in_braces && str[var_incr] != '}')) { + if(var_incr > (int)str.length() || (in_braces && str[var_incr] != '}')) { var_incr++; warn_msg(WarnParser, "%s:%d: Unterminated 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()); + str.mid(var_begin, QMAX(var_incr - var_begin, + (int)str.length())).latin1(), str.latin1()); var_begin += var_incr; continue; } else if(in_braces) { var_incr++; } QString replacement; if(as_env) { replacement = getenv(val); + } else if(as_prop) { + if(prop) + replacement = prop->value(val); } else if(args.isEmpty()) { if(val.left(1) == ".") replacement = ""; else if(val == "LITERAL_WHITESPACE") 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 replacement = place[varMap(val)].join(" "); } 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(" "); } } else if(val.lower() == "list") { static int x = 0; replacement.sprintf(".QMAKE_INTERNAL_TMP_VAR_%d", x++); QStringList &lst = (*((QMap<QString, QStringList>*)&place))[replacement]; lst.clear(); 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)); } else if(val.lower() == "join") { if(arg_list.count() < 1 || arg_list.count() > 4) { fprintf(stderr, "%s:%d: join(var, glue, before, after) requires four" "arguments.\n", parser.file.latin1(), parser.line_no); } else { QString glue, before, after; if(arg_list.count() >= 2) glue = arg_list[1].replace("\"", "" ); if(arg_list.count() >= 3) before = arg_list[2].replace("\"", "" ); if(arg_list.count() == 4) after = arg_list[3].replace("\"", "" ); const QStringList &var = place[varMap(arg_list.first())]; if(!var.isEmpty()) replacement = before + var.join(glue) + after; } + } 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") { if(arg_list.count() != 2) { fprintf(stderr, "%s:%d find(var, str) requires two arguments\n", parser.file.latin1(), parser.line_no); } else { QRegExp regx(arg_list[1]); const QStringList &var = place[varMap(arg_list.first())]; for(QStringList::ConstIterator vit = var.begin(); vit != var.end(); ++vit) { if(regx.search(*vit) != -1) { if(!replacement.isEmpty()) replacement += " "; replacement += (*vit); } } } } else if(val.lower() == "system") { if(arg_list.count() != 1) { fprintf(stderr, "%s:%d system(execut) requires one argument\n", parser.file.latin1(), parser.line_no); } else { char buff[256]; FILE *proc = QT_POPEN(arg_list.join(" ").latin1(), "r"); while(proc && !feof(proc)) { - int read_in = fread(buff, 1, 255, proc); + int read_in = int(fread(buff, 1, 255, proc)); if(!read_in) break; for(int i = 0; i < read_in; i++) { if(buff[i] == '\n' || buff[i] == '\t') buff[i] = ' '; } buff[read_in] = '\0'; replacement += buff; } } + } 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 { fprintf(stderr, "%s:%d: Unknown replace function: %s\n", parser.file.latin1(), parser.line_no, val.latin1()); } } //actually do replacement now.. int mlen = var_incr - var_begin; debug_msg(2, "Project Parser [var replace]: '%s' :: %s -> %s", str.latin1(), str.mid(var_begin, mlen).latin1(), replacement.latin1()); str.replace(var_begin, mlen, replacement); var_begin += replacement.length(); } return str; } diff --git a/qmake/project.h b/qmake/project.h index ec19f0c..0ca2a92 100644 --- a/qmake/project.h +++ b/qmake/project.h @@ -1,114 +1,121 @@ /**************************************************************************** -** $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. ** ** 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 __PROJECT_H__ #define __PROJECT_H__ #include <qstringlist.h> #include <qstring.h> #include <qmap.h> +class QMakeProperty; + class QMakeProject { enum TestStatus { TestNone, TestFound, TestSeek } test_status; int scope_block, scope_flag; QString pfile, cfile; + QMakeProperty *prop; + void reset(); QMap<QString, QStringList> vars, base_vars, cache; bool parse(const QString &text, QMap<QString, QStringList> &place); bool doProjectTest(const QString &func, const QString ¶ms, QMap<QString, QStringList> &place); bool doProjectTest(const QString &func, QStringList args, QMap<QString, QStringList> &place); bool doProjectCheckReqs(const QStringList &deps, QMap<QString, QStringList> &place); QString doVariableReplace(QString &str, const QMap<QString, QStringList> &place); 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(); QString configFile(); bool isEmpty(const QString &v); QStringList &values(const QString &v); QString first(const QString &v); 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); protected: friend class MakefileGenerator; bool read(const QString &file, QMap<QString, QStringList> &place); }; inline QString QMakeProject::projectFile() { #if defined(Q_CC_SUN) && (__SUNPRO_CC == 0x500) || defined(Q_CC_HP) // workaround for Sun WorkShop 5.0 bug fixed in Forte 6 if (pfile == "-") return QString("(stdin)"); else return pfile; #else return pfile == "-" ? QString("(stdin)") : pfile; #endif } inline QString QMakeProject::configFile() { return cfile; } inline bool QMakeProject::isEmpty(const QString &v) { return !vars.contains(v) || vars[v].isEmpty(); } inline QStringList &QMakeProject::values(const QString &v) { return vars[v]; } inline QString QMakeProject::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> &QMakeProject::variables() { return vars; } #endif /* __PROJECT_H__ */ 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 @@ -1,17 +1,22 @@ /* Install paths from configure */ -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,597 +1,564 @@ /**************************************************************************** -** $Id$ +** ** ** Implementation of QSettings class ** ** Created : 000626 ** -** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. +** Copyright (C) 2000-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 "qplatformdefs.h" // POSIX Large File Support redefines open -> open64 static inline int qt_open( const char *pathname, int flags, mode_t mode ) { return ::open( pathname, flags, mode ); } #if defined(open) # undef open #endif // POSIX Large File Support redefines truncate -> truncate64 #if defined(truncate) # undef truncate #endif #include "qsettings.h" #ifndef QT_NO_SETTINGS #include "qdir.h" #include "qfile.h" #include "qfileinfo.h" #include "qmap.h" #include "qtextstream.h" #include "qregexp.h" #include <private/qsettings_p.h> +#ifndef NO_ERRNO_H #include <errno.h> +#endif /*! \class QSettings \brief The QSettings class provides persistent platform-independent application settings. \ingroup io \ingroup misc \mainclass On Unix systems, QSettings uses text files to store settings. On Windows systems, QSettings uses the system registry. On Mac OS X, QSettings uses the Carbon preferences API. Each setting comprises an identifying key and the data associated with the key. A key is a unicode string which consists of \e two or more subkeys. A subkey is a slash, '/', followed by one or more unicode characters (excluding slashes, newlines, carriage returns and equals, '=', signs). The associated data, called the entry or value, may be a boolean, an integer, a double, a string or a list of strings. Entry strings may contain any unicode characters. If you want to save and restore the entire desktop's settings, i.e. which applications are running, use QSettings to save the settings for each individual application and QSessionManager to save the desktop's session. Example settings: \code /MyCompany/MyApplication/background color /MyCompany/MyApplication/foreground color /MyCompany/MyApplication/geometry/x /MyCompany/MyApplication/geometry/y /MyCompany/MyApplication/geometry/width /MyCompany/MyApplication/geometry/height /MyCompany/MyApplication/recent files/1 /MyCompany/MyApplication/recent files/2 /MyCompany/MyApplication/recent files/3 \endcode Each line above is a complete key, made up of subkeys. - A typical usage pattern for reading application startup: + A typical usage pattern for reading settings at application + startup: \code QSettings settings; settings.setPath( "MyCompany.com", "MyApplication" ); QString bgColor = settings.readEntry( "/colors/background", "white" ); int width = settings.readNumEntry( "/geometry/width", 640 ); // ... \endcode - A typical usage pattern for application exit or 'save preferences': + A typical usage pattern for saving settings at application exit or + 'save preferences': \code QSettings settings; settings.setPath( "MyCompany.com", "MyApplication" ); settings.writeEntry( "/colors/background", bgColor ); settings.writeEntry( "/geometry/width", width ); // ... \endcode - 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 QSettings settings; settings.beginGroup( "/MainWindow" ); settings.beginGroup( "/Geometry" ); int x = settings.readEntry( "/x" ); // ... settings.endGroup(); settings.beginGroup( "/Toolbars" ); // ... settings.endGroup(); settings.endGroup(); \endcode You can get a list of entry-holding keys by calling entryList(), and a list of key-holding keys using subkeyList(). \code QStringList keys = entryList( "/MyApplication" ); // keys contains 'background color' and 'foreground color'. QStringList keys = entryList( "/MyApplication/recent files" ); // keys contains '1', '2' and '3'. QStringList subkeys = subkeyList( "/MyApplication" ); // subkeys contains 'geometry' and 'recent files' QStringList subkeys = subkeyList( "/MyApplication/recent files" ); // subkeys is empty. \endcode - 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 \i A subkey may not exceed 255 characters. \i An entry's value may not exceed 16,300 characters. \i All the values of a key (for example, all the 'recent files' subkeys values), may not exceed 65,535 characters. \endlist These limitations are not enforced on Unix or Mac OS X. - 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. \section1 Notes for Mac OS X Applications - 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 \section1 Notes for Unix Applications There is no universally accepted place for storing application settings under Unix. In the examples the settings file will be searched for in the following directories: \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 When reading settings the files are searched in the order shown above, with later settings overriding earlier settings. Files for which the user doesn't have read permission are ignored. When saving settings QSettings works in the order shown above, writing to the first settings file for which the user has write permission. (\c INSTALL is the directory where Qt was installed. This can be modified by using the configure script's -prefix argument ) If you want to put the settings in a particular place in the filesystem you could do this: \code settings.insertSearchPath( QSettings::Unix, "/opt/MyCompany/share" ); \endcode But in practice you may prefer not to use a search path for Unix. For example the following code: \code settings.writeEntry( "/MyApplication/geometry/width", width ); \endcode will end up writing the "geometry/width" setting to the file \c{$HOME/.qt/myapplicationrc} (assuming that the application is being run by an ordinary user, i.e. not by root). - 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. */ /*! \enum QSettings::System \value Mac Macintosh execution environments \value Unix Mac OS X, Unix, Linux and Unix-like execution environments \value Windows Windows execution environments */ /*! \enum QSettings::Format \value Native Store the settings in a platform dependent location \value Ini Store the settings in a text file */ /*! \enum QSettings::Scope \value Global Save settings as global as possible \value User Save settings in user space */ #if defined(Q_OS_UNIX) typedef int HANDLE; #define Q_LOCKREAD F_RDLCK #define Q_LOCKWRITE F_WRLCK /* Locks the file specified by name. The lockfile is created as a hidden file in the same directory as the target file, with .lock appended to the name. For example, "/etc/settings/onerc" uses a lockfile named "/etc/settings/.onerc.lock". The type argument controls the type of the lock, it can be either F_RDLCK for a read lock, or F_WRLCK for a write lock. A file descriptor for the lock file is returned, and should be closed with closelock() when the lock is no longer needed. */ static HANDLE openlock( const QString &name, int type ) { QFileInfo info( name ); // lockfile should be hidden, and never removed QString lockfile = info.dirPath() + "/." + info.fileName() + ".lock"; // open the lockfile HANDLE fd = qt_open( QFile::encodeName( lockfile ), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR ); if ( fd < 0 ) { // failed to open the lock file, most likely because of permissions return fd; } struct flock fl; fl.l_type = type; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; if ( fcntl( fd, F_SETLKW, &fl ) == -1 ) { // the lock failed, so we should fail silently, so that people // using filesystems that do not support locking don't see // numerous warnings about a failed lock close( fd ); fd = -1; } return fd; } /* Closes the lock file specified by fd. fd is the file descriptor returned by the openlock() function. */ static void closelock( HANDLE fd ) { if ( fd < 0 ) { // the lock file is not open return; } struct flock fl; fl.l_type = F_UNLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; // ignore the return value, so that the unlock fails silently (void) fcntl( fd, F_SETLKW, &fl ); close( 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 QSettingsGroup::QSettingsGroup() : modified(FALSE) { } void QSettingsHeading::read(const QString &filename) { if (! QFileInfo(filename).exists()) return; +#ifndef Q_WS_WIN HANDLE lockfd = openlock( filename, Q_LOCKREAD ); +#endif QFile file(filename); if (! file.open(IO_ReadOnly)) { #if defined(QT_CHECK_STATE) qWarning("QSettings: failed to open file '%s'", filename.latin1()); #endif return; } git = end(); QTextStream stream(&file); stream.setEncoding(QTextStream::UnicodeUTF8); while (! stream.atEnd()) parseLine(stream); git = end(); file.close(); +#ifndef Q_WS_WIN closelock( lockfd ); +#endif } void QSettingsHeading::parseLine(QTextStream &stream) { QString line = stream.readLine(); if (line.isEmpty()) // empty line... we'll allow it return; if (line[0] == QChar('#')) // commented line return; if (line[0] == QChar('[')) { QString gname = line; - gname = gname.remove(0, 1); + gname = gname.remove((uint)0, 1); if (gname[(int)gname.length() - 1] == QChar(']')) gname = gname.remove(gname.length() - 1, 1); git = find(gname); if (git == end()) git = replace(gname, QSettingsGroup()); } else { if (git == end()) { #if defined(QT_CHECK_STATE) qWarning("QSettings: line '%s' out of group", line.latin1()); #endif return; } int i = line.find('='); if (i == -1) { #if defined(QT_CHECK_STATE) qWarning("QSettings: malformed line '%s' in group '%s'", line.latin1(), git.key().latin1()); #endif return; } else { QString key, value; key = line.left(i); value = ""; bool esc=TRUE; i++; while (esc) { esc = FALSE; for ( ; i < (int)line.length(); i++ ) { if ( esc ) { if ( line[i] == 'n' ) value.append('\n'); // escaped newline else if ( line[i] == '0' ) value = QString::null; // escaped empty string else value.append(line[i]); esc = FALSE; } else if ( line[i] == '\\' ) esc = TRUE; else value.append(line[i]); } if ( esc ) { // Backwards-compatiblity... // still escaped at EOL - manually escaped "newline" if (stream.atEnd()) { #if defined(QT_CHECK_STATE) qWarning("QSettings: reached end of file, expected continued line"); #endif break; } value.append('\n'); line = stream.readLine(); i = 0; } } (*git).insert(key, value); } } } #ifdef Q_WS_WIN // for homedirpath reading from registry #include "qt_windows.h" #include "qlibrary.h" #ifndef CSIDL_APPDATA #define CSIDL_APPDATA 0x001a // <user name>\Application Data #endif #ifndef CSIDL_COMMON_APPDATA #define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data #endif #endif QSettingsPrivate::QSettingsPrivate( QSettings::Format format ) : groupDirty( TRUE ), modified(FALSE), globalScope(TRUE) { #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( format != QSettings::Ini ) return; #else Q_UNUSED( format ); #endif QString appSettings(QDir::homeDirPath() + "/.qt/"); QString defPath; #ifdef Q_WS_WIN #ifdef Q_OS_TEMP TCHAR path[MAX_PATH]; SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE ); appSettings = QString::fromUcs2( path ); SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE ); defPath = QString::fromUcs2( path ); #else QLibrary library( "shell32" ); library.setAutoUnload( FALSE ); QT_WA( { typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int, BOOL); GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve( "SHGetSpecialFolderPathW" ); if ( SHGetSpecialFolderPath ) { TCHAR path[MAX_PATH]; SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE ); appSettings = QString::fromUcs2( (ushort*)path ); SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE ); defPath = QString::fromUcs2( (ushort*)path ); } } , { typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, char*, int, BOOL); GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve( "SHGetSpecialFolderPathA" ); if ( SHGetSpecialFolderPath ) { char path[MAX_PATH]; SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE ); appSettings = QString::fromLocal8Bit( path ); SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE ); defPath = QString::fromLocal8Bit( path ); } } ); #endif // Q_OS_TEMP #else -// for now -#define QSETTINGS_DEFAULT_PATH_SUFFIX "/etc/settings" - - defPath = qInstallPath(); - defPath += QSETTINGS_DEFAULT_PATH_SUFFIX; + defPath = qInstallPathSysconf(); #endif QDir dir(appSettings); if (! dir.exists()) { if (! dir.mkdir(dir.path())) #if defined(QT_CHECK_STATE) qWarning("QSettings: error creating %s", dir.path().latin1()); #else ; #endif } if ( !!defPath ) searchPaths.append(defPath); searchPaths.append(dir.path()); } QSettingsPrivate::~QSettingsPrivate() { } QSettingsGroup QSettingsPrivate::readGroup() { QSettingsHeading hd; QSettingsGroup grp; QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading); if (headingsit != headings.end()) hd = *headingsit; QSettingsHeading::Iterator grpit = hd.find(group); if (grpit == hd.end()) { QStringList::Iterator it = searchPaths.begin(); if ( !globalScope ) ++it; while (it != searchPaths.end()) { QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); QString fn((*it++) + "/" + filebase + "rc"); if (! hd.contains(fn + "cached")) { hd.read(fn); hd.insert(fn + "cached", QSettingsGroup()); } } headings.replace(heading, hd); grpit = hd.find(group); if (grpit != hd.end()) grp = *grpit; } else if (hd.count() != 0) grp = *grpit; return grp; } void QSettingsPrivate::removeGroup(const QString &key) { QSettingsHeading hd; QSettingsGroup grp; bool found = FALSE; QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading); if (headingsit != headings.end()) hd = *headingsit; @@ -640,243 +607,252 @@ void QSettingsPrivate::removeGroup(const QString &key) } void QSettingsPrivate::writeGroup(const QString &key, const QString &value) { QSettingsHeading hd; QSettingsGroup grp; QMap<QString,QSettingsHeading>::Iterator headingsit = headings.find(heading); if (headingsit != headings.end()) hd = *headingsit; QSettingsHeading::Iterator grpit = hd.find(group); if (grpit == hd.end()) { QStringList::Iterator it = searchPaths.begin(); if ( !globalScope ) ++it; while (it != searchPaths.end()) { QString filebase = heading.lower().replace(QRegExp("\\s+"), "_"); QString fn((*it++) + "/" + filebase + "rc"); if (! hd.contains(fn + "cached")) { hd.read(fn); hd.insert(fn + "cached", QSettingsGroup()); } } headings.replace(heading, hd); grpit = hd.find(group); if (grpit != hd.end()) grp = *grpit; } else if (hd.count() != 0) grp = *grpit; grp.modified = TRUE; grp.replace(key, value); hd.replace(group, grp); headings.replace(heading, hd); modified = TRUE; } QDateTime QSettingsPrivate::modificationTime() { QSettingsHeading hd = headings[heading]; QSettingsGroup grp = hd[group]; QDateTime datetime; QStringList::Iterator it = searchPaths.begin(); if ( !globalScope ) ++it; while (it != searchPaths.end()) { QFileInfo fi((*it++) + "/" + heading + "rc"); if (fi.exists() && fi.lastModified() > datetime) datetime = fi.lastModified(); } return datetime; } 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; return TRUE; } -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] == '/' ) ) { // group is empty, or it contains a single '/', so we just return the 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; } /*! 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. When \a s is \e Windows and the execution environment is \e not Windows the function does nothing. Similarly when \a s is \e Unix and the execution environment is \e not Unix the function does nothing. When \a s is \e Windows, and the execution environment is Windows, the search path list will be used as the first subfolder of the "Software" folder in the registry. When reading settings the folders are searched forwards from the first folder (listed below) to the last, returning the first settings found, and ignoring any folders for which the user doesn't have read permission. \list 1 \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication \i HKEY_CURRENT_USER/Software/MyApplication \i HKEY_LOCAL_MACHINE/Software/MyApplication \endlist \code QSettings settings; settings.insertSearchPath( QSettings::Windows, "/MyCompany" ); settings.writeEntry( "/MyApplication/Tip of the day", TRUE ); \endcode The code above will write the subkey "Tip of the day" into the \e first of the registry folders listed below that is found and for which the user has write permission. \list 1 \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication \i HKEY_LOCAL_MACHINE/Software/MyApplication \i HKEY_CURRENT_USER/Software/MyApplication \endlist If a setting is found in the HKEY_CURRENT_USER space, this setting is overwritten independently of write permissions in the HKEY_LOCAL_MACHINE space. When \a s is \e Unix, and the execution environment is Unix, the search path list will be used when trying to determine a suitable filename for reading and writing settings files. By default, there are two entries in the search path: \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 All insertions into the search path will go before $HOME/.qt/. For example: \code QSettings settings; settings.insertSearchPath( QSettings::Unix, "/opt/MyCompany/share/etc" ); settings.insertSearchPath( QSettings::Unix, "/opt/MyCompany/share/MyApplication/etc" ); // ... \endcode Will result in a search path of: \list 1 - \i INSTALL/etc + \i SYSCONF \i /opt/MyCompany/share/etc \i /opt/MyCompany/share/MyApplication/etc \i $HOME/.qt \endlist When reading settings the files are searched in the order shown above, with later settings overriding earlier settings. Files for which the user doesn't have read permission are ignored. When saving settings QSettings works in the order shown above, writing to the first settings file for which the user has write permission. + 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 first subkey of the key (not including the search path). The algorithm for creating names is essentially: lowercase the first subkey, replace spaces with underscores and add 'rc', e.g. <tt>/MyCompany/MyApplication/background color</tt> will be stored in <tt>myapplicationrc</tt> (assuming that <tt>/MyCompany</tt> is part of the search path). \sa removeSearchPath() */ void QSettings::insertSearchPath( System s, const QString &path) { #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) { d->sysInsertSearchPath( s, path ); return; } #endif #if !defined(Q_WS_WIN) if ( s == Windows ) return; #endif -#if !defined(Q_WS_WIN) +#if !defined(Q_OS_MAC) if ( s == Mac ) return; #endif if ( !qt_verify_key( path ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() ); #endif return; } #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd && s != Unix ) { #else if ( s != Unix ) { #endif #if !defined(QWS) && defined(Q_OS_MAC) if(s != Mac) //mac is respected on the mac as well #endif return; } QString realPath = path; #if defined(Q_WS_WIN) QString defPath = d->globalScope ? d->searchPaths.first() : d->searchPaths.last(); realPath = defPath + path; #endif QStringList::Iterator it = d->searchPaths.find(d->searchPaths.last()); if (it != d->searchPaths.end()) { d->searchPaths.insert(it, realPath); } } /*! Removes all occurrences of \a path (using exact matching) from the settings search path for system \a s. Note that the default search paths cannot be removed. \sa insertSearchPath() */ void QSettings::removeSearchPath( System s, const QString &path) { if ( !qt_verify_key( path ) ) { #if defined(QT_CHECK_STATE) qWarning( "QSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() ); #endif return; } #ifdef Q_WS_WIN if ( d->sysd ) { d->sysRemoveSearchPath( s, path ); return; } #endif #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd && s != Unix ) { #else if ( s != Unix ) { #endif #if !defined(QWS) && defined(Q_OS_MAC) if(s != Mac) //mac is respected on the mac as well @@ -903,1151 +879,1186 @@ QSettings::QSettings() d->sysd = 0; d->sysInit(); #endif } /*! Creates a settings object. If \a format is 'Ini' the settings will be stored in a text file, using the Unix strategy (see above). If \a format is 'Native', the settings will be stored in a platform specific way (ie. the Windows registry). */ QSettings::QSettings( Format format ) { d = new QSettingsPrivate( format ); Q_CHECK_PTR(d); #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) d->sysd = 0; if ( format == Native ) d->sysInit(); #else Q_UNUSED(format); #endif } /*! Destroys the settings object. All modifications made to the settings will automatically be saved. */ QSettings::~QSettings() { sync(); #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) d->sysClear(); #endif delete d; } /*! \internal Writes all modifications to the settings to disk. If any errors are encountered, this function returns FALSE, otherwise it will return TRUE. */ bool QSettings::sync() { #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return d->sysSync(); #endif if (! d->modified) // fake success return TRUE; bool success = TRUE; QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin(); while (it != d->headings.end()) { // determine filename QSettingsHeading hd(*it); QSettingsHeading::Iterator hdit = hd.begin(); - QFile file; + QString filename; QStringList::Iterator pit = d->searchPaths.begin(); if ( !d->globalScope ) ++pit; while (pit != d->searchPaths.end()) { QString filebase = it.key().lower().replace(QRegExp("\\s+"), "_"); QFileInfo di(*pit); + if ( !di.exists() ) { + QDir dir; + dir.mkdir( *pit ); + } + QFileInfo fi((*pit++) + "/" + filebase + "rc"); 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; } } ++it; - if ( file.name().isEmpty() ) { + if ( filename.isEmpty() ) { #ifdef QT_CHECK_STATE qWarning("QSettings::sync: filename is null/empty"); #endif // QT_CHECK_STATE success = FALSE; continue; } - 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)) { #ifdef QT_CHECK_STATE qWarning("QSettings::sync: failed to open '%s' for writing", file.name().latin1()); #endif // QT_CHECK_STATE success = FALSE; continue; } // spew to file QTextStream stream(&file); stream.setEncoding(QTextStream::UnicodeUTF8); while (hdit != hd.end()) { if ((*hdit).count() > 0) { stream << "[" << hdit.key() << "]" << endl; QSettingsGroup grp(*hdit); QSettingsGroup::Iterator grpit = grp.begin(); while (grpit != grp.end()) { QString v = grpit.data(); if ( v.isNull() ) { v = "\\0"; // escape null string } else { v.replace("\\", "\\\\"); // escape backslash v.replace("\n", "\\n"); // escape newlines } stream << grpit.key() << "=" << v << endl; ++grpit; } stream << endl; } ++hdit; } if (file.status() != IO_Ok) { #ifdef QT_CHECK_STATE qWarning("QSettings::sync: error at end of write"); #endif // QT_CHECK_STATE success = FALSE; } file.close(); + 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 } d->modified = FALSE; return success; } /*! \fn bool QSettings::readBoolEntry(const QString &key, bool def, bool *ok ) const Reads the entry specified by \a key, and returns a bool, or the default value, \a def, if the entry couldn't be read. If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE otherwise. \sa readEntry(), readNumEntry(), readDoubleEntry(), writeEntry(), removeEntry() */ /*! \internal */ 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 if ( ok ) *ok = FALSE; return def; } #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysReadBoolEntry( groupKey( group(), key ), def, ok ); + return d->sysReadBoolEntry( grp_key, def, ok ); #endif QString value = readEntry( key, ( def ? "true" : "false" ), ok ); if (value.lower() == "true") return TRUE; else if (value.lower() == "false") return FALSE; else if (value == "1") return TRUE; else if (value == "0") return FALSE; if (! value.isEmpty()) qWarning("QSettings::readBoolEntry: '%s' is not 'true' or 'false'", value.latin1()); if ( ok ) *ok = FALSE; return def; } /*! \fn double QSettings::readDoubleEntry(const QString &key, double def, bool *ok ) const Reads the entry specified by \a key, and returns a double, or the default value, \a def, if the entry couldn't be read. If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE otherwise. \sa readEntry(), readNumEntry(), readBoolEntry(), writeEntry(), removeEntry() */ /*! \internal */ 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 if ( ok ) *ok = FALSE; return def; } #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysReadDoubleEntry( groupKey( group(), key ), def, ok ); + return d->sysReadDoubleEntry( grp_key, def, ok ); #endif QString value = readEntry( key, QString::number(def), ok ); bool conv_ok; double retval = value.toDouble( &conv_ok ); if ( conv_ok ) return retval; if ( ! value.isEmpty() ) qWarning( "QSettings::readDoubleEntry: '%s' is not a number", value.latin1() ); if ( ok ) *ok = FALSE; return def; } /*! \fn int QSettings::readNumEntry(const QString &key, int def, bool *ok ) const Reads the entry specified by \a key, and returns an integer, or the default value, \a def, if the entry couldn't be read. If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE otherwise. \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry() */ /*! \internal */ 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 if ( ok ) *ok = FALSE; return def; } #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysReadNumEntry( groupKey( group(), key ), def, ok ); + return d->sysReadNumEntry( grp_key, def, ok ); #endif QString value = readEntry( key, QString::number( def ), ok ); bool conv_ok; int retval = value.toInt( &conv_ok ); if ( conv_ok ) return retval; if ( ! value.isEmpty() ) qWarning( "QSettings::readNumEntry: '%s' is not a number", value.latin1() ); if ( ok ) *ok = FALSE; return def; } /*! \fn QString QSettings::readEntry(const QString &key, const QString &def, bool *ok ) const Reads the entry specified by \a key, and returns a QString, or the default value, \a def, if the entry couldn't be read. If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE otherwise. \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry() */ /*! \internal */ 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 if ( ok ) *ok = FALSE; return def; } - 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 if ( ok ) // no, everything is not ok *ok = FALSE; QString realkey; - if (theKey[0] == '/') { + if (grp_key[0] == '/') { // parse our key - QStringList list(QStringList::split('/', theKey)); + QStringList list(QStringList::split('/', grp_key)); if (list.count() < 2) { #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 if ( ok ) *ok = FALSE; return def; } if (list.count() == 2) { d->heading = list[0]; d->group = "General"; realkey = list[1]; } else { d->heading = list[0]; d->group = list[1]; // remove the group from the list list.remove(list.at(1)); // remove the heading from the list list.remove(list.at(0)); realkey = list.join("/"); } - } else - realkey = theKey; + } else { + realkey = grp_key; + } QSettingsGroup grp = d->readGroup(); QSettingsGroup::const_iterator it = grp.find( realkey ), end = grp.end(); QString retval = def; if ( it != end ) { // found the value we needed retval = *it; if ( ok ) *ok = TRUE; } return retval; } #if !defined(Q_NO_BOOL_TYPE) /*! Writes the boolean entry \a value into key \a key. The \a key is created if it doesn't exist. Any previous value is overwritten by \a value. If an error occurs the settings are left unchanged and FALSE is returned; otherwise TRUE is returned. \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ 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 return FALSE; } #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysWriteEntry( groupKey( group(), key ), value ); + return d->sysWriteEntry( grp_key, value ); #endif QString s(value ? "true" : "false"); return writeEntry(key, s); } #endif /*! \overload Writes the double entry \a value into key \a key. The \a key is created if it doesn't exist. Any previous value is overwritten by \a value. If an error occurs the settings are left unchanged and FALSE is returned; otherwise TRUE is returned. \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ 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 return FALSE; } #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysWriteEntry( groupKey( group(), key ), value ); + return d->sysWriteEntry( grp_key, value ); #endif QString s(QString::number(value)); return writeEntry(key, s); } /*! \overload Writes the integer entry \a value into key \a key. The \a key is created if it doesn't exist. Any previous value is overwritten by \a value. If an error occurs the settings are left unchanged and FALSE is returned; otherwise TRUE is returned. \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ 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 return FALSE; } #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) - return d->sysWriteEntry( groupKey( group(), key ), value ); + return d->sysWriteEntry( grp_key, value ); #endif QString s(QString::number(value)); return writeEntry(key, s); } /*! \internal Writes the entry specified by \a key with the string-literal \a value, replacing any previous setting. If \a value is zero-length or null, the entry is replaced by an empty setting. \e NOTE: This function is provided because some compilers use the writeEntry (const QString &, bool) overload for this code: writeEntry ("/foo/bar", "baz") If an error occurs, this functions returns FALSE and the object is left unchanged. \sa readEntry(), removeEntry() */ 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)); } /*! \overload Writes the string entry \a value into key \a key. The \a key is created if it doesn't exist. Any previous value is overwritten by \a value. If \a value is an empty string or a null string the key's value will be an empty string. If an error occurs the settings are left unchanged and FALSE is returned; otherwise TRUE is returned. \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ 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 return FALSE; } - 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 // NOTE: we *do* allow value to be a null/empty string QString realkey; - if (theKey[0] == '/') { + if (grp_key[0] == '/') { // parse our key - QStringList list(QStringList::split('/', theKey)); + QStringList list(QStringList::split('/', grp_key)); if (list.count() < 2) { #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 return FALSE; } if (list.count() == 2) { d->heading = list[0]; d->group = "General"; realkey = list[1]; } else { d->heading = list[0]; d->group = list[1]; // remove the group from the list list.remove(list.at(1)); // remove the heading from the list list.remove(list.at(0)); realkey = list.join("/"); } - } else - realkey = theKey; + } else { + realkey = grp_key; + } d->writeGroup(realkey, value); return TRUE; } /*! Removes the entry specified by \a key. Returns TRUE if the entry existed and was removed; otherwise returns FALSE. \sa readEntry(), writeEntry() */ 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 return FALSE; } - 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 QString realkey; - - if (theKey[0] == '/') { + if (grp_key[0] == '/') { // parse our key - QStringList list(QStringList::split('/', theKey)); + QStringList list(QStringList::split('/', grp_key)); if (list.count() < 2) { #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 return FALSE; } if (list.count() == 2) { d->heading = list[0]; d->group = "General"; realkey = list[1]; } else { d->heading = list[0]; d->group = list[1]; // remove the group from the list list.remove(list.at(1)); // remove the heading from the list list.remove(list.at(0)); realkey = list.join("/"); } - } else - realkey = theKey; + } else { + realkey = grp_key; + } d->removeGroup(realkey); return TRUE; } /*! Returns a list of the keys which contain entries under \a key. Does \e not return any keys that contain keys. Example settings: \code /MyCompany/MyApplication/background color /MyCompany/MyApplication/foreground color /MyCompany/MyApplication/geometry/x /MyCompany/MyApplication/geometry/y /MyCompany/MyApplication/geometry/width /MyCompany/MyApplication/geometry/height \endcode \code QStringList keys = entryList( "/MyCompany/MyApplication" ); \endcode \c keys contains 'background color' and 'foreground color'. It does not contain 'geometry' because this key contains keys not entries. To access the geometry values could either use subkeyList() to read the keys and then read each entry, or simply read each entry directly by specifying its full key, e.g. "/MyCompany/MyApplication/geometry/y". \sa subkeyList() */ 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 return QStringList(); } - 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 QString realkey; - if (theKey[0] == '/') { + if (grp_key[0] == '/') { // parse our key - QStringList list(QStringList::split('/', theKey)); + QStringList list(QStringList::split('/', grp_key)); if (list.count() < 1) { #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 return QStringList(); } if (list.count() == 1) { d->heading = list[0]; d->group = "General"; } else { d->heading = list[0]; d->group = list[1]; // remove the group from the list list.remove(list.at(1)); // remove the heading from the list list.remove(list.at(0)); realkey = list.join("/"); } } else - realkey = theKey; + realkey = grp_key; QSettingsGroup grp = d->readGroup(); QSettingsGroup::Iterator it = grp.begin(); QStringList ret; QString itkey; while (it != grp.end()) { itkey = it.key(); ++it; if ( realkey.length() > 0 ) { if ( itkey.left( realkey.length() ) != realkey ) continue; else itkey.remove( 0, realkey.length() + 1 ); } if ( itkey.find( '/' ) != -1 ) continue; ret << itkey; } return ret; } /*! Returns a list of the keys which contain keys under \a key. Does \e not return any keys that contain entries. Example settings: \code /MyCompany/MyApplication/background color /MyCompany/MyApplication/foreground color /MyCompany/MyApplication/geometry/x /MyCompany/MyApplication/geometry/y /MyCompany/MyApplication/geometry/width /MyCompany/MyApplication/geometry/height /MyCompany/MyApplication/recent files/1 /MyCompany/MyApplication/recent files/2 /MyCompany/MyApplication/recent files/3 \endcode \code QStringList keys = subkeyList( "/MyCompany/MyApplication" ); \endcode \c keys contains 'geometry' and 'recent files'. It does not contain 'background color' or 'foreground color' because they are keys which contain entries not keys. To get a list of keys that have values rather than subkeys use entryList(). \sa entryList() */ 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 return QStringList(); } - 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 QString realkey; int subkeycount = 2; - if (theKey[0] == '/') { + if (grp_key[0] == '/') { // parse our key - QStringList list(QStringList::split('/', theKey)); + QStringList list(QStringList::split('/', grp_key)); if (list.count() < 1) { #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 return QStringList(); } subkeycount = list.count(); if (list.count() == 1) { d->heading = list[0]; d->group = "General"; } else { d->heading = list[0]; d->group = list[1]; // remove the group from the list list.remove(list.at(1)); // remove the heading from the list list.remove(list.at(0)); realkey = list.join("/"); } } else - realkey = theKey; + realkey = grp_key; QStringList ret; if ( subkeycount == 1 ) { QMap<QString,QSettingsHeading>::Iterator it = d->headings.begin(); while ( it != d->headings.end() ) { if ( it.key() != "General" && ! ret.contains( it.key() ) ) ret << it.key(); ++it; } return ret; } QSettingsGroup grp = d->readGroup(); QSettingsGroup::Iterator it = grp.begin(); QString itkey; while (it != grp.end()) { itkey = it.key(); ++it; if ( realkey.length() > 0 ) { if ( itkey.left( realkey.length() ) != realkey ) continue; else itkey.remove( 0, realkey.length() + 1 ); } int slash = itkey.find( '/' ); if ( slash == -1 ) continue; itkey.truncate( slash ); if ( ! ret.contains( itkey ) ) ret << itkey; } return ret; } /*! \internal This function returns the time of last modification for \a key. */ -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 return QDateTime(); } - QString theKey = groupKey( group(), key ); - #if !defined(QWS) && (defined(Q_WS_WIN) || defined(Q_OS_MAC)) if ( d->sysd ) return QDateTime(); #endif - if (theKey[0] == '/') { + if (grp_key[0] == '/') { // parse our key - QStringList list(QStringList::split('/', theKey)); + QStringList list(QStringList::split('/', grp_key)); if (list.count() < 2) { #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 return QDateTime(); } if (list.count() == 2) { d->heading = list[0]; d->group = "General"; } else { d->heading = list[0]; d->group = list[1]; } } return d->modificationTime(); } /*! \overload + \obsolete Writes the string list entry \a value into key \a key. The \a key is created if it doesn't exist. Any previous value is overwritten by \a value. The list is stored as a sequence of strings separated by \a separator (using QStringList::join()), so none of the strings in the list should contain the separator. If the list is empty or null the key's value will be an empty string. \warning The list should not contain empty or null strings, as readListEntry() will use QStringList::split() to recreate the list. As the documentation states, QStringList::split() will omit empty strings from the list. Because of this, it is impossible to retrieve identical list data that is stored with this function. We recommend using the writeEntry() and readListEntry() overloads that do not take a \a separator argument. + If an error occurs the settings are left unchanged and FALSE is returned; otherwise returns TRUE. - \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() + \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry(), QStringList::join() */ bool QSettings::writeEntry(const QString &key, const QStringList &value, const QChar &separator) { QString s(value.join(separator)); return writeEntry(key, s); } /*! \overload Writes the string list entry \a value into key \a key. The \a key is created if it doesn't exist. Any previous value is overwritten by \a value. If an error occurs the settings are left unchanged and FALSE is returned; otherwise returns TRUE. \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry() */ bool QSettings::writeEntry(const QString &key, const QStringList &value) { QString s; for (QStringList::ConstIterator it=value.begin(); it!=value.end(); ++it) { QString el = *it; if ( el.isNull() ) { el = "^0"; } else { el.replace("^", "^^"); } s+=el; s+="^e"; // end of element } return writeEntry(key, s); } /*! \overload QStringList QSettings::readListEntry(const QString &key, const QChar &separator, bool *ok ) const + \obsolete Reads the entry specified by \a key as a string. The \a separator 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. \warning As the documentation states, QStringList::split() will omit empty strings from the list. Because of this, it is impossible to retrieve identical list data with this function. We recommend using the readListEntry() and writeEntry() overloads that do not take a \a separator argument. - Note that if you want to iterate over the list, you should iterate over a copy, e.g. \code QStringList list = mySettings.readListEntry( "size", " " ); QStringList::Iterator it = list.begin(); while( it != list.end() ) { myProcessing( *it ); ++it; } \endcode \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry(), QStringList::split() */ /*! \internal */ QStringList QSettings::readListEntry(const QString &key, const QChar &separator, bool *ok ) { QString value = readEntry( key, QString::null, ok ); if ( ok && !*ok ) return QStringList(); return QStringList::split(separator, value); } /*! \fn QStringList QSettings::readListEntry(const QString &key, bool *ok ) const Reads the entry specified by \a key as a string. If \a ok is not 0, \a *ok is set to TRUE if the key was read, otherwise \a *ok is set to FALSE. Note that if you want to iterate over the list, you should iterate over a copy, e.g. \code QStringList list = mySettings.readListEntry( "recentfiles" ); QStringList::Iterator it = list.begin(); while( it != list.end() ) { myProcessing( *it ); ++it; } \endcode \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry(), QStringList::split() */ /*! \internal */ QStringList QSettings::readListEntry(const QString &key, bool *ok ) { QString value = readEntry( key, QString::null, ok ); if ( ok && !*ok ) return QStringList(); QStringList l; QString s; bool esc=FALSE; for (int i=0; i<(int)value.length(); i++) { if ( esc ) { if ( value[i] == 'e' ) { // end-of-string l.append(s); s=""; } else if ( value[i] == '0' ) { // null string s=QString::null; } else { s.append(value[i]); } esc=FALSE; } else if ( value[i] == '^' ) { esc = TRUE; } else { s.append(value[i]); if ( i == (int)value.length()-1 ) l.append(s); } } return l; } #ifdef Q_OS_MAC void qt_setSettingsBasePath(const QString &); //qsettings_mac.cpp #endif /*! Insert platform-dependent paths from platform-independent information. The \a domain should be an Internet domain name controlled by the producer of the software, eg. Trolltech products use "trolltech.com". The \a product should be the official name of the product. The \a scope should be QSettings::User for user-specific settings, or QSettings::Global for system-wide settings (generally these will be read-only to many users). - 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. */ void QSettings::setPath( const QString &domain, const QString &product, Scope scope ) { // On Windows, any trailing ".com(\..*)" is stripped from the domain. The // Global scope corresponds to HKEY_LOCAL_MACHINE, and User corresponds to // HKEY_CURRENT_USER. Note that on some installations, not all users can // write to the Global scope. On UNIX, any trailing ".com(\..*)" is stripped // from the domain. The Global scope corresponds to "/opt" (this would be // configurable at library build time - eg. to "/usr/local" or "/usr"), // while the User scope corresponds to $HOME/.*rc. // Note that on most installations, not all users can write to the System // scope. // // On MacOS X, if there is no "." in domain, append ".com", then reverse the // order of the elements (Mac OS uses "com.apple.finder" as domain+product). // The Global scope corresponds to /Library/Preferences/*.plist, while the // User scope corresponds to ~/Library/Preferences/*.plist. // Note that on most installations, not all users can write to the System // scope. d->globalScope = scope == Global; QString actualSearchPath; int lastDot = domain.findRev( '.' ); #if defined(Q_WS_WIN) actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product; insertSearchPath( Windows, actualSearchPath ); #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 ); #endif } /*! Appends \a group to the current key prefix. \code QSettings settings; settings.beginGroup( "/MainWindow" ); // read values settings.endGroup(); \endcode */ void QSettings::beginGroup( const QString &group ) { d->groupStack.push( group ); d->groupDirty = TRUE; } /*! Undo previous calls to beginGroup(). Note that a single beginGroup("a/b/c") is undone by a single call to endGroup(). \code QSettings settings; settings.beginGroup( "/MainWindow/Geometry" ); // read values settings.endGroup(); \endcode */ void QSettings::endGroup() { d->groupStack.pop(); d->groupDirty = TRUE; } /*! Set the current key prefix to the empty string. */ void QSettings::resetGroup() { d->groupStack.clear(); d->groupDirty = FALSE; d->groupPrefix = QString::null; } /*! Returns the current key prefix, or a null string if there is no key prefix set. \sa beginGroup(); */ QString QSettings::group() const { if ( d->groupDirty ) { d->groupDirty = FALSE; d->groupPrefix = QString::null; QValueStack<QString>::Iterator it = d->groupStack.begin(); while ( it != d->groupStack.end() ) { QString group = *it; ++it; if ( group[0] != '/' ) group.prepend( "/" ); 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,230 +1,418 @@ /**************************************************************************** -** $Id$ +** ** ** Implementation of QUuid class ** ** Copyright (C) 2000-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. ** **********************************************************************/ #include "quuid.h" -#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(). */ /*! - \fn QUuid::QUuid() + \fn QUuid::QUuid() - Creates the null UUID {00000000-0000-0000-0000-000000000000}. + Creates the null UUID {00000000-0000-0000-0000-000000000000}. */ /*! - \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 */ /*! - \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. */ #ifndef QT_NO_QUUID_STRING /*! - 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. */ 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 += "}"; data1 = temp.mid( 1, 8 ).toULong( &ok, 16 ); if ( !ok ) { *this = QUuid(); return; } data2 = temp.mid( 10, 4 ).toUInt( &ok, 16 ); if ( !ok ) { *this = QUuid(); return; } data3 = temp.mid( 15, 4 ).toUInt( &ok, 16 ); if ( !ok ) { *this = QUuid(); return; } data4[0] = temp.mid( 20, 2 ).toUInt( &ok, 16 ); if ( !ok ) { *this = QUuid(); return; } data4[1] = temp.mid( 22, 2 ).toUInt( &ok, 16 ); if ( !ok ) { *this = QUuid(); return; } for ( int i = 2; i<8; i++ ) { data4[i] = temp.mid( 25 + (i-2)*2, 2 ).toUShort( &ok, 16 ); if ( !ok ) { *this = QUuid(); return; } } } /*! - \overload + \internal */ QUuid::QUuid( const char *text ) { *this = QUuid( QString(text) ); } #endif /*! - \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. */ /*! - \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. */ /*! - \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. */ #ifndef QT_NO_QUUID_STRING /*! - \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() */ /*! - QString QUuid::toString() const + QString QUuid::toString() const - Returns the string representation of the uuid. + Returns the string representation of the uuid. */ QString QUuid::toString() const { QString result; result = "{" + QString::number( data1, 16 ).rightJustify( 8, '0' ) + "-"; result += QString::number( (int)data2, 16 ).rightJustify( 4, '0' ) + "-"; result += QString::number( (int)data3, 16 ).rightJustify( 4, '0' ) + "-"; result += QString::number( (int)data4[0], 16 ).rightJustify( 2, '0' ); result += QString::number( (int)data4[1], 16 ).rightJustify( 2, '0' ) + "-"; for ( int i = 2; i < 8; i++ ) result += QString::number( (int)data4[i], 16 ).rightJustify( 2, '0' ); return result + "}"; } #endif #ifndef QT_NO_DATASTREAM /*! - \relates QUuid - Writes the \a id to the datastream \a s. + \relates QUuid + Writes the uuid \a id to the datastream \a s. */ QDataStream &operator<<( QDataStream &s, const QUuid &id ) { s << (Q_UINT32)id.data1; s << (Q_UINT16)id.data2; s << (Q_UINT16)id.data3; for (int i = 0; i < 8; i++ ) s << (Q_UINT8)id.data4[i]; return s; } /*! - \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. */ QDataStream &operator>>( QDataStream &s, QUuid &id ) { Q_UINT32 u32; Q_UINT16 u16; Q_UINT8 u8; s >> u32; id.data1 = u32; s >> u16; id.data2 = u16; s >> u16; id.data3 = u16; for (int i = 0; i < 8; i++ ) { s >> u8; id.data4[i] = u8; } return s; } #endif /*! - 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. */ bool QUuid::isNull() const { return data4[0] == 0 && data4[1] == 0 && data4[2] == 0 && data4[3] == 0 && data4[4] == 0 && data4[5] == 0 && data4[6] == 0 && data4[7] == 0 && data1 == 0 && data2 == 0 && data3 == 0; } + +/*! + \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 + |