summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>2000-10-15 15:32:16 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>2000-10-15 15:32:16 (GMT)
commiteb7f0413527724df305245200c56f54ab2853ab7 (patch)
tree7824ba2a5c9f1fe6ddc8633a13cc7d1e7a6c79a3
parent0d0eec1df129221379625a52e5fe8ff6f21f104c (diff)
downloadDoxygen-eb7f0413527724df305245200c56f54ab2853ab7.zip
Doxygen-eb7f0413527724df305245200c56f54ab2853ab7.tar.gz
Doxygen-eb7f0413527724df305245200c56f54ab2853ab7.tar.bz2
Release-1.2.2-20001015
-rw-r--r--INSTALL4
-rw-r--r--Makefile.in10
-rw-r--r--Makefile.win.in3
-rw-r--r--README4
-rw-r--r--VERSION2
-rw-r--r--addon/configgen/configgen.cpp18
-rwxr-xr-xconfigure48
-rw-r--r--doc/config.doc18
-rw-r--r--doc/install.doc6
-rw-r--r--doc/starting.doc4
-rw-r--r--make.bat32
-rw-r--r--packages/rpm/doxygen.spec2
-rw-r--r--qtools/LICENSE.GPL349
-rw-r--r--qtools/LICENSE.QPL103
-rw-r--r--qtools/Makefile.in30
-rw-r--r--qtools/README4
-rw-r--r--qtools/qarray.h110
-rw-r--r--qtools/qasciidict.h96
-rw-r--r--qtools/qbuffer.cpp465
-rw-r--r--qtools/qbuffer.h98
-rw-r--r--qtools/qcollection.cpp182
-rw-r--r--qtools/qcollection.h74
-rw-r--r--qtools/qconfig.h8
-rw-r--r--qtools/qcstring.cpp1917
-rw-r--r--qtools/qcstring.h399
-rw-r--r--qtools/qdatastream.cpp951
-rw-r--r--qtools/qdatastream.h173
-rw-r--r--qtools/qdatetime.cpp1434
-rw-r--r--qtools/qdatetime.h215
-rw-r--r--qtools/qdict.h106
-rw-r--r--qtools/qdir.cpp1207
-rw-r--r--qtools/qdir.h235
-rw-r--r--qtools/qdir_unix.cpp286
-rw-r--r--qtools/qdir_win32.cpp406
-rw-r--r--qtools/qfeatures.h671
-rw-r--r--qtools/qfile.cpp550
-rw-r--r--qtools/qfile.h124
-rw-r--r--qtools/qfile_unix.cpp601
-rw-r--r--qtools/qfile_win32.cpp582
-rw-r--r--qtools/qfiledefs_p.h259
-rw-r--r--qtools/qfileinfo.cpp458
-rw-r--r--qtools/qfileinfo.h138
-rw-r--r--qtools/qfileinfo_unix.cpp425
-rw-r--r--qtools/qfileinfo_win32.cpp334
-rw-r--r--qtools/qgarray.cpp747
-rw-r--r--qtools/qgarray.h120
-rw-r--r--qtools/qgdict.cpp1215
-rw-r--r--qtools/qgdict.h222
-rw-r--r--qtools/qgeneric.h43
-rw-r--r--qtools/qglist.cpp1223
-rw-r--r--qtools/qglist.h257
-rw-r--r--qtools/qglobal.cpp678
-rw-r--r--qtools/qglobal.h592
-rw-r--r--qtools/qgvector.cpp638
-rw-r--r--qtools/qgvector.h120
-rw-r--r--qtools/qintdict.h102
-rw-r--r--qtools/qiodevice.cpp636
-rw-r--r--qtools/qiodevice.h155
-rw-r--r--qtools/qlist.h140
-rw-r--r--qtools/qptrdict.h103
-rw-r--r--qtools/qqueue.h70
-rw-r--r--qtools/qregexp.cpp1091
-rw-r--r--qtools/qregexp.h92
-rw-r--r--qtools/qshared.h55
-rw-r--r--qtools/qsortedlist.h59
-rw-r--r--qtools/qstack.h70
-rw-r--r--qtools/qstring.cpp15205
-rw-r--r--qtools/qstring.h821
-rw-r--r--qtools/qstringlist.cpp302
-rw-r--r--qtools/qstringlist.h81
-rw-r--r--qtools/qstrlist.h109
-rw-r--r--qtools/qstrvec.h90
-rw-r--r--qtools/qtextcodec.cpp2019
-rw-r--r--qtools/qtextcodec.h104
-rw-r--r--qtools/qtextstream.cpp2145
-rw-r--r--qtools/qtextstream.h347
-rw-r--r--qtools/qtl.h223
-rw-r--r--qtools/qtools.pro.in71
-rw-r--r--qtools/qvaluelist.h449
-rw-r--r--qtools/qvector.h85
-rw-r--r--src/classdef.cpp42
-rw-r--r--src/classdef.h2
-rw-r--r--src/code.l3
-rw-r--r--src/config.h4
-rw-r--r--src/config.l33
-rw-r--r--src/doc.l115
-rw-r--r--src/doxygen.cpp22
-rw-r--r--src/doxygen.dtd4
-rw-r--r--src/doxygen.pro.in10
-rw-r--r--src/doxytag.pro.in12
-rw-r--r--src/entry.h4
-rw-r--r--src/filedef.cpp1
-rw-r--r--src/groupdef.cpp2
-rw-r--r--src/htmlgen.cpp2
-rw-r--r--src/index.cpp28
-rw-r--r--src/language.cpp5
-rw-r--r--src/logos.cpp38
-rw-r--r--src/logos.h2
-rw-r--r--src/mangen.cpp19
-rw-r--r--src/memberdef.cpp19
-rw-r--r--src/memberdef.h8
-rw-r--r--src/memberlist.cpp21
-rw-r--r--src/message.cpp35
-rw-r--r--src/message.h2
-rw-r--r--src/scanner.l14
-rw-r--r--src/translator.h20
-rw-r--r--src/translator_cn.h707
-rw-r--r--src/translator_cz.h18
-rw-r--r--src/translator_nl.h35
-rw-r--r--src/util.cpp708
-rw-r--r--src/util.h18
-rw-r--r--src/xml_dtd.h4
112 files changed, 45130 insertions, 447 deletions
diff --git a/INSTALL b/INSTALL
index fcc29d6..c9fffeb 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,6 +1,6 @@
-DOXYGEN Version 1.2.2-20001001
+DOXYGEN Version 1.2.2-20001015
Please read the installation section of the manual for instructions.
--------
-Dimitri van Heesch (01 October 2000)
+Dimitri van Heesch (15 October 2000)
diff --git a/Makefile.in b/Makefile.in
index 95fc3ae..812c91b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,10 +1,12 @@
all: src/version.cpp configgen doxywizard
+ cd qtools ; $(MAKE)
cd src ; $(MAKE)
clean: FORCE
cd examples ; $(MAKE) clean
cd doc ; $(MAKE) clean
+ cd qtools ; $(MAKE) clean
cd src ; $(MAKE) clean
cd addon/configgen ; $(MAKE) clean
cd addon/doxywizard ; $(MAKE) clean
@@ -13,16 +15,14 @@ clean: FORCE
-rm -f objects/*.o
distclean: clean
- cd examples ; $(MAKE) clean
- cd doc ; $(MAKE) clean
cd src ; $(MAKE) distclean
cd addon/configgen ; $(MAKE) distclean
cd addon/doxywizard ; $(MAKE) distclean
-rm -f bin/doxy*
-rm -f html
-rm -f objects/*.o
- -rm -f src/Makefile.doxygen src/Makefile.doxytag src/Makefile.doxysearch
- -rm -f Makefile src/Makefile examples/Makefile doc/Makefile
+ -rm -f src/Makefile.doxygen src/Makefile.doxytag src/Makefile.doxysearch qtools/Makefile.qtools
+ -rm -f Makefile qtools/Makefile src/Makefile examples/Makefile doc/Makefile
-rm -f .makeconfig .tmakeconfig
-rm -f src/doxygen.pro src/doxytag.pro src/doxysearch.pro
-rm -f src/version.cpp
@@ -69,7 +69,7 @@ pdf: docs
archive: clean
tar zcvf dx`date +%y%m%d`.tgz addon tmake doc wintools examples bin objects \
- src configure configure.bin Makefile.in Makefile.win.in INSTALL \
+ qtools src configure configure.bin Makefile.in Makefile.win.in INSTALL \
make.bat LANGUAGE.HOWTO LICENSE PLATFORMS VERSION packages
src/version.cpp: Makefile
diff --git a/Makefile.win.in b/Makefile.win.in
index add71f6..4ca50ec 100644
--- a/Makefile.win.in
+++ b/Makefile.win.in
@@ -1,5 +1,8 @@
all: src\version.cpp
set TMAKEPATH=$(TMAKEPATH)
+ cd qtools
+ $(MAKE)
+ cd ..
cd src
$(MAKE)
diff --git a/README b/README
index 94dbeff..c67bd3b 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-DOXYGEN Version 1.2.2-20001001
+DOXYGEN Version 1.2.2-20001015
Please read INSTALL for compilation instructions.
@@ -7,4 +7,4 @@ The latest version of doxygen can be obtained at
Enjoy,
-Dimitri van Heesch (01 October 2000)
+Dimitri van Heesch (15 October 2000)
diff --git a/VERSION b/VERSION
index 906cfeb..fdad0e7 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.2.2-20001001
+1.2.2-20001015
diff --git a/addon/configgen/configgen.cpp b/addon/configgen/configgen.cpp
index 7a11fc0..c9d5a2d 100644
--- a/addon/configgen/configgen.cpp
+++ b/addon/configgen/configgen.cpp
@@ -1075,6 +1075,14 @@ void init()
"tags, which will be replaced by the file and line number from which the \n"
"warning originated and the warning text. \n"
);
+ ConfigString::add("warnLogFile",
+ "WARN_LOGFILE",
+ "",
+ "log file to write warning to",
+ "The WARN_LOGFILE tag can be used to specify a file to which warning \n"
+ "and error messages should be written. If left blank the output is written \n"
+ "to stderr. \n"
+ );
//-----------------------------------------------------------------------------------------------
ConfigInfo::add( "Input","configuration options related to the input files");
//-----------------------------------------------------------------------------------------------
@@ -1658,7 +1666,15 @@ void init()
100,30000
);
addDependency("maxDotGraphHeight","haveDotFlag");
-
+ ConfigBool::add( "generateLegend",
+ "GENERATE_LEGEND",
+ "TRUE",
+ "generate legend page",
+ "If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will \n"
+ "generate a legend page explaining the meaning of the various boxes and \n"
+ "arrows in the dot generated graphs. \n"
+ );
+ addDependency("generateLegend","haveDotFlag");
//-----------------------------------------------------------------------------------------------
ConfigInfo::add( "Search","Configuration::addtions related to the search engine ");
diff --git a/configure b/configure
index 9649450..9f5021a 100755
--- a/configure
+++ b/configure
@@ -218,27 +218,27 @@ if test "$f_plf_auto" = NO; then
fi
#- check for qt --------------------------------------------------------------
-
-echo -n " Checking for Qt..."
-if test -z "$QTDIR"; then
- echo "QTDIR not set!"
- echo
- echo "tmake requires the QTDIR environment variable to be set."
- echo "check your Qt installation!"
- exit 2
-else
- if test ! -d "$QTDIR/lib"; then
- echo "QTDIR is set, but library directory does not exist!"
- exit 2
- fi
- if test ! -d "$QTDIR/include"; then
- echo "QTDIR is set, but include directory does not exist!"
- exit 2
- fi
- echo " headers $QTDIR/include,"
- echo " libraries $QTDIR/lib"
-fi
-
+#
+# echo -n " Checking for Qt..."
+# if test -z "$QTDIR"; then
+# echo "QTDIR not set!"
+# echo
+# echo "tmake requires the QTDIR environment variable to be set."
+# echo "check your Qt installation!"
+# exit 2
+# else
+# if test ! -d "$QTDIR/lib"; then
+# echo "QTDIR is set, but library directory does not exist!"
+# exit 2
+# fi
+# if test ! -d "$QTDIR/include"; then
+# echo "QTDIR is set, but include directory does not exist!"
+# exit 2
+# fi
+# echo " headers $QTDIR/include,"
+# echo " libraries $QTDIR/lib"
+# fi
+#
# - check for make ------------------------------------------------------------
echo -n " Checking for GNU make tool... "
@@ -268,7 +268,7 @@ echo "using $f_make"
# - check for dot ------------------------------------------------------------
-echo -n " Checking for dot... "
+echo -n " Checking for dot (part of GraphViz)... "
if test "$f_dot" = NO; then
dot_dirs="$bin_dirs"
dot_prog=NO
@@ -374,7 +374,7 @@ TMAKE_CXXFLAGS = -DENGLISH_ONLY
EOF
fi
-f_inmakefiles="Makefile.in src/Makefile.in examples/Makefile.in doc/Makefile.in addon/configgen/Makefile.in addon/doxywizard/Makefile.in addon/xmlread/Makefile.in"
+f_inmakefiles="Makefile.in qtools/Makefile.in src/Makefile.in examples/Makefile.in doc/Makefile.in addon/configgen/Makefile.in addon/doxywizard/Makefile.in addon/xmlread/Makefile.in"
for i in $f_inmakefiles ; do
SRC=$i
@@ -404,7 +404,7 @@ EOF
echo " Created $DST from $SRC..."
done
-f_inprofiles="src/doxygen.pro.in src/doxytag.pro.in src/doxysearch.pro.in addon/configgen/configgen.pro.in addon/doxywizard/doxywizard.pro.in addon/xmlread/xmlread.pro.in"
+f_inprofiles="qtools/qtools.pro.in src/doxygen.pro.in src/doxytag.pro.in src/doxysearch.pro.in addon/configgen/configgen.pro.in addon/doxywizard/doxywizard.pro.in addon/xmlread/xmlread.pro.in"
for i in $f_inprofiles ; do
SRC=$i
diff --git a/doc/config.doc b/doc/config.doc
index 9b92688..1d3046f 100644
--- a/doc/config.doc
+++ b/doc/config.doc
@@ -103,6 +103,7 @@ followed by the descriptions of the tags grouped by category.
<li> \refitem cfg_generate_html GENERATE_HTML
<li> \refitem cfg_generate_htmlhelp GENERATE_HTMLHELP
<li> \refitem cfg_generate_latex GENERATE_LATEX
+<li> \refitem cfg_generate_legend GENERATE_LEGEND
<li> \refitem cfg_generate_man GENERATE_MAN
<li> \refitem cfg_generate_rtf GENERATE_RTF
<li> \refitem cfg_generate_tagfile GENERATE_TAGFILE
@@ -163,6 +164,7 @@ followed by the descriptions of the tags grouped by category.
<li> \refitem cfg_verbatim_headers VERBATIM_HEADERS
<li> \refitem cfg_warn_format WARN_FORMAT
<li> \refitem cfg_warn_if_undocumented WARN_IF_UNDOCUMENTED
+<li> \refitem cfg_warn_logfile WARN_LOGFILE
<li> \refitem cfg_warnings WARNINGS
\htmlonly
</ul>
@@ -481,12 +483,19 @@ followed by the descriptions of the tags grouped by category.
\anchor cfg_warn_format
<dt>\c WARN_FORMAT <dd>
\addindex WARN_FORMAT
- The WARN_FORMAT tag determines the format of the warning messages that
+ The \c WARN_FORMAT tag determines the format of the warning messages that
doxygen can produce. The string should contain the <code>\$file</code>,
<code>\$line</code>, and <code>\$text</code>
tags, which will be replaced by the file and line number from which the
warning originated and the warning text.
+\anchor cfg_warn_logfile
+<dt>\c WARN_LOGFILE <dd>
+ \addindex WARN_LOGFILE
+ The \c WARN_LOGFILE tag can be used to specify a file to which warning
+ and error messages should be written. If left blank the output is written
+ to stderr.
+
</dl>
\subsection config_input Input related options
@@ -1061,6 +1070,13 @@ TAGFILES = file1=loc1 "file2 = loc2" ... </pre>
the specified constraint. Beware that most browsers cannot cope with very
large images.
+\anchor cfg_generate_legend <dd>
+<dt>\c GENERATE_LEGEND <dd>
+ \addindex GENERATE_LEGEND
+ If the \c GENERATE_LEGEND tag is set to \c YES (the default) Doxygen will
+ generate a legend page explaining the meaning of the various boxes and
+ arrows in the dot generated graphs.
+
</dl>
\subsection config_search Search engine options
\anchor cfg_searchengine
diff --git a/doc/install.doc b/doc/install.doc
index 2d31184..3b0c6b2 100644
--- a/doc/install.doc
+++ b/doc/install.doc
@@ -337,7 +337,7 @@ Here is what is required:
variables (if you did not select to do this automatically during
installation).
<li>Perl 5.0 or higher for Windows. This can be download from:
- http://www.ActiveState.com/pw32
+ http://www.ActiveState.com/Products/ActivePerl/
<li>The GNU tools flex, bison and sed.
To get these working on Windows you should install the
<a href="http://sourceware.cygnus.com/cygwin/">cygwin tools</a>
@@ -351,8 +351,8 @@ Here is what is required:
the directory they are in to the search path.
<li>A professional license of
- <A HREF="http://www.trolltech.com/products/qt.html">Qt for Windows</A><br>
- \latexonly(see {\tt http://www.trolltech.com/products/qt.html})\endlatexonly.
+ <A HREF="http://www.trolltech.com/products/qt.html">Qt for Windows</A>
+ \latexonly\par (see {\tt http://www.trolltech.com/products/qt.html})\endlatexonly.
If you do not have that and you can live without the GUI front-end
you can also download Qt-1.44 for X11. Doxygen only the depends on
diff --git a/doc/starting.doc b/doc/starting.doc
index b518838..70dfc50 100644
--- a/doc/starting.doc
+++ b/doc/starting.doc
@@ -131,7 +131,7 @@ of compiling the generated
documentation, \c doxygen writes a \c Makefile into the \c latex directory.
By typing \c make in the \c latex directory the dvi file \c refman.dvi
will be generated (provided that you have a make tool called
-<code>make</code> ofcourse). This file can then be viewed using \c xdvi or
+<code>make</code> of course). This file can then be viewed using \c xdvi or
converted into a postscript file \c refman.ps by
typing <code>make ps</code> (this requires <code>dvips</code>).
To put 2 pages on one physical page use <code>make ps_2on1</code> instead.
@@ -152,7 +152,7 @@ capabilities of the man page format, so some information
\subsection step3 Step 3: Documenting the sources
Although documenting the source is presented as step 3, in a new project
-this should ofcourse be step 1. Here I assume
+this should of course be step 1. Here I assume
you already have some code and you want doxygen to generate a nice document
describing the API and maybe the internals as well.
diff --git a/make.bat b/make.bat
deleted file mode 100644
index 67d3a26..0000000
--- a/make.bat
+++ /dev/null
@@ -1,32 +0,0 @@
-REM make script for Microsoft Visual C++
-
-REM goto OK
-
-if not '%QTDIR%'=='' goto OK
-echo The QTDIR environment variable is not set! See the INSTALL file for more info.
-rem You can also remove the comment from the upper "REM goto OK" line
-rem and set the QTDIR correctly on the line below.
-goto END
-:OK
-
-REM Change the QTDIR setting as appropriate (at the following line)
-if '%QTDIR%'=='' set QTDIR=c:\usr\qt-1.44
-
-REM Generate the batch for compilation from the src subdirectory (make.bat)
-echo set QTDIR=%QTDIR%>src\make.bat
-echo nmake>>src\make.bat
-
-REM use perl to create the config file
-perl wintools\make.pl
-
-type makeconfig Makefile.win.in >Makefile
-type makeconfig src\Makefile.in >src\Makefile
-type makeconfig examples\Makefile.win.in >examples\Makefile
-type makeconfig doc\Makefile.win.in >doc\Makefile
-type src\doxygen.pro.in | sed "s/\$extraopts/release/g" >src\doxygen.pro
-type src\doxytag.pro.in | sed "s/\$extraopts/release/g" >src\doxytag.pro
-type src\doxysearch.pro.in | sed "s/\$extraopts/release/g" >src\doxysearch.pro
-
-nmake
-
-:END
diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec
index bb0d2f8..ee917cc 100644
--- a/packages/rpm/doxygen.spec
+++ b/packages/rpm/doxygen.spec
@@ -1,5 +1,5 @@
Name: doxygen
-Version: 1.2.2-20001001
+Version: 1.2.2-20001015
Summary: documentation system for C, C++ and IDL
Release: 1
Source0: doxygen-%{version}.src.tar.gz
diff --git a/qtools/LICENSE.GPL b/qtools/LICENSE.GPL
new file mode 100644
index 0000000..935a2a0
--- /dev/null
+++ b/qtools/LICENSE.GPL
@@ -0,0 +1,349 @@
+
+ The Qt GUI Toolkit is Copyright (C) 1994-2000 Trolltech AS.
+
+ You may use, distribute and copy the Qt GUI Toolkit under the terms of
+ GNU General Public License version 2, which is display below.
+
+-------------------------------------------------------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+-------------------------------------------------------------------------
diff --git a/qtools/LICENSE.QPL b/qtools/LICENSE.QPL
new file mode 100644
index 0000000..ecdad6e
--- /dev/null
+++ b/qtools/LICENSE.QPL
@@ -0,0 +1,103 @@
+ THE Q PUBLIC LICENSE
+ version 1.0
+
+ Copyright (C) 1999-2000 Trolltech AS, Norway.
+ Everyone is permitted to copy and
+ distribute this license document.
+
+The intent of this license is to establish freedom to share and change the
+software regulated by this license under the open source model.
+
+This license applies to any software containing a notice placed by the
+copyright holder saying that it may be distributed under the terms of
+the Q Public License version 1.0. Such software is herein referred to as
+the Software. This license covers modification and distribution of the
+Software, use of third-party application programs based on the Software,
+and development of free software which uses the Software.
+
+ Granted Rights
+
+1. You are granted the non-exclusive rights set forth in this license
+ provided you agree to and comply with any and all conditions in this
+ license. Whole or partial distribution of the Software, or software
+ items that link with the Software, in any form signifies acceptance of
+ this license.
+
+2. You may copy and distribute the Software in unmodified form provided
+ that the entire package, including - but not restricted to - copyright,
+ trademark notices and disclaimers, as released by the initial developer
+ of the Software, is distributed.
+
+3. You may make modifications to the Software and distribute your
+ modifications, in a form that is separate from the Software, such as
+ patches. The following restrictions apply to modifications:
+
+ a. Modifications must not alter or remove any copyright notices in
+ the Software.
+
+ b. When modifications to the Software are released under this
+ license, a non-exclusive royalty-free right is granted to the
+ initial developer of the Software to distribute your modification
+ in future versions of the Software provided such versions remain
+ available under these terms in addition to any other license(s) of
+ the initial developer.
+
+4. You may distribute machine-executable forms of the Software or
+ machine-executable forms of modified versions of the Software, provided
+ that you meet these restrictions:
+
+ a. You must include this license document in the distribution.
+
+ b. You must ensure that all recipients of the machine-executable forms
+ are also able to receive the complete machine-readable source code
+ to the distributed Software, including all modifications, without
+ any charge beyond the costs of data transfer, and place prominent
+ notices in the distribution explaining this.
+
+ c. You must ensure that all modifications included in the
+ machine-executable forms are available under the terms of this
+ license.
+
+5. You may use the original or modified versions of the Software to
+ compile, link and run application programs legally developed by you
+ or by others.
+
+6. You may develop application programs, reusable components and other
+ software items that link with the original or modified versions of the
+ Software. These items, when distributed, are subject to the following
+ requirements:
+
+ a. You must ensure that all recipients of machine-executable forms of
+ these items are also able to receive and use the complete
+ machine-readable source code to the items without any charge
+ beyond the costs of data transfer.
+
+ b. You must explicitly license all recipients of your items to use
+ and re-distribute original and modified versions of the items in
+ both machine-executable and source code forms. The recipients must
+ be able to do so without any charges whatsoever, and they must be
+ able to re-distribute to anyone they choose.
+
+
+ c. If the items are not available to the general public, and the
+ initial developer of the Software requests a copy of the items,
+ then you must supply one.
+
+ Limitations of Liability
+
+In no event shall the initial developers or copyright holders be liable
+for any damages whatsoever, including - but not restricted to - lost
+revenue or profits or other direct, indirect, special, incidental or
+consequential damages, even if they have been advised of the possibility
+of such damages, except to the extent invariable law, if any, provides
+otherwise.
+
+ No Warranty
+
+The Software and this license document are provided AS IS with NO WARRANTY
+OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE.
+ Choice of Law
+
+This license is governed by the Laws of Norway. Disputes shall be settled
+by Oslo City Court.
diff --git a/qtools/Makefile.in b/qtools/Makefile.in
new file mode 100644
index 0000000..730d6b2
--- /dev/null
+++ b/qtools/Makefile.in
@@ -0,0 +1,30 @@
+#
+#
+#
+# Copyright (C) 1997-2000 by Dimitri van Heesch.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation under the terms of the GNU General Public License is hereby
+# granted. No representations are made about the suitability of this software
+# for any purpose. It is provided "as is" without express or implied warranty.
+# See the GNU General Public License for more details.
+#
+# Documents produced by Doxygen are derivative works derived from the
+# input used in their production; they are not affected by this license.
+#
+
+all: Makefile.qtools Makefile
+ $(MAKE) -f Makefile.qtools $@
+
+Makefile.qtools: qtools.pro
+ $(PERL) $(TMAKE) qtools.pro >Makefile.qtools
+
+tmake:
+ $(PERL) $(TMAKE) qtools.pro >Makefile.qtools
+
+clean: Makefile.qtools
+ $(MAKE) -f Makefile.qtools clean
+
+distclean: clean
+
+FORCE:
diff --git a/qtools/README b/qtools/README
new file mode 100644
index 0000000..1e7fc8d
--- /dev/null
+++ b/qtools/README
@@ -0,0 +1,4 @@
+This directory contains a small subset of Troll-Tech's Qt library
+The subset is enough to build the doxygen executable, but lacks many of
+the features found in the Qt library. See http://www.trolltech.com
+for the full package.
diff --git a/qtools/qarray.h b/qtools/qarray.h
new file mode 100644
index 0000000..90dcbb7
--- /dev/null
+++ b/qtools/qarray.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+**
+** Definition of QArray template/macro class
+**
+** Created : 930906
+**
+** Copyright (C) 1992-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 QARRAY_H
+#define QARRAY_H
+
+#ifndef QT_H
+#include "qgarray.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QArray : public QGArray
+{
+public:
+ typedef type* Iterator;
+ typedef const type* ConstIterator;
+ typedef type ValueType;
+
+protected:
+ QArray( int, int ) : QGArray( 0, 0 ) {}
+
+public:
+ QArray() {}
+ QArray( int size ) : QGArray(size*sizeof(type)) {}
+ QArray( const QArray<type> &a ) : QGArray(a) {}
+ ~QArray() {}
+ QArray<type> &operator=(const QArray<type> &a)
+ { return (QArray<type>&)QGArray::assign(a); }
+ type *data() const { return (type *)QGArray::data(); }
+ uint nrefs() const { return QGArray::nrefs(); }
+ uint size() const { return QGArray::size()/sizeof(type); }
+ uint count() const { return size(); }
+ bool isEmpty() const { return QGArray::size() == 0; }
+ bool isNull() const { return QGArray::data() == 0; }
+ bool resize( uint size ) { return QGArray::resize(size*sizeof(type)); }
+ bool truncate( uint pos ) { return QGArray::resize(pos*sizeof(type)); }
+ bool fill( const type &d, int size = -1 )
+ { return QGArray::fill((char*)&d,size,sizeof(type) ); }
+ void detach() { QGArray::detach(); }
+ QArray<type> copy() const
+ { QArray<type> tmp; return tmp.duplicate(*this); }
+ QArray<type>& assign( const QArray<type>& a )
+ { return (QArray<type>&)QGArray::assign(a); }
+ QArray<type>& assign( const type *a, uint n )
+ { return (QArray<type>&)QGArray::assign((char*)a,n*sizeof(type)); }
+ QArray<type>& duplicate( const QArray<type>& a )
+ { return (QArray<type>&)QGArray::duplicate(a); }
+ QArray<type>& duplicate( const type *a, uint n )
+ { return (QArray<type>&)QGArray::duplicate((char*)a,n*sizeof(type)); }
+ QArray<type>& setRawData( const type *a, uint n )
+ { return (QArray<type>&)QGArray::setRawData((char*)a,
+ n*sizeof(type)); }
+ void resetRawData( const type *a, uint n )
+ { QGArray::resetRawData((char*)a,n*sizeof(type)); }
+ int find( const type &d, uint i=0 ) const
+ { return QGArray::find((char*)&d,i,sizeof(type)); }
+ int contains( const type &d ) const
+ { return QGArray::contains((char*)&d,sizeof(type)); }
+ void sort() { QGArray::sort(sizeof(type)); }
+ int bsearch( const type &d ) const
+ { return QGArray::bsearch((const char*)&d,sizeof(type)); }
+ type& operator[]( int i ) const
+ { return (type &)(*(type *)QGArray::at(i*sizeof(type))); }
+ type& at( uint i ) const
+ { return (type &)(*(type *)QGArray::at(i*sizeof(type))); }
+ operator const type*() const { return (const type *)QGArray::data(); }
+ bool operator==( const QArray<type> &a ) const { return isEqual(a); }
+ bool operator!=( const QArray<type> &a ) const { return !isEqual(a); }
+ Iterator begin() { return data(); }
+ Iterator end() { return data() + size(); }
+ ConstIterator begin() const { return data(); }
+ ConstIterator end() const { return data() + size(); }
+};
+
+
+#endif // QARRAY_H
diff --git a/qtools/qasciidict.h b/qtools/qasciidict.h
new file mode 100644
index 0000000..3f2deaf
--- /dev/null
+++ b/qtools/qasciidict.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+**
+** Definition of QAsciiDict template class
+**
+** Created : 920821
+**
+** Copyright (C) 1992-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 QASCIIDICT_H
+#define QASCIIDICT_H
+
+#ifndef QT_H
+#include "qgdict.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QAsciiDict : public QGDict
+{
+public:
+ QAsciiDict(int size=17, bool caseSensitive=TRUE, bool copyKeys=TRUE )
+ : QGDict(size,AsciiKey,caseSensitive,copyKeys) {}
+ QAsciiDict( const QAsciiDict<type> &d ) : QGDict(d) {}
+ ~QAsciiDict() { clear(); }
+ QAsciiDict<type> &operator=(const QAsciiDict<type> &d)
+ { return (QAsciiDict<type>&)QGDict::operator=(d); }
+ uint count() const { return QGDict::count(); }
+ uint size() const { return QGDict::size(); }
+ bool isEmpty() const { return QGDict::count() == 0; }
+
+ void insert( const char *k, const type *d )
+ { QGDict::look_ascii(k,(Item)d,1); }
+ void replace( const char *k, const type *d )
+ { QGDict::look_ascii(k,(Item)d,2); }
+ bool remove( const char *k ) { return QGDict::remove_ascii(k); }
+ type *take( const char *k ) { return (type *)QGDict::take_ascii(k); }
+ type *find( const char *k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_ascii(k,0,0); }
+ type *operator[]( const char *k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_ascii(k,0,0); }
+
+ void clear() { QGDict::clear(); }
+ void resize( uint n ) { QGDict::resize(n); }
+ void statistics() const { QGDict::statistics(); }
+private:
+ void deleteItem( Item d ) { if ( del_item ) delete (type *)d; }
+};
+
+
+template<class type> class Q_EXPORT QAsciiDictIterator : public QGDictIterator
+{
+public:
+ QAsciiDictIterator(const QAsciiDict<type> &d)
+ : QGDictIterator((QGDict &)d) {}
+ ~QAsciiDictIterator() {}
+ uint count() const { return dict->count(); }
+ bool isEmpty() const { return dict->count() == 0; }
+ type *toFirst() { return (type *)QGDictIterator::toFirst(); }
+ operator type *() const { return (type *)QGDictIterator::get(); }
+ type *current() const { return (type *)QGDictIterator::get(); }
+ const char *currentKey() const { return QGDictIterator::getKeyAscii(); }
+ type *operator()() { return (type *)QGDictIterator::operator()(); }
+ type *operator++() { return (type *)QGDictIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j);}
+};
+
+
+#endif // QASCIIDICT_H
diff --git a/qtools/qbuffer.cpp b/qtools/qbuffer.cpp
new file mode 100644
index 0000000..beed0ba
--- /dev/null
+++ b/qtools/qbuffer.cpp
@@ -0,0 +1,465 @@
+/****************************************************************************
+**
+**
+** Implementation of QBuffer class
+**
+** Created : 930812
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qbuffer.h"
+#include <stdlib.h>
+
+// REVISED: paul
+/*!
+ \class QBuffer qbuffer.h
+ \brief The QBuffer class is an I/O device that operates on a QByteArray
+
+ \ingroup io
+
+ QBuffer allows reading and writing a memory buffer. It is normally
+ used together with a QTextStream or a QDataStream. QBuffer has an
+ associated QByteArray which holds the buffer data. The size() of the
+ buffer is automatically adjusted as data is written.
+
+ The constructor \c QBuffer(QByteArray) creates a QBuffer with an
+ existing byte array. The byte array can also be set with setBuffer().
+ Writing to the QBuffer will modify the original byte array, since
+ QByteArray is \link shclass.html explicitly shared.\endlink
+
+ Use open() to open the buffer before use, and to set the mode
+ (read-only,write-only, etc.). close() closes the buffer. The buffer
+ must be closed before reopening or calling setBuffer().
+
+ The common way to use QBuffer is through \l QDataStream or \l QTextStream
+ which have constructors that take a QBuffer parameter. For
+ convenience, there are also QDataStream and QTextStream constructors
+ that take a QByteArray parameter. These constructors create and open
+ an internal QBuffer.
+
+ Note that QTextStream can also operate on a QString (a Unicode
+ string); a QBuffer cannot.
+
+ You can also use QBuffer directly through the standard QIODevice
+ functions readBlock(), writeBlock() readLine(), at(), getch(), putch() and
+ ungetch().
+
+ \sa QFile, QDataStream, QTextStream, QByteArray, \link shclass.html Shared Classes\endlink
+*/
+
+
+/*!
+ Constructs an empty buffer.
+*/
+
+QBuffer::QBuffer()
+{
+ setFlags( IO_Direct );
+ a_inc = 16; // initial increment
+ a_len = 0;
+ ioIndex = 0;
+}
+
+
+/*!
+ Constructs a buffer that operates on \a buf.
+ If you open the buffer in write mode (\c IO_WriteOnly or
+ \c IO_ReadWrite) and write something into the buffer, \a buf
+ will be modified.
+
+
+ Example:
+ \code
+ QCString str = "abc";
+ QBuffer b( str );
+ b.open( IO_WriteOnly );
+ b.at( 3 ); // position at \0
+ b.writeBlock( "def", 4 ); // write including \0
+ b.close();
+ // Now, str == "abcdef"
+ \endcode
+
+
+ \sa setBuffer()
+*/
+
+QBuffer::QBuffer( QByteArray buf ) : a(buf)
+{
+ setFlags( IO_Direct );
+ a_len = a.size();
+ a_inc = (a_len > 512) ? 512 : a_len; // initial increment
+ if ( a_inc < 16 )
+ a_inc = 16;
+ ioIndex = 0;
+}
+
+/*!
+ Destructs the buffer.
+*/
+
+QBuffer::~QBuffer()
+{
+}
+
+
+/*!
+ Replaces the buffer's contents with \a buf.
+
+ This may not be done when isOpen() is TRUE.
+
+ Note that if you open the buffer in write mode (\c IO_WriteOnly or
+ IO_ReadWrite) and write something into the buffer, \a buf is also
+ modified because QByteArray is an explicitly shared class.
+
+ \sa buffer(), open(), close()
+*/
+
+bool QBuffer::setBuffer( QByteArray buf )
+{
+ if ( isOpen() ) {
+#if defined(CHECK_STATE)
+ qWarning( "QBuffer::setBuffer: Buffer is open");
+#endif
+ return FALSE;
+ }
+ a = buf;
+ a_len = a.size();
+ a_inc = (a_len > 512) ? 512 : a_len; // initial increment
+ if ( a_inc < 16 )
+ a_inc = 16;
+ ioIndex = 0;
+ return TRUE;
+}
+
+/*!
+ \fn QByteArray QBuffer::buffer() const
+
+ Returns this buffer's byte array.
+
+ \sa setBuffer()
+*/
+
+/*!
+ \reimp
+ Opens the buffer in the mode \a m. Returns TRUE if successful,
+ otherwise FALSE. The buffer must be opened before use.
+
+ The mode parameter \a m must be a combination of the following flags.
+ <ul>
+ <li>\c IO_ReadOnly opens a buffer in read-only mode.
+ <li>\c IO_WriteOnly opens a buffer in write-only mode.
+ <li>\c IO_ReadWrite opens a buffer in read/write mode.
+ <li>\c IO_Append sets the buffer index to the end of the buffer.
+ <li>\c IO_Truncate truncates the buffer.
+ </ul>
+
+ \sa close(), isOpen()
+*/
+
+bool QBuffer::open( int m )
+{
+ if ( isOpen() ) { // buffer already open
+#if defined(CHECK_STATE)
+ qWarning( "QBuffer::open: Buffer already open" );
+#endif
+ return FALSE;
+ }
+ setMode( m );
+ if ( m & IO_Truncate ) { // truncate buffer
+ a.resize( 0 );
+ a_len = 0;
+ }
+ if ( m & IO_Append ) { // append to end of buffer
+ ioIndex = a.size();
+ } else {
+ ioIndex = 0;
+ }
+ a_inc = 16;
+ setState( IO_Open );
+ setStatus( 0 );
+ return TRUE;
+}
+
+/*!
+ \reimp
+ Closes an open buffer.
+ \sa open()
+*/
+
+void QBuffer::close()
+{
+ if ( isOpen() ) {
+ setFlags( IO_Direct );
+ ioIndex = 0;
+ a_inc = 16;
+ }
+}
+
+/*!
+ \reimp
+ The flush function does nothing for a QBuffer.
+*/
+
+void QBuffer::flush()
+{
+ return;
+}
+
+
+/*!
+ \fn int QBuffer::at() const
+ \reimp
+*/
+
+/*!
+ \fn uint QBuffer::size() const
+ \reimp
+*/
+
+/*!
+ \reimp
+*/
+
+bool QBuffer::at( int pos )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "QBuffer::at: Buffer is not open" );
+ return FALSE;
+ }
+#endif
+ if ( (uint)pos > a_len ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QBuffer::at: Index %d out of range", pos );
+#endif
+ return FALSE;
+ }
+ ioIndex = pos;
+ return TRUE;
+}
+
+
+/*!
+ \reimp
+*/
+
+int QBuffer::readBlock( char *p, uint len )
+{
+#if defined(CHECK_STATE)
+ CHECK_PTR( p );
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QBuffer::readBlock: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QBuffer::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)ioIndex + len > a.size() ) { // overflow
+ if ( (uint)ioIndex >= a.size() ) {
+ setStatus( IO_ReadError );
+ return -1;
+ } else {
+ len = a.size() - (uint)ioIndex;
+ }
+ }
+ memcpy( p, a.data()+ioIndex, len );
+ ioIndex += len;
+ return len;
+}
+
+/*!
+ \reimp
+
+ Writes \a len bytes from \a p into the buffer at the current index,
+ overwriting any characters there and extending the buffer if necessary.
+ Returns the number of bytes actually written.
+
+ Returns -1 if a serious error occurred.
+
+ \sa readBlock()
+*/
+
+int QBuffer::writeBlock( const char *p, uint len )
+{
+#if defined(CHECK_NULL)
+ if ( p == 0 && len != 0 )
+ qWarning( "QBuffer::writeBlock: Null pointer error" );
+#endif
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QBuffer::writeBlock: Buffer not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "QBuffer::writeBlock: Write operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)ioIndex + len >= a_len ) { // overflow
+ uint new_len = a_len + a_inc*(((uint)ioIndex+len-a_len)/a_inc+1);
+ if ( !a.resize( new_len ) ) { // could not resize
+#if defined(CHECK_NULL)
+ qWarning( "QBuffer::writeBlock: Memory allocation error" );
+#endif
+ setStatus( IO_ResourceError );
+ return -1;
+ }
+ a_inc *= 2; // double increment
+ a_len = new_len;
+ a.shd->len = (uint)ioIndex + len;
+ }
+ memcpy( a.data()+ioIndex, p, len );
+ ioIndex += len;
+ if ( a.shd->len < (uint)ioIndex )
+ a.shd->len = (uint)ioIndex; // fake (not alloc'd) length
+ return len;
+}
+
+
+/*!
+ \reimp
+*/
+
+int QBuffer::readLine( char *p, uint maxlen )
+{
+#if defined(CHECK_STATE)
+ CHECK_PTR( p );
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QBuffer::readLine: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QBuffer::readLine: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( maxlen == 0 )
+ return 0;
+ uint start = (uint)ioIndex;
+ char *d = a.data() + ioIndex;
+ maxlen--; // make room for 0-terminator
+ if ( a.size() - (uint)ioIndex < maxlen )
+ maxlen = a.size() - (uint)ioIndex;
+ while ( maxlen-- ) {
+ if ( (*p++ = *d++) == '\n' )
+ break;
+ }
+ *p = '\0';
+ ioIndex = d - a.data();
+ return (uint)ioIndex - start;
+}
+
+
+/*!
+ \reimp
+*/
+
+int QBuffer::getch()
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QBuffer::getch: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QBuffer::getch: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)ioIndex+1 > a.size() ) { // overflow
+ setStatus( IO_ReadError );
+ return -1;
+ }
+ return uchar(*(a.data()+ioIndex++));
+}
+
+/*!
+ \reimp
+ Writes the character \a ch into the buffer, overwriting
+ the character at the current index, extending the buffer
+ if necessary.
+
+ Returns \a ch, or -1 if some error occurred.
+
+ \sa getch(), ungetch()
+*/
+
+int QBuffer::putch( int ch )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QBuffer::putch: Buffer not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "QBuffer::putch: Write operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)ioIndex + 1 >= a_len ) { // overflow
+ char buf[1];
+ buf[0] = (char)ch;
+ if ( writeBlock(buf,1) != 1 )
+ return -1; // write error
+ } else {
+ *(a.data() + ioIndex++) = (char)ch;
+ if ( a.shd->len < (uint)ioIndex )
+ a.shd->len = (uint)ioIndex;
+ }
+ return ch;
+}
+
+/*!
+ \reimp
+*/
+
+int QBuffer::ungetch( int ch )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QBuffer::ungetch: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QBuffer::ungetch: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( ch != -1 ) {
+ if ( ioIndex )
+ ioIndex--;
+ else
+ ch = -1;
+ }
+ return ch;
+}
diff --git a/qtools/qbuffer.h b/qtools/qbuffer.h
new file mode 100644
index 0000000..9dcd286
--- /dev/null
+++ b/qtools/qbuffer.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+**
+** Definition of QBuffer class
+**
+** Created : 930812
+**
+** Copyright (C) 1992-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 QBUFFER_H
+#define QBUFFER_H
+
+#ifndef QT_H
+#include "qiodevice.h"
+#include "qstring.h"
+#endif // QT_H
+
+
+class Q_EXPORT QBuffer : public QIODevice
+{
+public:
+ QBuffer();
+ QBuffer( QByteArray );
+ ~QBuffer();
+
+ QByteArray buffer() const;
+ bool setBuffer( QByteArray );
+
+ bool open( int );
+ void close();
+ void flush();
+
+ uint size() const;
+ int at() const;
+ bool at( int );
+
+ int readBlock( char *p, uint );
+ int writeBlock( const char *p, uint );
+ int readLine( char *p, uint );
+
+ int getch();
+ int putch( int );
+ int ungetch( int );
+
+protected:
+ QByteArray a;
+
+private:
+ uint a_len;
+ uint a_inc;
+
+private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ QBuffer( const QBuffer & );
+ QBuffer &operator=( const QBuffer & );
+#endif
+};
+
+
+inline QByteArray QBuffer::buffer() const
+{ return a; }
+
+inline uint QBuffer::size() const
+{ return a.size(); }
+
+inline int QBuffer::at() const
+{ return ioIndex; }
+
+
+#endif // QBUFFER_H
diff --git a/qtools/qcollection.cpp b/qtools/qcollection.cpp
new file mode 100644
index 0000000..e70b64b
--- /dev/null
+++ b/qtools/qcollection.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+**
+** Implementation of base class for all collection classes
+**
+** Created : 920820
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qcollection.h"
+
+// NOT REVISED
+/*!
+ \class QCollection qcollection.h
+ \brief The QCollection class is the base class of all Qt collections.
+
+ \ingroup collection
+ \ingroup tools
+
+ The QCollection class is an abstract base class for the Qt \link
+ collection.html collection classes\endlink QDict, QList etc. via QGDict,
+ QGList etc.
+
+ A QCollection knows only about the number of objects in the
+ collection and the deletion strategy (see setAutoDelete()).
+
+ A collection is implemented using the \c Item (generic collection
+ item) type, which is a \c void*. The template classes that create
+ the real collections cast the \c Item to the required type.
+
+ \sa \link collection.html Collection Classes\endlink
+*/
+
+
+/*! \enum QCollection::Item
+
+ This type is the generic "item" in a QCollection.
+*/
+
+
+/*!
+ \fn QCollection::QCollection()
+
+ Constructs a collection. The constructor is protected because
+ QCollection is an abstract class.
+*/
+
+/*!
+ \fn QCollection::QCollection( const QCollection & source )
+
+ Constructs a copy of \a source with autoDelete() set to FALSE. The
+ constructor is protected because QCollection is an abstract class.
+
+ Note that if \a source has autoDelete turned on, copying it is a
+ good way to get memory leaks, reading freed memory, or both.
+*/
+
+/*!
+ \fn QCollection::~QCollection()
+ Destroys the collection. The destructor is protected because QCollection
+ is an abstract class.
+*/
+
+
+/*!
+ \fn bool QCollection::autoDelete() const
+ Returns the setting of the auto-delete option (default is FALSE).
+ \sa setAutoDelete()
+*/
+
+/*!
+ \fn void QCollection::setAutoDelete( bool enable )
+
+ Sets the auto-delete option of the collection.
+
+ Enabling auto-delete (\e enable is TRUE) will delete objects that
+ are removed from the collection. This can be useful if the
+ collection has the only reference to the objects. (Note that the
+ object can still be copied using the copy constructor - copying such
+ objects is a good way to get memory leaks, reading freed memory or
+ both.)
+
+ Disabling auto-delete (\e enable is FALSE) will \e not delete objects
+ that are removed from the collection. This is useful if the objects
+ are part of many collections.
+
+ The default setting is FALSE.
+
+ \sa autoDelete()
+*/
+
+
+/*!
+ \fn virtual uint QCollection::count() const
+ Returns the number of objects in the collection.
+*/
+
+/*!
+ \fn virtual void QCollection::clear()
+ Removes all objects from the collection. The objects will be deleted
+ if auto-delete has been enabled.
+ \sa setAutoDelete()
+*/
+
+
+/*!
+ Virtual function that creates a copy of an object that is about to
+ be inserted into the collection.
+
+ The default implementation returns the \e d pointer, i.e. no copy
+ is made.
+
+ This function is seldom reimplemented in the collection template
+ classes. It is not common practice to make a copy of something
+ that is being inserted.
+
+ \sa deleteItem()
+*/
+
+QCollection::Item QCollection::newItem( Item d )
+{
+ return d; // just return reference
+}
+
+/*!
+ Virtual function that deletes an item that is about to be removed from
+ the collection.
+
+ The default implementation deletes \e d pointer if and only if
+ auto-delete has been enabled.
+
+ This function is always reimplemented in the collection template
+ classes.
+
+ \warning If you reimplement this function you must also reimplement
+ the destructor and call the virtual function clear() from your
+ destructor. This is due to the way virtual functions and
+ destructors work in C++: virtual functions in derived classes cannot
+ be called from a destructor. If you do not do this your
+ deleteItem() function will not be called when the container is
+ destructed.
+
+ \sa newItem(), setAutoDelete()
+*/
+
+void QCollection::deleteItem( Item d )
+{
+ if ( del_item )
+#if defined(Q_DELETING_VOID_UNDEFINED)
+ delete (char *)d; // default operation
+#else
+ delete d; // default operation
+#endif
+}
diff --git a/qtools/qcollection.h b/qtools/qcollection.h
new file mode 100644
index 0000000..c7ba00f
--- /dev/null
+++ b/qtools/qcollection.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+**
+** Definition of base class for all collection classes
+**
+** Created : 920629
+**
+** Copyright (C) 1992-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 QCOLLECTION_H
+#define QCOLLECTION_H
+
+#ifndef QT_H
+#include "qglobal.h"
+#endif // QT_H
+
+
+class QGVector;
+class QGList;
+class QGDict;
+
+
+class Q_EXPORT QCollection // inherited by all collections
+{
+public:
+ bool autoDelete() const { return del_item; }
+ void setAutoDelete( bool enable ) { del_item = enable; }
+
+ virtual uint count() const = 0;
+ virtual void clear() = 0; // delete all objects
+
+ typedef void *Item; // generic collection item
+
+protected:
+ QCollection() { del_item = FALSE; } // no deletion of objects
+ QCollection(const QCollection &) { del_item = FALSE; }
+ virtual ~QCollection() {}
+
+ bool del_item; // default FALSE
+
+ virtual Item newItem( Item ); // create object
+ virtual void deleteItem( Item ); // delete object
+};
+
+
+#endif // QCOLLECTION_H
diff --git a/qtools/qconfig.h b/qtools/qconfig.h
new file mode 100644
index 0000000..fe14e97
--- /dev/null
+++ b/qtools/qconfig.h
@@ -0,0 +1,8 @@
+// Empty leaves all features enabled. See doc/html/features.html for choices.
+
+// 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.
+
+#define QT_DLL // Internal
diff --git a/qtools/qcstring.cpp b/qtools/qcstring.cpp
new file mode 100644
index 0000000..77dc386
--- /dev/null
+++ b/qtools/qcstring.cpp
@@ -0,0 +1,1917 @@
+/****************************************************************************
+**
+**
+** Implementation of extended char array operations, and QByteArray and
+** QCString classes
+**
+** Created : 920722
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qstring.h"
+#include "qregexp.h"
+#include "qdatastream.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+/*****************************************************************************
+ Safe and portable C string functions; extensions to standard string.h
+ *****************************************************************************/
+
+/*!
+ \fn void *memmove( void *dst, const void *src, uint len )
+ \relates QCString
+
+ This function is normally part of the C library. Qt implements
+ memmove() for platforms that do not have it.
+
+ memmove() copies \e len bytes from \e src into \e dst. The data is
+ copied correctly even if \e src and \e dst overlap.
+*/
+
+void *qmemmove( void *dst, const void *src, uint len )
+{
+ register char *d;
+ register char *s;
+ if ( dst > src ) {
+ d = (char *)dst + len - 1;
+ s = (char *)src + len - 1;
+ while ( len-- )
+ *d-- = *s--;
+ } else if ( dst < src ) {
+ d = (char *)dst;
+ s = (char *)src;
+ while ( len-- )
+ *d++ = *s++;
+ }
+ return dst;
+}
+
+/*!
+ \relates QCString
+
+ Returns a duplicate string.
+
+ Allocates space for a copy of \e str (using \c new), copies it, and returns
+ a pointer to the copy.
+ If \e src is null, it immediately returns 0.
+*/
+
+char *qstrdup( const char *str )
+{
+ if ( !str )
+ return 0;
+ char *dst = new char[strlen(str)+1];
+ CHECK_PTR( dst );
+ return strcpy( dst, str );
+}
+
+/*!
+ \relates QCString
+
+ A safe strncpy() function.
+
+ Copies all characters up to \e len bytes from \e str into \e dst and returns
+ a pointer to \e dst. Guarantees that \e dst is \0-terminated.
+ If \e src is null, it immediately returns 0.
+
+ \sa qstrcpy()
+*/
+
+char *qstrncpy( char *dst, const char *src, uint len )
+{
+ if ( !src )
+ return 0;
+ strncpy( dst, src, len );
+ if ( len > 0 )
+ dst[len-1] = '\0';
+ return dst;
+}
+
+/*!
+ \fn int qstrcmp( const char *str1, const char *str2 )
+ \relates QCString
+
+ A safe strcmp() function.
+
+ Compares \e str1 and \e str2. Returns a negative value if \e str1
+ is less than \e str2, 0 if \e str1 is equal to \e str2 or a positive
+ value if \e str1 is greater than \e str2.
+
+ Special case I: Returns 0 if \e str1 and \e str2 are both null.
+
+ Special case II: Returns a random nonzero value if \e str1 is null
+ or \e str2 is null (but not both).
+
+ \sa qstrncmp(), qstricmp(), qstrnicmp()
+*/
+
+/*!
+ \fn int qstrncmp( const char *str1, const char *str2, uint len )
+ \relates QCString
+
+ A safe strncmp() function.
+
+ Compares \e str1 and \e str2 up to \e len bytes.
+
+ Returns a negative value if \e str1 is less than \e str2, 0 if \e str1
+ is equal to \e str2 or a positive value if \e str1 is greater than \e
+ str2.
+
+ Special case I: Returns 0 if \e str1 and \e str2 are both null.
+
+ Special case II: Returns a random nonzero value if \e str1 is null
+ or \e str2 is null (but not both).
+
+ \sa qstrcmp(), qstricmp(), qstrnicmp()
+*/
+
+/*!
+ \fn int qstricmp( const char *str1, const char *str2 )
+ \relates QCString
+
+ A safe stricmp() function.
+
+ Compares \e str1 and \e str2 ignoring the case.
+
+ Returns a negative value if \e str1 is less than \e str2, 0 if \e str1
+ is equal to \e str2 or a positive value if \e str1 is greater than \e
+ str2.
+
+ Special case I: Returns 0 if \e str1 and \e str2 are both null.
+
+ Special case II: Returns a random nonzero value if \e str1 is null
+ or \e str2 is null (but not both).
+
+ \sa qstrcmp(), qstrncmp(), qstrnicmp()
+*/
+
+int qstricmp( const char *str1, const char *str2 )
+{
+ register const uchar *s1 = (const uchar *)str1;
+ register const uchar *s2 = (const uchar *)str2;
+ int res;
+ uchar c;
+ if ( !s1 || !s2 )
+ return s1 == s1 ? 0 : (int)((long)s2 - (long)s1);
+ for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
+ if ( !c ) // strings are equal
+ break;
+ return res;
+}
+
+/*!
+ \fn int strnicmp( const char *str1, const char *str2, uint len )
+ \relates QCString
+
+ A safe strnicmp() function.
+
+ Compares \e str1 and \e str2 up to \e len bytes ignoring the case.
+
+ Returns a negative value if \e str1 is less than \e str2, 0 if \e str1
+ is equal to \e str2 or a positive value if \e str1 is greater than \e
+ str2.
+
+ Special case I: Returns 0 if \e str1 and \e str2 are both null.
+
+ Special case II: Returns a random nonzero value if \e str1 is null
+ or \e str2 is null (but not both).
+
+ \sa qstrcmp(), qstrncmp() qstricmp()
+*/
+
+int qstrnicmp( const char *str1, const char *str2, uint len )
+{
+ register const uchar *s1 = (const uchar *)str1;
+ register const uchar *s2 = (const uchar *)str2;
+ int res;
+ uchar c;
+ if ( !s1 || !s2 )
+ return (int)((long)s2 - (long)s1);
+ for ( ; len--; s1++, s2++ ) {
+ if ( (res = (c=tolower(*s1)) - tolower(*s2)) )
+ return res;
+ if ( !c ) // strings are equal
+ break;
+ }
+ return 0;
+}
+
+
+static Q_UINT16 crc_tbl[16];
+static bool crc_tbl_init = FALSE;
+
+static void createCRC16Table() // build CRC16 lookup table
+{
+ register uint i;
+ register uint j;
+ uint v0, v1, v2, v3;
+ for ( i=0; i<16; i++ ) {
+ v0 = i & 1;
+ v1 = (i >> 1) & 1;
+ v2 = (i >> 2) & 1;
+ v3 = (i >> 3) & 1;
+ j = 0;
+#undef SET_BIT
+#define SET_BIT(x,b,v) x |= v << b
+ SET_BIT(j, 0,v0);
+ SET_BIT(j, 7,v0);
+ SET_BIT(j,12,v0);
+ SET_BIT(j, 1,v1);
+ SET_BIT(j, 8,v1);
+ SET_BIT(j,13,v1);
+ SET_BIT(j, 2,v2);
+ SET_BIT(j, 9,v2);
+ SET_BIT(j,14,v2);
+ SET_BIT(j, 3,v3);
+ SET_BIT(j,10,v3);
+ SET_BIT(j,15,v3);
+ crc_tbl[i] = j;
+ }
+}
+
+/*!
+ \relates QByteArray
+ Returns the CRC-16 checksum of \e len bytes starting at \e data.
+
+ The checksum is independent of the byte order (endianness).
+*/
+
+Q_UINT16 qChecksum( const char *data, uint len )
+{
+ if ( !crc_tbl_init ) { // create lookup table
+ createCRC16Table();
+ crc_tbl_init = TRUE;
+ }
+ register Q_UINT16 crc = 0xffff;
+ uchar c;
+ uchar *p = (uchar *)data;
+ while ( len-- ) {
+ c = *p++;
+ crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
+ c >>= 4;
+ crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
+ }
+ return (~crc & 0xffff);
+}
+
+
+/*****************************************************************************
+ QByteArray member functions
+ *****************************************************************************/
+
+// NOT REVISED
+/*! \class QByteArray qcstring.h
+
+ \brief The QByteArray class provides an array of bytes.
+
+ \inherit QArray
+ \ingroup tools
+ \ingroup shared
+
+ QByteArray is defined as QArray\<char\>.
+*/
+
+
+/*****************************************************************************
+ QByteArray stream functions
+ *****************************************************************************/
+
+/*!
+ \relates QByteArray
+ Writes a byte array to a stream and returns a reference to the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+#ifndef QT_NO_DATASTREAM
+
+QDataStream &operator<<( QDataStream &s, const QByteArray &a )
+{
+ return s.writeBytes( a.data(), a.size() );
+}
+
+/*!
+ \relates QByteArray
+ Reads a byte array from a stream and returns a reference to the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>( QDataStream &s, QByteArray &a )
+{
+ Q_UINT32 len;
+ s >> len; // read size of array
+ if ( len == 0 || s.eof() ) { // end of file reached
+ a.resize( 0 );
+ return s;
+ }
+ if ( !a.resize( (uint)len ) ) { // resize array
+#if defined(CHECK_NULL)
+ qWarning( "QDataStream: Not enough memory to read QByteArray" );
+#endif
+ len = 0;
+ }
+ if ( len > 0 ) // not null array
+ s.readRawBytes( a.data(), (uint)len );
+ return s;
+}
+
+#endif //QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QCString member functions
+ *****************************************************************************/
+
+/*!
+ \class QCString qcstring.h
+
+ \brief The QCString class provides an abstraction of the classic C
+ zero-terminated char array (<var>char*</var>).
+
+ \ingroup tools
+ \ingroup shared
+
+ QCString inherits QByteArray, which is defined as QArray\<char\>.
+
+ Since QCString is a QArray, it uses \e explicit
+ \link shclass.html sharing\endlink with a reference count.
+
+ You might use QCString for text that is never exposed to the user,
+ but for text the user sees, you should use QString (which provides
+ implicit sharing, Unicode and other internationalization support).
+
+ Note that QCString is one of the weaker classes in Qt; its design is
+ flawed (it tries to behave like a more convenient const char *) and
+ as a result, algorithms that use QCString heavily all too often
+ perform badly. For example, append() is O(length()) since it scans
+ for a null terminator, which makes many algorithms that use QCString
+ scale even worse.
+
+ Note that for the QCString methods that take a <var>const char *</var>
+ parameter the results are undefined if the QCString is not
+ zero-terminated. It is legal for the <var>const char *</var> parameter
+ to be 0.
+
+ A QCString that has not been assigned to anything is \e null, i.e. both
+ the length and data pointer is 0. A QCString that references the empty
+ string ("", a single '\0' char) is \e empty. Both null and empty
+ QCStrings are legal parameters to the methods. Assigning <var>const char
+ * 0</var> to QCString gives a null QCString.
+
+ \sa \link shclass.html Shared classes\endlink
+*/
+
+
+/*
+ Implementation note: The QCString methods for QRegExp searching are
+ implemented by converting the QCString to a QString and performing
+ the search on that. This implies a deep copy of the QCString
+ data. Therefore, if you are giong to perform many QRegExp searches
+ on one and the same, large QCString, you will get better performance
+ by converting the QCString to a QString yourself, and do the
+ searches on that. The results will be of course be identical.
+*/
+
+
+
+/*!
+ \fn QCString::QCString()
+ Constructs a null string.
+ \sa isNull()
+*/
+
+/*!
+ \fn QCString::QCString( const QCString &s )
+ Constructs a shallow copy \e s.
+ \sa assign()
+*/
+
+/*!
+ Constructs a string with room for \e size characters, including the
+ '\0'-terminator. Makes a null string if \e size == 0.
+
+ If \e size \> 0, then the first and last characters in the string are
+ initialized to '\0'. All other characters are uninitialized.
+
+ \sa resize(), isNull()
+*/
+
+QCString::QCString( int size )
+ : QByteArray( size )
+{
+ if ( size > 0 ) {
+ *data() = '\0'; // set terminator
+ *(data()+(size-1)) = '\0';
+ }
+}
+
+/*!
+ Constructs a string that is a deep copy of \e str.
+
+ If \a str is 0 a null string is created.
+
+ \sa isNull()
+*/
+
+QCString::QCString( const char *str )
+{
+ duplicate( str, qstrlen(str) + 1 );
+}
+
+
+/*!
+ Constructs a string that is a deep copy of \e str, that is no more
+ than \a maxsize bytes long including the '\0'-terminator.
+
+ Example:
+ \code
+ QCString str( "helloworld", 6 ); // Assigns "hello" to str.
+ \endcode
+
+ If \a str contains a 0 byte within the first \a maxsize bytes, the
+ resulting QCString will be terminated by the 0. If \a str is 0 a
+ null string is created.
+
+ \sa isNull()
+*/
+
+QCString::QCString( const char *str, uint maxsize )
+{
+ if ( str == 0 )
+ return;
+ uint len; // index of first '\0'
+ for ( len = 0; len < maxsize - 1; len++ ) {
+ if ( str[len] == '\0' )
+ break;
+ }
+ QByteArray::resize( len + 1 );
+ memcpy( data(), str, len );
+ data()[len] = 0;
+}
+
+/*!
+ \fn QCString &QCString::operator=( const QCString &s )
+ Assigns a shallow copy of \e s to this string and returns a reference to
+ this string.
+*/
+
+/*!
+ \fn QCString &QCString::operator=( const char *str )
+ Assigns a deep copy of \a str to this string and returns a reference to
+ this string.
+
+ If \a str is 0 a null string is created.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn bool QCString::isNull() const
+ Returns TRUE if the string is null, i.e. if data() == 0.
+ A null string is also an empty string.
+
+ Example:
+ \code
+ QCString a; // a.data() == 0, a.size() == 0, a.length() == 0
+ QCString b == ""; // b.data() == "", b.size() == 1, b.length() == 0
+ a.isNull(); // TRUE, because a.data() == 0
+ a.isEmpty(); // TRUE, because a.length() == 0
+ b.isNull(); // FALSE, because b.data() == ""
+ b.isEmpty(); // TRUE, because b.length() == 0
+ \endcode
+
+ \sa isEmpty(), length(), size()
+*/
+
+/*!
+ \fn bool QCString::isEmpty() const
+
+ Returns TRUE if the string is empty, i.e. if length() == 0.
+ An empty string is not always a null string.
+
+ See example in isNull().
+
+ \sa isNull(), length(), size()
+*/
+
+/*!
+ \fn uint QCString::length() const
+ Returns the length of the string, excluding the '\0'-terminator.
+ Equivalent to calling \c strlen(data()).
+
+ Null strings and empty strings have zero length.
+
+ \sa size(), isNull(), isEmpty()
+*/
+
+/*!
+ \fn bool QCString::truncate( uint pos )
+ Truncates the string at position \e pos.
+
+ Equivalent to calling \c resize(pos+1).
+
+ Example:
+ \code
+ QCString s = "truncate this string";
+ s.truncate( 5 ); // s == "trunc"
+ \endcode
+
+ \sa resize()
+*/
+
+/*!
+ Extends or shrinks the string to \e len bytes, including the
+ '\0'-terminator.
+
+ A \0-terminator is set at position <code>len - 1</code> unless
+ <code>len == 0</code>.
+
+ Example:
+ \code
+ QCString s = "resize this string";
+ s.resize( 7 ); // s == "resize"
+ \endcode
+
+ \sa truncate()
+*/
+
+bool QCString::resize( uint len )
+{
+ detach();
+ if ( !QByteArray::resize(len) )
+ return FALSE;
+ if ( len )
+ *(data()+len-1) = '\0';
+ return TRUE;
+}
+
+
+/*!
+ Implemented as a call to the native vsprintf() (see your C-library
+ manual).
+
+ If your string is shorter than 256 characters, this sprintf() calls
+ resize(256) to decrease the chance of memory corruption. The string is
+ resized back to its natural length before sprintf() returns.
+
+ Example:
+ \code
+ QCString s;
+ s.sprintf( "%d - %s", 1, "first" ); // result < 256 chars
+
+ QCString big( 25000 ); // very long string
+ big.sprintf( "%d - %s", 2, longString ); // result < 25000 chars
+ \endcode
+
+ \warning All vsprintf() implementations will write past the end of
+ the target string (*this) if the format specification and arguments
+ happen to be longer than the target string, and some will also fail
+ if the target string is longer than some arbitrary implementation
+ limit.
+
+ Giving user-supplied arguments to sprintf() is begging for trouble.
+ Sooner or later someone \e will paste a 3000-character line into
+ your application.
+*/
+
+QCString &QCString::sprintf( const char *format, ... )
+{
+ detach();
+ va_list ap;
+ va_start( ap, format );
+ if ( size() < 256 )
+ QByteArray::resize( 256 ); // make string big enough
+ vsprintf( data(), format, ap );
+ resize( qstrlen(data()) + 1 ); // truncate
+ va_end( ap );
+ return *this;
+}
+
+
+/*!
+ Fills the string with \e len bytes of value \e c, followed by a
+ '\0'-terminator.
+
+ If \e len is negative, then the current string length is used.
+
+ Returns FALSE is \e len is nonnegative and there is no memory to
+ resize the string, otherwise TRUE is returned.
+*/
+
+bool QCString::fill( char c, int len )
+{
+ detach();
+ if ( len < 0 )
+ len = length();
+ if ( !QByteArray::fill(c,len+1) )
+ return FALSE;
+ *(data()+len) = '\0';
+ return TRUE;
+}
+
+
+/*!
+ \fn QCString QCString::copy() const
+ Returns a deep copy of this string.
+ \sa detach()
+*/
+
+
+/*!
+ Finds the first occurrence of the character \e c, starting at
+ position \e index.
+
+ The search is case sensitive if \e cs is TRUE, or case insensitive if \e
+ cs is FALSE.
+
+ Returns the position of \e c, or -1 if \e c could not be found.
+*/
+
+int QCString::find( char c, int index, bool cs ) const
+{
+ if ( (uint)index >= size() ) // index outside string
+ return -1;
+ register const char *d;
+ if ( cs ) { // case sensitive
+ d = strchr( data()+index, c );
+ } else {
+ d = data()+index;
+ c = tolower( c );
+ while ( *d && tolower(*d) != c )
+ d++;
+ if ( !*d && c ) // not found
+ d = 0;
+ }
+ return d ? (int)(d - data()) : -1;
+}
+
+/*!
+ Finds the first occurrence of the string \e str, starting at position
+ \e index.
+
+ The search is case sensitive if \e cs is TRUE, or case insensitive if \e
+ cs is FALSE.
+
+ Returns the position of \e str, or -1 if \e str could not be found.
+*/
+
+int QCString::find( const char *str, int index, bool cs ) const
+{
+ if ( (uint)index >= size() ) // index outside string
+ return -1;
+ if ( !str ) // no search string
+ return -1;
+ if ( !*str ) // zero-length search string
+ return index;
+ register const char *d;
+ if ( cs ) { // case sensitive
+ d = strstr( data()+index, str );
+ } else { // case insensitive
+ d = data()+index;
+ int len = qstrlen( str );
+ while ( *d ) {
+ if ( qstrnicmp(d, str, len) == 0 )
+ break;
+ d++;
+ }
+ if ( !*d ) // not found
+ d = 0;
+ }
+ return d ? (int)(d - data()) : -1;
+}
+
+/*!
+ Finds the first occurrence of the character \e c, starting at
+ position \e index and searching backwards.
+
+ The search is case sensitive if \e cs is TRUE, or case insensitive if \e
+ cs is FALSE.
+
+ Returns the position of \e c, or -1 if \e c could not be found.
+*/
+
+int QCString::findRev( char c, int index, bool cs ) const
+{
+ const char *b = data();
+ const char *d;
+ if ( index < 0 ) { // neg index ==> start from end
+ if ( size() == 0 )
+ return -1;
+ if ( cs ) {
+ d = strrchr( b, c );
+ return d ? (int)(d - b) : -1;
+ }
+ index = length();
+ } else if ( (uint)index >= size() ) { // bad index
+ return -1;
+ }
+ d = b+index;
+ if ( cs ) { // case sensitive
+ while ( d >= b && *d != c )
+ d--;
+ } else { // case insensitive
+ c = tolower( c );
+ while ( d >= b && tolower(*d) != c )
+ d--;
+ }
+ return d >= b ? (int)(d - b) : -1;
+}
+
+/*!
+ Finds the first occurrence of the string \e str, starting at
+ position \e index and searching backwards.
+
+ The search is case sensitive if \e cs is TRUE, or case insensitive if \e
+ cs is FALSE.
+
+ Returns the position of \e str, or -1 if \e str could not be found.
+*/
+
+int QCString::findRev( const char *str, int index, bool cs ) const
+{
+ int slen = qstrlen(str);
+ if ( index < 0 ) // neg index ==> start from end
+ index = length()-slen;
+ else if ( (uint)index >= size() ) // bad index
+ return -1;
+ else if ( (uint)(index + slen) > length() ) // str would be too long
+ index = length() - slen;
+ if ( index < 0 )
+ return -1;
+
+ register char *d = data() + index;
+ if ( cs ) { // case sensitive
+ for ( int i=index; i>=0; i-- )
+ if ( qstrncmp(d--,str,slen)==0 )
+ return i;
+ } else { // case insensitive
+ for ( int i=index; i>=0; i-- )
+ if ( qstrnicmp(d--,str,slen)==0 )
+ return i;
+ }
+ return -1;
+}
+
+
+/*!
+ Returns the number of times the character \e c occurs in the string.
+
+ The match is case sensitive if \e cs is TRUE, or case insensitive if \e cs
+ if FALSE.
+*/
+
+int QCString::contains( char c, bool cs ) const
+{
+ int count = 0;
+ char *d = data();
+ if ( !d )
+ return 0;
+ if ( cs ) { // case sensitive
+ while ( *d )
+ if ( *d++ == c )
+ count++;
+ } else { // case insensitive
+ c = tolower( c );
+ while ( *d ) {
+ if ( tolower(*d) == c )
+ count++;
+ d++;
+ }
+ }
+ return count;
+}
+
+/*!
+ Returns the number of times \e str occurs in the string.
+
+ The match is case sensitive if \e cs is TRUE, or case insensitive if \e
+ cs if FALSE.
+
+ This function counts overlapping substrings, for example, "banana"
+ contains two occurrences of "ana".
+
+ \sa findRev()
+*/
+
+int QCString::contains( const char *str, bool cs ) const
+{
+ int count = 0;
+ char *d = data();
+ if ( !d )
+ return 0;
+ int len = qstrlen( str );
+ while ( *d ) { // counts overlapping strings
+ if ( cs ) {
+ if ( qstrncmp( d, str, len ) == 0 )
+ count++;
+ } else {
+ if ( qstrnicmp(d, str, len) == 0 )
+ count++;
+ }
+ d++;
+ }
+ return count;
+}
+
+/*!
+ Returns a substring that contains the \e len leftmost characters
+ of the string.
+
+ The whole string is returned if \e len exceeds the length of the string.
+
+ Example:
+ \code
+ QCString s = "Pineapple";
+ QCString t = s.left( 4 ); // t == "Pine"
+ \endcode
+
+ \sa right(), mid()
+*/
+
+QCString QCString::left( uint len ) const
+{
+ if ( isEmpty() ) {
+ QCString empty;
+ return empty;
+ } else if ( len >= size() ) {
+ QCString same( data() );
+ return same;
+ } else {
+ QCString s( len+1 );
+ strncpy( s.data(), data(), len );
+ *(s.data()+len) = '\0';
+ return s;
+ }
+}
+
+/*!
+ Returns a substring that contains the \e len rightmost characters
+ of the string.
+
+ The whole string is returned if \e len exceeds the length of the string.
+
+ Example:
+ \code
+ QCString s = "Pineapple";
+ QCString t = s.right( 5 ); // t == "apple"
+ \endcode
+
+ \sa left(), mid()
+*/
+
+QCString QCString::right( uint len ) const
+{
+ if ( isEmpty() ) {
+ QCString empty;
+ return empty;
+ } else {
+ uint l = length();
+ if ( len > l )
+ len = l;
+ char *p = data() + (l - len);
+ return QCString( p );
+ }
+}
+
+/*!
+ Returns a substring that contains the \e len characters of this
+ string, starting at position \e index.
+
+ Returns a null string if the string is empty or \e index is out
+ of range. Returns the whole string from \e index if \e index+len exceeds
+ the length of the string.
+
+ Example:
+ \code
+ QCString s = "Two pineapples";
+ QCString t = s.mid( 4, 4 ); // t == "pine"
+ \endcode
+
+ \sa left(), right()
+*/
+
+QCString QCString::mid( uint index, uint len ) const
+{
+ if ( len == 0xffffffff ) len = length()-index;
+ uint slen = qstrlen( data() );
+ if ( isEmpty() || index >= slen ) {
+ QCString empty;
+ return empty;
+ } else {
+ register char *p = data()+index;
+ QCString s( len+1 );
+ strncpy( s.data(), p, len );
+ *(s.data()+len) = '\0';
+ return s;
+ }
+}
+
+/*!
+ Returns a string of length \e width (plus '\0') that contains this
+ string and padded by the \e fill character.
+
+ If the length of the string exceeds \e width and \e truncate is FALSE,
+ then the returned string is a copy of the string.
+ If the length of the string exceeds \e width and \e truncate is TRUE,
+ then the returned string is a left(\e width).
+
+ Example:
+ \code
+ QCString s("apple");
+ QCString t = s.leftJustify(8, '.'); // t == "apple..."
+ \endcode
+
+ \sa rightJustify()
+*/
+
+QCString QCString::leftJustify( uint width, char fill, bool truncate ) const
+{
+ QCString result;
+ int len = qstrlen(data());
+ int padlen = width - len;
+ if ( padlen > 0 ) {
+ result.QByteArray::resize( len+padlen+1 );
+ memcpy( result.data(), data(), len );
+ memset( result.data()+len, fill, padlen );
+ result[len+padlen] = '\0';
+ } else {
+ if ( truncate )
+ result = left( width );
+ else
+ result = copy();
+ }
+ return result;
+}
+
+/*!
+ Returns a string of length \e width (plus '\0') that contains pad
+ characters followed by the string.
+
+ If the length of the string exceeds \e width and \e truncate is FALSE,
+ then the returned string is a copy of the string.
+ If the length of the string exceeds \e width and \e truncate is TRUE,
+ then the returned string is a left(\e width).
+
+ Example:
+ \code
+ QCString s("pie");
+ QCString t = s.rightJustify(8, '.'); // t == ".....pie"
+ \endcode
+
+ \sa leftJustify()
+*/
+
+QCString QCString::rightJustify( uint width, char fill, bool truncate ) const
+{
+ QCString result;
+ int len = qstrlen(data());
+ int padlen = width - len;
+ if ( padlen > 0 ) {
+ result.QByteArray::resize( len+padlen+1 );
+ memset( result.data(), fill, padlen );
+ memcpy( result.data()+padlen, data(), len );
+ result[len+padlen] = '\0';
+ } else {
+ if ( truncate )
+ result = left( width );
+ else
+ result = copy();
+ }
+ return result;
+}
+
+/*!
+ Returns a new string that is the string converted to lower case.
+
+ Presently it only handles 7-bit ASCII, or whatever tolower()
+ handles (if $LC_CTYPE is set, most UNIX systems do the Right Thing).
+
+ Example:
+ \code
+ QCString s("TeX");
+ QCString t = s.lower(); // t == "tex"
+ \endcode
+
+ \sa upper()
+*/
+
+QCString QCString::lower() const
+{
+ QCString s( data() );
+ register char *p = s.data();
+ if ( p ) {
+ while ( *p ) {
+ *p = tolower(*p);
+ p++;
+ }
+ }
+ return s;
+}
+
+/*!
+ Returns a new string that is the string converted to upper case.
+
+ Presently it only handles 7-bit ASCII, or whatever toupper()
+ handles (if $LC_CTYPE is set, most UNIX systems do the Right Thing).
+
+ Example:
+ \code
+ QCString s("TeX");
+ QCString t = s.upper(); // t == "TEX"
+ \endcode
+
+ \sa lower()
+*/
+
+QCString QCString::upper() const
+{
+ QCString s( data() );
+ register char *p = s.data();
+ if ( p ) {
+ while ( *p ) {
+ *p = toupper(*p);
+ p++;
+ }
+ }
+ return s;
+}
+
+
+/*!
+ Returns a new string that has white space removed from the start and the end.
+
+ White space means any ASCII code 9, 10, 11, 12, 13 or 32.
+
+ Example:
+ \code
+ QCString s = " space ";
+ QCString t = s.stripWhiteSpace(); // t == "space"
+ \endcode
+
+ \sa simplifyWhiteSpace()
+*/
+
+QCString QCString::stripWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return copy();
+
+ register char *s = data();
+ QCString result = s;
+ int reslen = result.length();
+ if ( !isspace(s[0]) && !isspace(s[reslen-1]) )
+ return result; // returns a copy
+
+ s = result.data();
+ int start = 0;
+ int end = reslen - 1;
+ while ( isspace(s[start]) ) // skip white space from start
+ start++;
+ if ( s[start] == '\0' ) { // only white space
+ result.resize( 1 );
+ return result;
+ }
+ while ( end && isspace(s[end]) ) // skip white space from end
+ end--;
+ end -= start - 1;
+ memmove( result.data(), &s[start], end );
+ result.resize( end + 1 );
+ return result;
+}
+
+
+/*!
+ Returns a new string that has white space removed from the start and the end,
+ plus any sequence of internal white space replaced with a single space
+ (ASCII 32).
+
+ White space means any ASCII code 9, 10, 11, 12, 13 or 32.
+
+ \code
+ QCString s = " lots\t of\nwhite space ";
+ QCString t = s.simplifyWhiteSpace(); // t == "lots of white space"
+ \endcode
+
+ \sa stripWhiteSpace()
+*/
+
+QCString QCString::simplifyWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return copy();
+ QCString result( size() );
+ char *from = data();
+ char *to = result.data();
+ char *first = to;
+ while ( TRUE ) {
+ while ( *from && isspace(*from) )
+ from++;
+ while ( *from && !isspace(*from) )
+ *to++ = *from++;
+ if ( *from )
+ *to++ = 0x20; // ' '
+ else
+ break;
+ }
+ if ( to > first && *(to-1) == 0x20 )
+ to--;
+ *to = '\0';
+ result.resize( (int)((long)to - (long)result.data()) + 1 );
+ return result;
+}
+
+
+/*!
+ Insert \e s into the string before position \e index.
+
+ If \e index is beyond the end of the string, the string is extended with
+ spaces (ASCII 32) to length \e index and \e s is then appended.
+
+ \code
+ QCString s = "I like fish";
+ s.insert( 2, "don't "); // s == "I don't like fish"
+ s = "x";
+ s.insert( 3, "yz" ); // s == "x yz"
+ \endcode
+*/
+
+QCString &QCString::insert( uint index, const char *s )
+{
+ int len = qstrlen(s);
+ if ( len == 0 )
+ return *this;
+ uint olen = length();
+ int nlen = olen + len;
+ if ( index >= olen ) { // insert after end of string
+ detach();
+ if ( QByteArray::resize(nlen+index-olen+1) ) {
+ memset( data()+olen, ' ', index-olen );
+ memcpy( data()+index, s, len+1 );
+ }
+ } else if ( QByteArray::resize(nlen+1) ) { // normal insert
+ detach();
+ memmove( data()+index+len, data()+index, olen-index+1 );
+ memcpy( data()+index, s, len );
+ }
+ return *this;
+}
+
+/*!
+ Insert \e c into the string at (before) position \e index and returns
+ a reference to the string.
+
+ If \e index is beyond the end of the string, the string is extended with
+ spaces (ASCII 32) to length \e index and \e c is then appended.
+
+ Example:
+ \code
+ QCString s = "Yes";
+ s.insert( 3, '!'); // s == "Yes!"
+ \endcode
+
+ \sa remove(), replace()
+*/
+
+QCString &QCString::insert( uint index, char c ) // insert char
+{
+ char buf[2];
+ buf[0] = c;
+ buf[1] = '\0';
+ return insert( index, buf );
+}
+
+/*!
+ \fn QCString &QCString::prepend( const char *s )
+
+ Prepend \a s to the string. Equivalent to insert(0,s).
+
+ \sa insert()
+*/
+
+/*!
+ Removes \e len characters starting at position \e index from the
+ string and returns a reference to the string.
+
+ If \e index is too big, nothing happens. If \e index is valid, but
+ \e len is too large, the rest of the string is removed.
+
+ \code
+ QCString s = "Montreal";
+ s.remove( 1, 4 );
+ // s == "Meal"
+ \endcode
+
+ \sa insert(), replace()
+*/
+
+QCString &QCString::remove( uint index, uint len )
+{
+ uint olen = length();
+ if ( index + len >= olen ) { // range problems
+ if ( index < olen ) { // index ok
+ detach();
+ resize( index+1 );
+ }
+ } else if ( len != 0 ) {
+ detach();
+ memmove( data()+index, data()+index+len, olen-index-len+1 );
+ QByteArray::resize(olen-len+1);
+ }
+ return *this;
+}
+
+/*!
+ Replaces \e len characters starting at position \e index from the
+ string with \e s, and returns a reference to the string.
+
+ If \e index is too big, nothing is deleted and \e s is inserted at the
+ end of the string. If \e index is valid, but \e len is too large, \e
+ str replaces the rest of the string.
+
+ \code
+ QCString s = "Say yes!";
+ s.replace( 4, 3, "NO" ); // s == "Say NO!"
+ \endcode
+
+ \sa insert(), remove()
+*/
+
+QCString &QCString::replace( uint index, uint len, const char *s )
+{
+ remove( index, len );
+ insert( index, s );
+ return *this;
+}
+
+
+/*!
+ Finds the first occurrence of the regular expression \e rx, starting at
+ position \e index.
+
+ Returns the position of the next match, or -1 if \e rx was not found.
+*/
+
+int QCString::find( const QRegExp &rx, int index ) const
+{
+ QString d = QString::fromLatin1( data() );
+ return d.find( rx, index );
+}
+
+/*!
+ Finds the first occurrence of the regular expression \e rx, starting at
+ position \e index and searching backwards.
+
+ The search will start from the end of the string if \e index is negative.
+
+ Returns the position of the next match (backwards), or -1 if \e rx was not
+ found.
+*/
+
+int QCString::findRev( const QRegExp &rx, int index ) const
+{
+ QString d = QString::fromLatin1( data() );
+ return d.findRev( rx, index );
+}
+
+/*!
+ Counts the number of overlapping occurrences of \e rx in the string.
+
+ Example:
+ \code
+ QString s = "banana and panama";
+ QRegExp r = QRegExp("a[nm]a", TRUE, FALSE);
+ s.contains( r ); // 4 matches
+ \endcode
+
+ \sa find(), findRev()
+*/
+
+int QCString::contains( const QRegExp &rx ) const
+{
+ QString d = QString::fromLatin1( data() );
+ return d.contains( rx );
+}
+
+
+/*!
+ Replaces every occurrence of \e rx in the string with \e str.
+ Returns a reference to the string.
+
+ Example:
+ \code
+ QString s = "banana";
+ s.replace( QRegExp("a.*a"), "" ); // becomes "b"
+
+ QString s = "banana";
+ s.replace( QRegExp("^[bn]a"), " " ); // becomes " nana"
+
+ QString s = "banana";
+ s.replace( QRegExp("^[bn]a"), "" ); // NOTE! becomes ""
+ \endcode
+
+*/
+
+QCString &QCString::replace( const QRegExp &rx, const char *str )
+{
+ QString d = QString::fromLatin1( data() );
+ QString r = QString::fromLatin1( str );
+ d.replace( rx, r );
+ setStr( d.ascii() );
+ return *this;
+}
+
+/*!
+ Returns the string converted to a <code>long</code> value.
+
+ If \e ok is non-null, \e *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all, or if
+ it has trailing garbage.
+*/
+
+long QCString::toLong( bool *ok ) const
+{
+ char *p = data();
+ long val=0;
+ const long max_mult = 214748364;
+ bool is_ok = FALSE;
+ int neg = 0;
+ if ( !p )
+ goto bye;
+ while ( isspace(*p) ) // skip leading space
+ p++;
+ if ( *p == '-' ) {
+ p++;
+ neg = 1;
+ } else if ( *p == '+' ) {
+ p++;
+ }
+ if ( !isdigit(*p) )
+ goto bye;
+ while ( isdigit(*p) ) {
+ if ( val > max_mult || (val == max_mult && (*p-'0') > 7+neg) )
+ goto bye;
+ val = 10*val + (*p++ - '0');
+ }
+ if ( neg )
+ val = -val;
+ while ( isspace(*p) ) // skip trailing space
+ p++;
+ if ( *p == '\0' )
+ is_ok = TRUE;
+bye:
+ if ( ok )
+ *ok = is_ok;
+ return is_ok ? val : 0;
+}
+
+/*!
+ Returns the string converted to an <code>unsigned long</code>
+ value.
+
+ If \e ok is non-null, \e *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all,
+ or if it has trailing garbage.
+*/
+
+ulong QCString::toULong( bool *ok ) const
+{
+ char *p = data();
+ ulong val=0;
+ const ulong max_mult = 429496729;
+ bool is_ok = FALSE;
+ if ( !p )
+ goto bye;
+ while ( isspace(*p) ) // skip leading space
+ p++;
+ if ( *p == '+' )
+ p++;
+ if ( !isdigit(*p) )
+ goto bye;
+ while ( isdigit(*p) ) {
+ if ( val > max_mult || (val == max_mult && (*p-'0') > 5) )
+ goto bye;
+ val = 10*val + (*p++ - '0');
+ }
+ while ( isspace(*p) ) // skip trailing space
+ p++;
+ if ( *p == '\0' )
+ is_ok = TRUE;
+bye:
+ if ( ok )
+ *ok = is_ok;
+ return is_ok ? val : 0;
+}
+
+/*!
+ Returns the string converted to a <code>short</code> value.
+
+ If \e ok is non-null, \e *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all, or if
+ it has trailing garbage.
+*/
+
+short QCString::toShort( bool *ok ) const
+{
+ long v = toLong( ok );
+ if ( ok && *ok && (v < -32768 || v > 32767) )
+ *ok = FALSE;
+ return (short)v;
+}
+
+/*!
+ Returns the string converted to an <code>unsigned short</code> value.
+
+ If \e ok is non-null, \e *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all, or if
+ it has trailing garbage.
+*/
+
+ushort QCString::toUShort( bool *ok ) const
+{
+ ulong v = toULong( ok );
+ if ( ok && *ok && (v > 65535) )
+ *ok = FALSE;
+ return (ushort)v;
+}
+
+
+/*!
+ Returns the string converted to a <code>int</code> value.
+
+ If \e ok is non-null, \e *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all,
+ or if it has trailing garbage.
+*/
+
+int QCString::toInt( bool *ok ) const
+{
+ return (int)toLong( ok );
+}
+
+/*!
+ Returns the string converted to an <code>unsigned int</code> value.
+
+ If \e ok is non-null, \e *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all,
+ or if it has trailing garbage.
+*/
+
+uint QCString::toUInt( bool *ok ) const
+{
+ return (uint)toULong( ok );
+}
+
+/*!
+ Returns the string converted to a <code>double</code> value.
+
+ If \e ok is non-null, \e *ok is set to TRUE if there are no conceivable
+ errors, and FALSE if the string is not a number at all, or if it has
+ trailing garbage.
+*/
+
+double QCString::toDouble( bool *ok ) const
+{
+ char *end;
+ double val = strtod( data() ? data() : "", &end );
+ if ( ok )
+ *ok = ( data() && *data() && ( end == 0 || *end == '\0' ) );
+ return val;
+}
+
+/*!
+ Returns the string converted to a <code>float</code> value.
+
+ If \e ok is non-null, \e *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all,
+ or if it has trailing garbage.
+*/
+
+float QCString::toFloat( bool *ok ) const
+{
+ return (float)toDouble( ok );
+}
+
+
+/*!
+ Makes a deep copy of \e str.
+ Returns a reference to the string.
+*/
+
+QCString &QCString::setStr( const char *str )
+{
+ detach();
+ if ( str ) // valid string
+ store( str, qstrlen(str)+1 );
+ else // empty
+ resize( 0 );
+ return *this;
+}
+
+/*!
+ Sets the string to the printed value of \e n and returns a
+ reference to the string.
+*/
+
+QCString &QCString::setNum( long n )
+{
+ detach();
+ char buf[20];
+ register char *p = &buf[19];
+ bool neg;
+ if ( n < 0 ) {
+ neg = TRUE;
+ n = -n;
+ } else {
+ neg = FALSE;
+ }
+ *p = '\0';
+ do {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ if ( neg )
+ *--p = '-';
+ store( p, qstrlen(p)+1 );
+ return *this;
+}
+
+/*!
+ Sets the string to the printed unsigned value of \e n and
+ returns a reference to the string.
+*/
+
+QCString &QCString::setNum( ulong n )
+{
+ detach();
+ char buf[20];
+ register char *p = &buf[19];
+ *p = '\0';
+ do {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ store( p, qstrlen(p)+1 );
+ return *this;
+}
+
+/*!
+ \fn QCString &QCString::setNum( int n )
+ Sets the string to the printed value of \e n and returns a reference
+ to the string.
+*/
+
+/*!
+ \fn QCString &QCString::setNum( uint n )
+ Sets the string to the printed unsigned value of \e n and returns a
+ reference to the string.
+*/
+
+/*!
+ \fn QCString &QCString::setNum( short n )
+ Sets the string to the printed value of \e n and returns a reference
+ to the string.
+*/
+
+/*!
+ \fn QCString &QCString::setNum( ushort n )
+ Sets the string to the printed unsigned value of \e n and returns a
+ reference to the string.
+*/
+
+/*!
+ Sets the string to the printed value of \e n.
+
+ \arg \e f is the format specifier: 'f', 'F', 'e', 'E', 'g', 'G' (same
+ as sprintf()).
+ \arg \e prec is the precision.
+
+ Returns a reference to the string.
+*/
+
+QCString &QCString::setNum( double n, char f, int prec )
+{
+#if defined(CHECK_RANGE)
+ if ( !(f=='f' || f=='F' || f=='e' || f=='E' || f=='g' || f=='G') )
+ qWarning( "QCString::setNum: Invalid format char '%c'", f );
+#endif
+ char format[20];
+ register char *fs = format; // generate format string
+ *fs++ = '%'; // "%.<prec>l<f>"
+ if ( prec > 99 )
+ prec = 99;
+ *fs++ = '.';
+ if ( prec >= 10 ) {
+ *fs++ = prec / 10 + '0';
+ *fs++ = prec % 10 + '0';
+ } else {
+ *fs++ = prec + '0';
+ }
+ *fs++ = 'l';
+ *fs++ = f;
+ *fs = '\0';
+ return sprintf( format, n );
+}
+
+/*!
+ \fn QCString &QCString::setNum( float n, char f, int prec )
+ Sets the string to the printed value of \e n.
+
+ \arg \e f is the format specifier: 'f', 'F', 'e', 'E', 'g', 'G' (same
+ as sprintf()).
+ \arg \e prec is the precision.
+
+ Returns a reference to the string.
+*/
+
+
+/*!
+ Sets the character at position \e index to \e c and expands the
+ string if necessary, filling with spaces.
+
+ Returns FALSE if this \e index was out of range and the string could
+ not be expanded, otherwise TRUE.
+*/
+
+bool QCString::setExpand( uint index, char c )
+{
+ detach();
+ uint oldlen = length();
+ if ( index >= oldlen ) {
+ if ( !QByteArray::resize( index+2 ) ) // no memory
+ return FALSE;
+ if ( index > oldlen )
+ memset( data() + oldlen, ' ', index - oldlen );
+ *(data() + index+1) = '\0'; // terminate padded string
+ }
+ *(data() + index) = c;
+ return TRUE;
+}
+
+
+/*!
+ \fn QCString::operator const char *() const
+ Returns the string data.
+*/
+
+
+/*!
+ \fn QCString& QCString::append( const char *str )
+ Appends \e str to the string and returns a reference to the string.
+ Equivalent to operator+=().
+ */
+
+/*!
+ Appends \e str to the string and returns a reference to the string.
+*/
+
+QCString& QCString::operator+=( const char *str )
+{
+ if ( !str )
+ return *this; // nothing to append
+ detach();
+ uint len1 = length();
+ uint len2 = qstrlen(str);
+ if ( !QByteArray::resize( len1 + len2 + 1 ) )
+ return *this; // no memory
+ memcpy( data() + len1, str, len2 + 1 );
+ return *this;
+}
+
+/*!
+ Appends \e c to the string and returns a reference to the string.
+*/
+
+QCString &QCString::operator+=( char c )
+{
+ detach();
+ uint len = length();
+ if ( !QByteArray::resize( len + 2 ) )
+ return *this; // no memory
+ *(data() + len) = c;
+ *(data() + len+1) = '\0';
+ return *this;
+}
+
+
+/*****************************************************************************
+ QCString stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+/*!
+ \relates QCString
+ Writes a string to the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+QDataStream &operator<<( QDataStream &s, const QCString &str )
+{
+ return s.writeBytes( str.data(), str.size() );
+}
+
+/*!
+ \relates QCString
+ Reads a string from the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>( QDataStream &s, QCString &str )
+{
+ str.detach();
+ Q_UINT32 len;
+ s >> len; // read size of string
+ if ( len == 0 || s.eof() ) { // end of file reached
+ str.resize( 0 );
+ return s;
+ }
+ if ( !str.QByteArray::resize( (uint)len )) {// resize string
+#if defined(CHECK_NULL)
+ qWarning( "QDataStream: Not enough memory to read QCString" );
+#endif
+ len = 0;
+ }
+ if ( len > 0 ) // not null array
+ s.readRawBytes( str.data(), (uint)len );
+ return s;
+}
+#endif //QT_NO_DATASTREAM
+
+/*****************************************************************************
+ Documentation for related functions
+ *****************************************************************************/
+
+/*!
+ \fn bool operator==( const QCString &s1, const QCString &s2 )
+ \relates QCString
+ Returns TRUE if the two strings are equal, or FALSE if they are different.
+
+ Equivalent to <code>qstrcmp(s1,s2) == 0</code>.
+*/
+
+/*!
+ \fn bool operator==( const QCString &s1, const char *s2 )
+ \relates QCString
+ Returns TRUE if the two strings are equal, or FALSE if they are different.
+
+ Equivalent to <code>qstrcmp(s1,s2) == 0</code>.
+*/
+
+/*!
+ \fn bool operator==( const char *s1, const QCString &s2 )
+ \relates QCString
+ Returns TRUE if the two strings are equal, or FALSE if they are different.
+
+ Equivalent to <code>qstrcmp(s1,s2) == 0</code>.
+*/
+
+/*!
+ \fn bool operator!=( const QCString &s1, const QCString &s2 )
+ \relates QCString
+ Returns TRUE if the two strings are different, or FALSE if they are equal.
+
+ Equivalent to <code>qstrcmp(s1,s2) != 0</code>.
+*/
+
+/*!
+ \fn bool operator!=( const QCString &s1, const char *s2 )
+ \relates QCString
+ Returns TRUE if the two strings are different, or FALSE if they are equal.
+
+ Equivalent to <code>qstrcmp(s1,s2) != 0</code>.
+*/
+
+/*!
+ \fn bool operator!=( const char *s1, const QCString &s2 )
+ \relates QCString
+ Returns TRUE if the two strings are different, or FALSE if they are equal.
+
+ Equivalent to <code>qstrcmp(s1,s2) != 0</code>.
+*/
+
+/*!
+ \fn bool operator<( const QCString &s1, const char *s2 )
+ \relates QCString
+ Returns TRUE if \e s1 is alphabetically less than \e s2, otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \< 0</code>.
+*/
+
+/*!
+ \fn bool operator<( const char *s1, const QCString &s2 )
+ \relates QCString
+ Returns TRUE if \e s1 is alphabetically less than \e s2, otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \< 0</code>.
+*/
+
+/*!
+ \fn bool operator<=( const QCString &s1, const char *s2 )
+ \relates QCString
+ Returns TRUE if \e s1 is alphabetically less than or equal to \e s2,
+ otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \<= 0</code>.
+*/
+
+/*!
+ \fn bool operator<=( const char *s1, const QCString &s2 )
+ \relates QCString
+ Returns TRUE if \e s1 is alphabetically less than or equal to \e s2,
+ otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \<= 0</code>.
+*/
+
+/*!
+ \fn bool operator>( const QCString &s1, const char *s2 )
+ \relates QCString
+ Returns TRUE if \e s1 is alphabetically greater than \e s2, otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \> 0</code>.
+*/
+
+/*!
+ \fn bool operator>( const char *s1, const QCString &s2 )
+ \relates QCString
+ Returns TRUE if \e s1 is alphabetically greater than \e s2, otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \> 0</code>.
+*/
+
+/*!
+ \fn bool operator>=( const QCString &s1, const char *s2 )
+ \relates QCString
+ Returns TRUE if \e s1 is alphabetically greater than or equal to \e s2,
+ otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \>= 0</code>.
+*/
+
+/*!
+ \fn bool operator>=( const char *s1, const QCString &s2 )
+ \relates QCString
+ Returns TRUE if \e s1 is alphabetically greater than or equal to \e s2,
+ otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \>= 0</code>.
+*/
+
+/*!
+ \fn QCString operator+( const QCString &s1, const QCString &s2 )
+ \relates QCString
+ Returns the concatenated string of s1 and s2.
+*/
+
+/*!
+ \fn QCString operator+( const QCString &s1, const char *s2 )
+ \relates QCString
+ Returns the concatenated string of s1 and s2.
+*/
+
+/*!
+ \fn QCString operator+( const char *s1, const QCString &s2 )
+ \relates QCString
+ Returns the concatenated string of s1 and s2.
+*/
+
+/*!
+ \fn QCString operator+( const QCString &s, char c )
+ \relates QCString
+ Returns the concatenated string of s and c.
+*/
+
+/*!
+ \fn QCString operator+( char c, const QCString &s )
+ \relates QCString
+ Returns the concatenated string of c and s.
+*/
diff --git a/qtools/qcstring.h b/qtools/qcstring.h
new file mode 100644
index 0000000..073a969
--- /dev/null
+++ b/qtools/qcstring.h
@@ -0,0 +1,399 @@
+/****************************************************************************
+**
+**
+** Definition of the extended char array operations,
+** and QByteArray and QCString classes
+**
+** Created : 920609
+**
+** Copyright (C) 1992-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 QCSTRING_H
+#define QCSTRING_H
+
+#ifndef QT_H
+#include "qarray.h"
+#endif // QT_H
+
+#include <string.h>
+
+#if defined(_OS_SUN_) && defined(_CC_GNU_)
+#include <strings.h>
+#endif
+
+
+/*****************************************************************************
+ Fixes and workarounds for some platforms
+ *****************************************************************************/
+
+#if defined(_OS_HPUX_)
+// HP-UX has badly defined strstr() etc.
+// ### fix in 3.0: change hack_* to qt_hack_*
+// by the way HP-UX is probably right, the standard has evolved and
+// we'll have to adapt to it
+inline char *hack_strstr( const char *s1, const char *s2 )
+{ return (char *)strstr(s1, s2); }
+inline char *hack_strchr( const char *s, int c )
+{ return (char *)strchr(s, c); }
+inline char *hack_strrchr( const char *s, int c )
+{ return (char *)strrchr(s, c); }
+#define strstr(s1,s2) hack_strstr((s1),(s2))
+#define strchr(s,c) hack_strchr((s),(c))
+#define strrchr(s,c) hack_strrchr((s),(c))
+#endif
+
+
+/*****************************************************************************
+ Safe and portable C string functions; extensions to standard string.h
+ *****************************************************************************/
+
+Q_EXPORT void *qmemmove( void *dst, const void *src, uint len );
+
+#if defined(_OS_SUN_) || defined(_CC_OC_)
+#define memmove(s1,s2,n) qmemmove((s1),(s2),(n))
+#endif
+
+Q_EXPORT char *qstrdup( const char * );
+
+Q_EXPORT inline uint cstrlen( const char *str )
+{ return strlen(str); }
+
+Q_EXPORT inline uint qstrlen( const char *str )
+{ return str ? strlen(str) : 0; }
+
+Q_EXPORT inline char *cstrcpy( char *dst, const char *src )
+{ return strcpy(dst,src); }
+
+Q_EXPORT inline char *qstrcpy( char *dst, const char *src )
+{ return src ? strcpy(dst, src) : 0; }
+
+Q_EXPORT char *qstrncpy( char *dst, const char *src, uint len );
+
+Q_EXPORT inline int cstrcmp( const char *str1, const char *str2 )
+{ return strcmp(str1,str2); }
+
+Q_EXPORT inline int qstrcmp( const char *str1, const char *str2 )
+{ return (str1 && str2) ? strcmp(str1,str2) : (int)((long)str2 - (long)str1); }
+
+Q_EXPORT inline int cstrncmp( const char *str1, const char *str2, uint len )
+{ return strncmp(str1,str2,len); }
+
+Q_EXPORT inline int qstrncmp( const char *str1, const char *str2, uint len )
+{ return (str1 && str2) ? strncmp(str1,str2,len) :
+ (int)((long)str2 - (long)str1); }
+
+Q_EXPORT int qstricmp( const char *, const char * );
+
+Q_EXPORT int qstrnicmp( const char *, const char *, uint len );
+
+// ### TODO for 3.0: these and the cstr* functions should be used if
+// !defined(QT_CLEAN_NAMESPACE)
+// We want to keep source compatibility for 2.x
+// ### TODO for 4.0: completely remove these and the cstr* functions
+
+#if !defined(QT_GENUINE_STR)
+
+#undef strlen
+#define strlen qstrlen
+
+#undef strcpy
+#define strcpy qstrcpy
+
+#undef strcmp
+#define strcmp qstrcmp
+
+#undef strncmp
+#define strncmp qstrncmp
+
+#undef stricmp
+#define stricmp qstricmp
+
+#undef strnicmp
+#define strnicmp qstrnicmp
+
+#endif
+
+
+// qChecksum: Internet checksum
+
+Q_EXPORT Q_UINT16 qChecksum( const char *s, uint len );
+
+/*****************************************************************************
+ QByteArray class
+ *****************************************************************************/
+
+#if defined(Q_TEMPLATEDLL)
+template class Q_EXPORT QArray<char>;
+#endif
+typedef QArray<char> QByteArray;
+
+
+/*****************************************************************************
+ QByteArray stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QByteArray & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, QByteArray & );
+#endif
+
+
+
+/*****************************************************************************
+ QCString class
+ *****************************************************************************/
+
+class QRegExp;
+
+class Q_EXPORT QCString : public QByteArray // C string class
+{
+public:
+ QCString() {} // make null string
+ QCString( int size ); // allocate size incl. \0
+ QCString( const QCString &s ) : QByteArray( s ) {}
+ QCString( const char *str ); // deep copy
+ QCString( const char *str, uint maxlen ); // deep copy, max length
+
+ QCString &operator=( const QCString &s );// shallow copy
+ QCString &operator=( const char *str ); // deep copy
+
+ bool isNull() const;
+ bool isEmpty() const;
+ uint length() const;
+ bool resize( uint newlen );
+ bool truncate( uint pos );
+ bool fill( char c, int len = -1 );
+
+ QCString copy() const;
+
+ QCString &sprintf( const char *format, ... );
+
+ int find( char c, int index=0, bool cs=TRUE ) const;
+ int find( const char *str, int index=0, bool cs=TRUE ) const;
+ int find( const QRegExp &, int index=0 ) const;
+ int findRev( char c, int index=-1, bool cs=TRUE) const;
+ int findRev( const char *str, int index=-1, bool cs=TRUE) const;
+ int findRev( const QRegExp &, int index=-1 ) const;
+ int contains( char c, bool cs=TRUE ) const;
+ int contains( const char *str, bool cs=TRUE ) const;
+ int contains( const QRegExp & ) const;
+
+ QCString left( uint len ) const;
+ QCString right( uint len ) const;
+ QCString mid( uint index, uint len=0xffffffff) const;
+
+ QCString leftJustify( uint width, char fill=' ', bool trunc=FALSE)const;
+ QCString rightJustify( uint width, char fill=' ',bool trunc=FALSE)const;
+
+ QCString lower() const;
+ QCString upper() const;
+
+ QCString stripWhiteSpace() const;
+ QCString simplifyWhiteSpace() const;
+
+ QCString &insert( uint index, const char * );
+ QCString &insert( uint index, char );
+ QCString &append( const char * );
+ QCString &prepend( const char * );
+ QCString &remove( uint index, uint len );
+ QCString &replace( uint index, uint len, const char * );
+ QCString &replace( const QRegExp &, const char * );
+
+ short toShort( bool *ok=0 ) const;
+ ushort toUShort( bool *ok=0 ) const;
+ int toInt( bool *ok=0 ) const;
+ uint toUInt( bool *ok=0 ) const;
+ long toLong( bool *ok=0 ) const;
+ ulong toULong( bool *ok=0 ) const;
+ float toFloat( bool *ok=0 ) const;
+ double toDouble( bool *ok=0 ) const;
+
+ QCString &setStr( const char *s );
+ QCString &setNum( short );
+ QCString &setNum( ushort );
+ QCString &setNum( int );
+ QCString &setNum( uint );
+ QCString &setNum( long );
+ QCString &setNum( ulong );
+ QCString &setNum( float, char f='g', int prec=6 );
+ QCString &setNum( double, char f='g', int prec=6 );
+
+ bool setExpand( uint index, char c );
+
+ operator const char *() const;
+ QCString &operator+=( const char *str );
+ QCString &operator+=( char c );
+};
+
+
+/*****************************************************************************
+ QCString stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QCString & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, QCString & );
+#endif
+
+/*****************************************************************************
+ QCString inline functions
+ *****************************************************************************/
+
+inline QCString &QCString::operator=( const QCString &s )
+{ return (QCString&)assign( s ); }
+
+inline QCString &QCString::operator=( const char *str )
+{ return (QCString&)duplicate( str, qstrlen(str)+1 ); }
+
+inline bool QCString::isNull() const
+{ return data() == 0; }
+
+inline bool QCString::isEmpty() const
+{ return data() == 0 || *data() == '\0'; }
+
+inline uint QCString::length() const
+{ return qstrlen( data() ); }
+
+inline bool QCString::truncate( uint pos )
+{ return resize(pos+1); }
+
+inline QCString QCString::copy() const
+{ return QCString( data() ); }
+
+inline QCString &QCString::prepend( const char *s )
+{ return insert(0,s); }
+
+inline QCString &QCString::append( const char *s )
+{ return operator+=(s); }
+
+inline QCString &QCString::setNum( short n )
+{ return setNum((long)n); }
+
+inline QCString &QCString::setNum( ushort n )
+{ return setNum((ulong)n); }
+
+inline QCString &QCString::setNum( int n )
+{ return setNum((long)n); }
+
+inline QCString &QCString::setNum( uint n )
+{ return setNum((ulong)n); }
+
+inline QCString &QCString::setNum( float n, char f, int prec )
+{ return setNum((double)n,f,prec); }
+
+inline QCString::operator const char *() const
+{ return (const char *)data(); }
+
+
+/*****************************************************************************
+ QCString non-member operators
+ *****************************************************************************/
+
+Q_EXPORT inline bool operator==( const QCString &s1, const QCString &s2 )
+{ return qstrcmp(s1.data(),s2.data()) == 0; }
+
+Q_EXPORT inline bool operator==( const QCString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) == 0; }
+
+Q_EXPORT inline bool operator==( const char *s1, const QCString &s2 )
+{ return qstrcmp(s1,s2.data()) == 0; }
+
+Q_EXPORT inline bool operator!=( const QCString &s1, const QCString &s2 )
+{ return qstrcmp(s1.data(),s2.data()) != 0; }
+
+Q_EXPORT inline bool operator!=( const QCString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) != 0; }
+
+Q_EXPORT inline bool operator!=( const char *s1, const QCString &s2 )
+{ return qstrcmp(s1,s2.data()) != 0; }
+
+Q_EXPORT inline bool operator<( const QCString &s1, const QCString& s2 )
+{ return qstrcmp(s1.data(),s2.data()) < 0; }
+
+Q_EXPORT inline bool operator<( const QCString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) < 0; }
+
+Q_EXPORT inline bool operator<( const char *s1, const QCString &s2 )
+{ return qstrcmp(s1,s2.data()) < 0; }
+
+Q_EXPORT inline bool operator<=( const QCString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) <= 0; }
+
+Q_EXPORT inline bool operator<=( const char *s1, const QCString &s2 )
+{ return qstrcmp(s1,s2.data()) <= 0; }
+
+Q_EXPORT inline bool operator>( const QCString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) > 0; }
+
+Q_EXPORT inline bool operator>( const char *s1, const QCString &s2 )
+{ return qstrcmp(s1,s2.data()) > 0; }
+
+Q_EXPORT inline bool operator>=( const QCString &s1, const char *s2 )
+{ return qstrcmp(s1.data(),s2) >= 0; }
+
+Q_EXPORT inline bool operator>=( const char *s1, const QCString &s2 )
+{ return qstrcmp(s1,s2.data()) >= 0; }
+
+Q_EXPORT inline QCString operator+( const QCString &s1, const QCString &s2 )
+{
+ QCString tmp( s1.data() );
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QCString operator+( const QCString &s1, const char *s2 )
+{
+ QCString tmp( s1.data() );
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QCString operator+( const char *s1, const QCString &s2 )
+{
+ QCString tmp( s1 );
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QCString operator+( const QCString &s1, char c2 )
+{
+ QCString tmp( s1.data() );
+ tmp += c2;
+ return tmp;
+}
+
+Q_EXPORT inline QCString operator+( char c1, const QCString &s2 )
+{
+ QCString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+#endif // QCSTRING_H
diff --git a/qtools/qdatastream.cpp b/qtools/qdatastream.cpp
new file mode 100644
index 0000000..7f63cbf
--- /dev/null
+++ b/qtools/qdatastream.cpp
@@ -0,0 +1,951 @@
+/****************************************************************************
+**
+**
+** Implementation of QDataStream class
+**
+** Created : 930831
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qdatastream.h"
+
+#ifndef QT_NO_DATASTREAM
+#include "qbuffer.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+// REVISED: warwick
+/*!
+ \class QDataStream qdatastream.h
+
+ \brief The QDataStream class provides serialization of
+ binary data to a QIODevice.
+
+ \ingroup io
+
+ A data stream is a binary stream of encoded information which is 100%
+ independent of the host computer operation system, CPU or byte order. A
+ stream that is written by a PC under DOS/Windows can be read by a
+ Sun SPARC running Solaris.
+
+ The QDataStream class implements serialization of primitive types, like
+ \c char, \c short, \c int, \c char* etc. Serialization of more complex
+ data is accomplished by breaking up the data into primitive units.
+
+ The programmer can select which byte order to use when serializing data.
+ The default setting is big endian (MSB first). Changing it to little
+ endian breaks the portability (unless the reader also changes to little
+ endian). We recommend keeping this setting unless you have
+ special requirements.
+
+ A data stream cooperates closely with a QIODevice. A QIODevice
+ represents an input/output medium one can read data from and write data
+ to. The QFile class is an example of an IO device.
+
+ Example (write data to a stream):
+ \code
+ QFile f( "file.dta" );
+ f.open( IO_WriteOnly ); // open file for writing
+ QDataStream s( &f ); // serialize using f
+ s << "the answer is"; // serialize string
+ s << (Q_INT32)42; // serialize integer
+ \endcode
+
+ Example (read data from a stream):
+ \code
+ QFile f( "file.dta" );
+ f.open( IO_ReadOnly ); // open file for reading
+ QDataStream s( &f ); // serialize using f
+ char *str;
+ Q_INT32 a;
+ s >> str >> a; // "the answer is" and 42
+ delete str; // delete string
+ \endcode
+
+ In the last example, if you read into a QString instead of a \c char*
+ you do not have to delete it.
+
+ Normally, each item written to the stream is written in a fixed binary
+ format.
+ For example, a \c char* is written as a 32-bit integer equal to the
+ length of the string including the NUL byte, followed by all the
+ characters of the string including the NUL byte. Similarly when
+ reading a string, 4 bytes are read to create the 32-bit length value,
+ then that many characters for the string including the NUL. For a complete
+ description of all Qt types supporting data streaming see \link
+ datastreamformat.html Format of the QDataStream operators \endlink .
+
+ If you want a "parsing" input stream, see QTextStream. If you just want the
+ data to be human-readable to aid in debugging, you can set the data
+ stream into printable data mode with setPrintableData(). The data is
+ then written slower, in a human readable bloated form that is sufficient
+ for debugging.
+
+ If you are producing a new binary data format, such as a file format
+ for documents created by your application, you could use a QDataStream
+ to write the data in a portable format. Typically, you would write
+ a brief header containing a magic string and a version number to give
+ yourself room for future expansion. For example:
+
+ \code
+ // Open the file.
+ QFile f( "file.xxx" );
+ f.open( IO_WriteOnly );
+ QDataStream s( &f );
+
+ // Write a header with a "magic number" and a version
+ s << 0xa0b0c0d0;
+ s << 123;
+
+ // Write the data
+ s << [lots of interesting data]
+ \endcode
+
+ Then read it in with:
+
+ \code
+ // Open the file.
+ QFile f( "file.xxx" );
+ f.open( IO_ReadOnly );
+ QDataStream s( &f );
+
+ // Read and check the header
+ Q_UINT32 magic;
+ s >> magic;
+ if ( magic != 0xa0b0c0d0 )
+ return XXX_BAD_FILE_FORMAT;
+
+ // Read the version
+ Q_INT32 version;
+ s >> version;
+ if ( version < 100 )
+ return XXX_BAD_FILE_TOO_OLD;
+ if ( version > 123 )
+ return XXX_BAD_FILE_TOO_NEW;
+ if ( version <= 110 )
+ s.setVersion(1);
+
+ // Read the data
+ s >> [lots of interesting data];
+ if ( version > 120 )
+ s >> [data new in XXX version 1.2];
+ s >> [other interesting data];
+ \endcode
+
+ \sa QTextStream QVariant
+*/
+
+
+/*****************************************************************************
+ QDataStream member functions
+ *****************************************************************************/
+
+#if defined(CHECK_STATE)
+#undef CHECK_STREAM_PRECOND
+#define CHECK_STREAM_PRECOND if ( !dev ) { \
+ qWarning( "QDataStream: No device" ); \
+ return *this; }
+#else
+#define CHECK_STREAM_PRECOND
+#endif
+
+static int systemWordSize = 0;
+static bool systemBigEndian;
+
+static const int DefaultStreamVersion = 3;
+// 3 is default in Qt 2.1
+// 2 is the Qt 2.0.x format
+// 1 is the Qt 1.x format
+
+/*!
+ Constructs a data stream that has no IO device.
+
+ \sa setDevice()
+*/
+
+QDataStream::QDataStream()
+{
+ if ( systemWordSize == 0 ) // get system features
+ qSysInfo( &systemWordSize, &systemBigEndian );
+ dev = 0; // no device set
+ owndev = FALSE;
+ byteorder = BigEndian; // default byte order
+ printable = FALSE;
+ ver = DefaultStreamVersion;
+ noswap = systemBigEndian;
+}
+
+/*!
+ Constructs a data stream that uses the IO device \a d.
+
+ \sa setDevice(), device()
+*/
+
+QDataStream::QDataStream( QIODevice *d )
+{
+ if ( systemWordSize == 0 ) // get system features
+ qSysInfo( &systemWordSize, &systemBigEndian );
+ dev = d; // set device
+ owndev = FALSE;
+ byteorder = BigEndian; // default byte order
+ printable = FALSE;
+ ver = DefaultStreamVersion;
+ noswap = systemBigEndian;
+}
+
+/*!
+ Constructs a data stream that operates on a byte array through an
+ internal QBuffer device.
+
+ Example:
+ \code
+ static char bindata[] = { 231, 1, 44, ... };
+ QByteArray a;
+ a.setRawData( bindata, sizeof(bindata) ); // a points to bindata
+ QDataStream s( a, IO_ReadOnly ); // open on a's data
+ s >> [something]; // read raw bindata
+ a.resetRawData( bindata, sizeof(bindata) ); // finished
+ \endcode
+
+ The QArray::setRawData() function is not for the inexperienced.
+*/
+
+QDataStream::QDataStream( QByteArray a, int mode )
+{
+ if ( systemWordSize == 0 ) // get system features
+ qSysInfo( &systemWordSize, &systemBigEndian );
+ dev = new QBuffer( a ); // create device
+ ((QBuffer *)dev)->open( mode ); // open device
+ owndev = TRUE;
+ byteorder = BigEndian; // default byte order
+ printable = FALSE;
+ ver = DefaultStreamVersion;
+ noswap = systemBigEndian;
+}
+
+/*!
+ Destructs the data stream.
+
+ The destructor will not affect the current IO device, unless it
+ is an internal IO device processing a QByteArray passed in the constructor.
+*/
+
+QDataStream::~QDataStream()
+{
+ if ( owndev )
+ delete dev;
+}
+
+
+/*!
+ \fn QIODevice *QDataStream::device() const
+ Returns the IO device currently set.
+ \sa setDevice(), unsetDevice()
+*/
+
+/*!
+ void QDataStream::setDevice(QIODevice *d )
+ Sets the IO device to \a d.
+ \sa device(), unsetDevice()
+*/
+
+void QDataStream::setDevice(QIODevice *d )
+{
+ if ( owndev ) {
+ delete dev;
+ owndev = FALSE;
+ }
+ dev = d;
+}
+
+/*!
+ Unsets the IO device. This is the same as calling setDevice( 0 ).
+ \sa device(), setDevice()
+*/
+
+void QDataStream::unsetDevice()
+{
+ setDevice( 0 );
+}
+
+
+/*!
+ \fn bool QDataStream::atEnd() const
+ Returns TRUE if the IO device has reached the end position (end of
+ stream or file) or if there is no IO device set.
+
+ Returns FALSE if the current position of the read/write head of the IO
+ device is somewhere before the end position.
+
+ \sa QIODevice::atEnd()
+*/
+
+/*!\fn bool QDataStream::eof() const
+
+ \obsolete
+
+ Returns TRUE if the IO device has reached the end position (end of
+ stream or file) or if there is no IO device set.
+
+ Returns FALSE if the current position of the read/write head of the IO
+ device is somewhere before the end position.
+
+ \sa QIODevice::atEnd()
+*/
+
+/*!
+ \fn int QDataStream::byteOrder() const
+ Returns the current byte order setting - either \c BigEndian or
+ \c LittleEndian.
+
+ \sa setByteOrder()
+*/
+
+/*!
+ Sets the serialization byte order to \a bo.
+
+ The \a bo parameter can be \c QDataStream::BigEndian or
+ \c QDataStream::LittleEndian.
+
+ The default setting is big endian. We recommend leaving this setting unless
+ you have special requirements.
+
+ \sa byteOrder()
+*/
+
+void QDataStream::setByteOrder( int bo )
+{
+ byteorder = bo;
+ if ( systemBigEndian )
+ noswap = byteorder == BigEndian;
+ else
+ noswap = byteorder == LittleEndian;
+}
+
+
+/*!
+ \fn bool QDataStream::isPrintableData() const
+ Returns TRUE if the printable data flag has been set.
+ \sa setPrintableData()
+*/
+
+/*!
+ \fn void QDataStream::setPrintableData( bool enable )
+ Sets or clears the printable data flag.
+
+ If this flag is set, the write functions will generate output that
+ consists of printable characters (7 bit ASCII).
+
+ We recommend enabling printable data only for debugging purposes
+ (it is slower and creates larger output).
+*/
+
+
+/*!
+ \fn int QDataStream::version() const
+ Returns the version number of the data serialization format.
+ In Qt 2.1, this number is by default 3.
+ \sa setVersion()
+*/
+
+/*!
+ \fn void QDataStream::setVersion( int v )
+ Sets the version number of the data serialization format.
+
+ In order to accomodate for new functionality, the datastream
+ serialization format of some Qt classes has changed in some versions of
+ Qt. If you want to read data that was created by an earlier version of
+ Qt, or write data that can be read by a program that was compiled with
+ an earlier version of Qt, use this function to modify the serialization
+ format of QDataStream.
+
+ For Qt 1.x compatibility, use \a v == 1.
+
+ For Qt 2.0.x compatibility, use \a v == 2 (Not required for reading in
+ Qt 2.1).
+
+ \sa version()
+*/
+
+/*****************************************************************************
+ QDataStream read functions
+ *****************************************************************************/
+
+
+static Q_INT32 read_int_ascii( QDataStream *s )
+{
+ register int n = 0;
+ char buf[40];
+ while ( TRUE ) {
+ buf[n] = s->device()->getch();
+ if ( buf[n] == '\n' || n > 38 ) // $-terminator
+ break;
+ n++;
+ }
+ buf[n] = '\0';
+ return atol( buf );
+}
+
+
+/*!
+ \fn QDataStream &QDataStream::operator>>( Q_UINT8 &i )
+ Reads an unsigned byte from the stream and returns a reference to
+ the stream.
+*/
+
+/*!
+ Reads a signed byte from the stream.
+*/
+
+QDataStream &QDataStream::operator>>( Q_INT8 &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = (Q_INT8)dev->getch();
+ if ( i == '\\' ) { // read octal code
+ char buf[4];
+ dev->readBlock( buf, 3 );
+ i = (buf[2] & 0x07)+((buf[1] & 0x07) << 3)+((buf[0] & 0x07) << 6);
+ }
+ } else { // data or text
+ i = (Q_INT8)dev->getch();
+ }
+ return *this;
+}
+
+
+/*!
+ \fn QDataStream &QDataStream::operator>>( Q_UINT16 &i )
+ Reads an unsigned 16-bit integer from the stream and returns a reference to
+ the stream.
+*/
+
+/*!
+ Reads a signed 16-bit integer from the stream and returns a reference to
+ the stream.
+*/
+
+QDataStream &QDataStream::operator>>( Q_INT16 &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = (Q_INT16)read_int_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&i, sizeof(Q_INT16) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[2];
+ dev->readBlock( b, 2 );
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+
+/*!
+ \fn QDataStream &QDataStream::operator>>( Q_UINT32 &i )
+ Reads an unsigned 32-bit integer from the stream and returns a reference to
+ the stream.
+*/
+
+/*!
+ Reads a signed 32-bit integer from the stream and returns a reference to
+ the stream.
+*/
+
+QDataStream &QDataStream::operator>>( Q_INT32 &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = read_int_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&i, sizeof(Q_INT32) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[4];
+ dev->readBlock( b, 4 );
+ *p++ = b[3];
+ *p++ = b[2];
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+/*!
+ \fn QDataStream &QDataStream::operator>>( Q_UINT64 &i )
+ Reads an unsigned 64-bit integer from the stream and returns a reference to
+ the stream, or uses the Q_UINT32 operator if 64 bit is not available.
+*/
+
+/*!
+ Reads a signed 64-bit integer from the stream and returns a reference to
+ the stream, or uses the Q_UINT32 operator if 64 bit is not available.
+*/
+
+QDataStream &QDataStream::operator>>( Q_INT64 &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = read_int_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&i, sizeof(Q_INT64) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[sizeof(Q_INT64)];
+ dev->readBlock( b, sizeof(Q_INT64) );
+ if ( sizeof(Q_INT64) == 8 ) {
+ *p++ = b[7];
+ *p++ = b[6];
+ *p++ = b[5];
+ *p++ = b[4];
+ }
+ *p++ = b[3];
+ *p++ = b[2];
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+static double read_double_ascii( QDataStream *s )
+{
+ register int n = 0;
+ char buf[80];
+ while ( TRUE ) {
+ buf[n] = s->device()->getch();
+ if ( buf[n] == '\n' || n > 78 ) // $-terminator
+ break;
+ n++;
+ }
+ buf[n] = '\0';
+ return atof( buf );
+}
+
+
+/*!
+ Reads a 32-bit floating point number from the stream using the standard
+ IEEE754 format. Returns a reference to the stream.
+*/
+
+QDataStream &QDataStream::operator>>( float &f )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ f = (float)read_double_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&f, sizeof(float) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&f);
+ char b[4];
+ dev->readBlock( b, 4 );
+ *p++ = b[3];
+ *p++ = b[2];
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+
+/*!
+ Reads a 64-bit floating point number from the stream using the standard
+ IEEE754 format. Returns a reference to the stream.
+*/
+
+QDataStream &QDataStream::operator>>( double &f )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ f = read_double_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&f, sizeof(double) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&f);
+ char b[8];
+ dev->readBlock( b, 8 );
+ *p++ = b[7];
+ *p++ = b[6];
+ *p++ = b[5];
+ *p++ = b[4];
+ *p++ = b[3];
+ *p++ = b[2];
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+
+/*!
+ Reads the '\0'-terminated string \a s from the stream and returns
+ a reference to the stream.
+
+ Space for the string is allocated using \c new - the caller must
+ eventually call delete[] on the value.
+*/
+
+QDataStream &QDataStream::operator>>( char *&s )
+{
+ uint len = 0;
+ return readBytes( s, len );
+}
+
+
+/*!
+ Reads the buffer \a s from the stream and returns a reference to the
+ stream.
+
+ The buffer \a s is allocated using \c new. Destroy it with the \c delete[]
+ operator. If the length is zero or \a s cannot be allocated, \a s is
+ set to 0.
+
+ The \a l parameter will be set to the length of the buffer.
+
+ The serialization format is an Q_UINT32 length specifier first, then the
+ data (\a l bytes).
+
+ \sa readRawBytes(), writeBytes()
+*/
+
+QDataStream &QDataStream::readBytes( char *&s, uint &l )
+{
+ CHECK_STREAM_PRECOND
+ Q_UINT32 len;
+ *this >> len; // first read length spec
+ l = (uint)len;
+ if ( len == 0 || eof() ) {
+ s = 0;
+ return *this;
+ } else {
+ s = new char[len]; // create char array
+ CHECK_PTR( s );
+ if ( !s ) // no memory
+ return *this;
+ return readRawBytes( s, (uint)len );
+ }
+}
+
+
+/*!
+ Reads \a len bytes from the stream into \a s and returns a reference to
+ the stream.
+
+ The buffer \a s must be preallocated.
+
+ \sa readBytes(), QIODevice::readBlock(), writeRawBytes()
+*/
+
+QDataStream &QDataStream::readRawBytes( char *s, uint len )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ register Q_INT8 *p = (Q_INT8*)s;
+ while ( len-- )
+ *this >> *p++;
+ } else { // read data char array
+ dev->readBlock( s, len );
+ }
+ return *this;
+}
+
+
+/*****************************************************************************
+ QDataStream write functions
+ *****************************************************************************/
+
+
+/*!
+ \fn QDataStream &QDataStream::operator<<( Q_UINT8 i )
+ Writes an unsigned byte to the stream and returns a reference to
+ the stream.
+*/
+
+/*!
+ Writes a signed byte to the stream.
+*/
+
+QDataStream &QDataStream::operator<<( Q_INT8 i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable && (i == '\\' || !isprint(i)) ) {
+ char buf[6]; // write octal code
+ buf[0] = '\\';
+ buf[1] = '0' + ((i >> 6) & 0x07);
+ buf[2] = '0' + ((i >> 3) & 0x07);
+ buf[3] = '0' + (i & 0x07);
+ buf[4] = '\0';
+ dev->writeBlock( buf, 4 );
+ } else {
+ dev->putch( i );
+ }
+ return *this;
+}
+
+
+/*!
+ \fn QDataStream &QDataStream::operator<<( Q_UINT16 i )
+ Writes an unsigned 16-bit integer to the stream and returns a reference
+ to the stream.
+*/
+
+/*!
+ Writes a signed 16-bit integer to the stream and returns a reference to
+ the stream.
+*/
+
+QDataStream &QDataStream::operator<<( Q_INT16 i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[16];
+ sprintf( buf, "%d\n", i );
+ dev->writeBlock( buf, strlen(buf) );
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&i, sizeof(Q_INT16) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[2];
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 2 );
+ }
+ return *this;
+}
+
+
+/*!
+ \fn QDataStream &QDataStream::operator<<( Q_UINT32 i )
+ Writes an unsigned 32-bit integer to the stream and returns a reference to
+ the stream.
+*/
+
+/*!
+ Writes a signed 32-bit integer to the stream and returns a reference to
+ the stream.
+*/
+
+QDataStream &QDataStream::operator<<( Q_INT32 i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[16];
+ sprintf( buf, "%d\n", i );
+ dev->writeBlock( buf, strlen(buf) );
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&i, sizeof(Q_INT32) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[4];
+ b[3] = *p++;
+ b[2] = *p++;
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 4 );
+ }
+ return *this;
+}
+
+/*!
+ \fn QDataStream &QDataStream::operator<<( Q_UINT64 i )
+ Writes an unsigned 64-bit integer to the stream and returns a reference to
+ the stream, or uses the Q_UINT32-operator if 64 bit is not available.
+*/
+
+/*!
+ Writes a signed 64-bit integer to the stream and returns a reference to
+ the stream, or calls the Q_INT32-operator if 64 bit is not available.
+*/
+
+QDataStream &QDataStream::operator<<( Q_INT64 i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[20];
+ sprintf( buf, "%ld\n", i );
+ dev->writeBlock( buf, strlen(buf) );
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&i, sizeof(Q_INT64) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[sizeof(Q_INT64)];
+ if ( sizeof(Q_INT64) == 8 ) {
+ b[7] = *p++;
+ b[6] = *p++;
+ b[5] = *p++;
+ b[4] = *p++;
+ }
+ b[3] = *p++;
+ b[2] = *p++;
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, sizeof(Q_INT64) );
+ }
+ return *this;
+}
+
+/*!
+ \fn QDataStream &QDataStream::operator<<( uint i )
+ Writes an unsigned integer to the stream as a 32-bit unsigned integer
+ (Q_UINT32).
+ Returns a reference to the stream.
+*/
+
+/*!
+ \fn QDataStream &QDataStream::operator<<( int i )
+ Writes a signed integer to the stream as a 32-bit signed integer (Q_INT32).
+ Returns a reference to the stream.
+*/
+
+
+/*!
+ Writes a 32-bit floating point number to the stream using the standard
+ IEEE754 format. Returns a reference to the stream.
+*/
+
+QDataStream &QDataStream::operator<<( float f )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[32];
+ sprintf( buf, "%g\n", (double)f );
+ dev->writeBlock( buf, strlen(buf) );
+ } else {
+ float g = f; // fixes float-on-stack problem
+ if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&g, sizeof(float) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&g);
+ char b[4];
+ b[3] = *p++;
+ b[2] = *p++;
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 4 );
+ }
+ }
+ return *this;
+}
+
+
+/*!
+ Writes a 64-bit floating point number to the stream using the standard
+ IEEE754 format. Returns a reference to the stream.
+*/
+
+QDataStream &QDataStream::operator<<( double f )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[32];
+ sprintf( buf, "%g\n", f );
+ dev->writeBlock( buf, strlen(buf) );
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&f, sizeof(double) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&f);
+ char b[8];
+ b[7] = *p++;
+ b[6] = *p++;
+ b[5] = *p++;
+ b[4] = *p++;
+ b[3] = *p++;
+ b[2] = *p++;
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 8 );
+ }
+ return *this;
+}
+
+
+/*!
+ Writes the '\0'-terminated string \a s to the stream and returns
+ a reference to the stream.
+
+ The string is serialized using writeBytes().
+*/
+
+QDataStream &QDataStream::operator<<( const char *s )
+{
+ if ( !s ) {
+ *this << (Q_UINT32)0;
+ return *this;
+ }
+ uint len = qstrlen( s ) + 1; // also write null terminator
+ *this << (Q_UINT32)len; // write length specifier
+ return writeRawBytes( s, len );
+}
+
+
+/*!
+ Writes the length specifier \a len and the buffer \a s to the stream and
+ returns a reference to the stream.
+
+ The \a len is serialized as an Q_UINT32, followed by \a len bytes from
+ \a s.
+
+ \sa writeRawBytes(), readBytes()
+*/
+
+QDataStream &QDataStream::writeBytes(const char *s, uint len)
+{
+ CHECK_STREAM_PRECOND
+ *this << (Q_UINT32)len; // write length specifier
+ if ( len )
+ writeRawBytes( s, len );
+ return *this;
+}
+
+
+/*!
+ Writes \a len bytes from \a s to the stream and returns a reference to the
+ stream.
+
+ \sa writeBytes(), QIODevice::writeBlock(), readRawBytes()
+*/
+
+QDataStream &QDataStream::writeRawBytes( const char *s, uint len )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // write printable
+ register char *p = (char *)s;
+ while ( len-- )
+ *this << *p++;
+ } else { // write data char array
+ dev->writeBlock( s, len );
+ }
+ return *this;
+}
+
+#endif // QT_NO_DATASTREAM
diff --git a/qtools/qdatastream.h b/qtools/qdatastream.h
new file mode 100644
index 0000000..3d18062
--- /dev/null
+++ b/qtools/qdatastream.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+**
+** Definition of QDataStream class
+**
+** Created : 930831
+**
+** Copyright (C) 1992-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 QDATASTREAM_H
+#define QDATASTREAM_H
+
+#ifndef QT_H
+#include "qiodevice.h"
+#include "qstring.h"
+#endif // QT_H
+
+#ifndef QT_NO_DATASTREAM
+class Q_EXPORT QDataStream // data stream class
+{
+public:
+ QDataStream();
+ QDataStream( QIODevice * );
+ QDataStream( QByteArray, int mode );
+ virtual ~QDataStream();
+
+ QIODevice *device() const;
+ void setDevice( QIODevice * );
+ void unsetDevice();
+
+ bool atEnd() const;
+ bool eof() const;
+
+ enum ByteOrder { BigEndian, LittleEndian };
+ int byteOrder() const;
+ void setByteOrder( int );
+
+ bool isPrintableData() const;
+ void setPrintableData( bool );
+
+ int version() const;
+ void setVersion( int );
+
+ QDataStream &operator>>( Q_INT8 &i );
+ QDataStream &operator>>( Q_UINT8 &i );
+ QDataStream &operator>>( Q_INT16 &i );
+ QDataStream &operator>>( Q_UINT16 &i );
+ QDataStream &operator>>( Q_INT32 &i );
+ QDataStream &operator>>( Q_UINT32 &i );
+ QDataStream &operator>>( Q_INT64 &i );
+ QDataStream &operator>>( Q_UINT64 &i );
+
+ QDataStream &operator>>( float &f );
+ QDataStream &operator>>( double &f );
+ QDataStream &operator>>( char *&str );
+
+ QDataStream &operator<<( Q_INT8 i );
+ QDataStream &operator<<( Q_UINT8 i );
+ QDataStream &operator<<( Q_INT16 i );
+ QDataStream &operator<<( Q_UINT16 i );
+ QDataStream &operator<<( Q_INT32 i );
+ QDataStream &operator<<( Q_UINT32 i );
+ QDataStream &operator<<( Q_INT64 i );
+ QDataStream &operator<<( Q_UINT64 i );
+ QDataStream &operator<<( float f );
+ QDataStream &operator<<( double f );
+ QDataStream &operator<<( const char *str );
+
+ QDataStream &readBytes( char *&, uint &len );
+ QDataStream &readRawBytes( char *, uint len );
+
+ QDataStream &writeBytes( const char *, uint len );
+ QDataStream &writeRawBytes( const char *, uint len );
+
+private:
+ QIODevice *dev;
+ bool owndev;
+ int byteorder;
+ bool printable;
+ bool noswap;
+ int ver;
+
+private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ QDataStream( const QDataStream & );
+ QDataStream &operator=( const QDataStream & );
+#endif
+};
+
+
+/*****************************************************************************
+ QDataStream inline functions
+ *****************************************************************************/
+
+inline QIODevice *QDataStream::device() const
+{ return dev; }
+
+inline bool QDataStream::atEnd() const
+{ return dev ? dev->atEnd() : TRUE; }
+
+inline bool QDataStream::eof() const
+{ return atEnd(); }
+
+inline int QDataStream::byteOrder() const
+{ return byteorder; }
+
+inline bool QDataStream::isPrintableData() const
+{ return printable; }
+
+inline void QDataStream::setPrintableData( bool p )
+{ printable = p; }
+
+inline int QDataStream::version() const
+{ return ver; }
+
+inline void QDataStream::setVersion( int v )
+{ ver = v; }
+
+inline QDataStream &QDataStream::operator>>( Q_UINT8 &i )
+{ return *this >> (Q_INT8&)i; }
+
+inline QDataStream &QDataStream::operator>>( Q_UINT16 &i )
+{ return *this >> (Q_INT16&)i; }
+
+inline QDataStream &QDataStream::operator>>( Q_UINT32 &i )
+{ return *this >> (Q_INT32&)i; }
+
+inline QDataStream &QDataStream::operator>>( Q_UINT64 &i )
+{ return *this >> (Q_INT64&)i; }
+
+inline QDataStream &QDataStream::operator<<( Q_UINT8 i )
+{ return *this << (Q_INT8)i; }
+
+inline QDataStream &QDataStream::operator<<( Q_UINT16 i )
+{ return *this << (Q_INT16)i; }
+
+inline QDataStream &QDataStream::operator<<( Q_UINT32 i )
+{ return *this << (Q_INT32)i; }
+
+inline QDataStream &QDataStream::operator<<( Q_UINT64 i )
+{ return *this << (Q_INT64)i; }
+
+
+#endif // QT_NO_DATASTREAM
+#endif // QDATASTREAM_H
diff --git a/qtools/qdatetime.cpp b/qtools/qdatetime.cpp
new file mode 100644
index 0000000..521a022
--- /dev/null
+++ b/qtools/qdatetime.cpp
@@ -0,0 +1,1434 @@
+/****************************************************************************
+**
+**
+** Implementation of date and time classes
+**
+** Created : 940124
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#define gettimeofday __hide_gettimeofday
+#include "qdatetime.h"
+#include "qdatastream.h"
+#include <stdio.h>
+#include <time.h>
+#if defined(_OS_WIN32_)
+#if defined(_CC_BOOL_DEF_)
+#undef bool
+#include <windows.h>
+#define bool int
+#else
+#include <windows.h>
+#endif
+#elif defined(_OS_MSDOS_)
+#include <dos.h>
+#elif defined(_OS_OS2_)
+#include <os2.h>
+#elif defined(_OS_UNIX_)
+#include <sys/time.h>
+#include <unistd.h>
+#undef gettimeofday
+extern "C" int gettimeofday( struct timeval *, struct timezone * );
+#endif
+
+static const uint FIRST_DAY = 2361222; // Julian day for 1752/09/14
+static const int FIRST_YEAR = 1752; // ### wrong for many countries
+static const uint SECS_PER_DAY = 86400;
+static const uint MSECS_PER_DAY = 86400000;
+static const uint SECS_PER_HOUR = 3600;
+static const uint MSECS_PER_HOUR= 3600000;
+static const uint SECS_PER_MIN = 60;
+static const uint MSECS_PER_MIN = 60000;
+
+static const short monthDays[] ={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+// ##### Localize.
+
+const char * const QDate::monthNames[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+const char * const QDate::weekdayNames[] ={
+ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+
+
+/*****************************************************************************
+ QDate member functions
+ *****************************************************************************/
+
+// REVISED: aavit
+
+/*!
+ \class QDate qdatetime.h
+ \brief The QDate class provides date functions.
+
+ \ingroup time
+
+ A QDate object contains a calendar date, i.e. year, month, and day
+ numbers in the modern western (Gregorian) calendar. It can read the
+ current date from the system clock. It provides functions for
+ comparing dates and for manipulating a date by adding a number of
+ days.
+
+ A QDate object is typically created either by giving the year, month
+ and day numbers explicitly, or by using the static function
+ currentDate(), which makes a QDate object which contains the
+ system's clock date. An explicit date can also be set using
+ setYMD().
+
+ The year(), month(), and day() functions provide access to the year,
+ month, and day numbers. Also, dayOfWeek() and dayOfYear() functions
+ are provided. The same information is provided in textual format by
+ the toString(), dayName(), and monthName() functions.
+
+ QDate provides a full set of operators to compare two QDate
+ objects. A date is considered smaller than another if it is earlier
+ than the other.
+
+ The date a given number of days later than a given date can be found
+ using the addDays() function. Correspondingly, the number of days
+ between two dates can be found using the daysTo() function.
+
+ The daysInMonth() and daysInYear() functions tell how many days
+ there are in this date's month and year, respectively. The
+ isLeapYear() function tells whether this date is in a leap year.
+
+ Note that QDate may not be used for date calculations for dates in
+ the remote past, i.e. prior to the introduction of the Gregorian
+ calendar. This calendar was adopted by England Sep. 14. 1752 (hence
+ this is the earliest valid QDate), and subsequently by most other
+ western countries, until 1923.
+
+ The end of time is reached around 8000AD, by which time we expect Qt
+ to be obsolete.
+
+ \sa QTime, QDateTime
+*/
+
+
+/*!
+ \fn QDate::QDate()
+ Constructs a null date. Null dates are invalid.
+
+ \sa isNull(), isValid()
+*/
+
+
+/*!
+ Constructs a date with the year \a y, month \a m and day \a d.
+
+ \a y must be in the range 1752-ca. 8000, \a m must be in the range
+ 1-12, and \a d must be in the range 1-31. Exception: if \a y is in
+ the range 0-99, it is interpreted as 1900-1999.
+
+ \sa isValid()
+*/
+
+QDate::QDate( int y, int m, int d )
+{
+ jd = 0;
+ setYMD( y, m, d );
+}
+
+
+/*!
+ \fn bool QDate::isNull() const
+
+ Returns TRUE if the date is null. A null date is invalid.
+
+ \sa isValid()
+*/
+
+
+/*!
+ Returns TRUE if this date is valid.
+
+ \sa isNull()
+*/
+
+bool QDate::isValid() const
+{
+ return jd >= FIRST_DAY;
+}
+
+
+/*!
+ Returns the year (>= 1752) of this date.
+
+ \sa month(), day()
+*/
+
+int QDate::year() const
+{
+ int y, m, d;
+ jul2greg( jd, y, m, d );
+ return y;
+}
+
+/*!
+ Returns the month (January=1 .. December=12) of this date.
+
+ \sa year(), day()
+*/
+
+int QDate::month() const
+{
+ int y, m, d;
+ jul2greg( jd, y, m, d );
+ return m;
+}
+
+/*!
+ Returns the day of the month (1..31) of this date.
+
+ \sa year(), month(), dayOfWeek()
+*/
+
+int QDate::day() const
+{
+ int y, m, d;
+ jul2greg( jd, y, m, d );
+ return d;
+}
+
+/*!
+ Returns the weekday (Monday=1 .. Sunday=7) for this date.
+
+ \sa day(), dayOfYear()
+*/
+
+int QDate::dayOfWeek() const
+{
+ return (((jd+1) % 7) + 6)%7 + 1;
+}
+
+/*!
+ Returns the day of the year (1..365) for this date.
+
+ \sa day(), dayOfWeek()
+*/
+
+int QDate::dayOfYear() const
+{
+ return jd - greg2jul(year(), 1, 1) + 1;
+}
+
+/*!
+ Returns the number of days in the month (28..31) for this date.
+
+ \sa day(), daysInYear()
+*/
+
+int QDate::daysInMonth() const
+{
+ int y, m, d;
+ jul2greg( jd, y, m, d );
+ if ( m == 2 && leapYear(y) )
+ return 29;
+ else
+ return monthDays[m];
+}
+
+/*!
+ Returns the number of days in the year (365 or 366) for this date.
+
+ \sa day(), daysInMonth()
+*/
+
+int QDate::daysInYear() const
+{
+ int y, m, d;
+ jul2greg( jd, y, m, d );
+ return leapYear(y) ? 366 : 365;
+}
+
+
+/*!
+ Returns the name of the \a month.
+
+ Month 1 == "Jan", month 2 == "Feb" etc.
+
+ \sa toString(), dayName()
+*/
+
+QString QDate::monthName( int month ) const
+{
+#if defined(CHECK_RANGE)
+ if ( month < 1 || month > 12 ) {
+ qWarning( "QDate::monthName: Parameter out ouf range." );
+ month = 1;
+ }
+#endif
+ // ### Remove the fromLatin1 during localization
+ return QString::fromLatin1(monthNames[month-1]);
+}
+
+/*!
+ Returns the name of the \a weekday.
+
+ Weekday 1 == "Mon", day 2 == "Tue" etc.
+
+ \sa toString(), monthName()
+*/
+
+QString QDate::dayName( int weekday ) const
+{
+#if defined(CHECK_RANGE)
+ if ( weekday < 1 || weekday > 7 ) {
+ qWarning( "QDate::dayName: Parameter out of range." );
+ weekday = 1;
+ }
+#endif
+ // ### Remove the fromLatin1 during localization
+ return QString::fromLatin1(weekdayNames[weekday-1]);
+}
+
+
+/*!
+ Returns the date as a string.
+
+ The string format is "Sat May 20 1995". This function uses the
+ dayName() and monthName() functions to generate the string.
+
+ \sa dayName(), monthName()
+*/
+
+QString QDate::toString() const
+{
+ int y, m, d;
+ jul2greg( jd, y, m, d );
+ QString buf = dayName(dayOfWeek());
+ buf += ' ';
+ buf += monthName(m);
+ QString t;
+ t.sprintf( " %d %d", d, y);
+ buf += t;
+ return buf;
+}
+
+
+/*!
+ Sets the year \a y, month \a m and day \a d.
+
+ \a y must be in the range 1752-ca. 8000, \a m must be in the range
+ 1-12, and \a d must be in the range 1-31. Exception: if \a y is in
+ the range 0-99, it is interpreted as 1900-1999.
+
+ Returns TRUE if the date is valid, otherwise FALSE.
+*/
+
+bool QDate::setYMD( int y, int m, int d )
+{
+ if ( !isValid(y,m,d) ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QDate::setYMD: Invalid date %04d/%02d/%02d", y, m, d );
+#endif
+ return FALSE;
+ }
+ jd = greg2jul( y, m, d );
+#if defined(DEBUG)
+ ASSERT( year() == y && month() == m && day() == d );
+#endif
+ return TRUE;
+}
+
+/*!
+ Returns a QDate object containing a date \a ndays later than the
+ date of this object (or earlier if \a ndays is negative).
+
+ \sa daysTo()
+*/
+
+QDate QDate::addDays( int ndays ) const
+{
+ QDate d;
+ d.jd = jd + ndays;
+ return d;
+}
+
+/*!
+ Returns the number of days from this date to \a d (which is negative
+ if \a d is earlier than this date).
+
+ Example:
+ \code
+ QDate d1( 1995, 5, 17 ); // May 17th 1995
+ QDate d2( 1995, 5, 20 ); // May 20th 1995
+ d1.daysTo( d2 ); // returns 3
+ d2.daysTo( d1 ); // returns -3
+ \endcode
+
+ \sa addDays()
+*/
+
+int QDate::daysTo( const QDate &d ) const
+{
+ return d.jd - jd;
+}
+
+
+/*!
+ \fn bool QDate::operator==( const QDate &d ) const
+ Returns TRUE if this date is equal to \a d, or FALSE if
+ they are different.
+*/
+
+/*!
+ \fn bool QDate::operator!=( const QDate &d ) const
+ Returns TRUE if this date is different from \a d, or FALSE if
+ they are equal.
+*/
+
+/*!
+ \fn bool QDate::operator<( const QDate &d ) const
+ Returns TRUE if this date is earlier than \a d, otherwise FALSE.
+*/
+
+/*!
+ \fn bool QDate::operator<=( const QDate &d ) const
+ Returns TRUE if this date is earlier than or equal to \a d, otherwise FALSE.
+*/
+
+/*!
+ \fn bool QDate::operator>( const QDate &d ) const
+ Returns TRUE if this date is later than \a d, otherwise FALSE.
+*/
+
+/*!
+ \fn bool QDate::operator>=( const QDate &d ) const
+ Returns TRUE if this date is later than or equal to \a d, otherwise FALSE.
+*/
+
+
+/*!
+ Returns the current date, as reported by the system clock.
+
+ \sa QTime::currentTime(), QDateTime::currentDateTime()
+*/
+
+QDate QDate::currentDate()
+{
+#if defined(_OS_WIN32_)
+
+ SYSTEMTIME t;
+ GetLocalTime( &t );
+ QDate d;
+ d.jd = greg2jul( t.wYear, t.wMonth, t.wDay );
+ return d;
+
+#else
+
+ time_t ltime;
+ time( &ltime );
+ tm *t = localtime( &ltime );
+ QDate d;
+ d.jd = greg2jul( t->tm_year + 1900, t->tm_mon + 1, t->tm_mday );
+ return d;
+
+#endif
+}
+
+/*!
+ Returns TRUE if the specified date (year \a y, month \a m and day \a
+ d) is valid.
+
+ Example:
+ \code
+ QDate::isValid( 2002, 5, 17 ); // TRUE; May 17th 2002 is OK.
+ QDate::isValid( 2002, 2, 30 ); // FALSE; Feb 30th does not exist
+ QDate::isValid( 2004, 2, 29 ); // TRUE; 2004 is a leap year
+ QDate::isValid( 1202, 6, 6 ); // FALSE; 1202 is pre-Gregorian
+ \endcode
+
+ Note that a \a y value in the range 00-99 is interpreted as
+ 1900-1999.
+
+ \sa isNull(), setYMD()
+*/
+
+bool QDate::isValid( int y, int m, int d )
+{
+ if ( y >= 0 && y <= 99 )
+ y += 1900;
+ else if ( y < FIRST_YEAR || (y == FIRST_YEAR && (m < 9 ||
+ (m == 9 && d < 14))) )
+ return FALSE;
+ return (d > 0 && m > 0 && m <= 12) &&
+ (d <= monthDays[m] || (d == 29 && m == 2 && leapYear(y)));
+}
+
+/*!
+ Returns TRUE if the specified year \a y is a leap year.
+*/
+
+bool QDate::leapYear( int y )
+{
+ return y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
+}
+
+/*!
+ \internal
+ Converts a Gregorian date to a Julian day.
+ This algorithm is taken from Communications of the ACM, Vol 6, No 8.
+ \sa jul2greg()
+*/
+
+uint QDate::greg2jul( int y, int m, int d )
+{
+ uint c, ya;
+ if ( y <= 99 )
+ y += 1900;
+ if ( m > 2 ) {
+ m -= 3;
+ } else {
+ m += 9;
+ y--;
+ }
+ c = y; // NOTE: Sym C++ 6.0 bug
+ c /= 100;
+ ya = y - 100*c;
+ return 1721119 + d + (146097*c)/4 + (1461*ya)/4 + (153*m+2)/5;
+}
+
+/*!
+ \internal
+ Converts a Julian day to a Gregorian date.
+ This algorithm is taken from Communications of the ACM, Vol 6, No 8.
+ \sa greg2jul()
+*/
+
+void QDate::jul2greg( uint jd, int &y, int &m, int &d )
+{
+ uint x;
+ uint j = jd - 1721119;
+ y = (j*4 - 1)/146097;
+ j = j*4 - 146097*y - 1;
+ x = j/4;
+ j = (x*4 + 3) / 1461;
+ y = 100*y + j;
+ x = (x*4) + 3 - 1461*j;
+ x = (x + 4)/4;
+ m = (5*x - 3)/153;
+ x = 5*x - 3 - 153*m;
+ d = (x + 5)/5;
+ if ( m < 10 ) {
+ m += 3;
+ } else {
+ m -= 9;
+ y++;
+ }
+}
+
+
+/*****************************************************************************
+ QTime member functions
+ *****************************************************************************/
+
+/*!
+ \class QTime qdatetime.h
+
+ \brief The QTime class provides clock time functions.
+
+ \ingroup time
+
+ A QTime object contains a clock time, i.e. a number of hours,
+ minutes, seconds and milliseconds since midnight. It can read the
+ current time from the system clock, and measure a span of elapsed
+ time. It provides functions for comparing times and for manipulating
+ a time by adding a number of (milli)seconds.
+
+ QTime operates with 24-hour clock format; it has no concept of
+ AM/PM. It operates with local time; it does not know anything about
+ time zones or daylight savings time.
+
+ A QTime object is typically created either by giving the number of
+ hours, minutes, seconds, and milliseconds explicitly, or by using
+ the static function currentTime(), which makes a QTime object which
+ contains the system's clock time. Note that the accuracy depends on
+ the accuracy of the underlying operating system; not all systems
+ provide 1-millisecond accuracy.
+
+ The hour(), minute(), second(), and msec() functions provide access
+ to the number of hours, minutes, seconds, and milliseconds of the
+ time. The same information is provided in textual format by the
+ toString() function.
+
+ QTime provides a full set of operators to compare two QTime
+ objects. A time is considered smaller than another if it is earlier
+ than the other.
+
+ The time a given number of seconds or milliseconds later than a
+ given time can be found using the addSecs() or addMSecs()
+ functions. Correspondingly, the number of (milli)seconds between two
+ times can be found using the secsTo() or msecsTo() functions.
+
+ QTime can be used to measure a span of elapsed time using the
+ start(), restart(), and elapsed() functions.
+
+ \sa QDate, QDateTime
+*/
+
+/*!
+ \fn QTime::QTime()
+
+ Constructs the time 0 hours, minutes, seconds and milliseconds,
+ i.e. 00:00:00.000 (midnight). This is a valid time.
+
+ \sa isValid()
+*/
+
+/*!
+ Constructs a time with hour \a h, minute \a m, seconds \a s and
+ milliseconds \a ms.
+
+ \a h must be in the range 0-23, \a m and \a s must be in the range
+ 0-59, and \a ms must be in the range 0-999.
+
+ \sa isValid()
+*/
+
+QTime::QTime( int h, int m, int s, int ms )
+{
+ setHMS( h, m, s, ms );
+}
+
+
+/*!
+ \fn bool QTime::isNull() const
+ Returns TRUE if the time is equal to 00:00:00.000. A null time is valid.
+
+ \sa isValid()
+*/
+
+/*!
+ Returns TRUE if the time is valid, or FALSE if the time is invalid.
+ The time 23:30:55.746 is valid, while 24:12:30 is invalid.
+
+ \sa isNull()
+*/
+
+bool QTime::isValid() const
+{
+ return ds < MSECS_PER_DAY;
+}
+
+
+/*!
+ Returns the hour part (0..23) of the time.
+*/
+
+int QTime::hour() const
+{
+ return ds / MSECS_PER_HOUR;
+}
+
+/*!
+ Returns the minute part (0..59) of the time.
+*/
+
+int QTime::minute() const
+{
+ return (ds % MSECS_PER_HOUR)/MSECS_PER_MIN;
+}
+
+/*!
+ Returns the second part (0..59) of the time.
+*/
+
+int QTime::second() const
+{
+ return (ds / 1000)%SECS_PER_MIN;
+}
+
+/*!
+ Returns the millisecond part (0..999) of the time.
+*/
+
+int QTime::msec() const
+{
+ return ds % 1000;
+}
+
+
+/*!
+ Returns the time of this object in a textual format. Milliseconds
+ are not included. The string format is HH:MM:SS, e.g. 1 second
+ before midnight would be "23:59:59".
+*/
+
+QString QTime::toString() const
+{
+ QString buf;
+ buf.sprintf( "%.2d:%.2d:%.2d", hour(), minute(), second() );
+ return buf;
+}
+
+
+/*!
+ Sets the time to hour \a h, minute \a m, seconds \a s and
+ milliseconds \a ms.
+
+ \a h must be in the range 0-23, \a m and \a s must be in the range
+ 0-59, and \a ms must be in the range 0-999. Returns TRUE if the set
+ time is valid, otherwise FALSE.
+
+ \sa isValid()
+*/
+
+bool QTime::setHMS( int h, int m, int s, int ms )
+{
+ if ( !isValid(h,m,s,ms) ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QTime::setHMS Invalid time %02d:%02d:%02d.%03d", h, m, s,
+ ms );
+#endif
+ ds = MSECS_PER_DAY; // make this invalid
+ return FALSE;
+ }
+ ds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms;
+ return TRUE;
+}
+
+/*!
+ Returns a QTime object containing a time \a nsecs seconds later than
+ the time of this object (or earlier if \a ms is negative).
+
+ Note that the time will wrap if it passes midnight.
+
+ Example:
+ \code
+ QTime n( 14, 0, 0 ); // n == 14:00:00
+ QTime t;
+ t = n.addSecs( 70 ); // t == 14:01:10
+ t = n.addSecs( -70 ); // t == 13:58:50
+ t = n.addSecs( 10*60*60 + 5 ); // t == 00:00:05
+ t = n.addSecs( -15*60*60 ); // t == 23:00:00
+ \endcode
+
+ \sa addMSecs(), secsTo(), QDateTime::addSecs()
+*/
+
+QTime QTime::addSecs( int nsecs ) const
+{
+ return addMSecs(nsecs*1000);
+}
+
+/*!
+ Returns the number of seconds from this time to \a t (which is
+ negative if \a t is earlier than this time).
+
+ Since QTime measures time within a day and there are 86400 seconds
+ in a day, the result is between -86400 and 86400.
+
+ \sa addSecs() QDateTime::secsTo()
+*/
+
+int QTime::secsTo( const QTime &t ) const
+{
+ return ((int)t.ds - (int)ds)/1000;
+}
+
+/*!
+ Returns a QTime object containing a time \a ms milliseconds later than
+ the time of this object (or earlier if \a ms is negative).
+
+ Note that the time will wrap if it passes midnight. See addSecs()
+ for an example.
+
+ \sa addSecs(), msecsTo()
+*/
+
+QTime QTime::addMSecs( int ms ) const
+{
+ QTime t;
+ if ( ms < 0 ) {
+ // % not well-defined for -ve, but / is.
+ int negdays = (MSECS_PER_DAY-ms) / MSECS_PER_DAY;
+ t.ds = ((int)ds + ms + negdays*MSECS_PER_DAY)
+ % MSECS_PER_DAY;
+ } else {
+ t.ds = ((int)ds + ms) % MSECS_PER_DAY;
+ }
+ return t;
+}
+
+/*!
+ Returns the number of milliseconds from this time to \a t (which is
+ negative if \a t is earlier than this time).
+
+ Since QTime measures time within a day and there are 86400000
+ milliseconds in a day, the result is between -86400000 and 86400000.
+
+ \sa secsTo()
+*/
+
+int QTime::msecsTo( const QTime &t ) const
+{
+ return (int)t.ds - (int)ds;
+}
+
+
+/*!
+ \fn bool QTime::operator==( const QTime &t ) const
+
+ Returns TRUE if this time is equal to \a t, or FALSE if they are
+ different.
+*/
+
+/*!
+ \fn bool QTime::operator!=( const QTime &t ) const
+
+ Returns TRUE if this time is different from \a t, or FALSE if they
+ are equal.
+*/
+
+/*!
+ \fn bool QTime::operator<( const QTime &t ) const
+
+ Returns TRUE if this time is earlier than \a t, otherwise FALSE.
+*/
+
+/*!
+ \fn bool QTime::operator<=( const QTime &t ) const
+
+ Returns TRUE if this time is earlier than or equal to \a t,
+ otherwise FALSE.
+*/
+
+/*!
+ \fn bool QTime::operator>( const QTime &t ) const
+
+ Returns TRUE if this time is later than \a t, otherwise FALSE.
+*/
+
+/*!
+ \fn bool QTime::operator>=( const QTime &t ) const
+
+ Returns TRUE if this time is later than or equal to \a t, otherwise
+ FALSE.
+*/
+
+
+
+/*!
+ Returns the current time, as reported by the system clock.
+
+ Note that the accuracy depends on the accuracy of the underlying
+ operating system; not all systems provide 1-millisecond accuracy.
+*/
+
+QTime QTime::currentTime()
+{
+ QTime ct;
+ currentTime( &ct );
+ return ct;
+}
+
+/*!
+ \internal
+
+ Fetches the current time and returns TRUE if the time is within one
+ minute after midnight, otherwise FALSE. The return value is used by
+ QDateTime::currentDateTime() to ensure that the date there is correct.
+*/
+
+bool QTime::currentTime( QTime *ct )
+{
+ if ( !ct ) {
+#if defined(CHECK_NULL)
+ qWarning( "QTime::currentTime(QTime *): Null pointer not allowed" );
+#endif
+ return FALSE;
+ }
+
+#if defined(_OS_WIN32_)
+
+ SYSTEMTIME t;
+ GetLocalTime( &t );
+ ct->ds = MSECS_PER_HOUR*t.wHour + MSECS_PER_MIN*t.wMinute +
+ 1000*t.wSecond + t.wMilliseconds;
+ return (t.wHour == 0 && t.wMinute == 0);
+
+#elif defined(_OS_OS2_)
+
+ DATETIME t;
+ DosGetDateTime( &t );
+ ct->ds = MSECS_PER_HOUR*t.hours + MSECS_PER_MIN*t.minutes +
+ 1000*t.seconds + 10*t.hundredths;
+ return (t.hours == 0 && t.minutes == 0);
+
+#elif defined(_OS_MSDOS_)
+
+ _dostime_t t;
+ _dos_gettime( &t );
+ ct->ds = MSECS_PER_HOUR*t.hour + MSECS_PER_MIN*t.minute +
+ t.second*1000 + t.hsecond*10;
+ return (t.hour== 0 && t.minute == 0);
+
+#elif defined(_OS_UNIX_)
+
+ struct timeval tv;
+ gettimeofday( &tv, 0 );
+ time_t ltime = tv.tv_sec;
+ tm *t = localtime( &ltime );
+ ct->ds = (uint)( MSECS_PER_HOUR*t->tm_hour + MSECS_PER_MIN*t->tm_min +
+ 1000*t->tm_sec + tv.tv_usec/1000 );
+ return (t->tm_hour== 0 && t->tm_min == 0);
+
+#else
+
+ time_t ltime; // no millisecond resolution!!
+ ::time( &ltime );
+ tm *t = localtime( &ltime );
+ ct->ds = MSECS_PER_HOUR*t->tm_hour + MSECS_PER_MIN*t->tm_min +
+ 1000*t->tm_sec;
+ return (t->tm_hour== 0 && t->tm_min == 0);
+#endif
+}
+
+/*!
+ Returns TRUE if the specified time is valid, otherwise FALSE.
+
+ The time is valid if \a h is in the range 0-23, \a m and \a s are in
+ the range 0-59, and \a ms is in the range 0-999.
+
+ Example:
+ \code
+ QTime::isValid(21, 10, 30); // returns TRUE
+ QTime::isValid(22, 5, 62); // returns FALSE
+ \endcode
+*/
+
+bool QTime::isValid( int h, int m, int s, int ms )
+{
+ return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
+}
+
+
+/*!
+ Sets this time to the current time. This is practical for timing:
+
+ \code
+ QTime t;
+ t.start(); // start clock
+ ... // some lengthy task
+ qDebug( "%d\n", t.elapsed() ); // prints # msecs elapsed
+ \endcode
+
+ \sa restart(), elapsed(), currentTime()
+*/
+
+void QTime::start()
+{
+ *this = currentTime();
+}
+
+/*!
+ Sets this time to the current time, and returns the number of
+ milliseconds that have elapsed since the last time start() or
+ restart() was called.
+
+ This function is guaranteed to be atomic, and is thus very handy for
+ repeated measurements: call start() to start the first measurement,
+ then restart() for each later measurement.
+
+ Note that the counter wraps to zero 24 hours after the last call to
+ start() or restart().
+
+ \warning If the system's clock setting has been changed since the
+ last time start() or restart() was called, the result is undefined.
+ This can happen e.g. when daylight saving is turned on or off.
+
+ \sa start(), elapsed(), currentTime()
+*/
+
+int QTime::restart()
+{
+ QTime t = currentTime();
+ int n = msecsTo( t );
+ if ( n < 0 ) // passed midnight
+ n += 86400*1000;
+ *this = t;
+ return n;
+}
+
+/*!
+ Returns the number of milliseconds that have elapsed since the last
+ time start() or restart() was called.
+
+ Note that the counter wraps to zero 24 hours after the last call to
+ start() or restart.
+
+ Note that the accuracy depends on the accuracy of the underlying
+ operating system; not all systems provide 1-millisecond accuracy.
+
+ \warning If the system's clock setting has been changed since the
+ last time start() or restart() was called, the result is undefined.
+ This can happen e.g. when daylight saving is turned on or off.
+
+ \sa start(), restart()
+*/
+
+int QTime::elapsed()
+{
+ int n = msecsTo( currentTime() );
+ if ( n < 0 ) // passed midnight
+ n += 86400*1000;
+ return n;
+}
+
+
+/*****************************************************************************
+ QDateTime member functions
+ *****************************************************************************/
+
+/*!
+ \class QDateTime qdatetime.h
+ \brief The QDateTime class provides date and time functions.
+
+ \ingroup time
+
+ A QDateTime object contains a calendar date and a clock time (a
+ "datetime"). It is a combination of the QDate and QTime classes. It
+ can read the current datetime from the system clock. It provides
+ functions for comparing datetimes and for manipulating a datetime by
+ adding a number of seconds or days.
+
+ A QDateTime object is typically created either by giving a date and
+ time explicitly, or by using the static function currentTime(),
+ which makes a QDateTime object which contains the system's clock
+ time.
+
+ The date() and time() functions provide access to the date and time
+ parts of the datetime. The same information is provided in textual
+ format by the toString() function.
+
+ QDateTime provides a full set of operators to compare two QDateTime
+ objects. A datetime is considered smaller than another if it is
+ earlier than the other.
+
+ The datetime a given number of days or seconds later than a given
+ datetime can be found using the addDays() and addSecs()
+ functions. Correspondingly, the number of days or seconds between
+ two times can be found using the daysTo() or secsTo() functions.
+
+ A datetime can also be set using the setTime_t() function, which
+ takes a POSIX-standard "number of seconds since 00:00:00 on January
+ 1, 1970" value.
+
+ The limitations regarding range and resolution mentioned in the
+ QDate and QTime documentation apply for QDateTime also.
+
+ \sa QDate, QTime
+*/
+
+
+/*!
+ \fn QDateTime::QDateTime()
+
+ Constructs a null datetime (i.e. null date and null time). A null
+ datetime is invalid, since the date is invalid.
+
+ \sa isValid()
+*/
+
+
+/*!
+ Constructs a datetime with date \a date and null time (00:00:00.000).
+*/
+
+QDateTime::QDateTime( const QDate &date )
+ : d(date)
+{
+}
+
+/*!
+ Constructs a datetime with date \a date and time \a time.
+*/
+
+QDateTime::QDateTime( const QDate &date, const QTime &time )
+ : d(date), t(time)
+{
+}
+
+
+/*!
+ \fn bool QDateTime::isNull() const
+
+ Returns TRUE if both the date and the time are null. A null date is invalid.
+
+ \sa QDate::isNull(), QTime::isNull()
+*/
+
+/*!
+ \fn bool QDateTime::isValid() const
+
+ Returns TRUE if both the date and the time are valid.
+
+ \sa QDate::isValid(), QTime::isValid()
+*/
+
+/*!
+ \fn QDate QDateTime::date() const
+
+ Returns the date part of this datetime.
+
+ \sa setDate(), time()
+*/
+
+/*!
+ \fn QTime QDateTime::time() const
+
+ Returns the time part of this datetime.
+
+ \sa setTime(), date()
+*/
+
+/*!
+ \fn void QDateTime::setDate( const QDate &date )
+
+ Sets the date part of this datetime.
+
+ \sa date(), setTime()
+*/
+
+/*!
+ \fn void QDateTime::setTime( const QTime &time )
+
+ Sets the time part of this datetime.
+
+ \sa time(), setDate()
+*/
+
+
+/*!
+ Sets the local date and time given the number of seconds that have passed
+ since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).
+ On systems that do not support timezones this function will behave as if
+ local time were UTC.
+
+ Note that Microsoft Windows supports only a limited range of values for
+ \a secsSince1Jan1970UTC.
+*/
+
+void QDateTime::setTime_t( uint secsSince1Jan1970UTC )
+{
+ time_t tmp = (time_t) secsSince1Jan1970UTC;
+ tm *tM = localtime( &tmp );
+ if ( !tM ) {
+ tM = gmtime( &tmp );
+ if ( !tM ) {
+ d.jd = QDate::greg2jul( 1970, 1, 1 );
+ t.ds = 0;
+ return;
+ }
+ }
+ d.jd = QDate::greg2jul( tM->tm_year + 1900, tM->tm_mon + 1, tM->tm_mday );
+ t.ds = MSECS_PER_HOUR*tM->tm_hour + MSECS_PER_MIN*tM->tm_min +
+ 1000*tM->tm_sec;
+}
+
+
+/*!
+ Returns the datetime as a string.
+
+ The string format is "Sat May 20 03:40:13 1998".
+
+ This function uses QDate::dayName(), QDate::monthName(), and
+ QTime::toString() to generate the string.
+
+*/
+
+QString QDateTime::toString() const
+{
+ QString buf = d.dayName(d.dayOfWeek());
+ buf += ' ';
+ buf += d.monthName(d.month());
+ buf += ' ';
+ buf += QString().setNum(d.day());
+ buf += ' ';
+ buf += t.toString();
+ buf += ' ';
+ buf += QString().setNum(d.year());
+ return buf;
+}
+
+/*!
+ Returns a QDateTime object containing a datetime \a ndays days later
+ than the datetime of this object (or earlier if \a ndays is
+ negative).
+
+ \sa daysTo(), addSecs()
+*/
+
+QDateTime QDateTime::addDays( int ndays ) const
+{
+ return QDateTime( d.addDays(ndays), t );
+}
+
+/*!
+ Returns a QDateTime object containing a datetime \a nsecs seconds
+ later than the datetime of this object (or earlier if \a nsecs is
+ negative).
+
+ \sa secsTo(), addDays()
+*/
+
+QDateTime QDateTime::addSecs( int nsecs ) const
+{
+ uint dd = d.jd;
+ int tt = t.ds;
+ int sign = 1;
+ if ( nsecs < 0 ) {
+ nsecs = -nsecs;
+ sign = -1;
+ }
+ if ( nsecs >= (int)SECS_PER_DAY ) {
+ dd += sign*(nsecs/SECS_PER_DAY);
+ nsecs %= SECS_PER_DAY;
+ }
+ tt += sign*nsecs*1000;
+ if ( tt < 0 ) {
+ tt = MSECS_PER_DAY - tt - 1;
+ dd -= tt / MSECS_PER_DAY;
+ tt = tt % MSECS_PER_DAY;
+ tt = MSECS_PER_DAY - tt - 1;
+ } else if ( tt >= (int)MSECS_PER_DAY ) {
+ dd += ( tt / MSECS_PER_DAY );
+ tt = tt % MSECS_PER_DAY;
+ }
+ QDateTime ret;
+ ret.t.ds = tt;
+ ret.d.jd = dd;
+ return ret;
+}
+
+/*!
+ Returns the number of days from this datetime to \a dt (which is
+ negative if \a dt is earlier than this datetime).
+
+ \sa addDays(), secsTo()
+*/
+
+int QDateTime::daysTo( const QDateTime &dt ) const
+{
+ return d.daysTo( dt.d );
+}
+
+/*!
+ Returns the number of seconds from this datetime to \a dt (which is
+ negative if \a dt is earlier than this datetime).
+
+ Example:
+ \code
+ QDateTime dt = QDateTime::currentDateTime();
+ QDateTime x( QDate(dt.year(),12,24), QTime(17,00) );
+ qDebug( "There are %d seconds to Christmas", dt.secsTo(x) );
+ \endcode
+
+ \sa addSecs(), daysTo(), QTime::secsTo()
+*/
+
+int QDateTime::secsTo( const QDateTime &dt ) const
+{
+ return t.secsTo(dt.t) + d.daysTo(dt.d)*SECS_PER_DAY;
+}
+
+
+/*!
+ Returns TRUE if this datetime is equal to \a dt, or FALSE if
+ they are different.
+ \sa operator!=()
+*/
+
+bool QDateTime::operator==( const QDateTime &dt ) const
+{
+ return t == dt.t && d == dt.d;
+}
+
+/*!
+ Returns TRUE if this datetime is different from \a dt, or FALSE if
+ they are equal.
+ \sa operator==()
+*/
+
+bool QDateTime::operator!=( const QDateTime &dt ) const
+{
+ return t != dt.t || d != dt.d;
+}
+
+/*!
+ Returns TRUE if this datetime is earlier than \a dt, otherwise FALSE.
+*/
+
+bool QDateTime::operator<( const QDateTime &dt ) const
+{
+ if ( d < dt.d )
+ return TRUE;
+ return d == dt.d ? t < dt.t : FALSE;
+}
+
+/*!
+ Returns TRUE if this datetime is earlier than or equal to \a dt,
+ otherwise FALSE.
+*/
+
+bool QDateTime::operator<=( const QDateTime &dt ) const
+{
+ if ( d < dt.d )
+ return TRUE;
+ return d == dt.d ? t <= dt.t : FALSE;
+}
+
+/*!
+ Returns TRUE if this datetime is later than \a dt, otherwise FALSE.
+*/
+
+bool QDateTime::operator>( const QDateTime &dt ) const
+{
+ if ( d > dt.d )
+ return TRUE;
+ return d == dt.d ? t > dt.t : FALSE;
+}
+
+/*!
+ Returns TRUE if this datetime is later than or equal to \a dt,
+ otherwise FALSE.
+*/
+
+bool QDateTime::operator>=( const QDateTime &dt ) const
+{
+ if ( d > dt.d )
+ return TRUE;
+ return d == dt.d ? t >= dt.t : FALSE;
+}
+
+/*!
+ Returns the current datetime, as reported by the system clock.
+
+ \sa QDate::currentDate(), QTime::currentTime()
+*/
+
+QDateTime QDateTime::currentDateTime()
+{
+ QDate cd = QDate::currentDate();
+ QTime ct;
+ if ( QTime::currentTime(&ct) ) // too close to midnight?
+ cd = QDate::currentDate(); // YES! time for some midnight
+ // voodoo, fetch date again
+ return QDateTime( cd, ct );
+}
+
+
+/*****************************************************************************
+ Date/time stream functions
+ *****************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \relates QDate
+ Writes the date to the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator<<( QDataStream &s, const QDate &d )
+{
+ return s << (Q_UINT32)(d.jd);
+}
+
+/*!
+ \relates QDate
+ Reads a date from the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>( QDataStream &s, QDate &d )
+{
+ Q_UINT32 jd;
+ s >> jd;
+ d.jd = jd;
+ return s;
+}
+
+/*!
+ \relates QTime
+ Writes a time to the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator<<( QDataStream &s, const QTime &t )
+{
+ return s << (Q_UINT32)(t.ds);
+}
+
+/*!
+ \relates QTime
+ Reads a time from the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>( QDataStream &s, QTime &t )
+{
+ Q_UINT32 ds;
+ s >> ds;
+ t.ds = ds;
+ return s;
+}
+
+/*!
+ \relates QDateTime
+ Writes a datetime to the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator<<( QDataStream &s, const QDateTime &dt )
+{
+ return s << dt.d << dt.t;
+}
+
+/*!
+ \relates QDateTime
+ Reads a datetime from the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>( QDataStream &s, QDateTime &dt )
+{
+ s >> dt.d >> dt.t;
+ return s;
+}
+#endif //QT_NO_DATASTREAM
diff --git a/qtools/qdatetime.h b/qtools/qdatetime.h
new file mode 100644
index 0000000..2479dbf
--- /dev/null
+++ b/qtools/qdatetime.h
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+**
+** Definition of date and time classes
+**
+** Created : 940124
+**
+** Copyright (C) 1992-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 QDATETIME_H
+#define QDATETIME_H
+
+#ifndef QT_H
+#include "qstring.h"
+#endif // QT_H
+
+
+/*****************************************************************************
+ QDate class
+ *****************************************************************************/
+
+class Q_EXPORT QDate
+{
+public:
+ QDate() { jd=0; } // set null date
+ QDate( int y, int m, int d ); // set date
+
+ bool isNull() const { return jd == 0; }
+ bool isValid() const; // valid date
+
+ int year() const; // 1752..
+ int month() const; // 1..12
+ int day() const; // 1..31
+ int dayOfWeek() const; // 1..7 (monday==1)
+ int dayOfYear() const; // 1..365
+ int daysInMonth() const; // 28..31
+ int daysInYear() const; // 365 or 366
+
+ virtual QString monthName( int month ) const;
+ virtual QString dayName( int weekday ) const;
+
+ QString toString() const;
+
+ bool setYMD( int y, int m, int d );
+
+ QDate addDays( int days ) const;
+ int daysTo( const QDate & ) const;
+
+ bool operator==( const QDate &d ) const { return jd == d.jd; }
+ bool operator!=( const QDate &d ) const { return jd != d.jd; }
+ bool operator<( const QDate &d ) const { return jd < d.jd; }
+ bool operator<=( const QDate &d ) const { return jd <= d.jd; }
+ bool operator>( const QDate &d ) const { return jd > d.jd; }
+ bool operator>=( const QDate &d ) const { return jd >= d.jd; }
+
+ static QDate currentDate();
+ static bool isValid( int y, int m, int d );
+ static bool leapYear( int year );
+
+protected:
+ static uint greg2jul( int y, int m, int d );
+ static void jul2greg( uint jd, int &y, int &m, int &d );
+private:
+ static const char * const monthNames[];
+ static const char * const weekdayNames[];
+ uint jd;
+ friend class QDateTime;
+#ifndef QT_NO_DATASTREAM
+ friend Q_EXPORT QDataStream &operator<<( QDataStream &, const QDate & );
+ friend Q_EXPORT QDataStream &operator>>( QDataStream &, QDate & );
+#endif
+};
+
+
+/*****************************************************************************
+ QTime class
+ *****************************************************************************/
+
+class Q_EXPORT QTime
+{
+public:
+ QTime() { ds=0; } // set null time
+ QTime( int h, int m, int s=0, int ms=0 ); // set time
+
+ bool isNull() const { return ds == 0; }
+ bool isValid() const; // valid time
+
+ int hour() const; // 0..23
+ int minute() const; // 0..59
+ int second() const; // 0..59
+ int msec() const; // 0..999
+
+ QString toString() const;
+
+ bool setHMS( int h, int m, int s, int ms=0 );
+
+ QTime addSecs( int secs ) const;
+ int secsTo( const QTime & ) const;
+ QTime addMSecs( int ms ) const;
+ int msecsTo( const QTime & ) const;
+
+ bool operator==( const QTime &d ) const { return ds == d.ds; }
+ bool operator!=( const QTime &d ) const { return ds != d.ds; }
+ bool operator<( const QTime &d ) const { return ds < d.ds; }
+ bool operator<=( const QTime &d ) const { return ds <= d.ds; }
+ bool operator>( const QTime &d ) const { return ds > d.ds; }
+ bool operator>=( const QTime &d ) const { return ds >= d.ds; }
+
+ static QTime currentTime();
+ static bool isValid( int h, int m, int s, int ms=0 );
+
+ void start();
+ int restart();
+ int elapsed();
+
+private:
+ static bool currentTime( QTime * );
+
+ uint ds;
+ friend class QDateTime;
+#ifndef QT_NO_DATASTREAM
+ friend Q_EXPORT QDataStream &operator<<( QDataStream &, const QTime & );
+ friend Q_EXPORT QDataStream &operator>>( QDataStream &, QTime & );
+#endif
+};
+
+
+/*****************************************************************************
+ QDateTime class
+ *****************************************************************************/
+
+class Q_EXPORT QDateTime
+{
+public:
+ QDateTime() {} // set null date and null time
+ QDateTime( const QDate & );
+ QDateTime( const QDate &, const QTime & );
+
+ bool isNull() const { return d.isNull() && t.isNull(); }
+ bool isValid() const { return d.isValid() && t.isValid(); }
+
+ QDate date() const { return d; }
+ QTime time() const { return t; }
+ void setDate( const QDate &date ) { d=date; }
+ void setTime( const QTime &time ) { t=time; }
+ void setTime_t( uint secsSince1Jan1970UTC );
+
+ QString toString() const;
+
+ QDateTime addDays( int days ) const;
+ QDateTime addSecs( int secs ) const;
+ int daysTo( const QDateTime & ) const;
+ int secsTo( const QDateTime & ) const;
+
+ bool operator==( const QDateTime &dt ) const;
+ bool operator!=( const QDateTime &dt ) const;
+ bool operator<( const QDateTime &dt ) const;
+ bool operator<=( const QDateTime &dt ) const;
+ bool operator>( const QDateTime &dt ) const;
+ bool operator>=( const QDateTime &dt ) const;
+
+ static QDateTime currentDateTime();
+
+private:
+ QDate d;
+ QTime t;
+#ifndef QT_NO_DATASTREAM
+ friend Q_EXPORT QDataStream &operator<<( QDataStream &, const QDateTime &);
+ friend Q_EXPORT QDataStream &operator>>( QDataStream &, QDateTime & );
+#endif
+};
+
+
+/*****************************************************************************
+ Date and time stream functions
+ *****************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QDate & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, QDate & );
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QTime & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, QTime & );
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QDateTime & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, QDateTime & );
+#endif // QT_NO_DATASTREAM
+
+#endif // QDATETIME_H
diff --git a/qtools/qdict.h b/qtools/qdict.h
new file mode 100644
index 0000000..3b70336
--- /dev/null
+++ b/qtools/qdict.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+**
+** Definition of QDict template class
+**
+** Created : 920821
+**
+** Copyright (C) 1992-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 QDICT_H
+#define QDICT_H
+
+#ifndef QT_H
+#include "qgdict.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QDict : public QGDict
+{
+public:
+ QDict(int size=17, bool caseSensitive=TRUE)
+ : QGDict(size,StringKey,caseSensitive,FALSE) {}
+ QDict( const QDict<type> &d ) : QGDict(d) {}
+ ~QDict() { clear(); }
+ QDict<type> &operator=(const QDict<type> &d)
+ { return (QDict<type>&)QGDict::operator=(d); }
+ uint count() const { return QGDict::count(); }
+ uint size() const { return QGDict::size(); }
+ bool isEmpty() const { return QGDict::count() == 0; }
+
+ void insert( const QString &k, const type *d )
+ { QGDict::look_string(k,(Item)d,1); }
+ void replace( const QString &k, const type *d )
+ { QGDict::look_string(k,(Item)d,2); }
+ bool remove( const QString &k ) { return QGDict::remove_string(k); }
+ type *take( const QString &k ) { return (type *)QGDict::take_string(k); }
+ type *find( const QString &k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_string(k,0,0); }
+ type *operator[]( const QString &k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_string(k,0,0); }
+
+ void clear() { QGDict::clear(); }
+ void resize( uint n ) { QGDict::resize(n); }
+ void statistics() const { QGDict::statistics(); }
+private:
+ void deleteItem( Item d );
+};
+
+#if defined(Q_DELETING_VOID_UNDEFINED)
+template<> inline void QDict<void>::deleteItem( Item )
+{
+}
+#endif
+
+template<class type> inline void QDict<type>::deleteItem( QCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+
+template<class type> class Q_EXPORT QDictIterator : public QGDictIterator
+{
+public:
+ QDictIterator(const QDict<type> &d) :QGDictIterator((QGDict &)d) {}
+ ~QDictIterator() {}
+ uint count() const { return dict->count(); }
+ bool isEmpty() const { return dict->count() == 0; }
+ type *toFirst() { return (type *)QGDictIterator::toFirst(); }
+ operator type *() const { return (type *)QGDictIterator::get(); }
+ type *current() const { return (type *)QGDictIterator::get(); }
+ QString currentKey() const{ return QGDictIterator::getKeyString(); }
+ type *operator()() { return (type *)QGDictIterator::operator()(); }
+ type *operator++() { return (type *)QGDictIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j);}
+};
+
+
+#endif // QDICT_H
diff --git a/qtools/qdir.cpp b/qtools/qdir.cpp
new file mode 100644
index 0000000..c4b4987
--- /dev/null
+++ b/qtools/qdir.cpp
@@ -0,0 +1,1207 @@
+/****************************************************************************
+**
+**
+** Implementation of QDir class
+**
+** Created : 950427
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qglobal.h"
+
+#include "qdir.h"
+
+#ifndef QT_NO_DIR
+#include "qfileinfo.h"
+#include "qfiledefs_p.h"
+#include "qregexp.h"
+#include "qstringlist.h"
+#include <stdlib.h>
+#include <ctype.h>
+
+// NOT REVISED
+/*!
+ \class QDir qdir.h
+ \brief Traverses directory structures and contents in a
+ platform-independent way.
+
+ \ingroup io
+
+ A QDir can point to a file using either a relative or an absolute file
+ path. Absolute file paths begin with the directory separator ('/') or a
+ drive specification (not applicable to UNIX). Relative file names begin
+ with a directory name or a file name and specify a path relative to the
+ current directory.
+
+ An example of an absolute path is the string "/tmp/quartz", a relative
+ path might look like "src/fatlib". You can use the function isRelative()
+ to check if a QDir is using a relative or an absolute file path. You can
+ call the function convertToAbs() to convert a relative QDir to an
+ absolute one.
+
+ The directory "example" under the current directory is checked for existence
+ in the example below:
+
+ \code
+ QDir d( "example" ); // "./example"
+ if ( !d.exists() )
+ qWarning( "Cannot find the example directory" );
+ \endcode
+
+ If you always use '/' as a directory separator, Qt will translate your
+ paths to conform to the underlying operating system.
+
+ cd() and cdUp() can be used to navigate the directory tree. Note that the
+ logical cd and cdUp operations are not performed if the new directory does
+ not exist.
+
+ Example:
+ \code
+ QDir d = QDir::root(); // "/"
+ if ( !d.cd("tmp") ) { // "/tmp"
+ qWarning( "Cannot find the \"/tmp\" directory" );
+ } else {
+ QFile f( d.filePath("ex1.txt") ); // "/tmp/ex1.txt"
+ if ( !f.open(IO_ReadWrite) )
+ qWarning( "Cannot create the file %s", f.name() );
+ }
+ \endcode
+
+ To read the contents of a directory you can use the entryList() and
+ entryInfoList() functions.
+
+ Example:
+ \code
+ #include <stdio.h>
+ #include <qdir.h>
+
+ //
+ // This program scans the current directory and lists all files
+ // that are not symbolic links, sorted by size with the smallest files
+ // first.
+ //
+
+ int main( int argc, char **argv )
+ {
+ QDir d;
+ d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
+ d.setSorting( QDir::Size | QDir::Reversed );
+
+ const QFileInfoList *list = d.entryInfoList();
+ QFileInfoListIterator it( *list ); // create list iterator
+ QFileInfo *fi; // pointer for traversing
+
+ printf( " BYTES FILENAME\n" ); // print header
+ while ( (fi=it.current()) ) { // for each file...
+ printf( "%10li %s\n", fi->size(), fi->fileName().data() );
+ ++it; // goto next list element
+ }
+ }
+ \endcode
+*/
+
+
+/*!
+ Constructs a QDir pointing to the current directory.
+ \sa currentDirPath()
+*/
+
+QDir::QDir()
+{
+ dPath = QString::fromLatin1(".");
+ init();
+}
+
+/*!
+ Constructs a QDir.
+
+ \arg \e path is the directory.
+ \arg \e nameFilter is the file name filter.
+ \arg \e sortSpec is the sort specification, which describes how to
+ sort the files in the directory.
+ \arg \e filterSpec is the filter specification, which describes how
+ to filter the files in the directory.
+
+ Most of these arguments (except \e path) have optional values.
+
+ Example:
+ \code
+ // lists all files in /tmp
+
+ QDir d( "/tmp" );
+ for ( int i=0; i<d.count(); i++ )
+ printf( "%s\n", d[i] );
+ \endcode
+
+ If \e path is "" or null, the directory is set to "." (the current
+ directory). If \e nameFilter is "" or null, it is set to "*" (all
+ files).
+
+ No check is made to ensure that the directory exists.
+
+ \sa exists(), setPath(), setNameFilter(), setFilter(), setSorting()
+*/
+
+QDir::QDir( const QString &path, const QString &nameFilter,
+ int sortSpec, int filterSpec )
+{
+ init();
+ dPath = cleanDirPath( path );
+ if ( dPath.isEmpty() )
+ dPath = QString::fromLatin1(".");
+ nameFilt = nameFilter;
+ if ( nameFilt.isEmpty() )
+ nameFilt = QString::fromLatin1("*");
+ filtS = (FilterSpec)filterSpec;
+ sortS = (SortSpec)sortSpec;
+}
+
+/*!
+ Constructs a QDir that is a copy of the given directory.
+ \sa operator=()
+*/
+
+QDir::QDir( const QDir &d )
+{
+ dPath = d.dPath;
+ fList = 0;
+ fiList = 0;
+ nameFilt = d.nameFilt;
+ dirty = TRUE;
+ allDirs = d.allDirs;
+ filtS = d.filtS;
+ sortS = d.sortS;
+}
+
+
+void QDir::init()
+{
+ fList = 0;
+ fiList = 0;
+ nameFilt = QString::fromLatin1("*");
+ dirty = TRUE;
+ allDirs = FALSE;
+ filtS = All;
+ sortS = SortSpec(Name | IgnoreCase);
+}
+
+/*!
+ Destructs the QDir and cleans up.
+*/
+
+QDir::~QDir()
+{
+ if ( fList )
+ delete fList;
+ if ( fiList )
+ delete fiList;
+}
+
+
+/*!
+ Sets the path of the directory. The path is cleaned of redundant ".", ".."
+ and multiple separators. No check is made to ensure that a directory
+ with this path exists.
+
+ The path can be either absolute or relative. Absolute paths begin with the
+ directory separator ('/') or a drive specification (not
+ applicable to UNIX).
+ Relative file names begin with a directory name or a file name and specify
+ a path relative to the current directory. An example of
+ an absolute path is the string "/tmp/quartz", a relative path might look like
+ "src/fatlib". You can use the function isRelative() to check if a QDir
+ is using a relative or an absolute file path. You can call the function
+ convertToAbs() to convert a relative QDir to an absolute one.
+
+ \sa path(), absPath(), exists, cleanDirPath(), dirName(),
+ absFilePath(), isRelative(), convertToAbs()
+*/
+
+void QDir::setPath( const QString &path )
+{
+ dPath = cleanDirPath( path );
+ if ( dPath.isEmpty() )
+ dPath = QString::fromLatin1(".");
+ dirty = TRUE;
+}
+
+/*!
+ \fn QString QDir::path() const
+ Returns the path, this may contain symbolic links, but never contains
+ redundant ".", ".." or multiple separators.
+
+ The returned path can be either absolute or relative (see setPath()).
+
+ \sa setPath(), absPath(), exists(), cleanDirPath(), dirName(),
+ absFilePath(), convertSeparators()
+*/
+
+/*!
+ Returns the absolute (a path that starts with '/') path, which may
+ contain symbolic links, but never contains redundant ".", ".." or
+ multiple separators.
+
+ \sa setPath(), canonicalPath(), exists(), cleanDirPath(), dirName(),
+ absFilePath()
+*/
+
+QString QDir::absPath() const
+{
+ if ( QDir::isRelativePath(dPath) ) {
+ QString tmp = currentDirPath();
+ if ( tmp.right(1) != QString::fromLatin1("/") )
+ tmp += '/';
+ tmp += dPath;
+ return cleanDirPath( tmp );
+ } else {
+ return cleanDirPath( dPath );
+ }
+}
+
+/*!
+ Returns the name of the directory, this is NOT the same as the path, e.g.
+ a directory with the name "mail", might have the path "/var/spool/mail".
+ If the directory has no name (e.g. the root directory) a null string is
+ returned.
+
+ No check is made to ensure that a directory with this name actually exists.
+
+ \sa path(), absPath(), absFilePath(), exists(), QString::isNull()
+*/
+
+QString QDir::dirName() const
+{
+ int pos = dPath.findRev( '/' );
+ if ( pos == -1 )
+ return dPath;
+ return dPath.right( dPath.length() - pos - 1 );
+}
+
+/*!
+ Returns the path name of a file in the directory. Does NOT check if
+ the file actually exists in the directory. If the QDir is relative
+ the returned path name will also be relative. Redundant multiple separators
+ or "." and ".." directories in \e fileName will not be removed (see
+ cleanDirPath()).
+
+ If \e acceptAbsPath is TRUE a \e fileName starting with a separator
+ ('/') will be returned without change.
+ If \e acceptAbsPath is FALSE an absolute path will be appended to
+ the directory path.
+
+ \sa absFilePath(), isRelative(), canonicalPath()
+*/
+
+QString QDir::filePath( const QString &fileName,
+ bool acceptAbsPath ) const
+{
+ if ( acceptAbsPath && !isRelativePath(fileName) )
+ return QString(fileName);
+
+ QString tmp = dPath;
+ if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
+ fileName[0] != '/') )
+ tmp += '/';
+ tmp += fileName;
+ return tmp;
+}
+
+/*!
+ Returns the absolute path name of a file in the directory. Does NOT check if
+ the file actually exists in the directory. Redundant multiple separators
+ or "." and ".." directories in \e fileName will NOT be removed (see
+ cleanDirPath()).
+
+ If \e acceptAbsPath is TRUE a \e fileName starting with a separator
+ ('/') will be returned without change.
+ if \e acceptAbsPath is FALSE an absolute path will be appended to
+ the directory path.
+
+ \sa filePath()
+*/
+
+QString QDir::absFilePath( const QString &fileName,
+ bool acceptAbsPath ) const
+{
+ if ( acceptAbsPath && !isRelativePath( fileName ) )
+ return fileName;
+
+ QString tmp = absPath();
+ if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
+ fileName[0] != '/') )
+ tmp += '/';
+ tmp += fileName;
+ return tmp;
+}
+
+
+/*!
+ Converts the '/' separators in \a pathName to system native
+ separators. Returns the translated string.
+
+ On Windows, convertSeparators("c:/winnt/system32") returns
+ "c:\winnt\system32".
+
+ No conversion is done on UNIX.
+*/
+
+QString QDir::convertSeparators( const QString &pathName )
+{
+ QString n( pathName );
+#if defined(_OS_FATFS_) || defined(_OS_OS2EMX_)
+ for ( int i=0; i<(int)n.length(); i++ ) {
+ if ( n[i] == '/' )
+ n[i] = '\\';
+ }
+#endif
+ return n;
+}
+
+
+/*!
+ Changes directory by descending into the given directory. Returns
+ TRUE if the new directory exists and is readable. Note that the logical
+ cd operation is NOT performed if the new directory does not exist.
+
+ If \e acceptAbsPath is TRUE a path starting with a separator ('/')
+ will cd to the absolute directory, if \e acceptAbsPath is FALSE
+ any number of separators at the beginning of \e dirName will be removed.
+
+ Example:
+ \code
+ QDir d = QDir::home(); // now points to home directory
+ if ( !d.cd("c++") ) { // now points to "c++" under home directory if OK
+ QFileInfo fi( d, "c++" );
+ if ( fi.exists() ) {
+ if ( fi.isDir() )
+ qWarning( "Cannot cd into \"%s\".", (char*)d.absFilePath("c++") );
+ else
+ qWarning( "Cannot create directory \"%s\"\n"
+ "A file named \"c++\" already exists in \"%s\"",
+ (const char *)d.absFilePath("c++"),
+ (const char *)d.path() );
+ return;
+ } else {
+ qWarning( "Creating directory \"%s\"",
+ (const char *) d.absFilePath("c++") );
+ if ( !d.mkdir( "c++" ) ) {
+ qWarning("Could not create directory \"%s\"",
+ (const char *)d.absFilePath("c++") );
+ return;
+ }
+ }
+ }
+ \endcode
+
+ Calling cd( ".." ) is equivalent to calling cdUp().
+
+ \sa cdUp(), isReadable(), exists(), path()
+*/
+
+bool QDir::cd( const QString &dirName, bool acceptAbsPath )
+{
+ if ( dirName.isEmpty() || dirName==QString::fromLatin1(".") )
+ return TRUE;
+ QString old = dPath;
+ if ( acceptAbsPath && !isRelativePath(dirName) ) {
+ dPath = cleanDirPath( dirName );
+ } else {
+ if ( !isRoot() )
+ dPath += '/';
+ dPath += dirName;
+ if ( dirName.find('/') >= 0
+ || old == QString::fromLatin1(".")
+ || dirName == QString::fromLatin1("..") )
+ dPath = cleanDirPath( dPath );
+ }
+ if ( !exists() ) {
+ dPath = old; // regret
+ return FALSE;
+ }
+ dirty = TRUE;
+ return TRUE;
+}
+
+/*!
+ Changes directory by moving one directory up the path followed to arrive
+ at the current directory.
+
+ Returns TRUE if the new directory exists and is readable. Note that the
+ logical cdUp() operation is not performed if the new directory does not
+ exist.
+
+ \sa cd(), isReadable(), exists(), path()
+*/
+
+bool QDir::cdUp()
+{
+ return cd( QString::fromLatin1("..") );
+}
+
+/*!
+ \fn QString QDir::nameFilter() const
+ Returns the string set by setNameFilter()
+ \sa setNameFilter()
+*/
+
+/*!
+ Sets the name filter used by entryList() and entryInfoList().
+
+ The name filter is a wildcarding filter that understands "*" and "?"
+ wildcards, You may specify several filter entries separated by a " " or a ";". If
+ you want entryList() and entryInfoList() to list all files ending with
+ ".cpp" and all files ending with ".h", you simply call
+ dir.setNameFilter("*.cpp *.h") or dir.setNameFilter("*.cpp;*.h")
+
+ \sa nameFilter()
+*/
+
+void QDir::setNameFilter( const QString &nameFilter )
+{
+ nameFilt = nameFilter;
+ if ( nameFilt.isEmpty() )
+ nameFilt = QString::fromLatin1("*");
+ dirty = TRUE;
+}
+
+/*!
+ \fn QDir::FilterSpec QDir::filter() const
+ Returns the value set by setFilter()
+ \sa setFilter()
+*/
+
+/*! \enum QDir::FilterSpec
+
+ This enum describes how QDir is to select what entries in a
+ directory to return. The filter value is specified by or-ing
+ together values from the following list: <ul>
+
+ <li> \c Dirs - List directories only
+ <li> \c Files - List files only
+
+ <li> \c Drives - List disk drives (does nothing under unix)
+ <li> \c NoSymLinks - Do not list symbolic links (where they exist)
+ <li> \c Readable - List files for which the application has read access.
+ <li> \c Writable - List files for which the application has write access.
+ <li> \c Executable - List files for which the application has execute access
+ <li> \c Modified - Only list files that have been modified (does nothing
+ under unix)
+ <li> \c Hidden - List hidden files (on unix, files starting with a .)
+ <li> \c System - List system files (does nothing under unix)
+ </ul>
+
+ If you do not set any of \c Readable, \c Writable or \c Executable,
+ QDir will set all three of them. This makes the default easy to
+ write and at the same time useful.
+
+ Examples: \c Readable|Writable means list all files for which the
+ application has read access, write access or both. \c Dirs|Drives
+ means list drives, directories, all files that the application can
+ read, write or execute, and also symlinks to such files/directories.
+*/
+
+
+/*!
+ Sets the filter used by entryList() and entryInfoList(). The filter is used
+ to specify the kind of files that should be returned by entryList() and
+ entryInfoList().
+ \sa nameFilter()
+*/
+
+void QDir::setFilter( int filterSpec )
+{
+ if ( filtS == (FilterSpec) filterSpec )
+ return;
+ filtS = (FilterSpec) filterSpec;
+ dirty = TRUE;
+}
+
+/*!
+ \fn QDir::SortSpec QDir::sorting() const
+
+ Returns the value set by setSorting()
+
+ \sa setSorting()
+*/
+
+/*! \enum QDir::SortSpec
+
+ This enum describes how QDir is to sort entries in a directory when
+ it returns a list of them. The sort value is specified by or-ing
+ together values from the following list: <ul>
+
+ <li> \c Name - sort by name
+ <li> \c Time - sort by time (modification time)
+ <li> \c Size - sort by file size
+ <li> \c Unsorted - do not sort
+
+ <li> \c DirsFirst - put all directories first in the list
+ <li> \c Reversed - reverse the sort order
+ <li> \c IgnoreCase - sort case-insensitively
+
+ </ul>
+
+ You can only specify one of the first four. If you specify both \c
+ DirsFirst and \c Reversed, directories are still put first but the
+ list is otherwise reversed.
+*/
+
+// ### Unsorted+DirsFirst ? Unsorted+Reversed?
+
+/*!
+ Sets the sorting order used by entryList() and entryInfoList().
+
+ The \e sortSpec is specified by or-ing values from the enum
+ SortSpec. The different values are:
+
+ One of these:
+ <dl compact>
+ <dt>Name<dd> Sort by name (alphabetical order).
+ <dt>Time<dd> Sort by time (most recent first).
+ <dt>Size<dd> Sort by size (largest first).
+ <dt>Unsorted<dd> Use the operating system order (UNIX does NOT sort
+ alphabetically).
+
+ ORed with zero or more of these:
+
+ <dt>DirsFirst<dd> Always put directory names first.
+ <dt>Reversed<dd> Reverse sort order.
+ <dt>IgnoreCase<dd> Ignore case when sorting by name.
+ </dl>
+*/
+
+void QDir::setSorting( int sortSpec )
+{
+ if ( sortS == (SortSpec) sortSpec )
+ return;
+ sortS = (SortSpec) sortSpec;
+ dirty = TRUE;
+}
+
+/*!
+ \fn bool QDir::matchAllDirs() const
+ Returns the value set by setMatchAllDirs()
+
+ \sa setMatchAllDirs()
+*/
+
+/*!
+ If \e enable is TRUE, all directories will be listed (even if they do not
+ match the filter or the name filter), otherwise only matched directories
+ will be listed.
+
+ \bug Currently, directories that do not match the filter will not be
+ included (the name filter will be ignored as expected).
+
+ \sa matchAllDirs()
+*/
+
+void QDir::setMatchAllDirs( bool enable )
+{
+ if ( (bool)allDirs == enable )
+ return;
+ allDirs = enable;
+ dirty = TRUE;
+}
+
+
+/*!
+ Returns the number of files that was found.
+ Equivalent to entryList().count().
+ \sa operator[](), entryList()
+*/
+
+uint QDir::count() const
+{
+ return entryList().count();
+}
+
+/*!
+ Returns the file name at position \e index in the list of found file
+ names.
+ Equivalent to entryList().at(index).
+
+ Returns null if the \e index is out of range or if the entryList()
+ function failed.
+
+ \sa count(), entryList()
+*/
+
+QString QDir::operator[]( int index ) const
+{
+ entryList();
+ return fList && index >= 0 && index < (int)fList->count() ?
+ (*fList)[index] : QString::null;
+}
+
+
+/*!
+ This function is included to easy porting from Qt 1.x to Qt 2.0,
+ it is the same as entryList(), but encodes the filenames as 8-bit
+ strings using QFile::encodedName().
+
+ It is more efficient to use entryList().
+*/
+QStrList QDir::encodedEntryList( int filterSpec, int sortSpec ) const
+{
+ QStrList r;
+ QStringList l = entryList(filterSpec,sortSpec);
+ for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
+ r.append( QFile::encodeName(*it) );
+ }
+ return r;
+}
+
+/*!
+ This function is included to easy porting from Qt 1.x to Qt 2.0,
+ it is the same as entryList(), but encodes the filenames as 8-bit
+ strings using QFile::encodedName().
+
+ It is more efficient to use entryList().
+*/
+QStrList QDir::encodedEntryList( const QString &nameFilter,
+ int filterSpec,
+ int sortSpec ) const
+{
+ QStrList r;
+ QStringList l = entryList(nameFilter,filterSpec,sortSpec);
+ for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
+ r.append( QFile::encodeName(*it) );
+ }
+ return r;
+}
+
+
+
+/*!
+ Returns a list of the names of all files and directories in the directory
+ indicated by the setSorting(), setFilter() and setNameFilter()
+ specifications.
+
+ The the filter and sorting specifications can be overridden using the
+ \e filterSpec and \e sortSpec arguments.
+
+ Returns an empty list if the directory is unreadable or does not exist.
+
+ \sa entryInfoList(), setNameFilter(), setSorting(), setFilter(),
+ encodedEntryList()
+*/
+
+QStringList QDir::entryList( int filterSpec, int sortSpec ) const
+{
+ if ( !dirty && filterSpec == (int)DefaultFilter &&
+ sortSpec == (int)DefaultSort )
+ return *fList;
+ return entryList( nameFilt, filterSpec, sortSpec );
+}
+
+/*!
+ Returns a list of the names of all files and directories in the directory
+ indicated by the setSorting(), setFilter() and setNameFilter()
+ specifications.
+
+ The the filter and sorting specifications can be overridden using the
+ \e nameFilter, \e filterSpec and \e sortSpec arguments.
+
+ Returns and empty list if the directory is unreadable or does not exist.
+
+ \sa entryInfoList(), setNameFilter(), setSorting(), setFilter(),
+ encodedEntryList()
+*/
+
+QStringList QDir::entryList( const QString &nameFilter,
+ int filterSpec, int sortSpec ) const
+{
+ if ( filterSpec == (int)DefaultFilter )
+ filterSpec = filtS;
+ if ( sortSpec == (int)DefaultSort )
+ sortSpec = sortS;
+ QDir *that = (QDir*)this; // mutable function
+ if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) )
+ return *that->fList;
+ else
+ return QStringList();
+}
+
+/*!
+ Returns a list of QFileInfo objects for all files and directories in
+ the directory pointed to using the setSorting(), setFilter() and
+ setNameFilter() specifications.
+
+ The the filter and sorting specifications can be overridden using the
+ \e filterSpec and \e sortSpec arguments.
+
+ Returns 0 if the directory is unreadable or does not exist.
+
+ The returned pointer is a const pointer to a QFileInfoList. The list is
+ owned by the QDir object and will be reused on the next call to
+ entryInfoList() for the same QDir instance. If you want to keep the
+ entries of the list after a subsequent call to this function you will
+ need to copy them.
+
+ \sa entryList(), setNameFilter(), setSorting(), setFilter()
+*/
+
+const QFileInfoList *QDir::entryInfoList( int filterSpec, int sortSpec ) const
+{
+ if ( !dirty && filterSpec == (int)DefaultFilter &&
+ sortSpec == (int)DefaultSort )
+ return fiList;
+ return entryInfoList( nameFilt, filterSpec, sortSpec );
+}
+
+/*!
+ Returns a list of QFileInfo objects for all files and directories in
+ the directory pointed to using the setSorting(), setFilter() and
+ setNameFilter() specifications.
+
+ The the filter and sorting specifications can be overridden using the
+ \e nameFilter, \e filterSpec and \e sortSpec arguments.
+
+ Returns 0 if the directory is unreadable or does not exist.
+
+ The returned pointer is a const pointer to a QFileInfoList. The list is
+ owned by the QDir object and will be reused on the next call to
+ entryInfoList() for the same QDir instance. If you want to keep the
+ entries of the list after a subsequent call to this function you will
+ need to copy them.
+
+ \sa entryList(), setNameFilter(), setSorting(), setFilter()
+*/
+
+const QFileInfoList *QDir::entryInfoList( const QString &nameFilter,
+ int filterSpec, int sortSpec ) const
+{
+ if ( filterSpec == (int)DefaultFilter )
+ filterSpec = filtS;
+ if ( sortSpec == (int)DefaultSort )
+ sortSpec = sortS;
+ QDir *that = (QDir*)this; // mutable function
+ if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) )
+ return that->fiList;
+ else
+ return 0;
+}
+
+/*!
+ Returns TRUE if the directory exists. (If a file with the same
+ name is found this function will of course return FALSE).
+
+ \sa QFileInfo::exists(), QFile::exists()
+*/
+
+bool QDir::exists() const
+{
+ QFileInfo fi( dPath );
+ return fi.exists() && fi.isDir();
+}
+
+/*!
+ Returns TRUE if the directory path is relative to the current directory,
+ FALSE if the path is absolute (e.g. under UNIX a path is relative if it
+ does not start with a '/').
+
+ According to Einstein this function should always return TRUE.
+
+ \sa convertToAbs()
+*/
+
+bool QDir::isRelative() const
+{
+ return isRelativePath( dPath );
+}
+
+/*!
+ Converts the directory path to an absolute path. If it is already
+ absolute nothing is done.
+
+ \sa isRelative()
+*/
+
+void QDir::convertToAbs()
+{
+ dPath = absPath();
+}
+
+/*!
+ Makes a copy of d and assigns it to this QDir.
+*/
+
+QDir &QDir::operator=( const QDir &d )
+{
+ dPath = d.dPath;
+ delete fList;
+ fList = 0;
+ delete fiList;
+ fiList = 0;
+ nameFilt = d.nameFilt;
+ dirty = TRUE;
+ allDirs = d.allDirs;
+ filtS = d.filtS;
+ sortS = d.sortS;
+ return *this;
+}
+
+/*!
+ Sets the directory path to be the given path.
+*/
+
+QDir &QDir::operator=( const QString &path )
+{
+ dPath = cleanDirPath( path );
+ dirty = TRUE;
+ return *this;
+}
+
+
+/*!
+ \fn bool QDir::operator!=( const QDir &d ) const
+ Returns TRUE if the \e d and this dir have different path or
+ different sort/filter settings, otherwise FALSE.
+*/
+
+/*!
+ Returns TRUE if the \e d and this dir have the same path and all sort
+ and filter settings are equal, otherwise FALSE.
+*/
+
+bool QDir::operator==( const QDir &d ) const
+{
+ return dPath == d.dPath &&
+ nameFilt == d.nameFilt &&
+ allDirs == d.allDirs &&
+ filtS == d.filtS &&
+ sortS == d.sortS;
+}
+
+
+/*!
+ Removes a file.
+
+ If \e acceptAbsPath is TRUE a path starting with a separator ('/')
+ will remove the file with the absolute path, if \e acceptAbsPath is FALSE
+ any number of separators at the beginning of \e fileName will be removed.
+
+ Returns TRUE if successful, otherwise FALSE.
+*/
+
+bool QDir::remove( const QString &fileName, bool acceptAbsPath )
+{
+ if ( fileName.isEmpty() ) {
+#if defined(CHECK_NULL)
+ qWarning( "QDir::remove: Empty or null file name" );
+#endif
+ return FALSE;
+ }
+ QString p = filePath( fileName, acceptAbsPath );
+ return QFile::remove( p );
+}
+
+/*!
+ Checks for existence of a file.
+
+ If \e acceptAbsPaths is TRUE a path starting with a separator ('/')
+ will check the file with the absolute path, if \e acceptAbsPath is FALSE
+ any number of separators at the beginning of \e name will be removed.
+
+ Returns TRUE if the file exists, otherwise FALSE.
+
+ \sa QFileInfo::exists(), QFile::exists()
+*/
+
+bool QDir::exists( const QString &name, bool acceptAbsPath )
+{
+ if ( name.isEmpty() ) {
+#if defined(CHECK_NULL)
+ qWarning( "QDir::exists: Empty or null file name" );
+#endif
+ return FALSE;
+ }
+ QString tmp = filePath( name, acceptAbsPath );
+ return QFile::exists( tmp );
+}
+
+/*!
+ Returns the native directory separator; '/' under UNIX and '\' under
+ MS-DOS, Windows NT and OS/2.
+
+ You do not need to use this function to build file paths. If you always
+ use '/', Qt will translate your paths to conform to the underlying
+ operating system.
+*/
+
+char QDir::separator()
+{
+#if defined(_OS_UNIX_)
+ return '/';
+#elif defined (_OS_FATFS_)
+ return '\\';
+#elif defined (_OS_MAC_)
+ return ':';
+#else
+ return '/';
+#endif
+}
+
+/*!
+ Returns the current directory.
+ \sa currentDirPath(), QDir::QDir()
+*/
+
+QDir QDir::current()
+{
+ return QDir( currentDirPath() );
+}
+
+/*!
+ Returns the home directory.
+ \sa homeDirPath()
+*/
+
+QDir QDir::home()
+{
+ return QDir( homeDirPath() );
+}
+
+/*!
+ Returns the root directory.
+ \sa rootDirPath() drives()
+*/
+
+QDir QDir::root()
+{
+ return QDir( rootDirPath() );
+}
+
+/*!
+ \fn QString QDir::homeDirPath()
+
+ Returns the absolute path for the user's home directory,
+ \sa home()
+*/
+
+QStringList qt_makeFilterList( const QString &filter )
+{
+ if ( filter.isEmpty() )
+ return QStringList();
+
+ int i = filter.find( ' ', 0 );
+ QChar sep( ' ' );
+ if ( i == -1 ) {
+ if ( filter.find( ';', 0 ) != -1 ) {
+ sep = QChar( ';' );
+ i = filter.find( sep, 0 );
+ }
+ }
+
+ QStringList lst = QStringList::split( sep, filter );
+ QStringList lst2;
+ QStringList::Iterator it = lst.begin();
+
+ for ( ; it != lst.end(); ++it ) {
+ QString s = *it;
+ if ( s[ (int)s.length() - 1 ] == ';' )
+ s.remove( s.length() - 1, 1 );
+ lst2 << s;
+ }
+ return lst2;
+}
+
+/*!
+ Returns TRUE if the \e fileName matches one of the wildcards in the list \e filters.
+ \sa QRegExp
+*/
+
+bool QDir::match( const QStringList &filters, const QString &fileName )
+{
+ QStringList::ConstIterator sit = filters.begin();
+ bool matched = FALSE;
+ for ( ; sit != filters.end(); ++sit ) {
+ QRegExp regexp( *sit, FALSE, TRUE );
+ if ( regexp.match( fileName ) != -1 ) {
+ matched = TRUE;
+ break;
+ }
+ }
+
+ return matched;
+}
+
+/*!
+ Returns TRUE if the \e fileName matches the wildcard \e filter.
+ \a Filter may also contain multiple wildcards separated by spaces or
+ semicolons.
+ \sa QRegExp
+*/
+
+bool QDir::match( const QString &filter, const QString &fileName )
+{
+ QStringList lst = qt_makeFilterList( filter );
+ return match( lst, fileName );
+}
+
+
+/*!
+ Removes all multiple directory separators ('/') and resolves
+ any "." or ".." found in the path.
+
+ Symbolic links are kept. This function does not return the
+ canonical path, but rather the most simplified version of the input.
+ "../stuff" becomes "stuff", "stuff/../nonsense" becomes "nonsense"
+ and "\\stuff\\more\\..\\nonsense" becomes "\\stuff\\nonsense".
+
+ \sa absPath() canonicalPath()
+*/
+
+QString QDir::cleanDirPath( const QString &filePath )
+{
+ QString name = filePath;
+ QString newPath;
+
+ if ( name.isEmpty() )
+ return name;
+
+ slashify( name );
+
+ bool addedSeparator;
+ if ( isRelativePath(name) ) {
+ addedSeparator = TRUE;
+ name.insert( 0, '/' );
+ } else {
+ addedSeparator = FALSE;
+ }
+
+ int ePos, pos, upLevel;
+
+ pos = ePos = name.length();
+ upLevel = 0;
+ int len;
+
+ while ( pos && (pos = name.findRev('/',--pos)) != -1 ) {
+ len = ePos - pos - 1;
+ if ( len == 2 && name.at(pos + 1) == '.'
+ && name.at(pos + 2) == '.' ) {
+ upLevel++;
+ } else {
+ if ( len != 0 && (len != 1 || name.at(pos + 1) != '.') ) {
+ if ( !upLevel )
+ newPath = QString::fromLatin1("/")
+ + name.mid(pos + 1, len) + newPath;
+ else
+ upLevel--;
+ }
+ }
+ ePos = pos;
+ }
+ if ( addedSeparator ) {
+ while ( upLevel-- )
+ newPath.insert( 0, QString::fromLatin1("/..") );
+ if ( !newPath.isEmpty() )
+ newPath.remove( 0, 1 );
+ else
+ newPath = QString::fromLatin1(".");
+ } else {
+ if ( newPath.isEmpty() )
+ newPath = QString::fromLatin1("/");
+#if defined(_OS_FATFS_) || defined(_OS_OS2EMX_)
+ if ( name[0] == '/' ) {
+ if ( name[1] == '/' ) // "\\machine\x\ ..."
+ newPath.insert( 0, '/' );
+ } else {
+ newPath = name.left(2) + newPath;
+ }
+#endif
+ }
+ return newPath;
+}
+
+int qt_cmp_si_sortSpec;
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+int qt_cmp_si( const void *n1, const void *n2 )
+{
+ if ( !n1 || !n2 )
+ return 0;
+
+ QDirSortItem* f1 = (QDirSortItem*)n1;
+ QDirSortItem* f2 = (QDirSortItem*)n2;
+
+ if ( qt_cmp_si_sortSpec & QDir::DirsFirst )
+ if ( f1->item->isDir() != f2->item->isDir() )
+ return f1->item->isDir() ? -1 : 1;
+
+ int r = 0;
+ int sortBy = qt_cmp_si_sortSpec & QDir::SortByMask;
+
+ switch ( sortBy ) {
+ case QDir::Time:
+ r = f1->item->lastModified().secsTo(f2->item->lastModified());
+ break;
+ case QDir::Size:
+ r = f2->item->size() - f1->item->size();
+ break;
+ default:
+ ;
+ }
+
+ if ( r == 0 && sortBy != QDir::Unsorted ) {
+ // Still not sorted - sort by name
+ bool ic = qt_cmp_si_sortSpec & QDir::IgnoreCase;
+
+ if ( f1->filename_cache.isNull() )
+ f1->filename_cache = ic ? f1->item->fileName().lower()
+ : f1->item->fileName();
+ if ( f2->filename_cache.isNull() )
+ f2->filename_cache = ic ? f2->item->fileName().lower()
+ : f2->item->fileName();
+
+ r = f1->filename_cache.compare(f2->filename_cache);
+ }
+
+ if ( r == 0 ) {
+ // Enforce an order - the order the items appear in the array
+ r = (char*)n1 - (char*)n2;
+ }
+
+ if ( qt_cmp_si_sortSpec & QDir::Reversed )
+ return -r;
+ else
+ return r;
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+#endif // QT_NO_DIR
diff --git a/qtools/qdir.h b/qtools/qdir.h
new file mode 100644
index 0000000..dd74271
--- /dev/null
+++ b/qtools/qdir.h
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+**
+** Definition of QDir class
+**
+** Created : 950427
+**
+** Copyright (C) 1992-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_H
+#define QDIR_H
+
+#ifndef QT_H
+#include "qstrlist.h"
+#include "qfileinfo.h"
+#endif // QT_H
+
+#ifndef QT_NO_DIR
+typedef QList<QFileInfo> QFileInfoList;
+typedef QListIterator<QFileInfo> QFileInfoListIterator;
+class QStringList;
+
+
+class Q_EXPORT QDir
+{
+public:
+ enum FilterSpec { Dirs = 0x001,
+ Files = 0x002,
+ Drives = 0x004,
+ NoSymLinks = 0x008,
+ All = 0x007,
+ TypeMask = 0x00F,
+
+ Readable = 0x010,
+ Writable = 0x020,
+ Executable = 0x040,
+ RWEMask = 0x070,
+
+ Modified = 0x080,
+ Hidden = 0x100,
+ System = 0x200,
+ AccessMask = 0x3F0,
+
+ DefaultFilter = -1 };
+
+ enum SortSpec { Name = 0x00,
+ Time = 0x01,
+ Size = 0x02,
+ Unsorted = 0x03,
+ SortByMask = 0x03,
+
+ DirsFirst = 0x04,
+ Reversed = 0x08,
+ IgnoreCase = 0x10,
+ DefaultSort = -1 };
+
+ QDir();
+ QDir( const QString &path, const QString &nameFilter = QString::null,
+ int sortSpec = Name | IgnoreCase, int filterSpec = All );
+ QDir( const QDir & );
+
+ virtual ~QDir();
+
+ QDir &operator=( const QDir & );
+ QDir &operator=( const QString &path );
+
+ virtual void setPath( const QString &path );
+ virtual QString path() const;
+ virtual QString absPath() const;
+ virtual QString canonicalPath() const;
+
+ virtual QString dirName() const;
+ virtual QString filePath( const QString &fileName,
+ bool acceptAbsPath = TRUE ) const;
+ virtual QString absFilePath( const QString &fileName,
+ bool acceptAbsPath = TRUE ) const;
+
+ static QString convertSeparators( const QString &pathName );
+
+ virtual bool cd( const QString &dirName, bool acceptAbsPath = TRUE );
+ virtual bool cdUp();
+
+ QString nameFilter() const;
+ virtual void setNameFilter( const QString &nameFilter );
+ FilterSpec filter() const;
+ virtual void setFilter( int filterSpec );
+ SortSpec sorting() const;
+ virtual void setSorting( int sortSpec );
+
+ bool matchAllDirs() const;
+ virtual void setMatchAllDirs( bool );
+
+ uint count() const;
+ QString operator[]( int ) const;
+
+ virtual QStrList encodedEntryList( int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+ virtual QStrList encodedEntryList( const QString &nameFilter,
+ int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+ virtual QStringList entryList( int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+ virtual QStringList entryList( const QString &nameFilter,
+ int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+
+ virtual const QFileInfoList *entryInfoList( int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+ virtual const QFileInfoList *entryInfoList( const QString &nameFilter,
+ int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+
+ static const QFileInfoList *drives();
+
+ virtual bool mkdir( const QString &dirName,
+ bool acceptAbsPath = TRUE ) const;
+ virtual bool rmdir( const QString &dirName,
+ bool acceptAbsPath = TRUE ) const;
+
+ virtual bool isReadable() const;
+ virtual bool exists() const;
+ virtual bool isRoot() const;
+
+ virtual bool isRelative() const;
+ virtual void convertToAbs();
+
+ virtual bool operator==( const QDir & ) const;
+ virtual bool operator!=( const QDir & ) const;
+
+ virtual bool remove( const QString &fileName,
+ bool acceptAbsPath = TRUE );
+ virtual bool rename( const QString &name, const QString &newName,
+ bool acceptAbsPaths = TRUE );
+ virtual bool exists( const QString &name,
+ bool acceptAbsPath = TRUE );
+
+ static char separator();
+
+ static bool setCurrent( const QString &path );
+ static QDir current();
+ static QDir home();
+ static QDir root();
+ static QString currentDirPath();
+ static QString homeDirPath();
+ static QString rootDirPath();
+
+ static bool match( const QStringList &filters, const QString &fileName );
+ static bool match( const QString &filter, const QString &fileName );
+ static QString cleanDirPath( const QString &dirPath );
+ static bool isRelativePath( const QString &path );
+
+private:
+ void init();
+ virtual bool readDirEntries( const QString &nameFilter,
+ int FilterSpec, int SortSpec );
+
+ static void slashify ( QString &);
+
+ QString dPath;
+ QStringList *fList;
+ QFileInfoList *fiList;
+ QString nameFilt;
+ FilterSpec filtS;
+ SortSpec sortS;
+ uint dirty : 1;
+ uint allDirs : 1;
+};
+
+
+inline QString QDir::path() const
+{
+ return dPath;
+}
+
+inline QString QDir::nameFilter() const
+{
+ return nameFilt;
+}
+
+inline QDir::FilterSpec QDir::filter() const
+{
+ return filtS;
+}
+
+inline QDir::SortSpec QDir::sorting() const
+{
+ return sortS;
+}
+
+inline bool QDir::matchAllDirs() const
+{
+ return allDirs;
+}
+
+inline bool QDir::operator!=( const QDir &d ) const
+{
+ return !(*this == d);
+}
+
+
+struct QDirSortItem {
+ QString filename_cache;
+ QFileInfo* item;
+};
+
+#endif // QT_NO_DIR
+#endif // QDIR_H
diff --git a/qtools/qdir_unix.cpp b/qtools/qdir_unix.cpp
new file mode 100644
index 0000000..3b12de9
--- /dev/null
+++ b/qtools/qdir_unix.cpp
@@ -0,0 +1,286 @@
+/****************************************************************************
+**
+**
+** Implementation of QDirclass
+**
+** Created : 950628
+**
+** Copyright (C) 1992-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 for Unix/X11 or for Qt/Embedded 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 "qglobal.h"
+
+#include "qdir.h"
+#ifndef QT_NO_DIR
+
+#include "qfileinfo.h"
+#include "qfiledefs_p.h"
+#include "qregexp.h"
+#include "qstringlist.h"
+#include <stdlib.h>
+#include <ctype.h>
+
+extern QStringList qt_makeFilterList( const QString &filter );
+
+extern int qt_cmp_si_sortSpec;
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+extern int qt_cmp_si( const void *, const void * );
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+
+void QDir::slashify( QString& )
+{
+}
+
+QString QDir::homeDirPath()
+{
+ QString d;
+ d = QFile::decodeName(getenv("HOME"));
+ slashify( d );
+ if ( d.isNull() )
+ d = rootDirPath();
+ return d;
+}
+
+QString QDir::canonicalPath() const
+{
+ QString r;
+
+ char cur[PATH_MAX];
+ char tmp[PATH_MAX];
+ GETCWD( cur, PATH_MAX );
+ if ( CHDIR(QFile::encodeName(dPath)) >= 0 ) {
+ GETCWD( tmp, PATH_MAX );
+ r = QFile::decodeName(tmp);
+ }
+ CHDIR( cur );
+
+ slashify( r );
+ return r;
+}
+
+bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const
+{
+ return MKDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 )
+ == 0;
+}
+
+bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const
+{
+ return RMDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0;
+}
+
+bool QDir::isReadable() const
+{
+ return ACCESS( QFile::encodeName(dPath), R_OK | X_OK ) == 0;
+}
+
+bool QDir::isRoot() const
+{
+ return dPath == QString::fromLatin1("/");
+}
+
+bool QDir::rename( const QString &name, const QString &newName,
+ bool acceptAbsPaths )
+{
+ if ( name.isEmpty() || newName.isEmpty() ) {
+#if defined(CHECK_NULL)
+ qWarning( "QDir::rename: Empty or null file name(s)" );
+#endif
+ return FALSE;
+ }
+ QString fn1 = filePath( name, acceptAbsPaths );
+ QString fn2 = filePath( newName, acceptAbsPaths );
+ return ::rename( QFile::encodeName(fn1),
+ QFile::encodeName(fn2) ) == 0;
+}
+
+bool QDir::setCurrent( const QString &path )
+{
+ int r;
+ r = CHDIR( QFile::encodeName(path) );
+ return r >= 0;
+}
+
+QString QDir::currentDirPath()
+{
+ QString result;
+
+ STATBUF st;
+ if ( STAT( ".", &st ) == 0 ) {
+ char currentName[PATH_MAX];
+ if ( GETCWD( currentName, PATH_MAX ) != 0 )
+ result = QFile::decodeName(currentName);
+#if defined(DEBUG)
+ if ( result.isNull() )
+ qWarning( "QDir::currentDirPath: getcwd() failed" );
+#endif
+ } else {
+#if defined(DEBUG)
+ qWarning( "QDir::currentDirPath: stat(\".\") failed" );
+#endif
+ }
+ slashify( result );
+ return result;
+}
+
+QString QDir::rootDirPath()
+{
+ QString d = QString::fromLatin1( "/" );
+ return d;
+}
+
+bool QDir::isRelativePath( const QString &path )
+{
+ int len = path.length();
+ if ( len == 0 )
+ return TRUE;
+ return path[0] != '/';
+}
+
+bool QDir::readDirEntries( const QString &nameFilter,
+ int filterSpec, int sortSpec )
+{
+ int i;
+ if ( !fList ) {
+ fList = new QStringList;
+ CHECK_PTR( fList );
+ fiList = new QFileInfoList;
+ CHECK_PTR( fiList );
+ fiList->setAutoDelete( TRUE );
+ } else {
+ fList->clear();
+ fiList->clear();
+ }
+
+ QStringList filters = qt_makeFilterList( nameFilter );
+
+ bool doDirs = (filterSpec & Dirs) != 0;
+ bool doFiles = (filterSpec & Files) != 0;
+ bool noSymLinks = (filterSpec & NoSymLinks) != 0;
+ bool doReadable = (filterSpec & Readable) != 0;
+ bool doWritable = (filterSpec & Writable) != 0;
+ bool doExecable = (filterSpec & Executable) != 0;
+ bool doHidden = (filterSpec & Hidden) != 0;
+
+#if defined(_OS_OS2EMX_)
+ //QRegExp wc( nameFilter, FALSE, TRUE ); // wild card, case insensitive
+#else
+ //QRegExp wc( nameFilter, TRUE, TRUE ); // wild card, case sensitive
+#endif
+ QFileInfo fi;
+ DIR *dir;
+ dirent *file;
+
+ dir = opendir( QFile::encodeName(dPath) );
+ if ( !dir ) {
+#if defined(CHECK_NULL)
+ qWarning( "QDir::readDirEntries: Cannot read the directory: %s",
+ QFile::encodeName(dPath).data() );
+#endif
+ return FALSE;
+ }
+
+ while ( (file = readdir(dir)) ) {
+ QString fn = QFile::decodeName(file->d_name);
+ fi.setFile( *this, fn );
+ if ( !match( filters, fn ) && !(allDirs && fi.isDir()) )
+ continue;
+ if ( (doDirs && fi.isDir()) || (doFiles && fi.isFile()) ) {
+ if ( noSymLinks && fi.isSymLink() )
+ continue;
+ if ( (filterSpec & RWEMask) != 0 )
+ if ( (doReadable && !fi.isReadable()) ||
+ (doWritable && !fi.isWritable()) ||
+ (doExecable && !fi.isExecutable()) )
+ continue;
+ if ( !doHidden && fn[0] == '.' &&
+ fn != QString::fromLatin1(".")
+ && fn != QString::fromLatin1("..") )
+ continue;
+ fiList->append( new QFileInfo( fi ) );
+ }
+ }
+ if ( closedir(dir) != 0 ) {
+#if defined(CHECK_NULL)
+ qWarning( "QDir::readDirEntries: Cannot close the directory: %s",
+ dPath.local8Bit().data() );
+#endif
+ }
+
+ // Sort...
+ QDirSortItem* si= new QDirSortItem[fiList->count()];
+ QFileInfo* itm;
+ i=0;
+ for (itm = fiList->first(); itm; itm = fiList->next())
+ si[i++].item = itm;
+ qt_cmp_si_sortSpec = sortSpec;
+ qsort( si, i, sizeof(si[0]), qt_cmp_si );
+ // put them back in the list
+ fiList->setAutoDelete( FALSE );
+ fiList->clear();
+ int j;
+ for ( j=0; j<i; j++ ) {
+ fiList->append( si[j].item );
+ fList->append( si[j].item->fileName() );
+ }
+ delete [] si;
+ fiList->setAutoDelete( TRUE );
+
+ if ( filterSpec == (FilterSpec)filtS && sortSpec == (SortSpec)sortS &&
+ nameFilter == nameFilt )
+ dirty = FALSE;
+ else
+ dirty = TRUE;
+ return TRUE;
+}
+
+const QFileInfoList * QDir::drives()
+{
+ // at most one instance of QFileInfoList is leaked, and this variable
+ // points to that list
+ static QFileInfoList * knownMemoryLeak = 0;
+
+ if ( !knownMemoryLeak ) {
+ knownMemoryLeak = new QFileInfoList;
+ // non-win32 versions both use just one root directory
+ knownMemoryLeak->append( new QFileInfo( rootDirPath() ) );
+ }
+
+ return knownMemoryLeak;
+}
+#endif //QT_NO_DIR
diff --git a/qtools/qdir_win32.cpp b/qtools/qdir_win32.cpp
new file mode 100644
index 0000000..70c3563
--- /dev/null
+++ b/qtools/qdir_win32.cpp
@@ -0,0 +1,406 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2000 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Based on qdir_unix.cpp
+ *
+ * Copyright (C) 1992-2000 Trolltech AS.
+ */
+
+
+#include "qglobal.h"
+
+#include "qdir.h"
+#ifndef QT_NO_DIR
+
+
+#include "qfileinfo.h"
+#include "qfiledefs_p.h"
+#include "qregexp.h"
+#include "qstringlist.h"
+#include <stdlib.h>
+#include <ctype.h>
+#if defined(_OS_WIN32_)
+#if defined(_CC_BOOL_DEF_)
+#undef bool
+#include <windows.h>
+#define bool int
+#else
+#include <windows.h>
+#endif
+#endif
+#if defined(_OS_OS2EMX_)
+extern Q_UINT32 DosQueryCurrentDisk(Q_UINT32*,Q_UINT32*);
+#define NO_ERROR 0
+#endif
+
+extern QStringList qt_makeFilterList( const QString &filter );
+
+extern int qt_cmp_si_sortSpec;
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+extern int qt_cmp_si( const void *, const void * );
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+
+void QDir::slashify( QString& n )
+{
+ for ( int i=0; i<(int)n.length(); i++ )
+ {
+ if ( n[i] == '\\' )
+ n[i] = '/';
+ }
+}
+
+QString QDir::homeDirPath()
+{
+ QString d;
+ d = QFile::decodeName(getenv("HOME"));
+ slashify( d );
+ if ( d.isNull() )
+ d = rootDirPath();
+ return d;
+}
+
+QString QDir::canonicalPath() const
+{
+ QString r;
+
+ char cur[PATH_MAX];
+ char tmp[PATH_MAX];
+ GETCWD( cur, PATH_MAX );
+ if ( CHDIR(QFile::encodeName(dPath)) >= 0 ) {
+ GETCWD( tmp, PATH_MAX );
+ r = QFile::decodeName(tmp);
+ }
+ CHDIR( cur );
+
+ slashify( r );
+ return r;
+}
+
+bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const
+{
+#if defined(__CYGWIN32_)
+ return MKDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 )
+ == 0;
+#else
+ return MKDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0;
+
+#endif
+}
+
+bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const
+{
+ return RMDIR( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0;
+}
+
+bool QDir::isReadable() const
+{
+ return ACCESS( QFile::encodeName(dPath), R_OK ) == 0;
+}
+
+bool QDir::isRoot() const
+{
+ return dPath == QString::fromLatin1("/");
+}
+
+bool QDir::rename( const QString &name, const QString &newName,
+ bool acceptAbsPaths )
+{
+ if ( name.isEmpty() || newName.isEmpty() ) {
+#if defined(CHECK_NULL)
+ qWarning( "QDir::rename: Empty or null file name(s)" );
+#endif
+ return FALSE;
+ }
+ QString fn1 = filePath( name, acceptAbsPaths );
+ QString fn2 = filePath( newName, acceptAbsPaths );
+ return ::rename( QFile::encodeName(fn1),
+ QFile::encodeName(fn2) ) == 0;
+}
+
+bool QDir::setCurrent( const QString &path )
+{
+ int r;
+ r = CHDIR( QFile::encodeName(path) );
+ return r >= 0;
+}
+
+QString QDir::currentDirPath()
+{
+ QString result;
+
+ STATBUF st;
+ if ( STAT( ".", &st ) == 0 ) {
+ char currentName[PATH_MAX];
+ if ( GETCWD( currentName, PATH_MAX ) != 0 )
+ result = QFile::decodeName(currentName);
+#if defined(DEBUG)
+ if ( result.isNull() )
+ qWarning( "QDir::currentDirPath: getcwd() failed" );
+#endif
+ } else {
+#if defined(DEBUG)
+ qWarning( "QDir::currentDirPath: stat(\".\") failed" );
+#endif
+ }
+ slashify( result );
+ return result;
+}
+
+QString QDir::rootDirPath()
+{
+ QString d = QString::fromLatin1( "/" );
+ return d;
+}
+
+bool QDir::isRelativePath( const QString &path )
+{
+ int len = path.length();
+ if ( len == 0 )
+ return TRUE;
+ int i = 0;
+ if ( isalpha(path[0]) && path[1] == ':' ) // drive, e.g. a:
+ i = 2;
+ return path[i] != '/' && path[i] != '\\';
+}
+
+#undef IS_SUBDIR
+#undef IS_RDONLY
+#undef IS_ARCH
+#undef IS_HIDDEN
+#undef IS_SYSTEM
+#undef FF_GETFIRST
+#undef FF_GETNEXT
+#undef FF_ERROR
+
+#if defined(_OS_WIN32_)
+#define IS_SUBDIR FILE_ATTRIBUTE_DIRECTORY
+#define IS_RDONLY FILE_ATTRIBUTE_READONLY
+#define IS_ARCH FILE_ATTRIBUTE_ARCHIVE
+#define IS_HIDDEN FILE_ATTRIBUTE_HIDDEN
+#define IS_SYSTEM FILE_ATTRIBUTE_SYSTEM
+#define FF_GETFIRST FindFirstFile
+#define FF_GETNEXT FindNextFile
+#define FF_ERROR INVALID_HANDLE_VALUE
+#else
+#define IS_SUBDIR _A_SUBDIR
+#define IS_RDONLY _A_RDONLY
+#define IS_ARCH _A_ARCH
+#define IS_HIDDEN _A_HIDDEN
+#define IS_SYSTEM _A_SYSTEM
+#define FF_GETFIRST _findfirst
+#define FF_GETNEXT _findnext
+#define FF_ERROR -1
+#endif
+
+
+bool QDir::readDirEntries( const QString &nameFilter,
+ int filterSpec, int sortSpec )
+{
+ int i;
+ if ( !fList ) {
+ fList = new QStringList;
+ CHECK_PTR( fList );
+ fiList = new QFileInfoList;
+ CHECK_PTR( fiList );
+ fiList->setAutoDelete( TRUE );
+ } else {
+ fList->clear();
+ fiList->clear();
+ }
+
+ QStringList filters = qt_makeFilterList( nameFilter );
+
+ bool doDirs = (filterSpec & Dirs) != 0;
+ bool doFiles = (filterSpec & Files) != 0;
+ bool noSymLinks = (filterSpec & NoSymLinks) != 0;
+ bool doReadable = (filterSpec & Readable) != 0;
+ bool doWritable = (filterSpec & Writable) != 0;
+ bool doExecable = (filterSpec & Executable) != 0;
+ bool doHidden = (filterSpec & Hidden) != 0;
+ // show hidden files if the user asks explicitly for e.g. .*
+ if ( !doHidden && !nameFilter.isEmpty() && nameFilter[0] == '.' )
+ doHidden = TRUE;
+ bool doModified = (filterSpec & Modified) != 0;
+ bool doSystem = (filterSpec & System) != 0;
+
+ QRegExp wc( nameFilter, FALSE, TRUE ); // wild card, case insensitive
+ bool first = TRUE;
+ QString p = dPath.copy();
+ int plen = p.length();
+#if defined(_OS_WIN32_)
+ HANDLE ff;
+ WIN32_FIND_DATA finfo;
+#else
+ long ff;
+ _finddata_t finfo;
+#endif
+ QFileInfo fi;
+ if ( plen == 0 )
+ {
+#if defined(CHECK_NULL)
+ warning( "QDir::readDirEntries: No directory name specified" );
+#endif
+ return FALSE;
+ }
+ if ( p.at(plen-1) != '/' && p.at(plen-1) != '\\' )
+ p += '/';
+ p += "*.*";
+
+ ff = FF_GETFIRST( p.data(), &finfo );
+ if ( ff == FF_ERROR )
+ {
+#if defined(DEBUG)
+ warning( "QDir::readDirEntries: Cannot read the directory: %s",
+ (const char *)dPath );
+#endif
+ return FALSE;
+ }
+
+ while ( TRUE )
+ {
+ if ( first )
+ first = FALSE;
+ else
+ {
+#if defined(_OS_WIN32_)
+ if ( !FF_GETNEXT(ff,&finfo) )
+ break;
+#else
+ if ( FF_GETNEXT(ff,&finfo) == -1 )
+ break;
+#endif
+ }
+#if defined(_OS_WIN32_)
+ int attrib = finfo.dwFileAttributes;
+#else
+ int attrib = finfo.attrib;
+#endif
+ bool isDir = (attrib & IS_SUBDIR) != 0;
+ bool isFile = !isDir;
+ bool isSymLink = FALSE;
+ bool isReadable = TRUE;
+ bool isWritable = (attrib & IS_RDONLY) == 0;
+ bool isExecable = FALSE;
+ bool isModified = (attrib & IS_ARCH) != 0;
+ bool isHidden = (attrib & IS_HIDDEN) != 0;
+ bool isSystem = (attrib & IS_SYSTEM) != 0;
+
+#if defined(_OS_WIN32_)
+ const char *fname = finfo.cFileName;
+#else
+ const char *fname = finfo.name;
+#endif
+ if ( wc.match(fname) == -1 && !(allDirs && isDir) )
+ continue;
+
+ QString name = fname;
+ if ( doExecable )
+ {
+ QString ext = name.right(4).lower();
+ if ( ext == ".exe" || ext == ".com" || ext == ".bat" ||
+ ext == ".pif" || ext == ".cmd" )
+ isExecable = TRUE;
+ }
+
+ if ( (doDirs && isDir) || (doFiles && isFile) )
+ {
+ if ( noSymLinks && isSymLink )
+ continue;
+ if ( (filterSpec & RWEMask) != 0 )
+ if ( (doReadable && !isReadable) ||
+ (doWritable && !isWritable) ||
+ (doExecable && !isExecable) )
+ continue;
+ if ( doModified && !isModified )
+ continue;
+ if ( !doHidden && isHidden )
+ continue;
+ if ( !doSystem && isSystem )
+ continue;
+ fi.setFile( *this, name );
+ fiList->append( new QFileInfo( fi ) );
+ }
+ }
+#if defined(_OS_WIN32_)
+ FindClose( ff );
+#else
+ _findclose( ff );
+#endif
+
+ // Sort...
+ QDirSortItem* si= new QDirSortItem[fiList->count()];
+ QFileInfo* itm;
+ i=0;
+ for (itm = fiList->first(); itm; itm = fiList->next())
+ si[i++].item = itm;
+ qt_cmp_si_sortSpec = sortSpec;
+ qsort( si, i, sizeof(si[0]), qt_cmp_si );
+ // put them back in the list
+ fiList->setAutoDelete( FALSE );
+ fiList->clear();
+ int j;
+ for ( j=0; j<i; j++ ) {
+ fiList->append( si[j].item );
+ fList->append( si[j].item->fileName() );
+ }
+ delete [] si;
+ fiList->setAutoDelete( TRUE );
+
+ if ( filterSpec == (FilterSpec)filtS && sortSpec == (SortSpec)sortS &&
+ nameFilter == nameFilt )
+ dirty = FALSE;
+ else
+ dirty = TRUE;
+ return TRUE;
+}
+
+const QFileInfoList * QDir::drives()
+{
+ // at most one instance of QFileInfoList is leaked, and this variable
+ // points to that list
+ static QFileInfoList * knownMemoryLeak = 0;
+
+ if ( !knownMemoryLeak ) {
+ knownMemoryLeak = new QFileInfoList;
+
+#if defined(_OS_WIN32_)
+ Q_UINT32 driveBits = (Q_UINT32) GetLogicalDrives() & 0x3ffffff;
+#elif defined(_OS_OS2EMX_)
+ Q_UINT32 driveBits, cur;
+ if (DosQueryCurrentDisk(&cur,&driveBits) != NO_ERROR)
+ exit(1);
+ driveBits &= 0x3ffffff;
+#endif
+ char driveName[4];
+ qstrcpy( driveName, "a:/" );
+ while( driveBits ) {
+ if ( driveBits & 1 )
+ knownMemoryLeak->append( new QFileInfo( driveName ) );
+ driveName[0]++;
+ driveBits = driveBits >> 1;
+ }
+ }
+
+ return knownMemoryLeak;
+}
+#endif //QT_NO_DIR
diff --git a/qtools/qfeatures.h b/qtools/qfeatures.h
new file mode 100644
index 0000000..5f6f663
--- /dev/null
+++ b/qtools/qfeatures.h
@@ -0,0 +1,671 @@
+/****************************************************************************
+**
+**
+** Global feature selection
+**
+** Created : 000417
+**
+** 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 QFEATURES_H
+#define QFEATURES_H
+
+/*! \page features....html
+ ...
+*/
+
+#include <qconfig.h>
+
+
+// Data structures
+/*!
+ QStringList
+*/
+//#define QT_NO_STRINGLIST
+
+// File I/O
+#if defined(QT_NO_STRINGLIST)
+ /*!
+ QDir
+ */
+# define QT_NO_DIR
+#endif
+
+/*!
+ QTextStream
+*/
+//#define QT_NO_TEXTSTREAM
+/*!
+ QDataStream
+*/
+//#define QT_NO_DATASTREAM
+
+// Images
+/*!
+ BMP image I/O
+ <p>The Windows Bitmap (BMP) image format is common on MS-Windows.
+ <p>This is an uncompressed image format
+ offering few advantages over PNG or JPEG.
+*/
+#if defined(QT_NO_DATASTREAM)
+# define QT_NO_IMAGEIO_BMP
+#endif
+/*!
+ PPM image I/O
+ <p>The Portable PixMap (PPM) image format is common on Unix.
+ <p>This is an uncompressed image format
+ offering few advantages over PNG or JPEG.
+*/
+//#define QT_NO_IMAGEIO_PPM
+/*!
+ XBM image I/O
+ <p>The X11 BitMap (XBM) image format is common on X11.
+ <p>This is an uncompressed monochrome image format.
+ Qt uses this format for some internal images (eg. mouse cursors).
+*/
+//#define QT_NO_IMAGEIO_XBM
+/*!
+ XPM image I/O
+ <p>The X11 PixMap (XPM) image format is common on X11.
+ <p>This is an uncompressed image format.
+ XPM images have the small advantage that they can be trivially
+ included in source files as they are C code.
+ Qt uses this format for some internal images (eg. QMessageBox icons).
+*/
+#if defined(QT_NO_TEXTSTREAM)
+# define QT_NO_IMAGEIO_XPM
+#endif
+/*!
+ PNG image I/O
+ <p>The Portable Network Graphics (PNG) is a compressed image format.
+ <p>See <a href=http://www.libpng.org/pub/png/>The PNG Home Site</a> for
+ details of the format.
+*/
+//#define QT_NO_IMAGEIO_PNG
+/*!
+ MNG image I/O
+ <p>The Multiple-image Network Graphics (MNG) is a compressed animation format.
+ <p>See <a href=http://www.libpng.org/pub/mng/>The MNG Home Site</a> for
+ details of the format.
+*/
+//#define QT_NO_IMAGEIO_MNG
+/*!
+ JPEG image I/O
+ <p>The Joint Photographic Experts Group (JPEG) is a compressed lossy image format that gives high compression
+ for real-world and photo-realistic images.
+*/
+//#define QT_NO_IMAGEIO_JPEG
+
+/*!
+ Asynchronous I/O
+ <p>Allows push-driven data processing.
+*/
+//#define QT_NO_ASYNC_IO
+/*!
+ Asynchronous image I/O
+ <p>Allows push-driven images.
+*/
+//#define QT_NO_ASYNC_IMAGE_IO
+#if defined(QT_NO_ASYNC_IO) || defined(QT_NO_ASYNC_IMAGE_IO)
+ /*!
+ Animated images
+ <p>This includes animated GIFs.
+ <p><b>Note: this currently also requires <tt>QT_BUILTIN_GIF_READER</tt> to
+ be defined when building Qt.</b>
+ */
+# define QT_NO_MOVIE
+#endif
+
+// Fonts
+/*!
+ TrueType font files
+ <p>Scalable font format common on MS-Windows and becoming common on Unix.
+ <p>Only supported on Qt/Embedded.
+*/
+//#define QT_NO_TRUETYPE
+/*!
+ BDF font files
+ <p>The Bitmap Distribution Format (BDF) font file format, common
+ on Unix.
+ <p>Only supported on Qt/Embedded.
+*/
+#if defined(QT_NO_TEXTSTREAM) || defined(QT_NO_STRINGLIST)
+# define QT_NO_BDF
+#endif
+/*!
+ QFontDatabase
+*/
+#if defined(QT_NO_STRINGLIST)
+# define QT_NO_FONTDATABASE
+#endif
+
+// Internationalization
+
+/*!
+ QObject::tr()
+*/
+#if defined(QT_NO_DATASTREAM)
+# define QT_NO_TRANSLATION
+#endif
+
+/*!
+ QTextCodec class and subclasses
+*/
+//#define QT_NO_TEXTCODEC
+
+#if defined(QT_NO_TEXTCODEC)
+ /*!
+ QTextCodec classes
+ <p>This includes some large conversion tables.
+ */
+# define QT_NO_CODECS
+#endif
+#if defined(QT_LITE_UNICODE)
+ /*!
+ Unicode property tables
+ <p>These include some large tables.
+ */
+# define QT_NO_UNICODETABLES
+#endif
+
+// MIME-typed data
+/*!
+ MIME
+*/
+#if defined(QT_NO_DIR)
+# define QT_NO_MIME
+#endif
+#if defined(QT_NO_MIME) || defined(QT_NO_TEXTSTREAM)
+ /*!
+ RichText (HTML) display
+ */
+# define QT_NO_RICHTEXT
+#endif
+
+//XML
+
+#if defined(QT_NO_STRINGLIST)
+# define QT_NO_XML
+#endif
+
+/*! Document Object Model */
+#if defined(QT_NO_XML) ||defined(QT_NO_MIME)
+# define QT_NO_DOM
+#endif
+
+// Sound
+/*!
+ QSound
+*/
+//#define QT_NO_SOUND
+
+// Scripting
+/*!
+ Properties
+*/
+#if defined(QT_NO_STRINGLIST)
+# define QT_NO_PROPERTIES
+#endif
+
+// Qt/Embedded-specific
+/*!
+ Visible cursor
+*/
+//#define QT_NO_QWS_CURSOR
+/*!
+ Alpha-blended cursor
+*/
+//#define QT_NO_QWS_ALPHA_CURSOR
+/*!
+ Mach64 acceleration
+*/
+#define QT_NO_QWS_MACH64
+/*!
+ Voodoo3 acceleration
+*/
+#define QT_NO_QWS_VOODOO3
+/*!
+ Matrox MGA acceleration (Millennium/Millennium II/Mystique/G200/G400)
+*/
+#define QT_NO_QWS_MATROX
+/*!
+ Virtual frame buffer
+*/
+//#define QT_NO_QWS_VFB
+/*!
+ Remote frame buffer (VNC)
+*/
+#define QT_NO_QWS_VNC
+/*!
+ 1-bit monochrome
+*/
+//#define QT_NO_QWS_DEPTH_1
+/*!
+ 4-bit VGA
+ Not yet implemented
+*/
+#define QT_NO_QWS_VGA_16
+/*!
+ 8-bit grayscale
+*/
+#define QT_NO_QWS_DEPTH_8GRAYSCALE
+/*!
+ 8-bit color
+*/
+//#define QT_NO_QWS_DEPTH_8
+/*!
+ 15-bit color
+*/
+#define QT_NO_QWS_DEPTH_15
+/*!
+ 16-bit color
+*/
+//#define QT_NO_QWS_DEPTH_16
+/*!
+ 32-bit color
+*/
+//#define QT_NO_QWS_DEPTH_32
+
+/*!
+ Window manager
+*/
+//#define QT_NO_QWS_MANAGER
+
+/*!
+ Saving of fonts
+*/
+#define QT_NO_QWS_SAVEFONTS
+
+/*!
+ Favour code size over graphics speed
+ <p>Smaller, slower code will be used for drawing operations.
+ <p>Only supported on Qt/Embedded.
+*/
+//#define QT_NO_QWS_GFX_SPEED
+
+/*!
+ Qt/Embedded window system properties.
+*/
+//#define QT_NO_QWS_PROPERTIES
+
+#if defined(QT_NO_QWS_PROPERTIES) || defined(QT_NO_MIME) && !defined(_WS_QWS_)
+/*! Cut and paste */
+# define QT_NO_CLIPBOARD
+#endif
+
+#if defined(QT_NO_MIME) || defined(QT_NO_QWS_PROPERTIES)
+ /*!
+ Drag and drop
+ */
+# define QT_NO_DRAGANDDROP
+#endif
+
+#if defined(QT_NO_CLIPBOARD) || defined(QT_NO_MIME) || defined(_WS_QWS_)
+ /*!
+ Cut and paste of complex data types (non-text)
+ Not yet implemented for QWS.
+ */
+# define QT_NO_MIMECLIPBOARD
+#endif
+
+
+/*!
+ Drawing utility functions
+*/
+//#define QT_NO_DRAWUTIL
+/*!
+ TrueColor QImage
+*/
+//#define QT_NO_IMAGE_TRUECOLOR
+/*!
+ Smooth QImage scaling
+*/
+//#define QT_NO_IMAGE_SMOOTHSCALE
+/*!
+ Image file text strings
+*/
+#if defined(QT_NO_STRINGLIST)
+# define QT_NO_IMAGE_TEXT
+#endif
+
+#if defined(QT_NO_IMAGE_TRUECOLOR)
+ /*!
+ 16-bit QImage
+ */
+# define QT_NO_IMAGE_16_BIT
+#endif
+#if defined(QT_NO_QWS_CURSOR) && defined(_WS_QWS_)
+ /*!
+ Cursors
+ */
+# define QT_NO_CURSOR
+#endif
+
+
+
+// Networking
+/*!
+ DNS
+*/
+//#define QT_NO_DNS
+/*!
+ Network file access
+*/
+#if defined(QT_NO_DIR) || defined(QT_NO_STRINGLIST)
+# define QT_NO_NETWORKPROTOCOL
+#endif
+#if defined(QT_NO_NETWORKPROTOCOL) || defined(QT_NO_DNS)
+ /*!
+ FTP file access
+ */
+# define QT_NO_NETWORKPROTOCOL_FTP
+ /*!
+ HTTP file access
+ */
+# define QT_NO_NETWORKPROTOCOL_HTTP
+#endif
+
+// Painting
+/*!
+ Named colors
+*/
+//#define QT_NO_COLORNAMES
+/*!
+ Scaling and rotation
+*/
+//#define QT_NO_TRANSFORMATIONS
+
+// Printing
+/*!
+ Printing
+*/
+#if defined(QT_NO_TEXTSTREAM)
+# define QT_NO_PRINTER
+#endif
+
+// Metafiles
+/*!
+ QPicture
+*/
+#if defined(QT_NO_DATASTREAM)
+# define QT_NO_PICTURE
+#endif
+
+// Layout
+/*!
+ Automatic widget layout
+*/
+//#define QT_NO_LAYOUT
+
+// Widgets
+/*!
+ QStyle
+*/
+//#define QT_NO_STYLE
+
+
+#if defined QT_NO_IMAGE_SMOOTHSCALE
+/*!
+ QIconSet
+*/
+# define QT_NO_ICONSET
+#endif
+/*!
+ QDialog
+*/
+//#define QT_NO_DIALOG
+/*!
+ QSemiModal
+*/
+//#define QT_NO_SEMIMODAL
+/*!
+ QFrame
+*/
+//#define QT_NO_FRAME
+
+#if defined(QT_NO_FRAME) ||defined(QT_NO_PALETTE) || defined(QT_NO_STYLE) ||defined(QT_NO_DRAWUTIL)
+ /*!
+ Basic widgets: QLAbel, QPushbutton, ...
+ */
+# define QT_NO_SIMPLEWIDGETS
+#endif
+
+#if defined(QT_NO_SIMPLEWIDGETS)
+ /*!
+ QLabel
+ */
+# define QT_NO_LABEL
+ /*!
+ QPushButton (not implemented).
+ */
+# define QT_NO_PUSHBUTTON
+ /*!
+ QLineEdit (not implemented).
+ */
+# define QT_NO_LINEEDIT
+#endif
+#if defined(QT_NO_ICONSET) || defined(QT_NO_IMAGE_SMOOTHSCALE) || defined(QT_NO_SIMPLEWIDGETS)
+ /*!
+ Pre-defined complex widgets
+ */
+# define QT_NO_COMPLEXWIDGETS
+#endif
+#if defined(QT_NO_COMPLEXWIDGETS) || defined(QT_NO_RICHTEXT)
+ /*!
+ QTextView
+ */
+# define QT_NO_TEXTVIEW
+#endif
+#if defined(QT_NO_TEXTVIEW)
+ /*!
+ QTextBrowser
+ */
+# define QT_NO_TEXTBROWSER
+#endif
+
+#if defined(QT_NO_STYLE)
+ /*!
+ Windows style
+ */
+# define QT_NO_STYLE_WINDOWS
+ /*!
+ Motif style
+ */
+# define QT_NO_STYLE_MOTIF
+#endif
+
+#if defined(QT_NO_STYLE_MOTIF)
+# define QT_NO_STYLE_MOTIFPLUS
+#endif
+
+
+#if defined(QT_NO_COMPLEXWIDGETS) || defined(QT_NO_STRINGLIST)
+ /*!
+ QListBox
+ */
+# define QT_NO_LISTBOX
+#endif
+
+#if defined(QT_NO_COMPLEXWIDGETS)
+ /*!
+ QAccel
+ */
+# define QT_NO_ACCEL
+
+ /*!
+ QSizeGrip
+ */
+# define QT_NO_SIZEGRIP
+ /*!
+ QHeader
+ */
+# define QT_NO_HEADER
+ /*!
+ QMenuBar
+ */
+# define QT_NO_MENUBAR
+ /*!
+ QCanvas
+ */
+# define QT_NO_CANVAS
+ /*!
+ QDial
+ */
+# define QT_NO_DIAL
+ /*!
+ QWorkSpace
+ */
+# define QT_NO_WORKSPACE
+ /*!
+ QLCDNumber
+ */
+# define QT_NO_LCDNUMBER
+ /*!
+ QAction
+ */
+# define QT_NO_ACTION
+ /*!
+ QTable
+ */
+# define QT_NO_TABLE
+#endif
+#if defined(QT_NO_LISTBOX) || defined(QT_NO_COMPLEXWIDGETS)
+ /*!
+ QComboBox
+ */
+# define QT_NO_COMBOBOX
+#endif
+#if defined(QT_NO_COMPLEXWIDGETS)
+ /*!
+ QIconView
+ */
+# define QT_NO_ICONVIEW
+#endif
+#if defined(QT_NO_HEADER)
+ /*!
+ QListView
+ */
+# define QT_NO_LISTVIEW
+#endif
+#if defined(QT_NO_COMPLEXWIDGETS) || defined(QT_NO_DIALOG)
+ /*!
+ Built-in dialogs
+ */
+# define QT_NO_DIALOGS
+#endif
+
+#if defined(QT_NO_STYLE_WINDOWS)
+ /*!
+ Compact Windows style
+ */
+# define QT_NO_STYLE_COMPACT
+#endif
+
+#if defined(QT_NO_STYLE_MOTIF)
+ /*!
+ CDE style
+ */
+# define QT_NO_STYLE_CDE
+ /*!
+ SGI style
+ */
+# define QT_NO_STYLE_SGI
+#endif
+#if defined(QT_NO_STYLE_WINDOWS)
+ /*!
+ Platinum style
+ */
+# define QT_NO_STYLE_PLATINUM
+#endif
+
+#if defined(QT_NO_DIALOGS)
+ /*!
+ QColorDialog
+ */
+# define QT_NO_COLORDIALOG
+ /*!
+ QMessageBox
+ */
+# define QT_NO_MESSAGEBOX
+ /*!
+ QTabDialog
+ */
+# define QT_NO_TABDIALOG
+ /*!
+ QWizard
+ */
+# define QT_NO_WIZARD
+#endif
+
+#if defined(QT_NO_DIALOGS) || defined(QT_NO_LISTVIEW) || defined(QT_NO_NETWORKPROTOCOL) || defined(QT_NO_COMBOBOX) || defined(QT_NO_DIR) || defined(QT_NO_MESSAGEBOX)
+ /*!
+ QFileDialog
+ */
+# define QT_NO_FILEDIALOG
+#endif
+
+#if defined(QT_NO_DIALOGS) || defined(QT_NO_FONTDATABASE) || defined(QT_NO_COMBOBOX)
+ /*!
+ QFontDialog
+ */
+# define QT_NO_FONTDIALOG
+#endif
+
+#if defined(QT_NO_DIALOGS) || defined(QT_NO_LISTVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_COMBOBOX) || defined(QT_NO_DIR)
+ /*!
+ QPrintDialog
+ */
+# define QT_NO_PRINTDIALOG
+#endif
+
+#if defined(QT_NO_DIALOGS) || defined(QT_NO_SEMIMODAL)
+ /*!
+ QProgressDialog
+ */
+# define QT_NO_PROGRESSDIALOG
+#endif
+#if defined(QT_NO_DIALOGS) || defined(QT_NO_COMBOBOX)
+ /*!
+ QInputDialog
+ */
+# define QT_NO_INPUTDIALOG
+#endif
+
+#if defined(QT_NO_STRINGLIST)
+ // Desktop features
+ /*! Session management support */
+# define QT_NO_SESSIONMANAGER
+#endif
+
+/*! Special widget effects (fading, scrolling) */
+//#define QT_NO_EFFECTS
+
+#endif // QFEATURES_H
diff --git a/qtools/qfile.cpp b/qtools/qfile.cpp
new file mode 100644
index 0000000..2222b5b
--- /dev/null
+++ b/qtools/qfile.cpp
@@ -0,0 +1,550 @@
+/****************************************************************************
+**
+**
+** Implementation of QFile class
+**
+** Created : 930812
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qglobal.h"
+#if defined(_OS_WIN32_)
+#ifdef UNICODE
+#ifndef _UNICODE
+#define _UNICODE
+#endif
+#endif
+#endif
+
+#include "qfile.h"
+#include "qfiledefs_p.h"
+
+extern bool qt_file_access( const QString& fn, int t );
+
+// NOT REVISED
+/*!
+ \class QFile qfile.h
+ \brief The QFile class is an I/O device that operates on files.
+
+ \ingroup io
+
+ QFile is an I/O device for reading and writing binary and text files. A
+ QFile may be used by itself (readBlock and writeBlock) or by more
+ conveniently using QDataStream or QTextStream.
+
+ Here is a code fragment that uses QTextStream to read a text
+ file line by line. It prints each line with a line number.
+ \code
+ QFile f("file.txt");
+ if ( f.open(IO_ReadOnly) ) { // file opened successfully
+ QTextStream t( &f ); // use a text stream
+ QString s;
+ int n = 1;
+ while ( !t.eof() ) { // until end of file...
+ s = t.readLine(); // line of text excluding '\n'
+ printf( "%3d: %s\n", n++, (const char *)s );
+ }
+ f.close();
+ }
+ \endcode
+
+ The QFileInfo class holds detailed information about a file, such as
+ access permissions, file dates and file types.
+
+ The QDir class manages directories and lists of file names.
+
+ \sa QDataStream, QTextStream
+*/
+
+
+/*!
+ Constructs a QFile with no name.
+*/
+
+QFile::QFile()
+{
+ init();
+}
+
+/*!
+ Constructs a QFile with a file name \e name.
+ \sa setName()
+*/
+
+QFile::QFile( const QString &name )
+ : fn(name)
+{
+ init();
+}
+
+
+/*!
+ Destructs a QFile. Calls close().
+*/
+
+QFile::~QFile()
+{
+ close();
+}
+
+
+/*!
+ \internal
+ Initialize internal data.
+*/
+
+void QFile::init()
+{
+ setFlags( IO_Direct );
+ setStatus( IO_Ok );
+ fh = 0;
+ fd = 0;
+ length = 0;
+ ioIndex = 0;
+ ext_f = FALSE; // not an external file handle
+}
+
+
+/*!
+ \fn QString QFile::name() const
+ Returns the name set by setName().
+ \sa setName(), QFileInfo::fileName()
+*/
+
+/*!
+ Sets the name of the file. The name can include an absolute directory
+ path or it can be a name or a path relative to the current directory.
+
+ Do not call this function if the file has already been opened.
+
+ Note that if the name is relative QFile does not associate it with the
+ current directory. If you change directory before calling open(), open
+ uses the new current directory.
+
+ Example:
+ \code
+ QFile f;
+ QDir::setCurrent( "/tmp" );
+ f.setName( "readme.txt" );
+ QDir::setCurrent( "/home" );
+ f.open( IO_ReadOnly ); // opens "/home/readme.txt" under UNIX
+ \endcode
+
+ Also note that the directory separator '/' works for all operating
+ systems supported by Qt.
+
+ \sa name(), QFileInfo, QDir
+*/
+
+void QFile::setName( const QString &name )
+{
+ if ( isOpen() ) {
+#if defined(CHECK_STATE)
+ qWarning( "QFile::setName: File is open" );
+#endif
+ close();
+ }
+ fn = name;
+}
+
+/*!
+ Returns TRUE if this file exists, otherwise FALSE.
+ \sa name()
+*/
+
+bool QFile::exists() const
+{
+ return qt_file_access( fn, F_OK );
+}
+
+/*!
+ Returns TRUE if the file given by \e fileName exists, otherwise FALSE.
+*/
+
+bool QFile::exists( const QString &fileName )
+{
+ return qt_file_access( fileName, F_OK );
+}
+
+
+/*!
+ Removes the file specified by the file name currently set.
+ Returns TRUE if successful, otherwise FALSE.
+
+ The file is closed before it is removed.
+*/
+
+bool QFile::remove()
+{
+ close();
+ return remove( fn );
+}
+
+#if defined(_OS_MAC_) || defined(_OS_MSDOS_) || defined(_OS_WIN32_) || defined(_OS_OS2_)
+# define HAS_TEXT_FILEMODE // has translate/text filemode
+#endif
+#if defined(O_NONBLOCK)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NONBLOCK
+#elif defined(O_NDELAY)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NDELAY
+#endif
+
+/*!
+ Flushes the file buffer to the disk.
+
+ close() also flushes the file buffer.
+*/
+
+void QFile::flush()
+{
+ if ( isOpen() && fh ) // can only flush open/buffered
+ fflush( fh ); // file
+}
+
+/*!
+ Returns TRUE if the end of file has been reached, otherwise FALSE.
+ \sa size()
+*/
+
+bool QFile::atEnd() const
+{
+ if ( !isOpen() ) {
+#if defined(CHECK_STATE)
+ qWarning( "QFile::atEnd: File is not open" );
+#endif
+ return FALSE;
+ }
+ if ( isDirectAccess() && !isTranslated() ) {
+ if ( at() < length )
+ return FALSE;
+ }
+ return QIODevice::atEnd();
+}
+
+/*!
+ Reads a line of text.
+
+ Reads bytes from the file until end-of-line is reached, or up to \a
+ maxlen bytes, and returns the number of bytes read, or -1 in case of
+ error. The terminating newline is not stripped.
+
+ This function is efficient only for buffered files. Avoid
+ readLine() for files that have been opened with the \c IO_Raw
+ flag.
+
+ \sa readBlock(), QTextStream::readLine()
+*/
+
+int QFile::readLine( char *p, uint maxlen )
+{
+ if ( maxlen == 0 ) // application bug?
+ return 0;
+#if defined(CHECK_STATE)
+ CHECK_PTR( p );
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::readLine: File not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QFile::readLine: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ int nread; // number of bytes read
+ if ( isRaw() ) { // raw file
+ nread = QIODevice::readLine( p, maxlen );
+ } else { // buffered file
+ p = fgets( p, maxlen, fh );
+ if ( p ) {
+ nread = qstrlen( p );
+ ioIndex += nread;
+ } else {
+ nread = -1;
+ setStatus(IO_ReadError);
+ }
+ }
+ return nread;
+}
+
+
+/*!
+ Reads a line of text.
+
+ Reads bytes from the file until end-of-line is reached, or up to \a
+ maxlen bytes, and returns the number of bytes read, or -1 in case of
+ error. The terminating newline is not stripped.
+
+ This function is efficient only for buffered files. Avoid
+ readLine() for files that have been opened with the \c IO_Raw
+ flag.
+
+ Note that the string is read as plain Latin1 bytes, not Unicode.
+
+ \sa readBlock(), QTextStream::readLine()
+*/
+
+int QFile::readLine( QString& s, uint maxlen )
+{
+ QByteArray ba(maxlen);
+ int l = readLine(ba.data(),maxlen);
+ if ( l >= 0 ) {
+ ba.truncate(l);
+ s = QString(ba);
+ }
+ return l;
+}
+
+
+/*!
+ Reads a single byte/character from the file.
+
+ Returns the byte/character read, or -1 if the end of the file has been
+ reached.
+
+ \sa putch(), ungetch()
+*/
+
+int QFile::getch()
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::getch: File not open" );
+ return EOF;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QFile::getch: Read operation not permitted" );
+ return EOF;
+ }
+#endif
+
+ int ch;
+
+ if ( !ungetchBuffer.isEmpty() ) {
+ int len = ungetchBuffer.length();
+ ch = ungetchBuffer[ len-1 ];
+ ungetchBuffer.truncate( len - 1 );
+ return ch;
+ }
+
+ if ( isRaw() ) { // raw file (inefficient)
+ char buf[1];
+ ch = readBlock( buf, 1 ) == 1 ? buf[0] : EOF;
+ } else { // buffered file
+ if ( (ch = getc( fh )) != EOF )
+ ioIndex++;
+ else
+ setStatus(IO_ReadError);
+ }
+ return ch;
+}
+
+/*!
+ \fn int QFile::writeBlock( const QByteArray& data )
+ \reimp
+ \internal
+ Should be removed in 3.0
+*/
+
+/*!
+ Writes the character \e ch to the file.
+
+ Returns \e ch, or -1 if some error occurred.
+
+ \sa getch(), ungetch()
+*/
+
+int QFile::putch( int ch )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::putch: File not open" );
+ return EOF;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "QFile::putch: Write operation not permitted" );
+ return EOF;
+ }
+#endif
+ if ( isRaw() ) { // raw file (inefficient)
+ char buf[1];
+ buf[0] = ch;
+ ch = writeBlock( buf, 1 ) == 1 ? ch : EOF;
+ } else { // buffered file
+ if ( (ch = putc( ch, fh )) != EOF ) {
+ ioIndex++;
+ if ( ioIndex > length ) // update file length
+ length = ioIndex;
+ } else {
+ setStatus(IO_WriteError);
+ }
+ }
+ return ch;
+}
+
+/*!
+ Puts the character \e ch back into the file and decrements the index if it
+ is not zero.
+
+ This function is normally called to "undo" a getch() operation.
+
+ Returns \e ch, or -1 if some error occurred.
+
+ \sa getch(), putch()
+*/
+
+int QFile::ungetch( int ch )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::ungetch: File not open" );
+ return EOF;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QFile::ungetch: Read operation not permitted" );
+ return EOF;
+ }
+#endif
+ if ( ch == EOF ) // cannot unget EOF
+ return ch;
+
+ if ( isSequentialAccess() && !fh) {
+ // pipe or similar => we cannot ungetch, so do it manually
+ ungetchBuffer +=ch;
+ return ch;
+ }
+
+ if ( isRaw() ) { // raw file (very inefficient)
+ char buf[1];
+ at( ioIndex-1 );
+ buf[0] = ch;
+ if ( writeBlock(buf, 1) == 1 )
+ at ( ioIndex-1 );
+ else
+ ch = EOF;
+ } else { // buffered file
+ if ( (ch = ungetc(ch, fh)) != EOF )
+ ioIndex--;
+ else
+ setStatus( IO_ReadError );
+ }
+ return ch;
+}
+
+
+static QCString locale_encoder( const QString &fileName )
+{
+ return fileName.local8Bit();
+}
+
+
+static QFile::EncoderFn encoder = locale_encoder;
+
+/*!
+ When you use QFile, QFileInfo, and QDir to access the filesystem
+ with Qt, you can use Unicode filenames. On Unix, these filenames
+ are converted to an 8-bit encoding. If you want to do your own
+ file I/O on Unix, you should convert the filename using this
+ function. On Windows NT, Unicode filenames are supported directly
+ in the filesystem and this function should be avoided. On Windows 95,
+ non-Latin1 locales are not supported at this time.
+
+ By default, this function converts to the local 8-bit encoding
+ determined by the user's locale. This is sufficient for
+ filenames that the user chooses. Filenames hard-coded into the
+ application should only use 7-bit ASCII filename characters.
+
+ The conversion scheme can be changed using setEncodingFunction().
+ This might be useful if you wish to give the user an option to
+ store in filenames in UTF-8, etc., but beware that such filenames
+ would probably then be unrecognizable when seen by other programs.
+
+ \sa decodeName()
+*/
+
+QCString QFile::encodeName( const QString &fileName )
+{
+ return (*encoder)(fileName);
+}
+
+/*!
+ \enum QFile::EncoderFn
+
+ This is used by QFile::setEncodingFunction().
+*/
+
+/*!
+ Sets the function for encoding Unicode filenames.
+ The default encodes in the locale-specific 8-bit encoding.
+
+ \sa encodeName()
+*/
+void QFile::setEncodingFunction( EncoderFn f )
+{
+ encoder = f;
+}
+
+static
+QString locale_decoder( const QCString &localFileName )
+{
+ return QString::fromLocal8Bit(localFileName);
+}
+
+static QFile::DecoderFn decoder = locale_decoder;
+
+/*!
+ This does the reverse of QFile::encodeName().
+
+ \sa setDecodingFunction()
+*/
+QString QFile::decodeName( const QCString &localFileName )
+{
+ return (*decoder)(localFileName);
+}
+
+/*!
+ \enum QFile::DecoderFn
+
+ This is used by QFile::setDecodingFunction().
+*/
+
+/*!
+ Sets the function for decoding 8-bit filenames.
+ The default uses the locale-specific 8-bit encoding.
+
+ \sa encodeName(), decodeName()
+*/
+
+void QFile::setDecodingFunction( DecoderFn f )
+{
+ decoder = f;
+}
diff --git a/qtools/qfile.h b/qtools/qfile.h
new file mode 100644
index 0000000..4ef0685
--- /dev/null
+++ b/qtools/qfile.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+**
+** Definition of QFile class
+**
+** Created : 930831
+**
+** Copyright (C) 1992-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 QFILE_H
+#define QFILE_H
+
+#ifndef QT_H
+#include "qiodevice.h"
+#include "qstring.h"
+#include <stdio.h>
+#endif // QT_H
+
+class QDir;
+
+
+class Q_EXPORT QFile : public QIODevice // file I/O device class
+{
+public:
+ QFile();
+ QFile( const QString &name );
+ ~QFile();
+
+ QString name() const;
+ void setName( const QString &name );
+
+ typedef QCString (*EncoderFn)( const QString &fileName );
+ typedef QString (*DecoderFn)( const QCString &localfileName );
+ static QCString encodeName( const QString &fileName );
+ static QString decodeName( const QCString &localFileName );
+ static void setEncodingFunction( EncoderFn );
+ static void setDecodingFunction( DecoderFn );
+
+ bool exists() const;
+ static bool exists( const QString &fileName );
+
+ bool remove();
+ static bool remove( const QString &fileName );
+
+ bool open( int );
+ bool open( int, FILE * );
+ bool open( int, int );
+ void close();
+ void flush();
+
+ uint size() const;
+ int at() const;
+ bool at( int );
+ bool atEnd() const;
+
+ int readBlock( char *data, uint len );
+ int writeBlock( const char *data, uint len );
+ int writeBlock( const QByteArray& data )
+ { return QIODevice::writeBlock(data); }
+ int readLine( char *data, uint maxlen );
+ int readLine( QString &, uint maxlen );
+
+ int getch();
+ int putch( int );
+ int ungetch( int );
+
+ int handle() const;
+
+protected:
+ QString fn;
+ FILE *fh;
+ int fd;
+ int length;
+ bool ext_f;
+ void * d;
+
+private:
+ void init();
+ QCString ungetchBuffer;
+
+private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ QFile( const QFile & );
+ QFile &operator=( const QFile & );
+#endif
+};
+
+
+inline QString QFile::name() const
+{ return fn; }
+
+inline int QFile::at() const
+{ return ioIndex; }
+
+
+#endif // QFILE_H
diff --git a/qtools/qfile_unix.cpp b/qtools/qfile_unix.cpp
new file mode 100644
index 0000000..5c27988
--- /dev/null
+++ b/qtools/qfile_unix.cpp
@@ -0,0 +1,601 @@
+/****************************************************************************
+**
+**
+** Implementation of QFileInfo class
+**
+** Created : 950628
+**
+** Copyright (C) 1992-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 for Unix/X11 or for Qt/Embedded 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 "qglobal.h"
+
+#include "qfile.h"
+#include "qfiledefs_p.h"
+
+bool qt_file_access( const QString& fn, int t )
+{
+ if ( fn.isEmpty() )
+ return FALSE;
+ return ACCESS( QFile::encodeName(fn), t ) == 0;
+}
+
+/*!
+ Removes the file \a fileName.
+ Returns TRUE if successful, otherwise FALSE.
+*/
+
+bool QFile::remove( const QString &fileName )
+{
+ if ( fileName.isEmpty() ) {
+#if defined(CHECK_NULL)
+ qWarning( "QFile::remove: Empty or null file name" );
+#endif
+ return FALSE;
+ }
+ return unlink( QFile::encodeName(fileName) ) == 0;
+ // unlink more common in UNIX
+}
+
+#if defined(O_NONBLOCK)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NONBLOCK
+#elif defined(O_NDELAY)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NDELAY
+#endif
+
+/*!
+ Opens the file specified by the file name currently set, using the mode \e m.
+ Returns TRUE if successful, otherwise FALSE.
+
+ The mode parameter \e m must be a combination of the following flags:
+ <ul>
+ <li>\c IO_Raw specified raw (non-buffered) file access.
+ <li>\c IO_ReadOnly opens the file in read-only mode.
+ <li>\c IO_WriteOnly opens the file in write-only mode (and truncates).
+ <li>\c IO_ReadWrite opens the file in read/write mode, equivalent to
+ \c (IO_ReadOnly|IO_WriteOnly).
+ <li>\c IO_Append opens the file in append mode. This mode is very useful
+ when you want to write something to a log file. The file index is set to
+ the end of the file. Note that the result is undefined if you position the
+ file index manually using at() in append mode.
+ <li>\c IO_Truncate truncates the file.
+ <li>\c IO_Translate enables carriage returns and linefeed translation
+ for text files under MS-DOS, Windows and OS/2.
+ </ul>
+
+ The raw access mode is best when I/O is block-operated using 4kB block size
+ or greater. Buffered access works better when reading small portions of
+ data at a time.
+
+ <strong>Important:</strong> When working with buffered files, data may
+ not be written to the file at once. Call \link flush() flush\endlink
+ to make sure the data is really written.
+
+ \warning We have experienced problems with some C libraries when a buffered
+ file is opened for both reading and writing. If a read operation takes place
+ immediately after a write operation, the read buffer contains garbage data.
+ Worse, the same garbage is written to the file. Calling flush() before
+ readBlock() solved this problem.
+
+ If the file does not exist and \c IO_WriteOnly or \c IO_ReadWrite is
+ specified, it is created.
+
+ Example:
+ \code
+ QFile f1( "/tmp/data.bin" );
+ QFile f2( "readme.txt" );
+ f1.open( IO_Raw | IO_ReadWrite | IO_Append );
+ f2.open( IO_ReadOnly | IO_Translate );
+ \endcode
+
+ \sa name(), close(), isOpen(), flush()
+*/
+
+bool QFile::open( int m )
+{
+ if ( isOpen() ) { // file already open
+#if defined(CHECK_STATE)
+ qWarning( "QFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ if ( fn.isNull() ) { // no file name defined
+#if defined(CHECK_NULL)
+ qWarning( "QFile::open: No file name specified" );
+#endif
+ return FALSE;
+ }
+ init(); // reset params
+ setMode( m );
+ if ( !(isReadable() || isWritable()) ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QFile::open: File access not specified" );
+#endif
+ return FALSE;
+ }
+ bool ok = TRUE;
+ STATBUF st;
+ if ( isRaw() ) { // raw file I/O
+ int oflags = OPEN_RDONLY;
+ if ( isReadable() && isWritable() )
+ oflags = OPEN_RDWR;
+ else if ( isWritable() )
+ oflags = OPEN_WRONLY;
+ if ( flags() & IO_Append ) { // append to end of file?
+ if ( flags() & IO_Truncate )
+ oflags |= (OPEN_CREAT | OPEN_TRUNC);
+ else
+ oflags |= (OPEN_APPEND | OPEN_CREAT);
+ setFlags( flags() | IO_WriteOnly ); // append implies write
+ } else if ( isWritable() ) { // create/trunc if writable
+ if ( flags() & IO_Truncate )
+ oflags |= (OPEN_CREAT | OPEN_TRUNC);
+ else
+ oflags |= OPEN_CREAT;
+ }
+#if defined(HAS_TEXT_FILEMODE)
+ if ( isTranslated() )
+ oflags |= OPEN_TEXT;
+ else
+ oflags |= OPEN_BINARY;
+#endif
+#if defined(HAS_ASYNC_FILEMODE)
+ if ( isAsynchronous() )
+ oflags |= OPEN_ASYNC;
+#endif
+ fd = OPEN( QFile::encodeName(fn), oflags, 0666 );
+
+ if ( fd != -1 ) { // open successful
+ FSTAT( fd, &st ); // get the stat for later usage
+ } else {
+ ok = FALSE;
+ }
+ } else { // buffered file I/O
+ QCString perm;
+ char perm2[4];
+ bool try_create = FALSE;
+ if ( flags() & IO_Append ) { // append to end of file?
+ setFlags( flags() | IO_WriteOnly ); // append implies write
+ perm = isReadable() ? "a+" : "a";
+ } else {
+ if ( isReadWrite() ) {
+ if ( flags() & IO_Truncate ) {
+ perm = "w+";
+ } else {
+ perm = "r+";
+ try_create = TRUE; // try to create if not exists
+ }
+ } else if ( isReadable() ) {
+ perm = "r";
+ } else if ( isWritable() ) {
+ perm = "w";
+ }
+ }
+ qstrcpy( perm2, perm );
+#if defined(HAS_TEXT_FILEMODE)
+ if ( isTranslated() )
+ strcat( perm2, "t" );
+ else
+ strcat( perm2, "b" );
+#endif
+ while (1) { // At most twice
+
+ fh = fopen( QFile::encodeName(fn), perm2 );
+
+ if ( !fh && try_create ) {
+ perm2[0] = 'w'; // try "w+" instead of "r+"
+ try_create = FALSE;
+ } else {
+ break;
+ }
+ }
+ if ( fh ) {
+ FSTAT( FILENO(fh), &st ); // get the stat for later usage
+ } else {
+ ok = FALSE;
+ }
+ }
+ if ( ok ) {
+ setState( IO_Open );
+ // on successful open the file stat was got; now test what type
+ // of file we have
+ if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
+ } else {
+ length = (int)st.st_size;
+ ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
+ if ( (flags() & !IO_Truncate) && length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // device; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ }
+ }
+ }
+ } else {
+ init();
+ if ( errno == EMFILE ) // no more file handles/descrs
+ setStatus( IO_ResourceError );
+ else
+ setStatus( IO_OpenError );
+ }
+ return ok;
+}
+
+/*!
+ Opens a file in the mode \e m using an existing file handle \e f.
+ Returns TRUE if successful, otherwise FALSE.
+
+ Example:
+ \code
+ #include <stdio.h>
+
+ void printError( const char* msg )
+ {
+ QFile f;
+ f.open( IO_WriteOnly, stderr );
+ f.writeBlock( msg, qstrlen(msg) ); // write to stderr
+ f.close();
+ }
+ \endcode
+
+ When a QFile is opened using this function, close() does not actually
+ close the file, only flushes it.
+
+ \warning If \e f is \c stdin, \c stdout, \c stderr, you may not
+ be able to seek. See QIODevice::isSequentialAccess() for more
+ information.
+
+ \sa close()
+*/
+
+bool QFile::open( int m, FILE *f )
+{
+ if ( isOpen() ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ init();
+ setMode( m &~IO_Raw );
+ setState( IO_Open );
+ fh = f;
+ ext_f = TRUE;
+ STATBUF st;
+ FSTAT( FILENO(fh), &st );
+ ioIndex = (int)ftell( fh );
+ if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ } else {
+ length = (int)st.st_size;
+ if ( (flags() & !IO_Truncate) && length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // device; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ Opens a file in the mode \e m using an existing file descriptor \e f.
+ Returns TRUE if successful, otherwise FALSE.
+
+ When a QFile is opened using this function, close() does not actually
+ close the file.
+
+ \warning If \e f is one of 0 (stdin), 1 (stdout) or 2 (stderr), you may not
+ be able to seek. size() is set to \c INT_MAX (in limits.h).
+
+ \sa close()
+*/
+
+
+bool QFile::open( int m, int f )
+{
+ if ( isOpen() ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ init();
+ setMode( m |IO_Raw );
+ setState( IO_Open );
+ fd = f;
+ ext_f = TRUE;
+ STATBUF st;
+ FSTAT( fd, &st );
+ ioIndex = (int)LSEEK(fd, 0, SEEK_CUR);
+ if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ } else {
+ length = (int)st.st_size;
+ if ( length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // device; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ Returns the file size.
+ \sa at()
+*/
+
+uint QFile::size() const
+{
+ STATBUF st;
+ if ( isOpen() ) {
+ FSTAT( fh ? FILENO(fh) : fd, &st );
+ } else {
+ STAT( QFile::encodeName(fn), &st );
+ }
+ return st.st_size;
+}
+
+/*!
+ \fn int QFile::at() const
+ Returns the file index.
+ \sa size()
+*/
+
+/*!
+ Sets the file index to \e pos. Returns TRUE if successful, otherwise FALSE.
+
+ Example:
+ \code
+ QFile f( "data.bin" );
+ f.open( IO_ReadOnly ); // index set to 0
+ f.at( 100 ); // set index to 100
+ f.at( f.at()+50 ); // set index to 150
+ f.at( f.size()-80 ); // set index to 80 before EOF
+ f.close();
+ \endcode
+
+ \warning The result is undefined if the file was \link open() opened\endlink
+ using the \c IO_Append specifier.
+
+ \sa size(), open()
+*/
+
+bool QFile::at( int pos )
+{
+ if ( !isOpen() ) {
+#if defined(CHECK_STATE)
+ qWarning( "QFile::at: File is not open" );
+#endif
+ return FALSE;
+ }
+ bool ok;
+ if ( isRaw() ) { // raw file
+ pos = (int)LSEEK(fd, pos, SEEK_SET);
+ ok = pos != -1;
+ } else { // buffered file
+ ok = fseek(fh, pos, SEEK_SET) == 0;
+ }
+ if ( ok )
+ ioIndex = pos;
+#if defined(CHECK_RANGE)
+ else
+ qWarning( "QFile::at: Cannot set file position %d", pos );
+#endif
+ return ok;
+}
+
+/*!
+ Reads at most \e len bytes from the file into \e p and returns the
+ number of bytes actually read.
+
+ Returns -1 if a serious error occurred.
+
+ \warning We have experienced problems with some C libraries when a buffered
+ file is opened for both reading and writing. If a read operation takes place
+ immediately after a write operation, the read buffer contains garbage data.
+ Worse, the same garbage is written to the file. Calling flush() before
+ readBlock() solved this problem.
+
+ \sa writeBlock()
+*/
+
+int QFile::readBlock( char *p, uint len )
+{
+#if defined(CHECK_NULL)
+ if ( !p )
+ qWarning( "QFile::readBlock: Null pointer error" );
+#endif
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::readBlock: File not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QFile::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ int nread; // number of bytes read
+ if ( isRaw() ) { // raw file
+ nread = READ( fd, p, len );
+ if ( len && nread <= 0 ) {
+ nread = 0;
+ setStatus(IO_ReadError);
+ }
+ } else { // buffered file
+ nread = fread( p, 1, len, fh );
+ if ( (uint)nread != len ) {
+ if ( ferror( fh ) || nread==0 )
+ setStatus(IO_ReadError);
+ }
+ }
+ ioIndex += nread;
+ return nread;
+}
+
+/*! \overload int writeBlock( const QByteArray& data )
+*/
+
+/*! \reimp
+
+ Writes \e len bytes from \e p to the file and returns the number of
+ bytes actually written.
+
+ Returns -1 if a serious error occurred.
+
+ \warning When working with buffered files, data may not be written
+ to the file at once. Call flush() to make sure the data is really
+ written.
+
+ \sa readBlock()
+*/
+
+int QFile::writeBlock( const char *p, uint len )
+{
+#if defined(CHECK_NULL)
+ if ( p == 0 && len != 0 )
+ qWarning( "QFile::writeBlock: Null pointer error" );
+#endif
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::writeBlock: File not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "QFile::writeBlock: Write operation not permitted" );
+ return -1;
+ }
+#endif
+ int nwritten; // number of bytes written
+ if ( isRaw() ) // raw file
+ nwritten = WRITE( fd, p, len );
+ else // buffered file
+ nwritten = fwrite( p, 1, len, fh );
+ if ( nwritten != (int)len ) { // write error
+ if ( errno == ENOSPC ) // disk is full
+ setStatus( IO_ResourceError );
+ else
+ setStatus( IO_WriteError );
+ if ( isRaw() ) // recalc file position
+ ioIndex = (int)LSEEK( fd, 0, SEEK_CUR );
+ else
+ ioIndex = fseek( fh, 0, SEEK_CUR );
+ } else {
+ ioIndex += nwritten;
+ }
+ if ( ioIndex > length ) // update file length
+ length = ioIndex;
+ return nwritten;
+}
+
+/*!
+ Returns the file handle of the file.
+
+ This is a small positive integer, suitable for use with C library
+ functions such as fdopen() and fcntl(), as well as with QSocketNotifier.
+
+ If the file is not open or there is an error, handle() returns -1.
+
+ \sa QSocketNotifier
+*/
+
+int QFile::handle() const
+{
+ if ( !isOpen() )
+ return -1;
+ else if ( fh )
+ return FILENO( fh );
+ else
+ return fd;
+}
+
+/*!
+ Closes an open file.
+
+ The file is not closed if it was opened with an existing file handle.
+ If the existing file handle is a \c FILE*, the file is flushed.
+ If the existing file handle is an \c int file descriptor, nothing
+ is done to the file.
+
+ Some "write-behind" filesystems may report an unspecified error on
+ closing the file. These errors only indicate that something may
+ have gone wrong since the previous open(). In such a case status()
+ reports IO_UnspecifiedError after close(), otherwise IO_Ok.
+
+ \sa open(), flush()
+*/
+
+
+void QFile::close()
+{
+ bool ok = FALSE;
+ if ( isOpen() ) { // file is not open
+ if ( fh ) { // buffered file
+ if ( ext_f )
+ ok = fflush( fh ) != -1; // flush instead of closing
+ else
+ ok = fclose( fh ) != -1;
+ } else { // raw file
+ if ( ext_f )
+ ok = TRUE; // cannot close
+ else
+ ok = CLOSE( fd ) != -1;
+ }
+ init(); // restore internal state
+ }
+ if (!ok)
+ setStatus (IO_UnspecifiedError);
+
+ return;
+}
diff --git a/qtools/qfile_win32.cpp b/qtools/qfile_win32.cpp
new file mode 100644
index 0000000..5272365
--- /dev/null
+++ b/qtools/qfile_win32.cpp
@@ -0,0 +1,582 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2000 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Based on qfile_unix.cpp
+ *
+ * Copyright (C) 1992-2000 Trolltech AS.
+ */
+
+#include "qglobal.h"
+
+#include "qfile.h"
+#include "qfiledefs_p.h"
+
+bool qt_file_access( const QString& fn, int t )
+{
+ if ( fn.isEmpty() )
+ return FALSE;
+ return ACCESS( QFile::encodeName(fn), t ) == 0;
+}
+
+/*!
+ Removes the file \a fileName.
+ Returns TRUE if successful, otherwise FALSE.
+*/
+
+bool QFile::remove( const QString &fileName )
+{
+ if ( fileName.isEmpty() ) {
+#if defined(CHECK_NULL)
+ qWarning( "QFile::remove: Empty or null file name" );
+#endif
+ return FALSE;
+ }
+ return ::remove( QFile::encodeName(fileName) ) == 0;
+ // unlink more common in UNIX
+}
+
+#if defined(O_NONBLOCK)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NONBLOCK
+#elif defined(O_NDELAY)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NDELAY
+#endif
+
+/*!
+ Opens the file specified by the file name currently set, using the mode \e m.
+ Returns TRUE if successful, otherwise FALSE.
+
+ The mode parameter \e m must be a combination of the following flags:
+ <ul>
+ <li>\c IO_Raw specified raw (non-buffered) file access.
+ <li>\c IO_ReadOnly opens the file in read-only mode.
+ <li>\c IO_WriteOnly opens the file in write-only mode (and truncates).
+ <li>\c IO_ReadWrite opens the file in read/write mode, equivalent to
+ \c (IO_ReadOnly|IO_WriteOnly).
+ <li>\c IO_Append opens the file in append mode. This mode is very useful
+ when you want to write something to a log file. The file index is set to
+ the end of the file. Note that the result is undefined if you position the
+ file index manually using at() in append mode.
+ <li>\c IO_Truncate truncates the file.
+ <li>\c IO_Translate enables carriage returns and linefeed translation
+ for text files under MS-DOS, Windows and OS/2.
+ </ul>
+
+ The raw access mode is best when I/O is block-operated using 4kB block size
+ or greater. Buffered access works better when reading small portions of
+ data at a time.
+
+ <strong>Important:</strong> When working with buffered files, data may
+ not be written to the file at once. Call \link flush() flush\endlink
+ to make sure the data is really written.
+
+ \warning We have experienced problems with some C libraries when a buffered
+ file is opened for both reading and writing. If a read operation takes place
+ immediately after a write operation, the read buffer contains garbage data.
+ Worse, the same garbage is written to the file. Calling flush() before
+ readBlock() solved this problem.
+
+ If the file does not exist and \c IO_WriteOnly or \c IO_ReadWrite is
+ specified, it is created.
+
+ Example:
+ \code
+ QFile f1( "/tmp/data.bin" );
+ QFile f2( "readme.txt" );
+ f1.open( IO_Raw | IO_ReadWrite | IO_Append );
+ f2.open( IO_ReadOnly | IO_Translate );
+ \endcode
+
+ \sa name(), close(), isOpen(), flush()
+*/
+
+bool QFile::open( int m )
+{
+ if ( isOpen() ) { // file already open
+#if defined(CHECK_STATE)
+ qWarning( "QFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ if ( fn.isNull() ) { // no file name defined
+#if defined(CHECK_NULL)
+ qWarning( "QFile::open: No file name specified" );
+#endif
+ return FALSE;
+ }
+ init(); // reset params
+ setMode( m );
+ if ( !(isReadable() || isWritable()) ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QFile::open: File access not specified" );
+#endif
+ return FALSE;
+ }
+ bool ok = TRUE;
+ STATBUF st;
+ if ( isRaw() ) { // raw file I/O
+ int oflags = OPEN_RDONLY;
+ if ( isReadable() && isWritable() )
+ oflags = OPEN_RDWR;
+ else if ( isWritable() )
+ oflags = OPEN_WRONLY;
+ if ( flags() & IO_Append ) { // append to end of file?
+ if ( flags() & IO_Truncate )
+ oflags |= (OPEN_CREAT | OPEN_TRUNC);
+ else
+ oflags |= (OPEN_APPEND | OPEN_CREAT);
+ setFlags( flags() | IO_WriteOnly ); // append implies write
+ } else if ( isWritable() ) { // create/trunc if writable
+ if ( flags() & IO_Truncate )
+ oflags |= (OPEN_CREAT | OPEN_TRUNC);
+ else
+ oflags |= OPEN_CREAT;
+ }
+#if defined(HAS_TEXT_FILEMODE)
+ if ( isTranslated() )
+ oflags |= OPEN_TEXT;
+ else
+ oflags |= OPEN_BINARY;
+#endif
+#if defined(HAS_ASYNC_FILEMODE)
+ if ( isAsynchronous() )
+ oflags |= OPEN_ASYNC;
+#endif
+ fd = OPEN( QFile::encodeName(fn), oflags, 0666 );
+
+ if ( fd != -1 ) { // open successful
+ FSTAT( fd, &st ); // get the stat for later usage
+ } else {
+ ok = FALSE;
+ }
+ } else { // buffered file I/O
+ QCString perm;
+ char perm2[4];
+ bool try_create = FALSE;
+ if ( flags() & IO_Append ) { // append to end of file?
+ setFlags( flags() | IO_WriteOnly ); // append implies write
+ perm = isReadable() ? "a+" : "a";
+ } else {
+ if ( isReadWrite() ) {
+ if ( flags() & IO_Truncate ) {
+ perm = "w+";
+ } else {
+ perm = "r+";
+ try_create = TRUE; // try to create if not exists
+ }
+ } else if ( isReadable() ) {
+ perm = "r";
+ } else if ( isWritable() ) {
+ perm = "w";
+ }
+ }
+ qstrcpy( perm2, perm );
+ if ( isTranslated() )
+ strcat( perm2, "t" );
+ else
+ strcat( perm2, "b" );
+ while (1) { // At most twice
+
+ fh = fopen( QFile::encodeName(fn), perm2 );
+
+ if ( !fh && try_create ) {
+ perm2[0] = 'w'; // try "w+" instead of "r+"
+ try_create = FALSE;
+ } else {
+ break;
+ }
+ }
+ if ( fh ) {
+ FSTAT( FILENO(fh), &st ); // get the stat for later usage
+ } else {
+ ok = FALSE;
+ }
+ }
+ if ( ok ) {
+ setState( IO_Open );
+ // on successful open the file stat was got; now test what type
+ // of file we have
+ if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
+ } else {
+ length = (int)st.st_size;
+ ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
+ if ( (flags() & !IO_Truncate) && length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // device; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ }
+ }
+ }
+ } else {
+ init();
+ if ( errno == EMFILE ) // no more file handles/descrs
+ setStatus( IO_ResourceError );
+ else
+ setStatus( IO_OpenError );
+ }
+ return ok;
+}
+
+/*!
+ Opens a file in the mode \e m using an existing file handle \e f.
+ Returns TRUE if successful, otherwise FALSE.
+
+ Example:
+ \code
+ #include <stdio.h>
+
+ void printError( const char* msg )
+ {
+ QFile f;
+ f.open( IO_WriteOnly, stderr );
+ f.writeBlock( msg, qstrlen(msg) ); // write to stderr
+ f.close();
+ }
+ \endcode
+
+ When a QFile is opened using this function, close() does not actually
+ close the file, only flushes it.
+
+ \warning If \e f is \c stdin, \c stdout, \c stderr, you may not
+ be able to seek. See QIODevice::isSequentialAccess() for more
+ information.
+
+ \sa close()
+*/
+
+bool QFile::open( int m, FILE *f )
+{
+ if ( isOpen() ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ init();
+ setMode( m &~IO_Raw );
+ setState( IO_Open );
+ fh = f;
+ ext_f = TRUE;
+ STATBUF st;
+ FSTAT( FILENO(fh), &st );
+ ioIndex = (int)ftell( fh );
+ if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ } else {
+ length = (int)st.st_size;
+ if ( (flags() & !IO_Truncate) && length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // device; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ Opens a file in the mode \e m using an existing file descriptor \e f.
+ Returns TRUE if successful, otherwise FALSE.
+
+ When a QFile is opened using this function, close() does not actually
+ close the file.
+
+ \warning If \e f is one of 0 (stdin), 1 (stdout) or 2 (stderr), you may not
+ be able to seek. size() is set to \c INT_MAX (in limits.h).
+
+ \sa close()
+*/
+
+
+bool QFile::open( int m, int f )
+{
+ if ( isOpen() ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ init();
+ setMode( m |IO_Raw );
+ setState( IO_Open );
+ fd = f;
+ ext_f = TRUE;
+ STATBUF st;
+ FSTAT( fd, &st );
+ ioIndex = (int)LSEEK(fd, 0, SEEK_CUR);
+ if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ } else {
+ length = (int)st.st_size;
+ if ( length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // device; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ Returns the file size.
+ \sa at()
+*/
+
+uint QFile::size() const
+{
+ STATBUF st;
+ if ( isOpen() ) {
+ FSTAT( fh ? FILENO(fh) : fd, &st );
+ } else {
+ STAT( QFile::encodeName(fn), &st );
+ }
+ return st.st_size;
+}
+
+/*!
+ \fn int QFile::at() const
+ Returns the file index.
+ \sa size()
+*/
+
+/*!
+ Sets the file index to \e pos. Returns TRUE if successful, otherwise FALSE.
+
+ Example:
+ \code
+ QFile f( "data.bin" );
+ f.open( IO_ReadOnly ); // index set to 0
+ f.at( 100 ); // set index to 100
+ f.at( f.at()+50 ); // set index to 150
+ f.at( f.size()-80 ); // set index to 80 before EOF
+ f.close();
+ \endcode
+
+ \warning The result is undefined if the file was \link open() opened\endlink
+ using the \c IO_Append specifier.
+
+ \sa size(), open()
+*/
+
+bool QFile::at( int pos )
+{
+ if ( !isOpen() ) {
+#if defined(CHECK_STATE)
+ qWarning( "QFile::at: File is not open" );
+#endif
+ return FALSE;
+ }
+ bool ok;
+ if ( isRaw() ) { // raw file
+ pos = (int)LSEEK(fd, pos, SEEK_SET);
+ ok = pos != -1;
+ } else { // buffered file
+ ok = fseek(fh, pos, SEEK_SET) == 0;
+ }
+ if ( ok )
+ ioIndex = pos;
+#if defined(CHECK_RANGE)
+ else
+ qWarning( "QFile::at: Cannot set file position %d", pos );
+#endif
+ return ok;
+}
+
+/*!
+ Reads at most \e len bytes from the file into \e p and returns the
+ number of bytes actually read.
+
+ Returns -1 if a serious error occurred.
+
+ \warning We have experienced problems with some C libraries when a buffered
+ file is opened for both reading and writing. If a read operation takes place
+ immediately after a write operation, the read buffer contains garbage data.
+ Worse, the same garbage is written to the file. Calling flush() before
+ readBlock() solved this problem.
+
+ \sa writeBlock()
+*/
+
+int QFile::readBlock( char *p, uint len )
+{
+#if defined(CHECK_NULL)
+ if ( !p )
+ qWarning( "QFile::readBlock: Null pointer error" );
+#endif
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::readBlock: File not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QFile::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ int nread; // number of bytes read
+ if ( isRaw() ) { // raw file
+ nread = READ( fd, p, len );
+ if ( len && nread <= 0 ) {
+ nread = 0;
+ setStatus(IO_ReadError);
+ }
+ } else { // buffered file
+ nread = fread( p, 1, len, fh );
+ if ( (uint)nread != len ) {
+ if ( ferror( fh ) || nread==0 )
+ setStatus(IO_ReadError);
+ }
+ }
+ ioIndex += nread;
+ return nread;
+}
+
+/*! \overload int writeBlock( const QByteArray& data )
+*/
+
+/*! \reimp
+
+ Writes \e len bytes from \e p to the file and returns the number of
+ bytes actually written.
+
+ Returns -1 if a serious error occurred.
+
+ \warning When working with buffered files, data may not be written
+ to the file at once. Call flush() to make sure the data is really
+ written.
+
+ \sa readBlock()
+*/
+
+int QFile::writeBlock( const char *p, uint len )
+{
+#if defined(CHECK_NULL)
+ if ( p == 0 && len != 0 )
+ qWarning( "QFile::writeBlock: Null pointer error" );
+#endif
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "QFile::writeBlock: File not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "QFile::writeBlock: Write operation not permitted" );
+ return -1;
+ }
+#endif
+ int nwritten; // number of bytes written
+ if ( isRaw() ) // raw file
+ nwritten = WRITE( fd, p, len );
+ else // buffered file
+ nwritten = fwrite( p, 1, len, fh );
+ if ( nwritten != (int)len ) { // write error
+ if ( errno == ENOSPC ) // disk is full
+ setStatus( IO_ResourceError );
+ else
+ setStatus( IO_WriteError );
+ if ( isRaw() ) // recalc file position
+ ioIndex = (int)LSEEK( fd, 0, SEEK_CUR );
+ else
+ ioIndex = fseek( fh, 0, SEEK_CUR );
+ } else {
+ ioIndex += nwritten;
+ }
+ if ( ioIndex > length ) // update file length
+ length = ioIndex;
+ return nwritten;
+}
+
+/*!
+ Returns the file handle of the file.
+
+ This is a small positive integer, suitable for use with C library
+ functions such as fdopen() and fcntl(), as well as with QSocketNotifier.
+
+ If the file is not open or there is an error, handle() returns -1.
+
+ \sa QSocketNotifier
+*/
+
+int QFile::handle() const
+{
+ if ( !isOpen() )
+ return -1;
+ else if ( fh )
+ return FILENO( fh );
+ else
+ return fd;
+}
+
+/*!
+ Closes an open file.
+
+ The file is not closed if it was opened with an existing file handle.
+ If the existing file handle is a \c FILE*, the file is flushed.
+ If the existing file handle is an \c int file descriptor, nothing
+ is done to the file.
+
+ Some "write-behind" filesystems may report an unspecified error on
+ closing the file. These errors only indicate that something may
+ have gone wrong since the previous open(). In such a case status()
+ reports IO_UnspecifiedError after close(), otherwise IO_Ok.
+
+ \sa open(), flush()
+*/
+
+
+void QFile::close()
+{
+ bool ok = FALSE;
+ if ( isOpen() ) { // file is not open
+ if ( fh ) { // buffered file
+ if ( ext_f )
+ ok = fflush( fh ) != -1; // flush instead of closing
+ else
+ ok = fclose( fh ) != -1;
+ } else { // raw file
+ if ( ext_f )
+ ok = TRUE; // cannot close
+ else
+ ok = CLOSE( fd ) != -1;
+ }
+ init(); // restore internal state
+ }
+ if (!ok)
+ setStatus (IO_UnspecifiedError);
+
+ return;
+}
diff --git a/qtools/qfiledefs_p.h b/qtools/qfiledefs_p.h
new file mode 100644
index 0000000..4a1a154
--- /dev/null
+++ b/qtools/qfiledefs_p.h
@@ -0,0 +1,259 @@
+/****************************************************************************
+**
+**
+** Common macros and system include files for QFile, QFileInfo and QDir.
+**
+** Created : 930812
+**
+** Copyright (C) 1992-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 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 qfile.cpp, qfileinfo.cpp and qdir.cpp.
+// This header file may change from version to version without notice,
+// or even be removed.
+//
+//
+
+
+#if defined(_CC_MWERKS_)
+# include <stdlib.h>
+# include <stat.h>
+#elif !defined(_OS_MAC_)
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#if defined(_OS_UNIX_)
+# include <dirent.h>
+# include <unistd.h>
+#endif
+#if defined(_OS_MSDOS_) || defined(_OS_WIN32_) || defined(_OS_OS2_)
+# define _OS_FATFS_
+# if defined(__CYGWIN32__)
+# include <dirent.h>
+# include <unistd.h>
+# if !defined(_OS_UNIX_)
+# define _OS_UNIX_
+# endif
+# else
+# include <io.h>
+# if !defined(_CC_MWERKS_)
+# include <dos.h>
+# endif
+# include <direct.h>
+# endif
+#endif
+#include <limits.h>
+
+
+#if !defined(PATH_MAX)
+#if defined( MAXPATHLEN )
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+
+#undef STATBUF
+#undef STAT
+#undef STAT_REG
+#undef STAT_DIR
+#undef STAT_LNK
+#undef STAT_MASK
+#undef FILENO
+#undef OPEN
+#undef CLOSE
+#undef LSEEK
+#undef READ
+#undef WRITE
+#undef ACCESS
+#undef GETCWD
+#undef CHDIR
+#undef MKDIR
+#undef RMDIR
+#undef OPEN_RDONLY
+#undef OPEN_WRONLY
+#undef OPEN_CREAT
+#undef OPEN_TRUNC
+#undef OPEN_APPEND
+#undef OPEN_TEXT
+#undef OPEN_BINARY
+
+
+#if defined(_CC_MSVC_) || defined(_CC_SYM_)
+
+# define STATBUF struct _stat // non-ANSI defs
+# define STATBUF4TSTAT struct _stat // non-ANSI defs
+# define STAT ::_stat
+# define FSTAT ::_fstat
+# define STAT_REG _S_IFREG
+# define STAT_DIR _S_IFDIR
+# define STAT_MASK _S_IFMT
+# if defined(_S_IFLNK)
+# define STAT_LNK _S_IFLNK
+# endif
+# define FILENO _fileno
+# define OPEN ::_open
+# define CLOSE ::_close
+# define LSEEK ::_lseek
+# define READ ::_read
+# define WRITE ::_write
+# define ACCESS ::_access
+# define GETCWD ::_getcwd
+# define CHDIR ::_chdir
+# define MKDIR ::_mkdir
+# define RMDIR ::_rmdir
+# define OPEN_RDONLY _O_RDONLY
+# define OPEN_WRONLY _O_WRONLY
+# define OPEN_RDWR _O_RDWR
+# define OPEN_CREAT _O_CREAT
+# define OPEN_TRUNC _O_TRUNC
+# define OPEN_APPEND _O_APPEND
+# if defined(O_TEXT)
+# define OPEN_TEXT _O_TEXT
+# define OPEN_BINARY _O_BINARY
+# endif
+
+#elif defined(_CC_BOR_) && __BORLANDC__ >= 0x550
+
+# define STATBUF struct stat // non-ANSI defs
+# define STATBUF4TSTAT struct _stat // non-ANSI defs
+# define STAT ::stat
+# define FSTAT ::fstat
+# define STAT_REG _S_IFREG
+# define STAT_DIR _S_IFDIR
+# define STAT_MASK _S_IFMT
+# if defined(_S_IFLNK)
+# define STAT_LNK _S_IFLNK
+# endif
+# define FILENO _fileno
+# define OPEN ::open
+# define CLOSE ::_close
+# define LSEEK ::_lseek
+# define READ ::_read
+# define WRITE ::_write
+# define ACCESS ::_access
+# define GETCWD ::_getcwd
+# define CHDIR ::chdir
+# define MKDIR ::_mkdir
+# define RMDIR ::_rmdir
+# define OPEN_RDONLY _O_RDONLY
+# define OPEN_WRONLY _O_WRONLY
+# define OPEN_RDWR _O_RDWR
+# define OPEN_CREAT _O_CREAT
+# define OPEN_TRUNC _O_TRUNC
+# define OPEN_APPEND _O_APPEND
+# if defined(O_TEXT)
+# define OPEN_TEXT _O_TEXT
+# define OPEN_BINARY _O_BINARY
+# endif
+
+#else // all other systems
+
+# define STATBUF struct stat
+# define STATBUF4TSTAT struct stat
+# define STAT ::stat
+# define FSTAT ::fstat
+# define STAT_REG S_IFREG
+# define STAT_DIR S_IFDIR
+# define STAT_MASK S_IFMT
+# if defined(S_IFLNK)
+# define STAT_LNK S_IFLNK
+# endif
+# define FILENO fileno
+# define OPEN ::open
+# define CLOSE ::close
+# define LSEEK ::lseek
+# define READ ::read
+# define WRITE ::write
+# define ACCESS ::access
+# if defined(_OS_OS2EMX_)
+# define GETCWD ::_getcwd2
+# define CHDIR ::_chdir2
+# else
+# define GETCWD ::getcwd
+# define CHDIR ::chdir
+# endif
+# define MKDIR ::mkdir
+# define RMDIR ::rmdir
+# define OPEN_RDONLY O_RDONLY
+# define OPEN_WRONLY O_WRONLY
+# define OPEN_RDWR O_RDWR
+# define OPEN_CREAT O_CREAT
+# define OPEN_TRUNC O_TRUNC
+# define OPEN_APPEND O_APPEND
+# if defined(O_TEXT)
+# define OPEN_TEXT O_TEXT
+# define OPEN_BINARY O_BINARY
+# endif
+#endif
+
+#if defined(_CC_MWERKS_)
+#undef mkdir
+#undef MKDIR
+#define MKDIR _mkdir
+#undef rmdir
+#undef RMDIR
+#define RMDIR _rmdir
+#endif
+
+
+#if defined(_OS_FATFS_)
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+#if defined(_OS_MAC_)
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+struct QFileInfoCache
+{
+ STATBUF st;
+ bool isSymLink;
+};
+
+#endif
diff --git a/qtools/qfileinfo.cpp b/qtools/qfileinfo.cpp
new file mode 100644
index 0000000..5053b76
--- /dev/null
+++ b/qtools/qfileinfo.cpp
@@ -0,0 +1,458 @@
+/****************************************************************************
+**
+**
+** Implementation of QFileInfo class
+**
+** Created : 950628
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qglobal.h"
+
+#include "qfileinfo.h"
+#include "qfiledefs_p.h"
+#include "qdatetime.h"
+#include "qdir.h"
+
+extern bool qt_file_access( const QString& fn, int t );
+
+// NOT REVISED
+/*!
+ \class QFileInfo qfileinfo.h
+ \brief The QFileInfo class provides system-independent file information.
+
+ \ingroup io
+
+ QFileInfo provides information about a file's name and position (path) in
+ the file system, its access rights and whether it is a directory or a
+ symbolic link. Its size and last modified/read times are also available.
+
+ To speed up performance QFileInfo caches information about the file. Since
+ files can be changed by other users or programs, or even by other parts of
+ the same program there is a function that refreshes the file information;
+ refresh(). If you would rather like a QFileInfo to access the file system
+ every time you request information from it, you can call the function
+ setCaching( FALSE ).
+
+ A QFileInfo can point to a file using either a relative or an absolute
+ file path. Absolute file paths begin with the directory separator
+ ('/') or a drive specification (not applicable to UNIX).
+ Relative file names begin with a directory name or a file name and specify
+ a path relative to the current directory. An example of
+ an absolute path is the string "/tmp/quartz". A relative path might look like
+ "src/fatlib". You can use the function isRelative() to check if a QFileInfo
+ is using a relative or an absolute file path. You can call the function
+ convertToAbs() to convert a relative QFileInfo to an absolute one.
+
+ If you need to read and traverse directories, see the QDir class.
+*/
+
+
+/*!
+ Constructs a new empty QFileInfo.
+*/
+
+QFileInfo::QFileInfo()
+{
+ fic = 0;
+ cache = TRUE;
+}
+
+/*!
+ Constructs a new QFileInfo that gives information about the given file.
+ The string given can be an absolute or a relative file path.
+
+ \sa bool setFile(QString ), isRelative(), QDir::setCurrent(),
+ QDir::isRelativePath()
+*/
+
+QFileInfo::QFileInfo( const QString &file )
+{
+ fn = file;
+ slashify( fn );
+ fic = 0;
+ cache = TRUE;
+}
+
+/*!
+ Constructs a new QFileInfo that gives information about \e file.
+
+ If the file has a relative path, the QFileInfo will also have one.
+
+ \sa isRelative()
+*/
+
+QFileInfo::QFileInfo( const QFile &file )
+{
+ fn = file.name();
+ slashify( fn );
+ fic = 0;
+ cache = TRUE;
+}
+
+/*!
+ Constructs a new QFileInfo that gives information about the file
+ named \e fileName in the directory \e d.
+
+ If the directory has a relative path, the QFileInfo will also have one.
+
+ \sa isRelative()
+*/
+#ifndef QT_NO_DIR
+QFileInfo::QFileInfo( const QDir &d, const QString &fileName )
+{
+ fn = d.filePath( fileName );
+ slashify( fn );
+ fic = 0;
+ cache = TRUE;
+}
+#endif
+/*!
+ Constructs a new QFileInfo that is a copy of \e fi.
+*/
+
+QFileInfo::QFileInfo( const QFileInfo &fi )
+{
+ fn = fi.fn;
+ if ( fi.fic ) {
+ fic = new QFileInfoCache;
+ *fic = *fi.fic;
+ } else {
+ fic = 0;
+ }
+ cache = fi.cache;
+}
+
+/*!
+ Destructs the QFileInfo.
+*/
+
+QFileInfo::~QFileInfo()
+{
+ delete fic;
+}
+
+
+/*!
+ Makes a copy of \e fi and assigns it to this QFileInfo.
+*/
+
+QFileInfo &QFileInfo::operator=( const QFileInfo &fi )
+{
+ fn = fi.fn;
+ if ( !fi.fic ) {
+ delete fic;
+ fic = 0;
+ } else {
+ if ( !fic ) {
+ fic = new QFileInfoCache;
+ CHECK_PTR( fic );
+ }
+ *fic = *fi.fic;
+ }
+ cache = fi.cache;
+ return *this;
+}
+
+
+/*!
+ Sets the file to obtain information about.
+
+ The string given can be an absolute or a relative file path. Absolute file
+ paths begin with the directory separator (e.g. '/' under UNIX) or a drive
+ specification (not applicable to UNIX). Relative file names begin with a
+ directory name or a file name and specify a path relative to the current
+ directory.
+
+ Example:
+ \code
+ #include <qfileinfo.h>
+ #include <qdir.h>
+
+ void test()
+ {
+ QString absolute = "/liver/aorta";
+ QString relative = "liver/aorta";
+ QFileInfo fi1( absolute );
+ QFileInfo fi2( relative );
+
+ QDir::setCurrent( QDir::rootDirPath() );
+ // fi1 and fi2 now point to the same file
+
+ QDir::setCurrent( "/tmp" );
+ // fi1 now points to "/liver/aorta",
+ // while fi2 points to "/tmp/liver/aorta"
+ }
+ \endcode
+
+ \sa isRelative(), QDir::setCurrent(), QDir::isRelativePath()
+*/
+
+void QFileInfo::setFile( const QString &file )
+{
+ fn = file;
+ slashify( fn );
+ delete fic;
+ fic = 0;
+}
+
+/*!
+ Sets the file to obtain information about.
+
+ If the file has a relative path, the QFileInfo will also have one.
+
+ \sa isRelative()
+*/
+
+void QFileInfo::setFile( const QFile &file )
+{
+ fn = file.name();
+ slashify( fn );
+ delete fic;
+ fic = 0;
+}
+
+/*!
+ Sets the file to obtains information about to \e fileName in the
+ directory \e d.
+
+ If the directory has a relative path, the QFileInfo will also have one.
+
+ \sa isRelative()
+*/
+#ifndef QT_NO_DIR
+void QFileInfo::setFile( const QDir &d, const QString &fileName )
+{
+ fn = d.filePath( fileName );
+ slashify( fn );
+ delete fic;
+ fic = 0;
+}
+#endif
+
+/*!
+ Returns TRUE if the file pointed to exists, otherwise FALSE.
+*/
+
+bool QFileInfo::exists() const
+{
+ return qt_file_access( fn, F_OK );
+}
+
+/*!
+ Refresh the information about the file, i.e. read in information from the
+ file system the next time a cached property is fetched.
+
+ \sa setCaching()
+*/
+
+void QFileInfo::refresh() const
+{
+ QFileInfo *that = (QFileInfo*)this; // Mutable function
+ delete that->fic;
+ that->fic = 0;
+}
+
+/*!
+ \fn bool QFileInfo::caching() const
+ Returns TRUE if caching is enabled.
+ \sa setCaching(), refresh()
+*/
+
+/*!
+ Enables caching of file information if \e enable is TRUE, or disables it
+ if \e enable is FALSE.
+
+ When caching is enabled, QFileInfo reads the file information the first
+ time
+
+ Caching is enabled by default.
+
+ \sa refresh(), caching()
+*/
+
+void QFileInfo::setCaching( bool enable )
+{
+ if ( cache == enable )
+ return;
+ cache = enable;
+ if ( cache ) {
+ delete fic;
+ fic = 0;
+ }
+}
+
+
+/*!
+ Returns the name, i.e. the file name including the path (which can be
+ absolute or relative).
+
+ \sa isRelative(), absFilePath()
+*/
+
+QString QFileInfo::filePath() const
+{
+ return fn;
+}
+
+/*!
+ Returns the base name of the file.
+
+ The base name consists of all characters in the file name up to (but not
+ including) the first '.' character. The path is not included.
+
+ Example:
+ \code
+ QFileInfo fi( "/tmp/abdomen.lower" );
+ QString base = fi.baseName(); // base = "abdomen"
+ \endcode
+
+ \sa fileName(), extension()
+*/
+
+QString QFileInfo::baseName() const
+{
+ QString tmp = fileName();
+ int pos = tmp.find( '.' );
+ if ( pos == -1 )
+ return tmp;
+ else
+ return tmp.left( pos );
+}
+
+/*!
+ Returns the extension name of the file.
+
+ If \a complete is TRUE (the default), extension() returns the string
+ of all characters in the file name after (but not including) the
+ first '.' character. For a file named "archive.tar.gz" this
+ returns "tar.gz".
+
+ If \a complete is FALSE, extension() returns the string of all
+ characters in the file name after (but not including) the last '.'
+ character. For a file named "archive.tar.gz" this returns "gz".
+
+ Example:
+ \code
+ QFileInfo fi( "lex.yy.c" );
+ QString ext = fi.extension(); // ext = "yy.c"
+ QString ext = fi.extension( FALSE ); // ext = "c"
+ \endcode
+
+ \sa fileName(), baseName()
+
+*/
+
+QString QFileInfo::extension( bool complete ) const
+{
+ QString s = fileName();
+ int pos = complete ? s.find( '.' ) : s.findRev( '.' );
+ if ( pos < 0 )
+ return QString::fromLatin1( "" );
+ else
+ return s.right( s.length() - pos - 1 );
+}
+
+/*!
+ Returns the directory path of the file.
+
+ If the QFileInfo is relative and \e absPath is FALSE, the QDir will be
+ relative, otherwise it will be absolute.
+
+ \sa dirPath(), filePath(), fileName(), isRelative()
+*/
+#ifndef QT_NO_DIR
+QDir QFileInfo::dir( bool absPath ) const
+{
+ return QDir( dirPath(absPath) );
+}
+#endif
+
+
+/*!
+ Returns TRUE if the file is readable.
+ \sa isWritable(), isExecutable(), permission()
+*/
+
+bool QFileInfo::isReadable() const
+{
+ return qt_file_access( fn, R_OK );
+}
+
+/*!
+ Returns TRUE if the file is writable.
+ \sa isReadable(), isExecutable(), permission()
+*/
+
+bool QFileInfo::isWritable() const
+{
+ return qt_file_access( fn, W_OK );
+}
+
+/*!
+ Returns TRUE if the file is executable.
+ \sa isReadable(), isWritable(), permission()
+*/
+
+bool QFileInfo::isExecutable() const
+{
+ return qt_file_access( fn, X_OK );
+}
+
+
+/*!
+ Returns TRUE if the file path name is relative to the current directory,
+ FALSE if the path is absolute (e.g. under UNIX a path is relative if it
+ does not start with a '/').
+
+ According to Einstein this function should always return TRUE.
+*/
+#ifndef QT_NO_DIR
+bool QFileInfo::isRelative() const
+{
+ return QDir::isRelativePath( fn );
+}
+
+/*!
+ Converts the file path name to an absolute path.
+
+ If it is already absolute nothing is done.
+
+ \sa filePath(), isRelative()
+*/
+
+bool QFileInfo::convertToAbs()
+{
+ if ( isRelative() )
+ fn = absFilePath();
+ return QDir::isRelativePath( fn );
+}
+#endif
diff --git a/qtools/qfileinfo.h b/qtools/qfileinfo.h
new file mode 100644
index 0000000..76ef8c2
--- /dev/null
+++ b/qtools/qfileinfo.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+**
+** Definition of QFileInfo class
+**
+** Created : 950628
+**
+** Copyright (C) 1992-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 QFILEINFO_H
+#define QFILEINFO_H
+
+#ifndef QT_H
+#include "qfile.h"
+#include "qdatetime.h"
+#endif // QT_H
+
+
+class QDir;
+struct QFileInfoCache;
+
+
+class Q_EXPORT QFileInfo // file information class
+{
+public:
+ enum PermissionSpec {
+ ReadUser = 0400, WriteUser = 0200, ExeUser = 0100,
+ ReadGroup = 0040, WriteGroup = 0020, ExeGroup = 0010,
+ ReadOther = 0004, WriteOther = 0002, ExeOther = 0001 };
+
+ QFileInfo();
+ QFileInfo( const QString &file );
+ QFileInfo( const QFile & );
+#ifndef QT_NO_DIR
+ QFileInfo( const QDir &, const QString &fileName );
+#endif
+ QFileInfo( const QFileInfo & );
+ ~QFileInfo();
+
+ QFileInfo &operator=( const QFileInfo & );
+
+ void setFile( const QString &file );
+ void setFile( const QFile & );
+#ifndef QT_NO_DIR
+ void setFile( const QDir &, const QString &fileName );
+#endif
+ bool exists() const;
+ void refresh() const;
+ bool caching() const;
+ void setCaching( bool );
+
+ QString filePath() const;
+ QString fileName() const;
+#ifndef QT_NO_DIR //###
+ QString absFilePath() const;
+#endif
+ QString baseName() const;
+ QString extension( bool complete = TRUE ) const;
+
+#ifndef QT_NO_DIR //###
+ QString dirPath( bool absPath = FALSE ) const;
+#endif
+#ifndef QT_NO_DIR
+ QDir dir( bool absPath = FALSE ) const;
+#endif
+ bool isReadable() const;
+ bool isWritable() const;
+ bool isExecutable() const;
+
+#ifndef QT_NO_DIR //###
+ bool isRelative() const;
+ bool convertToAbs();
+#endif
+
+ bool isFile() const;
+ bool isDir() const;
+ bool isSymLink() const;
+
+ QString readLink() const;
+
+ QString owner() const;
+ uint ownerId() const;
+ QString group() const;
+ uint groupId() const;
+
+ bool permission( int permissionSpec ) const;
+
+ uint size() const;
+
+ QDateTime lastModified() const;
+ QDateTime lastRead() const;
+
+private:
+ void doStat() const;
+ static void slashify( QString & );
+ static void makeAbs( QString & );
+
+ QString fn;
+ QFileInfoCache *fic;
+ bool cache;
+};
+
+
+inline bool QFileInfo::caching() const
+{
+ return cache;
+}
+
+
+#endif // QFILEINFO_H
diff --git a/qtools/qfileinfo_unix.cpp b/qtools/qfileinfo_unix.cpp
new file mode 100644
index 0000000..5a8fe04
--- /dev/null
+++ b/qtools/qfileinfo_unix.cpp
@@ -0,0 +1,425 @@
+/****************************************************************************
+**
+**
+** Implementation of QFileInfo class
+**
+** Created : 950628
+**
+** Copyright (C) 1992-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 for Unix/X11 or for Qt/Embedded 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 "qglobal.h"
+
+#if defined(_OS_SUN_)
+#define readlink _qt_hide_readlink
+#endif
+
+#include <pwd.h>
+#include <grp.h>
+
+#include "qfileinfo.h"
+#include "qfiledefs_p.h"
+#include "qdatetime.h"
+#include "qdir.h"
+
+#if defined(_OS_SUN_)
+#undef readlink
+extern "C" int readlink( const char *, void *, uint );
+#endif
+
+
+void QFileInfo::slashify( QString& )
+{
+ return;
+}
+
+
+void QFileInfo::makeAbs( QString & )
+{
+ return;
+}
+
+extern bool qt_file_access( const QString& fn, int t );
+
+/*!
+ Returns TRUE if we are pointing to a real file.
+ \sa isDir(), isSymLink()
+*/
+bool QFileInfo::isFile() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? (fic->st.st_mode & STAT_MASK) == STAT_REG : FALSE;
+}
+
+/*!
+ Returns TRUE if we are pointing to a directory or a symbolic link to
+ a directory.
+ \sa isFile(), isSymLink()
+*/
+
+bool QFileInfo::isDir() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? (fic->st.st_mode & STAT_MASK) == STAT_DIR : FALSE;
+}
+
+/*!
+ Returns TRUE if we are pointing to a symbolic link.
+ \sa isFile(), isDir(), readLink()
+*/
+
+bool QFileInfo::isSymLink() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? fic->isSymLink : FALSE;
+}
+
+
+/*!
+ Returns the name a symlink points to, or a null QString if the
+ object does not refer to a symbolic link.
+
+ This name may not represent an existing file; it is only a string.
+ QFileInfo::exists() returns TRUE if the symlink points to an
+ existing file.
+
+ \sa exists(), isSymLink(), isDir(), isFile()
+*/
+
+QString QFileInfo::readLink() const
+{
+ QString r;
+
+#if defined(_OS_UNIX_) && !defined(_OS_OS2EMX_)
+ char s[PATH_MAX+1];
+ if ( !isSymLink() )
+ return QString();
+ int len = readlink( QFile::encodeName(fn).data(), s, PATH_MAX );
+ if ( len >= 0 ) {
+ s[len] = '\0';
+ r = QFile::decodeName(s);
+ }
+#endif
+
+ return r;
+}
+
+static const uint nobodyID = (uint) -2;
+
+/*!
+ Returns the owner of the file.
+
+ On systems where files do not have owners this function returns 0.
+
+ Note that this function can be time-consuming under UNIX. (in the order
+ of milliseconds on a 486 DX2/66 running Linux).
+
+ \sa ownerId(), group(), groupId()
+*/
+
+QString QFileInfo::owner() const
+{
+ passwd *pw = getpwuid( ownerId() );
+ if ( pw )
+ return QFile::decodeName( pw->pw_name );
+ return QString::null;
+}
+
+/*!
+ Returns the id of the owner of the file.
+
+ On systems where files do not have owners this function returns ((uint) -2).
+
+ \sa owner(), group(), groupId()
+*/
+
+uint QFileInfo::ownerId() const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ return fic->st.st_uid;
+ return nobodyID;
+}
+
+/*!
+ Returns the group the file belongs to.
+
+ On systems where files do not have groups this function always
+ returns 0.
+
+ Note that this function can be time-consuming under UNIX (in the order of
+ milliseconds on a 486 DX2/66 running Linux).
+
+ \sa groupId(), owner(), ownerId()
+*/
+
+QString QFileInfo::group() const
+{
+ struct group *gr = getgrgid( groupId() );
+ if ( gr )
+ return QFile::decodeName( gr->gr_name );
+ return QString::null;
+}
+
+/*!
+ Returns the id of the group the file belongs to.
+
+ On systems where files do not have groups this function always
+ returns ((uind) -2).
+
+ \sa group(), owner(), ownerId()
+*/
+
+uint QFileInfo::groupId() const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ return fic->st.st_gid;
+ return nobodyID;
+}
+
+
+/*!
+ \fn bool QFileInfo::permission( int permissionSpec ) const
+
+ Tests for file permissions. The \e permissionSpec argument can be several
+ flags of type PermissionSpec or'ed together to check for permission
+ combinations.
+
+ On systems where files do not have permissions this function always
+ returns TRUE.
+
+ Example:
+ \code
+ QFileInfo fi( "/tmp/tonsils" );
+ if ( fi.permission( QFileInfo::WriteUser | QFileInfo::ReadGroup ) )
+ qWarning( "Tonsils can be changed by me, and the group can read them.");
+ if ( fi.permission( QFileInfo::WriteGroup | QFileInfo::WriteOther ) )
+ qWarning( "Danger! Tonsils can be changed by the group or others!" );
+ \endcode
+
+ \sa isReadable(), isWritable(), isExecutable()
+*/
+
+bool QFileInfo::permission( int permissionSpec ) const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic ) {
+ uint mask = 0;
+ if ( permissionSpec & ReadUser)
+ mask |= S_IRUSR;
+ if ( permissionSpec & WriteUser)
+ mask |= S_IWUSR;
+ if ( permissionSpec & ExeUser)
+ mask |= S_IXUSR;
+ if ( permissionSpec & ReadGroup)
+ mask |= S_IRGRP;
+ if ( permissionSpec & WriteGroup)
+ mask |= S_IWGRP;
+ if ( permissionSpec & ExeGroup)
+ mask |= S_IXGRP;
+ if ( permissionSpec & ReadOther)
+ mask |= S_IROTH;
+ if ( permissionSpec & WriteOther)
+ mask |= S_IWOTH;
+ if ( permissionSpec & ExeOther)
+ mask |= S_IXOTH;
+ if ( mask ) {
+ return (fic->st.st_mode & mask) == mask;
+ } else {
+#if defined(CHECK_NULL)
+ qWarning( "QFileInfo::permission: permissionSpec is 0" );
+#endif
+ return TRUE;
+ }
+ } else {
+ return FALSE;
+ }
+}
+
+/*!
+ Returns the file size in bytes, or 0 if the file does not exist if the size
+ cannot be fetched.
+*/
+
+uint QFileInfo::size() const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ return (uint)fic->st.st_size;
+ else
+ return 0;
+}
+
+
+/*!
+ Returns the date and time when the file was last modified.
+ \sa lastRead()
+*/
+
+QDateTime QFileInfo::lastModified() const
+{
+ QDateTime dt;
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ dt.setTime_t( fic->st.st_mtime );
+ return dt;
+}
+
+/*!
+ Returns the date and time when the file was last read (accessed).
+
+ On systems that do not support last read times, the modification time is
+ returned.
+
+ \sa lastModified()
+*/
+
+QDateTime QFileInfo::lastRead() const
+{
+ QDateTime dt;
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ dt.setTime_t( fic->st.st_atime );
+ return dt;
+}
+
+
+void QFileInfo::doStat() const
+{
+ QFileInfo *that = ((QFileInfo*)this); // mutable function
+ if ( !that->fic )
+ that->fic = new QFileInfoCache;
+ STATBUF *b = &that->fic->st;
+ that->fic->isSymLink = FALSE;
+
+#if defined(_OS_UNIX_) && defined(S_IFLNK)
+ if ( ::lstat(QFile::encodeName(fn),b) == 0 ) {
+ if ( S_ISLNK( b->st_mode ) )
+ that->fic->isSymLink = TRUE;
+ else
+ return;
+ }
+#endif
+ int r;
+
+ r = STAT( QFile::encodeName(fn), b );
+
+ if ( r != 0 ) {
+ delete that->fic;
+ that->fic = 0;
+ }
+}
+
+/*!
+ Returns the directory path of the file.
+
+ If \e absPath is TRUE an absolute path is always returned.
+
+ \sa dir(), filePath(), fileName(), isRelative()
+*/
+#ifndef QT_NO_DIR
+QString QFileInfo::dirPath( bool absPath ) const
+{
+ QString s;
+ if ( absPath )
+ s = absFilePath();
+ else
+ s = fn;
+ int pos = s.findRev( '/' );
+ if ( pos == -1 ) {
+ return QString::fromLatin1(".");
+ } else {
+ if ( pos == 0 )
+ return QString::fromLatin1( "/" );
+ return s.left( pos );
+ }
+}
+#endif
+/*!
+ Returns the name of the file, the file path is not included.
+
+ Example:
+ \code
+ QFileInfo fi( "/tmp/abdomen.lower" );
+ QString name = fi.fileName(); // name = "abdomen.lower"
+ \endcode
+
+ \sa isRelative(), filePath(), baseName(), extension()
+*/
+
+QString QFileInfo::fileName() const
+{
+ int p = fn.findRev( '/' );
+ if ( p == -1 ) {
+ return fn;
+ } else {
+ return fn.mid(p+1);
+ }
+}
+
+/*!
+ Returns the absolute path name.
+
+ The absolute path name is the file name including the absolute path. If
+ the QFileInfo is absolute (i.e. not relative) this function will return
+ the same string as filePath().
+
+ Note that this function can be time-consuming under UNIX. (in the order
+ of milliseconds on a 486 DX2/66 running Linux).
+
+ \sa isRelative(), filePath()
+*/
+#ifndef QT_NO_DIR
+QString QFileInfo::absFilePath() const
+{
+ if ( QDir::isRelativePath(fn) ) {
+ QString tmp = QDir::currentDirPath();
+ tmp += '/';
+ tmp += fn;
+ makeAbs( tmp );
+ return QDir::cleanDirPath( tmp );
+ } else {
+ QString tmp = fn;
+ makeAbs( tmp );
+ return QDir::cleanDirPath( tmp );
+ }
+
+}
+#endif
diff --git a/qtools/qfileinfo_win32.cpp b/qtools/qfileinfo_win32.cpp
new file mode 100644
index 0000000..47b8491
--- /dev/null
+++ b/qtools/qfileinfo_win32.cpp
@@ -0,0 +1,334 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2000 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ * Based on qfileinfo_unix.cpp
+ *
+ * Copyright (C) 1992-2000 Trolltech AS.
+ */
+
+#include "qglobal.h"
+
+#include "qfileinfo.h"
+#include "qfiledefs_p.h"
+#include "qdatetime.h"
+#include "qdir.h"
+
+void QFileInfo::slashify( QString& n )
+{
+ for ( int i=0; i<(int)n.length(); i++ )
+ {
+ if ( n[i] == '\\' )
+ n[i] = '/';
+ }
+}
+
+void QFileInfo::makeAbs( QString & )
+{
+ // TODO: what to do here?
+ return;
+}
+
+extern bool qt_file_access( const QString& fn, int t );
+
+/*!
+ Returns TRUE if we are pointing to a real file.
+ \sa isDir(), isSymLink()
+*/
+bool QFileInfo::isFile() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? (fic->st.st_mode & STAT_MASK) == STAT_REG : FALSE;
+}
+
+/*!
+ Returns TRUE if we are pointing to a directory or a symbolic link to
+ a directory.
+ \sa isFile(), isSymLink()
+*/
+
+bool QFileInfo::isDir() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? (fic->st.st_mode & STAT_MASK) == STAT_DIR : FALSE;
+}
+
+/*!
+ Returns TRUE if we are pointing to a symbolic link.
+ \sa isFile(), isDir(), readLink()
+*/
+
+bool QFileInfo::isSymLink() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? fic->isSymLink : FALSE;
+}
+
+
+/*!
+ Returns the name a symlink points to, or a null QString if the
+ object does not refer to a symbolic link.
+
+ This name may not represent an existing file; it is only a string.
+ QFileInfo::exists() returns TRUE if the symlink points to an
+ existing file.
+
+ \sa exists(), isSymLink(), isDir(), isFile()
+*/
+
+QString QFileInfo::readLink() const
+{
+ QString r;
+ return r;
+}
+
+static const uint nobodyID = (uint) -2;
+
+/*!
+ Returns the owner of the file.
+
+ On systems where files do not have owners this function returns
+ a null string.
+
+ Note that this function can be time-consuming under UNIX. (in the order
+ of milliseconds on a 486 DX2/66 running Linux).
+
+ \sa ownerId(), group(), groupId()
+*/
+
+QString QFileInfo::owner() const
+{
+ return QString::null;
+}
+
+/*!
+ Returns the id of the owner of the file.
+
+ On systems where files do not have owners this function returns ((uint) -2).
+
+ \sa owner(), group(), groupId()
+*/
+
+uint QFileInfo::ownerId() const
+{
+ return (uint)-2;
+}
+
+/*!
+ Returns the group the file belongs to.
+
+ On systems where files do not have groups this function always
+ returns 0.
+
+ Note that this function can be time-consuming under UNIX (in the order of
+ milliseconds on a 486 DX2/66 running Linux).
+
+ \sa groupId(), owner(), ownerId()
+*/
+
+QString QFileInfo::group() const
+{
+ return QString::null;
+}
+
+/*!
+ Returns the id of the group the file belongs to.
+
+ On systems where files do not have groups this function always
+ returns ((uind) -2).
+
+ \sa group(), owner(), ownerId()
+*/
+
+uint QFileInfo::groupId() const
+{
+ return (uint)-2;
+}
+
+
+/*!
+ \fn bool QFileInfo::permission( int permissionSpec ) const
+
+ Tests for file permissions. The \e permissionSpec argument can be several
+ flags of type PermissionSpec or'ed together to check for permission
+ combinations.
+
+ On systems where files do not have permissions this function always
+ returns TRUE.
+
+ Example:
+ \code
+ QFileInfo fi( "/tmp/tonsils" );
+ if ( fi.permission( QFileInfo::WriteUser | QFileInfo::ReadGroup ) )
+ qWarning( "Tonsils can be changed by me, and the group can read them.");
+ if ( fi.permission( QFileInfo::WriteGroup | QFileInfo::WriteOther ) )
+ qWarning( "Danger! Tonsils can be changed by the group or others!" );
+ \endcode
+
+ \sa isReadable(), isWritable(), isExecutable()
+*/
+
+bool QFileInfo::permission( int permissionSpec ) const
+{
+ return TRUE;
+}
+
+/*!
+ Returns the file size in bytes, or 0 if the file does not exist if the size
+ cannot be fetched.
+*/
+
+uint QFileInfo::size() const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ return (uint)fic->st.st_size;
+ else
+ return 0;
+}
+
+
+/*!
+ Returns the date and time when the file was last modified.
+ \sa lastRead()
+*/
+
+QDateTime QFileInfo::lastModified() const
+{
+ QDateTime dt;
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ dt.setTime_t( fic->st.st_mtime );
+ return dt;
+}
+
+/*!
+ Returns the date and time when the file was last read (accessed).
+
+ On systems that do not support last read times, the modification time is
+ returned.
+
+ \sa lastModified()
+*/
+
+QDateTime QFileInfo::lastRead() const
+{
+ QDateTime dt;
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ dt.setTime_t( fic->st.st_atime );
+ return dt;
+}
+
+
+void QFileInfo::doStat() const
+{
+ QFileInfo *that = ((QFileInfo*)this); // mutable function
+ if ( !that->fic )
+ that->fic = new QFileInfoCache;
+ STATBUF *b = &that->fic->st;
+ that->fic->isSymLink = FALSE;
+
+ int r;
+
+ r = STAT( QFile::encodeName(fn), b );
+
+ if ( r != 0 ) {
+ delete that->fic;
+ that->fic = 0;
+ }
+}
+
+/*!
+ Returns the directory path of the file.
+
+ If \e absPath is TRUE an absolute path is always returned.
+
+ \sa dir(), filePath(), fileName(), isRelative()
+*/
+#ifndef QT_NO_DIR
+QString QFileInfo::dirPath( bool absPath ) const
+{
+ QString s;
+ if ( absPath )
+ s = absFilePath();
+ else
+ s = fn;
+ int pos = s.findRev( '/' );
+ if ( pos == -1 ) {
+ return QString::fromLatin1(".");
+ } else {
+ if ( pos == 0 )
+ return QString::fromLatin1( "/" );
+ return s.left( pos );
+ }
+}
+#endif
+/*!
+ Returns the name of the file, the file path is not included.
+
+ Example:
+ \code
+ QFileInfo fi( "/tmp/abdomen.lower" );
+ QString name = fi.fileName(); // name = "abdomen.lower"
+ \endcode
+
+ \sa isRelative(), filePath(), baseName(), extension()
+*/
+
+QString QFileInfo::fileName() const
+{
+ int p = fn.findRev( '/' );
+ if ( p == -1 ) {
+ return fn;
+ } else {
+ return fn.mid(p+1);
+ }
+}
+
+/*!
+ Returns the absolute path name.
+
+ The absolute path name is the file name including the absolute path. If
+ the QFileInfo is absolute (i.e. not relative) this function will return
+ the same string as filePath().
+
+ Note that this function can be time-consuming under UNIX. (in the order
+ of milliseconds on a 486 DX2/66 running Linux).
+
+ \sa isRelative(), filePath()
+*/
+#ifndef QT_NO_DIR
+QString QFileInfo::absFilePath() const
+{
+ if ( QDir::isRelativePath(fn) ) {
+ QString tmp = QDir::currentDirPath();
+ tmp += '/';
+ tmp += fn;
+ makeAbs( tmp );
+ return QDir::cleanDirPath( tmp );
+ } else {
+ QString tmp = fn;
+ makeAbs( tmp );
+ return QDir::cleanDirPath( tmp );
+ }
+
+}
+#endif
diff --git a/qtools/qgarray.cpp b/qtools/qgarray.cpp
new file mode 100644
index 0000000..efc9de0
--- /dev/null
+++ b/qtools/qgarray.cpp
@@ -0,0 +1,747 @@
+/****************************************************************************
+**
+**
+** Implementation of QGArray class
+**
+** Created : 930906
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#define QGARRAY_CPP
+#include "qgarray.h"
+#include "qstring.h"
+#include <stdlib.h>
+
+#define USE_MALLOC // comment to use new/delete
+
+#undef NEW
+#undef DELETE
+
+#if defined(USE_MALLOC)
+#define NEW(type,size) ((type*)malloc(size*sizeof(type)))
+#define DELETE(array) (free((char*)array))
+#else
+#define NEW(type,size) (new type[size])
+#define DELETE(array) (delete[] array)
+#define DONT_USE_REALLOC // comment to use realloc()
+#endif
+
+
+// NOT REVISED
+/*!
+ \class QShared qshared.h
+ \brief The QShared struct is internally used for implementing shared classes.
+
+ It only contains a reference count and member functions to increment and
+ decrement it.
+
+ Shared classes normally have internal classes that inherit QShared and
+ add the shared data.
+
+ \sa \link shclass.html Shared Classes\endlink
+*/
+
+
+/*!
+ \class QGArray qgarray.h
+ \brief The QGArray class is an internal class for implementing the QArray class.
+
+ QGArray is a strictly internal class that acts as base class for the
+ QArray template array.
+
+ It contains an array of bytes and has no notion of an array element.
+*/
+
+
+/*!
+ \internal
+ Constructs a null array.
+*/
+
+QGArray::QGArray()
+{
+ shd = newData();
+ CHECK_PTR( shd );
+}
+
+/*!
+ \internal
+ Dummy constructor; does not allocate any data.
+
+ This constructor does not initialize any array data so subclasses
+ must do it. The intention is to make the code more efficient.
+*/
+
+QGArray::QGArray( int, int )
+{
+}
+
+/*!
+ \internal
+ Constructs an array with room for \e size bytes.
+*/
+
+QGArray::QGArray( int size )
+{
+ if ( size < 0 ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QGArray: Cannot allocate array with negative length" );
+#endif
+ size = 0;
+ }
+ shd = newData();
+ CHECK_PTR( shd );
+ if ( size == 0 ) // zero length
+ return;
+ shd->data = NEW(char,size);
+ CHECK_PTR( shd->data );
+ shd->len = size;
+}
+
+/*!
+ \internal
+ Constructs a shallow copy of \e a.
+*/
+
+QGArray::QGArray( const QGArray &a )
+{
+ shd = a.shd;
+ shd->ref();
+}
+
+/*!
+ \internal
+ Dereferences the array data and deletes it if this was the last
+ reference.
+*/
+
+QGArray::~QGArray()
+{
+ if ( shd && shd->deref() ) { // delete when last reference
+ if ( shd->data ) // is lost
+ DELETE(shd->data);
+ deleteData( shd );
+ }
+}
+
+
+/*!
+ \fn QGArray &QGArray::operator=( const QGArray &a )
+ \internal
+ Assigns a shallow copy of \e a to this array and returns a reference to
+ this array. Equivalent to assign().
+*/
+
+/*!
+ \fn void QGArray::detach()
+ \internal
+ Detaches this array from shared array data.
+*/
+
+/*!
+ \fn char *QGArray::data() const
+ \internal
+ Returns a pointer to the actual array data.
+*/
+
+/*!
+ \fn uint QGArray::nrefs() const
+ \internal
+ Returns the reference count.
+*/
+
+/*!
+ \fn uint QGArray::size() const
+ \internal
+ Returns the size of the array, in bytes.
+*/
+
+
+/*!
+ \internal
+ Returns TRUE if this array is equal to \e a, otherwise FALSE.
+ The comparison is bitwise, of course.
+*/
+
+bool QGArray::isEqual( const QGArray &a ) const
+{
+ if ( size() != a.size() ) // different size
+ return FALSE;
+ if ( data() == a.data() ) // has same data
+ return TRUE;
+ return (size() ? memcmp( data(), a.data(), size() ) : 0) == 0;
+}
+
+
+/*!
+ \internal
+ Resizes the array to \e newsize bytes.
+*/
+
+bool QGArray::resize( uint newsize )
+{
+ if ( newsize == shd->len ) // nothing to do
+ return TRUE;
+ if ( newsize == 0 ) { // remove array
+ duplicate( 0, 0 );
+ return TRUE;
+ }
+ if ( shd->data ) { // existing data
+#if defined(DONT_USE_REALLOC)
+ char *newdata = NEW(char,newsize); // manual realloc
+ memcpy( newdata, shd->data, QMIN(shd->len,newsize) );
+ DELETE(shd->data);
+ shd->data = newdata;
+#else
+ shd->data = (char *)realloc( shd->data, newsize );
+#endif
+ } else {
+ shd->data = NEW(char,newsize);
+ }
+ CHECK_PTR( shd->data );
+ if ( !shd->data ) // no memory
+ return FALSE;
+ shd->len = newsize;
+ return TRUE;
+}
+
+/*!
+ \internal
+ Fills the array with the repeated occurrences of \e d, which is
+ \e sz bytes long.
+ If \e len is specified as different from -1, then the array will be
+ resized to \e len*sz before it is filled.
+
+ Returns TRUE if successful, or FALSE if the memory cannot be allocated
+ (only when \e len != -1).
+
+ \sa resize()
+*/
+
+bool QGArray::fill( const char *d, int len, uint sz )
+{
+ if ( len < 0 )
+ len = shd->len/sz; // default: use array length
+ else if ( !resize( len*sz ) )
+ return FALSE;
+ if ( sz == 1 ) // 8 bit elements
+ memset( data(), *d, len );
+ else if ( sz == 4 ) { // 32 bit elements
+ register Q_INT32 *x = (Q_INT32*)data();
+ Q_INT32 v = *((Q_INT32*)d);
+ while ( len-- )
+ *x++ = v;
+ } else if ( sz == 2 ) { // 16 bit elements
+ register Q_INT16 *x = (Q_INT16*)data();
+ Q_INT16 v = *((Q_INT16*)d);
+ while ( len-- )
+ *x++ = v;
+ } else { // any other size elements
+ register char *x = data();
+ while ( len-- ) { // more complicated
+ memcpy( x, d, sz );
+ x += sz;
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ \internal
+ Shallow copy. Dereference the current array and references the data
+ contained in \e a instead. Returns a reference to this array.
+ \sa operator=()
+*/
+
+QGArray &QGArray::assign( const QGArray &a )
+{
+ a.shd->ref(); // avoid 'a = a'
+ if ( shd->deref() ) { // delete when last reference
+ if ( shd->data ) // is lost
+ DELETE(shd->data);
+ deleteData( shd );
+ }
+ shd = a.shd;
+ return *this;
+}
+
+/*!
+ \internal
+ Shallow copy. Dereference the current array and references the
+ array data \e d, which contains \e len bytes.
+ Returns a reference to this array.
+
+ Do not delete \e d later, because QGArray takes care of that.
+*/
+
+QGArray &QGArray::assign( const char *d, uint len )
+{
+ if ( shd->count > 1 ) { // disconnect this
+ shd->count--;
+ shd = newData();
+ CHECK_PTR( shd );
+ } else {
+ if ( shd->data )
+ DELETE(shd->data);
+ }
+ shd->data = (char *)d;
+ shd->len = len;
+ return *this;
+}
+
+/*!
+ \internal
+ Deep copy. Dereference the current array and obtains a copy of the data
+ contained in \e a instead. Returns a reference to this array.
+ \sa assign(), operator=()
+*/
+
+QGArray &QGArray::duplicate( const QGArray &a )
+{
+ if ( a.shd == shd ) { // a.duplicate(a) !
+ if ( shd->count > 1 ) {
+ shd->count--;
+ register array_data *n = newData();
+ CHECK_PTR( n );
+ if ( (n->len=shd->len) ) {
+ n->data = NEW(char,n->len);
+ CHECK_PTR( n->data );
+ if ( n->data )
+ memcpy( n->data, shd->data, n->len );
+ } else {
+ n->data = 0;
+ }
+ shd = n;
+ }
+ return *this;
+ }
+ char *oldptr = 0;
+ if ( shd->count > 1 ) { // disconnect this
+ shd->count--;
+ shd = newData();
+ CHECK_PTR( shd );
+ } else { // delete after copy was made
+ oldptr = shd->data;
+ }
+ if ( a.shd->len ) { // duplicate data
+ shd->data = NEW(char,a.shd->len);
+ CHECK_PTR( shd->data );
+ if ( shd->data )
+ memcpy( shd->data, a.shd->data, a.shd->len );
+ } else {
+ shd->data = 0;
+ }
+ shd->len = a.shd->len;
+ if ( oldptr )
+ DELETE(oldptr);
+ return *this;
+}
+
+/*!
+ \internal
+ Deep copy. Dereferences the current array and obtains a copy of the
+ array data \e d instead. Returns a reference to this array.
+ \sa assign(), operator=()
+*/
+
+QGArray &QGArray::duplicate( const char *d, uint len )
+{
+ char *data;
+ if ( d == 0 || len == 0 ) {
+ data = 0;
+ len = 0;
+ } else {
+ if ( shd->count == 1 && shd->len == len ) {
+ memcpy( shd->data, d, len ); // use same buffer
+ return *this;
+ }
+ data = NEW(char,len);
+ CHECK_PTR( data );
+ memcpy( data, d, len );
+ }
+ if ( shd->count > 1 ) { // detach
+ shd->count--;
+ shd = newData();
+ CHECK_PTR( shd );
+ } else { // just a single reference
+ if ( shd->data )
+ DELETE(shd->data);
+ }
+ shd->data = data;
+ shd->len = len;
+ return *this;
+}
+
+/*!
+ \internal
+ Resizes this array to \e len bytes and copies the \e len bytes at
+ address \e into it.
+
+ \warning This function disregards the reference count mechanism. If
+ other QGArrays reference the same data as this, all will be updated.
+*/
+
+void QGArray::store( const char *d, uint len )
+{ // store, but not deref
+ resize( len );
+ memcpy( shd->data, d, len );
+}
+
+
+/*!
+ \fn array_data *QGArray::sharedBlock() const
+ \internal
+ Returns a pointer to the shared array block.
+
+ \warning
+
+ Do not use this function. Using it is begging for trouble. We dare
+ not remove it, for fear of breaking code, but we \e strongly
+ discourage new use of it.
+*/
+
+/*!
+ \fn void QGArray::setSharedBlock( array_data *p )
+ \internal
+ Sets the shared array block to \e p.
+
+ \warning
+
+ Do not use this function. Using it is begging for trouble. We dare
+ not remove it, for fear of breaking code, but we \e strongly
+ discourage new use of it.
+*/
+
+
+/*!
+ \internal
+ Sets raw data and returns a reference to the array.
+
+ Dereferences the current array and sets the new array data to \e d and
+ the new array size to \e len. Do not attempt to resize or re-assign the
+ array data when raw data has been set.
+ Call resetRawData(d,len) to reset the array.
+
+ Setting raw data is useful because it set QArray data without allocating
+ memory or copying data.
+
+ Example of intended use:
+ \code
+ static uchar bindata[] = { 231, 1, 44, ... };
+ QByteArray a;
+ a.setRawData( bindata, sizeof(bindata) ); // a points to bindata
+ QDataStream s( a, IO_ReadOnly ); // open on a's data
+ s >> <something>; // read raw bindata
+ s.close();
+ a.resetRawData( bindata, sizeof(bindata) ); // finished
+ \endcode
+
+ Example of misuse (do not do this):
+ \code
+ static uchar bindata[] = { 231, 1, 44, ... };
+ QByteArray a, b;
+ a.setRawData( bindata, sizeof(bindata) ); // a points to bindata
+ a.resize( 8 ); // will crash
+ b = a; // will crash
+ a[2] = 123; // might crash
+ // forget to resetRawData - will crash
+ \endcode
+
+ \warning If you do not call resetRawData(), QGArray will attempt to
+ deallocate or reallocate the raw data, which might not be too good.
+ Be careful.
+*/
+
+QGArray &QGArray::setRawData( const char *d, uint len )
+{
+ duplicate( 0, 0 ); // set null data
+ shd->data = (char *)d;
+ shd->len = len;
+ return *this;
+}
+
+/*!
+ \internal
+ Resets raw data.
+
+ The arguments must be the data and length that were passed to
+ setRawData(). This is for consistency checking.
+*/
+
+void QGArray::resetRawData( const char *d, uint len )
+{
+ if ( d != shd->data || len != shd->len ) {
+#if defined(CHECK_STATE)
+ qWarning( "QGArray::resetRawData: Inconsistent arguments" );
+#endif
+ return;
+ }
+ shd->data = 0;
+ shd->len = 0;
+}
+
+
+/*!
+ \internal
+ Finds the first occurrence of \e d in the array from position \e index,
+ where \e sz is the size of the \e d element.
+
+ Note that \e index is given in units of \e sz, not bytes.
+
+ This function only compares whole cells, not bytes.
+*/
+
+int QGArray::find( const char *d, uint index, uint sz ) const
+{
+ index *= sz;
+ if ( index >= shd->len ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QGArray::find: Index %d out of range", index/sz );
+#endif
+ return -1;
+ }
+ register uint i;
+ uint ii;
+ switch ( sz ) {
+ case 1: { // 8 bit elements
+ register char *x = data() + index;
+ char v = *d;
+ for ( i=index; i<shd->len; i++ ) {
+ if ( *x++ == v )
+ break;
+ }
+ ii = i;
+ }
+ break;
+ case 2: { // 16 bit elements
+ register Q_INT16 *x = (Q_INT16*)(data() + index);
+ Q_INT16 v = *((Q_INT16*)d);
+ for ( i=index; i<shd->len; i+=2 ) {
+ if ( *x++ == v )
+ break;
+ }
+ ii = i/2;
+ }
+ break;
+ case 4: { // 32 bit elements
+ register Q_INT32 *x = (Q_INT32*)(data() + index);
+ Q_INT32 v = *((Q_INT32*)d);
+ for ( i=index; i<shd->len; i+=4 ) {
+ if ( *x++ == v )
+ break;
+ }
+ ii = i/4;
+ }
+ break;
+ default: { // any size elements
+ for ( i=index; i<shd->len; i+=sz ) {
+ if ( memcmp( d, &shd->data[i], sz ) == 0 )
+ break;
+ }
+ ii = i/sz;
+ }
+ break;
+ }
+ return i<shd->len ? (int)ii : -1;
+}
+
+/*!
+ \internal
+ Returns the number of occurrences of \e d in the array, where \e sz is
+ the size of the \e d element.
+
+ This function only compares whole cells, not bytes.
+*/
+
+int QGArray::contains( const char *d, uint sz ) const
+{
+ register uint i = shd->len;
+ int count = 0;
+ switch ( sz ) {
+ case 1: { // 8 bit elements
+ register char *x = data();
+ char v = *d;
+ while ( i-- ) {
+ if ( *x++ == v )
+ count++;
+ }
+ }
+ break;
+ case 2: { // 16 bit elements
+ register Q_INT16 *x = (Q_INT16*)data();
+ Q_INT16 v = *((Q_INT16*)d);
+ i /= 2;
+ while ( i-- ) {
+ if ( *x++ == v )
+ count++;
+ }
+ }
+ break;
+ case 4: { // 32 bit elements
+ register Q_INT32 *x = (Q_INT32*)data();
+ Q_INT32 v = *((Q_INT32*)d);
+ i /= 4;
+ while ( i-- ) {
+ if ( *x++ == v )
+ count++;
+ }
+ }
+ break;
+ default: { // any size elements
+ for ( i=0; i<shd->len; i+=sz ) {
+ if ( memcmp(d, &shd->data[i], sz) == 0 )
+ count++;
+ }
+ }
+ break;
+ }
+ return count;
+}
+
+static int cmp_item_size = 0;
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static int cmp_arr( const void *n1, const void *n2 )
+{
+ return ( n1 && n2 ) ? memcmp( n1, n2, cmp_item_size )
+ : (int)((long)n1 - (long)n2);
+ // Qt 3.0: Add a virtual compareItems() method and call that instead
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+/*!
+ \internal
+
+ Sort the array.
+*/
+
+void QGArray::sort( uint sz )
+{
+ int numItems = size() / sz;
+ if ( numItems < 2 )
+ return;
+ cmp_item_size = sz;
+ qsort( shd->data, numItems, sz, cmp_arr );
+}
+
+/*!
+ \internal
+
+ Binary search; assumes sorted array
+*/
+
+int QGArray::bsearch( const char *d, uint sz ) const
+{
+ int numItems = size() / sz;
+ if ( !numItems )
+ return -1;
+ cmp_item_size = sz;
+ char* r = (char*)::bsearch( d, shd->data, numItems, sz, cmp_arr );
+ if ( !r )
+ return -1;
+ while( (r >= shd->data + sz) && (cmp_arr( r - sz, d ) == 0) )
+ r -= sz; // search to first of equal elements; bsearch is undef
+ return (int)(( r - shd->data ) / sz);
+}
+
+
+/*!
+ \fn char *QGArray::at( uint index ) const
+ \internal
+ Returns a pointer to the byte at offset \e index in the array.
+*/
+
+/*!
+ \internal
+ Expand the array if necessary, and copies (the first part of) its
+ contents from the \e index*zx bytes at \e d.
+
+ Returns TRUE if the operation succeeds, FALSE if it runs out of
+ memory.
+
+ \warning This function disregards the reference count mechanism. If
+ other QGArrays reference the same data as this, all will be changed.
+*/
+
+bool QGArray::setExpand( uint index, const char *d, uint sz )
+{
+ index *= sz;
+ if ( index >= shd->len ) {
+ if ( !resize( index+sz ) ) // no memory
+ return FALSE;
+ }
+ memcpy( data() + index, d, sz );
+ return TRUE;
+}
+
+
+/*!
+ \internal
+ Prints a warning message if at() or [] is given a bad index.
+*/
+
+void QGArray::msg_index( uint index )
+{
+#if defined(CHECK_RANGE)
+ qWarning( "QGArray::at: Absolute index %d out of range", index );
+#else
+ Q_UNUSED( index )
+#endif
+}
+
+
+/*!
+ \internal
+ Returns a new shared array block.
+*/
+
+QGArray::array_data * QGArray::newData()
+{
+ return new array_data;
+}
+
+
+/*!
+ \internal
+ Deletes the shared array block.
+*/
+
+void QGArray::deleteData( array_data *p )
+{
+ delete p;
+ p = 0;
+}
diff --git a/qtools/qgarray.h b/qtools/qgarray.h
new file mode 100644
index 0000000..12c463b
--- /dev/null
+++ b/qtools/qgarray.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+**
+** Definition of QGArray class
+**
+** Created : 930906
+**
+** Copyright (C) 1992-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 QGARRAY_H
+#define QGARRAY_H
+
+#ifndef QT_H
+#include "qshared.h"
+#endif // QT_H
+
+
+class Q_EXPORT QGArray // generic array
+{
+friend class QBuffer;
+public:
+ //### DO NOT USE THIS. IT IS PUBLIC BUT DO NOT USE IT IN NEW CODE.
+ struct array_data : public QShared { // shared array
+ array_data() { data=0; len=0; }
+ char *data; // actual array data
+ uint len;
+ };
+ QGArray();
+protected:
+ QGArray( int, int ); // dummy; does not alloc
+ QGArray( int size ); // allocate 'size' bytes
+ QGArray( const QGArray &a ); // shallow copy
+ virtual ~QGArray();
+
+ QGArray &operator=( const QGArray &a ) { return assign( a ); }
+
+ virtual void detach() { duplicate(*this); }
+
+ char *data() const { return shd->data; }
+ uint nrefs() const { return shd->count; }
+ uint size() const { return shd->len; }
+ bool isEqual( const QGArray &a ) const;
+
+ bool resize( uint newsize );
+
+ bool fill( const char *d, int len, uint sz );
+
+ QGArray &assign( const QGArray &a );
+ QGArray &assign( const char *d, uint len );
+ QGArray &duplicate( const QGArray &a );
+ QGArray &duplicate( const char *d, uint len );
+ void store( const char *d, uint len );
+
+ array_data *sharedBlock() const { return shd; }
+ void setSharedBlock( array_data *p ) { shd=(array_data*)p; }
+
+ QGArray &setRawData( const char *d, uint len );
+ void resetRawData( const char *d, uint len );
+
+ int find( const char *d, uint index, uint sz ) const;
+ int contains( const char *d, uint sz ) const;
+
+ void sort( uint sz );
+ int bsearch( const char *d, uint sz ) const;
+
+ char *at( uint index ) const;
+
+ bool setExpand( uint index, const char *d, uint sz );
+
+protected:
+ virtual array_data *newData();
+ virtual void deleteData( array_data *p );
+
+private:
+ static void msg_index( uint );
+ array_data *shd;
+};
+
+
+inline char *QGArray::at( uint index ) const
+{
+#if defined(CHECK_RANGE)
+ if ( index >= size() ) {
+ msg_index( index );
+ index = 0;
+ }
+#endif
+ return &shd->data[index];
+}
+
+
+#endif // QGARRAY_H
diff --git a/qtools/qgdict.cpp b/qtools/qgdict.cpp
new file mode 100644
index 0000000..c3b2f74
--- /dev/null
+++ b/qtools/qgdict.cpp
@@ -0,0 +1,1215 @@
+/****************************************************************************
+**
+**
+** Implementation of QGDict and QGDictIterator classes
+**
+** Created : 920529
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qgdict.h"
+#include "qlist.h"
+#include "qstring.h"
+#include "qdatastream.h"
+#include <ctype.h>
+
+
+// NOT REVISED
+/*!
+ \class QGDict qgdict.h
+ \brief The QGDict class is an internal class for implementing QDict template classes.
+
+ QGDict is a strictly internal class that acts as a base class for the
+ \link collection.html collection classes\endlink QDict and QIntDict.
+
+ QGDict has some virtual functions that can be reimplemented to customize
+ the subclasses.
+ <ul>
+ <li> read() reads a collection/dictionary item from a QDataStream.
+ <li> write() writes a collection/dictionary item to a QDataStream.
+ </ul>
+ Normally, you do not have to reimplement any of these functions.
+*/
+
+static const int op_find = 0;
+static const int op_insert = 1;
+static const int op_replace = 2;
+
+
+class QGDItList : public QList<QGDictIterator>
+{
+public:
+ QGDItList() : QList<QGDictIterator>() {}
+ QGDItList( const QGDItList &list ) : QList<QGDictIterator>(list) {}
+ ~QGDItList() { clear(); }
+ QGDItList &operator=(const QGDItList &list)
+ { return (QGDItList&)QList<QGDictIterator>::operator=(list); }
+};
+
+
+/*****************************************************************************
+ Default implementation of special and virtual functions
+ *****************************************************************************/
+
+/*!
+ \internal
+ Returns the hash key for \e key, when key is a string.
+*/
+
+int QGDict::hashKeyString( const QString &key )
+{
+#if defined(CHECK_NULL)
+ if ( key.isNull() )
+ qWarning( "QGDict::hashStringKey: Invalid null key" );
+#endif
+ int i;
+ register uint h=0;
+ uint g;
+ const QChar *p = key.unicode();
+ if ( cases ) { // case sensitive
+ for ( i=0; i<(int)key.length(); i++ ) {
+ h = (h<<4) + p[i].cell();
+ if ( (g = h & 0xf0000000) )
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ } else { // case insensitive
+ for ( i=0; i<(int)key.length(); i++ ) {
+ h = (h<<4) + p[i].lower().cell();
+ if ( (g = h & 0xf0000000) )
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ }
+ int index = h;
+ if ( index < 0 ) // adjust index to table size
+ index = -index;
+ return index;
+}
+
+/*!
+ \internal
+ Returns the hash key for \a key, which is a C string.
+*/
+
+int QGDict::hashKeyAscii( const char *key )
+{
+#if defined(CHECK_NULL)
+ if ( key == 0 )
+ qWarning( "QGDict::hashAsciiKey: Invalid null key" );
+#endif
+ register const char *k = key;
+ register uint h=0;
+ uint g;
+ if ( cases ) { // case sensitive
+ while ( *k ) {
+ h = (h<<4) + *k++;
+ if ( (g = h & 0xf0000000) )
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ } else { // case insensitive
+ while ( *k ) {
+ h = (h<<4) + tolower(*k);
+ if ( (g = h & 0xf0000000) )
+ h ^= g >> 24;
+ h &= ~g;
+ k++;
+ }
+ }
+ int index = h;
+ if ( index < 0 ) // adjust index to table size
+ index = -index;
+ return index;
+}
+
+#ifndef QT_NO_DATASTREAM
+
+/*!
+ Reads a collection/dictionary item from the stream \e s and returns a
+ reference to the stream.
+
+ The default implementation sets \e item to 0.
+
+ \sa write()
+*/
+
+QDataStream& QGDict::read( QDataStream &s, QCollection::Item &item )
+{
+ item = 0;
+ return s;
+}
+
+/*!
+ Writes a collection/dictionary item to the stream \e s and returns a
+ reference to the stream.
+
+ \sa read()
+*/
+
+QDataStream& QGDict::write( QDataStream &s, QCollection::Item ) const
+{
+ return s;
+}
+#endif //QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QGDict member functions
+ *****************************************************************************/
+
+/*!
+ \internal
+ Constructs a dictionary.
+*/
+
+QGDict::QGDict( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
+{
+ init( len, kt, caseSensitive, copyKeys );
+}
+
+
+void QGDict::init( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
+{
+ vec = new QBaseBucket *[vlen = len]; // allocate hash table
+ CHECK_PTR( vec );
+ memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) );
+ numItems = 0;
+ iterators = 0;
+ // The caseSensitive and copyKey options don't make sense for
+ // all dict types.
+ switch ( (keytype = (uint)kt) ) {
+ case StringKey:
+ cases = caseSensitive;
+ copyk = FALSE;
+ break;
+ case AsciiKey:
+ cases = caseSensitive;
+ copyk = copyKeys;
+ break;
+ default:
+ cases = FALSE;
+ copyk = FALSE;
+ break;
+ }
+}
+
+
+/*!
+ \internal
+ Constructs a copy of \e dict.
+*/
+
+QGDict::QGDict( const QGDict & dict )
+ : QCollection( dict )
+{
+ init( dict.vlen, (KeyType)dict.keytype, dict.cases, dict.copyk );
+ QGDictIterator it( dict );
+ while ( it.get() ) { // copy from other dict
+ switch ( keytype ) {
+ case StringKey:
+ look_string( it.getKeyString(), it.get(), op_insert );
+ break;
+ case AsciiKey:
+ look_ascii( it.getKeyAscii(), it.get(), op_insert );
+ break;
+ case IntKey:
+ look_int( it.getKeyInt(), it.get(), op_insert );
+ break;
+ case PtrKey:
+ look_ptr( it.getKeyPtr(), it.get(), op_insert );
+ break;
+ }
+ ++it;
+ }
+}
+
+
+/*!
+ \internal
+ Removes all items from the dictionary and destroys it.
+*/
+
+QGDict::~QGDict()
+{
+ clear(); // delete everything
+ delete [] vec;
+ if ( !iterators ) // no iterators for this dict
+ return;
+ QGDictIterator *i = iterators->first();
+ while ( i ) { // notify all iterators that
+ i->dict = 0; // this dict is deleted
+ i = iterators->next();
+ }
+ delete iterators;
+}
+
+
+/*!
+ \internal
+ Assigns \e dict to this dictionary.
+*/
+
+QGDict &QGDict::operator=( const QGDict &dict )
+{
+ clear();
+ QGDictIterator it( dict );
+ while ( it.get() ) { // copy from other dict
+ switch ( keytype ) {
+ case StringKey:
+ look_string( it.getKeyString(), it.get(), op_insert );
+ break;
+ case AsciiKey:
+ look_ascii( it.getKeyAscii(), it.get(), op_insert );
+ break;
+ case IntKey:
+ look_int( it.getKeyInt(), it.get(), op_insert );
+ break;
+ case PtrKey:
+ look_ptr( it.getKeyPtr(), it.get(), op_insert );
+ break;
+ }
+ ++it;
+ }
+ return *this;
+}
+
+
+/*! \fn QCollection::Item QGDictIterator::get() const
+
+ \internal
+*/
+
+
+/*! \fn QString QGDictIterator::getKeyString() const
+
+ \internal
+*/
+
+
+/*! \fn const char * QGDictIterator::getKeyAscii() const
+
+ \internal
+*/
+
+
+/*! \fn void * QGDictIterator::getKeyPtr() const
+
+ \internal
+*/
+
+
+/*! \fn long QGDictIterator::getKeyInt() const
+
+ \internal
+*/
+
+
+/*!
+ \fn uint QGDict::count() const
+ \internal
+ Returns the number of items in the dictionary.
+*/
+
+/*!
+ \fn uint QGDict::size() const
+ \internal
+ Returns the size of the hash array.
+*/
+
+
+/*!
+ \internal
+ The do-it-all function; op is one of op_find, op_insert, op_replace
+*/
+
+QCollection::Item QGDict::look_string( const QString &key, QCollection::Item d, int op )
+{
+ QStringBucket *n;
+ int index = hashKeyString(key) % vlen;
+ if ( op == op_find ) { // find
+ if ( cases ) {
+ for ( n=(QStringBucket*)vec[index]; n;
+ n=(QStringBucket*)n->getNext() ) {
+ if ( key == n->getKey() )
+ return n->getData(); // item found
+ }
+ } else {
+ QString k = key.lower();
+ for ( n=(QStringBucket*)vec[index]; n;
+ n=(QStringBucket*)n->getNext() ) {
+ if ( k == n->getKey().lower() )
+ return n->getData(); // item found
+ }
+ }
+ return 0; // not found
+ }
+ if ( op == op_replace ) { // replace
+ if ( vec[index] != 0 ) // maybe something there
+ remove_string( key );
+ }
+ // op_insert or op_replace
+ n = new QStringBucket(key,newItem(d),vec[index]);
+ CHECK_PTR( n );
+#if defined(CHECK_NULL)
+ if ( n->getData() == 0 )
+ qWarning( "QDict: Cannot insert null item" );
+#endif
+ vec[index] = n;
+ numItems++;
+ return n->getData();
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::look_ascii( const char *key, QCollection::Item d, int op )
+{
+ QAsciiBucket *n;
+ int index = hashKeyAscii(key) % vlen;
+ if ( op == op_find ) { // find
+ if ( cases ) {
+ for ( n=(QAsciiBucket*)vec[index]; n;
+ n=(QAsciiBucket*)n->getNext() ) {
+ if ( qstrcmp(n->getKey(),key) == 0 )
+ return n->getData(); // item found
+ }
+ } else {
+ for ( n=(QAsciiBucket*)vec[index]; n;
+ n=(QAsciiBucket*)n->getNext() ) {
+ if ( qstricmp(n->getKey(),key) == 0 )
+ return n->getData(); // item found
+ }
+ }
+ return 0; // not found
+ }
+ if ( op == op_replace ) { // replace
+ if ( vec[index] != 0 ) // maybe something there
+ remove_ascii( key );
+ }
+ // op_insert or op_replace
+ n = new QAsciiBucket(copyk ? qstrdup(key) : key,newItem(d),vec[index]);
+ CHECK_PTR( n );
+#if defined(CHECK_NULL)
+ if ( n->getData() == 0 )
+ qWarning( "QAsciiDict: Cannot insert null item" );
+#endif
+ vec[index] = n;
+ numItems++;
+ return n->getData();
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::look_int( long key, QCollection::Item d, int op )
+{
+ QIntBucket *n;
+ int index = (int)((ulong)key % vlen); // simple hash
+ if ( op == op_find ) { // find
+ for ( n=(QIntBucket*)vec[index]; n;
+ n=(QIntBucket*)n->getNext() ) {
+ if ( n->getKey() == key )
+ return n->getData(); // item found
+ }
+ return 0; // not found
+ }
+ if ( op == op_replace ) { // replace
+ if ( vec[index] != 0 ) // maybe something there
+ remove_int( key );
+ }
+ // op_insert or op_replace
+ n = new QIntBucket(key,newItem(d),vec[index]);
+ CHECK_PTR( n );
+#if defined(CHECK_NULL)
+ if ( n->getData() == 0 )
+ qWarning( "QIntDict: Cannot insert null item" );
+#endif
+ vec[index] = n;
+ numItems++;
+ return n->getData();
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::look_ptr( void *key, QCollection::Item d, int op )
+{
+ QPtrBucket *n;
+ int index = (int)((ulong)key % vlen); // simple hash
+ if ( op == op_find ) { // find
+ for ( n=(QPtrBucket*)vec[index]; n;
+ n=(QPtrBucket*)n->getNext() ) {
+ if ( n->getKey() == key )
+ return n->getData(); // item found
+ }
+ return 0; // not found
+ }
+ if ( op == op_replace ) { // replace
+ if ( vec[index] != 0 ) // maybe something there
+ remove_ptr( key );
+ }
+ // op_insert or op_replace
+ n = new QPtrBucket(key,newItem(d),vec[index]);
+ CHECK_PTR( n );
+#if defined(CHECK_NULL)
+ if ( n->getData() == 0 )
+ qWarning( "QPtrDict: Cannot insert null item" );
+#endif
+ vec[index] = n;
+ numItems++;
+ return n->getData();
+}
+
+
+/*!
+ \internal
+ Changes the size of the hashtable.
+ The contents of the dictionary are preserved,
+ but all iterators on the dictionary become invalid.
+*/
+void QGDict::resize( uint newsize )
+{
+ // Save old information
+ QBaseBucket **old_vec = vec;
+ uint old_vlen = vlen;
+ bool old_copyk = copyk;
+
+ vec = new QBaseBucket *[vlen = newsize];
+ CHECK_PTR( vec );
+ memset( (char*)vec, 0, vlen*sizeof(QBaseBucket*) );
+ numItems = 0;
+ copyk = FALSE;
+
+ // Reinsert every item from vec, deleting vec as we go
+ for ( uint index = 0; index < old_vlen; index++ ) {
+ switch ( keytype ) {
+ case StringKey:
+ {
+ QStringBucket *n=(QStringBucket *)old_vec[index];
+ while ( n ) {
+ look_string( n->getKey(), n->getData(), op_insert );
+ QStringBucket *t=(QStringBucket *)n->getNext();
+ delete n;
+ n = t;
+ }
+ }
+ break;
+ case AsciiKey:
+ {
+ QAsciiBucket *n=(QAsciiBucket *)old_vec[index];
+ while ( n ) {
+ look_ascii( n->getKey(), n->getData(), op_insert );
+ QAsciiBucket *t=(QAsciiBucket *)n->getNext();
+ delete n;
+ n = t;
+ }
+ }
+ break;
+ case IntKey:
+ {
+ QIntBucket *n=(QIntBucket *)old_vec[index];
+ while ( n ) {
+ look_int( n->getKey(), n->getData(), op_insert );
+ QIntBucket *t=(QIntBucket *)n->getNext();
+ delete n;
+ n = t;
+ }
+ }
+ break;
+ case PtrKey:
+ {
+ QPtrBucket *n=(QPtrBucket *)old_vec[index];
+ while ( n ) {
+ look_ptr( n->getKey(), n->getData(), op_insert );
+ QPtrBucket *t=(QPtrBucket *)n->getNext();
+ delete n;
+ n = t;
+ }
+ }
+ break;
+ }
+ }
+ delete [] old_vec;
+
+ // Restore state
+ copyk = old_copyk;
+
+ // Invalidate all iterators, since order is lost
+ if ( iterators && iterators->count() ) {
+ QGDictIterator *i = iterators->first();
+ while ( i ) {
+ i->toFirst();
+ i = iterators->next();
+ }
+ }
+}
+
+/*!
+ \internal
+ Unlinks the bucket with the specified key (and specified data pointer,
+ if it is set).
+*/
+
+void QGDict::unlink_common( int index, QBaseBucket *node, QBaseBucket *prev )
+{
+ if ( iterators && iterators->count() ) { // update iterators
+ QGDictIterator *i = iterators->first();
+ while ( i ) { // invalidate all iterators
+ if ( i->curNode == node ) // referring to pending node
+ i->operator++();
+ i = iterators->next();
+ }
+ }
+ if ( prev ) // unlink node
+ prev->setNext( node->getNext() );
+ else
+ vec[index] = node->getNext();
+ numItems--;
+}
+
+QStringBucket *QGDict::unlink_string( const QString &key, QCollection::Item d )
+{
+ if ( numItems == 0 ) // nothing in dictionary
+ return 0;
+ QStringBucket *n;
+ QStringBucket *prev = 0;
+ int index = hashKeyString(key) % vlen;
+ if ( cases ) {
+ for ( n=(QStringBucket*)vec[index]; n;
+ n=(QStringBucket*)n->getNext() ) {
+ bool found = (key == n->getKey());
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ } else {
+ QString k = key.lower();
+ for ( n=(QStringBucket*)vec[index]; n;
+ n=(QStringBucket*)n->getNext() ) {
+ bool found = (k == n->getKey().lower());
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ }
+ return 0;
+}
+
+QAsciiBucket *QGDict::unlink_ascii( const char *key, QCollection::Item d )
+{
+ if ( numItems == 0 ) // nothing in dictionary
+ return 0;
+ QAsciiBucket *n;
+ QAsciiBucket *prev = 0;
+ int index = hashKeyAscii(key) % vlen;
+ for ( n=(QAsciiBucket *)vec[index]; n; n=(QAsciiBucket *)n->getNext() ) {
+ bool found = (cases ? qstrcmp(n->getKey(),key)
+ : qstricmp(n->getKey(),key)) == 0;
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ return 0;
+}
+
+QIntBucket *QGDict::unlink_int( long key, QCollection::Item d )
+{
+ if ( numItems == 0 ) // nothing in dictionary
+ return 0;
+ QIntBucket *n;
+ QIntBucket *prev = 0;
+ int index = (int)((ulong)key % vlen);
+ for ( n=(QIntBucket *)vec[index]; n; n=(QIntBucket *)n->getNext() ) {
+ bool found = (n->getKey() == key);
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ return 0;
+}
+
+QPtrBucket *QGDict::unlink_ptr( void *key, QCollection::Item d )
+{
+ if ( numItems == 0 ) // nothing in dictionary
+ return 0;
+ QPtrBucket *n;
+ QPtrBucket *prev = 0;
+ int index = (int)((ulong)key % vlen);
+ for ( n=(QPtrBucket *)vec[index]; n; n=(QPtrBucket *)n->getNext() ) {
+ bool found = (n->getKey() == key);
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ return 0;
+}
+
+
+/*!
+ \internal
+ Removes the item with the specified key. If item is non-null,
+ the remove will match the \a item as well (used to remove an
+ item when several items have the same key).
+*/
+
+bool QGDict::remove_string( const QString &key, QCollection::Item item )
+{
+ QStringBucket *n = unlink_string( key, item );
+ if ( n ) {
+ deleteItem( n->getData() );
+ delete n;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+/*! \internal */
+
+bool QGDict::remove_ascii( const char *key, QCollection::Item item )
+{
+ QAsciiBucket *n = unlink_ascii( key, item );
+ if ( n ) {
+ if ( copyk )
+ delete [] (char *)n->getKey();
+ deleteItem( n->getData() );
+ delete n;
+ }
+ return n != 0;
+}
+
+
+/*! \internal */
+
+bool QGDict::remove_int( long key, QCollection::Item item )
+{
+ QIntBucket *n = unlink_int( key, item );
+ if ( n ) {
+ deleteItem( n->getData() );
+ delete n;
+ }
+ return n != 0;
+}
+
+
+/*! \internal */
+
+bool QGDict::remove_ptr( void *key, QCollection::Item item )
+{
+ QPtrBucket *n = unlink_ptr( key, item );
+ if ( n ) {
+ deleteItem( n->getData() );
+ delete n;
+ }
+ return n != 0;
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::take_string( const QString &key )
+{
+ QStringBucket *n = unlink_string( key );
+ Item d;
+ if ( n ) {
+ d = n->getData();
+ delete n;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::take_ascii( const char *key )
+{
+ QAsciiBucket *n = unlink_ascii( key );
+ Item d;
+ if ( n ) {
+ if ( copyk )
+ delete [] (char *)n->getKey();
+ d = n->getData();
+ delete n;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::take_int( long key )
+{
+ QIntBucket *n = unlink_int( key );
+ Item d;
+ if ( n ) {
+ d = n->getData();
+ delete n;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+
+/*! \internal */
+
+QCollection::Item QGDict::take_ptr( void *key )
+{
+ QPtrBucket *n = unlink_ptr( key );
+ Item d;
+ if ( n ) {
+ d = n->getData();
+ delete n;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+
+/*!
+ \internal
+ Removes all items from the dictionary.
+*/
+
+void QGDict::clear()
+{
+ if ( !numItems )
+ return;
+ numItems = 0; // disable remove() function
+ for ( uint j=0; j<vlen; j++ ) { // destroy hash table
+ if ( vec[j] ) {
+ switch ( keytype ) {
+ case StringKey:
+ {
+ QStringBucket *n=(QStringBucket *)vec[j];
+ while ( n ) {
+ QStringBucket *next = (QStringBucket*)n->getNext();
+ deleteItem( n->getData() );
+ delete n;
+ n = next;
+ }
+ }
+ break;
+ case AsciiKey:
+ {
+ QAsciiBucket *n=(QAsciiBucket *)vec[j];
+ while ( n ) {
+ QAsciiBucket *next = (QAsciiBucket*)n->getNext();
+ if ( copyk )
+ delete [] (char *)n->getKey();
+ deleteItem( n->getData() );
+ delete n;
+ n = next;
+ }
+ }
+ break;
+ case IntKey:
+ {
+ QIntBucket *n=(QIntBucket *)vec[j];
+ while ( n ) {
+ QIntBucket *next = (QIntBucket*)n->getNext();
+ deleteItem( n->getData() );
+ delete n;
+ n = next;
+ }
+ }
+ break;
+ case PtrKey:
+ {
+ QPtrBucket *n=(QPtrBucket *)vec[j];
+ while ( n ) {
+ QPtrBucket *next = (QPtrBucket*)n->getNext();
+ deleteItem( n->getData() );
+ delete n;
+ n = next;
+ }
+ }
+ break;
+ }
+ vec[j] = 0; // detach list of buckets
+ }
+ }
+ if ( iterators && iterators->count() ) { // invalidate all iterators
+ QGDictIterator *i = iterators->first();
+ while ( i ) {
+ i->curNode = 0;
+ i = iterators->next();
+ }
+ }
+}
+
+
+/*!
+ \internal
+ Outputs debug statistics.
+*/
+
+void QGDict::statistics() const
+{
+#if defined(DEBUG)
+ QString line;
+ line.fill( '-', 60 );
+ double real, ideal;
+ qDebug( line.ascii() );
+ qDebug( "DICTIONARY STATISTICS:" );
+ if ( count() == 0 ) {
+ qDebug( "Empty!" );
+ qDebug( line.ascii() );
+ return;
+ }
+ real = 0.0;
+ ideal = (float)count()/(2.0*size())*(count()+2.0*size()-1);
+ uint i = 0;
+ while ( i<size() ) {
+ QBaseBucket *n = vec[i];
+ int b = 0;
+ while ( n ) { // count number of buckets
+ b++;
+ n = n->getNext();
+ }
+ real = real + (double)b * ((double)b+1.0)/2.0;
+ char buf[80], *pbuf;
+ if ( b > 78 )
+ b = 78;
+ pbuf = buf;
+ while ( b-- )
+ *pbuf++ = '*';
+ *pbuf = '\0';
+ qDebug( buf );
+ i++;
+ }
+ qDebug( "Array size = %d", size() );
+ qDebug( "# items = %d", count() );
+ qDebug( "Real dist = %g", real );
+ qDebug( "Rand dist = %g", ideal );
+ qDebug( "Real/Rand = %g", real/ideal );
+ qDebug( line.ascii() );
+#endif // DEBUG
+}
+
+
+/*****************************************************************************
+ QGDict stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator>>( QDataStream &s, QGDict &dict )
+{
+ return dict.read( s );
+}
+
+QDataStream &operator<<( QDataStream &s, const QGDict &dict )
+{
+ return dict.write( s );
+}
+
+#if defined(_CC_DEC_) && defined(__alpha) && (__DECCXX_VER >= 50190001)
+#pragma message disable narrowptr
+#endif
+
+/*!
+ \internal
+ Reads a dictionary from the stream \e s.
+*/
+
+QDataStream &QGDict::read( QDataStream &s )
+{
+ uint num;
+ s >> num; // read number of items
+ clear(); // clear dict
+ while ( num-- ) { // read all items
+ Item d;
+ switch ( keytype ) {
+ case StringKey:
+ {
+ QString k;
+ s >> k;
+ read( s, d );
+ look_string( k, d, op_insert );
+ }
+ break;
+ case AsciiKey:
+ {
+ char *k;
+ s >> k;
+ read( s, d );
+ look_ascii( k, d, op_insert );
+ if ( copyk )
+ delete [] k;
+ }
+ break;
+ case IntKey:
+ {
+ Q_UINT32 k;
+ s >> k;
+ read( s, d );
+ look_int( k, d, op_insert );
+ }
+ break;
+ case PtrKey:
+ {
+ Q_UINT32 k;
+ s >> k;
+ read( s, d );
+ // ### cannot insert 0 - this renders the thing
+ // useless since all pointers are written as 0,
+ // but hey, serializing pointers? can it be done
+ // at all, ever?
+ if ( k )
+ look_ptr( (void *)k, d, op_insert );
+ }
+ break;
+ }
+ }
+ return s;
+}
+
+/*!
+ \internal
+ Writes the dictionary to the stream \e s.
+*/
+
+QDataStream& QGDict::write( QDataStream &s ) const
+{
+ s << count(); // write number of items
+ uint i = 0;
+ while ( i<size() ) {
+ QBaseBucket *n = vec[i];
+ while ( n ) { // write all buckets
+ switch ( keytype ) {
+ case StringKey:
+ s << ((QStringBucket*)n)->getKey();
+ break;
+ case AsciiKey:
+ s << ((QAsciiBucket*)n)->getKey();
+ break;
+ case IntKey:
+ s << (Q_UINT32)((QIntBucket*)n)->getKey();
+ break;
+ case PtrKey:
+ s << (Q_UINT32)0; // ### cannot serialize a pointer
+ break;
+ }
+ write( s, n->getData() ); // write data
+ n = n->getNext();
+ }
+ i++;
+ }
+ return s;
+}
+#endif //QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QGDictIterator member functions
+ *****************************************************************************/
+
+/*!
+ \class QGDictIterator qgdict.h
+ \brief An internal class for implementing QDictIterator and QIntDictIterator.
+
+ QGDictIterator is a strictly internal class that does the heavy work for
+ QDictIterator and QIntDictIterator.
+*/
+
+/*!
+ \internal
+ Constructs an iterator that operates on the dictionary \e d.
+*/
+
+QGDictIterator::QGDictIterator( const QGDict &d )
+{
+ dict = (QGDict *)&d; // get reference to dict
+ toFirst(); // set to first noe
+ if ( !dict->iterators ) {
+ dict->iterators = new QGDItList; // create iterator list
+ CHECK_PTR( dict->iterators );
+ }
+ dict->iterators->append( this ); // attach iterator to dict
+}
+
+/*!
+ \internal
+ Constructs a copy of the iterator \e it.
+*/
+
+QGDictIterator::QGDictIterator( const QGDictIterator &it )
+{
+ dict = it.dict;
+ curNode = it.curNode;
+ curIndex = it.curIndex;
+ if ( dict )
+ dict->iterators->append( this ); // attach iterator to dict
+}
+
+/*!
+ \internal
+ Assigns a copy of the iterator \e it and returns a reference to this
+ iterator.
+*/
+
+QGDictIterator &QGDictIterator::operator=( const QGDictIterator &it )
+{
+ if ( dict ) // detach from old dict
+ dict->iterators->removeRef( this );
+ dict = it.dict;
+ curNode = it.curNode;
+ curIndex = it.curIndex;
+ if ( dict )
+ dict->iterators->append( this ); // attach to new list
+ return *this;
+}
+
+/*!
+ \internal
+ Destroys the iterator.
+*/
+
+QGDictIterator::~QGDictIterator()
+{
+ if ( dict ) // detach iterator from dict
+ dict->iterators->removeRef( this );
+}
+
+
+/*!
+ \internal
+ Sets the iterator to point to the first item in the dictionary.
+*/
+
+QCollection::Item QGDictIterator::toFirst()
+{
+ if ( !dict ) {
+#if defined(CHECK_NULL)
+ qWarning( "QGDictIterator::toFirst: Dictionary has been deleted" );
+#endif
+ return 0;
+ }
+ if ( dict->count() == 0 ) { // empty dictionary
+ curNode = 0;
+ return 0;
+ }
+ register uint i = 0;
+ register QBaseBucket **v = dict->vec;
+ while ( !(*v++) )
+ i++;
+ curNode = dict->vec[i];
+ curIndex = i;
+ return curNode->getData();
+}
+
+
+/*!
+ \internal
+ Moves to the next item (postfix).
+*/
+
+QCollection::Item QGDictIterator::operator()()
+{
+ if ( !dict ) {
+#if defined(CHECK_NULL)
+ qWarning( "QGDictIterator::operator(): Dictionary has been deleted" );
+#endif
+ return 0;
+ }
+ if ( !curNode )
+ return 0;
+ QCollection::Item d = curNode->getData();
+ this->operator++();
+ return d;
+}
+
+/*!
+ \internal
+ Moves to the next item (prefix).
+*/
+
+QCollection::Item QGDictIterator::operator++()
+{
+ if ( !dict ) {
+#if defined(CHECK_NULL)
+ qWarning( "QGDictIterator::operator++: Dictionary has been deleted" );
+#endif
+ return 0;
+ }
+ if ( !curNode )
+ return 0;
+ curNode = curNode->getNext();
+ if ( !curNode ) { // no next bucket
+ register uint i = curIndex + 1; // look from next vec element
+ register QBaseBucket **v = &dict->vec[i];
+ while ( i < dict->size() && !(*v++) )
+ i++;
+ if ( i == dict->size() ) { // nothing found
+ curNode = 0;
+ return 0;
+ }
+ curNode = dict->vec[i];
+ curIndex = i;
+ }
+ return curNode->getData();
+}
+
+/*!
+ \internal
+ Moves \e jumps positions forward.
+*/
+
+QCollection::Item QGDictIterator::operator+=( uint jumps )
+{
+ while ( curNode && jumps-- )
+ operator++();
+ return curNode ? curNode->getData() : 0;
+}
diff --git a/qtools/qgdict.h b/qtools/qgdict.h
new file mode 100644
index 0000000..6243364
--- /dev/null
+++ b/qtools/qgdict.h
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+**
+** Definition of QGDict and QGDictIterator classes
+**
+** Created : 920529
+**
+** Copyright (C) 1992-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 QGDICT_H
+#define QGDICT_H
+
+#ifndef QT_H
+#include "qcollection.h"
+#include "qstring.h"
+#endif // QT_H
+
+class QGDictIterator;
+class QGDItList;
+
+
+class QBaseBucket // internal dict node
+{
+public:
+ QCollection::Item getData() { return data; }
+ QCollection::Item setData( QCollection::Item d ) { return data = d; }
+ QBaseBucket *getNext() { return next; }
+ void setNext( QBaseBucket *n) { next = n; }
+protected:
+ QBaseBucket( QCollection::Item d, QBaseBucket *n ) : data(d), next(n) {}
+ QCollection::Item data;
+ QBaseBucket *next;
+};
+
+class QStringBucket : public QBaseBucket
+{
+public:
+ QStringBucket( const QString &k, QCollection::Item d, QBaseBucket *n )
+ : QBaseBucket(d,n), key(k) {}
+ const QString &getKey() const { return key; }
+private:
+ QString key;
+};
+
+class QAsciiBucket : public QBaseBucket
+{
+public:
+ QAsciiBucket( const char *k, QCollection::Item d, QBaseBucket *n )
+ : QBaseBucket(d,n), key(k) {}
+ const char *getKey() const { return key; }
+private:
+ const char *key;
+};
+
+class QIntBucket : public QBaseBucket
+{
+public:
+ QIntBucket( long k, QCollection::Item d, QBaseBucket *n )
+ : QBaseBucket(d,n), key(k) {}
+ long getKey() const { return key; }
+private:
+ long key;
+};
+
+class QPtrBucket : public QBaseBucket
+{
+public:
+ QPtrBucket( void *k, QCollection::Item d, QBaseBucket *n )
+ : QBaseBucket(d,n), key(k) {}
+ void *getKey() const { return key; }
+private:
+ void *key;
+};
+
+
+class Q_EXPORT QGDict : public QCollection // generic dictionary class
+{
+public:
+ uint count() const { return numItems; }
+ uint size() const { return vlen; }
+ QCollection::Item look_string( const QString& key, QCollection::Item,
+ int );
+ QCollection::Item look_ascii( const char *key, QCollection::Item, int );
+ QCollection::Item look_int( long key, QCollection::Item, int );
+ QCollection::Item look_ptr( void *key, QCollection::Item, int );
+#ifndef QT_NO_DATASTREAM
+ QDataStream &read( QDataStream & );
+ QDataStream &write( QDataStream & ) const;
+#endif
+protected:
+ enum KeyType { StringKey, AsciiKey, IntKey, PtrKey };
+
+ QGDict( uint len, KeyType kt, bool cs, bool ck );
+ QGDict( const QGDict & );
+ ~QGDict();
+
+ QGDict &operator=( const QGDict & );
+
+ bool remove_string( const QString &key, QCollection::Item item=0 );
+ bool remove_ascii( const char *key, QCollection::Item item=0 );
+ bool remove_int( long key, QCollection::Item item=0 );
+ bool remove_ptr( void *key, QCollection::Item item=0 );
+ QCollection::Item take_string( const QString &key );
+ QCollection::Item take_ascii( const char *key );
+ QCollection::Item take_int( long key );
+ QCollection::Item take_ptr( void *key );
+
+ void clear();
+ void resize( uint );
+
+ int hashKeyString( const QString & );
+ int hashKeyAscii( const char * );
+
+ void statistics() const;
+
+#ifndef QT_NO_DATASTREAM
+ virtual QDataStream &read( QDataStream &, QCollection::Item & );
+ virtual QDataStream &write( QDataStream &, QCollection::Item ) const;
+#endif
+private:
+ QBaseBucket **vec;
+ uint vlen;
+ uint numItems;
+ uint keytype : 2;
+ uint cases : 1;
+ uint copyk : 1;
+ QGDItList *iterators;
+ void unlink_common( int, QBaseBucket *, QBaseBucket * );
+ QStringBucket *unlink_string( const QString &,
+ QCollection::Item item = 0 );
+ QAsciiBucket *unlink_ascii( const char *, QCollection::Item item = 0 );
+ QIntBucket *unlink_int( long, QCollection::Item item = 0 );
+ QPtrBucket *unlink_ptr( void *, QCollection::Item item = 0 );
+ void init( uint, KeyType, bool, bool );
+ friend class QGDictIterator;
+};
+
+
+class Q_EXPORT QGDictIterator // generic dictionary iterator
+{
+friend class QGDict;
+public:
+ QGDictIterator( const QGDict & );
+ QGDictIterator( const QGDictIterator & );
+ QGDictIterator &operator=( const QGDictIterator & );
+ ~QGDictIterator();
+
+ QCollection::Item toFirst();
+
+ QCollection::Item get() const;
+ QString getKeyString() const;
+ const char *getKeyAscii() const;
+ long getKeyInt() const;
+ void *getKeyPtr() const;
+
+ QCollection::Item operator()();
+ QCollection::Item operator++();
+ QCollection::Item operator+=(uint);
+
+protected:
+ QGDict *dict;
+
+private:
+ QBaseBucket *curNode;
+ uint curIndex;
+};
+
+inline QCollection::Item QGDictIterator::get() const
+{
+ return curNode ? curNode->getData() : 0;
+}
+
+inline QString QGDictIterator::getKeyString() const
+{
+ return curNode ? ((QStringBucket*)curNode)->getKey() : QString::null;
+}
+
+inline const char *QGDictIterator::getKeyAscii() const
+{
+ return curNode ? ((QAsciiBucket*)curNode)->getKey() : 0;
+}
+
+inline long QGDictIterator::getKeyInt() const
+{
+ return curNode ? ((QIntBucket*)curNode)->getKey() : 0;
+}
+
+inline void *QGDictIterator::getKeyPtr() const
+{
+ return curNode ? ((QPtrBucket*)curNode)->getKey() : 0;
+}
+
+
+#endif // QGDICT_H
diff --git a/qtools/qgeneric.h b/qtools/qgeneric.h
new file mode 100644
index 0000000..c2892a0
--- /dev/null
+++ b/qtools/qgeneric.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+**
+** Macros for pasting tokens; utilized by our generic classes
+**
+** Created : 920529
+**
+** Copyright (C) 1992-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 QGENERIC_H
+#define QGENERIC_H
+
+#error "do not include qgeneric.h any more"
+
+#endif // QGENERIC_H
diff --git a/qtools/qglist.cpp b/qtools/qglist.cpp
new file mode 100644
index 0000000..f464a73
--- /dev/null
+++ b/qtools/qglist.cpp
@@ -0,0 +1,1223 @@
+/****************************************************************************
+**
+**
+** Implementation of QGList and QGListIterator classes
+**
+** Created : 920624
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qglist.h"
+#include "qgvector.h"
+#include "qdatastream.h"
+
+
+// NOT REVISED
+/*!
+ \class QLNode qglist.h
+ \brief The QLNode class is an internal class for the QList template collection.
+
+ QLNode is a doubly linked list node; it has three pointers:
+ <ol>
+ <li> Pointer to the previous node.
+ <li> Pointer to the next node.
+ <li> Pointer to the actual data.
+ </ol>
+
+ Sometimes it might be practical to have direct access to the list nodes
+ in a QList, but it is seldom required.
+
+ \warning Be very careful if you want to access the list nodes. The heap
+ can easily get corrupted if you make a mistake.
+
+ \sa QList::currentNode(), QList::removeNode(), QList::takeNode()
+*/
+
+/*!
+ \fn QCollection::Item QLNode::getData()
+ Returns a pointer (\c void*) to the actual data in the list node.
+*/
+
+
+/*!
+ \class QGList qglist.h
+ \brief The QGList class is an internal class for implementing Qt collection classes.
+
+ QGList is a strictly internal class that acts as a base class for several
+ \link collection.html collection classes\endlink; QList, QQueue and
+ QStack.
+
+ QGList has some virtual functions that can be reimplemented to customize
+ the subclasses.
+ <ul>
+ <li> compareItems() compares two collection/list items.
+ <li> read() reads a collection/list item from a QDataStream.
+ <li> write() writes a collection/list item to a QDataStream.
+ </ul>
+ Normally, you do not have to reimplement any of these functions.
+ If you still want to reimplement them, see the QStrList class (qstrlist.h),
+ which is a good example.
+*/
+
+
+/*****************************************************************************
+ Default implementation of virtual functions
+ *****************************************************************************/
+
+/*!
+ This virtual function compares two list items.
+
+ Returns:
+ <ul>
+ <li> 0 if \e item1 == \e item2
+ <li> non-zero if \e item1 != \e item2
+ </ul>
+
+ This function returns \e int rather than \e bool so that
+ reimplementations can return three values and use it to sort by:
+
+ <ul>
+ <li> 0 if \e item1 == \e item2
+ <li> \> 0 (positive integer) if \e item1 \> \e item2
+ <li> \< 0 (negative integer) if \e item1 \< \e item2
+ </ul>
+
+ The QList::inSort() function requires that compareItems() is implemented
+ as described here.
+
+ This function should not modify the list because some const functions
+ call compareItems().
+
+ The default implementation compares the pointers:
+ \code
+
+ \endcode
+*/
+
+int QGList::compareItems( QCollection::Item item1, QCollection::Item item2 )
+{
+ return item1 != item2; // compare pointers
+}
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ Reads a collection/list item from the stream \a s and returns a reference
+ to the stream.
+
+ The default implementation sets \a item to 0.
+
+ \sa write()
+*/
+
+QDataStream &QGList::read( QDataStream &s, QCollection::Item &item )
+{
+ item = 0;
+ return s;
+}
+
+/*!
+ Writes a collection/list item to the stream \a s and returns a reference
+ to the stream.
+
+ The default implementation does nothing.
+
+ \sa read()
+*/
+
+QDataStream &QGList::write( QDataStream &s, QCollection::Item ) const
+{
+ return s;
+}
+#endif // QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QGList member functions
+ *****************************************************************************/
+
+/*!
+ \internal
+ Constructs an empty list.
+*/
+
+QGList::QGList()
+{
+ firstNode = lastNode = curNode = 0; // initialize list
+ numNodes = 0;
+ curIndex = -1;
+ iterators = 0; // initialize iterator list
+}
+
+/*!
+ \internal
+ Constructs a copy of \e list.
+*/
+
+QGList::QGList( const QGList & list )
+ : QCollection( list )
+{
+ firstNode = lastNode = curNode = 0; // initialize list
+ numNodes = 0;
+ curIndex = -1;
+ iterators = 0; // initialize iterator list
+ QLNode *n = list.firstNode;
+ while ( n ) { // copy all items from list
+ append( n->data );
+ n = n->next;
+ }
+}
+
+/*!
+ \internal
+ Removes all items from the list and destroys the list.
+*/
+
+QGList::~QGList()
+{
+ clear();
+ if ( !iterators ) // no iterators for this list
+ return;
+ QGListIterator *i = (QGListIterator*)iterators->first();
+ while ( i ) { // notify all iterators that
+ i->list = 0; // this list is deleted
+ i->curNode = 0;
+ i = (QGListIterator*)iterators->next();
+ }
+ delete iterators;
+}
+
+
+/*!
+ \internal
+ Assigns \e list to this list.
+*/
+
+QGList& QGList::operator=( const QGList &list )
+{
+ clear();
+ if ( list.count() > 0 ) {
+ QLNode *n = list.firstNode;
+ while ( n ) { // copy all items from list
+ append( n->data );
+ n = n->next;
+ }
+ curNode = firstNode;
+ curIndex = 0;
+ }
+ return *this;
+}
+
+/*!
+ Compares this list with \a list. Retruns TRUE if the lists
+ contain the same data, else FALSE.
+*/
+
+bool QGList::operator==( const QGList &list ) const
+{
+ if ( count() != list.count() )
+ return FALSE;
+
+ if ( count() == 0 )
+ return TRUE;
+
+ QLNode *n1 = firstNode;
+ QLNode *n2 = list.firstNode;
+ while ( n1 && n2 ) {
+ // should be mutable
+ if ( ( (QGList*)this )->compareItems( n1->data, n2->data ) != 0 )
+ return FALSE;
+ n1 = n1->next;
+ n2 = n2->next;
+ }
+
+ return TRUE;
+}
+
+/*!
+ \fn uint QGList::count() const
+ \internal
+ Returns the number of items in the list.
+*/
+
+
+/*!
+ \internal
+ Returns the node at position \e index. Sets this node to current.
+*/
+
+QLNode *QGList::locate( uint index )
+{
+ if ( index == (uint)curIndex ) // current node ?
+ return curNode;
+ if ( !curNode && firstNode ) { // set current node
+ curNode = firstNode;
+ curIndex = 0;
+ }
+ register QLNode *node;
+ int distance = index - curIndex; // node distance to cur node
+ bool forward; // direction to traverse
+
+ if ( index >= numNodes ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QGList::locate: Index %d out of range", index );
+#endif
+ return 0;
+ }
+
+ if ( distance < 0 )
+ distance = -distance;
+ if ( (uint)distance < index && (uint)distance < numNodes - index ) {
+ node = curNode; // start from current node
+ forward = index > (uint)curIndex;
+ } else if ( index < numNodes - index ) { // start from first node
+ node = firstNode;
+ distance = index;
+ forward = TRUE;
+ } else { // start from last node
+ node = lastNode;
+ distance = numNodes - index - 1;
+ if ( distance < 0 )
+ distance = 0;
+ forward = FALSE;
+ }
+ if ( forward ) { // now run through nodes
+ while ( distance-- )
+ node = node->next;
+ } else {
+ while ( distance-- )
+ node = node->prev;
+ }
+ curIndex = index; // must update index
+ return curNode = node;
+}
+
+
+/*!
+ \internal
+ Inserts an item at its sorted position in the list.
+*/
+
+void QGList::inSort( QCollection::Item d )
+{
+ int index = 0;
+ register QLNode *n = firstNode;
+ while ( n && compareItems(n->data,d) < 0 ){ // find position in list
+ n = n->next;
+ index++;
+ }
+ insertAt( index, d );
+}
+
+
+/*!
+ \internal
+ Inserts an item at the start of the list.
+*/
+
+void QGList::prepend( QCollection::Item d )
+{
+ register QLNode *n = new QLNode( newItem(d) );
+ CHECK_PTR( n );
+ n->prev = 0;
+ if ( (n->next = firstNode) ) // list is not empty
+ firstNode->prev = n;
+ else // initialize list
+ lastNode = n;
+ firstNode = curNode = n; // curNode affected
+ numNodes++;
+ curIndex = 0;
+}
+
+
+/*!
+ \internal
+ Inserts an item at the end of the list.
+*/
+
+void QGList::append( QCollection::Item d )
+{
+ register QLNode *n = new QLNode( newItem(d) );
+ CHECK_PTR( n );
+ n->next = 0;
+ if ( (n->prev = lastNode) ) // list is not empty
+ lastNode->next = n;
+ else // initialize list
+ firstNode = n;
+ lastNode = curNode = n; // curNode affected
+ curIndex = numNodes;
+ numNodes++;
+}
+
+
+/*!
+ \internal
+ Inserts an item at position \e index in the list.
+*/
+
+bool QGList::insertAt( uint index, QCollection::Item d )
+{
+ if ( index == 0 ) { // insert at head of list
+ prepend( d );
+ return TRUE;
+ } else if ( index == numNodes ) { // append at tail of list
+ append( d );
+ return TRUE;
+ }
+ QLNode *nextNode = locate( index );
+ if ( !nextNode ) // illegal position
+ return FALSE;
+ QLNode *prevNode = nextNode->prev;
+ register QLNode *n = new QLNode( newItem(d) );
+ CHECK_PTR( n );
+ nextNode->prev = n;
+ prevNode->next = n;
+ n->prev = prevNode; // link new node into list
+ n->next = nextNode;
+ curNode = n; // curIndex set by locate()
+ numNodes++;
+ return TRUE;
+}
+
+
+/*!
+ \internal
+ Relinks node \e n and makes it the first node in the list.
+*/
+
+void QGList::relinkNode( QLNode *n )
+{
+ if ( n == firstNode ) // already first
+ return;
+ curNode = n;
+ unlink();
+ n->prev = 0;
+ if ( (n->next = firstNode) ) // list is not empty
+ firstNode->prev = n;
+ else // initialize list
+ lastNode = n;
+ firstNode = curNode = n; // curNode affected
+ numNodes++;
+ curIndex = 0;
+}
+
+
+/*!
+ \internal
+ Unlinks the current list node and returns a pointer to this node.
+*/
+
+QLNode *QGList::unlink()
+{
+ if ( curNode == 0 ) // null current node
+ return 0;
+ register QLNode *n = curNode; // unlink this node
+ if ( n == firstNode ) { // removing first node ?
+ if ( (firstNode = n->next) ) {
+ firstNode->prev = 0;
+ } else {
+ lastNode = curNode = 0; // list becomes empty
+ curIndex = -1;
+ }
+ } else {
+ if ( n == lastNode ) { // removing last node ?
+ lastNode = n->prev;
+ lastNode->next = 0;
+ } else { // neither last nor first node
+ n->prev->next = n->next;
+ n->next->prev = n->prev;
+ }
+ }
+ if ( n->next ) { // change current node
+ curNode = n->next;
+ } else if ( n->prev ) {
+ curNode = n->prev;
+ curIndex--;
+ }
+ if ( iterators && iterators->count() ) { // update iterators
+ QGListIterator *i = (QGListIterator*)iterators->first();
+ while ( i ) { // fix all iterators that
+ if ( i->curNode == n ) // refers to pending node
+ i->curNode = curNode;
+ i = (QGListIterator*)iterators->next();
+ }
+ }
+ numNodes--;
+ return n;
+}
+
+
+/*!
+ \internal
+ Removes the node \e n from the list.
+*/
+
+bool QGList::removeNode( QLNode *n )
+{
+#if defined(CHECK_NULL)
+ if ( n == 0 || (n->prev && n->prev->next != n) ||
+ (n->next && n->next->prev != n) ) {
+ qWarning( "QGList::removeNode: Corrupted node" );
+ return FALSE;
+ }
+#endif
+ curNode = n;
+ unlink(); // unlink node
+ deleteItem( n->data ); // deallocate this node
+ delete n;
+ curNode = firstNode;
+ curIndex = curNode ? 0 : -1;
+ return TRUE;
+}
+
+/*!
+ \internal
+ Removes the item \e d from the list. Uses compareItems() to find the item.
+*/
+
+bool QGList::remove( QCollection::Item d )
+{
+ if ( d ) { // find the item
+ if ( find(d) == -1 )
+ return FALSE;
+ }
+ QLNode *n = unlink(); // unlink node
+ if ( !n )
+ return FALSE;
+ deleteItem( n->data ); // deallocate this node
+ delete n;
+ return TRUE;
+}
+
+/*!
+ \internal
+ Removes the item \e d from the list.
+*/
+
+bool QGList::removeRef( QCollection::Item d )
+{
+ if ( d ) { // find the item
+ if ( findRef(d) == -1 )
+ return FALSE;
+ }
+ QLNode *n = unlink(); // unlink node
+ if ( !n )
+ return FALSE;
+ deleteItem( n->data ); // deallocate this node
+ delete n;
+ return TRUE;
+}
+
+/*!
+ \fn bool QGList::removeFirst()
+ \internal
+ Removes the first item in the list.
+*/
+
+/*!
+ \fn bool QGList::removeLast()
+ \internal
+ Removes the last item in the list.
+*/
+
+/*!
+ \internal
+ Removes the item at position \e index from the list.
+*/
+
+bool QGList::removeAt( uint index )
+{
+ if ( !locate(index) )
+ return FALSE;
+ QLNode *n = unlink(); // unlink node
+ if ( !n )
+ return FALSE;
+ deleteItem( n->data ); // deallocate this node
+ delete n;
+ return TRUE;
+}
+
+
+/*!
+ \internal
+ Takes the node \e n out of the list.
+*/
+
+QCollection::Item QGList::takeNode( QLNode *n )
+{
+#if defined(CHECK_NULL)
+ if ( n == 0 || (n->prev && n->prev->next != n) ||
+ (n->next && n->next->prev != n) ) {
+ qWarning( "QGList::takeNode: Corrupted node" );
+ return 0;
+ }
+#endif
+ curNode = n;
+ unlink(); // unlink node
+ Item d = n->data;
+ delete n; // delete the node, not data
+ curNode = firstNode;
+ curIndex = curNode ? 0 : -1;
+ return d;
+}
+
+/*!
+ \internal
+ Takes the current item out of the list.
+*/
+
+QCollection::Item QGList::take()
+{
+ QLNode *n = unlink(); // unlink node
+ Item d = n ? n->data : 0;
+ delete n; // delete node, keep contents
+ return d;
+}
+
+/*!
+ \internal
+ Takes the item at position \e index out of the list.
+*/
+
+QCollection::Item QGList::takeAt( uint index )
+{
+ if ( !locate(index) )
+ return 0;
+ QLNode *n = unlink(); // unlink node
+ Item d = n ? n->data : 0;
+ delete n; // delete node, keep contents
+ return d;
+}
+
+/*!
+ \internal
+ Takes the first item out of the list.
+*/
+
+QCollection::Item QGList::takeFirst()
+{
+ first();
+ QLNode *n = unlink(); // unlink node
+ Item d = n ? n->data : 0;
+ delete n;
+ return d;
+}
+
+/*!
+ \internal
+ Takes the last item out of the list.
+*/
+
+QCollection::Item QGList::takeLast()
+{
+ last();
+ QLNode *n = unlink(); // unlink node
+ Item d = n ? n->data : 0;
+ delete n;
+ return d;
+}
+
+
+/*!
+ \internal
+ Removes all items from the list.
+*/
+
+void QGList::clear()
+{
+ register QLNode *n = firstNode;
+
+ firstNode = lastNode = curNode = 0; // initialize list
+ numNodes = 0;
+ curIndex = -1;
+
+ if ( iterators && iterators->count() ) {
+ QGListIterator *i = (QGListIterator*)iterators->first();
+ while ( i ) { // notify all iterators that
+ i->curNode = 0; // this list is empty
+ i = (QGListIterator*)iterators->next();
+ }
+ }
+
+ QLNode *prevNode;
+ while ( n ) { // for all nodes ...
+ deleteItem( n->data ); // deallocate data
+ prevNode = n;
+ n = n->next;
+ delete prevNode; // deallocate node
+ }
+}
+
+
+/*!
+ \internal
+ Finds an item in the list.
+*/
+
+int QGList::findRef( QCollection::Item d, bool fromStart )
+{
+ register QLNode *n;
+ int index;
+ if ( fromStart ) { // start from first node
+ n = firstNode;
+ index = 0;
+ } else { // start from current node
+ n = curNode;
+ index = curIndex;
+ }
+ while ( n && n->data != d ) { // find exact match
+ n = n->next;
+ index++;
+ }
+ curNode = n;
+ curIndex = n ? index : -1;
+ return curIndex; // return position of item
+}
+
+/*!
+ \internal
+ Finds an item in the list. Uses compareItems().
+*/
+
+int QGList::find( QCollection::Item d, bool fromStart )
+{
+ register QLNode *n;
+ int index;
+ if ( fromStart ) { // start from first node
+ n = firstNode;
+ index = 0;
+ } else { // start from current node
+ n = curNode;
+ index = curIndex;
+ }
+ while ( n && compareItems(n->data,d) ){ // find equal match
+ n = n->next;
+ index++;
+ }
+ curNode = n;
+ curIndex = n ? index : -1;
+ return curIndex; // return position of item
+}
+
+
+/*!
+ \internal
+ Counts the number an item occurs in the list.
+*/
+
+uint QGList::containsRef( QCollection::Item d ) const
+{
+ register QLNode *n = firstNode;
+ uint count = 0;
+ while ( n ) { // for all nodes...
+ if ( n->data == d ) // count # exact matches
+ count++;
+ n = n->next;
+ }
+ return count;
+}
+
+/*!
+ \internal
+ Counts the number an item occurs in the list. Uses compareItems().
+*/
+
+uint QGList::contains( QCollection::Item d ) const
+{
+ register QLNode *n = firstNode;
+ uint count = 0;
+ QGList *that = (QGList*)this; // mutable for compareItems()
+ while ( n ) { // for all nodes...
+ if ( !that->compareItems(n->data,d) ) // count # equal matches
+ count++;
+ n = n->next;
+ }
+ return count;
+}
+
+
+/*!
+ \fn QCollection::Item QGList::at( uint index )
+ \internal
+ Sets the item at position \e index to the current item.
+*/
+
+/*!
+ \fn int QGList::at() const
+ \internal
+ Returns the current index.
+*/
+
+/*!
+ \fn QLNode *QGList::currentNode() const
+ \internal
+ Returns the current node.
+*/
+
+/*!
+ \fn QCollection::Item QGList::get() const
+ \internal
+ Returns the current item.
+*/
+
+/*!
+ \fn QCollection::Item QGList::cfirst() const
+ \internal
+ Returns the first item in the list.
+*/
+
+/*!
+ \fn QCollection::Item QGList::clast() const
+ \internal
+ Returns the last item in the list.
+*/
+
+
+/*!
+ \internal
+ Returns the first list item. Sets this to current.
+*/
+
+QCollection::Item QGList::first()
+{
+ if ( firstNode ) {
+ curIndex = 0;
+ return (curNode=firstNode)->data;
+ }
+ return 0;
+}
+
+/*!
+ \internal
+ Returns the last list item. Sets this to current.
+*/
+
+QCollection::Item QGList::last()
+{
+ if ( lastNode ) {
+ curIndex = numNodes-1;
+ return (curNode=lastNode)->data;
+ }
+ return 0;
+}
+
+/*!
+ \internal
+ Returns the next list item (after current). Sets this to current.
+*/
+
+QCollection::Item QGList::next()
+{
+ if ( curNode ) {
+ if ( curNode->next ) {
+ curIndex++;
+ curNode = curNode->next;
+ return curNode->data;
+ }
+ curIndex = -1;
+ curNode = 0;
+ }
+ return 0;
+}
+
+/*!
+ \internal
+ Returns the previous list item (before current). Sets this to current.
+*/
+
+QCollection::Item QGList::prev()
+{
+ if ( curNode ) {
+ if ( curNode->prev ) {
+ curIndex--;
+ curNode = curNode->prev;
+ return curNode->data;
+ }
+ curIndex = -1;
+ curNode = 0;
+ }
+ return 0;
+}
+
+
+/*!
+ \internal
+ Converts the list to a vector.
+*/
+
+void QGList::toVector( QGVector *vector ) const
+{
+ vector->clear();
+ if ( !vector->resize( count() ) )
+ return;
+ register QLNode *n = firstNode;
+ uint i = 0;
+ while ( n ) {
+ vector->insert( i, n->data );
+ n = n->next;
+ i++;
+ }
+}
+
+void QGList::heapSortPushDown( QCollection::Item* heap, int first, int last )
+{
+ int r = first;
+ while( r <= last/2 ) {
+ // Node r has only one child ?
+ if ( last == 2*r ) {
+ // Need for swapping ?
+ if ( compareItems( heap[r], heap[ 2*r ] ) > 0 ) {
+ QCollection::Item tmp = heap[r];
+ heap[ r ] = heap[ 2*r ];
+ heap[ 2*r ] = tmp;
+ }
+ // That's it ...
+ r = last;
+ } else {
+ // Node has two children
+ if ( compareItems( heap[r], heap[ 2*r ] ) > 0 &&
+ compareItems( heap[ 2*r ], heap[ 2*r+1 ] ) <= 0 ) {
+ // Swap with left child
+ QCollection::Item tmp = heap[r];
+ heap[ r ] = heap[ 2*r ];
+ heap[ 2*r ] = tmp;
+ r *= 2;
+ } else if ( compareItems( heap[r], heap[ 2*r+1 ] ) > 0 &&
+ compareItems( heap[ 2*r+1 ], heap[ 2*r ] ) < 0 ) {
+ // Swap with right child
+ QCollection::Item tmp = heap[r];
+ heap[ r ] = heap[ 2*r+1 ];
+ heap[ 2*r+1 ] = tmp;
+ r = 2*r+1;
+ } else {
+ // We are done
+ r = last;
+ }
+ }
+ }
+}
+
+
+/*! Sorts the list by the result of the virtual compareItems() function.
+
+ The Heap-Sort algorithm is used for sorting. It sorts n items with
+ O(n*log n) compares. This is the asymptotic optimal solution of the
+ sorting problem.
+*/
+
+void QGList::sort()
+{
+ uint n = count();
+ if ( n < 2 )
+ return;
+
+ // Create the heap
+ QCollection::Item* realheap = new QCollection::Item[ n ];
+ // Wow, what a fake. But I want the heap to be indexed as 1...n
+ QCollection::Item* heap = realheap - 1;
+ int size = 0;
+ QLNode* insert = firstNode;
+ for( ; insert != 0; insert = insert->next ) {
+ heap[++size] = insert->data;
+ int i = size;
+ while( i > 1 && compareItems( heap[i], heap[ i / 2 ] ) < 0 ) {
+ QCollection::Item tmp = heap[ i ];
+ heap[ i ] = heap[ i/2 ];
+ heap[ i/2 ] = tmp;
+ i /= 2;
+ }
+ }
+
+ insert = firstNode;
+ // Now do the sorting
+ for ( int i = n; i > 0; i-- ) {
+ insert->data = heap[1];
+ insert = insert->next;
+ if ( i > 1 ) {
+ heap[1] = heap[i];
+ heapSortPushDown( heap, 1, i - 1 );
+ }
+ }
+
+ delete [] realheap;
+}
+
+
+/*****************************************************************************
+ QGList stream functions
+ *****************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator>>( QDataStream &s, QGList &list )
+{ // read list
+ return list.read( s );
+}
+
+QDataStream &operator<<( QDataStream &s, const QGList &list )
+{ // write list
+ return list.write( s );
+}
+
+/*!
+ \internal
+ Reads a list from the stream \e s.
+*/
+
+QDataStream &QGList::read( QDataStream &s )
+{
+ uint num;
+ s >> num; // read number of items
+ clear(); // clear list
+ while ( num-- ) { // read all items
+ Item d;
+ read( s, d );
+ CHECK_PTR( d );
+ if ( !d ) // no memory
+ break;
+ QLNode *n = new QLNode( d );
+ CHECK_PTR( n );
+ if ( !n ) // no memory
+ break;
+ n->next = 0;
+ if ( (n->prev = lastNode) ) // list is not empty
+ lastNode->next = n;
+ else // initialize list
+ firstNode = n;
+ lastNode = n;
+ numNodes++;
+ }
+ curNode = firstNode;
+ curIndex = curNode ? 0 : -1;
+ return s;
+}
+
+/*!
+ \internal
+ Writes the list to the stream \e s.
+*/
+
+QDataStream &QGList::write( QDataStream &s ) const
+{
+ s << count(); // write number of items
+ QLNode *n = firstNode;
+ while ( n ) { // write all items
+ write( s, n->data );
+ n = n->next;
+ }
+ return s;
+}
+
+#endif // QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QGListIterator member functions
+ *****************************************************************************/
+
+/*!
+ \class QGListIterator qglist.h
+ \brief The QGListIterator class is an internal class for implementing QListIterator.
+
+ QGListIterator is a strictly internal class that does the heavy work for
+ QListIterator.
+*/
+
+/*!
+ \internal
+ Constructs an iterator that operates on the list \e l.
+*/
+
+QGListIterator::QGListIterator( const QGList &l )
+{
+ list = (QGList *)&l; // get reference to list
+ curNode = list->firstNode; // set to first node
+ if ( !list->iterators ) {
+ list->iterators = new QGList; // create iterator list
+ CHECK_PTR( list->iterators );
+ }
+ list->iterators->append( this ); // attach iterator to list
+}
+
+/*!
+ \internal
+ Constructs a copy of the iterator \e it.
+*/
+
+QGListIterator::QGListIterator( const QGListIterator &it )
+{
+ list = it.list;
+ curNode = it.curNode;
+ if ( list )
+ list->iterators->append( this ); // attach iterator to list
+}
+
+/*!
+ \internal
+ Assigns a copy of the iterator \e it and returns a reference to this
+ iterator.
+*/
+
+QGListIterator &QGListIterator::operator=( const QGListIterator &it )
+{
+ if ( list ) // detach from old list
+ list->iterators->removeRef( this );
+ list = it.list;
+ curNode = it.curNode;
+ if ( list )
+ list->iterators->append( this ); // attach to new list
+ return *this;
+}
+
+/*!
+ \internal
+ Destroys the iterator.
+*/
+
+QGListIterator::~QGListIterator()
+{
+ if ( list ) // detach iterator from list
+ list->iterators->removeRef(this);
+}
+
+
+/*!
+ \fn bool QGListIterator::atFirst() const
+ \internal
+ Returns TRUE if the iterator points to the first item, otherwise FALSE.
+*/
+
+/*!
+ \fn bool QGListIterator::atLast() const
+ \internal
+ Returns TRUE if the iterator points to the last item, otherwise FALSE.
+*/
+
+
+/*!
+ \internal
+ Sets the list iterator to point to the first item in the list.
+*/
+
+QCollection::Item QGListIterator::toFirst()
+{
+ if ( !list ) {
+#if defined(CHECK_NULL)
+ qWarning( "QGListIterator::toFirst: List has been deleted" );
+#endif
+ return 0;
+ }
+ return list->firstNode ? (curNode = list->firstNode)->getData() : 0;
+}
+
+/*!
+ \internal
+ Sets the list iterator to point to the last item in the list.
+*/
+
+QCollection::Item QGListIterator::toLast()
+{
+ if ( !list ) {
+#if defined(CHECK_NULL)
+ qWarning( "QGListIterator::toLast: List has been deleted" );
+#endif
+ return 0;
+ }
+ return list->lastNode ? (curNode = list->lastNode)->getData() : 0;
+}
+
+
+/*!
+ \fn QCollection::Item QGListIterator::get() const
+ \internal
+ Returns the iterator item.
+*/
+
+
+/*!
+ \internal
+ Moves to the next item (postfix).
+*/
+
+QCollection::Item QGListIterator::operator()()
+{
+ if ( !curNode )
+ return 0;
+ QCollection::Item d = curNode->getData();
+ curNode = curNode->next;
+ return d;
+}
+
+/*!
+ \internal
+ Moves to the next item (prefix).
+*/
+
+QCollection::Item QGListIterator::operator++()
+{
+ if ( !curNode )
+ return 0;
+ curNode = curNode->next;
+ return curNode ? curNode->getData() : 0;
+}
+
+/*!
+ \internal
+ Moves \e jumps positions forward.
+*/
+
+QCollection::Item QGListIterator::operator+=( uint jumps )
+{
+ while ( curNode && jumps-- )
+ curNode = curNode->next;
+ return curNode ? curNode->getData() : 0;
+}
+
+/*!
+ \internal
+ Moves to the previous item (prefix).
+*/
+
+QCollection::Item QGListIterator::operator--()
+{
+ if ( !curNode )
+ return 0;
+ curNode = curNode->prev;
+ return curNode ? curNode->getData() : 0;
+}
+
+/*!
+ \internal
+ Moves \e jumps positions backward.
+*/
+
+QCollection::Item QGListIterator::operator-=( uint jumps )
+{
+ while ( curNode && jumps-- )
+ curNode = curNode->prev;
+ return curNode ? curNode->getData() : 0;
+}
diff --git a/qtools/qglist.h b/qtools/qglist.h
new file mode 100644
index 0000000..f400b64
--- /dev/null
+++ b/qtools/qglist.h
@@ -0,0 +1,257 @@
+/****************************************************************************
+**
+**
+** Definition of QGList and QGListIterator classes
+**
+** Created : 920624
+**
+** Copyright (C) 1992-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 QGLIST_H
+#define QGLIST_H
+
+#ifndef QT_H
+#include "qcollection.h"
+#endif // QT_H
+
+
+/*****************************************************************************
+ QLNode class (internal doubly linked list node)
+ *****************************************************************************/
+
+class Q_EXPORT QLNode
+{
+friend class QGList;
+friend class QGListIterator;
+public:
+ QCollection::Item getData() { return data; }
+private:
+ QCollection::Item data;
+ QLNode *prev;
+ QLNode *next;
+ QLNode( QCollection::Item d ) { data = d; }
+};
+
+
+/*****************************************************************************
+ QGList class
+ *****************************************************************************/
+
+class Q_EXPORT QGList : public QCollection // doubly linked generic list
+{
+friend class QGListIterator;
+friend class QGVector; // needed by QGVector::toList
+public:
+ uint count() const; // return number of nodes
+
+#ifndef QT_NO_DATASTREAM
+ QDataStream &read( QDataStream & ); // read list from stream
+ QDataStream &write( QDataStream & ) const; // write list to stream
+#endif
+protected:
+ QGList(); // create empty list
+ QGList( const QGList & ); // make copy of other list
+ virtual ~QGList();
+
+ QGList &operator=( const QGList & ); // assign from other list
+ bool operator==( const QGList& ) const;
+
+ void inSort( QCollection::Item ); // add item sorted in list
+ void append( QCollection::Item ); // add item at end of list
+ bool insertAt( uint index, QCollection::Item ); // add item at i'th position
+ void relinkNode( QLNode * ); // relink as first item
+ bool removeNode( QLNode * ); // remove node
+ bool remove( QCollection::Item = 0 ); // remove item (0=current)
+ bool removeRef( QCollection::Item = 0 ); // remove item (0=current)
+ bool removeFirst(); // remove first item
+ bool removeLast(); // remove last item
+ bool removeAt( uint index ); // remove item at i'th position
+ QCollection::Item takeNode( QLNode * ); // take out node
+ QCollection::Item take(); // take out current item
+ QCollection::Item takeAt( uint index ); // take out item at i'th pos
+ QCollection::Item takeFirst(); // take out first item
+ QCollection::Item takeLast(); // take out last item
+
+ void sort(); // sort all items;
+ void clear(); // remove all items
+
+ int findRef( QCollection::Item, bool = TRUE ); // find exact item in list
+ int find( QCollection::Item, bool = TRUE ); // find equal item in list
+
+ uint containsRef( QCollection::Item ) const; // get number of exact matches
+ uint contains( QCollection::Item ) const; // get number of equal matches
+
+ QCollection::Item at( uint index ); // access item at i'th pos
+ int at() const; // get current index
+ QLNode *currentNode() const; // get current node
+
+ QCollection::Item get() const; // get current item
+
+ QCollection::Item cfirst() const; // get ptr to first list item
+ QCollection::Item clast() const; // get ptr to last list item
+ QCollection::Item first(); // set first item in list curr
+ QCollection::Item last(); // set last item in list curr
+ QCollection::Item next(); // set next item in list curr
+ QCollection::Item prev(); // set prev item in list curr
+
+ void toVector( QGVector * ) const; // put items in vector
+
+ virtual int compareItems( QCollection::Item, QCollection::Item );
+
+#ifndef QT_NO_DATASTREAM
+ virtual QDataStream &read( QDataStream &, QCollection::Item & );
+ virtual QDataStream &write( QDataStream &, QCollection::Item ) const;
+#endif
+private:
+ void prepend( QCollection::Item ); // add item at start of list
+
+ void heapSortPushDown( QCollection::Item* heap, int first, int last );
+
+ QLNode *firstNode; // first node
+ QLNode *lastNode; // last node
+ QLNode *curNode; // current node
+ int curIndex; // current index
+ uint numNodes; // number of nodes
+ QGList *iterators; // list of iterators
+
+ QLNode *locate( uint ); // get node at i'th pos
+ QLNode *unlink(); // unlink node
+};
+
+
+inline uint QGList::count() const
+{
+ return numNodes;
+}
+
+inline bool QGList::removeFirst()
+{
+ first();
+ return remove();
+}
+
+inline bool QGList::removeLast()
+{
+ last();
+ return remove();
+}
+
+inline int QGList::at() const
+{
+ return curIndex;
+}
+
+inline QCollection::Item QGList::at( uint index )
+{
+ QLNode *n = locate( index );
+ return n ? n->data : 0;
+}
+
+inline QLNode *QGList::currentNode() const
+{
+ return curNode;
+}
+
+inline QCollection::Item QGList::get() const
+{
+ return curNode ? curNode->data : 0;
+}
+
+inline QCollection::Item QGList::cfirst() const
+{
+ return firstNode ? firstNode->data : 0;
+}
+
+inline QCollection::Item QGList::clast() const
+{
+ return lastNode ? lastNode->data : 0;
+}
+
+
+/*****************************************************************************
+ QGList stream functions
+ *****************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator>>( QDataStream &, QGList & );
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QGList & );
+#endif
+
+/*****************************************************************************
+ QGListIterator class
+ *****************************************************************************/
+
+class Q_EXPORT QGListIterator // QGList iterator
+{
+friend class QGList;
+protected:
+ QGListIterator( const QGList & );
+ QGListIterator( const QGListIterator & );
+ QGListIterator &operator=( const QGListIterator & );
+ ~QGListIterator();
+
+ bool atFirst() const; // test if at first item
+ bool atLast() const; // test if at last item
+ QCollection::Item toFirst(); // move to first item
+ QCollection::Item toLast(); // move to last item
+
+ QCollection::Item get() const; // get current item
+ QCollection::Item operator()(); // get current and move to next
+ QCollection::Item operator++(); // move to next item (prefix)
+ QCollection::Item operator+=(uint); // move n positions forward
+ QCollection::Item operator--(); // move to prev item (prefix)
+ QCollection::Item operator-=(uint); // move n positions backward
+
+protected:
+ QGList *list; // reference to list
+
+private:
+ QLNode *curNode; // current node in list
+};
+
+
+inline bool QGListIterator::atFirst() const
+{
+ return curNode == list->firstNode;
+}
+
+inline bool QGListIterator::atLast() const
+{
+ return curNode == list->lastNode;
+}
+
+inline QCollection::Item QGListIterator::get() const
+{
+ return curNode ? curNode->data : 0;
+}
+
+
+#endif // QGLIST_H
diff --git a/qtools/qglobal.cpp b/qtools/qglobal.cpp
new file mode 100644
index 0000000..2789e30
--- /dev/null
+++ b/qtools/qglobal.cpp
@@ -0,0 +1,678 @@
+/****************************************************************************
+**
+**
+** Global functions
+**
+** Created : 920604
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qglobal.h"
+#include "qasciidict.h"
+#include "qstring.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+// NOT REVISED
+
+/*!
+ \relates QApplication
+ Returns the Qt version number for the library, typically "1.30"
+ or "2.1.0".
+*/
+
+const char *qVersion()
+{
+ return QT_VERSION_STR;
+}
+
+
+/*****************************************************************************
+ System detection routines
+ *****************************************************************************/
+
+static bool si_alreadyDone = FALSE;
+static int si_wordSize;
+static bool si_bigEndian;
+
+/*!
+ \relates QApplication
+ Obtains information about the system.
+
+ The system's word size in bits (typically 32) is returned in \e *wordSize.
+ The \e *bigEndian is set to TRUE if this is a big-endian machine,
+ or to FALSE if this is a little-endian machine.
+
+ This function calls qFatal() with a message if the computer is truly weird
+ (i.e. different endianness for 16 bit and 32 bit integers).
+*/
+
+bool qSysInfo( int *wordSize, bool *bigEndian )
+{
+#if defined(CHECK_NULL)
+ ASSERT( wordSize != 0 );
+ ASSERT( bigEndian != 0 );
+#endif
+
+ if ( si_alreadyDone ) { // run it only once
+ *wordSize = si_wordSize;
+ *bigEndian = si_bigEndian;
+ return TRUE;
+ }
+ si_alreadyDone = TRUE;
+
+ si_wordSize = 0;
+ uint n = (uint)(~0);
+ while ( n ) { // detect word size
+ si_wordSize++;
+ n /= 2;
+ }
+ *wordSize = si_wordSize;
+
+ if ( *wordSize != 64 &&
+ *wordSize != 32 &&
+ *wordSize != 16 ) { // word size: 16, 32 or 64
+#if defined(CHECK_RANGE)
+ qFatal( "qSysInfo: Unsupported system word size %d", *wordSize );
+#endif
+ return FALSE;
+ }
+ if ( sizeof(Q_INT8) != 1 || sizeof(Q_INT16) != 2 || sizeof(Q_INT32) != 4 ||
+ sizeof(float) != 4 || sizeof(double) != 8 ) {
+#if defined(CHECK_RANGE)
+ qFatal( "qSysInfo: Unsupported system data type size" );
+#endif
+ return FALSE;
+ }
+
+ bool be16, be32; // determine byte ordering
+ short ns = 0x1234;
+ int nl = 0x12345678;
+
+ unsigned char *p = (unsigned char *)(&ns); // 16-bit integer
+ be16 = *p == 0x12;
+
+ p = (unsigned char *)(&nl); // 32-bit integer
+ if ( p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78 )
+ be32 = TRUE;
+ else
+ if ( p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] == 0x12 )
+ be32 = FALSE;
+ else
+ be32 = !be16;
+
+ if ( be16 != be32 ) { // strange machine!
+#if defined(CHECK_RANGE)
+ qFatal( "qSysInfo: Inconsistent system byte order" );
+#endif
+ return FALSE;
+ }
+
+ *bigEndian = si_bigEndian = be32;
+ return TRUE;
+}
+
+
+/*****************************************************************************
+ Debug output routines
+ *****************************************************************************/
+
+/*!
+ \fn void qDebug( const char *msg, ... )
+
+ \relates QApplication
+ Prints a debug message, or calls the message handler (if it has been
+ installed).
+
+ This function takes a format string and a list of arguments, similar to
+ the C printf() function.
+
+ Example:
+ \code
+ qDebug( "my window handle = %x", myWidget->id() );
+ \endcode
+
+ Under X11, the text is printed to stderr. Under Windows, the text is
+ sent to the debugger.
+
+ \warning The internal buffer is limited to 8196 bytes (including the
+ 0-terminator).
+
+ \sa qWarning(), qFatal(), qInstallMsgHandler(),
+ \link debug.html Debugging\endlink
+*/
+
+/*!
+ \fn void qWarning( const char *msg, ... )
+
+ \relates QApplication
+ Prints a warning message, or calls the message handler (if it has been
+ installed).
+
+ This function takes a format string and a list of arguments, similar to
+ the C printf() function.
+
+ Example:
+ \code
+ void f( int c )
+ {
+ if ( c > 200 )
+ qWarning( "f: bad argument, c == %d", c );
+ }
+ \endcode
+
+ Under X11, the text is printed to stderr. Under Windows, the text is
+ sent to the debugger.
+
+ \warning The internal buffer is limited to 8196 bytes (including the
+ 0-terminator).
+
+ \sa qDebug(), qFatal(), qInstallMsgHandler(),
+ \link debug.html Debugging\endlink
+*/
+
+/*!
+ \fn void qFatal( const char *msg, ... )
+
+ \relates QApplication
+ Prints a fatal error message and exits, or calls the message handler (if it
+ has been installed).
+
+ This function takes a format string and a list of arguments, similar to
+ the C printf() function.
+
+ Example:
+ \code
+ int divide( int a, int b )
+ {
+ if ( b == 0 ) // program error
+ qFatal( "divide: cannot divide by zero" );
+ return a/b;
+ }
+ \endcode
+
+ Under X11, the text is printed to stderr. Under Windows, the text is
+ sent to the debugger.
+
+ \warning The internal buffer is limited to 8196 bytes (including the
+ 0-terminator).
+
+ \sa qDebug(), qWarning(), qInstallMsgHandler(),
+ \link debug.html Debugging\endlink
+*/
+
+
+static msg_handler handler = 0; // pointer to debug handler
+
+
+#ifdef _OS_MAC_
+
+static FILE * mac_debug=0;
+
+void qDebug( const char *msg, ... )
+{
+ mac_debug=fopen( "debug.txt", "a+" );
+ if(mac_debug) {
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( mac_debug, msg, ap );
+ va_end( ap );
+ fprintf( mac_debug, "\n" ); // add newline
+ fflush( mac_debug );
+ }
+ fclose(mac_debug);
+ } else {
+ exit(0);
+ }
+}
+
+// copied... this looks really bad.
+void debug( const char *msg, ... )
+{
+ mac_debug=fopen( "debug.txt", "a+" );
+ if(mac_debug) {
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( mac_debug, msg, ap );
+ va_end( ap );
+ fprintf( mac_debug, "\n" ); // add newline
+ fflush( mac_debug );
+ }
+ fclose(mac_debug);
+ }
+}
+
+void qWarning( const char *msg, ... )
+{
+ mac_debug=fopen( "debug.txt", "a+" );
+ if(mac_debug) {
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( mac_debug, msg, ap );
+ va_end( ap );
+ fprintf( mac_debug, "\n" ); // add newline
+ fflush( mac_debug );
+ }
+ fclose(mac_debug);
+ }
+}
+
+// copied... this looks really bad.
+void warning( const char *msg, ... )
+{
+ mac_debug=fopen( "debug.txt", "a+" );
+ if(mac_debug) {
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( mac_debug, msg, ap );
+ va_end( ap );
+ fprintf( mac_debug, "\n" ); // add newline
+ fflush( mac_debug );
+ }
+ fclose(mac_debug);
+ }
+}
+
+void qFatal( const char *msg, ... )
+{
+ mac_debug=fopen( "debug.txt", "a+");
+ if(mac_debug) {
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( mac_debug, msg, ap );
+ va_end( ap );
+ fprintf( mac_debug, "\n" ); // add newline
+ fflush( mac_debug );
+ }
+ fclose(mac_debug);
+ }
+ exit(0);
+}
+
+// copied... this looks really bad.
+void fatal( const char *msg, ... )
+{
+ mac_debug=fopen( "debug.txt", "a+" );
+ if(mac_debug) {
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( mac_debug, msg, ap );
+ va_end( ap );
+ fprintf( mac_debug, "\n" ); // add newline
+ fflush( mac_debug );
+ }
+ fclose(mac_debug);
+ }
+ exit(0);
+}
+
+#else
+
+void qDebug( const char *msg, ... )
+{
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap ); // ### vsnprintf would be great here
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( stderr, msg, ap );
+ va_end( ap );
+ fprintf( stderr, "\n" ); // add newline
+ }
+}
+
+// copied... this looks really bad.
+void debug( const char *msg, ... )
+{
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtDebugMsg, buf );
+ } else {
+ vfprintf( stderr, msg, ap );
+ va_end( ap );
+ fprintf( stderr, "\n" ); // add newline
+ }
+}
+
+void qWarning( const char *msg, ... )
+{
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtWarningMsg, buf );
+ } else {
+ vfprintf( stderr, msg, ap );
+ va_end( ap );
+ fprintf( stderr, "\n" ); // add newline
+ }
+}
+
+
+// again, copied
+void warning( const char *msg, ... )
+{
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtWarningMsg, buf );
+ } else {
+ vfprintf( stderr, msg, ap );
+ va_end( ap );
+ fprintf( stderr, "\n" ); // add newline
+ }
+}
+
+void qFatal( const char *msg, ... )
+{
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtFatalMsg, buf );
+ } else {
+ vfprintf( stderr, msg, ap );
+ va_end( ap );
+ fprintf( stderr, "\n" ); // add newline
+#if defined(_OS_UNIX_) && defined(DEBUG)
+ abort(); // trap; generates core dump
+#else
+ exit( 1 ); // goodbye cruel world
+#endif
+ }
+}
+
+// yet again, copied
+void fatal( const char *msg, ... )
+{
+ char buf[8196];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+ if ( handler ) {
+ vsprintf( buf, msg, ap );
+ va_end( ap );
+ (*handler)( QtFatalMsg, buf );
+ } else {
+ vfprintf( stderr, msg, ap );
+ va_end( ap );
+ fprintf( stderr, "\n" ); // add newline
+#if defined(_OS_UNIX_) && defined(DEBUG)
+ abort(); // trap; generates core dump
+#else
+ exit( 1 ); // goodbye cruel world
+#endif
+ }
+}
+
+#endif
+
+
+/*!
+ \fn void ASSERT( bool test )
+ \relates QApplication
+ Prints a warning message containing the source code file name and line number
+ if \e test is FALSE.
+
+ This is really a macro defined in qglobal.h.
+
+ ASSERT is useful for testing required conditions in your program.
+
+ Example:
+ \code
+ //
+ // File: div.cpp
+ //
+
+ #include <qglobal.h>
+
+ int divide( int a, int b )
+ {
+ ASSERT( b != 0 ); // this is line 9
+ return a/b;
+ }
+ \endcode
+
+ If \c b is zero, the ASSERT statement will output the following message
+ using the qWarning() function:
+ \code
+ ASSERT: "b == 0" in div.cpp (9)
+ \endcode
+
+ \sa qWarning(), \link debug.html Debugging\endlink
+*/
+
+
+/*!
+ \fn void CHECK_PTR( void *p )
+ \relates QApplication
+ If \e p is null, a fatal messages says that the program ran out of memory
+ and exits. If \e p is not null, nothing happens.
+
+ This is really a macro defined in qglobal.h.
+
+ Example:
+ \code
+ int *a;
+ CHECK_PTR( a = new int[80] ); // never do this!
+ // do this instead:
+ a = new int[80];
+ CHECK_PTR( a ); // this is fine
+ \endcode
+
+ \sa qFatal(), \link debug.html Debugging\endlink
+*/
+
+
+//
+// The CHECK_PTR macro calls this function to check if an allocation went ok.
+//
+
+bool qt_check_pointer( bool c, const char *n, int l )
+{
+ if ( c )
+ qFatal( "In file %s, line %d: Out of memory", n, l );
+ return TRUE;
+}
+
+
+static bool firstObsoleteWarning(const char *obj, const char *oldfunc )
+{
+ static QAsciiDict<int> *obsoleteDict = 0;
+ if ( !obsoleteDict ) { // first time func is called
+ obsoleteDict = new QAsciiDict<int>;
+#if defined(DEBUG)
+ qDebug(
+ "You are using obsolete functions in the Qt library. Call the function\n"
+ "qSuppressObsoleteWarnings() to suppress obsolete warnings.\n"
+ );
+#endif
+ }
+ QCString s( obj );
+ s += "::";
+ s += oldfunc;
+ if ( obsoleteDict->find(s.data()) == 0 ) {
+ obsoleteDict->insert( s.data(), (int*)1 ); // anything different from 0
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool suppressObsolete = FALSE;
+
+void qSuppressObsoleteWarnings( bool suppress )
+{
+ suppressObsolete = suppress;
+}
+
+void qObsolete( const char *obj, const char *oldfunc, const char *newfunc )
+{
+ if ( suppressObsolete )
+ return;
+ if ( !firstObsoleteWarning(obj, oldfunc) )
+ return;
+ qDebug( "%s::%s: This function is obsolete, use %s instead",
+ obj, oldfunc, newfunc );
+}
+
+void qObsolete( const char *obj, const char *oldfunc )
+{
+ if ( suppressObsolete )
+ return;
+ if ( !firstObsoleteWarning(obj, oldfunc) )
+ return;
+ qDebug( "%s::%s: This function is obsolete.", obj, oldfunc );
+}
+
+void qObsolete( const char *message )
+{
+ if ( suppressObsolete )
+ return;
+ if ( !firstObsoleteWarning( "Qt", message) )
+ return;
+ qDebug( "%s", message );
+}
+
+
+/*!
+ \relates QApplication
+ Installs a Qt message handler. Returns a pointer to the message handler
+ previously defined.
+
+ The message handler is a function that prints out debug messages,
+ warnings and fatal error messages. The Qt library (debug version)
+ contains hundreds of warning messages that are printed when internal
+ errors (usually invalid function arguments) occur. If you implement
+ your own message handler, you get total control of these messages.
+
+ The default message handler prints the message to the standard output
+ under X11 or to the debugger under Windows. If it is a fatal message,
+ the application aborts immediately.
+
+ Only one message handler can be defined, since this is usually done on
+ an application-wide basis to control debug output.
+
+ To restore the message handler, call \c qInstallMsgHandler(0).
+
+ Example:
+ \code
+ #include <qapplication.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ void myMessageOutput( QtMsgType type, const char *msg )
+ {
+ switch ( type ) {
+ case QtDebugMsg:
+ fprintf( stderr, "Debug: %s\n", msg );
+ break;
+ case QtWarningMsg:
+ fprintf( stderr, "Warning: %s\n", msg );
+ break;
+ case QtFatalMsg:
+ fprintf( stderr, "Fatal: %s\n", msg );
+ abort(); // dump core on purpose
+ }
+ }
+
+ int main( int argc, char **argv )
+ {
+ qInstallMsgHandler( myMessageOutput );
+ QApplication a( argc, argv );
+ ...
+ return a.exec();
+ }
+ \endcode
+
+ \sa qDebug(), qWarning(), qFatal(), \link debug.html Debugging\endlink
+*/
+
+msg_handler qInstallMsgHandler( msg_handler h )
+{
+ msg_handler old = handler;
+ handler = h;
+ return old;
+}
+
+
+#ifdef _WS_WIN_
+bool qt_winunicode=FALSE;
+#endif
diff --git a/qtools/qglobal.h b/qtools/qglobal.h
new file mode 100644
index 0000000..314043a
--- /dev/null
+++ b/qtools/qglobal.h
@@ -0,0 +1,592 @@
+/****************************************************************************
+**
+**
+** Global type declarations and definitions
+**
+** Created : 920529
+**
+** Copyright (C) 1992-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 QGLOBAL_H
+#define QGLOBAL_H
+
+
+#define QT_VERSION 220
+#define QT_VERSION_STR "2.2.0"
+
+
+//
+// The operating system, must be one of: (_OS_x_)
+//
+// MAC - Macintosh
+// MSDOS - MS-DOS and Windows
+// OS2 - OS/2
+// OS2EMX - XFree86 on OS/2 (not PM)
+// WIN32 - Win32 (Windows 95/98 and Windows NT)
+// SUN - SunOS
+// SOLARIS - Sun Solaris
+// HPUX - HP-UX
+// ULTRIX - DEC Ultrix
+// LINUX - Linux
+// FREEBSD - FreeBSD
+// NETBSD - NetBSD
+// OPENBSD - OpenBSD
+// IRIX - SGI Irix
+// OSF - OSF Unix
+// BSDI - BSDI Unix
+// SCO - SCO of some sort
+// AIX - AIX Unix
+// UNIXWARE - SCO UnixWare
+// GNU - GNU Hurd
+// DGUX - DG Unix
+// UNIX - Any UNIX bsd/sysv system
+//
+
+#if defined(macintosh)
+#define _OS_MAC_
+#elif defined(MSDOS) || defined(_MSDOS) || defined(__MSDOS__)
+#define _OS_MSDOS_
+#elif defined(OS2) || defined(_OS2) || defined(__OS2__)
+#if defined(__EMX__)
+#define _OS_OS2EMX_
+#else
+#define _OS_OS2_
+#endif
+#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
+#define _OS_WIN32_
+#elif defined(__MWERKS__) && defined(__INTEL__)
+#define _OS_WIN32_
+#elif defined(sun) || defined(__sun) || defined(__sun__)
+#if defined(__SVR4)
+#define _OS_SOLARIS_
+#else
+#define _OS_SUN_
+#endif
+#elif defined(hpux) || defined(__hpux) || defined(__hpux__)
+#define _OS_HPUX_
+#elif defined(ultrix) || defined(__ultrix) || defined(__ultrix__)
+#define _OS_ULTRIX_
+#elif defined(reliantunix)
+#define _OS_RELIANTUNIX_
+#elif defined(linux) || defined(__linux) || defined(__linux__)
+#define _OS_LINUX_
+#if defined(__alpha__) || defined(__alpha)
+#define _OS_ALPHA_LINUX_
+#endif
+#elif defined(__FreeBSD__)
+#define _OS_FREEBSD_
+#elif defined(__NetBSD__)
+#define _OS_NETBSD_
+#elif defined(__OpenBSD__)
+#define _OS_OPENBSD_
+#elif defined(sgi) || defined(__sgi)
+#define _OS_IRIX_
+#elif defined(__osf__)
+#define _OS_OSF_
+#elif defined(bsdi) || defined(__bsdi__)
+#define _OS_BSDI_
+#elif defined(_AIX)
+#define _OS_AIX_
+#elif defined(__Lynx__)
+#define _OS_LYNXOS_
+#elif defined(_UNIXWARE)
+#define _OS_UNIXWARE_
+#elif defined(__GNU__)
+#define _OS_GNU_
+#elif defined(DGUX)
+#define _OS_DGUX_
+#elif defined(__QNX__)
+#define _OS_QNX_
+#elif defined(_SCO_DS) || defined(M_UNIX) || defined(M_XENIX)
+#define _OS_SCO_
+#elif defined(sco) || defined(_UNIXWARE7)
+#define _OS_UNIXWARE7_
+#elif !defined(_SCO_DS) && defined(__USLC__) && defined(__SCO_VERSION__)
+#define _OS_UNIXWARE7_
+#else
+#error "Qt has not been ported to this OS - talk to qt-bugs@trolltech.com"
+#endif
+
+#if defined(_OS_MAC_) || defined(_OS_MSDOS_) || defined(_OS_OS2_) || defined(_OS_WIN32_)
+#undef _OS_UNIX_
+#elif !defined(_OS_UNIX_)
+#define _OS_UNIX_
+// QT_CLEAN_NAMESPACE is not defined by default; it would break too
+// much code.
+#if !defined(QT_CLEAN_NAMESPACE) && !defined(UNIX)
+// ### remove 3.0
+#define UNIX
+#endif
+#endif
+
+
+//
+// The compiler, must be one of: (_CC_x_)
+//
+// SYM - Symantec C++ for both PC and Macintosh
+// MPW - MPW C++
+// MWERKS - Metroworks CodeWarrior
+// MSVC - Microsoft Visual C/C++
+// BOR - Borland/Turbo C++
+// WAT - Watcom C++
+// GNU - GNU C++
+// COMEAU - Comeau C++
+// EDG - Edison Design Group C++
+// OC - CenterLine ObjectCenter C++
+// SUN - Sun C++
+// DEC - DEC C++
+// HP - HPUX C++
+// USLC - SCO UnixWare C++
+// KAI - KAI C++
+//
+
+
+// Should be sorted most-authorative to least-authorative
+
+#if defined(__SC__)
+#define _CC_SYM_
+#elif defined( __KCC )
+#define _CC_KAI_
+#define Q_HAS_BOOL_TYPE
+#elif defined(applec)
+#define _CC_MPW_
+#elif defined(__MWERKS__)
+#define _CC_MWERKS_
+#define Q_HAS_BOOL_TYPE
+#elif defined(_MSC_VER)
+#define _CC_MSVC_
+#elif defined(__BORLANDC__) || defined(__TURBOC__)
+#define _CC_BOR_
+#elif defined(__WATCOMC__)
+#define _CC_WAT_
+#define Q_HAS_BOOL_TYPE
+#elif defined(__GNUC__)
+#define _CC_GNU_
+#if __GNUC__ == 2 && __GNUC_MINOR__ <= 7
+#define Q_FULL_TEMPLATE_INSTANTIATION
+#define Q_TEMPLATE_NEEDS_CLASS_DECLARATION
+#define Q_TEMPLATE_NEEDS_EXPLICIT_CONVERSION
+#define Q_SPURIOUS_NON_VOID_WARNING
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 96
+#define Q_DELETING_VOID_UNDEFINED
+#define Q_FP_CCAST_BROKEN
+#endif
+#if (defined(__arm__) || defined(__ARMEL__)) && !defined(QT_MOC_CPP)
+#define Q_PACKED __attribute__ ((packed))
+#endif
+#elif defined(__xlC__)
+#define _CC_XLC_
+#define Q_FULL_TEMPLATE_INSTANTIATION
+#elif defined(como40)
+#define _CC_EDG_
+#define _CC_COMEAU_
+#elif defined(__USLC__)
+#define _CC_USLC_
+#ifdef __EDG__ // UnixWare7
+#define Q_HAS_BOOL_TYPE
+#endif
+#elif defined(__EDG) || defined(__EDG__)
+// one observed on SGI DCC, the other documented
+#define Q_HAS_BOOL_TYPE
+#define _CC_EDG_
+#elif defined(OBJECTCENTER) || defined(CENTERLINE_CLPP)
+#define _CC_OC_
+#elif defined(__SUNPRO_CC)
+#define _CC_SUN_
+#if __SUNPRO_CC >= 0x500
+#define Q_HAS_BOOL_TYPE
+#define Q_SPARCWORKS_FUNCP_BUG
+#define Q_C_CALLBACKS
+#endif
+#elif defined(__DECCXX)
+#define _CC_DEC_
+#elif defined(__CDS__)
+#define _CC_CDS_
+#define Q_HAS_BOOL_TYPE
+#elif defined(_OS_HPUX_)
+// this test is from aCC online help
+#if defined(__HP_aCC) || __cplusplus >= 199707L
+// this is the aCC
+#define _CC_HP_ACC_
+#define Q_HAS_BOOL_TYPE
+#else
+// this is the CC
+#define _CC_HP_
+#define Q_FULL_TEMPLATE_INSTANTIATION
+#define Q_TEMPLATE_NEEDS_EXPLICIT_CONVERSION
+#endif // __HP_aCC
+#else
+#error "Qt has not been tested with this compiler - talk to qt-bugs@trolltech.com"
+#endif
+
+#if defined(_CC_COMEAU_)
+#define Q_C_CALLBACKS
+#endif
+
+#ifndef Q_PACKED
+#define Q_PACKED
+#endif
+
+// Window system setting
+
+#if defined(_OS_MAC_)
+#define _WS_MAC_
+#elif defined(_OS_MSDOS_)
+#define _WS_WIN16_
+#error "Qt requires Win32 and does not work with Windows 3.x"
+#elif defined(_WIN32_X11_)
+#define _WS_X11_
+#elif defined(_OS_WIN32_)
+#define _WS_WIN32_
+#elif defined(_OS_OS2_)
+#error "Qt does not work with OS/2 Presentation Manager or Workplace Shell"
+#elif defined(_OS_UNIX_)
+#ifdef QWS
+#define _WS_QWS_
+#else
+#define _WS_X11_
+#endif
+#endif
+
+#if defined(_WS_WIN16_) || defined(_WS_WIN32_)
+#define _WS_WIN_
+#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
+
+
+//
+// Useful type definitions for Qt
+//
+
+#if defined(bool)
+#define Q_HAS_BOOL_TYPE
+#elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 6)
+#define Q_HAS_BOOL_TYPE
+#elif _MSC_VER >= 1100 || __BORLANDC__ >= 0x500
+#define Q_HAS_BOOL_TYPE
+#elif defined(_CC_COMEAU_)
+#define Q_HAS_BOOL_TYPE
+#elif defined(sgi) && ( (_COMPILER_VERSION >= 710) || defined(_BOOL) )
+#define Q_HAS_BOOL_TYPE
+#elif defined(__DECCXX) && (__DECCXX_VER >= 60060005)
+#define Q_HAS_BOOL_TYPE
+#elif defined(_AIX) && (__xlC__ >= 0x500)
+#define Q_HAS_BOOL_TYPE
+#endif
+
+#if (QT_VERSION >= 300)
+#error "Use an enum for bool"
+#endif
+
+#if !defined(Q_HAS_BOOL_TYPE)
+#if defined(_CC_MSVC_)
+#define _CC_BOOL_DEF_
+#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(_CC_MSVC_)
+// Workaround for static const members.
+#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) ((a) > (b) ? (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-0.5);
+}
+
+
+//
+// Size-dependent types (architechture-dependent byte order)
+//
+
+// QT_CLEAN_NAMESPACE is not defined by default; it would break too
+// much code.
+#if !defined(QT_CLEAN_NAMESPACE)
+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
+typedef long Q_INT64; // up to 64 bit signed
+typedef unsigned long Q_UINT64; // up to 64 bit unsigned
+
+//
+// Data stream functions is provided by many classes (defined in qdatastream.h)
+//
+
+class QDataStream;
+
+
+
+#ifdef _WS_WIN_
+extern bool qt_winunicode;
+#endif
+
+#ifndef QT_H
+#include <qfeatures.h>
+#endif // QT_H
+
+//
+// Create Qt DLL if QT_DLL is defined (Windows only)
+//
+
+#if defined(_OS_WIN32_)
+#if defined(QT_NODLL)
+#undef QT_MAKEDLL
+#undef QT_DLL
+#endif
+#ifdef QT_DLL
+#if defined(QT_MAKEDLL) /* create a Qt DLL library */
+#undef QT_DLL
+#define Q_EXPORT __declspec(dllexport)
+#define Q_TEMPLATEDLL
+#undef Q_DISABLE_COPY /* avoid unresolved externals */
+#endif
+#endif
+#if defined(QT_DLL) /* use a Qt DLL library */
+#define Q_EXPORT __declspec(dllimport)
+#define Q_TEMPLATEDLL
+#undef Q_DISABLE_COPY /* avoid unresolved externals */
+#endif
+#else // ! _OS_WIN32_
+#undef QT_MAKEDLL /* ignore these for other platforms */
+#undef QT_DLL
+#endif
+
+#ifndef Q_EXPORT
+#define Q_EXPORT
+#endif
+
+//
+// System information
+//
+
+Q_EXPORT const char *qVersion();
+Q_EXPORT bool qSysInfo( int *wordSize, bool *bigEndian );
+
+
+//
+// Debugging and error handling
+//
+
+#if !defined(NO_CHECK)
+#define CHECK_STATE // check state of objects etc.
+#define CHECK_RANGE // check range of indexes etc.
+#define CHECK_NULL // check null pointers
+#define CHECK_MATH // check math functions
+#endif
+
+#if !defined(NO_DEBUG) && !defined(DEBUG)
+#define DEBUG // display debug messages
+#endif
+
+//
+// Avoid some particularly useless warnings from some stupid compilers.
+// To get ALL C++ compiler warnings, define CC_WARNINGS or comment out
+// the line "#define Q_NO_WARNINGS"
+//
+
+#if !defined(CC_WARNINGS)
+#define Q_NO_WARNINGS
+#endif
+#if defined(Q_NO_WARNINGS)
+#if defined(_CC_MSVC_)
+#pragma warning(disable: 4244)
+#pragma warning(disable: 4275)
+#pragma warning(disable: 4514)
+#pragma warning(disable: 4800)
+#elif defined(_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(_CC_MWERKS_)
+#pragma warn_possunwant off
+#endif
+#endif // Q_NO_WARNINGS
+
+//
+// Avoid dead code
+//
+
+#if defined(_CC_EDG_) || defined(_CC_WAT_)
+#define Q_NO_DEAD_CODE
+#endif
+
+//
+// Use to avoid "unused parameter" warnings
+//
+
+#define Q_UNUSED(x) x=x;
+#define Q_CONST_UNUSED(x) (void)x;
+
+Q_EXPORT void qDebug( const char *, ... ) // print debug message
+#if defined(_CC_GNU_) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+Q_EXPORT void qWarning( const char *, ... ) // print warning message
+#if defined(_CC_GNU_) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+Q_EXPORT void qFatal( const char *, ... ) // print fatal message and exit
+#if defined(_CC_GNU_)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+
+// QT_CLEAN_NAMESPACE is not defined by default; it would break too
+// much code.
+#if !defined(QT_CLEAN_NAMESPACE)
+// in that case, also define the old ones...
+
+Q_EXPORT void debug( const char *, ... ) // print debug message
+#if defined(_CC_GNU_) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+Q_EXPORT void warning( const char *, ... ) // print warning message
+#if defined(_CC_GNU_) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+Q_EXPORT void fatal( const char *, ... ) // print fatal message and exit
+#if defined(_CC_GNU_) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+// okay, that was debug()/warning()/fatal()
+#endif
+
+#if !defined(ASSERT)
+#if defined(CHECK_STATE)
+#if defined(QT_FATAL_ASSERT)
+#define ASSERT(x) if ( !(x) )\
+ qFatal("ASSERT: \"%s\" in %s (%d)",#x,__FILE__,__LINE__)
+#else
+#define ASSERT(x) if ( !(x) )\
+ qWarning("ASSERT: \"%s\" in %s (%d)",#x,__FILE__,__LINE__)
+#endif
+#else
+#define ASSERT(x)
+#endif
+#endif
+
+Q_EXPORT bool qt_check_pointer( bool c, const char *, int );
+
+#if defined(CHECK_NULL)
+#define CHECK_PTR(p) (qt_check_pointer((p)==0,__FILE__,__LINE__))
+#else
+#define CHECK_PTR(p)
+#endif
+
+enum QtMsgType { QtDebugMsg, QtWarningMsg, QtFatalMsg };
+
+typedef void (*msg_handler)(QtMsgType, const char *);
+Q_EXPORT msg_handler qInstallMsgHandler( msg_handler );
+
+
+Q_EXPORT void qSuppressObsoleteWarnings( bool = TRUE );
+
+#if !defined(QT_REJECT_OBSOLETE)
+#define QT_OBSOLETE
+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 );
+#endif
+
+#endif // QGLOBAL_H
diff --git a/qtools/qgvector.cpp b/qtools/qgvector.cpp
new file mode 100644
index 0000000..88409ce
--- /dev/null
+++ b/qtools/qgvector.cpp
@@ -0,0 +1,638 @@
+/****************************************************************************
+**
+**
+** Implementation of QGVector class
+**
+** Created : 930907
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#define QGVECTOR_CPP
+#include "qgvector.h"
+#include "qglist.h"
+#include "qstring.h"
+#include "qdatastream.h"
+#include <stdlib.h>
+
+#define USE_MALLOC // comment to use new/delete
+
+#undef NEW
+#undef DELETE
+
+#if defined(USE_MALLOC)
+#define NEW(type,size) ((type*)malloc(size*sizeof(type)))
+#define DELETE(array) (free((char*)array))
+#else
+#define NEW(type,size) (new type[size])
+#define DELETE(array) (delete[] array)
+#define DONT_USE_REALLOC // comment to use realloc()
+#endif
+
+// NOT REVISED
+
+/*!
+ \class QGVector qgvector.h
+
+ \brief The QGVector class is an internal class for implementing Qt
+ collection classes.
+
+ QGVector is a strictly internal class that acts as a base class for
+ the QVector collection class.
+
+ QGVector has some virtual functions that may be reimplemented in
+ subclasses to to customize behavior.
+
+ <ul>
+ <li> compareItems() compares two collection/vector items.
+ <li> read() reads a collection/vector item from a QDataStream.
+ <li> write() writes a collection/vector item to a QDataStream.
+ </ul>
+*/
+
+/*****************************************************************************
+ Default implementation of virtual functions
+ *****************************************************************************/
+
+/*!
+ This virtual function compares two list items.
+
+ Returns:
+ <ul>
+ <li> 0 if \a item1 == \a item2
+ <li> non-zero if \a item1 != \a item2
+ </ul>
+
+ This function returns \e int rather than \e bool so that
+ reimplementations can return one of three values and use it to sort
+ by:
+
+ <ul>
+ <li> 0 if \e item1 == \e item2
+ <li> \> 0 (positive integer) if \a item1 \> \a item2
+ <li> \< 0 (negative integer) if \a item1 \< \a item2
+ </ul>
+
+ The QVector::sort() and QVector::bsearch() functions require that
+ compareItems() is implemented as described here.
+
+ This function should not modify the vector because some const
+ functions call compareItems().
+*/
+
+int QGVector::compareItems( Item d1, Item d2 )
+{
+ return d1 != d2; // compare pointers
+}
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ Reads a collection/vector item from the stream \a s and returns a reference
+ to the stream.
+
+ The default implementation sets \e item to 0.
+
+ \sa write()
+*/
+
+QDataStream &QGVector::read( QDataStream &s, Item &d )
+{ // read item from stream
+ d = 0;
+ return s;
+}
+
+/*!
+ Writes a collection/vector item to the stream \a s and returns a reference
+ to the stream.
+
+ The default implementation does nothing.
+
+ \sa read()
+*/
+
+QDataStream &QGVector::write( QDataStream &s, Item ) const
+{ // write item to stream
+ return s;
+}
+#endif // QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QGVector member functions
+ *****************************************************************************/
+
+/*!
+ \internal
+*/
+
+QGVector::QGVector() // create empty vector
+{
+ vec = 0;
+ len = numItems = 0;
+}
+
+/*!
+ \internal
+*/
+QGVector::QGVector( uint size ) // create vectors with nullptrs
+{
+ len = size;
+ numItems = 0;
+ if ( len == 0 ) { // zero length
+ vec = 0;
+ return;
+ }
+ vec = NEW(Item,len);
+ CHECK_PTR( vec );
+ memset( (void*)vec, 0, len*sizeof(Item) ); // fill with nulls
+}
+
+/*!
+ \internal
+*/
+
+QGVector::QGVector( const QGVector &a ) // make copy of other vector
+ : QCollection( a )
+{
+ len = a.len;
+ numItems = a.numItems;
+ vec = NEW(Item,len);
+ CHECK_PTR( vec );
+ for ( uint i=0; i<len; i++ ) {
+ vec[i] = a.vec[i] ? newItem( a.vec[i] ) : 0;
+ CHECK_PTR( vec[i] );
+ }
+}
+
+/*!
+ \internal
+*/
+
+QGVector::~QGVector()
+{
+ clear();
+}
+
+
+/*!
+ \internal
+*/
+
+QGVector& QGVector::operator=( const QGVector &v )
+{ // assign from other vector
+ clear(); // first delete old vector
+ len = v.len;
+ numItems = v.numItems;
+ vec = NEW(Item,len); // create new vector
+ CHECK_PTR( vec );
+ for ( uint i=0; i<len; i++ ) { // copy elements
+ vec[i] = v.vec[i] ? newItem( v.vec[i] ) : 0;
+ CHECK_PTR( vec[i] );
+ }
+ return *this;
+}
+
+
+/*!
+ \fn Item *QGVector::data() const
+ \internal
+*/
+
+/*!
+ \fn uint QGVector::size() const
+ \internal
+*/
+
+/*!
+ \fn uint QGVector::count() const
+ \internal
+*/
+
+/*!
+ \fn Item QGVector::at( uint index ) const
+ \internal
+*/
+
+/*!
+ \internal
+*/
+
+bool QGVector::insert( uint index, Item d ) // insert item at index
+{
+#if defined(CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "QGVector::insert: Index %d out of range", index );
+ return FALSE;
+ }
+#endif
+ if ( vec[index] ) { // remove old item
+ deleteItem( vec[index] );
+ numItems--;
+ }
+ if ( d ) {
+ vec[index] = newItem( d );
+ CHECK_PTR( vec[index] );
+ numItems++;
+ return vec[index] != 0;
+ } else {
+ vec[index] = 0; // reset item
+ }
+ return TRUE;
+}
+
+/*!
+ \internal
+*/
+
+bool QGVector::remove( uint index ) // remove item at index
+{
+#if defined(CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "QGVector::remove: Index %d out of range", index );
+ return FALSE;
+ }
+#endif
+ if ( vec[index] ) { // valid item
+ deleteItem( vec[index] ); // delete it
+ vec[index] = 0; // reset pointer
+ numItems--;
+ }
+ return TRUE;
+}
+
+/*!
+ \internal
+*/
+
+QCollection::Item QGVector::take( uint index ) // take out item
+{
+#if defined(CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "QGVector::take: Index %d out of range", index );
+ return 0;
+ }
+#endif
+ Item d = vec[index]; // don't delete item
+ if ( d )
+ numItems--;
+ vec[index] = 0;
+ return d;
+}
+
+
+/*!
+ \internal
+*/
+
+void QGVector::clear() // clear vector
+{
+ if ( vec ) {
+ for ( uint i=0; i<len; i++ ) { // delete each item
+ if ( vec[i] )
+ deleteItem( vec[i] );
+ }
+ DELETE(vec);
+ vec = 0;
+ len = numItems = 0;
+ }
+}
+
+/*!
+ \internal
+*/
+
+bool QGVector::resize( uint newsize ) // resize array
+{
+ if ( newsize == len ) // nothing to do
+ return TRUE;
+ if ( vec ) { // existing data
+ if ( newsize < len ) { // shrink vector
+ uint i = newsize;
+ while ( i < len ) { // delete lost items
+ if ( vec[i] ) {
+ deleteItem( vec[i] );
+ numItems--;
+ }
+ i++;
+ }
+ }
+ if ( newsize == 0 ) { // vector becomes empty
+ DELETE(vec);
+ vec = 0;
+ len = numItems = 0;
+ return TRUE;
+ }
+#if defined(DONT_USE_REALLOC)
+ Item *newvec = NEW(Item,newsize); // manual realloc
+ memcpy( newvec, vec, (len < newsize ? len : newsize)*sizeof(Item) );
+ DELETE(vec);
+ vec = newvec;
+#else
+ vec = (Item*)realloc( (char *)vec, newsize*sizeof(Item) );
+#endif
+ } else { // create new vector
+ vec = NEW(Item,newsize);
+ len = numItems = 0;
+ }
+ CHECK_PTR( vec );
+ if ( !vec ) // no memory
+ return FALSE;
+ if ( newsize > len ) // init extra space added
+ memset( (void*)&vec[len], 0, (newsize-len)*sizeof(Item) );
+ len = newsize;
+ return TRUE;
+}
+
+
+/*!
+ \internal
+*/
+
+bool QGVector::fill( Item d, int flen ) // resize and fill vector
+{
+ if ( flen < 0 )
+ flen = len; // default: use vector length
+ else if ( !resize( flen ) )
+ return FALSE;
+ for ( uint i=0; i<(uint)flen; i++ ) // insert d at every index
+ insert( i, d );
+ return TRUE;
+}
+
+
+static QGVector *sort_vec=0; // current sort vector
+
+
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+
+static int cmp_vec( const void *n1, const void *n2 )
+{
+ return sort_vec->compareItems( *((QCollection::Item*)n1), *((QCollection::Item*)n2) );
+}
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
+
+
+/*!
+ \internal
+*/
+
+void QGVector::sort() // sort vector
+{
+ if ( count() == 0 ) // no elements
+ return;
+ register Item *start = &vec[0];
+ register Item *end = &vec[len-1];
+ Item tmp;
+ while ( TRUE ) { // put all zero elements behind
+ while ( start < end && *start != 0 )
+ start++;
+ while ( end > start && *end == 0 )
+ end--;
+ if ( start < end ) {
+ tmp = *start;
+ *start = *end;
+ *end = tmp;
+ } else {
+ break;
+ }
+ }
+ sort_vec = (QGVector*)this;
+ qsort( vec, count(), sizeof(Item), cmp_vec );
+ sort_vec = 0;
+}
+
+/*!
+ \internal
+*/
+
+int QGVector::bsearch( Item d ) const // binary search; when sorted
+{
+ if ( !len )
+ return -1;
+ if ( !d ) {
+#if defined(CHECK_NULL)
+ qWarning( "QGVector::bsearch: Cannot search for null object" );
+#endif
+ return -1;
+ }
+ int n1 = 0;
+ int n2 = len - 1;
+ int mid = 0;
+ bool found = FALSE;
+ while ( n1 <= n2 ) {
+ int res;
+ mid = (n1 + n2)/2;
+ if ( vec[mid] == 0 ) // null item greater
+ res = -1;
+ else
+ res = ((QGVector*)this)->compareItems( d, vec[mid] );
+ if ( res < 0 )
+ n2 = mid - 1;
+ else if ( res > 0 )
+ n1 = mid + 1;
+ else { // found it
+ found = TRUE;
+ break;
+ }
+ }
+ if ( !found )
+ return -1;
+ // search to first of equal items
+ while ( (mid - 1 >= 0) && !((QGVector*)this)->compareItems(d, vec[mid-1]) )
+ mid--;
+ return mid;
+}
+
+
+/*!
+ \internal
+*/
+
+int QGVector::findRef( Item d, uint index) const // find exact item in vector
+{
+#if defined(CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "QGVector::findRef: Index %d out of range", index );
+ return -1;
+ }
+#endif
+ for ( uint i=index; i<len; i++ ) {
+ if ( vec[i] == d )
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ \internal
+*/
+
+int QGVector::find( Item d, uint index ) const // find equal item in vector
+{
+#if defined(CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "QGVector::find: Index %d out of range", index );
+ return -1;
+ }
+#endif
+ for ( uint i=index; i<len; i++ ) {
+ if ( vec[i] == 0 && d == 0 ) // found null item
+ return i;
+ if ( vec[i] && ((QGVector*)this)->compareItems( vec[i], d ) == 0 )
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ \internal
+*/
+
+uint QGVector::containsRef( Item d ) const // get number of exact matches
+{
+ uint count = 0;
+ for ( uint i=0; i<len; i++ ) {
+ if ( vec[i] == d )
+ count++;
+ }
+ return count;
+}
+
+/*!
+ \internal
+*/
+
+uint QGVector::contains( Item d ) const // get number of equal matches
+{
+ uint count = 0;
+ for ( uint i=0; i<len; i++ ) {
+ if ( vec[i] == 0 && d == 0 ) // count null items
+ count++;
+ if ( vec[i] && ((QGVector*)this)->compareItems( vec[i], d ) == 0 )
+ count++;
+ }
+ return count;
+}
+
+
+/*!
+ \internal
+*/
+
+bool QGVector::insertExpand( uint index, Item d )// insert and grow if necessary
+{
+ if ( index >= len ) {
+ if ( !resize( index+1 ) ) // no memory
+ return FALSE;
+ }
+ insert( index, d );
+ return TRUE;
+}
+
+
+/*!
+ \internal
+*/
+
+void QGVector::toList( QGList *list ) const // store items in list
+{
+ list->clear();
+ for ( uint i=0; i<len; i++ ) {
+ if ( vec[i] )
+ list->append( vec[i] );
+ }
+}
+
+
+void QGVector::warningIndexRange( uint i )
+{
+#if defined(CHECK_RANGE)
+ qWarning( "QGVector::operator[]: Index %d out of range", i );
+#else
+ Q_UNUSED( i )
+#endif
+}
+
+
+/*****************************************************************************
+ QGVector stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator>>( QDataStream &s, QGVector &vec )
+{ // read vector
+ return vec.read( s );
+}
+
+QDataStream &operator<<( QDataStream &s, const QGVector &vec )
+{ // write vector
+ return vec.write( s );
+}
+
+/*!
+ \internal
+*/
+
+QDataStream &QGVector::read( QDataStream &s ) // read vector from stream
+{
+ uint num;
+ s >> num; // read number of items
+ clear(); // clear vector
+ resize( num );
+ for (uint i=0; i<num; i++) { // read all items
+ Item d;
+ read( s, d );
+ CHECK_PTR( d );
+ if ( !d ) // no memory
+ break;
+ vec[i] = d;
+ }
+ return s;
+}
+
+/*!
+ \internal
+*/
+
+QDataStream &QGVector::write( QDataStream &s ) const
+{ // write vector to stream
+ uint num = count();
+ s << num; // number of items to write
+ num = size();
+ for (uint i=0; i<num; i++) { // write non-null items
+ if ( vec[i] )
+ write( s, vec[i] );
+ }
+ return s;
+}
+#endif // QT_NO_DATASTREAM
diff --git a/qtools/qgvector.h b/qtools/qgvector.h
new file mode 100644
index 0000000..6a7999d
--- /dev/null
+++ b/qtools/qgvector.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+**
+** Definition of QGVector class
+**
+** Created : 930907
+**
+** Copyright (C) 1992-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 QGVECTOR_H
+#define QGVECTOR_H
+
+#ifndef QT_H
+#include "qcollection.h"
+#endif // QT_H
+
+
+class Q_EXPORT QGVector : public QCollection // generic vector
+{
+friend class QGList; // needed by QGList::toVector
+public:
+#ifndef QT_NO_DATASTREAM
+ QDataStream &read( QDataStream & ); // read vector from stream
+ QDataStream &write( QDataStream & ) const; // write vector to stream
+#endif
+ virtual int compareItems( Item, Item );
+
+protected:
+ QGVector(); // create empty vector
+ QGVector( uint size ); // create vector with nullptrs
+ QGVector( const QGVector &v ); // make copy of other vector
+ ~QGVector();
+
+ QGVector &operator=( const QGVector &v ); // assign from other vector
+
+ Item *data() const { return vec; }
+ uint size() const { return len; }
+ uint count() const { return numItems; }
+
+ bool insert( uint index, Item ); // insert item at index
+ bool remove( uint index ); // remove item
+ Item take( uint index ); // take out item
+
+ void clear(); // clear vector
+ bool resize( uint newsize ); // resize vector
+
+ bool fill( Item, int flen ); // resize and fill vector
+
+ void sort(); // sort vector
+ int bsearch( Item ) const; // binary search (when sorted)
+
+ int findRef( Item, uint index ) const; // find exact item in vector
+ int find( Item, uint index ) const; // find equal item in vector
+ uint containsRef( Item ) const; // get number of exact matches
+ uint contains( Item ) const; // get number of equal matches
+
+ Item at( uint index ) const // return indexed item
+ {
+#if defined(CHECK_RANGE)
+ if ( index >= len )
+ warningIndexRange( index );
+#endif
+ return vec[index];
+ }
+
+ bool insertExpand( uint index, Item ); // insert, expand if necessary
+
+ void toList( QGList * ) const; // put items in list
+
+#ifndef QT_NO_DATASTREAM
+ virtual QDataStream &read( QDataStream &, Item & );
+ virtual QDataStream &write( QDataStream &, Item ) const;
+#endif
+private:
+ Item *vec;
+ uint len;
+ uint numItems;
+
+ static void warningIndexRange( uint );
+};
+
+
+/*****************************************************************************
+ QGVector stream functions
+ *****************************************************************************/
+
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator>>( QDataStream &, QGVector & );
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QGVector & );
+#endif
+
+#endif // QGVECTOR_H
diff --git a/qtools/qintdict.h b/qtools/qintdict.h
new file mode 100644
index 0000000..ddc5fdf
--- /dev/null
+++ b/qtools/qintdict.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+**
+** Definition of QIntDict template class
+**
+** Created : 940624
+**
+** Copyright (C) 1992-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 QINTDICT_H
+#define QINTDICT_H
+
+#ifndef QT_H
+#include "qgdict.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QIntDict : public QGDict
+{
+public:
+ QIntDict(int size=17) : QGDict(size,IntKey,0,0) {}
+ QIntDict( const QIntDict<type> &d ) : QGDict(d) {}
+ ~QIntDict() { clear(); }
+ QIntDict<type> &operator=(const QIntDict<type> &d)
+ { return (QIntDict<type>&)QGDict::operator=(d); }
+ uint count() const { return QGDict::count(); }
+ uint size() const { return QGDict::size(); }
+ bool isEmpty() const { return QGDict::count() == 0; }
+ void insert( long k, const type *d )
+ { QGDict::look_int(k,(Item)d,1); }
+ void replace( long k, const type *d )
+ { QGDict::look_int(k,(Item)d,2); }
+ bool remove( long k ) { return QGDict::remove_int(k); }
+ type *take( long k ) { return (type*)QGDict::take_int(k); }
+ type *find( long k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_int(k,0,0); }
+ type *operator[]( long k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_int(k,0,0); }
+ void clear() { QGDict::clear(); }
+ void resize( uint n ) { QGDict::resize(n); }
+ void statistics() const { QGDict::statistics(); }
+private:
+ void deleteItem( Item d );
+};
+
+#if defined(Q_DELETING_VOID_UNDEFINED)
+template<> inline void QIntDict<void>::deleteItem( QCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void QIntDict<type>::deleteItem( QCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+template<class type> class Q_EXPORT QIntDictIterator : public QGDictIterator
+{
+public:
+ QIntDictIterator(const QIntDict<type> &d) :QGDictIterator((QGDict &)d) {}
+ ~QIntDictIterator() {}
+ uint count() const { return dict->count(); }
+ bool isEmpty() const { return dict->count() == 0; }
+ type *toFirst() { return (type *)QGDictIterator::toFirst(); }
+ operator type *() const { return (type *)QGDictIterator::get(); }
+ type *current() const { return (type *)QGDictIterator::get(); }
+ long currentKey() const { return QGDictIterator::getKeyInt(); }
+ type *operator()() { return (type *)QGDictIterator::operator()(); }
+ type *operator++() { return (type *)QGDictIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j);}
+};
+
+
+#endif // QINTDICT_H
diff --git a/qtools/qiodevice.cpp b/qtools/qiodevice.cpp
new file mode 100644
index 0000000..b2a6751
--- /dev/null
+++ b/qtools/qiodevice.cpp
@@ -0,0 +1,636 @@
+/****************************************************************************
+**
+**
+** Implementation of QIODevice class
+**
+** Created : 940913
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qiodevice.h"
+
+// NOT REVISED
+/*!
+ \class QIODevice qiodevice.h
+
+ \brief The QIODevice class is the base class of I/O devices.
+
+ \ingroup io
+
+ An I/O device represents a medium that one can read bytes from
+ and/or write bytes to. The QIODevice class is the abstract
+ superclass of all such devices; classes like QFile, QBuffer and
+ QSocket inherit QIODevice and implement virtual functions like
+ write() appropriately.
+
+ While applications sometimes use QIODevice directly, mostly it is
+ better to go through QTextStream and QDataStream, which provide
+ stream operations on any QIODevice subclass. QTextStream provides
+ text-oriented stream functionality (for human-readable ASCII files,
+ for example), while QDataStream deals with binary data in a totally
+ platform-independent manner.
+
+ The public member functions in QIODevice roughly fall into two
+ groups: The action functions and the state access functions. The
+ most important action functions are: <ul>
+
+ <li> open() opens a device for reading and/or writing, depending on
+ the argument to open().
+
+ <li> close() closes the device and tidies up.
+
+ <li> readBlock() reads a block of data from the device.
+
+ <li> writeBlock() writes a block of data to the device.
+
+ <li> readLine() reads a line (of text, usually) from the device.
+
+ <li> flush() ensures that all buffered data are written to the real device.
+
+ </ul>There are also some other, less used, action functions: <ul>
+
+ <li> getch() reads a single character.
+
+ <li> ungetch() forgets the last call to getch(), if possible.
+
+ <li> putch() writes a single character.
+
+ <li> size() returns the size of the device, if there is one.
+
+ <li> at() returns the current read/write pointer, if there is one
+ for this device, or it moves the pointer.
+
+ <li> atEnd() says whether there is more to read, if that is a
+ meaningful question for this device.
+
+ <li> reset() moves the read/write pointer to the start of the
+ device, if that is possible for this device.
+
+ </ul>The state access are all "get" functions. The QIODevice subclass
+ calls setState() to update the state, and simple access functions
+ tell the user of the device what the device's state is. Here are
+ the settings, and their associated access functions: <ul>
+
+ <li> Access type. Some devices are direct access (it is possible to
+ read/write anywhere) while others are sequential. QIODevice
+ provides the access functions isDirectAccess(), isSequentialAccess()
+ and isCombinedAccess() to tell users what a given I/O device
+ supports.
+
+ <li> Buffering. Some devices are accessed in raw mode while others
+ are buffered. Buffering usually provides greater efficiency,
+ particularly for small read/write operations. isBuffered() tells
+ the user whether a given device is buffered. (This can often be set
+ by the application in the call to open().)
+
+ <li> Synchronicity. Synchronous devices work there and then, for
+ example files. When you read from a file, the file delivers its
+ data right away. Others, such as a socket connected to a HTTP
+ server, may not deliver the data until seconds after you ask to read
+ it. isSynchronous() and isAsynchronous() tells the user how this
+ device operates.
+
+ <li> CR/LF translation. For simplicity, applications often like to
+ see just a single CR/LF style, and QIODevice subclasses can provide
+ that. isTranslated() returns TRUE if this object translates CR/LF
+ to just LF. (This can often be set by the application in the call
+ to open().)
+
+ <li> Accessibility. Some files cannot be written, for example.
+ isReadable(), isWritable and isReadWrite() tells the application
+ whether it can read from and write to a given device. (This can
+ often be set by the application in the call to open().)
+
+ <li> Finally, isOpen() returns TRUE if the device is open. This can
+ quite obviously be set using open() :)
+
+ </ul>
+
+ QIODevice provides numerous pure virtual functions you need to
+ implement when subclassing it. Here is a skeleton subclass with all
+ the members you are certain to need, and some it's likely that you
+ will need:
+
+ \code
+ class YourDevice : public QIODevice
+ {
+ public:
+ YourDevice();
+ ~YourDevice();
+
+ bool open( int mode );
+ void close();
+ void flush();
+
+ uint size() const;
+ int at() const; // not a pure virtual function
+ bool at( int ); // not a pure virtual function
+ bool atEnd() const; // not a pure virtual function
+
+ int readBlock( char *data, uint maxlen );
+ int writeBlock( const char *data, uint len );
+ int readLine( char *data, uint maxlen );
+
+ int getch();
+ int putch( int );
+ int ungetch( int );
+ };
+ \endcode
+
+ The three non-pure virtual functions can be ignored if your device
+ is sequential (e.g. an RS-232 port).
+
+ \sa QDataStream, QTextStream
+*/
+
+
+/*!
+ Constructs an I/O device.
+*/
+
+QIODevice::QIODevice()
+{
+ ioMode = 0; // initial mode
+ ioSt = IO_Ok;
+ ioIndex = 0;
+}
+
+/*!
+ Destructs the I/O device.
+*/
+
+QIODevice::~QIODevice()
+{
+}
+
+
+/*!
+ \fn int QIODevice::flags() const
+ Returns the current I/O device flags setting.
+
+ Flags consists of mode flags and state flags.
+
+ \sa mode(), state()
+*/
+
+/*!
+ \fn int QIODevice::mode() const
+ Returns bits OR'ed together that specify the current operation mode.
+
+ These are the flags that were given to the open() function.
+
+ The flags are: \c IO_ReadOnly, \c IO_WriteOnly, \c IO_ReadWrite,
+ \c IO_Append, \c IO_Truncate and \c IO_Translate.
+*/
+
+/*!
+ \fn int QIODevice::state() const
+ Returns bits OR'ed together that specify the current state.
+
+ The flags are: \c IO_Open.
+
+ Subclasses may define more flags.
+*/
+
+/*!
+ \fn bool QIODevice::isDirectAccess() const
+ Returns TRUE if the I/O device is a direct access (not sequential) device,
+ otherwise FALSE.
+ \sa isSequentialAccess()
+*/
+
+/*!
+ \fn bool QIODevice::isSequentialAccess() const
+ Returns TRUE if the I/O device is a sequential access (not direct) device,
+ otherwise FALSE. Operations involving size() and at(int) are not valid
+ on sequential devices.
+ \sa isDirectAccess()
+*/
+
+/*!
+ \fn bool QIODevice::isCombinedAccess() const
+ Returns TRUE if the I/O device is a combined access (both direct and
+ sequential) device, otherwise FALSE.
+
+ This access method is currently not in use.
+*/
+
+/*!
+ \fn bool QIODevice::isBuffered() const
+ Returns TRUE if the I/O device is a buffered (not raw) device, otherwise
+ FALSE.
+ \sa isRaw()
+*/
+
+/*!
+ \fn bool QIODevice::isRaw() const
+ Returns TRUE if the I/O device is a raw (not buffered) device, otherwise
+ FALSE.
+ \sa isBuffered()
+*/
+
+/*!
+ \fn bool QIODevice::isSynchronous() const
+ Returns TRUE if the I/O device is a synchronous device, otherwise
+ FALSE.
+ \sa isAsynchronous()
+*/
+
+/*!
+ \fn bool QIODevice::isAsynchronous() const
+ Returns TRUE if the I/O device is a asynchronous device, otherwise
+ FALSE.
+
+ This mode is currently not in use.
+
+ \sa isSynchronous()
+*/
+
+/*!
+ \fn bool QIODevice::isTranslated() const
+ Returns TRUE if the I/O device translates carriage-return and linefeed
+ characters.
+
+ A QFile is translated if it is opened with the \c IO_Translate mode
+ flag.
+*/
+
+/*!
+ \fn bool QIODevice::isReadable() const
+ Returns TRUE if the I/O device was opened using \c IO_ReadOnly or
+ \c IO_ReadWrite mode.
+ \sa isWritable(), isReadWrite()
+*/
+
+/*!
+ \fn bool QIODevice::isWritable() const
+ Returns TRUE if the I/O device was opened using \c IO_WriteOnly or
+ \c IO_ReadWrite mode.
+ \sa isReadable(), isReadWrite()
+*/
+
+/*!
+ \fn bool QIODevice::isReadWrite() const
+ Returns TRUE if the I/O device was opened using \c IO_ReadWrite mode.
+ \sa isReadable(), isWritable()
+*/
+
+/*!
+ \fn bool QIODevice::isInactive() const
+ Returns TRUE if the I/O device state is 0, i.e. the device is not open.
+ \sa isOpen()
+*/
+
+/*!
+ \fn bool QIODevice::isOpen() const
+ Returns TRUE if the I/O device state has been opened, otherwise FALSE.
+ \sa isInactive()
+*/
+
+
+/*!
+ \fn int QIODevice::status() const
+ Returns the I/O device status.
+
+ The I/O device status returns an error code. If open() returns FALSE
+ or readBlock() or writeBlock() return -1, this function can be called to
+ get the reason why the operation did not succeed.
+
+ The status codes are:
+ <ul>
+ <li>\c IO_Ok The operation was successful.
+ <li>\c IO_ReadError Could not read from the device.
+ <li>\c IO_WriteError Could not write to the device.
+ <li>\c IO_FatalError A fatal unrecoverable error occurred.
+ <li>\c IO_OpenError Could not open the device.
+ <li>\c IO_ConnectError Could not connect to the device.
+ <li>\c IO_AbortError The operation was unexpectedly aborted.
+ <li>\c IO_TimeOutError The operation timed out.
+ <li>\c IO_OnCloseError An unspecified error happened on close.
+ </ul>
+
+ \sa resetStatus()
+*/
+
+/*!
+ \fn void QIODevice::resetStatus()
+
+ Sets the I/O device status to \c IO_Ok.
+
+ \sa status()
+*/
+
+
+/*!
+ \fn void QIODevice::setFlags( int f )
+ \internal
+ Used by subclasses to set the device flags.
+*/
+
+/*!
+ \internal
+ Used by subclasses to set the device type.
+*/
+
+void QIODevice::setType( int t )
+{
+#if defined(CHECK_RANGE)
+ if ( (t & IO_TypeMask) != t )
+ qWarning( "QIODevice::setType: Specified type out of range" );
+#endif
+ ioMode &= ~IO_TypeMask; // reset type bits
+ ioMode |= t;
+}
+
+/*!
+ \internal
+ Used by subclasses to set the device mode.
+*/
+
+void QIODevice::setMode( int m )
+{
+#if defined(CHECK_RANGE)
+ if ( (m & IO_ModeMask) != m )
+ qWarning( "QIODevice::setMode: Specified mode out of range" );
+#endif
+ ioMode &= ~IO_ModeMask; // reset mode bits
+ ioMode |= m;
+}
+
+/*!
+ \internal
+ Used by subclasses to set the device state.
+*/
+
+void QIODevice::setState( int s )
+{
+#if defined(CHECK_RANGE)
+ if ( ((uint)s & IO_StateMask) != (uint)s )
+ qWarning( "QIODevice::setState: Specified state out of range" );
+#endif
+ ioMode &= ~IO_StateMask; // reset state bits
+ ioMode |= (uint)s;
+}
+
+/*!
+ \internal
+ Used by subclasses to set the device status (not state).
+*/
+
+void QIODevice::setStatus( int s )
+{
+ ioSt = s;
+}
+
+
+/*!
+ \fn bool QIODevice::open( int mode )
+ Opens the I/O device using the specified \e mode.
+ Returns TRUE if successful, or FALSE if the device could not be opened.
+
+ The mode parameter \e m must be a combination of the following flags.
+ <ul>
+ <li>\c IO_Raw specified raw (unbuffered) file access.
+ <li>\c IO_ReadOnly opens a file in read-only mode.
+ <li>\c IO_WriteOnly opens a file in write-only mode.
+ <li>\c IO_ReadWrite opens a file in read/write mode.
+ <li>\c IO_Append sets the file index to the end of the file.
+ <li>\c IO_Truncate truncates the file.
+ <li>\c IO_Translate enables carriage returns and linefeed translation
+ for text files under MS-DOS, Window, OS/2 and Macintosh. Cannot be
+ combined with \c IO_Raw.
+ </ul>
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa close()
+*/
+
+/*!
+ \fn void QIODevice::close()
+ Closes the I/O device.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa open()
+*/
+
+/*!
+ \fn void QIODevice::flush()
+
+ Flushes an open I/O device.
+
+ This virtual function must be reimplemented by all subclasses.
+*/
+
+
+/*!
+ \fn uint QIODevice::size() const
+ Virtual function that returns the size of the I/O device.
+ \sa at()
+*/
+
+/*!
+ Virtual function that returns the current I/O device index.
+
+ This index is the data read/write head of the I/O device.
+
+ \sa size()
+*/
+
+int QIODevice::at() const
+{
+ return ioIndex;
+}
+
+/*!
+ Virtual function that sets the I/O device index to \e pos.
+ \sa size()
+*/
+
+bool QIODevice::at( int pos )
+{
+#if defined(CHECK_RANGE)
+ if ( (uint)pos > size() ) {
+ qWarning( "QIODevice::at: Index %d out of range", pos );
+ return FALSE;
+ }
+#endif
+ ioIndex = pos;
+ return TRUE;
+}
+
+/*!
+ Virtual function that returns TRUE if the I/O device index is at the
+ end of the input.
+*/
+
+bool QIODevice::atEnd() const
+{
+ if ( isSequentialAccess() || isTranslated() ) {
+ QIODevice* that = (QIODevice*)this;
+ int c = that->getch();
+ bool result = c < 0;
+ that->ungetch(c);
+ return result;
+ } else {
+ return at() == (int)size();
+ }
+}
+
+/*!
+ \fn bool QIODevice::reset()
+ Sets the device index to 0.
+ \sa at()
+*/
+
+
+/*!
+ \fn int QIODevice::readBlock( char *data, uint maxlen )
+ Reads at most \e maxlen bytes from the I/O device into \e data and
+ returns the number of bytes actually read.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa writeBlock()
+*/
+
+/*!
+ This convenience function returns all of the remaining data in the
+ device. Note that this only works for direct access devices, such
+ as QFile.
+
+ \sa isDirectAccess()
+*/
+QByteArray QIODevice::readAll()
+{
+ int n = size()-at();
+ QByteArray ba(size()-at());
+ char* c = ba.data();
+ while ( n ) {
+ int r = readBlock( c, n );
+ if ( r < 0 )
+ return QByteArray();
+ n -= r;
+ c += r;
+ }
+ return ba;
+}
+
+/*!
+ \fn int QIODevice::writeBlock( const char *data, uint len )
+ Writes \e len bytes from \e p to the I/O device and returns the number of
+ bytes actually written.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa readBlock()
+*/
+
+/*!
+ This convenience function is the same as calling
+ writeBlock( data.data(), data.size() ).
+*/
+int QIODevice::writeBlock( const QByteArray& data )
+{
+ return writeBlock( data.data(), data.size() );
+}
+
+/*!
+ Reads a line of text, up to \e maxlen bytes including a terminating
+ \0. If there is a newline at the end if the line, it is not stripped.
+
+ Returns the number of bytes read, or -1 in case of error.
+
+ This virtual function can be reimplemented much more efficiently by
+ the most subclasses.
+
+ \sa readBlock(), QTextStream::readLine()
+*/
+
+int QIODevice::readLine( char *data, uint maxlen )
+{
+ if ( maxlen == 0 ) // application bug?
+ return 0;
+ int pos = at(); // get current position
+ int s = (int)size(); // size of I/O device
+ char *p = data;
+ if ( pos >= s )
+ return 0;
+ while ( pos++ < s && --maxlen ) { // read one byte at a time
+ readBlock( p, 1 );
+ if ( *p++ == '\n' ) // end of line
+ break;
+ }
+ *p++ = '\0';
+ return (int)((long)p - (long)data);
+}
+
+
+/*!
+ \fn int QIODevice::getch()
+
+ Reads a single byte/character from the I/O device.
+
+ Returns the byte/character read, or -1 if the end of the I/O device has been
+ reached.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa putch(), ungetch()
+*/
+
+/*!
+ \fn int QIODevice::putch( int ch )
+
+ Writes the character \e ch to the I/O device.
+
+ Returns \e ch, or -1 if some error occurred.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa getch(), ungetch()
+*/
+
+/*!
+ \fn int QIODevice::ungetch( int ch )
+
+ Puts the character \e ch back into the I/O device and decrements the
+ index if it is not zero.
+
+ This function is normally called to "undo" a getch() operation.
+
+ Returns \e ch, or -1 if some error occurred.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa getch(), putch()
+*/
diff --git a/qtools/qiodevice.h b/qtools/qiodevice.h
new file mode 100644
index 0000000..1c54217
--- /dev/null
+++ b/qtools/qiodevice.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+**
+** Definition of QIODevice class
+**
+** Created : 940913
+**
+** Copyright (C) 1992-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 QIODEVICE_H
+#define QIODEVICE_H
+
+#ifndef QT_H
+#include "qglobal.h"
+#include "qcstring.h"
+#endif // QT_H
+
+
+// IO device access types
+
+#define IO_Direct 0x0100 // direct access device
+#define IO_Sequential 0x0200 // sequential access device
+#define IO_Combined 0x0300 // combined direct/sequential
+#define IO_TypeMask 0x0f00
+
+// IO handling modes
+
+#define IO_Raw 0x0040 // raw access (not buffered)
+#define IO_Async 0x0080 // asynchronous mode
+
+// IO device open modes
+
+#define IO_ReadOnly 0x0001 // readable device
+#define IO_WriteOnly 0x0002 // writable device
+#define IO_ReadWrite 0x0003 // read+write device
+#define IO_Append 0x0004 // append
+#define IO_Truncate 0x0008 // truncate device
+#define IO_Translate 0x0010 // translate CR+LF
+#define IO_ModeMask 0x00ff
+
+// IO device state
+
+#define IO_Open 0x1000 // device is open
+#define IO_StateMask 0xf000
+
+
+// IO device status
+
+#define IO_Ok 0
+#define IO_ReadError 1 // read error
+#define IO_WriteError 2 // write error
+#define IO_FatalError 3 // fatal unrecoverable error
+#define IO_ResourceError 4 // resource limitation
+#define IO_OpenError 5 // cannot open device
+#define IO_ConnectError 5 // cannot connect to device
+#define IO_AbortError 6 // abort error
+#define IO_TimeOutError 7 // time out
+#define IO_UnspecifiedError 8 // unspecified error
+
+class Q_EXPORT QIODevice // IO device class
+{
+public:
+ QIODevice();
+ virtual ~QIODevice();
+
+ int flags() const { return ioMode; }
+ int mode() const { return ioMode & IO_ModeMask; }
+ int state() const { return ioMode & IO_StateMask; }
+
+ bool isDirectAccess() const { return ((ioMode & IO_Direct) == IO_Direct); }
+ bool isSequentialAccess() const { return ((ioMode & IO_Sequential) == IO_Sequential); }
+ bool isCombinedAccess() const { return ((ioMode & IO_Combined) == IO_Combined); }
+ bool isBuffered() const { return ((ioMode & IO_Raw) != IO_Raw); }
+ bool isRaw() const { return ((ioMode & IO_Raw) == IO_Raw); }
+ bool isSynchronous() const { return ((ioMode & IO_Async) != IO_Async); }
+ bool isAsynchronous() const { return ((ioMode & IO_Async) == IO_Async); }
+ bool isTranslated() const { return ((ioMode & IO_Translate) == IO_Translate); }
+ bool isReadable() const { return ((ioMode & IO_ReadOnly) == IO_ReadOnly); }
+ bool isWritable() const { return ((ioMode & IO_WriteOnly) == IO_WriteOnly); }
+ bool isReadWrite() const { return ((ioMode & IO_ReadWrite) == IO_ReadWrite); }
+ bool isInactive() const { return state() == 0; }
+ bool isOpen() const { return state() == IO_Open; }
+
+ int status() const { return ioSt; }
+ void resetStatus() { ioSt = IO_Ok; }
+
+ virtual bool open( int mode ) = 0;
+ virtual void close() = 0;
+ virtual void flush() = 0;
+
+ virtual uint size() const = 0;
+ virtual int at() const;
+ virtual bool at( int );
+ virtual bool atEnd() const;
+ bool reset() { return at(0); }
+
+ virtual int readBlock( char *data, uint maxlen ) = 0;
+ virtual int writeBlock( const char *data, uint len ) = 0;
+ virtual int readLine( char *data, uint maxlen );
+ int writeBlock( const QByteArray& data );
+ QByteArray readAll();
+
+ virtual int getch() = 0;
+ virtual int putch( int ) = 0;
+ virtual int ungetch( int ) = 0;
+
+protected:
+ void setFlags( int f ) { ioMode = f; }
+ void setType( int );
+ void setMode( int );
+ void setState( int );
+ void setStatus( int );
+ int ioIndex;
+
+private:
+ int ioMode;
+ int ioSt;
+
+private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ QIODevice( const QIODevice & );
+ QIODevice &operator=( const QIODevice & );
+#endif
+};
+
+
+#endif // QIODEVICE_H
diff --git a/qtools/qlist.h b/qtools/qlist.h
new file mode 100644
index 0000000..678e92d
--- /dev/null
+++ b/qtools/qlist.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+**
+** Definition of QList template/macro class
+**
+** Created : 920701
+**
+** Copyright (C) 1992-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 QLIST_H
+#define QLIST_H
+
+#ifndef QT_H
+#include "qglist.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QList : public QGList
+{
+public:
+ QList() {}
+ QList( const QList<type> &l ) : QGList(l) {}
+ ~QList() { clear(); }
+ QList<type> &operator=(const QList<type> &l)
+ { return (QList<type>&)QGList::operator=(l); }
+ bool operator==( const QList<type> &list ) const
+ { return QGList::operator==( list ); }
+ uint count() const { return QGList::count(); }
+ bool isEmpty() const { return QGList::count() == 0; }
+ bool insert( uint i, const type *d){ return QGList::insertAt(i,(QCollection::Item)d); }
+ void inSort( const type *d ) { QGList::inSort((QCollection::Item)d); }
+ void prepend( const type *d ) { QGList::insertAt(0,(QCollection::Item)d); }
+ void append( const type *d ) { QGList::append((QCollection::Item)d); }
+ bool remove( uint i ) { return QGList::removeAt(i); }
+ bool remove() { return QGList::remove((QCollection::Item)0); }
+ bool remove( const type *d ) { return QGList::remove((QCollection::Item)d); }
+ bool removeRef( const type *d ) { return QGList::removeRef((QCollection::Item)d); }
+ void removeNode( QLNode *n ) { QGList::removeNode(n); }
+ bool removeFirst() { return QGList::removeFirst(); }
+ bool removeLast() { return QGList::removeLast(); }
+ type *take( uint i ) { return (type *)QGList::takeAt(i); }
+ type *take() { return (type *)QGList::take(); }
+ type *takeNode( QLNode *n ) { return (type *)QGList::takeNode(n); }
+ void clear() { QGList::clear(); }
+ void sort() { QGList::sort(); }
+ int find( const type *d ) { return QGList::find((QCollection::Item)d); }
+ int findNext( const type *d ) { return QGList::find((QCollection::Item)d,FALSE); }
+ int findRef( const type *d ) { return QGList::findRef((QCollection::Item)d); }
+ int findNextRef( const type *d ){ return QGList::findRef((QCollection::Item)d,FALSE);}
+ uint contains( const type *d ) const { return QGList::contains((QCollection::Item)d); }
+ uint containsRef( const type *d ) const
+ { return QGList::containsRef((QCollection::Item)d); }
+ type *at( uint i ) { return (type *)QGList::at(i); }
+ int at() const { return QGList::at(); }
+ type *current() const { return (type *)QGList::get(); }
+ QLNode *currentNode() const { return QGList::currentNode(); }
+ type *getFirst() const { return (type *)QGList::cfirst(); }
+ type *getLast() const { return (type *)QGList::clast(); }
+ type *first() { return (type *)QGList::first(); }
+ type *last() { return (type *)QGList::last(); }
+ type *next() { return (type *)QGList::next(); }
+ type *prev() { return (type *)QGList::prev(); }
+ void toVector( QGVector *vec )const{ QGList::toVector(vec); }
+private:
+ void deleteItem( QCollection::Item d );
+};
+
+#if defined(Q_DELETING_VOID_UNDEFINED)
+template<> inline void QList<void>::deleteItem( QCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void QList<type>::deleteItem( QCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+
+
+template<class type> class Q_EXPORT QListIterator : public QGListIterator
+{
+public:
+ QListIterator(const QList<type> &l) :QGListIterator((QGList &)l) {}
+ ~QListIterator() {}
+ uint count() const { return list->count(); }
+ bool isEmpty() const { return list->count() == 0; }
+ bool atFirst() const { return QGListIterator::atFirst(); }
+ bool atLast() const { return QGListIterator::atLast(); }
+ type *toFirst() { return (type *)QGListIterator::toFirst(); }
+ type *toLast() { return (type *)QGListIterator::toLast(); }
+ operator type *() const { return (type *)QGListIterator::get(); }
+ type *operator*() { return (type *)QGListIterator::get(); }
+
+ // No good, since QList<char> (ie. QStrList fails...
+ //
+ // MSVC++ gives warning
+ // Sunpro C++ 4.1 gives error
+ // type *operator->() { return (type *)QGListIterator::get(); }
+
+ type *current() const { return (type *)QGListIterator::get(); }
+ type *operator()() { return (type *)QGListIterator::operator()();}
+ type *operator++() { return (type *)QGListIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)QGListIterator::operator+=(j);}
+ type *operator--() { return (type *)QGListIterator::operator--(); }
+ type *operator-=(uint j) { return (type *)QGListIterator::operator-=(j);}
+ QListIterator<type>& operator=(const QListIterator<type>&it)
+ { QGListIterator::operator=(it); return *this; }
+};
+
+
+#endif // QLIST_H
diff --git a/qtools/qptrdict.h b/qtools/qptrdict.h
new file mode 100644
index 0000000..c075e30
--- /dev/null
+++ b/qtools/qptrdict.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+**
+** Definition of QPtrDict template class
+**
+** Created : 970415
+**
+** Copyright (C) 1992-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 QPTRDICT_H
+#define QPTRDICT_H
+
+#ifndef QT_H
+#include "qgdict.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QPtrDict : public QGDict
+{
+public:
+ QPtrDict(int size=17) : QGDict(size,PtrKey,0,0) {}
+ QPtrDict( const QPtrDict<type> &d ) : QGDict(d) {}
+ ~QPtrDict() { clear(); }
+ QPtrDict<type> &operator=(const QPtrDict<type> &d)
+ { return (QPtrDict<type>&)QGDict::operator=(d); }
+ uint count() const { return QGDict::count(); }
+ uint size() const { return QGDict::size(); }
+ bool isEmpty() const { return QGDict::count() == 0; }
+ void insert( void *k, const type *d )
+ { QGDict::look_ptr(k,(Item)d,1); }
+ void replace( void *k, const type *d )
+ { QGDict::look_ptr(k,(Item)d,2); }
+ bool remove( void *k ) { return QGDict::remove_ptr(k); }
+ type *take( void *k ) { return (type*)QGDict::take_ptr(k); }
+ type *find( void *k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_ptr(k,0,0); }
+ type *operator[]( void *k ) const
+ { return (type *)((QGDict*)this)->QGDict::look_ptr(k,0,0); }
+ void clear() { QGDict::clear(); }
+ void resize( uint n ) { QGDict::resize(n); }
+ void statistics() const { QGDict::statistics(); }
+private:
+ void deleteItem( Item d );
+};
+
+#if defined(Q_DELETING_VOID_UNDEFINED)
+template<> inline void QPtrDict<void>::deleteItem( QCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void QPtrDict<type>::deleteItem( QCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+
+template<class type> class Q_EXPORT QPtrDictIterator : public QGDictIterator
+{
+public:
+ QPtrDictIterator(const QPtrDict<type> &d) :QGDictIterator((QGDict &)d) {}
+ ~QPtrDictIterator() {}
+ uint count() const { return dict->count(); }
+ bool isEmpty() const { return dict->count() == 0; }
+ type *toFirst() { return (type *)QGDictIterator::toFirst(); }
+ operator type *() const { return (type *)QGDictIterator::get(); }
+ type *current() const { return (type *)QGDictIterator::get(); }
+ void *currentKey() const { return QGDictIterator::getKeyPtr(); }
+ type *operator()() { return (type *)QGDictIterator::operator()(); }
+ type *operator++() { return (type *)QGDictIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)QGDictIterator::operator+=(j);}
+};
+
+
+#endif // QPTRDICT_H
diff --git a/qtools/qqueue.h b/qtools/qqueue.h
new file mode 100644
index 0000000..94bc130
--- /dev/null
+++ b/qtools/qqueue.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+**
+** Definition of QQueue template/macro class
+**
+** Created : 920917
+**
+** Copyright (C) 1992-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 QQUEUE_H
+#define QQUEUE_H
+
+#ifndef QT_H
+#include "qglist.h"
+#endif // QT_H
+
+
+template<class type> class QQueue : private QGList
+{
+public:
+ QQueue() {}
+ QQueue( const QQueue<type> &q ) : QGList(q) {}
+ ~QQueue() { clear(); }
+ QQueue<type>& operator=(const QQueue<type> &q)
+ { return (QQueue<type>&)QGList::operator=(q); }
+ bool autoDelete() const { return QCollection::autoDelete(); }
+ void setAutoDelete( bool del ) { QCollection::setAutoDelete(del); }
+ uint count() const { return QGList::count(); }
+ bool isEmpty() const { return QGList::count() == 0; }
+ void enqueue( const type *d ) { QGList::append(Item(d)); }
+ type *dequeue() { return (type *)QGList::takeFirst();}
+ bool remove() { return QGList::removeFirst(); }
+ void clear() { QGList::clear(); }
+ type *head() const { return (type *)QGList::cfirst(); }
+ operator type *() const { return (type *)QGList::cfirst(); }
+ type *current() const { return (type *)QGList::cfirst(); }
+private:
+ void deleteItem( Item d ) { if ( del_item ) delete (type *)d; }
+};
+
+
+#endif // QQUEUE_H
diff --git a/qtools/qregexp.cpp b/qtools/qregexp.cpp
new file mode 100644
index 0000000..671867e
--- /dev/null
+++ b/qtools/qregexp.cpp
@@ -0,0 +1,1091 @@
+/****************************************************************************
+**
+**
+** Implementation of QRegExp class
+**
+** Created : 950126
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qregexp.h"
+#include <ctype.h>
+#include <stdlib.h>
+
+// NOT REVISED
+/*!
+ \class QRegExp qregexp.h
+ \ingroup tools
+ \ingroup misc
+ \brief The QRegExp class provides pattern matching using regular
+ expressions or wildcards.
+
+ QRegExp knows these regexp primitives:
+ <ul plain>
+ <li><dfn>c</dfn> matches the character 'c'
+ <li><dfn>.</dfn> matches any character
+ <li><dfn>^</dfn> matches start of input
+ <li><dfn>$</dfn> matches end of input
+ <li><dfn>[]</dfn> matches a defined set of characters - see below.
+ <li><dfn>a*</dfn> matches a sequence of zero or more a's
+ <li><dfn>a+</dfn> matches a sequence of one or more a's
+ <li><dfn>a?</dfn> matches an optional a
+ <li><dfn>\c</dfn> escape code for matching special characters such
+ as \, [, *, +, . etc.
+ <li><dfn>\t</dfn> matches the TAB character (9)
+ <li><dfn>\n</dfn> matches newline (10)
+ <li><dfn>\r</dfn> matches return (13)
+ <li><dfn>\s</dfn> matches a white space (defined as any character
+ for which QChar::isSpace() returns TRUE. This includes at least
+ ASCII characters 9 (TAB), 10 (LF), 11 (VT), 12(FF), 13 (CR) and 32
+ (Space)).
+ <li><dfn>\d</dfn> matches a digit (defined as any character for
+ which QChar::isDigit() returns TRUE. This includes at least ASCII
+ characters '0'-'9').
+ <li><dfn>\x1f6b</dfn> matches the character with unicode point U1f6b
+ (hexadecimal 1f6b). \x0012 will match the ASCII/Latin1 character
+ 0x12 (18 decimal, 12 hexadecimal).
+ <li><dfn>\022</dfn> matches the ASCII/Latin1 character 022 (18
+ decimal, 22 octal).
+ </ul>
+
+ In wildcard mode, it only knows four primitives:
+ <ul plain>
+ <li><dfn>c</dfn> matches the character 'c'
+ <li><dfn>?</dfn> matches any character
+ <li><dfn>*</dfn> matches any sequence of characters
+ <li><dfn>[]</dfn> matches a defined set of characters - see below.
+ </ul>
+
+ QRegExp supports Unicode both in the pattern strings and in the
+ strings to be matched.
+
+ When writing regular expressions in C++ code, remember that C++
+ processes \ characters. So in order to match e.g. a "." character,
+ you must write "\\." in C++ source, not "\.".
+
+ A character set matches a defined set of characters. For example,
+ [BSD] matches any of 'B', 'D' and 'S'. Within a character set, the
+ special characters '.', '*', '?', '^', '$', '+' and '[' lose their
+ special meanings. The following special characters apply:
+ <ul plain>
+ <li><dfn>^</dfn> When placed first in the list, changes the
+ character set to match any character \e not in the list. To include
+ the character '^' itself in the set, escape it or place it anywhere
+ but first.
+ <li><dfn>-</dfn> Defines a range of characters. To include the
+ character '-' itself in the set, escape it or place it last.
+ <li><dfn>]</dfn> Ends the character set definition. To include the
+ character ']' itself in the set, escape it or place it first (but
+ after the negation operator '^', if present)
+ </ul>
+ Thus, [a-zA-Z0-9.] matches upper and lower case ASCII letters,
+ digits and dot; and [^\s] matches everything except white space.
+
+ \bug Case insensitive matching is not supported for non-ASCII/Latin1
+ (non-8bit) characters. Any character with a non-zero QChar.row() is
+ matched case sensitively even if the QRegExp is in case insensitive
+ mode.
+
+ \note In Qt 3.0, the language of regular expressions will contain
+ five more special characters, namely '(', ')', '{', '|' and '}'. To
+ ease porting, it's a good idea to escape these characters with a
+ backslash in all the regular expressions you'll write from now on.
+*/
+
+
+//
+// The regexp pattern is internally represented as an array of uints,
+// each element containing an 16-bit character or a 32-bit code
+// (listed below). User-defined character classes (e.g. [a-zA-Z])
+// are encoded as this:
+// uint no: 1 2 3 ...
+// value: CCL | n from | to from | to
+//
+// where n is the (16-bit) number of following range definitions and
+// from and to define the ranges inclusive. from <= to is always true,
+// otherwise it is a built-in charclass (Pxx, eg \s - PWS). Single
+// characters in the class are coded as from==to. Negated classes
+// (e.g. [^a-z]) use CCN instead of CCL.
+
+const uint END = 0x00000000;
+const uint PWS = 0x10010000; // predef charclass: whitespace (\s)
+const uint PDG = 0x10020000; // predef charclass: digit (\d)
+const uint CCL = 0x20010000; // character class []
+const uint CCN = 0x20020000; // neg character class [^]
+const uint CHR = 0x40000000; // character
+const uint BOL = 0x80010000; // beginning of line ^
+const uint EOL = 0x80020000; // end of line $
+const uint BOW = 0x80030000; // beginning of word \<
+const uint EOW = 0x80040000; // end of word \>
+const uint ANY = 0x80050000; // any character .
+const uint CLO = 0x80070000; // Kleene closure *
+const uint OPT = 0x80080000; // Optional closure ?
+
+const uint MCC = 0x20000000; // character class bitmask
+const uint MCD = 0xffff0000; // code mask
+const uint MVL = 0x0000ffff; // value mask
+
+//
+// QRegExp::error codes (internal)
+//
+
+const int PatOk = 0; // pattern ok
+const int PatNull = 1; // no pattern defined
+const int PatSyntax = 2; // pattern syntax error
+const int PatOverflow = 4; // pattern too long
+
+
+/*****************************************************************************
+ QRegExp member functions
+ *****************************************************************************/
+
+/*!
+ Constructs an empty regular expression.
+*/
+
+QRegExp::QRegExp()
+{
+ rxdata = 0;
+ cs = TRUE;
+ wc = FALSE;
+ error = PatOk;
+}
+
+/*!
+ Constructs a regular expression.
+
+ \arg \e pattern is the regular expression pattern string.
+ \arg \e caseSensitive specifies whether or not to use case sensitive
+ matching.
+ \arg \e wildcard specifies whether the pattern string should be used for
+ wildcard matching (also called globbing expression), normally used for
+ matching file names.
+
+ \sa setWildcard()
+*/
+
+QRegExp::QRegExp( const QString &pattern, bool caseSensitive, bool wildcard )
+{
+ rxstring = pattern;
+ rxdata = 0;
+ cs = caseSensitive;
+ wc = wildcard;
+ compile();
+}
+
+/*!
+ Constructs a regular expression which is a copy of \e r.
+ \sa operator=(const QRegExp&)
+*/
+
+QRegExp::QRegExp( const QRegExp &r )
+{
+ rxstring = r.pattern();
+ rxdata = 0;
+ cs = r.caseSensitive();
+ wc = r.wildcard();
+ compile();
+}
+
+/*!
+ Destructs the regular expression and cleans up its internal data.
+*/
+
+QRegExp::~QRegExp()
+{
+ if ( rxdata ) // Avoid purify complaints
+ delete [] rxdata;
+}
+
+/*!
+ Copies the regexp \e r and returns a reference to this regexp.
+ The case sensitivity and wildcard options are copied, as well.
+*/
+
+QRegExp &QRegExp::operator=( const QRegExp &r )
+{
+ rxstring = r.rxstring;
+ cs = r.cs;
+ wc = r.wc;
+ compile();
+ return *this;
+}
+
+/*!
+ \obsolete
+ Consider using setPattern() instead of this method.
+
+ Sets the pattern string to \e pattern and returns a reference to this regexp.
+ The case sensitivity or wildcard options do not change.
+*/
+
+QRegExp &QRegExp::operator=( const QString &pattern )
+{
+ rxstring = pattern;
+ compile();
+ return *this;
+}
+
+
+/*!
+ Returns TRUE if this regexp is equal to \e r.
+
+ Two regexp objects are equal if they have equal pattern strings,
+ case sensitivity options and wildcard options.
+*/
+
+bool QRegExp::operator==( const QRegExp &r ) const
+{
+ return rxstring == r.rxstring && cs == r.cs && wc == r.wc;
+}
+
+/*!
+ \fn bool QRegExp::operator!=( const QRegExp &r ) const
+
+ Returns TRUE if this regexp is \e not equal to \e r.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn bool QRegExp::isEmpty() const
+ Returns TRUE if the regexp is empty.
+*/
+
+/*!
+ \fn bool QRegExp::isValid() const
+ Returns TRUE if the regexp is valid, or FALSE if it is invalid.
+
+ The pattern "[a-z" is an example of an invalid pattern, since it lacks a
+ closing bracket.
+*/
+
+
+/*!
+ \fn bool QRegExp::wildcard() const
+ Returns TRUE if wildcard mode is on, otherwise FALSE. \sa setWildcard().
+*/
+
+/*!
+ Sets the wildcard option for the regular expression. The default
+ is FALSE.
+
+ Setting \e wildcard to TRUE makes it convenient to match filenames
+ instead of plain text.
+
+ For example, "qr*.cpp" matches the string "qregexp.cpp" in wildcard mode,
+ but not "qicpp" (which would be matched in normal mode).
+
+ \sa wildcard()
+*/
+
+void QRegExp::setWildcard( bool wildcard )
+{
+ if ( wildcard != wc ) {
+ wc = wildcard;
+ compile();
+ }
+}
+
+/*!
+ \fn bool QRegExp::caseSensitive() const
+
+ Returns TRUE if case sensitivity is enabled, otherwise FALSE. The
+ default is TRUE.
+
+ \sa setCaseSensitive()
+*/
+
+/*!
+ Enables or disables case sensitive matching.
+
+ In case sensitive mode, "a.e" matches "axe" but not "Axe".
+
+ See also: caseSensitive()
+*/
+
+void QRegExp::setCaseSensitive( bool enable )
+{
+ if ( cs != enable ) {
+ cs = enable;
+ compile();
+ }
+}
+
+
+/*!
+ \fn QString QRegExp::pattern() const
+ Returns the pattern string of the regexp.
+*/
+
+
+/*!
+ \fn void QRegExp::setPattern(const QString & pattern)
+ Sets the pattern string to \a pattern and returns a reference to this regexp.
+ The case sensitivity or wildcard options do not change.
+*/
+
+static inline bool iswordchar( int x )
+{
+ return isalnum(x) || x == '_'; //# Only 8-bit support
+}
+
+
+/*!
+ \internal
+ Match character class
+*/
+
+static bool matchcharclass( uint *rxd, QChar c )
+{
+ uint *d = rxd;
+ uint clcode = *d & MCD;
+ bool neg = clcode == CCN;
+ if ( clcode != CCL && clcode != CCN)
+ qWarning("QRegExp: Internal error, please report to qt-bugs@trolltech.com");
+ uint numFields = *d & MVL;
+ uint cval = (((uint)(c.row())) << 8) | ((uint)c.cell());
+ bool found = FALSE;
+ for ( int i = 0; i < (int)numFields; i++ ) {
+ d++;
+ if ( *d == PWS && c.isSpace() ) {
+ found = TRUE;
+ break;
+ }
+ if ( *d == PDG && c.isDigit() ) {
+ found = TRUE;
+ break;
+ }
+ else {
+ uint from = ( *d & MCD ) >> 16;
+ uint to = *d & MVL;
+ if ( (cval >= from) && (cval <= to) ) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ return neg ? !found : found;
+}
+
+
+
+/*
+ Internal: Recursively match string.
+*/
+
+static int matchstring( uint *rxd, const QChar *str, uint strlength,
+ const QChar *bol, bool cs )
+{
+ const QChar *p = str;
+ const QChar *start = p;
+ uint pl = strlength;
+ uint *d = rxd;
+
+ //### in all cases here: handle pl == 0! (don't read past strlen)
+ while ( *d ) {
+ if ( *d & CHR ) { // match char
+ if ( !pl )
+ return -1;
+ QChar c( *d );
+ if ( !cs && !c.row() ) { // case insensitive, #Only 8bit
+ if ( p->row() || tolower(p->cell()) != c.cell() )
+ return -1;
+ p++;
+ pl--;
+ } else { // case insensitive
+ if ( *p != c )
+ return -1;
+ p++;
+ pl--;
+ }
+ d++;
+ }
+ else if ( *d & MCC ) { // match char class
+ if ( !pl )
+ return -1;
+ if ( !matchcharclass( d, *p ) )
+ return -1;
+ p++;
+ pl--;
+ d += (*d & MVL) + 1;
+ }
+ else switch ( *d++ ) {
+ case PWS: // match whitespace
+ if ( !pl || !p->isSpace() )
+ return -1;
+ p++;
+ pl--;
+ break;
+ case PDG: // match digits
+ if ( !pl || !p->isDigit() )
+ return -1;
+ p++;
+ pl--;
+ break;
+ case ANY: // match anything
+ if ( !pl )
+ return -1;
+ p++;
+ pl--;
+ break;
+ case BOL: // match beginning of line
+ if ( p != bol )
+ return -1;
+ break;
+ case EOL: // match end of line
+ if ( pl )
+ return -1;
+ break;
+ case BOW: // match beginning of word
+ if ( !iswordchar(*p) || (p > bol && iswordchar(*(p-1)) ) )
+ return -1;
+ break;
+ case EOW: // match end of word
+ if ( iswordchar(*p) || p == bol || !iswordchar(*(p-1)) )
+ return -1;
+ break;
+ case CLO: // Kleene closure
+ {
+ const QChar *first_p = p;
+ if ( *d & CHR ) { // match char
+ QChar c( *d );
+ if ( !cs && !c.row() ) { // case insensitive, #only 8bit
+ while ( pl && !p->row() && tolower(p->cell())==c.cell() ) {
+ p++;
+ pl--;
+ }
+ }
+ else { // case sensitive
+ while ( pl && *p == c ) {
+ p++;
+ pl--;
+ }
+ }
+ d++;
+ }
+ else if ( *d & MCC ) { // match char class
+ while( pl && matchcharclass( d, *p ) ) {
+ p++;
+ pl--;
+ }
+ d += (*d & MVL) + 1;
+ }
+ else if ( *d == PWS ) {
+ while ( pl && p->isSpace() ) {
+ p++;
+ pl--;
+ }
+ d++;
+ }
+ else if ( *d == PDG ) {
+ while ( pl && p->isDigit() ) {
+ p++;
+ pl--;
+ }
+ d++;
+ }
+ else if ( *d == ANY ) {
+ p += pl;
+ pl = 0;
+ d++;
+ }
+ else {
+ return -1; // error
+ }
+ d++; // skip CLO's END
+ while ( p >= first_p ) { // go backwards
+ int end = matchstring( d, p, pl, bol, cs );
+ if ( end >= 0 )
+ return ( p - start ) + end;
+ if ( !p )
+ return -1;
+ --p;
+ ++pl;
+ }
+ }
+ return -1;
+ case OPT: // optional closure
+ {
+ const QChar *first_p = p;
+ if ( *d & CHR ) { // match char
+ QChar c( *d );
+ if ( !cs && !c.row() ) { // case insensitive, #only 8bit
+ if ( pl && !p->row() && tolower(p->cell()) == c.cell() ) {
+ p++;
+ pl--;
+ }
+ }
+ else { // case sensitive
+ if ( pl && *p == c ) {
+ p++;
+ pl--;
+ }
+ }
+ d++;
+ }
+ else if ( *d & MCC ) { // match char class
+ if ( pl && matchcharclass( d, *p ) ) {
+ p++;
+ pl--;
+ }
+ d += (*d & MVL) + 1;
+ }
+ else if ( *d == PWS ) {
+ if ( pl && p->isSpace() ) {
+ p++;
+ pl--;
+ }
+ d++;
+ }
+ else if ( *d == PDG ) {
+ if ( pl && p->isDigit() ) {
+ p++;
+ pl--;
+ }
+ d++;
+ }
+ else if ( *d == ANY ) {
+ if ( pl ) {
+ p++;
+ pl--;
+ }
+ d++;
+ }
+ else {
+ return -1; // error
+ }
+ d++; // skip OPT's END
+ while ( p >= first_p ) { // go backwards
+ int end = matchstring( d, p, pl, bol, cs );
+ if ( end >= 0 )
+ return ( p - start ) + end;
+ if ( !p )
+ return -1;
+ --p;
+ ++pl;
+ }
+ }
+ return -1;
+
+ default: // error
+ return -1;
+ }
+ }
+ return p - start;
+}
+
+
+/*!
+ \internal
+ Recursively match string.
+*/
+
+// This is obsolete now, but since it is protected (not private), it
+// is still implemented on the off-chance that somebody has made a
+// class derived from QRegExp and calls this directly.
+// Qt 3.0: Remove this?
+
+
+const QChar *QRegExp::matchstr( uint *rxd, const QChar *str, uint strlength,
+ const QChar *bol ) const
+{
+ int len = matchstring( rxd, str, strlength, bol, cs );
+ if ( len < 0 )
+ return 0;
+ return str + len;
+}
+
+/*!
+ Attempts to match in \e str, starting from position \e index.
+ Returns the position of the match, or -1 if there was no match.
+
+ If \e len is not a null pointer, the length of the match is stored in
+ \e *len.
+
+ If \e indexIsStart is TRUE (the default), the position \e index in
+ the string will match the start-of-input primitive (^) in the
+ regexp, if present. Otherwise, position 0 in \e str will match.
+
+ Example:
+ \code
+ QRegExp r("[0-9]*\\.[0-9]+"); // matches floating point
+ int len;
+ r.match("pi = 3.1416", 0, &len); // returns 5, len == 6
+ \endcode
+
+ \note In Qt 3.0, this function will be replaced by find().
+*/
+
+int QRegExp::match( const QString &str, int index, int *len,
+ bool indexIsStart ) const
+{
+ if ( !isValid() || isEmpty() )
+ return -1;
+ if ( str.length() < (uint)index )
+ return -1;
+ const QChar *start = str.unicode();
+ const QChar *p = start + index;
+ uint pl = str.length() - index;
+ uint *d = rxdata;
+ int ep = -1;
+
+ if ( *d == BOL ) { // match from beginning of line
+ ep = matchstring( d, p, pl, indexIsStart ? p : start, cs );
+ } else {
+ if ( *d & CHR ) {
+ QChar c( *d );
+ if ( !cs && !c.row() ) { // case sensitive, # only 8bit
+ while ( pl && ( p->row() || tolower(p->cell()) != c.cell() ) ) {
+ p++;
+ pl--;
+ }
+ } else { // case insensitive
+ while ( pl && *p != c ) {
+ p++;
+ pl--;
+ }
+ }
+ }
+ while( 1 ) { // regular match
+ ep = matchstring( d, p, pl, indexIsStart ? start+index : start, cs );
+ if ( ep >= 0 )
+ break;
+ if ( !pl )
+ break;
+ p++;
+ pl--;
+ }
+ }
+ if ( len )
+ *len = ep >= 0 ? ep : 0; // No match -> 0, for historical reasons
+ return ep >= 0 ? (int)(p - start) : -1; // return index;
+}
+
+/*! \fn int QRegExp::find( const QString& str, int index )
+
+ Attempts to match in \e str, starting from position \e index.
+ Returns the position of the match, or -1 if there was no match.
+
+ \sa match()
+*/
+
+//
+// Translate wildcard pattern to standard regexp pattern.
+// Ex: *.cpp ==> ^.*\.cpp$
+//
+
+static QString wc2rx( const QString &pattern )
+{
+ int patlen = (int)pattern.length();
+ QString wcpattern = QString::fromLatin1("^");
+
+ QChar c;
+ for( int i = 0; i < patlen; i++ ) {
+ c = pattern[i];
+ switch ( (char)c ) {
+ case '*': // '*' ==> '.*'
+ wcpattern += '.';
+ break;
+ case '?': // '?' ==> '.'
+ c = '.';
+ break;
+ case '.': // quote special regexp chars
+ case '+':
+ case '\\':
+ case '$':
+ case '^':
+ wcpattern += '\\';
+ break;
+ case '[':
+ if ( (char)pattern[i+1] == '^' ) { // don't quote '^' after '['
+ wcpattern += '[';
+ c = pattern[i+1];
+ i++;
+ }
+ break;
+ }
+ wcpattern += c;
+
+ }
+ wcpattern += '$';
+ return wcpattern; // return new regexp pattern
+}
+
+
+//
+// Internal: Get char value and increment pointer.
+//
+
+static uint char_val( const QChar **str, uint *strlength ) // get char value
+{
+ const QChar *p = *str;
+ uint pl = *strlength;
+ uint len = 1;
+ uint v = 0;
+ if ( (char)*p == '\\' ) { // escaped code
+ p++;
+ pl--;
+ if ( !pl ) { // it is just a '\'
+ (*str)++;
+ (*strlength)--;
+ return '\\';
+ }
+ len++; // length at least 2
+ int i;
+ char c;
+ char ch = tolower((char)*p);
+ switch ( ch ) {
+ case 'b': v = '\b'; break; // bell
+ case 'f': v = '\f'; break; // form feed
+ case 'n': v = '\n'; break; // newline
+ case 'r': v = '\r'; break; // return
+ case 't': v = '\t'; break; // tab
+ case 's': v = PWS; break; // whitespace charclass
+ case 'd': v = PDG; break; // digit charclass
+ case '<': v = BOW; break; // word beginning matcher
+ case '>': v = EOW; break; // word ending matcher
+
+ case 'x': { // hex code
+ p++;
+ pl--;
+ for ( i = 0; (i < 4) && pl; i++ ) { //up to 4 hex digits
+ c = tolower((char)*p);
+ bool a = ( c >= 'a' && c <= 'f' );
+ if ( (c >= '0' && c <= '9') || a ) {
+ v <<= 4;
+ v += a ? 10 + c - 'a' : c - '0';
+ len++;
+ }
+ else {
+ break;
+ }
+ p++;
+ pl--;
+ }
+ }
+ break;
+
+ default: {
+ if ( ch >= '0' && ch <= '7' ) { //octal code
+ len--;
+ for ( i = 0; (i < 3) && pl; i++ ) { // up to 3 oct digits
+ c = (char)*p;
+ if ( c >= '0' && c <= '7' ) {
+ v <<= 3;
+ v += c - '0';
+ len++;
+ }
+ else {
+ break;
+ }
+ p++;
+ pl--;
+ }
+ }
+ else { // not an octal number
+ v = (((uint)(p->row())) << 8) | ((uint)p->cell());
+ }
+ }
+ }
+ } else {
+ v = (((uint)(p->row())) << 8) | ((uint)p->cell());
+ }
+ *str += len;
+ *strlength -= len;
+ return v;
+}
+
+
+#if defined(DEBUG)
+static uint *dump( uint *p )
+{
+ while ( *p != END ) {
+ if ( *p & CHR ) {
+ QChar uc = (QChar)*p;
+ char c = (char)uc;
+ uint u = (((uint)(uc.row())) << 8) | ((uint)uc.cell());
+ qDebug( "\tCHR\tU%04x (%c)", u, (c ? c : ' '));
+ p++;
+ }
+ else if ( *p & MCC ) {
+ uint clcode = *p & MCD;
+ uint numFields = *p & MVL;
+ if ( clcode == CCL )
+ qDebug( "\tCCL\t%i", numFields );
+ else if ( clcode == CCN )
+ qDebug( "\tCCN\t%i", numFields );
+ else
+ qDebug("coding error!");
+ for ( int i = 0; i < (int)numFields; i++ ) {
+ p++;
+ if ( *p == PWS )
+ qDebug( "\t\tPWS" );
+ else if ( *p == PDG )
+ qDebug( "\t\tPDG" );
+ else {
+ uint from = ( *p & MCD ) >> 16;
+ uint to = *p & MVL;
+ char fc = (char)QChar(from);
+ char tc = (char)QChar(to);
+ qDebug( "\t\tU%04x (%c) - U%04x (%c)", from,
+ (fc ? fc : ' '), to, (tc ? tc : ' ') );
+ }
+ }
+ p++;
+ }
+ else switch ( *p++ ) {
+ case PWS:
+ qDebug( "\tPWS" );
+ break;
+ case PDG:
+ qDebug( "\tPDG" );
+ break;
+ case BOL:
+ qDebug( "\tBOL" );
+ break;
+ case EOL:
+ qDebug( "\tEOL" );
+ break;
+ case BOW:
+ qDebug( "\tBOW" );
+ break;
+ case EOW:
+ qDebug( "\tEOW" );
+ break;
+ case ANY:
+ qDebug( "\tANY" );
+ break;
+ case CLO:
+ qDebug( "\tCLO" );
+ p = dump( p );
+ break;
+ case OPT:
+ qDebug( "\tOPT" );
+ p = dump( p );
+ break;
+ }
+ }
+ qDebug( "\tEND" );
+ return p+1;
+}
+#endif // DEBUG
+
+
+static const int maxlen = 1024; // max length of regexp array
+static uint rxarray[ maxlen ]; // tmp regexp array
+
+/*!
+ \internal
+ Compiles the regular expression and stores the result in rxdata.
+ The 'error' flag is set to non-zero if an error is detected.
+ NOTE! This function is not reentrant!
+*/
+
+void QRegExp::compile()
+{
+ if ( rxdata ) { // delete old data
+ delete [] rxdata;
+ rxdata = 0;
+ }
+ if ( rxstring.isEmpty() ) { // no regexp pattern set
+ error = PatNull;
+ return;
+ }
+
+ error = PatOk; // assume pattern is ok
+
+ QString pattern;
+ if ( wc )
+ pattern = wc2rx(rxstring);
+ else
+ pattern = rxstring;
+ const QChar *start = pattern.unicode(); // pattern pointer
+ const QChar *p = start; // pattern pointer
+ uint pl = pattern.length();
+ uint *d = rxarray; // data pointer
+ uint *prev_d = 0;
+
+#define GEN(x) *d++ = (x)
+
+ while ( pl ) {
+ char ch = (char)*p;
+ switch ( ch ) {
+
+ case '^': // beginning of line
+ prev_d = d;
+ GEN( p == start ? BOL : (CHR | ch) );
+ p++;
+ pl--;
+ break;
+
+ case '$': // end of line
+ prev_d = d;
+ GEN( pl == 1 ? EOL : (CHR | ch) );
+ p++;
+ pl--;
+ break;
+
+ case '.': // any char
+ prev_d = d;
+ GEN( ANY );
+ p++;
+ pl--;
+ break;
+
+ case '[': // character class
+ {
+ prev_d = d;
+ p++;
+ pl--;
+ if ( !pl ) {
+ error = PatSyntax;
+ return;
+ }
+ bool firstIsEscaped = ( (char)*p == '\\' );
+ uint cch = char_val( &p, &pl );
+ if ( cch == '^' && !firstIsEscaped ) { // negate!
+ GEN( CCN );
+ if ( !pl ) {
+ error = PatSyntax;
+ return;
+ }
+ cch = char_val( &p, &pl );
+ } else {
+ GEN( CCL );
+ }
+ uint numFields = 0;
+ while ( pl ) {
+ if ((pl>2) && ((char)*p == '-') && ((char)*(p+1) != ']')) {
+ // Found a range
+ char_val( &p, &pl ); // Read the '-'
+ uint cch2 = char_val( &p, &pl ); // Read the range end
+ if ( cch > cch2 ) { // swap start and stop
+ int tmp = cch;
+ cch = cch2;
+ cch2 = tmp;
+ }
+ GEN( (cch << 16) | cch2 ); // from < to
+ numFields++;
+ }
+ else {
+ // Found a single character
+ if ( cch & MCD ) // It's a code; will not be mistaken
+ GEN( cch ); // for a range, since from > to
+ else
+ GEN( (cch << 16) | cch ); // from == to range
+ numFields++;
+ }
+ if ( d >= rxarray + maxlen ) { // pattern too long
+ error = PatOverflow;
+ return;
+ }
+ if ( !pl ) { // At least ']' should be left
+ error = PatSyntax;
+ return;
+ }
+ bool nextIsEscaped = ( (char)*p == '\\' );
+ cch = char_val( &p, &pl );
+ if ( cch == (uint)']' && !nextIsEscaped )
+ break;
+ if ( !pl ) { // End, should have seen ']'
+ error = PatSyntax;
+ return;
+ }
+ }
+ *prev_d |= numFields; // Store number of fields
+ }
+ break;
+
+ case '*': // Kleene closure, or
+ case '+': // positive closure, or
+ case '?': // optional closure
+ {
+ if ( prev_d == 0 ) { // no previous expression
+ error = PatSyntax; // empty closure
+ return;
+ }
+ switch ( *prev_d ) { // test if invalid closure
+ case BOL:
+ case BOW:
+ case EOW:
+ case CLO:
+ case OPT:
+ error = PatSyntax;
+ return;
+ }
+ int ddiff = d - prev_d;
+ if ( *p == '+' ) { // convert to Kleene closure
+ if ( d + ddiff >= rxarray + maxlen ) {
+ error = PatOverflow; // pattern too long
+ return;
+ }
+ memcpy( d, prev_d, ddiff*sizeof(uint) );
+ d += ddiff;
+ prev_d += ddiff;
+ }
+ memmove( prev_d+1, prev_d, ddiff*sizeof(uint) );
+ *prev_d = ch == '?' ? OPT : CLO;
+ d++;
+ GEN( END );
+ p++;
+ pl--;
+ }
+ break;
+
+ default:
+ {
+ prev_d = d;
+ uint cv = char_val( &p, &pl );
+ if ( cv & MCD ) { // It's a code
+ GEN( cv );
+ }
+ else {
+ if ( !cs && cv <= 0xff ) // #only 8bit support
+ cv = tolower( cv );
+ GEN( CHR | cv );
+ }
+ }
+ }
+ if ( d >= rxarray + maxlen ) { // oops!
+ error = PatOverflow; // pattern too long
+ return;
+ }
+ }
+ GEN( END );
+ int len = d - rxarray;
+ rxdata = new uint[ len ]; // copy from rxarray to rxdata
+ CHECK_PTR( rxdata );
+ memcpy( rxdata, rxarray, len*sizeof(uint) );
+#if defined(DEBUG)
+ //dump( rxdata ); // uncomment this line for debugging
+#endif
+}
diff --git a/qtools/qregexp.h b/qtools/qregexp.h
new file mode 100644
index 0000000..25868ce
--- /dev/null
+++ b/qtools/qregexp.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+**
+** Definition of QRegExp class
+**
+** Created : 950126
+**
+** Copyright (C) 1992-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 QREGEXP_H
+#define QREGEXP_H
+
+#ifndef QT_H
+#include "qstring.h"
+#endif // QT_H
+
+
+class Q_EXPORT QRegExp
+{
+public:
+ QRegExp();
+ QRegExp( const QString &, bool caseSensitive=TRUE, bool wildcard=FALSE );
+ QRegExp( const QRegExp & );
+ ~QRegExp();
+ QRegExp &operator=( const QRegExp & );
+ QRegExp &operator=( const QString &pattern );
+
+ bool operator==( const QRegExp & ) const;
+ bool operator!=( const QRegExp &r ) const
+ { return !(this->operator==(r)); }
+
+ bool isEmpty() const { return rxdata == 0; }
+ bool isValid() const { return error == 0; }
+
+ bool caseSensitive() const { return cs; }
+ void setCaseSensitive( bool );
+
+ bool wildcard() const { return wc; }
+ void setWildcard( bool );
+
+ QString pattern() const { return rxstring; }
+ // ### in Qt 3.0, provide a real implementation
+ void setPattern( const QString& pattern )
+ { operator=( pattern ); }
+
+ int match( const QString &str, int index=0, int *len=0,
+ bool indexIsStart = TRUE ) const;
+ int find( const QString& str, int index )
+ { return match( str, index ); }
+
+protected:
+ void compile();
+ const QChar *matchstr( uint *, const QChar *, uint, const QChar * ) const;
+
+private:
+ QString rxstring; // regular expression pattern
+ uint *rxdata; // compiled regexp pattern
+ int error; // error status
+ bool cs; // case sensitive
+ bool wc; // wildcard
+};
+
+
+#endif // QREGEXP_H
diff --git a/qtools/qshared.h b/qtools/qshared.h
new file mode 100644
index 0000000..79fab7b
--- /dev/null
+++ b/qtools/qshared.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+**
+** Definition of QShared struct
+**
+** Created : 940112
+**
+** Copyright (C) 1992-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 QSHARED_H
+#define QSHARED_H
+
+#ifndef QT_H
+#include "qglobal.h"
+#endif // QT_H
+
+
+struct QShared
+{
+ QShared() { count = 1; }
+ void ref() { count++; }
+ bool deref() { return !--count; }
+ uint count;
+};
+
+
+#endif // QSHARED_H
diff --git a/qtools/qsortedlist.h b/qtools/qsortedlist.h
new file mode 100644
index 0000000..aeadd90
--- /dev/null
+++ b/qtools/qsortedlist.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+**
+** Definition of QList template/macro class
+**
+** Created : 920701
+**
+** Copyright (C) 1992-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 QSORTEDLIST_H
+#define QSORTEDLIST_H
+
+#ifndef QT_H
+#include "qlist.h"
+#endif // QT_H
+
+
+template<class type> class Q_EXPORT QSortedList : public QList<type>
+{
+public:
+ QSortedList() {}
+ QSortedList( const QSortedList<type> &l ) : QList<type>(l) {}
+ ~QSortedList() { clear(); }
+ QSortedList<type> &operator=(const QSortedList<type> &l)
+ { return (QSortedList<type>&)QList<type>::operator=(l); }
+
+ virtual int compareItems( QCollection::Item s1, QCollection::Item s2 )
+ { if ( *((type*)s1) == *((type*)s2) ) return 0; return ( *((type*)s1) < *((type*)s2) ? -1 : 1 ); }
+};
+
+#endif
diff --git a/qtools/qstack.h b/qtools/qstack.h
new file mode 100644
index 0000000..c23215c
--- /dev/null
+++ b/qtools/qstack.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+**
+** Definition of QStack template/macro class
+**
+** Created : 920917
+**
+** Copyright (C) 1992-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 QSTACK_H
+#define QSTACK_H
+
+#ifndef QT_H
+#include "qglist.h"
+#endif // QT_H
+
+
+template<class type> class QStack : private QGList
+{
+public:
+ QStack() {}
+ QStack( const QStack<type> &s ) : QGList(s) {}
+ ~QStack() { clear(); }
+ QStack<type> &operator=(const QStack<type> &s)
+ { return (QStack<type>&)QGList::operator=(s); }
+ bool autoDelete() const { return QCollection::autoDelete(); }
+ void setAutoDelete( bool del ) { QCollection::setAutoDelete(del); }
+ uint count() const { return QGList::count(); }
+ bool isEmpty() const { return QGList::count() == 0; }
+ void push( const type *d ) { QGList::insertAt(0,Item(d)); }
+ type *pop() { return (type *)QGList::takeFirst(); }
+ bool remove() { return QGList::removeFirst(); }
+ void clear() { QGList::clear(); }
+ type *top() const { return (type *)QGList::cfirst(); }
+ operator type *() const { return (type *)QGList::cfirst(); }
+ type *current() const { return (type *)QGList::cfirst(); }
+private:
+ void deleteItem( Item d ) { if ( del_item ) delete (type *)d; }
+};
+
+
+#endif // QSTACK_H
diff --git a/qtools/qstring.cpp b/qtools/qstring.cpp
new file mode 100644
index 0000000..44d4e6b
--- /dev/null
+++ b/qtools/qstring.cpp
@@ -0,0 +1,15205 @@
+/****************************************************************************
+**
+**
+** Implementation of the QString class and related Unicode functions
+**
+** Created : 920722
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+// Don't define it while compiling this module, or USERS of Qt will
+// not be able to link.
+#ifdef QT_NO_CAST_ASCII
+#undef QT_NO_CAST_ASCII
+#endif
+
+#include "qstring.h"
+#include "qregexp.h"
+#include "qdatastream.h"
+#include "qtextcodec.h"
+#include "qstack.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <limits.h>
+
+
+/* -------------------------------------------------------------------------
+ * unicode information
+ * these tables are generated from the unicode reference file
+ * ftp://ftp.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.html
+ *
+ * Lars Knoll <knoll@mpi-hd.mpg.de>
+ * -------------------------------------------------------------------------
+ */
+
+/* Perl script to generate (run perl -x tools/qstring.cpp)
+
+#!perl
+
+sub numberize
+{
+ my(%r, $n, $id);
+ for $id ( @_ ) {
+ $id="" if $id eq "EMPTY";
+ $r{$id}=$n++;
+ }
+ return %r;
+}
+
+
+# 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});
+
+# Read data into hashes...
+#
+open IN, "UnicodeData.txt";
+$position = 1;
+while (<IN>) {
+ @fields = split /;/;
+ $code = shift @fields;
+ 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 @fields;
+ $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;
+ }
+ @fields = split(" ", $decomp);
+ $tag = shift @fields;
+ $tag = $character_decomposition_tag{$tag};
+ $decomp = join( ", 0x", @fields );
+ $decomp = "0x".$decomp;
+ $decomposition{$code} = $decomp;
+ $decomposition_tag{$code} = $tag;
+ $decomposition_pos{$code} = $position;
+ $len = scalar(@fields);
+ $decomposition_len{$code} = $len;
+
+# we use canonical decompositions longer than 1 char
+# and all arabic ligatures for the ligature table
+ if(($len > 1 and $tag == 1) or ($tag > 3 and $tag < 8)) {
+# ligature to add...
+ $start = shift @fields;
+ $ligature{$start} = $ligature{$start}." ".$code;
+ }
+
+# adjust position
+ if($len != 0) {
+ $position += $len + 3;
+ }
+
+
+}
+
+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;
+}
+
+# Build pages...
+#
+$rowtable_txt =
+ "static const Q_UINT8 * const unicode_info[256] = {";
+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 ) {
+ $size+=256;
+ $therow = "ui_".sprintf("%02X",$row);
+ $rowtext{$therow} =
+ "static const Q_UINT8 ${therow}[] = {$txt\n};\n\n";
+ $row{$txt}=$therow;
+ }
+ $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...
+#
+for $r ( sort keys %rowtext ) {
+ print $rowtext{$r};
+}
+print "$rowtable_txt\n};\n";
+$size += 256*4;
+print "// $size bytes\n\n";
+
+# Build decomposition tables
+#
+$rowtable_txt =
+ "static const Q_UINT16 * const decomposition_info[256] = {";
+$table_txt =
+ "static const Q_UINT16 decomposition_map[] = {\n 0,\n";
+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 ) {
+ $size+=512;
+ $therow = "di_".sprintf("%02X",$row);
+ $dec_rowtext{$therow} =
+ "static const Q_UINT16 ${therow}[] = {$txt\n};\n\n";
+ $row{$txt}=$therow;
+ }
+ $rowtable_txt .= "\n " if $row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+# Print decomposition tables
+#
+print "$table_txt\n};\n\n";
+for $r ( sort keys %dec_rowtext ) {
+ print $dec_rowtext{$r};
+}
+print "$rowtable_txt\n};\n";
+$size += 256*4;
+print "// $size bytes\n\n";
+
+
+# build ligature tables
+#
+$size = 0;
+$position = 1;
+$rowtable_txt =
+ "static const Q_UINT16 * const ligature_info[256] = {";
+$table_txt =
+ "static const Q_UINT16 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 it's 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 ) {
+ $size+=512;
+ $therow = "li_".sprintf("%02X",$lig_row);
+ $lig_rowtext{$therow} =
+ "static const Q_UINT16 ${therow}[] = {$txt\n};\n\n";
+ $lig_row{$txt}=$therow;
+ }
+ $rowtable_txt .= "\n " if $lig_row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+# Print ligature tables
+#
+print "$table_txt\n};\n\n";
+for $r ( sort keys %lig_rowtext ) {
+ print $lig_rowtext{$r};
+}
+print "$rowtable_txt\n};\n";
+$size += 256*4;
+print "// $size bytes\n\n";
+
+
+
+# Build direction/joining/mirrored pages...
+#
+$rowtable_txt =
+ "static const Q_UINT8 * const direction_info[256] = {";
+for $dir_row ( 0..255 ) {
+ $nonzero=0;
+ $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 ) {
+ $size+=256;
+ $therow = "dir_".sprintf("%02X",$dir_row);
+ $dir_rowtext{$therow} =
+ "static const Q_UINT8 ${therow}[] = {$txt\n};\n\n";
+ $dir_row{$txt}=$therow;
+ }
+ $rowtable_txt .= "\n " if $dir_row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+# Print pages...
+#
+for $r ( sort keys %dir_rowtext ) {
+ print $dir_rowtext{$r};
+}
+print "$rowtable_txt\n};\n";
+$size += 256*4;
+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
+
+static const Q_UINT8 ui_00[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 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,
+};
+
+static const Q_UINT8 ui_01[] = {
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 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,
+};
+
+static const Q_UINT8 ui_02[] = {
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 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, 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,
+};
+
+static const Q_UINT8 ui_03[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 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,
+ 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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,
+ 0, 0, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_04[] = {
+ 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, 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, 15, 16, 15, 16, 0, 0, 15,
+ 16, 0, 0, 15, 16, 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, 0, 0,
+ 15, 16, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_05[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 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,
+};
+
+static const Q_UINT8 ui_06[] = {
+ 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, 0, 0,
+ 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, 3, 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,
+};
+
+static const Q_UINT8 ui_07[] = {
+ 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, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_08[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_09[] = {
+ 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,
+};
+
+static const Q_UINT8 ui_0A[] = {
+ 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,
+};
+
+static const Q_UINT8 ui_0B[] = {
+ 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, 2, 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,
+};
+
+static const Q_UINT8 ui_0C[] = {
+ 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,
+};
+
+static const Q_UINT8 ui_0D[] = {
+ 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,
+};
+
+static const Q_UINT8 ui_0E[] = {
+ 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,
+};
+
+static const Q_UINT8 ui_0F[] = {
+ 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,
+};
+
+static const Q_UINT8 ui_10[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 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, 0,
+ 0, 0, 0, 26, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_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, 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,
+};
+
+static const Q_UINT8 ui_12[] = {
+ 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,
+};
+
+static const Q_UINT8 ui_13[] = {
+ 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,
+};
+
+static const Q_UINT8 ui_14[] = {
+ 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,
+};
+
+static const Q_UINT8 ui_15[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+};
+
+static const Q_UINT8 ui_16[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 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, 6, 6,
+ 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_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,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 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, 26,
+ 26, 26, 26, 28, 26, 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,
+};
+
+static const Q_UINT8 ui_18[] = {
+ 26, 26, 26, 26, 26, 26, 21, 26,
+ 26, 26, 26, 11, 11, 11, 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,
+};
+
+static const Q_UINT8 ui_1E[] = {
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 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,
+};
+
+static const Q_UINT8 ui_1F[] = {
+ 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,
+};
+
+static const Q_UINT8 ui_20[] = {
+ 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, 0,
+ 26, 26, 26, 26, 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, 11, 11, 11, 11, 11, 11,
+ 6, 0, 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_21[] = {
+ 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, 0, 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,
+ 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_22[] = {
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_23[] = {
+ 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, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_24[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_25[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 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,
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_26[] = {
+ 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, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_27[] = {
+ 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,
+ 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, 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_28[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+};
+
+static const Q_UINT8 ui_2E[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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,
+};
+
+static const Q_UINT8 ui_2F[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 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,
+};
+
+static const Q_UINT8 ui_30[] = {
+ 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, 0, 0, 0, 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, 0, 0, 0,
+ 0, 1, 1, 29, 29, 18, 18, 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, 20, 18, 18, 18, 0,
+};
+
+static const Q_UINT8 ui_31[] = {
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_32[] = {
+ 30, 30, 30, 30, 30, 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, 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, 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, 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,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 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,
+};
+
+static const Q_UINT8 ui_33[] = {
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 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,
+};
+
+static const Q_UINT8 ui_34[] = {
+ 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,
+};
+
+static const Q_UINT8 ui_4D[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_9F[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_A4[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 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, 0, 0, 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, 0, 30, 30, 30, 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_D7[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_D8[] = {
+ 12, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_DB[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 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,
+};
+
+static const Q_UINT8 ui_DF[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 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,
+};
+
+static const Q_UINT8 ui_E0[] = {
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_F8[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 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,
+};
+
+static const Q_UINT8 ui_FA[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_FB[] = {
+ 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,
+};
+
+static const Q_UINT8 ui_FD[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 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, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 ui_FE[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 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, 0, 0, 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, 0, 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,
+};
+
+static const Q_UINT8 ui_FF[] = {
+ 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, 0,
+ 0, 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,
+};
+
+static const Q_UINT8 * const unicode_info[256] = {
+ ui_00, ui_01, ui_02, ui_03, ui_04, ui_05, ui_06, ui_07,
+ ui_08, ui_09, ui_0A, ui_0B, ui_0C, ui_0D, ui_0E, ui_0F,
+ ui_10, ui_11, ui_12, ui_13, ui_14, ui_15, ui_16, ui_17,
+ ui_18, ui_08, ui_08, ui_08, ui_08, ui_08, ui_1E, ui_1F,
+ ui_20, ui_21, ui_22, ui_23, ui_24, ui_25, ui_26, ui_27,
+ ui_28, ui_08, ui_08, ui_08, ui_08, ui_08, ui_2E, ui_2F,
+ ui_30, ui_31, ui_32, ui_33, ui_34, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_4D, ui_34, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_9F,
+ ui_15, ui_15, ui_15, ui_15, ui_A4, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_34, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_D7,
+ ui_D8, ui_08, ui_08, ui_DB, ui_D8, ui_08, ui_08, ui_DF,
+ ui_E0, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08, ui_08,
+ ui_F8, ui_15, ui_FA, ui_FB, ui_15, ui_FD, ui_FE, ui_FF,
+};
+// 15616 bytes
+
+static const Q_UINT16 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,
+ 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, 0x2048, 0x003F, 0x0021, 0,
+ 16, 0x2049, 0x0021, 0x003F, 0,
+ 9, 0x2070, 0x0030, 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,
+ 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, 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,
+ 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,
+ 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, 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,
+ 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, 0x96FB, 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,
+ 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,
+ 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,
+ 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,
+
+};
+
+static const Q_UINT16 di_00[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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,
+};
+
+static const Q_UINT16 di_01[] = {
+ 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,
+};
+
+static const Q_UINT16 di_02[] = {
+ 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,
+};
+
+static const Q_UINT16 di_03[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_04[] = {
+ 1688, 1693, 0, 1698, 0, 0, 0, 1703,
+ 0, 0, 0, 0, 1708, 1713, 1718, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1723, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1728, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1733, 1738, 0, 1743, 0, 0, 0, 1748,
+ 0, 0, 0, 0, 1753, 1758, 1763, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1768, 1773,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1778, 1783, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1788, 1793, 1798, 1803, 0, 0, 1808, 1813,
+ 0, 0, 1818, 1823, 1828, 1833, 1838, 1843,
+ 0, 0, 1848, 1853, 1858, 1863, 1868, 1873,
+ 0, 0, 1878, 1883, 1888, 1893, 1898, 1903,
+ 1908, 1913, 1918, 1923, 1928, 1933, 0, 0,
+ 1938, 1943, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_05[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1948,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_06[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1953, 1958, 1963, 1968, 1973, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1978, 1983, 1988,
+ 1993, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1998, 0, 2003, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2008, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_07[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_09[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2013, 0, 0, 0, 0, 0, 0,
+ 0, 2018, 0, 0, 2023, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2028, 2033, 2038, 2043, 2048, 2053, 2058, 2063,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2068, 2073, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2078, 2083, 0, 2088,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_0A[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2093, 0, 0, 2098, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2103, 2108, 2113, 0, 0, 2118, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_0B[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2123, 0, 0, 2128, 2133, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2138, 2143, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2148, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2153, 2158, 2163, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_0C[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2168, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2173, 0, 0, 0, 0, 0, 0, 2178,
+ 2183, 0, 2188, 2193, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_0D[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2198, 2203, 2208, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2213, 0, 2218, 2223, 2228, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_0E[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2233, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2238, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2243, 2248, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_0F[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2253, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2257, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2262, 0, 0,
+ 0, 0, 2267, 0, 0, 0, 0, 2272,
+ 0, 0, 0, 0, 2277, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2282, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2287, 0, 2292, 2297, 2302,
+ 2307, 2312, 0, 0, 0, 0, 0, 0,
+ 0, 2317, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2322, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2327, 0, 0,
+ 0, 0, 2332, 0, 0, 0, 0, 2337,
+ 0, 0, 0, 0, 2342, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2347, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_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, 2352, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_1E[] = {
+ 2357, 2362, 2367, 2372, 2377, 2382, 2387, 2392,
+ 2397, 2402, 2407, 2412, 2417, 2422, 2427, 2432,
+ 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472,
+ 2477, 2482, 2487, 2492, 2497, 2502, 2507, 2512,
+ 2517, 2522, 2527, 2532, 2537, 2542, 2547, 2552,
+ 2557, 2562, 2567, 2572, 2577, 2582, 2587, 2592,
+ 2597, 2602, 2607, 2612, 2617, 2622, 2627, 2632,
+ 2637, 2642, 2647, 2652, 2657, 2662, 2667, 2672,
+ 2677, 2682, 2687, 2692, 2697, 2702, 2707, 2712,
+ 2717, 2722, 2727, 2732, 2737, 2742, 2747, 2752,
+ 2757, 2762, 2767, 2772, 2777, 2782, 2787, 2792,
+ 2797, 2802, 2807, 2812, 2817, 2822, 2827, 2832,
+ 2837, 2842, 2847, 2852, 2857, 2862, 2867, 2872,
+ 2877, 2882, 2887, 2892, 2897, 2902, 2907, 2912,
+ 2917, 2922, 2927, 2932, 2937, 2942, 2947, 2952,
+ 2957, 2962, 2967, 2972, 2977, 2982, 2987, 2992,
+ 2997, 3002, 3007, 3012, 3017, 3022, 3027, 3032,
+ 3037, 3042, 3047, 3052, 3057, 3062, 3067, 3072,
+ 3077, 3082, 3087, 3092, 3097, 3102, 3107, 3112,
+ 3117, 3122, 3127, 3132, 0, 0, 0, 0,
+ 3137, 3142, 3147, 3152, 3157, 3162, 3167, 3172,
+ 3177, 3182, 3187, 3192, 3197, 3202, 3207, 3212,
+ 3217, 3222, 3227, 3232, 3237, 3242, 3247, 3252,
+ 3257, 3262, 3267, 3272, 3277, 3282, 3287, 3292,
+ 3297, 3302, 3307, 3312, 3317, 3322, 3327, 3332,
+ 3337, 3342, 3347, 3352, 3357, 3362, 3367, 3372,
+ 3377, 3382, 3387, 3392, 3397, 3402, 3407, 3412,
+ 3417, 3422, 3427, 3432, 3437, 3442, 3447, 3452,
+ 3457, 3462, 3467, 3472, 3477, 3482, 3487, 3492,
+ 3497, 3502, 3507, 3512, 3517, 3522, 3527, 3532,
+ 3537, 3542, 3547, 3552, 3557, 3562, 3567, 3572,
+ 3577, 3582, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_1F[] = {
+ 3587, 3592, 3597, 3602, 3607, 3612, 3617, 3622,
+ 3627, 3632, 3637, 3642, 3647, 3652, 3657, 3662,
+ 3667, 3672, 3677, 3682, 3687, 3692, 0, 0,
+ 3697, 3702, 3707, 3712, 3717, 3722, 0, 0,
+ 3727, 3732, 3737, 3742, 3747, 3752, 3757, 3762,
+ 3767, 3772, 3777, 3782, 3787, 3792, 3797, 3802,
+ 3807, 3812, 3817, 3822, 3827, 3832, 3837, 3842,
+ 3847, 3852, 3857, 3862, 3867, 3872, 3877, 3882,
+ 3887, 3892, 3897, 3902, 3907, 3912, 0, 0,
+ 3917, 3922, 3927, 3932, 3937, 3942, 0, 0,
+ 3947, 3952, 3957, 3962, 3967, 3972, 3977, 3982,
+ 0, 3987, 0, 3992, 0, 3997, 0, 4002,
+ 4007, 4012, 4017, 4022, 4027, 4032, 4037, 4042,
+ 4047, 4052, 4057, 4062, 4067, 4072, 4077, 4082,
+ 4087, 4092, 4096, 4101, 4105, 4110, 4114, 4119,
+ 4123, 4128, 4132, 4137, 4141, 4146, 0, 0,
+ 4150, 4155, 4160, 4165, 4170, 4175, 4180, 4185,
+ 4190, 4195, 4200, 4205, 4210, 4215, 4220, 4225,
+ 4230, 4235, 4240, 4245, 4250, 4255, 4260, 4265,
+ 4270, 4275, 4280, 4285, 4290, 4295, 4300, 4305,
+ 4310, 4315, 4320, 4325, 4330, 4335, 4340, 4345,
+ 4350, 4355, 4360, 4365, 4370, 4375, 4380, 4385,
+ 4390, 4395, 4400, 4405, 4410, 0, 4415, 4420,
+ 4425, 4430, 4435, 4440, 4444, 4449, 4454, 4458,
+ 4463, 4468, 4473, 4478, 4483, 0, 4488, 4493,
+ 4498, 4503, 4507, 4512, 4516, 4521, 4526, 4531,
+ 4536, 4541, 4546, 4551, 0, 0, 4555, 4560,
+ 4565, 4570, 4575, 4580, 0, 4584, 4589, 4594,
+ 4599, 4604, 4609, 4614, 4618, 4623, 4628, 4633,
+ 4638, 4643, 4648, 4653, 4657, 4662, 4667, 4671,
+ 0, 0, 4675, 4680, 4685, 0, 4690, 4695,
+ 4700, 4705, 4709, 4714, 4718, 4723, 4727, 0,
+};
+
+static const Q_UINT16 di_20[] = {
+ 4732, 4736, 4740, 4744, 4748, 4752, 4756, 4760,
+ 4764, 4768, 4772, 0, 0, 0, 0, 0,
+ 0, 4776, 0, 0, 0, 0, 0, 4780,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4785, 4789, 4794, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4800,
+ 0, 0, 0, 4804, 4809, 0, 4815, 4820,
+ 0, 0, 0, 0, 4826, 0, 4831, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4836, 4841, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4846, 0, 0, 0, 4850, 4854, 4858, 4862,
+ 4866, 4870, 4874, 4878, 4882, 4886, 4890, 4894,
+ 4898, 4902, 4906, 4910, 4914, 4918, 4922, 4926,
+ 4930, 4934, 4938, 4942, 4946, 4950, 4954, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4958, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_21[] = {
+ 4963, 4969, 4975, 4979, 0, 4984, 4990, 4996,
+ 0, 5000, 5005, 5009, 5013, 5017, 5021, 5025,
+ 5029, 5033, 5037, 5041, 0, 5045, 5049, 0,
+ 0, 5054, 5058, 5062, 5066, 5070, 0, 0,
+ 5074, 5079, 5085, 0, 5090, 0, 5094, 0,
+ 5098, 0, 5102, 5106, 5110, 5114, 0, 5118,
+ 5122, 5126, 0, 5130, 5134, 5138, 5142, 5146,
+ 5150, 5154, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5158, 5164, 5170, 5176, 5182,
+ 5188, 5194, 5200, 5206, 5212, 5218, 5224, 5230,
+ 5235, 5239, 5244, 5250, 5255, 5259, 5264, 5270,
+ 5277, 5282, 5286, 5291, 5297, 5301, 5305, 5309,
+ 5313, 5317, 5322, 5328, 5333, 5337, 5342, 5348,
+ 5355, 5360, 5364, 5369, 5375, 5379, 5383, 5387,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 5391, 5396, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 5401, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 5406, 5411, 5416,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_22[] = {
+ 0, 0, 0, 0, 5421, 0, 0, 0,
+ 0, 5426, 0, 0, 5431, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5436, 0, 5441, 0,
+ 0, 0, 0, 0, 5446, 5451, 0, 5457,
+ 5462, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5468, 0, 0, 5473, 0, 0, 5478,
+ 0, 5483, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 5488, 0, 5493, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 5498, 5503, 5508,
+ 5513, 5518, 0, 0, 5523, 5528, 0, 0,
+ 5533, 5538, 0, 0, 0, 0, 0, 0,
+ 5543, 5548, 0, 0, 5553, 5558, 0, 0,
+ 5563, 5568, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5573, 5578, 5583, 5588,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 5593, 5598, 5603, 5608, 0, 0, 0, 0,
+ 0, 0, 5613, 5618, 5623, 5628, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_23[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5633, 5637, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_24[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 5641, 5645, 5649, 5653, 5657, 5661, 5665, 5669,
+ 5673, 5677, 5682, 5687, 5692, 5697, 5702, 5707,
+ 5712, 5717, 5722, 5727, 5732, 5738, 5744, 5750,
+ 5756, 5762, 5768, 5774, 5780, 5786, 5793, 5800,
+ 5807, 5814, 5821, 5828, 5835, 5842, 5849, 5856,
+ 5863, 5868, 5873, 5878, 5883, 5888, 5893, 5898,
+ 5903, 5908, 5914, 5920, 5926, 5932, 5938, 5944,
+ 5950, 5956, 5962, 5968, 5974, 5980, 5986, 5992,
+ 5998, 6004, 6010, 6016, 6022, 6028, 6034, 6040,
+ 6046, 6052, 6058, 6064, 6070, 6076, 6082, 6088,
+ 6094, 6100, 6106, 6112, 6118, 6124, 6130, 6134,
+ 6138, 6142, 6146, 6150, 6154, 6158, 6162, 6166,
+ 6170, 6174, 6178, 6182, 6186, 6190, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_2E[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 6342,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6346, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_2F[] = {
+ 6350, 6354, 6358, 6362, 6366, 6370, 6374, 6378,
+ 6382, 6386, 6390, 6394, 6398, 6402, 6406, 6410,
+ 6414, 6418, 6422, 6426, 6430, 6434, 6438, 6442,
+ 6446, 6450, 6454, 6458, 6462, 6466, 6470, 6474,
+ 6478, 6482, 6486, 6490, 6494, 6498, 6502, 6506,
+ 6510, 6514, 6518, 6522, 6526, 6530, 6534, 6538,
+ 6542, 6546, 6550, 6554, 6558, 6562, 6566, 6570,
+ 6574, 6578, 6582, 6586, 6590, 6594, 6598, 6602,
+ 6606, 6610, 6614, 6618, 6622, 6626, 6630, 6634,
+ 6638, 6642, 6646, 6650, 6654, 6658, 6662, 6666,
+ 6670, 6674, 6678, 6682, 6686, 6690, 6694, 6698,
+ 6702, 6706, 6710, 6714, 6718, 6722, 6726, 6730,
+ 6734, 6738, 6742, 6746, 6750, 6754, 6758, 6762,
+ 6766, 6770, 6774, 6778, 6782, 6786, 6790, 6794,
+ 6798, 6802, 6806, 6810, 6814, 6818, 6822, 6826,
+ 6830, 6834, 6838, 6842, 6846, 6850, 6854, 6858,
+ 6862, 6866, 6870, 6874, 6878, 6882, 6886, 6890,
+ 6894, 6898, 6902, 6906, 6910, 6914, 6918, 6922,
+ 6926, 6930, 6934, 6938, 6942, 6946, 6950, 6954,
+ 6958, 6962, 6966, 6970, 6974, 6978, 6982, 6986,
+ 6990, 6994, 6998, 7002, 7006, 7010, 7014, 7018,
+ 7022, 7026, 7030, 7034, 7038, 7042, 7046, 7050,
+ 7054, 7058, 7062, 7066, 7070, 7074, 7078, 7082,
+ 7086, 7090, 7094, 7098, 7102, 7106, 7110, 7114,
+ 7118, 7122, 7126, 7130, 7134, 7138, 7142, 7146,
+ 7150, 7154, 7158, 7162, 7166, 7170, 7174, 7178,
+ 7182, 7186, 7190, 7194, 7198, 7202, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_30[] = {
+ 7206, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7210, 0,
+ 7214, 7218, 7222, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7226, 0, 7231, 0,
+ 7236, 0, 7241, 0, 7246, 0, 7251, 0,
+ 7256, 0, 7261, 0, 7266, 0, 7271, 0,
+ 7276, 0, 7281, 0, 0, 7286, 0, 7291,
+ 0, 7296, 0, 0, 0, 0, 0, 0,
+ 7301, 7306, 0, 7311, 7316, 0, 7321, 7326,
+ 0, 7331, 7336, 0, 7341, 7346, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7351, 0, 0, 0,
+ 0, 0, 0, 7356, 7361, 0, 7366, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7371, 0, 7376, 0,
+ 7381, 0, 7386, 0, 7391, 0, 7396, 0,
+ 7401, 0, 7406, 0, 7411, 0, 7416, 0,
+ 7421, 0, 7426, 0, 0, 7431, 0, 7436,
+ 0, 7441, 0, 0, 0, 0, 0, 0,
+ 7446, 7451, 0, 7456, 7461, 0, 7466, 7471,
+ 0, 7476, 7481, 0, 7486, 7491, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7496, 0, 0, 7501,
+ 7506, 7511, 7516, 0, 0, 0, 7521, 0,
+};
+
+static const Q_UINT16 di_31[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 7526, 7530, 7534, 7538, 7542, 7546, 7550,
+ 7554, 7558, 7562, 7566, 7570, 7574, 7578, 7582,
+ 7586, 7590, 7594, 7598, 7602, 7606, 7610, 7614,
+ 7618, 7622, 7626, 7630, 7634, 7638, 7642, 7646,
+ 7650, 7654, 7658, 7662, 7666, 7670, 7674, 7678,
+ 7682, 7686, 7690, 7694, 7698, 7702, 7706, 7710,
+ 7714, 7718, 7722, 7726, 7730, 7734, 7738, 7742,
+ 7746, 7750, 7754, 7758, 7762, 7766, 7770, 7774,
+ 7778, 7782, 7786, 7790, 7794, 7798, 7802, 7806,
+ 7810, 7814, 7818, 7822, 7826, 7830, 7834, 7838,
+ 7842, 7846, 7850, 7854, 7858, 7862, 7866, 7870,
+ 7874, 7878, 7882, 7886, 7890, 7894, 7898, 0,
+ 0, 0, 7902, 7906, 7910, 7914, 7918, 7922,
+ 7926, 7930, 7934, 7938, 7942, 7946, 7950, 7954,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_32[] = {
+ 7958, 7964, 7970, 7976, 7982, 7988, 7994, 8000,
+ 8006, 8012, 8018, 8024, 8030, 8036, 8042, 8049,
+ 8056, 8063, 8070, 8077, 8084, 8091, 8098, 8105,
+ 8112, 8119, 8126, 8133, 8140, 0, 0, 0,
+ 8147, 8153, 8159, 8165, 8171, 8177, 8183, 8189,
+ 8195, 8201, 8207, 8213, 8219, 8225, 8231, 8237,
+ 8243, 8249, 8255, 8261, 8267, 8273, 8279, 8285,
+ 8291, 8297, 8303, 8309, 8315, 8321, 8327, 8333,
+ 8339, 8345, 8351, 8357, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 8363, 8367, 8371, 8375, 8379, 8383, 8387, 8391,
+ 8395, 8399, 8403, 8407, 8411, 8415, 8419, 8424,
+ 8429, 8434, 8439, 8444, 8449, 8454, 8459, 8464,
+ 8469, 8474, 8479, 8484, 0, 0, 0, 0,
+ 8489, 8493, 8497, 8501, 8505, 8509, 8513, 8517,
+ 8521, 8525, 8529, 8533, 8537, 8541, 8545, 8549,
+ 8553, 8557, 8561, 8565, 8569, 8573, 8577, 8581,
+ 8585, 8589, 8593, 8597, 8601, 8605, 8609, 8613,
+ 8617, 8621, 8625, 8629, 8633, 8637, 8641, 8645,
+ 8649, 8653, 8657, 8661, 8665, 8669, 8673, 8677,
+ 8681, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 8685, 8690, 8695, 8700, 8705, 8710, 8715, 8720,
+ 8725, 8730, 8736, 8742, 0, 0, 0, 0,
+ 8748, 8752, 8756, 8760, 8764, 8768, 8772, 8776,
+ 8780, 8784, 8788, 8792, 8796, 8800, 8804, 8808,
+ 8812, 8816, 8820, 8824, 8828, 8832, 8836, 8840,
+ 8844, 8848, 8852, 8856, 8860, 8864, 8868, 8872,
+ 8876, 8880, 8884, 8888, 8892, 8896, 8900, 8904,
+ 8908, 8912, 8916, 8920, 8924, 8928, 8932, 0,
+};
+
+static const Q_UINT16 di_33[] = {
+ 8936, 8943, 8950, 8957, 8963, 8970, 8976, 8982,
+ 8990, 8997, 9003, 9009, 9015, 9022, 9029, 9035,
+ 9041, 9046, 9052, 9059, 9066, 9071, 9079, 9088,
+ 9096, 9102, 9110, 9118, 9125, 9131, 9137, 9143,
+ 9150, 9158, 9165, 9171, 9177, 9183, 9188, 9193,
+ 9198, 9203, 9209, 9215, 9223, 9229, 9236, 9244,
+ 9250, 9255, 9260, 9268, 9275, 9283, 9289, 9297,
+ 9302, 9308, 9314, 9320, 9326, 9332, 9339, 9345,
+ 9350, 9356, 9362, 9368, 9375, 9381, 9387, 9393,
+ 9401, 9408, 9413, 9421, 9426, 9433, 9440, 9446,
+ 9452, 9458, 9465, 9470, 9476, 9483, 9488, 9496,
+ 9502, 9507, 9512, 9517, 9522, 9527, 9532, 9537,
+ 9542, 9547, 9552, 9558, 9564, 9570, 9576, 9582,
+ 9588, 9594, 9600, 9606, 9612, 9618, 9624, 9630,
+ 9636, 9642, 9648, 9653, 9658, 9664, 9669, 0,
+ 0, 0, 0, 9674, 9679, 9684, 9689, 9694,
+ 9701, 9706, 9711, 9716, 9721, 9726, 9731, 9736,
+ 9741, 9747, 9754, 9759, 9764, 9769, 9774, 9779,
+ 9784, 9789, 9795, 9801, 9807, 9813, 9818, 9823,
+ 9828, 9833, 9838, 9843, 9848, 9853, 9858, 9863,
+ 9869, 9875, 9880, 9886, 9892, 9898, 9903, 9909,
+ 9915, 9922, 9927, 9933, 9939, 9945, 9951, 9959,
+ 9968, 9973, 9978, 9983, 9988, 9993, 9998, 10003,
+ 10008, 10013, 10018, 10023, 10028, 10033, 10038, 10043,
+ 10048, 10053, 10058, 10065, 10070, 10075, 10080, 10087,
+ 10093, 10098, 10103, 10108, 10113, 10118, 10123, 10128,
+ 10133, 10138, 10143, 10149, 10154, 10159, 10165, 10171,
+ 10176, 10183, 10189, 10194, 10199, 10204, 0, 0,
+ 10209, 10214, 10219, 10224, 10229, 10234, 10239, 10244,
+ 10249, 10254, 10260, 10266, 10272, 10278, 10284, 10290,
+ 10296, 10302, 10308, 10314, 10320, 10326, 10332, 10338,
+ 10344, 10350, 10356, 10362, 10368, 10374, 10380, 0,
+};
+
+static const Q_UINT16 di_F9[] = {
+ 10386, 10390, 10394, 10398, 10402, 10406, 10410, 10414,
+ 10418, 10422, 10426, 10430, 10434, 10438, 10442, 10446,
+ 10450, 10454, 10458, 10462, 10466, 10470, 10474, 10478,
+ 10482, 10486, 10490, 10494, 10498, 10502, 10506, 10510,
+ 10514, 10518, 10522, 10526, 10530, 10534, 10538, 10542,
+ 10546, 10550, 10554, 10558, 10562, 10566, 10570, 10574,
+ 10578, 10582, 10586, 10590, 10594, 10598, 10602, 10606,
+ 10610, 10614, 10618, 10622, 10626, 10630, 10634, 10638,
+ 10642, 10646, 10650, 10654, 10658, 10662, 10666, 10670,
+ 10674, 10678, 10682, 10686, 10690, 10694, 10698, 10702,
+ 10706, 10710, 10714, 10718, 10722, 10726, 10730, 10734,
+ 10738, 10742, 10746, 10750, 10754, 10758, 10762, 10766,
+ 10770, 10774, 10778, 10782, 10786, 10790, 10794, 10798,
+ 10802, 10806, 10810, 10814, 10818, 10822, 10826, 10830,
+ 10834, 10838, 10842, 10846, 10850, 10854, 10858, 10862,
+ 10866, 10870, 10874, 10878, 10882, 10886, 10890, 10894,
+ 10898, 10902, 10906, 10910, 10914, 10918, 10922, 10926,
+ 10930, 10934, 10938, 10942, 10946, 10950, 10954, 10958,
+ 10962, 10966, 10970, 10974, 10978, 10982, 10986, 10990,
+ 10994, 10998, 11002, 11006, 11010, 11014, 11018, 11022,
+ 11026, 11030, 11034, 11038, 11042, 11046, 11050, 11054,
+ 11058, 11062, 11066, 11070, 11074, 11078, 11082, 11086,
+ 11090, 11094, 11098, 11102, 11106, 11110, 11114, 11118,
+ 11122, 11126, 11130, 11134, 11138, 11142, 11146, 11150,
+ 11154, 11158, 11162, 11166, 11170, 11174, 11178, 11182,
+ 11186, 11190, 11194, 11198, 11202, 11206, 11210, 11214,
+ 11218, 11222, 11226, 11230, 11234, 11238, 11242, 11246,
+ 11250, 11254, 11258, 11262, 11266, 11270, 11274, 11278,
+ 11282, 11286, 11290, 11294, 11298, 11302, 11306, 11310,
+ 11314, 11318, 11322, 11326, 11330, 11334, 11338, 11342,
+ 11346, 11350, 11354, 11358, 11362, 11366, 11370, 11374,
+ 11378, 11382, 11386, 11390, 11394, 11398, 11402, 11406,
+};
+
+static const Q_UINT16 di_FA[] = {
+ 11410, 11414, 11418, 11422, 11426, 11430, 11434, 11438,
+ 11442, 11446, 11450, 11454, 11458, 11462, 0, 0,
+ 11466, 0, 11470, 0, 0, 11474, 11478, 11482,
+ 11486, 11490, 11494, 11498, 11502, 11506, 11510, 0,
+ 11514, 0, 11518, 0, 0, 11522, 11526, 0,
+ 0, 0, 11530, 11534, 11538, 11542, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_FB[] = {
+ 11546, 11551, 11556, 11561, 11567, 11573, 11578, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 11583, 11588, 11593, 11598, 11603,
+ 0, 0, 0, 0, 0, 11608, 0, 11613,
+ 11618, 11622, 11626, 11630, 11634, 11638, 11642, 11646,
+ 11650, 11654, 11658, 11663, 11668, 11673, 11678, 11683,
+ 11688, 11693, 11698, 11703, 11708, 11713, 11718, 0,
+ 11723, 11728, 11733, 11738, 11743, 0, 11748, 0,
+ 11753, 11758, 0, 11763, 11768, 0, 11773, 11778,
+ 11783, 11788, 11793, 11798, 11803, 11808, 11813, 11818,
+ 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, 12035, 12039, 12043,
+ 12047, 12051, 12055, 12059, 12063, 12067, 12071, 12075,
+ 12079, 12083, 12087, 12091, 12095, 12099, 12103, 12107,
+ 12111, 12115, 12119, 12123, 12127, 12131, 12135, 12139,
+ 12143, 12147, 12151, 12155, 12159, 12163, 12167, 12171,
+ 12175, 12179, 12183, 12187, 12191, 12195, 12199, 12203,
+ 12207, 12211, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 12215, 12219, 12223, 12227, 12231,
+ 12235, 12239, 12243, 12247, 12251, 12255, 12259, 12263,
+ 12267, 12271, 12275, 12279, 12283, 12287, 12291, 12295,
+ 12299, 12303, 12307, 12312, 12317, 12322, 12327, 12332,
+ 12337, 12342, 12347, 12352, 12357, 12362, 12367, 12372,
+ 12377, 12382, 12387, 12392, 12397, 12401, 12405, 12409,
+};
+
+static const Q_UINT16 di_FC[] = {
+ 12413, 12418, 12423, 12428, 12433, 12438, 12443, 12448,
+ 12453, 12458, 12463, 12468, 12473, 12478, 12483, 12488,
+ 12493, 12498, 12503, 12508, 12513, 12518, 12523, 12528,
+ 12533, 12538, 12543, 12548, 12553, 12558, 12563, 12568,
+ 12573, 12578, 12583, 12588, 12593, 12598, 12603, 12608,
+ 12613, 12618, 12623, 12628, 12633, 12638, 12643, 12648,
+ 12653, 12658, 12663, 12668, 12673, 12678, 12683, 12688,
+ 12693, 12698, 12703, 12708, 12713, 12718, 12723, 12728,
+ 12733, 12738, 12743, 12748, 12753, 12758, 12763, 12768,
+ 12773, 12778, 12783, 12788, 12793, 12798, 12803, 12808,
+ 12813, 12818, 12823, 12828, 12833, 12838, 12843, 12848,
+ 12853, 12858, 12863, 12868, 12873, 12878, 12883, 12889,
+ 12895, 12901, 12907, 12913, 12919, 12924, 12929, 12934,
+ 12939, 12944, 12949, 12954, 12959, 12964, 12969, 12974,
+ 12979, 12984, 12989, 12994, 12999, 13004, 13009, 13014,
+ 13019, 13024, 13029, 13034, 13039, 13044, 13049, 13054,
+ 13059, 13064, 13069, 13074, 13079, 13084, 13089, 13094,
+ 13099, 13104, 13109, 13114, 13119, 13124, 13129, 13134,
+ 13139, 13144, 13149, 13154, 13159, 13164, 13169, 13174,
+ 13179, 13184, 13189, 13194, 13199, 13204, 13209, 13214,
+ 13219, 13224, 13229, 13234, 13239, 13244, 13249, 13254,
+ 13259, 13264, 13269, 13274, 13279, 13284, 13289, 13294,
+ 13299, 13304, 13309, 13314, 13319, 13324, 13329, 13334,
+ 13339, 13344, 13349, 13354, 13359, 13364, 13369, 13374,
+ 13379, 13384, 13389, 13394, 13399, 13404, 13409, 13414,
+ 13419, 13424, 13429, 13434, 13439, 13444, 13449, 13454,
+ 13459, 13464, 13469, 13474, 13479, 13484, 13489, 13494,
+ 13499, 13504, 13509, 13514, 13519, 13524, 13529, 13534,
+ 13539, 13544, 13549, 13554, 13559, 13564, 13569, 13574,
+ 13579, 13584, 13589, 13594, 13599, 13604, 13609, 13614,
+ 13619, 13624, 13629, 13635, 13641, 13647, 13652, 13657,
+ 13662, 13667, 13672, 13677, 13682, 13687, 13692, 13697,
+};
+
+static const Q_UINT16 di_FD[] = {
+ 13702, 13707, 13712, 13717, 13722, 13727, 13732, 13737,
+ 13742, 13747, 13752, 13757, 13762, 13767, 13772, 13777,
+ 13782, 13787, 13792, 13797, 13802, 13807, 13812, 13817,
+ 13822, 13827, 13832, 13837, 13842, 13847, 13852, 13857,
+ 13862, 13867, 13872, 13877, 13882, 13887, 13892, 13897,
+ 13902, 13907, 13912, 13917, 13922, 13927, 13932, 13937,
+ 13942, 13947, 13952, 13957, 13962, 13967, 13972, 13977,
+ 13982, 13987, 13992, 13997, 14002, 14007, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 14012, 14018, 14024, 14030, 14036, 14042, 14048, 14054,
+ 14060, 14066, 14072, 14078, 14084, 14090, 14096, 14102,
+ 14108, 14114, 14120, 14126, 14132, 14138, 14144, 14150,
+ 14156, 14162, 14168, 14174, 14180, 14186, 14192, 14198,
+ 14204, 14210, 14216, 14222, 14228, 14234, 14240, 14246,
+ 14252, 14258, 14264, 14270, 14276, 14282, 14288, 14294,
+ 14300, 14306, 14312, 14318, 14324, 14330, 14336, 14342,
+ 14348, 14354, 14360, 14366, 14372, 14378, 14384, 14390,
+ 0, 0, 14396, 14402, 14408, 14414, 14420, 14426,
+ 14432, 14438, 14444, 14450, 14456, 14462, 14468, 14474,
+ 14480, 14486, 14492, 14498, 14504, 14510, 14516, 14522,
+ 14528, 14534, 14540, 14546, 14552, 14558, 14564, 14570,
+ 14576, 14582, 14588, 14594, 14600, 14606, 14612, 14618,
+ 14624, 14630, 14636, 14642, 14648, 14654, 14660, 14666,
+ 14672, 14678, 14684, 14690, 14696, 14702, 14708, 14714,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 14720, 14726, 14732, 14739, 14746, 14753, 14760, 14767,
+ 14774, 14781, 14787, 14808, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 di_FE[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 14819, 14823, 14827, 14831, 14835, 14839, 14843, 14847,
+ 14851, 14855, 14859, 14863, 14867, 14871, 14875, 14879,
+ 14883, 14887, 14891, 14895, 14899, 0, 0, 0,
+ 0, 14903, 14907, 14911, 14915, 14919, 14923, 14927,
+ 14931, 14935, 14939, 0, 14943, 14947, 14951, 14955,
+ 14959, 14963, 14967, 14971, 14975, 14979, 14983, 14987,
+ 14991, 14995, 14999, 15003, 15007, 15011, 15015, 0,
+ 15019, 15023, 15027, 15031, 0, 0, 0, 0,
+ 15035, 15040, 15045, 0, 15050, 0, 15055, 15060,
+ 15065, 15070, 15075, 15080, 15085, 15090, 15095, 15100,
+ 15105, 15109, 15113, 15117, 15121, 15125, 15129, 15133,
+ 15137, 15141, 15145, 15149, 15153, 15157, 15161, 15165,
+ 15169, 15173, 15177, 15181, 15185, 15189, 15193, 15197,
+ 15201, 15205, 15209, 15213, 15217, 15221, 15225, 15229,
+ 15233, 15237, 15241, 15245, 15249, 15253, 15257, 15261,
+ 15265, 15269, 15273, 15277, 15281, 15285, 15289, 15293,
+ 15297, 15301, 15305, 15309, 15313, 15317, 15321, 15325,
+ 15329, 15333, 15337, 15341, 15345, 15349, 15353, 15357,
+ 15361, 15365, 15369, 15373, 15377, 15381, 15385, 15389,
+ 15393, 15397, 15401, 15405, 15409, 15413, 15417, 15421,
+ 15425, 15429, 15433, 15437, 15441, 15445, 15449, 15453,
+ 15457, 15461, 15465, 15469, 15473, 15477, 15481, 15485,
+ 15489, 15493, 15497, 15501, 15505, 15509, 15513, 15517,
+ 15521, 15525, 15529, 15533, 15537, 15541, 15545, 15549,
+ 15553, 15557, 15561, 15565, 15569, 15573, 15578, 15583,
+ 15588, 15593, 15598, 15603, 15608, 0, 0, 0,
+};
+
+static const Q_UINT16 di_FF[] = {
+ 0, 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, 0,
+ 0, 15989, 15993, 15997, 16001, 16005, 16009, 16013,
+ 16017, 16021, 16025, 16029, 16033, 16037, 16041, 16045,
+ 16049, 16053, 16057, 16061, 16065, 16069, 16073, 16077,
+ 16081, 16085, 16089, 16093, 16097, 16101, 16105, 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, 0,
+ 0, 0, 16365, 16369, 16373, 16377, 16381, 16385,
+ 0, 0, 16389, 16393, 16397, 16401, 16405, 16409,
+ 0, 0, 16413, 16417, 16421, 16425, 16429, 16433,
+ 0, 0, 16437, 16441, 16445, 0, 0, 0,
+ 16449, 16453, 16457, 16461, 16465, 16469, 16473, 0,
+ 16477, 16481, 16485, 16489, 16493, 16497, 16501, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 * const decomposition_info[256] = {
+ di_00, di_01, di_02, di_03, di_04, di_05, di_06, di_07,
+ di_07, di_09, di_0A, di_0B, di_0C, di_0D, di_0E, di_0F,
+ di_10, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_1E, di_1F,
+ di_20, di_21, di_22, di_23, di_24, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_2E, di_2F,
+ di_30, di_31, di_32, di_33, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_07, di_07, di_07, di_07, di_07, di_07, di_07,
+ di_07, di_F9, di_FA, di_FB, di_FC, di_FD, di_FE, di_FF,
+};
+// 68080 bytes
+
+static const Q_UINT16 ligature_map [] = {
+ 0,
+ 12883, 12889, 12895, 12901, 12907, 12913, 15035, 15045, 15050, 15055, 15065, 15075, 15085, 15095, 0,
+ 5503, 0,
+ 5488, 0,
+ 5508, 0,
+ 67, 72, 77, 82, 87, 92, 332, 342, 352, 966, 1196, 1206, 1346, 2357, 3137, 3147, 0,
+ 2367, 2377, 2387, 0,
+ 97, 362, 372, 382, 392, 0,
+ 402, 2407, 2417, 2427, 2437, 2447, 0,
+ 102, 107, 112, 117, 412, 422, 432, 442, 452, 1216, 1226, 1356, 2477, 2487, 3257, 3267, 3277, 0,
+ 2507, 0,
+ 462, 472, 482, 492, 1076, 1146, 2517, 0,
+ 502, 1336, 2527, 2537, 2547, 2557, 2567, 0,
+ 122, 127, 132, 137, 512, 522, 532, 542, 552, 976, 1236, 1246, 2577, 3337, 3347, 0,
+ 567, 0,
+ 577, 1086, 2597, 2607, 2617, 0,
+ 587, 597, 607, 2627, 2647, 2657, 0,
+ 2667, 2677, 2687, 0,
+ 142, 627, 637, 647, 1156, 2697, 2707, 2717, 2727, 0,
+ 147, 152, 157, 162, 167, 662, 672, 682, 901, 986, 1096, 1256, 1266, 1386, 3357, 3367, 0,
+ 2777, 2787, 0,
+ 692, 702, 712, 1276, 1286, 2797, 2807, 2827, 0,
+ 722, 732, 742, 752, 1316, 2837, 2847, 0,
+ 762, 772, 1326, 2887, 2897, 2907, 2917, 0,
+ 172, 177, 182, 187, 782, 792, 802, 812, 822, 832, 911, 996, 1296, 1306, 2927, 2937, 2947, 3477, 3487, 0,
+ 2977, 2987, 0,
+ 842, 2997, 3007, 3017, 3027, 3037, 0,
+ 3047, 3057, 0,
+ 192, 852, 862, 1406, 3067, 3547, 3557, 3567, 3577, 0,
+ 867, 877, 887, 3077, 3087, 3097, 0,
+ 197, 202, 207, 212, 217, 222, 337, 347, 357, 971, 1201, 1211, 1351, 2362, 3142, 3152, 0,
+ 2372, 2382, 2392, 0,
+ 227, 367, 377, 387, 397, 0,
+ 407, 2412, 2422, 2432, 2442, 2452, 0,
+ 232, 237, 242, 247, 417, 427, 437, 447, 457, 1221, 1231, 1361, 2482, 2492, 3262, 3272, 3282, 0,
+ 2512, 0,
+ 467, 477, 487, 497, 1081, 1151, 2522, 0,
+ 507, 1341, 2532, 2542, 2552, 2562, 2572, 3107, 0,
+ 252, 257, 262, 267, 517, 527, 537, 547, 981, 1241, 1251, 2582, 3342, 3352, 0,
+ 572, 1126, 0,
+ 582, 1091, 2602, 2612, 2622, 0,
+ 592, 602, 612, 2632, 2652, 2662, 0,
+ 2672, 2682, 2692, 0,
+ 272, 632, 642, 652, 1161, 2702, 2712, 2722, 2732, 0,
+ 277, 282, 287, 292, 297, 667, 677, 687, 906, 991, 1101, 1261, 1271, 1391, 3362, 3372, 0,
+ 2782, 2792, 0,
+ 697, 707, 717, 1281, 1291, 2802, 2812, 2832, 0,
+ 727, 737, 747, 757, 1321, 2842, 2852, 0,
+ 767, 777, 1331, 2892, 2902, 2912, 2922, 3112, 0,
+ 302, 307, 312, 317, 787, 797, 807, 817, 827, 837, 916, 1001, 1301, 1311, 2932, 2942, 2952, 3482, 3492, 0,
+ 2982, 2992, 0,
+ 847, 3002, 3012, 3022, 3032, 3042, 3117, 0,
+ 3052, 3062, 0,
+ 322, 327, 857, 1411, 3072, 3122, 3552, 3562, 3572, 3582, 0,
+ 872, 882, 892, 3082, 3092, 3102, 0,
+ 1537, 4468, 4662, 0,
+ 3157, 3167, 3177, 3187, 0,
+ 1046, 0,
+ 1166, 0,
+ 1066, 1176, 0,
+ 2397, 0,
+ 3287, 3297, 3307, 3317, 0,
+ 2587, 0,
+ 3377, 3387, 3397, 3407, 0,
+ 1376, 2737, 2747, 0,
+ 1366, 0,
+ 1186, 0,
+ 1006, 1016, 1026, 1036, 0,
+ 3162, 3172, 3182, 3192, 0,
+ 1051, 0,
+ 1171, 0,
+ 1071, 1181, 0,
+ 2402, 0,
+ 3292, 3302, 3312, 3322, 0,
+ 2592, 0,
+ 3382, 3392, 3402, 3412, 0,
+ 1381, 2742, 2752, 0,
+ 1371, 0,
+ 1191, 0,
+ 1011, 1021, 1031, 1041, 0,
+ 3207, 3217, 3227, 3237, 0,
+ 3212, 3222, 3232, 3242, 0,
+ 2457, 2467, 0,
+ 2462, 2472, 0,
+ 2757, 2767, 0,
+ 2762, 2772, 0,
+ 2857, 0,
+ 2862, 0,
+ 2867, 0,
+ 2872, 0,
+ 2957, 0,
+ 2962, 0,
+ 2967, 0,
+ 2972, 0,
+ 3132, 0,
+ 3427, 3437, 3447, 3457, 3467, 0,
+ 3432, 3442, 3452, 3462, 3472, 0,
+ 3497, 3507, 3517, 3527, 3537, 0,
+ 3502, 3512, 3522, 3532, 3542, 0,
+ 1116, 0,
+ 1106, 0,
+ 1111, 0,
+ 1056, 0,
+ 1061, 0,
+ 2497, 0,
+ 2502, 0,
+ 1396, 0,
+ 1401, 0,
+ 1121, 0,
+ 1514, 0,
+ 1542, 3627, 3632, 4425, 4430, 4435, 4444, 0,
+ 1551, 3697, 3702, 4498, 0,
+ 1556, 3767, 3772, 4507, 4516, 0,
+ 1561, 1586, 3847, 3852, 4565, 4570, 4575, 0,
+ 1566, 3917, 3922, 4700, 0,
+ 4657, 0,
+ 1571, 1591, 3987, 4638, 4643, 4648, 0,
+ 1576, 4047, 4052, 4709, 4718, 0,
+ 4410, 0,
+ 4483, 0,
+ 1596, 3587, 3592, 4087, 4390, 4395, 4405, 4415, 0,
+ 1601, 3667, 3672, 4096, 0,
+ 1606, 3727, 3732, 4105, 4478, 4488, 0,
+ 1611, 1621, 3807, 3812, 4114, 4536, 4541, 4555, 0,
+ 1631, 3887, 3892, 4123, 0,
+ 4618, 4623, 0,
+ 1626, 1636, 3947, 3952, 4132, 4599, 4604, 4628, 0,
+ 1641, 4007, 4012, 4141, 4680, 4690, 0,
+ 1581, 4546, 4560, 0,
+ 1616, 4609, 4633, 0,
+ 4685, 0,
+ 1658, 1663, 0,
+ 1703, 0,
+ 1788, 1798, 0,
+ 1698, 0,
+ 1688, 1693, 1808, 0,
+ 1778, 1828, 0,
+ 1838, 0,
+ 1713, 1723, 1848, 1858, 0,
+ 1708, 0,
+ 1868, 0,
+ 1718, 1898, 1908, 1918, 0,
+ 1928, 0,
+ 1938, 0,
+ 1888, 0,
+ 1793, 1803, 0,
+ 1743, 0,
+ 1733, 1738, 1813, 0,
+ 1783, 1833, 0,
+ 1843, 0,
+ 1728, 1758, 1853, 1863, 0,
+ 1753, 0,
+ 1873, 0,
+ 1763, 1903, 1913, 1923, 0,
+ 1933, 0,
+ 1943, 0,
+ 1893, 0,
+ 1748, 0,
+ 1768, 0,
+ 1773, 0,
+ 1818, 0,
+ 1823, 0,
+ 1878, 0,
+ 1883, 0,
+ 11678, 11683, 11688, 0,
+ 11693, 11803, 0,
+ 11698, 0,
+ 11703, 0,
+ 11708, 0,
+ 11713, 11798, 0,
+ 11718, 0,
+ 11723, 0,
+ 11608, 11728, 0,
+ 11733, 0,
+ 11738, 11808, 0,
+ 11743, 0,
+ 11748, 0,
+ 11753, 0,
+ 11758, 0,
+ 11763, 0,
+ 11768, 11813, 0,
+ 11773, 0,
+ 11778, 0,
+ 11783, 0,
+ 11658, 11663, 11788, 0,
+ 11793, 0,
+ 11613, 0,
+ 15105, 0,
+ 15109, 15113, 0,
+ 15117, 15121, 0,
+ 15125, 15129, 0,
+ 15133, 15137, 0,
+ 12307, 12312, 12317, 12322, 12327, 12332, 12337, 12342, 12347, 12352, 12357, 12362, 12367, 12372, 12377, 12382, 12387, 12392, 12413, 12418, 12423, 12428, 12433, 12919, 12924, 12929, 12934, 12939, 12944, 13174, 13179, 13184, 13189, 13194, 13534, 13539, 15141, 15145, 15149, 15153, 0,
+ 14732, 14739, 1958, 1968, 14007, 14002, 1953, 15157, 15161, 0,
+ 14468, 14684, 12448, 12453, 12458, 12463, 12949, 12954, 12959, 12964, 12969, 12974, 13199, 13204, 13209, 13214, 13219, 13544, 13549, 12438, 12443, 15165, 15169, 15173, 15177, 0,
+ 15181, 15185, 0,
+ 14012, 14018, 14024, 14030, 14036, 14042, 14048, 14054, 14474, 14480, 14486, 14492, 14498, 14504, 13229, 13234, 13239, 13244, 13559, 13554, 12468, 12473, 12478, 12483, 12488, 12493, 12979, 12984, 12989, 12994, 12999, 13004, 13224, 15189, 15193, 15197, 15201, 0,
+ 12498, 12503, 12508, 12513, 13009, 13014, 13019, 13024, 13029, 13034, 13249, 13564, 13569, 15205, 15209, 15213, 15217, 0,
+ 14808, 14660, 14060, 14066, 14510, 14516, 14522, 12518, 12523, 13254, 13259, 13707, 13712, 13847, 13852, 15221, 15225, 15229, 15233, 0,
+ 14072, 14078, 14666, 13264, 13269, 13697, 13702, 13842, 13837, 12528, 12533, 15237, 15241, 15245, 15249, 0,
+ 12538, 12543, 12548, 13274, 13279, 13717, 13722, 13857, 13862, 15253, 15257, 15261, 15265, 0,
+ 15269, 15273, 0,
+ 12868, 15277, 15281, 0,
+ 14760, 12873, 15285, 15289, 0,
+ 15293, 15297, 0,
+ 14084, 14090, 14096, 14102, 14108, 14114, 14120, 14126, 14528, 14708, 13677, 13682, 13772, 13817, 13822, 13912, 13947, 13962, 13967, 13972, 12553, 12558, 12563, 12568, 13284, 13289, 13294, 13299, 13574, 13579, 15301, 15305, 15309, 15313, 0,
+ 14150, 14156, 14162, 14168, 14174, 14180, 14186, 14540, 13767, 13827, 13832, 13887, 13892, 13897, 13902, 13907, 13927, 13932, 13937, 13942, 13952, 13977, 13982, 13987, 13584, 13589, 13687, 13692, 13747, 13752, 13757, 13762, 15317, 15321, 15325, 15329, 0,
+ 14787, 14753, 14781, 14138, 14132, 14144, 14534, 14702, 14720, 12573, 12578, 13304, 13309, 13314, 13727, 13732, 13777, 13872, 13917, 13867, 15333, 15337, 15341, 15345, 0,
+ 14192, 14198, 14204, 14546, 13319, 13324, 13329, 13334, 13737, 13742, 13782, 13877, 13882, 13922, 12583, 12588, 12593, 12598, 15349, 15353, 15357, 15361, 0,
+ 14210, 14216, 14222, 14228, 13647, 13652, 13787, 13792, 13992, 13957, 12603, 12608, 13339, 15365, 15369, 15373, 15377, 0,
+ 12613, 13344, 13997, 15381, 15385, 15389, 15393, 0,
+ 14767, 14696, 14234, 14240, 14246, 14252, 14612, 12618, 12623, 13349, 13354, 13657, 13662, 13797, 13802, 15397, 15401, 15405, 15409, 0,
+ 14258, 14264, 14270, 13359, 13364, 13667, 13672, 13812, 13807, 12628, 12633, 15413, 15417, 15421, 15425, 0,
+ 13629, 13635, 13641, 15040, 15060, 15070, 15080, 15090, 15100, 0,
+ 14276, 14282, 14678, 12653, 12658, 12663, 13039, 13044, 13369, 13374, 13379, 13384, 12638, 12643, 12648, 15429, 15433, 15437, 15441, 0,
+ 14600, 14726, 14294, 14288, 14588, 12668, 12673, 12678, 12683, 13049, 13054, 13389, 13394, 15445, 15449, 15453, 15457, 0,
+ 14618, 14642, 14690, 12703, 12708, 12713, 12718, 12723, 13059, 13064, 13069, 13074, 13079, 13399, 13404, 13409, 13414, 13419, 13594, 13599, 12688, 12693, 12698, 15461, 15465, 15469, 15473, 0,
+ 14648, 14300, 14306, 14312, 14318, 14324, 14330, 14336, 14342, 14348, 14552, 14558, 14606, 14636, 12728, 12733, 12738, 12743, 12748, 12753, 13084, 13089, 13094, 13424, 13429, 13434, 13439, 13444, 13604, 15573, 15578, 15583, 15588, 15593, 15598, 15603, 15608, 15477, 15481, 15485, 15489, 0,
+ 14746, 14354, 14360, 14366, 14372, 14378, 14384, 14390, 14396, 14582, 14630, 14672, 12758, 12763, 12768, 12773, 12778, 12783, 13099, 13104, 13449, 13454, 13459, 13464, 15493, 15497, 15501, 15505, 0,
+ 14414, 14420, 14426, 14432, 14438, 14444, 14450, 14594, 14624, 14654, 14714, 13134, 13469, 13474, 13479, 13484, 13489, 13609, 13614, 12788, 12793, 12798, 12803, 12808, 12813, 13109, 13114, 13119, 13124, 13129, 15509, 15513, 15517, 15521, 0,
+ 14402, 14408, 12823, 12828, 12833, 13494, 13504, 13499, 12818, 15525, 15529, 15533, 15537, 0,
+ 14774, 1963, 15541, 15545, 0,
+ 12878, 13139, 12299, 12303, 15549, 15553, 0,
+ 14456, 14462, 14564, 14570, 14576, 12858, 12863, 13144, 13149, 13154, 13159, 13164, 13169, 13509, 13514, 13519, 13524, 13529, 13619, 13624, 1973, 12838, 12843, 12848, 12853, 15557, 15561, 15565, 15569, 0,
+ 11823, 11827, 0,
+ 12255, 0,
+ 11911, 11915, 11919, 11923, 0,
+ 11879, 11883, 11887, 11891, 0,
+ 11831, 11835, 11839, 11843, 0,
+ 11847, 11851, 11855, 11859, 0,
+ 11895, 11899, 11903, 11907, 0,
+ 11863, 11867, 11871, 11875, 0,
+ 11975, 11979, 11983, 11987, 0,
+ 11959, 11963, 11967, 11971, 0,
+ 11991, 11995, 11999, 12003, 0,
+ 12007, 12011, 12015, 12019, 0,
+ 12047, 12051, 0,
+ 12031, 12035, 0,
+ 12023, 12027, 0,
+ 12039, 12043, 0,
+ 12063, 12067, 0,
+ 12055, 12059, 0,
+ 11927, 11931, 11935, 11939, 0,
+ 11943, 11947, 11951, 11955, 0,
+ 12071, 12075, 12079, 12083, 0,
+ 12215, 12219, 12223, 12227, 0,
+ 12087, 12091, 12095, 12099, 0,
+ 12119, 12123, 12127, 12131, 0,
+ 12103, 12107, 12111, 12115, 0,
+ 12135, 12139, 0,
+ 12143, 12147, 12151, 12155, 0,
+ 12183, 12187, 12191, 12195, 0,
+ 12159, 12163, 0,
+ 2003, 12167, 12171, 12175, 12179, 0,
+ 12267, 12271, 0,
+ 12239, 12243, 0,
+ 12231, 12235, 0,
+ 12247, 12251, 0,
+ 12275, 12279, 0,
+ 12259, 12263, 0,
+ 12397, 12401, 12405, 12409, 0,
+ 12283, 12287, 12291, 12295, 0,
+ 2008, 12199, 12203, 0,
+ 12207, 12211, 0,
+ 1998, 0,
+ 2028, 0,
+ 2033, 0,
+ 2038, 0,
+ 2043, 0,
+ 2048, 0,
+ 2053, 0,
+ 2013, 0,
+ 2058, 0,
+ 2063, 0,
+ 2018, 0,
+ 2023, 0,
+ 2078, 0,
+ 2083, 0,
+ 2088, 0,
+ 2068, 2073, 0,
+ 2103, 0,
+ 2108, 0,
+ 2113, 0,
+ 2118, 0,
+ 2093, 0,
+ 2098, 0,
+ 2138, 0,
+ 2143, 0,
+ 2123, 2128, 2133, 0,
+ 2148, 0,
+ 2153, 2163, 0,
+ 2158, 0,
+ 2168, 0,
+ 2173, 0,
+ 2178, 2183, 2188, 0,
+ 2193, 0,
+ 2198, 2208, 0,
+ 2203, 0,
+ 2213, 2218, 2228, 0,
+ 2223, 0,
+ 2282, 0,
+ 2257, 0,
+ 2262, 0,
+ 2267, 0,
+ 2272, 0,
+ 2277, 0,
+ 2287, 2292, 2317, 0,
+ 2347, 0,
+ 2322, 0,
+ 2327, 0,
+ 2332, 0,
+ 2337, 0,
+ 2342, 0,
+ 2297, 0,
+ 2307, 0,
+ 2352, 0,
+ 2637, 0,
+ 2642, 0,
+ 2817, 0,
+ 2822, 0,
+ 2877, 0,
+ 2882, 0,
+ 3197, 3247, 0,
+ 3202, 3252, 0,
+ 3327, 0,
+ 3332, 0,
+ 3417, 0,
+ 3422, 0,
+ 3597, 3607, 3617, 4150, 0,
+ 3602, 3612, 3622, 4155, 0,
+ 4160, 0,
+ 4165, 0,
+ 4170, 0,
+ 4175, 0,
+ 4180, 0,
+ 4185, 0,
+ 3637, 3647, 3657, 4190, 0,
+ 3642, 3652, 3662, 4195, 0,
+ 4200, 0,
+ 4205, 0,
+ 4210, 0,
+ 4215, 0,
+ 4220, 0,
+ 4225, 0,
+ 3677, 3687, 0,
+ 3682, 3692, 0,
+ 3707, 3717, 0,
+ 3712, 3722, 0,
+ 3737, 3747, 3757, 4230, 0,
+ 3742, 3752, 3762, 4235, 0,
+ 4240, 0,
+ 4245, 0,
+ 4250, 0,
+ 4255, 0,
+ 4260, 0,
+ 4265, 0,
+ 3777, 3787, 3797, 4270, 0,
+ 3782, 3792, 3802, 4275, 0,
+ 4280, 0,
+ 4285, 0,
+ 4290, 0,
+ 4295, 0,
+ 4300, 0,
+ 4305, 0,
+ 3817, 3827, 3837, 0,
+ 3822, 3832, 3842, 0,
+ 3857, 3867, 3877, 0,
+ 3862, 3872, 3882, 0,
+ 3897, 3907, 0,
+ 3902, 3912, 0,
+ 3927, 3937, 0,
+ 3932, 3942, 0,
+ 3957, 3967, 3977, 0,
+ 3962, 3972, 3982, 0,
+ 3992, 3997, 4002, 0,
+ 4017, 4027, 4037, 4310, 0,
+ 4022, 4032, 4042, 4315, 0,
+ 4320, 0,
+ 4325, 0,
+ 4330, 0,
+ 4335, 0,
+ 4340, 0,
+ 4345, 0,
+ 4057, 4067, 4077, 4350, 0,
+ 4062, 4072, 4082, 4355, 0,
+ 4360, 0,
+ 4365, 0,
+ 4370, 0,
+ 4375, 0,
+ 4380, 0,
+ 4385, 0,
+ 4400, 0,
+ 4473, 0,
+ 4675, 0,
+ 4420, 0,
+ 4521, 4526, 4531, 0,
+ 4493, 0,
+ 4695, 0,
+ 4584, 4589, 4594, 0,
+ 5391, 0,
+ 5396, 0,
+ 5401, 0,
+ 5406, 0,
+ 5416, 0,
+ 5411, 0,
+ 5421, 0,
+ 5426, 0,
+ 5431, 0,
+ 5436, 0,
+ 5441, 0,
+ 5468, 0,
+ 5473, 0,
+ 5478, 0,
+ 5483, 0,
+ 5498, 0,
+ 5493, 0,
+ 5513, 0,
+ 5518, 0,
+ 5523, 0,
+ 5528, 0,
+ 5533, 0,
+ 5538, 0,
+ 5543, 0,
+ 5548, 0,
+ 5593, 0,
+ 5598, 0,
+ 5553, 0,
+ 5558, 0,
+ 5563, 0,
+ 5568, 0,
+ 5603, 0,
+ 5608, 0,
+ 5573, 0,
+ 5578, 0,
+ 5583, 0,
+ 5588, 0,
+ 5613, 0,
+ 5618, 0,
+ 5623, 0,
+ 5628, 0,
+ 7351, 0,
+ 7226, 0,
+ 7231, 0,
+ 7236, 0,
+ 7241, 0,
+ 7246, 0,
+ 7251, 0,
+ 7256, 0,
+ 7261, 0,
+ 7266, 0,
+ 7271, 0,
+ 7276, 0,
+ 7281, 0,
+ 7286, 0,
+ 7291, 0,
+ 7296, 0,
+ 7301, 7306, 0,
+ 7311, 7316, 0,
+ 7321, 7326, 0,
+ 7331, 7336, 0,
+ 7341, 7346, 0,
+ 7366, 0,
+ 7496, 0,
+ 7371, 0,
+ 7376, 0,
+ 7381, 0,
+ 7386, 0,
+ 7391, 0,
+ 7396, 0,
+ 7401, 0,
+ 7406, 0,
+ 7411, 0,
+ 7416, 0,
+ 7421, 0,
+ 7426, 0,
+ 7431, 0,
+ 7436, 0,
+ 7441, 0,
+ 7446, 7451, 0,
+ 7456, 7461, 0,
+ 7466, 7471, 0,
+ 7476, 7481, 0,
+ 7486, 7491, 0,
+ 7501, 0,
+ 7506, 0,
+ 7511, 0,
+ 7516, 0,
+ 7521, 0,
+ 11668, 11673, 0,
+
+};
+
+static const Q_UINT16 li_00[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 16, 18, 20, 0,
+ 0, 22, 39, 43, 49, 56, 74, 76,
+ 84, 92, 108, 110, 116, 123, 127, 137,
+ 154, 0, 157, 166, 174, 182, 202, 205,
+ 212, 215, 225, 0, 0, 0, 0, 0,
+ 0, 232, 249, 253, 259, 266, 284, 286,
+ 294, 303, 318, 321, 327, 334, 338, 348,
+ 365, 0, 368, 377, 385, 394, 414, 417,
+ 425, 428, 439, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 446, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 450, 0, 455, 457, 459, 462,
+ 0, 0, 464, 0, 0, 0, 0, 469,
+ 0, 0, 0, 0, 471, 476, 480, 0,
+ 482, 0, 0, 0, 484, 0, 0, 0,
+ 0, 0, 489, 0, 494, 496, 498, 501,
+ 0, 0, 503, 0, 0, 0, 0, 508,
+ 0, 0, 0, 0, 510, 515, 519, 0,
+ 521, 0, 0, 0, 523, 0, 0, 0,
+};
+
+static const Q_UINT16 li_01[] = {
+ 0, 0, 528, 533, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 538, 541, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 544, 547, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 550, 552, 0, 0, 0, 0,
+ 554, 556, 0, 0, 0, 0, 0, 0,
+ 558, 560, 562, 564, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 566,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 568, 574, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 580,
+ 586, 0, 0, 0, 0, 0, 0, 592,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 594, 596, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_02[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 598, 600,
+ 602, 604, 0, 0, 0, 0, 606, 608,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 610, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_03[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 612, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 614, 0, 0, 0, 622, 0, 627,
+ 0, 633, 0, 0, 0, 0, 0, 641,
+ 0, 646, 0, 0, 0, 648, 0, 0,
+ 0, 655, 0, 0, 661, 0, 663, 0,
+ 0, 665, 0, 0, 0, 674, 0, 679,
+ 0, 686, 0, 0, 0, 0, 0, 695,
+ 0, 700, 0, 0, 0, 703, 0, 0,
+ 0, 712, 719, 723, 0, 0, 727, 0,
+ 0, 0, 729, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_04[] = {
+ 0, 0, 0, 0, 0, 0, 732, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 734, 0, 0, 737, 0, 739, 743, 746,
+ 748, 0, 753, 0, 0, 0, 755, 0,
+ 0, 0, 0, 757, 0, 0, 0, 762,
+ 0, 0, 0, 764, 0, 766, 0, 0,
+ 768, 0, 0, 771, 0, 773, 777, 780,
+ 782, 0, 787, 0, 0, 0, 789, 0,
+ 0, 0, 0, 791, 0, 0, 0, 796,
+ 0, 0, 0, 798, 0, 800, 0, 0,
+ 0, 0, 0, 0, 0, 0, 802, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 804, 806, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 808, 810, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 812, 814, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_05[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 816, 820, 823, 825, 827, 829, 832, 0,
+ 834, 836, 839, 841, 844, 0, 846, 0,
+ 848, 850, 0, 852, 854, 0, 857, 859,
+ 861, 863, 867, 0, 0, 0, 0, 0,
+ 0, 0, 869, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_06[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 871, 873, 876, 879, 882, 885, 926,
+ 936, 962, 965, 1003, 1021, 1041, 1057, 1071,
+ 1074, 1078, 1083, 1086, 1121, 1158, 1183, 1206,
+ 1224, 1232, 1252, 0, 0, 0, 0, 0,
+ 1268, 1278, 1298, 1316, 1344, 1386, 1415, 1450,
+ 1464, 1469, 1476, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1506, 0, 0, 0, 0, 0, 1509,
+ 0, 1511, 1516, 1521, 0, 0, 1526, 1531,
+ 1536, 0, 0, 1541, 1546, 0, 1551, 1556,
+ 1561, 0, 0, 0, 1564, 1567, 1570, 0,
+ 0, 1573, 0, 0, 0, 0, 0, 0,
+ 1576, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1579, 0, 1584, 0,
+ 0, 1589, 0, 0, 0, 1594, 0, 1599,
+ 0, 1604, 0, 1609, 0, 0, 0, 0,
+ 0, 0, 1614, 1617, 0, 0, 1622, 0,
+ 1627, 1630, 0, 0, 0, 1636, 1639, 1642,
+ 1645, 1648, 0, 1651, 1654, 0, 0, 0,
+ 1659, 0, 1664, 1668, 0, 1671, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_07[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_09[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1673, 1675, 1677,
+ 0, 0, 0, 0, 1679, 0, 0, 0,
+ 0, 1681, 1683, 0, 0, 0, 0, 0,
+ 1685, 0, 0, 1687, 0, 0, 0, 1689,
+ 1691, 0, 0, 1693, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1695, 1697, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1699,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1701,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_0A[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1704, 1706,
+ 0, 0, 0, 0, 1708, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1710, 0, 0, 0, 0,
+ 0, 0, 1712, 0, 0, 0, 0, 0,
+ 1714, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_0B[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1716, 1718, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1720,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1724, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1726, 1729,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_0C[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1733,
+ 0, 0, 0, 0, 0, 0, 1735, 0,
+ 0, 0, 1739, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_0D[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1741, 1744,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1746, 0, 0, 1750, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_0F[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1752, 0, 1754, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1756, 0, 0, 0,
+ 0, 1758, 0, 0, 0, 0, 1760, 0,
+ 0, 0, 0, 1762, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1764, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1768, 0, 1770, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1772, 0, 0, 0,
+ 0, 1774, 0, 0, 0, 0, 1776, 0,
+ 0, 0, 0, 1778, 0, 0, 0, 0,
+ 0, 0, 1780, 1782, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_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, 1784, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_1E[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 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, 1788,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1790, 1792, 0, 0, 0, 0,
+ 0, 0, 1794, 1796, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1798, 1801, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1804, 1806, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1808, 1810, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_1F[] = {
+ 1812, 1817, 1822, 1824, 1826, 1828, 1830, 1832,
+ 1834, 1839, 1844, 1846, 1848, 1850, 1852, 1854,
+ 1856, 1859, 0, 0, 0, 0, 0, 0,
+ 1862, 1865, 0, 0, 0, 0, 0, 0,
+ 1868, 1873, 1878, 1880, 1882, 1884, 1886, 1888,
+ 1890, 1895, 1900, 1902, 1904, 1906, 1908, 1910,
+ 1912, 1916, 0, 0, 0, 0, 0, 0,
+ 1920, 1924, 0, 0, 0, 0, 0, 0,
+ 1928, 1931, 0, 0, 0, 0, 0, 0,
+ 1934, 1937, 0, 0, 0, 0, 0, 0,
+ 1940, 1944, 0, 0, 0, 0, 0, 0,
+ 0, 1948, 0, 0, 0, 0, 0, 0,
+ 1952, 1957, 1962, 1964, 1966, 1968, 1970, 1972,
+ 1974, 1979, 1984, 1986, 1988, 1990, 1992, 1994,
+ 1996, 0, 0, 0, 1998, 0, 0, 0,
+ 0, 0, 0, 0, 2000, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2002, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2004,
+ 0, 0, 0, 0, 0, 0, 2008, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2010, 0,
+ 0, 0, 0, 0, 0, 0, 2012, 0,
+};
+
+static const Q_UINT16 li_21[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2016, 0, 2018, 0, 2020, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2022, 0, 2024, 0, 2026, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 li_22[] = {
+ 0, 0, 0, 2028, 0, 0, 0, 0,
+ 2030, 0, 0, 2032, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2034, 0, 2036, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2038, 0, 0, 0,
+ 0, 0, 0, 2040, 0, 2042, 0, 0,
+ 2044, 0, 0, 0, 0, 2046, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2048, 0, 0, 2050, 2052, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2054, 2056, 0, 0, 2058, 2060,
+ 0, 0, 2062, 2064, 2066, 2068, 0, 0,
+ 0, 0, 2070, 2072, 0, 0, 2074, 2076,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2078, 2080, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2082, 0, 0, 0, 0, 0,
+ 2084, 2086, 0, 2088, 0, 0, 0, 0,
+ 0, 0, 2090, 2092, 2094, 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,
+};
+
+static const Q_UINT16 li_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, 2098, 0,
+ 0, 0, 0, 2100, 0, 2102, 0, 2104,
+ 0, 2106, 0, 2108, 0, 2110, 0, 2112,
+ 0, 2114, 0, 2116, 0, 2118, 0, 2120,
+ 0, 2122, 0, 0, 2124, 0, 2126, 0,
+ 2128, 0, 0, 0, 0, 0, 0, 2130,
+ 0, 0, 2133, 0, 0, 2136, 0, 0,
+ 2139, 0, 0, 2142, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2145, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2147, 0,
+ 0, 0, 0, 2149, 0, 2151, 0, 2153,
+ 0, 2155, 0, 2157, 0, 2159, 0, 2161,
+ 0, 2163, 0, 2165, 0, 2167, 0, 2169,
+ 0, 2171, 0, 0, 2173, 0, 2175, 0,
+ 2177, 0, 0, 0, 0, 0, 0, 2179,
+ 0, 0, 2182, 0, 0, 2185, 0, 0,
+ 2188, 0, 0, 2191, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2194,
+ 2196, 2198, 2200, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2202, 0, 0,
+};
+
+static const Q_UINT16 li_FB[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2204, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 * const ligature_info[256] = {
+ li_00, li_01, li_02, li_03, li_04, li_05, li_06, li_07,
+ li_07, li_09, li_0A, li_0B, li_0C, li_0D, li_07, li_0F,
+ li_10, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_1E, li_1F,
+ li_07, li_21, li_22, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_30, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_07, li_07, li_07, li_07, li_07,
+ li_07, li_07, li_07, li_FB, li_07, li_07, li_07, li_07,
+};
+// 16188 bytes
+
+static const Q_UINT8 dir_00[] = {
+ 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,
+};
+
+static const Q_UINT8 dir_01[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_02[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 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,
+};
+
+static const Q_UINT8 dir_03[] = {
+ 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, 0,
+ 17, 17, 17, 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, 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_04[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 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,
+};
+
+static const Q_UINT8 dir_05[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 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,
+};
+
+static const Q_UINT8 dir_06[] = {
+ 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, 77, 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, 0, 0,
+ 17, 13, 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, 13, 17, 17,
+ 17, 17, 17, 17, 17, 17, 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,
+};
+
+static const Q_UINT8 dir_07[] = {
+ 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, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_09[] = {
+ 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,
+};
+
+static const Q_UINT8 dir_0A[] = {
+ 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,
+};
+
+static const Q_UINT8 dir_0B[] = {
+ 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,
+};
+
+static const Q_UINT8 dir_0C[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 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,
+};
+
+static const Q_UINT8 dir_0D[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 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,
+};
+
+static const Q_UINT8 dir_0E[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 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,
+};
+
+static const Q_UINT8 dir_0F[] = {
+ 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,
+};
+
+static const Q_UINT8 dir_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, 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,
+};
+
+static const Q_UINT8 dir_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, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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,
+};
+
+static const Q_UINT8 dir_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, 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,
+};
+
+static const Q_UINT8 dir_18[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 18, 18, 18, 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,
+};
+
+static const Q_UINT8 dir_1F[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 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,
+};
+
+static const Q_UINT8 dir_20[] = {
+ 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 18, 18, 18, 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, 0,
+ 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, 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_21[] = {
+ 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,
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_22[] = {
+ 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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_23[] = {
+ 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, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_24[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_25[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 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,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 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,
+};
+
+static const Q_UINT8 dir_26[] = {
+ 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, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_27[] = {
+ 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,
+ 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, 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,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_28[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+};
+
+static const Q_UINT8 dir_2E[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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,
+};
+
+static const Q_UINT8 dir_2F[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 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,
+};
+
+static const Q_UINT8 dir_30[] = {
+ 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, 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, 17, 17, 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, 10, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_A4[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 0, 0, 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, 0, 10, 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,
+};
+
+static const Q_UINT8 dir_FB[] = {
+ 0, 0, 0, 0, 0, 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,
+};
+
+static const Q_UINT8 dir_FC[] = {
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+};
+
+static const Q_UINT8 dir_FD[] = {
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 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, 0, 0, 0, 0,
+};
+
+static const Q_UINT8 dir_FE[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 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, 0, 0, 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, 0, 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,
+};
+
+static const Q_UINT8 dir_FF[] = {
+ 0, 10, 10, 4, 4, 4, 10, 10,
+ 10, 10, 10, 4, 6, 4, 6, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 6, 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, 0, 0, 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,
+ 0, 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,
+ 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,
+};
+
+static const Q_UINT8 * const direction_info[256] = {
+ dir_00, dir_01, dir_02, dir_03, dir_04, dir_05, dir_06, dir_07,
+ dir_01, dir_09, dir_0A, dir_0B, dir_0C, dir_0D, dir_0E, dir_0F,
+ dir_10, dir_01, dir_01, dir_01, dir_01, dir_01, dir_16, dir_17,
+ dir_18, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_1F,
+ dir_20, dir_21, dir_22, dir_23, dir_24, dir_25, dir_26, dir_27,
+ dir_28, dir_01, dir_01, dir_01, dir_01, dir_01, dir_2E, dir_2F,
+ dir_30, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_A4, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01, dir_01,
+ dir_01, dir_01, dir_01, dir_FB, dir_FC, dir_FD, dir_FE, dir_FF,
+};
+// 26940 bytes
+
+#endif
+
+// END OF GENERATED DATA
+
+// This is generated too. Script?
+
+#ifndef QT_NO_UNICODETABLES
+
+static const Q_UINT16 case_0 [] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 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, 0x0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0x0, 0, 0,
+ 0, 0, 0x0, 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, 0x0,
+ 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,
+};
+
+static const Q_UINT16 case_1 [] = {
+ 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,
+ 0x0, 0x13a, 0x139, 0x13c, 0x13b, 0x13e, 0x13d, 0x140,
+ 0x13f, 0x142, 0x141, 0x144, 0x143, 0x146, 0x145, 0x148,
+ 0x147, 0x0, 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,
+ 0x0, 0x253, 0x183, 0x182, 0x185, 0x184, 0x254, 0x188,
+ 0x187, 0x256, 0x257, 0x18c, 0x18b, 0x0, 0x1dd, 0x259,
+ 0x25b, 0x192, 0x191, 0x260, 0x263, 0x3d9, 0x269, 0x268,
+ 0x199, 0x198, 0x51, 0x0, 0x26f, 0x272, 0x0, 0x275,
+ 0x1a1, 0x1a0, 0x1a3, 0x1a2, 0x1a5, 0x1a4, 0x280, 0x1a8,
+ 0x1a7, 0x283, 0, 0x0, 0x1ad, 0x1ac, 0x288, 0x1b0,
+ 0x1af, 0x28a, 0x28b, 0x1b4, 0x1b3, 0x1b6, 0x1b5, 0x292,
+ 0x1b9, 0x1b8, 0x0, 0, 0x1bd, 0x1bc, 0, 0,
+ 0, 0, 0, 0, 0x1c6, 0, 0x1c4, 0x1c9,
+ 0, 0x1c7, 0x1cc, 0, 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,
+ 0x0, 0x1f3, 0, 0x1f1, 0x1f5, 0x1f4, 0, 0,
+ 0, 0, 0x1fb, 0x1fa, 0x1fd, 0x1fc, 0x1ff, 0x1fe,
+};
+
+static const Q_UINT16 case_2 [] = {
+ 0x201, 0x200, 0x203, 0x202, 0x205, 0x204, 0x207, 0x206,
+ 0x209, 0x208, 0x20b, 0x20a, 0x20d, 0x20c, 0x20f, 0x20e,
+ 0x211, 0x210, 0x213, 0x212, 0x215, 0x214, 0x217, 0x216,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x0, 0x0, 0x0, 0x181, 0x186, 0x0, 0x189, 0x18a,
+ 0x0, 0x18f, 0x0, 0x190, 0x0, 0x0, 0x0, 0x0,
+ 0x193, 0x0, 0x0, 0x194, 0x0, 0x0, 0x631, 0x579,
+ 0x197, 0x196, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19c,
+ 0x0, 0x0, 0x19d, 0x0, 0x0, 0x19f, 0x0, 0x0,
+ 0x0, 0x0, 0x7e1, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x1a6, 0x0, 0x0, 0x1a9, 0x0, 0x0, 0x0, 0x0,
+ 0x1ae, 0x0, 0x1b1, 0x1b2, 0x0, 0xa21, 0x971, 0x0,
+ 0x0, 0x0, 0x1b7, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_3 [] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 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,
+ 0x0, 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,
+ 0x0, 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, 0x0, 0x0, 0x0, 0x3a6, 0x3a0, 0,
+ 0, 0, 0x0, 0, 0x0, 0, 0x0, 0,
+ 0x0, 0, 0x3e3, 0x3e2, 0x3e5, 0x3e4, 0x3e7, 0x3e6,
+ 0x3e9, 0x3e8, 0x3eb, 0x3ea, 0x3ed, 0x3ec, 0x3ef, 0x3ee,
+ 0x39a, 0x3a1, 0x3a3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_4 [] = {
+ 0, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457,
+ 0x458, 0x459, 0x45a, 0x45b, 0x45c, 0, 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,
+ 0, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407,
+ 0x408, 0x409, 0x40a, 0x40b, 0x40c, 0, 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, 0, 0, 0, 0, 0, 0,
+ 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, 0, 0, 0x4c8,
+ 0x4c7, 0, 0, 0x4cc, 0x4cb, 0, 0, 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, 0, 0, 0x4ef, 0x4ee,
+ 0x4f1, 0x4f0, 0x4f3, 0x4f2, 0x4f5, 0x4f4, 0, 0,
+ 0x4f9, 0x4f8, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_5 [] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 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, 0x0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_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,
+ 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7,
+ 0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df,
+ 0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7,
+ 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef,
+ 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_1e [] = {
+ 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, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 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,
+};
+
+static const Q_UINT16 case_1f [] = {
+ 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,
+ 0x0, 0x1f59, 0x0, 0x1f5b, 0x0, 0x1f5d, 0x0, 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, 0x0, 0x1fbc, 0x0, 0, 0x0, 0x0,
+ 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x1fb3, 0, 0x399, 0,
+ 0, 0, 0x0, 0x1fcc, 0x0, 0, 0x0, 0x0,
+ 0x1f72, 0x1f73, 0x1f74, 0x1f75, 0x1fc3, 0, 0, 0,
+ 0x1fd8, 0x1fd9, 0x0, 0x0, 0, 0, 0x0, 0x0,
+ 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0, 0, 0, 0,
+ 0x1fe8, 0x1fe9, 0x0, 0x0, 0x0, 0x1fec, 0x0, 0x0,
+ 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0, 0, 0,
+ 0, 0, 0x0, 0x1ffc, 0x0, 0, 0x0, 0x0,
+ 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x1ff3, 0, 0, 0,
+};
+
+static const Q_UINT16 case_20 [] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0x0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_21 [] = {
+ 0, 0, 0x0, 0, 0, 0, 0, 0x0,
+ 0, 0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0, 0x0, 0, 0,
+ 0x761, 0x0, 0x0, 0x0, 0x0, 0x0, 0, 0,
+ 0, 0, 0, 0, 0x0, 0, 0x0, 0,
+ 0x0, 0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0, 0x0, 0x0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_fb [] = {
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const Q_UINT16 case_ff [] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 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,
+};
+
+static const Q_UINT16 * const case_info[256] = {
+
+ case_0, case_1, case_2, case_3, case_4, case_5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ case_10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, case_1e, case_1f,
+ case_20, case_21, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, case_fb, 0, 0, 0, case_ff,
+};
+
+static const Q_INT8 num_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,
+ 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,
+};
+
+static const Q_INT8 num_6 [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -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,
+};
+
+static const Q_INT8 num_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, 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,
+};
+
+static const Q_INT8 num_b [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -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,
+};
+
+static const Q_INT8 num_d [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -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,
+};
+
+static const Q_INT8 num_e [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -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,
+};
+
+static const Q_INT8 num_f [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -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,
+};
+
+static const Q_INT8 num_20 [] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -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,
+};
+
+static const Q_INT8 num_ff [] = {
+ -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,
+};
+
+static const Q_INT8 * const decimal_info[256] = {
+ num_0, 0, 0, 0, 0, 0, num_6, 0,
+ 0, num_9, num_9, num_b, num_9, num_d, num_e, num_f,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ num_20, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, num_ff,
+};
+
+static const Q_UINT16 symmetricPairs[] = {
+ 0x0028, 0x0029, 0x0029, 0x0028, 0x003C, 0x003E, 0x003E, 0x003C,
+ 0x005B, 0x005D, 0x005D, 0x005B, 0x007B, 0x007D, 0x007D, 0x007B,
+ 0x2045, 0x2046, 0x2046, 0x2045, 0x207D, 0x207E, 0x207E, 0x207D,
+ 0x208D, 0x208E, 0x208E, 0x208D, 0x3008, 0x3009, 0x3009, 0x3008,
+ 0x300A, 0x300B, 0x300B, 0x300A, 0x300C, 0x300D, 0x300D, 0x300C,
+ 0x300E, 0x300F, 0x300F, 0x300E, 0x3010, 0x3011, 0x3011, 0x3010,
+ 0x3014, 0x3015, 0x3015, 0x3014, 0x3016, 0x3017, 0x3017, 0x3016,
+ 0x3018, 0x3019, 0x3019, 0x3018, 0x301A, 0x301B, 0x301B, 0x301A,
+ 0xFD3E, 0xFD3F, 0xFD3F, 0xFD3E, 0xFE59, 0xFE5A, 0xFE5A, 0xFE59,
+ 0xFE5B, 0xFE5C, 0xFE5C, 0xFE5B, 0xFE5D, 0xFE5E, 0xFE5E, 0xFE5D,
+ 0xFF08, 0xFF09, 0xFF09, 0xFF08, 0xFF3B, 0xFF3D, 0xFF3D, 0xFF3B,
+ 0xFF5B, 0xFF5D, 0xFF5D, 0xFF5B, 0xFF62, 0xFF63, 0xFF63, 0xFF62,
+};
+
+static int symmetricPairsSize =
+ sizeof(symmetricPairs)/sizeof(symmetricPairs[0]);
+
+/*
+ * ----------------------------------------------------------------------
+ * End of unicode tables
+ * ----------------------------------------------------------------------
+ */
+
+#endif
+
+
+static int ucstrcmp( const QString &as, const QString &bs )
+{
+ const QChar *a = as.unicode();
+ const QChar *b = bs.unicode();
+ if ( a == b )
+ return 0;
+ if ( a == 0 )
+ return 1;
+ if ( b == 0 )
+ return -1;
+ int l=QMIN(as.length(),bs.length());
+ while ( l-- && *a == *b )
+ a++,b++;
+ if ( l==-1 )
+ return ( as.length()-bs.length() );
+ return a->unicode() - b->unicode();
+}
+
+static int ucstrncmp( const QChar *a, const QChar *b, int l )
+{
+ while ( l-- && *a == *b )
+ a++,b++;
+ if ( l==-1 )
+ return 0;
+ return a->unicode() - b->unicode();
+}
+
+static int ucstrnicmp( const QChar *a, const QChar *b, int l )
+{
+ while ( l-- && a->lower() == b->lower() )
+ a++,b++;
+ if ( l==-1 )
+ return 0;
+ QChar al = a->lower();
+ QChar bl = b->lower();
+ return al.unicode() - bl.unicode();
+}
+
+// NOT REVISED
+/*! \class QCharRef qstring.h
+ \brief The QCharRef class is a helper class for QString.
+
+ It provides the ability to work on characters in a QString in a natural
+ fashion.
+
+ When you get an object of type QCharRef, you can assign to it, which
+ will operate on the string from which you got it. That is its whole
+ purpose in life. It becomes invalid once further modifications are
+ made to the string: If you want to keep it, copy it into a QChar.
+
+ Most of the QChar member functions also exist in QCharRef. However,
+ they are not explicitly documented here.
+
+ \sa QString::operator[]() QString::at() QChar
+*/
+
+/*! \class QChar qstring.h
+
+\brief The QChar class provides a light-weight Unicode character.
+
+Unicode characters are (so far) 16-bit entities without any markup or
+structure. This class represents such an entity. It is rather
+light-weight, so it can be used everywhere. Most compilers treat it
+approximately like "short int". (In a few years, it may be necessary
+to make QChar 32-bit, once more than 65536 Unicode code points have
+been defined and come into use.)
+
+QChar provides a full complement of testing/classification functions,
+conversion to and from other formats, from composed to decomposed
+unicode, and will try to compare and case-convert if you ask it to.
+
+The classification functions include functions like those in ctype.h,
+but operating on the full range of unicode characters. They all
+return TRUE if the character is a certain type of character, and FALSE
+otherwise.
+
+These functions are: isNull() (returns TRUE if the character is
+U+0000), isPrint() (TRUE if the character is any sort of printable
+character, including whitespace), isPunct() (any sort of punctation),
+isMark() (Unicode Marks), isLetter (letters), isNumber() (any sort of
+numeric characters), isLetterOrNumber(), and isDigit() (decimal digits).
+All of these are wrappers around category(), which returns the
+unicode-defined category of each character.
+
+QChar further provides direction(), which indicates the "natural"
+writing direction of this character, joining(), which indicates how
+this character joins with its neighbors (needed mostly for Arabic)
+and finally mirrored(), which indicates whether this character needs
+to be mirrored when it is printed in its unnatural writing
+direction.
+
+Composed Unicode characters (like &aring;) can be converted to
+decomposed Unicode ("a" followed by "ring above") using
+decomposition().
+
+In Unicode, comparison is not necessarily possible, and case
+conversion is at best very hard. Unicode, covering the "entire"
+globe, also includes a globe-sized collection of case and sorting
+problems. Qt tries, but not very hard: operator== and friends will do
+comparison based purely on the numeric Unicode value (code point) of
+the characters, and upper() and lower() will do case changes when the
+character has a well-defined upper/lower-case equivalent. There is no
+provision for locale-dependent case folding rules or comparison: These
+functions are meant to be fast, so they can be used unambiguously in
+data structures.
+
+The conversion functions include unicode() (to a scalar), latin1() (to
+scalar, but converts all non-Latin1 characters to 0), row() (gives the
+Unicode row), cell() (gives the unicode cell), digitValue() (gives the
+integer value of any of the numerous digit characters), and a host of
+constructors.
+
+\sa QString QCharRef \link unicode.html About Unicode \endlink
+*/
+
+/*! \enum QChar::Category
+
+This enum maps the Unicode character categories. The currently known
+categories are: <ul>
+
+<li> \c NoCategory - used when Qt is dazed and confused and cannot
+make sense of anything.
+
+<li> \c Mark_NonSpacing - (Mn) -
+
+<li> \c Mark_SpacingCombining - (Mc) -
+
+<li> \c Mark_Enclosing - (Me) -
+
+<li> \c Number_DecimalDigit - (Nd) -
+
+<li> \c Number_Letter - (Nl) -
+
+<li> \c Number_Other - (No) -
+
+<li> \c Separator_Space - (Zs) -
+
+<li> \c Separator_Line - (Zl) -
+
+<li> \c Separator_Paragraph - (Zp) -
+
+<li> \c Other_Control - (Cc) -
+
+<li> \c Other_Format - (Cf) -
+
+<li> \c Other_Surrogate - (Cs) -
+
+<li> \c Other_PrivateUse - (Co) -
+
+<li> \c Other_NotAssigned - (Cn) -
+
+<li> \c Letter_Uppercase - (Lu) -
+
+<li> \c Letter_Lowercase - (Ll) -
+
+<li> \c Letter_Titlecase - (Lt) -
+
+<li> \c Letter_Modifier - (Lm) -
+
+<li> \c Letter_Other - (Lo) -
+
+<li> \c Punctuation_Connector - (Pc) -
+
+<li> \c Punctuation_Dask - (Pd) -
+
+<li> \c Punctuation_Open - (Ps) -
+
+<li> \c Punctuation_Close - (Pe) -
+
+<li> \c Punctuation_InitialQuote - (Pi) -
+
+<li> \c Punctuation_FinalQuote - (Pf) -
+
+<li> \c Punctuation_Other - (Po) -
+
+<li> \c Symbol_Math - (Sm) -
+
+<li> \c Symbol_Currency - (Sc) -
+
+<li> \c Symbol_Modifier - (Sk) -
+
+<li> \c Symbol_Other - (So) -
+
+</ul>
+*/
+
+/*! \enum QChar::Direction
+
+ This enum type defines the Unicode direction attributes.
+ See <a href="http://www.unicode.org">the Unicode Standard</a>
+ for a description of the values.
+
+ In order to conform to C/C++ naming conventions "Dir" is
+ prepended to the codes used in The Unicode Standard.
+*/
+
+/*! \enum QChar::Decomposition
+
+ This enum type defines the Unicode decomposition attributes.
+ See <a href="http://www.unicode.org">the Unicode Standard</a>
+ for a description of the values.
+*/
+
+/*! \enum QChar::Joining
+
+ This enum type defines the Unicode decomposition attributes.
+ See <a href="http://www.unicode.org">the Unicode Standard</a>
+ for a description of the values.
+*/
+
+
+
+/*! \fn QChar::QChar()
+
+Constructs a null QChar (one that isNull()).
+*/
+
+
+/*! \fn QChar::QChar( char c )
+
+Constructs a QChar corresponding to ASCII/Latin1 character \a c.
+*/
+
+
+/*! \fn QChar::QChar( uchar c )
+
+Constructs a QChar corresponding to ASCII/Latin1 character \a c.
+*/
+
+
+/*! \fn QChar::QChar( uchar c, uchar r )
+
+Constructs a QChar for Unicode cell \a c in row \a r.
+*/
+
+
+/*! \fn QChar::QChar( const QChar& c )
+
+Constructs a copy of \a c. This is a deep copy, if such a
+light-weight object can be said to have deep copies.
+*/
+
+
+/*! \fn QChar::QChar( ushort rc )
+
+Constructs a QChar for the character with Unicode code point \a rc.
+*/
+
+
+/*! \fn QChar::QChar( short rc )
+
+Constructs a QChar for the character with Unicode code point \a rc.
+*/
+
+
+/*! \fn QChar::QChar( uint rc )
+
+Constructs a QChar for the character with Unicode code point \a rc.
+*/
+
+
+/*! \fn QChar::QChar( int rc )
+
+Constructs a QChar for the character with Unicode code point \a rc.
+*/
+
+
+/*! \fn bool QChar::networkOrdered ()
+
+ Returns TRUE if this character is in network byte order (MSB first),
+ and FALSE if it is not. This is a platform-dependent property, so
+ we strongly advise against using this function in portable code.
+*/
+
+
+/*!
+ \fn bool QChar::isNull() const
+ Returns TRUE if the characters is the unicode character 0x0000,
+ ie. ASCII NUL.
+*/
+
+/*!
+ \fn uchar QChar::cell () const
+ Returns the cell (least significant byte) of the Unicode character.
+*/
+/*!
+ \fn uchar QChar::row () const
+ Returns the row (most significant byte) of the Unicode character.
+*/
+/*!
+ \fn uchar& QChar::cell ()
+ Returns a reference to the cell (least significant byte) of the Unicode character.
+*/
+/*!
+ \fn uchar& QChar::row ()
+ Returns a reference to the row (most significant byte) of the Unicode character.
+*/
+
+/*!
+ Returns whether the character is a printable character. This is
+ any character not of category Cc or Cn. Note that this gives no indication
+ of whether the character is available in some font.
+*/
+bool QChar::isPrint() const
+{
+ Category c = category();
+ return !(c == Other_Control || c == Other_NotAssigned);
+}
+
+/*!
+ Returns whether the character is a separator
+ character (Separator_* categories).
+*/
+bool QChar::isSpace() const
+{
+ if( !row() )
+ if( cell() >= 9 && cell() <=13 ) return TRUE;
+ Category c = category();
+ return c >= Separator_Space && c <= Separator_Paragraph;
+}
+
+/*!
+ Returns whether the character is a mark (Mark_* categories).
+*/
+bool QChar::isMark() const
+{
+ Category c = category();
+ return c >= Mark_NonSpacing && c <= Mark_Enclosing;
+}
+
+/*!
+ Returns whether the character is punctuation (Punctuation_* categories).
+*/
+bool QChar::isPunct() const
+{
+ Category c = category();
+ return (c >= Punctuation_Connector && c <= Punctuation_Other);
+}
+
+/*!
+ Returns whether the character is a letter (Letter_* categories).
+*/
+bool QChar::isLetter() const
+{
+ Category c = category();
+ return (c >= Letter_Uppercase && c <= Letter_Other);
+}
+
+/*!
+ Returns whether the character is a number (of any sort - Number_* categories).
+
+ \sa isDigit()
+*/
+bool QChar::isNumber() const
+{
+ Category c = category();
+ return c >= Number_DecimalDigit && c <= Number_Other;
+}
+
+/*!
+ Returns whether the character is a letter or number (Letter_* or Number_* categories).
+*/
+bool QChar::isLetterOrNumber() const
+{
+ Category c = category();
+ return (c >= Letter_Uppercase && c <= Letter_Other)
+ || (c >= Number_DecimalDigit && c <= Number_Other);
+}
+
+
+/*!
+ Returns whether the character is a decimal digit (Number_DecimalDigit).
+ */
+bool QChar::isDigit() const
+{
+ return (category() == Number_DecimalDigit);
+}
+
+/*!
+ Returns the numeric value of the digit, or -1 if the character is not
+ a digit.
+*/
+int QChar::digitValue() const
+{
+#ifndef QT_NO_UNICODETABLES
+ const Q_INT8 *dec_row = decimal_info[row()];
+ if( !dec_row )
+ return -1;
+ return decimal_info[row()][cell()];
+#else
+ // ##### just latin1
+ if ( rw != 0 || cl < '0' || cl > '9' )
+ return -1;
+ else
+ return cl - '0';
+#endif
+}
+
+/*!
+ Returns the character category.
+
+ \sa Category
+*/
+QChar::Category QChar::category() const
+{
+#ifndef QT_NO_UNICODETABLES
+ return (Category)(unicode_info[row()][cell()]);
+#else
+// ### just ASCII
+ if ( rw == 0 ) {
+ if ( cl >= '0' && cl <='9' )
+ return Number_DecimalDigit;
+ if ( cl >= 'a' && cl <='z' )
+ return Letter_Lowercase;
+ if ( cl >= 'A' && cl <='Z' )
+ return Letter_Uppercase;
+ if ( cl == ' ' )
+ return Separator_Space;
+ if ( cl == '\n' )
+ return Separator_Line;
+ if ( cl < ' ' )
+ return Other_Control;
+ return Symbol_Other; //#######
+ }
+ return Letter_Uppercase; //#######
+#endif
+}
+
+/*!
+ Returns the characters directionality.
+
+ \sa Direction
+*/
+QChar::Direction QChar::direction() const
+{
+#ifndef QT_NO_UNICODETABLES
+ const Q_UINT8 *rowp = direction_info[row()];
+ if(!rowp) return QChar::DirL;
+ return (Direction) ( *(rowp+cell()) &0x1f );
+#else
+ return DirL;
+#endif
+}
+
+/*!
+ This function is not supported (it may change to use Unicode
+ character classes).
+
+ Returns information about the joining properties of the
+ character (needed for arabic).
+*/
+QChar::Joining QChar::joining() const
+{
+#ifndef QT_NO_UNICODETABLES
+ const Q_UINT8 *rowp = direction_info[row()];
+ if ( !rowp )
+ return QChar::OtherJoining;
+ return (Joining) ((*(rowp+cell()) >> 5) &0x3);
+#else
+ return OtherJoining;
+#endif
+}
+
+
+/*!
+ Returns whether the character is a mirrored character (one that
+ should be reversed if the text direction is reversed).
+*/
+bool QChar::mirrored() const
+{
+#ifndef QT_NO_UNICODETABLES
+ const Q_UINT8 *rowp = direction_info[row()];
+ if ( !rowp )
+ return FALSE;
+ return *(rowp+cell())>128;
+#else
+ return FALSE;
+#endif
+}
+
+/*!
+ Returns the mirrored char if this character is a mirrored char, the char
+ itself otherwise
+*/
+QChar QChar::mirroredChar() const
+{
+#ifndef QT_NO_UNICODETABLES
+ if(!mirrored()) return *this;
+
+ int i;
+ int c = unicode();
+ for (i = 0; i < symmetricPairsSize; i += 2) {
+ if (symmetricPairs[i] == c)
+ return symmetricPairs[i+1];
+ }
+ return 0;
+#else
+ return *this;
+#endif
+}
+
+/*!
+ Decomposes a character into its parts. Returns QString::null if
+ no decomposition exists.
+*/
+QString QChar::decomposition() const
+{
+#ifndef QT_NO_UNICODETABLES
+ const Q_UINT16 *r = decomposition_info[row()];
+ if(!r) return QString::null;
+
+ Q_UINT16 pos = r[cell()];
+ if(!pos) return QString::null;
+ pos+=2;
+
+ QString s;
+ Q_UINT16 c;
+ while((c = decomposition_map[pos++]) != 0) s += QChar(c);
+
+ return s;
+#else
+ return null;
+#endif
+}
+
+/*!
+ Returns the tag defining the composition of the character.
+ Returns QChar::Single if no decomposition exists.
+*/
+QChar::Decomposition QChar::decompositionTag() const
+{
+#ifndef QT_NO_UNICODETABLES
+ const Q_UINT16 *r = decomposition_info[row()];
+ if(!r) return QChar::Single;
+
+ Q_UINT16 pos = r[cell()];
+ if(!pos) return QChar::Single;
+
+ return (QChar::Decomposition) decomposition_map[pos];
+#else
+ return Single; // ########### FIX eg. just latin1
+#endif
+}
+
+/*!
+ Returns the lowercase equivalent if the character is uppercase,
+ or the character itself otherwise.
+*/
+QChar QChar::lower() const
+{
+#ifndef QT_NO_UNICODETABLES
+ if(category() != Letter_Uppercase) return *this;
+ Q_UINT16 lower = *(case_info[row()]+cell());
+ if(lower == 0) return *this;
+ return lower;
+#else
+ if (row())
+ return *this;
+ else
+ return QChar(tolower(latin1()));
+#endif
+}
+
+/*!
+ Returns the uppercase equivalent if the character is lowercase,
+ or the character itself otherwise.
+*/
+QChar QChar::upper() const
+{
+#ifndef QT_NO_UNICODETABLES
+ if(category() != Letter_Lowercase) return *this;
+ Q_UINT16 upper = *(case_info[row()]+cell());
+ if(upper == 0) return *this;
+ return upper;
+#else
+ if (row())
+ return *this;
+ else
+ return QChar(toupper(latin1()));
+#endif
+}
+
+/*!
+ \fn QChar::operator char() const
+
+ Returns the Latin1 character equivalent to the QChar,
+ or 0. This is mainly useful for non-internationalized software.
+
+ \sa unicode()
+*/
+
+/*!
+ \fn ushort QChar::unicode() const
+
+ Returns the numeric Unicode value equal to the QChar. Normally, you
+ should use QChar objects as they are equivalent, but for some low-level
+ tasks (eg. indexing into an array of Unicode information), this function
+ is useful.
+*/
+
+/*****************************************************************************
+ Documentation of QChar related functions
+ *****************************************************************************/
+
+/*!
+ \fn int operator==( QChar c1, QChar c2 )
+ \relates QChar
+
+ Returns TRUE if \a c1 and \a c2 are the same Unicode character.
+*/
+
+/*!
+ \fn int operator==( char ch, QChar c )
+ \relates QChar
+
+ Returns TRUE if \a c is the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator==( QChar c, char ch )
+ \relates QChar
+
+ Returns TRUE if \a c is the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator!=( QChar c1, QChar c2 )
+ \relates QChar
+
+ Returns TRUE if \a c1 and \a c2 are not the same Unicode character.
+*/
+
+/*!
+ \fn int operator!=( char ch, QChar c )
+ \relates QChar
+
+ Returns TRUE if \a c is not the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator!=( QChar c, char ch )
+ \relates QChar
+
+ Returns TRUE if \a c is not the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator<=( QChar c1, QChar c2 )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c1 is less than that
+ of \a c2, or they are the same Unicode character.
+*/
+
+/*!
+ \fn int operator<=( QChar c, char ch )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c is less than or
+ equal to that of the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator<=( char ch, QChar c )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of the ASCII/Latin1
+ character \a ch is less than or equal to that of \a c.
+*/
+
+/*!
+ \fn int operator>=( QChar c1, QChar c2 )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c1 is greater than that
+ of \a c2, or they are the same Unicode character.
+*/
+
+/*!
+ \fn int operator>=( QChar c, char ch )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c is greater than or
+ equal to that of the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator>=( char ch, QChar c )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of the ASCII/Latin1
+ character \a ch is greater than or equal to that of \a c.
+*/
+
+/*!
+ \fn int operator<( QChar c1, QChar c2 )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c1 is less than that
+ of \a c2.
+*/
+
+/*!
+ \fn int operator<( QChar c, char ch )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c is less than that
+ of the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator<( char ch, QChar c )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of the ASCII/Latin1
+ character \a ch is less than that of \a c.
+*/
+
+/*!
+ \fn int operator>( QChar c1, QChar c2 )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c1 is greater than
+ that of \a c2.
+*/
+
+/*!
+ \fn int operator>( QChar c, char ch )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of \a c is greater than
+ that of the ASCII/Latin1 character \a ch.
+*/
+
+/*!
+ \fn int operator>( char ch, QChar c )
+ \relates QChar
+
+ Returns TRUE if the numeric Unicode value of the ASCII/Latin1
+ character \a ch is greater than that of \a c.
+*/
+
+#ifndef QT_NO_UNICODETABLES
+
+// small class used internally in QString::Compose()
+class QLigature
+{
+public:
+ QLigature( QChar c );
+
+ Q_UINT16 first() { cur = ligatures; return cur ? *cur : 0; }
+ Q_UINT16 next() { return cur && *cur ? *(cur++) : 0; }
+ Q_UINT16 current() { return cur ? *cur : 0; }
+
+ int match(QString & str, unsigned int index);
+ QChar head();
+ QChar::Decomposition tag();
+
+private:
+ Q_UINT16 *ligatures;
+ Q_UINT16 *cur;
+};
+
+QLigature::QLigature( QChar c )
+{
+ const Q_UINT16 *r = ligature_info[c.row()];
+ if( !r )
+ ligatures = 0;
+ else
+ {
+ const Q_UINT16 pos = r[c.cell()];
+ ligatures = (Q_UINT16 *)&(ligature_map[pos]);
+ }
+ cur = ligatures;
+}
+
+QChar QLigature::head()
+{
+ if(current())
+ return QChar(decomposition_map[current()+1]);
+
+ return QChar::null;
+}
+
+QChar::Decomposition QLigature::tag()
+{
+ if(current())
+ return (QChar::Decomposition) decomposition_map[current()];
+
+ return QChar::Canonical;
+}
+
+int QLigature::match(QString & str, unsigned int index)
+{
+ unsigned int i=index;
+
+ if(!current()) return 0;
+
+ Q_UINT16 lig = current() + 2;
+ Q_UINT16 ch;
+
+ while ((i < str.length()) && (ch = decomposition_map[lig])) {
+ if (str[(int)i] != QChar(ch))
+ return 0;
+ i++; lig++;
+ }
+
+ if (!decomposition_map[lig])
+ {
+ return i-index;
+ }
+ return 0;
+}
+
+#endif
+
+// this function is just used in QString::compose()
+static inline bool format(QChar::Decomposition tag, QString & str,
+ int index, int len)
+{
+ unsigned int l = index + len;
+ unsigned int r = index;
+
+ bool left = FALSE, right = FALSE;
+
+ left = ((l < str.length()) &&
+ ((str[(int)l].joining() == QChar::Dual) ||
+ (str[(int)l].joining() == QChar::Right)));
+ if (r > 0) {
+ r--;
+ //printf("joining(right) = %d\n", str[(int)r].joining());
+ right = (str[(int)r].joining() == QChar::Dual);
+ }
+
+
+ switch (tag) {
+ case QChar::Medial:
+ return (left & right);
+ case QChar::Initial:
+ return (left && !right);
+ case QChar::Final:
+ return (right);// && !left);
+ case QChar::Isolated:
+ default:
+ return (!right && !left);
+ }
+} // format()
+
+/*
+ QString::compose() and visual() were developed by Gordon Tisher
+ <tisher@uniserve.ca>, with input from Lars Knoll <knoll@mpi-hd.mpg.de>,
+ who developed the unicode data tables.
+*/
+/*!
+ Note that this function is not supported in Qt 2.0, and is merely
+ for experimental and illustrative purposes. It is mainly of interest
+ to those experimenting with Arabic and other composition-rich texts.
+
+ Applies possible ligatures to a QString, useful when composition-rich
+ text requires rendering with glyph-poor fonts, but also
+ makes compositions such as QChar(0x0041) ('A') and QChar(0x0308)
+ (Unicode accent diaresis) giving QChar(0x00c4) (German A Umlaut).
+*/
+void QString::compose()
+{
+#ifndef QT_NO_UNICODETABLES
+ unsigned int index=0, len;
+ unsigned int cindex = 0;
+
+ QChar code, head;
+
+ QArray<QChar> dia;
+
+ QString composed = *this;
+
+ while (index < length()) {
+ code = at(index);
+ //printf("\n\nligature for 0x%x:\n", code.unicode());
+ QLigature ligature(code);
+ ligature.first();
+ while(ligature.current()) {
+ if ((len = ligature.match(*this, index)) != 0) {
+ head = ligature.head();
+ unsigned short code = head.unicode();
+ // we exclude Arabic presentation forms A and a few
+ // other ligatures, which are undefined in most fonts
+ if(!(code > 0xfb50 && code < 0xfe80) &&
+ !(code > 0xfb00 && code < 0xfb2a)) {
+ // joining info is only needed for arabic
+ if (format(ligature.tag(), *this, index, len)) {
+ //printf("using ligature 0x%x, len=%d\n",code,len);
+ // replace letter
+ composed.replace(cindex, len, QChar(head));
+ index += len-1;
+ // we continue searching in case we have a final
+ // form because medial ones are preferred.
+ if ( len != 1 || ligature.tag() !=QChar::Final )
+ break;
+ }
+ }
+ }
+ ligature.next();
+ }
+ cindex++;
+ index++;
+ }
+ *this = composed;
+#endif
+}
+
+static QChar LRM ((ushort)0x200e);
+static QChar RLM ((ushort)0x200f);
+static QChar LRE ((ushort)0x202a);
+static QChar RLE ((ushort)0x202b);
+static QChar RLO ((ushort)0x202e);
+static QChar LRO ((ushort)0x202d);
+static QChar PDF ((ushort)0x202c);
+
+#if 0
+static inline bool is_arabic(unsigned short x) {
+ return (((x >= 0x0600) && (x <= 0x07bf)) ||
+ ((x >= 0xfb50) && (x <= 0xfdff)) ||
+ ((x >= 0xfe70) && (x <= 0xfeff)));
+}
+#endif
+
+static inline bool is_neutral(unsigned short dir) {
+ return ((dir == QChar::DirB) ||
+ (dir == QChar::DirS) ||
+ (dir == QChar::DirWS) ||
+ (dir == QChar::DirON) ||
+ (dir == QChar::DirNSM));
+}
+
+/*!
+ This function returns the basic directionality of the string (QChar::DirR for
+ right to left and QChar::DirL for left to right). Useful to find the right
+ alignment.
+ */
+QChar::Direction QString::basicDirection()
+{
+#ifndef QT_NO_UNICODETABLES
+ // find base direction
+ unsigned int pos = 0;
+ while ((pos < length()) &&
+ (at(pos) != RLE) &&
+ (at(pos) != LRE) &&
+ (at(pos) != RLO) &&
+ (at(pos) != LRO) &&
+ (at(pos).direction() > 1) &&
+ (at(pos).direction() != QChar::DirAL)) // not R and not L
+ pos++;
+
+ if ((at(pos).direction() == QChar::DirR) ||
+ (at(pos).direction() == QChar::DirAL) ||
+ (at(pos) == RLE) ||
+ (at(pos) == RLO))
+ return QChar::DirR;
+#endif
+
+ return QChar::DirL;
+}
+
+#ifndef QT_NO_UNICODETABLES
+// reverses part of the QChar array to get visual ordering
+// called from QString::visual()
+//
+static unsigned int reverse( QString &chars, unsigned char *level,
+ unsigned int a, unsigned int b)
+{
+ unsigned int c = a;
+ unsigned char lev = level[c];
+
+ while ((c < b) && (level[c] >= lev)) {
+ if (level[c] > lev)
+ c = reverse(chars, level, c, b);
+ c++;
+ }
+
+ if (lev > 0) {
+ QChar temp;
+ unsigned int d = a, e = c-1;
+ while (d < e) {
+ temp = chars[(int)d];
+ chars[(int)d] = chars[(int)e];
+ chars[(int)e] = temp;
+
+ d++; e--;
+ }
+ }
+
+ return c;
+}
+
+// small class used for the ordering algorithm in QString::visual()
+class QBidiState {
+public:
+ unsigned char level;
+ signed char override;
+
+ QBidiState(unsigned char l, signed char o) : level(l), override(o) {};
+};
+
+// matrix for resolving neutral types
+
+#define NEG1 (QChar::Direction)(-1)
+
+static QChar::Direction resolv[5][5] =
+{
+ { NEG1, QChar::DirR, QChar::DirL, QChar::DirEN, QChar::DirAN },
+ { QChar::DirR, QChar::DirR, NEG1, QChar::DirR, QChar::DirR },
+ { QChar::DirL, NEG1, QChar::DirL, QChar::DirL, NEG1 },
+ { QChar::DirEN, QChar::DirR, QChar::DirL, QChar::DirEN, QChar::DirR },
+ { QChar::DirAN, QChar::DirR, NEG1, NEG1, QChar::DirAN }
+};
+
+#endif
+
+/*!
+ This function returns the QString ordered visually. Useful for
+ painting the string or when transforming to a visually ordered
+ encoding.
+*/
+QString QString::visual(int index, int len)
+{
+#ifndef QT_NO_UNICODETABLES
+ // #### This needs much more optimizing - it is called for
+ // #### every text operation.
+
+ unsigned char *level;
+ QChar::Direction *dir;
+ unsigned char base = 0;
+
+ unsigned int l = length();
+
+ // check bounds
+ if (len == -1)
+ len = length()-index;
+ if ((uint)index > l)
+ return QString::null;
+
+ // find base direction
+ unsigned int pos = 0;
+ while ((pos < length()) &&
+ (at(pos) != RLE) &&
+ (at(pos) != LRE) &&
+ (at(pos) != RLO) &&
+ (at(pos) != LRO) &&
+ (at(pos).direction() > 1) &&
+ (at(pos).direction() != QChar::DirAL)
+ ) // not R and not L
+ pos++;
+
+ if ((pos < length()) &&
+ ((at(pos).direction() == QChar::DirR) ||
+ (at(pos).direction() == QChar::DirAL) ||
+ (at(pos) == RLE) ||
+ (at(pos) == RLO)))
+ base = 1;
+
+ // is there any BiDi char at all?
+ if ( base == 0 && pos == l ) {
+ return mid(index, len);
+ }
+
+
+ level = new uchar[l];
+ dir = new QChar::Direction[l];
+
+ // explicit override pass
+ //unsigned int code_count = 0;
+
+ QStack<QBidiState> stack;
+ stack.setAutoDelete(TRUE);
+
+ unsigned char clevel = base;
+ signed char override = -1;
+
+ for (pos = 0; pos < l; pos++) {
+
+ if (at(pos) == RLE) {
+ //code_count++;
+ stack.push(new QBidiState(clevel, override));
+ if (clevel < 254)
+ clevel += 1 + clevel % 2;
+ override = -1;
+ }
+ else if (at(pos) == LRE) {
+ //code_count++;
+ stack.push(new QBidiState(clevel, override));
+ if (clevel < 254)
+ clevel += 2 - clevel % 2;
+ override = -1;
+ }
+ else if (at(pos) == RLO) {
+ //code_count++;
+ stack.push(new QBidiState(clevel, override));
+ if (clevel < 254)
+ clevel += 1 + clevel % 2;
+ override = QChar::DirR;
+ }
+ else if (at(pos) == LRO) {
+ //code_count++;
+ stack.push(new QBidiState(clevel, override));
+ if (clevel < 254)
+ clevel += 2 - clevel % 2;
+ override = QChar::DirL;
+ }
+ else if (at(pos) == PDF) {
+ //code_count++;
+ if (!stack.isEmpty()) {
+ override = stack.top()->override;
+ clevel = stack.top()->level;
+ stack.remove();
+ }
+ }
+
+ // TODO: catch block separators (newlines, paras, etc.)
+
+ level[pos] = clevel;
+ if (override != -1)
+ dir[pos] = (QChar::Direction) override;
+ else
+ dir[pos] = at(pos).direction();
+ }
+
+ // weak type pass
+ for (pos = 0; pos < l; pos++) {
+
+ int i;
+
+ switch (at(pos).direction()) {
+ case QChar::DirEN:
+ i = pos-1;
+ while ((i >= 0) &&
+ !(at(i).direction() == QChar::DirAN) &&
+ !(at(i).direction() == QChar::DirAL) &&
+ !(at(i).direction() == QChar::DirB))
+ i--;
+
+ if ((i >= 0) &&
+ ((at(i).direction() == QChar::DirAN) ||
+ (at(i).direction() == QChar::DirAL)))
+ dir[pos] = QChar::DirAN;
+
+ break;
+ case QChar::DirES:
+ case QChar::DirCS:
+ if ((pos > 0) && (pos < l-1) &&
+ (dir[pos-1] == dir[pos+1]))
+ dir[pos] = dir[pos-1];
+ else
+ dir[pos] = QChar::DirON;
+
+ break;
+ case QChar::DirET:
+ if (((pos > 0) && (dir[pos-1] == QChar::DirEN)) ||
+ ((pos < l-1) && (dir[pos+1] == QChar::DirEN)))
+ dir[pos] = QChar::DirEN;
+ else
+ dir[pos] = QChar::DirON;
+
+ break;
+ case QChar::DirAL:
+ dir[pos] = QChar::DirR;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // neutral type pass
+ for (pos = 0; pos < l; pos++) {
+ QChar::Direction left,right; // declaring l here shadowed previous l
+
+ if (is_neutral(dir[pos])) {
+ if (pos > 0)
+ left = dir[pos-1];
+ else
+ left = (base == 0 ? QChar::DirL : QChar::DirR);
+
+ int i = pos;
+
+ while ((i < (int)l-1) && is_neutral(dir[i+1]))
+ i++;
+
+ if (i < (int)l-1)
+ right = dir[i+1];
+ else
+ right = (base == 0 ? QChar::DirL : QChar::DirR);
+
+ for (int j=pos; j <= i; j++) {
+ int a = 1, b = 1;
+ while ((a < 5) && (left != resolv[0][a]))
+ a++;
+ while ((b < 5) && (right != resolv[0][b]))
+ b++;
+ if ((a == 5) || (b == 5))
+ dir[j] = (base == 0 ? QChar::DirL : QChar::DirR);
+ else
+ dir[j] = resolv[a][b];
+
+ if (dir[j] == (QChar::Direction)(-1))
+ dir[j] = (base == 0 ? QChar::DirL : QChar::DirR);
+ }
+ }
+ }
+
+ // implicit level pass
+ QChar::Direction prec = (base == 0 ? QChar::DirL : QChar::DirR);
+
+ for (pos = 0; pos < l; pos++) {
+ if (level[pos] % 2) {
+ switch (dir[pos]) {
+ case QChar::DirL:
+ case QChar::DirAN:
+ case QChar::DirEN:
+ level[pos] += 1;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (dir[pos]) {
+ case QChar::DirL:
+ // do nothing
+ break;
+ case QChar::DirR:
+ level[pos] += 1;
+ break;
+ case QChar::DirEN:
+ if (prec == QChar::DirL)
+ continue;
+ // fall through
+ case QChar::DirAN:
+ level[pos] += 2;
+ break;
+ default:
+ break;
+ }
+ }
+
+ prec = dir[pos];
+ }
+
+ // now do the work!
+ QString ret(*this);
+ reverse(ret, level, index, index+len);
+
+ delete [] level;
+ delete [] dir;
+
+ return ret;
+#else
+ return mid(index,len);
+#endif
+}
+
+
+
+// These macros are used for efficient allocation of QChar strings.
+// IMPORTANT! If you change these, make sure you also change the
+// "delete unicode" statement in ~QStringData() in qstring.h correspondingly!
+
+#define QT_ALLOC_QCHAR_VEC( N ) (QChar*) new char[ sizeof(QChar)*( N ) ]
+#define QT_DELETE_QCHAR_VEC( P ) delete[] ((char*)( P ))
+
+
+/*!
+ This utility function converts the 8-bit string
+ \a ba to Unicode, returning the result.
+
+ The caller is responsible for deleting the return value with delete[].
+*/
+
+QChar* QString::asciiToUnicode( const QByteArray& ba, uint* len )
+{
+ if ( ba.isNull() ) {
+ *len = 0;
+ return 0;
+ }
+ int l = 0;
+ while ( l < (int)ba.size() && ba[l] )
+ l++;
+ char* str = ba.data();
+ QChar *uc = new QChar[ l ]; // Can't use macro, since function is public
+ QChar *result = uc;
+ if ( len )
+ *len = l;
+ while (l--)
+ *uc++ = *str++;
+ return result;
+}
+
+static QChar* internalAsciiToUnicode( const QByteArray& ba, uint* len )
+{
+ if ( ba.isNull() ) {
+ *len = 0;
+ return 0;
+ }
+ int l = 0;
+ while ( l < (int)ba.size() && ba[l] )
+ l++;
+ char* str = ba.data();
+ QChar *uc = QT_ALLOC_QCHAR_VEC( l );
+ QChar *result = uc;
+ if ( len )
+ *len = l;
+ while (l--)
+ *uc++ = *str++;
+ return result;
+}
+
+/*!
+ This utility function converts the NUL-terminated 8-bit string
+ \a str to Unicode, returning the result and setting \a len to
+ the length of the Unicode string.
+
+ The caller is responsible for deleting the return value with delete[].
+*/
+
+QChar* QString::asciiToUnicode( const char *str, uint* len, uint maxlen )
+{
+ QChar* result = 0;
+ uint l = 0;
+ if ( str ) {
+ if ( maxlen != (uint)-1 ) {
+ while ( l < maxlen && str[l] )
+ l++;
+ } else {
+ // Faster?
+ l = qstrlen(str);
+ }
+ QChar *uc = new QChar[ l ]; // Can't use macro since function is public
+ result = uc;
+ uint i = l;
+ while ( i-- )
+ *uc++ = *str++;
+ }
+ if ( len )
+ *len = l;
+ return result;
+}
+
+static QChar* internalAsciiToUnicode( const char *str, uint* len,
+ uint maxlen = (uint)-1 )
+{
+ QChar* result = 0;
+ uint l = 0;
+ if ( str ) {
+ if ( maxlen != (uint)-1 ) {
+ while ( l < maxlen && str[l] )
+ l++;
+ } else {
+ // Faster?
+ l = qstrlen(str);
+ }
+ QChar *uc = QT_ALLOC_QCHAR_VEC( l );
+ result = uc;
+ uint i = l;
+ while ( i-- )
+ *uc++ = *str++;
+ }
+ if ( len )
+ *len = l;
+ return result;
+}
+
+/*!
+ This utility function converts \a l 16-bit characters from
+ \a uc to ASCII, returning a NUL-terminated string.
+
+ The caller is responsible for deleting the string with delete[].
+*/
+char* QString::unicodeToAscii(const QChar *uc, uint l)
+{
+ if (!uc) {
+ return 0;
+ }
+ char *a = new char[l+1];
+ char *result = a;
+ while (l--)
+ *a++ = *uc++;
+ *a = '\0';
+ return result;
+}
+
+/*****************************************************************************
+ QString member functions
+ *****************************************************************************/
+
+/*!
+ \class QString qstring.h
+
+ \brief The QString class provides an abstraction of Unicode text and
+ the classic C null-terminated char array (<var>char*</var>).
+
+ \ingroup tools
+ \ingroup shared
+
+ QString uses \link shclass.html implicit sharing\endlink, and so it
+ is very efficient and easy to use.
+
+ In all QString methods that take <var>const char*</var> parameters,
+ the <var>const char*</var> is interpreted as a classic C-style
+ 0-terminated ASCII string. It is legal for the <var>const
+ char*</var> parameter to be 0. The results are undefined if the
+ <var>const char*</var> string is not 0-terminated. Functions that
+ copy classic C strings into a QString will not copy the terminating
+ 0-character. The QChar array of the QString (as returned by
+ unicode()) is not terminated by a null.
+
+ A QString that has not been assigned to anything is \a null, i.e. both
+ the length and data pointer is 0. A QString that references the empty
+ string ("", a single '\0' char) is \a empty. Both null and empty
+ QStrings are legal parameters to the methods. Assigning <var>const char
+ * 0</var> to QString gives a null QString.
+
+ Note that if you find that you are mixing usage of QCString, QString,
+ and QByteArray, this causes lots of unnecessary copying and might
+ indicate that the true nature of the data you are dealing with is
+ uncertain. If the data is NUL-terminated 8-bit data, use QCString;
+ if it is unterminated (ie. contains NULs) 8-bit data, use QByteArray;
+ if it is text, use QString.
+
+ \sa QChar \link shclass.html Shared classes\endlink
+*/
+
+Q_EXPORT QStringData *QString::shared_null = 0;
+QT_STATIC_CONST_IMPL QString QString::null;
+QT_STATIC_CONST_IMPL QChar QChar::null;
+QT_STATIC_CONST_IMPL QChar QChar::replacement((ushort)0xfffd);
+QT_STATIC_CONST_IMPL QChar QChar::byteOrderMark((ushort)0xfeff);
+QT_STATIC_CONST_IMPL QChar QChar::byteOrderSwapped((ushort)0xfffe);
+QT_STATIC_CONST_IMPL QChar QChar::nbsp((ushort)0x00a0);
+
+QStringData* QString::makeSharedNull()
+{
+ return shared_null=new QStringData;
+}
+
+// Uncomment this to get some useful statistics.
+// #define Q2HELPER(x) x
+
+#ifdef Q2HELPER
+static int stat_construct_charstar=0;
+static int stat_construct_charstar_size=0;
+static int stat_construct_null=0;
+static int stat_construct_int=0;
+static int stat_construct_int_size=0;
+static int stat_construct_ba=0;
+static int stat_get_ascii=0;
+static int stat_get_ascii_size=0;
+static int stat_copy_on_write=0;
+static int stat_copy_on_write_size=0;
+static int stat_fast_copy=0;
+Q_EXPORT void qt_qstring_stats()
+{
+ qDebug("construct_charstar = %d (%d chars)", stat_construct_charstar, stat_construct_charstar_size);
+ qDebug("construct_null = %d", stat_construct_null);
+ qDebug("construct_int = %d (%d chars)", stat_construct_int, stat_construct_int_size);
+ qDebug("construct_ba = %d", stat_construct_ba);
+ qDebug("get_ascii = %d (%d chars)", stat_get_ascii, stat_get_ascii_size);
+ qDebug("copy_on_write = %d (%d chars)", stat_copy_on_write, stat_copy_on_write_size);
+ qDebug("fast_copy = %d", stat_fast_copy);
+}
+#else
+#define Q2HELPER(x)
+#endif
+
+/*!
+ \fn QString::QString()
+
+ Constructs a null string.
+ \sa isNull()
+*/
+
+/*!
+ Constructs a string containing the one character \a ch.
+*/
+QString::QString( QChar ch )
+{
+ d = new QStringData( QT_ALLOC_QCHAR_VEC( 1 ), 1, 1 );
+ d->unicode[0] = ch;
+}
+
+/*!
+ Constructs an implicitly-shared copy of \a s.
+*/
+QString::QString( const QString &s ) :
+ d(s.d)
+{
+ Q2HELPER(stat_fast_copy++)
+ d->ref();
+}
+
+/*!
+ Private function.
+
+ Constructs a string with preallocated space for \a size characters.
+
+ The string is empty.
+
+ \sa isNull()
+*/
+
+QString::QString( int size, bool /*dummy*/ )
+{
+ if ( size ) {
+ Q2HELPER(stat_construct_int++)
+ int l = size;
+ Q2HELPER(stat_construct_int_size+=l)
+ QChar* uc = QT_ALLOC_QCHAR_VEC( l );
+ d = new QStringData( uc, 0, l );
+ } else {
+ Q2HELPER(stat_construct_null++)
+ d = shared_null ? shared_null : (shared_null=new QStringData);
+ d->ref();
+ }
+}
+
+/*!
+ Constructs a string that is a deep copy of \a ba interpreted as
+ a classic C string.
+*/
+
+QString::QString( const QByteArray& ba )
+{
+ Q2HELPER(stat_construct_ba++)
+ uint l;
+ QChar *uc = internalAsciiToUnicode(ba,&l);
+ d = new QStringData(uc,l,l);
+}
+
+/*!
+ Constructs a string that is a deep copy of the
+ first \a length QChar in the array \a unicode.
+
+ If \a unicode and \a length are 0, a null string is created.
+
+ If only \a unicode is 0, the string is empty, but has
+ \a length characters of space preallocated - QString expands
+ automatically anyway, but this may speed some cases up a little.
+
+ \sa isNull()
+*/
+
+QString::QString( const QChar* unicode, uint length )
+{
+ if ( !unicode && !length ) {
+ d = shared_null ? shared_null : makeSharedNull();
+ } else {
+ QChar* uc = QT_ALLOC_QCHAR_VEC( length );
+ if ( unicode )
+ memcpy(uc, unicode, length*sizeof(QChar));
+ d = new QStringData(uc,unicode ? length : 0,length);
+ }
+}
+
+/*!
+ Constructs a string that is a deep copy of \a str, interpreted as a
+ classic C string.
+
+ If \a str is 0 a null string is created.
+
+ This is a cast constructor, but it is perfectly safe: converting a Latin1
+ const char* to QString preserves all the information.
+ You can disable this constructor by
+ defining QT_NO_CAST_ASCII when you compile your applications.
+ You can also make QString objects by using setLatin1()/fromLatin1(), or
+ fromLocal8Bit(), fromUtf8(), or whatever encoding is appropriate for
+ the 8-bit data you have.
+
+ \sa isNull()
+*/
+
+QString::QString( const char *str )
+{
+ Q2HELPER(stat_construct_charstar++)
+ uint l;
+ QChar *uc = internalAsciiToUnicode(str,&l);
+ Q2HELPER(stat_construct_charstar_size+=l)
+ d = new QStringData(uc,l,l);
+}
+
+
+/*! \fn QString::~QString()
+
+Destroys the string and frees the "real" string, if this was the last
+copy of that string.
+*/
+
+
+/*!
+ Deallocates any space reserved solely by this QString.
+*/
+
+void QString::real_detach()
+{
+ setLength( length() );
+}
+
+void QString::deref()
+{
+ if ( d->deref() ) {
+ delete d;
+ d = 0; // helps debugging
+ }
+}
+
+void QStringData::deleteSelf()
+{
+ delete this;
+}
+
+/*!
+ \fn QString& QString::operator=( QChar c )
+ Sets the string to contain just the single character \a c.
+*/
+
+/*!
+ \fn QString& QString::operator=( char c )
+ Sets the string to contain just the single character \a c.
+*/
+
+/*!
+ Assigns a shallow copy of \a s to this string and returns a
+ reference to this string.
+*/
+QString &QString::operator=( const QString &s )
+{
+ Q2HELPER(stat_fast_copy++)
+ s.d->ref();
+ deref();
+ d = s.d;
+ return *this;
+}
+
+/*!
+ Assigns a deep copy of \a cs, interpreted as a classic C string, to
+ this string and returns a reference to this string.
+*/
+QString &QString::operator=( const QCString& cs )
+{
+ return setLatin1(cs);
+}
+
+
+/*!
+ Assigns a deep copy of \a str, interpreted as a classic C string,
+ to this string and returns a reference to this string.
+
+ If \a str is 0 a null string is created.
+
+ \sa isNull()
+*/
+QString &QString::operator=( const char *str )
+{
+ return setLatin1(str);
+}
+
+
+/*!
+ \fn bool QString::isNull() const
+
+ Returns TRUE if the string is null.
+ A null string is also an empty string.
+
+ Example:
+ \code
+ QString a; // a.unicode() == 0, a.length() == 0
+ QString b = ""; // b.unicode() == "", b.length() == 0
+ a.isNull(); // TRUE, because a.unicode() == 0
+ a.isEmpty(); // TRUE, because a.length() == 0
+ b.isNull(); // FALSE, because b.unicode() != 0
+ b.isEmpty(); // TRUE, because b.length() == 0
+ \endcode
+
+ \sa isEmpty(), length()
+*/
+
+/*!
+ \fn bool QString::isEmpty() const
+
+ Returns TRUE if the string is empty, i.e. if length() == 0.
+ An empty string is not always a null string.
+
+ See example in isNull().
+
+ \sa isNull(), length()
+*/
+
+/*!
+ \fn uint QString::length() const
+
+ Returns the length of the string.
+
+ Null strings and empty strings have zero length.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ Truncates the string at position \a newLen if newLen is less than the
+ current length . Otherwise, nothing happens.
+
+ Example:
+ \code
+ QString s = "truncate this string";
+ s.truncate( 5 ); // s == "trunc"
+ \endcode
+
+ In Qt 1.x, it was possible to "truncate" a string to a longer
+ length. This is no longer possible.
+
+*/
+
+void QString::truncate( uint newLen )
+{
+ if ( newLen < d->len )
+ setLength( newLen );
+}
+
+/*### Make this public in 3.0
+ Ensures that at least \a newLen characters are allocated, and
+ sets the length to \a newLen. This function always detaches the
+ string from other references to the same data. Any new space
+ allocated is \e not defined.
+
+ If \a newLen is 0, this string becomes empty, unless this string is
+ null, in which case it remains null.
+
+ \sa truncate(), isNull(), isEmpty()
+*/
+
+void QString::setLength( uint newLen )
+{
+ if ( d->count != 1 || newLen > d->maxl || // detach, grow, or
+ ( newLen*4 < d->maxl && d->maxl > 4 ) ) { // shrink
+ Q2HELPER(stat_copy_on_write++)
+ Q2HELPER(stat_copy_on_write_size+=d->len)
+ uint newMax = 4;
+ while ( newMax < newLen )
+ newMax *= 2;
+ QChar* nd = QT_ALLOC_QCHAR_VEC( newMax );
+ uint len = QMIN( d->len, newLen );
+ if ( d->unicode )
+ memcpy( nd, d->unicode, sizeof(QChar)*len );
+ deref();
+ d = new QStringData( nd, newLen, newMax );
+ } else {
+ d->len = newLen;
+ d->dirtyascii = 1;
+ }
+}
+
+/*! Returns a string equal to this one, but with the lowest-numbered
+ occurrence of \c %i (for a positive integer i) replaced by \a a.
+
+ \code
+ label.setText( tr("Rename %1 to %2?").arg(oldName).arg(newName) );
+ \endcode
+
+ \a fieldwidth is the minimum amount of space \a a is padded to. A
+ positive value produces right-aligned text, while a negative value
+ produces left aligned text.
+
+ \warning Using arg() for constructing "real" sentences
+ programmatically is likely to lead to translation problems.
+ Inserting objects like numbers or file names is fairly safe.
+
+ \warning Relying on spaces to create alignment is prone to lead to
+ translation problems.
+
+ If there is no \c %i pattern, a warning message (qWarning()) is
+ printed and the text as appended at the end of the string. This is
+ error recovery and should not occur in correct code.
+
+ \sa QObject::tr()
+*/
+QString QString::arg(const QString& a, int fieldwidth) const
+{
+ int pos, len;
+ QString r = *this;
+
+ if ( !findArg( pos, len ) ) {
+ qWarning( "QString::arg(): Argument missing: %s, %s",
+ (const char *)this, (const char *)a );
+ // Make sure the text at least appears SOMEWHERE
+ r += ' ';
+ pos = r.length();
+ len = 0;
+ }
+
+ r.replace( pos, len, a );
+ if ( fieldwidth < 0 ) {
+ QString s;
+ while ( (uint)-fieldwidth > a.length() ) {
+ s += ' ';
+ fieldwidth++;
+ }
+ r.insert( pos + a.length(), s );
+ } else if ( fieldwidth ) {
+ QString s;
+ while ( (uint)fieldwidth > a.length() ) {
+ s += ' ';
+ fieldwidth--;
+ }
+ r.insert( pos, s );
+ }
+
+ return r;
+}
+
+
+/*! \overload
+
+ \a a is expressed in to \a base notation, which is decimal by
+ default and must be in the range 2-36 inclusive.
+*/
+QString QString::arg(long a, int fieldwidth, int base) const
+{
+ return arg( QString::number( a, base ), fieldwidth );
+}
+
+/*! \overload
+
+ \a a is expressed in to \a base notation, which is decimal by
+ default and must be in the range 2-36 inclusive.
+*/
+QString QString::arg(ulong a, int fieldwidth, int base) const
+{
+ return arg( QString::number( a, base ), fieldwidth );
+}
+
+/*!
+ \overload QString QString::arg(int a, int fieldwidth, int base) const
+
+ \a a is expressed in to \a base notation, which is decimal by
+ default and must be in the range 2-36 inclusive.
+
+*/
+
+/*!
+ \overload QString QString::arg(uint a, int fieldwidth, int base) const
+
+ \a a is expressed in to \a base notation, which is decimal by
+ default and must be in the range 2-36 inclusive.
+*/
+
+/*!
+ \overload QString QString::arg(short a, int fieldwidth, int base) const
+
+ \a a is expressed in to \a base notation, which is decimal by
+ default and must be in the range 2-36 inclusive.
+*/
+
+/*!
+ \overload QString QString::arg(ushort a, int fieldwidth, int base) const
+
+ \a a is expressed in to \a base notation, which is decimal by
+ default and must be in the range 2-36 inclusive.
+*/
+
+
+/*! \overload
+
+ \a a is assumed to be in the Latin1 character set.
+*/
+QString QString::arg(char a, int fieldwidth) const
+{
+ QString c;
+ c += a;
+ return arg( c, fieldwidth );
+}
+
+/*! \overload
+*/
+QString QString::arg(QChar a, int fieldwidth) const
+{
+ QString c;
+ c += a;
+ return arg( c, fieldwidth );
+}
+
+/*! \overload
+
+ \a is formatted according to the \a fmt format specified, which is
+ 'g' by default and can be any of 'f', 'F', 'e', 'E', 'g' or 'G', all
+ of which have the same meaning as for sprintf(). \a prec determines
+ the precision, just as for number() and sprintf().
+*/
+QString QString::arg(double a, int fieldwidth, char fmt, int prec) const
+{
+ return arg( QString::number( a, fmt, prec ), fieldwidth );
+}
+
+
+/*!
+ Just 1-digit arguments.
+*/
+bool QString::findArg(int& pos, int& len) const
+{
+ char lowest=0;
+ for (uint i=0; i<length(); i++) {
+ if ( at(i) == '%' && i+1<length() ) {
+ char dig = at(i+1);
+ if ( dig >= '0' && dig <= '9' ) {
+ if ( !lowest || dig < lowest ) {
+ lowest = dig;
+ pos = i;
+ len = 2;
+ }
+ }
+ }
+ }
+ return lowest != 0;
+}
+
+/*!
+ Safely builds a formatted string from a format string and an
+ arbitrary list of arguments. The format string supports all
+ the escape sequences of printf() in the standard C library.
+
+ The %s escape sequence expects a utf8() encoded string.
+ The format string \e cformat is expected to be in latin1. If you need a unicode
+ format string, use QString::arg() instead. For typesafe
+ string building, with full Unicode support, you can use QTextOStream
+ like this:
+
+ \code
+ QString str;
+ QString s = ...;
+ int x = ...;
+ QTextOStream(&str) << s << " : " << x;
+ \endcode
+
+ For \link QObject::tr() translations,\endlink especially if the
+ strings contains more than one escape sequence, you should consider
+ using the arg() function instead. This allows the order of the
+ replacements to be controlled by the translator, and has Unicode
+ support.
+
+ \sa arg()
+*/
+
+QString &QString::sprintf( const char* cformat, ... )
+{
+ va_list ap;
+ va_start( ap, cformat );
+
+ if ( !cformat || !*cformat ) {
+ // Qt 1.x compat
+ *this = QString::fromLatin1( "" );
+ return *this;
+ }
+ QString format = QString::fromLatin1( cformat );
+
+ static QRegExp *escape = 0;
+ if (!escape)
+ escape = new QRegExp( "%#?0?-? ?\\+?'?[0-9*]*\\.?[0-9*]*h?l?L?q?Z?" );
+
+ QString result;
+ uint last = 0;
+
+ int len = 0;
+ int pos;
+ while ( 1 ) {
+ pos = escape->match( format, last, &len );
+ // Non-escaped text
+ if ( pos > (int)last )
+ result += format.mid(last,pos-last);
+ if ( pos < 0 ) {
+ // The rest
+ if ( last < format.length() )
+ result += format.mid(last);
+ break;
+ }
+ last = pos + len + 1;
+
+ // Escape
+ QString f = format.mid( pos, len );
+ uint width, decimals;
+ int params = 0;
+ int wpos = f.find('*');
+ if ( wpos >= 0 ) {
+ params++;
+ width = va_arg( ap, int );
+ if ( f.find('*', wpos + 1) >= 0 ) {
+ decimals = va_arg( ap, int );
+ params++;
+ } else {
+ decimals = 0;
+ }
+ } else {
+ decimals = width = 0;
+ }
+ QString replacement;
+ if ( format[pos+len] == 's' ||
+ format[pos+len] == 'S' ||
+ format[pos+len] == 'c' )
+ {
+ bool rightjust = ( f.find('-') < 0 );
+ // Yes, %-5s really means left adjust in sprintf
+
+ if ( wpos < 0 ) {
+ QRegExp num( QString::fromLatin1("[0-9]+") );
+ QRegExp dot( QString::fromLatin1("\\.") );
+ int nlen;
+ int p = num.match( f, 0, &nlen );
+ int q = dot.match( f, 0 );
+ if ( q < 0 || (p < q && p >= 0) )
+ width = f.mid( p, nlen ).toInt();
+ if ( q >= 0 ) {
+ p = num.match( f, q );
+ // "decimals" is used to specify string truncation
+ if ( p >= 0 )
+ decimals = f.mid( p, nlen ).toInt();
+ }
+ }
+
+ if ( format[pos+len] == 's' ) {
+#ifndef QT_NO_TEXTCODEC
+ QString s = QString::fromUtf8(va_arg(ap, char*));
+#else
+ QString s = QString::fromLatin1(va_arg(ap, char*));
+#endif
+ if ( decimals <= 0 )
+ replacement = s;
+ else
+ replacement = s.left(decimals);
+ } else {
+ int ch = va_arg(ap, int);
+ replacement = QChar((ushort)ch);
+ }
+ if ( replacement.length() < width ) {
+ replacement = rightjust
+ ? replacement.rightJustify(width)
+ : replacement.leftJustify(width);
+ }
+ } else if ( format[pos+len] == '%' ) {
+ replacement = '%';
+ } else if ( format[pos+len] == 'n' ) {
+ int* n = va_arg(ap, int*);
+ *n = result.length();
+ } else {
+ char in[64], out[330] = "";
+ strncpy(in,f.latin1(),63);
+ char fch = format[pos+len].latin1();
+ in[f.length()] = fch;
+ switch ( fch ) {
+ case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': {
+ int value = va_arg(ap, int);
+ switch (params) {
+ case 0: ::sprintf( out, in, value ); break;
+ case 1: ::sprintf( out, in, width, value ); break;
+ case 2: ::sprintf( out, in, width, decimals, value ); break;
+ }
+ } break;
+ case 'e': case 'E': case 'f': case 'g': {
+ double value = va_arg(ap, double);
+ switch (params) {
+ case 0: ::sprintf( out, in, value ); break;
+ case 1: ::sprintf( out, in, width, value ); break;
+ case 2: ::sprintf( out, in, width, decimals, value ); break;
+ }
+ } break;
+ case 'p': {
+ void* value = va_arg(ap, void*);
+ switch (params) {
+ case 0: ::sprintf( out, in, value ); break;
+ case 1: ::sprintf( out, in, width, value ); break;
+ case 2: ::sprintf( out, in, width, decimals, value ); break;
+ }
+ } break;
+ }
+ replacement = QString::fromLatin1(out);
+ }
+ result += replacement;
+ }
+ *this = result;
+
+ va_end( ap );
+ return *this;
+}
+
+/*!
+ Fills the string with \a len characters of value \a c.
+
+ If \a len is negative, the current string length is used.
+*/
+
+void QString::fill( QChar c, int len )
+{
+ if ( len < 0 )
+ len = length();
+ if ( len == 0 ) {
+ *this = "";
+ } else {
+ deref();
+ QChar * nd = QT_ALLOC_QCHAR_VEC( len );
+ d = new QStringData(nd,len,len);
+ while (len--) *nd++ = c;
+ }
+}
+
+
+/*!
+ \fn QString QString::copy() const
+
+ \obsolete
+
+ Returns a deep copy of this string.
+
+ Doing this is redundant in Qt 2.x, since QString is implicitly
+ shared, and so will automatically be deeply copied as necessary.
+*/
+
+/*!
+ Finds the first occurrence of the character \a c, starting at
+ position \a index. If \a index is -1, the search starts at the
+ last character; if -2, at the next to last character; etc.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive
+ if \a cs is FALSE.
+
+ Returns the position of \a c, or -1 if \a c could not be found.
+*/
+
+int QString::find( QChar c, int index, bool cs ) const
+{
+ if ( index < 0 )
+ index += length();
+ if ( (uint)index >= length() ) // index outside string
+ return -1;
+ register const QChar *uc;
+ uc = unicode()+index;
+ int n = length()-index;
+ if ( cs ) {
+ while ( n-- && *uc != c )
+ uc++;
+ } else {
+ c = c.lower();
+ while ( n-- && uc->lower() != c )
+ uc++;
+ }
+ if ( uint(uc - unicode()) >= length() )
+ return -1;
+ return (int)(uc - unicode());
+}
+
+/*!
+ Finds the first occurrence of the string \a str, starting at position
+ \a index. If \a index is -1, the search starts at the last character;
+ if -2, at the next to last character; etc.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive if
+ \a cs is FALSE.
+
+ Returns the position of \a str, or -1 if \a str could not be found.
+*/
+
+int QString::find( const QString& str, int index, bool cs ) const
+{
+ /*
+ We use some weird hashing for efficiency's sake. Instead of
+ comparing strings, we compare the hash value of str with that of
+ a part of this QString. Only if that matches, we call ucstrncmp
+ or ucstrnicmp.
+
+ The hash value of a string is the sum of the cells of its
+ QChars.
+ */
+ if ( index < 0 )
+ index += length();
+ int lstr = str.length();
+ int lthis = length() - index;
+ if ( (uint)lthis > length() )
+ return -1;
+ int delta = lthis - lstr;
+ if ( delta < 0 )
+ return -1;
+
+ const QChar *uthis = unicode() + index;
+ const QChar *ustr = str.unicode();
+ uint hthis = 0;
+ uint hstr = 0;
+ int i;
+ if ( cs ) {
+ for ( i = 0; i < lstr; i++ ) {
+ hthis += uthis[i].cell();
+ hstr += ustr[i].cell();
+ }
+ i = 0;
+ while ( TRUE ) {
+ if ( hthis == hstr && ucstrncmp(uthis + i, ustr, lstr) == 0 )
+ return index + i;
+ if ( i == delta )
+ return -1;
+ hthis += uthis[i + lstr].cell();
+ hthis -= uthis[i].cell();
+ i++;
+ }
+ } else {
+ for ( i = 0; i < lstr; i++ ) {
+ hthis += uthis[i].lower().cell();
+ hstr += ustr[i].lower().cell();
+ }
+ i = 0;
+ while ( TRUE ) {
+ if ( hthis == hstr && ucstrnicmp(uthis + i, ustr, lstr) == 0 )
+ return index + i;
+ if ( i == delta )
+ return -1;
+ hthis += uthis[i + lstr].lower().cell();
+ hthis -= uthis[i].lower().cell();
+ i++;
+ }
+ }
+#if defined(Q_SPURIOUS_NON_VOID_WARNING)
+ return -1;
+#endif
+}
+
+/*!
+ \fn int QString::findRev( const char* str, int index ) const
+
+ Equivalent to findRev(QString(str), index).
+*/
+
+/*!
+ \fn int QString::find( const char* str, int index ) const
+
+ Equivalent to find(QString(str), index).
+*/
+
+/*!
+ Finds the first occurrence of the character \a c, starting at
+ position \a index and searching backwards. If \a index is -1,
+ the search starts at the last character; if -2, at the next to
+ last character; etc.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive if \a
+ cs is FALSE.
+
+ Returns the position of \a c, or -1 if \a c could not be found.
+*/
+
+int QString::findRev( QChar c, int index, bool cs ) const
+{
+ QString t( c );
+ return findRev( t, index, cs );
+}
+
+/*!
+ Finds the first occurrence of the string \a str, starting at
+ position \a index and searching backwards. If \a index is -1,
+ the search starts at the last character; -2, at the next to last
+ character; etc.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive if \e
+ cs is FALSE.
+
+ Returns the position of \a str, or -1 if \a str could not be found.
+*/
+
+int QString::findRev( const QString& str, int index, bool cs ) const
+{
+ /*
+ See QString::find() for explanations.
+ */
+ int lthis = length();
+ if ( index < 0 )
+ index += lthis;
+
+ int lstr = str.length();
+ int delta = lthis - lstr;
+ if ( index < 0 || index > lthis || delta < 0 )
+ return -1;
+ if ( index > delta )
+ index = delta;
+
+ const QChar *uthis = unicode();
+ const QChar *ustr = str.unicode();
+ uint hthis = 0;
+ uint hstr = 0;
+ int i;
+ if ( cs ) {
+ for ( i = 0; i < lstr; i++ ) {
+ hthis += uthis[index + i].cell();
+ hstr += ustr[i].cell();
+ }
+ i = index;
+ while ( TRUE ) {
+ if ( hthis == hstr && ucstrncmp(uthis + i, ustr, lstr) == 0 )
+ return i;
+ if ( i == 0 )
+ return -1;
+ i--;
+ hthis -= uthis[i + lstr].cell();
+ hthis += uthis[i].cell();
+ }
+ } else {
+ for ( i = 0; i < lstr; i++ ) {
+ hthis += uthis[index + i].lower().cell();
+ hstr += ustr[i].lower().cell();
+ }
+ i = index;
+ while ( TRUE ) {
+ if ( hthis == hstr && ucstrnicmp(uthis + i, ustr, lstr) == 0 )
+ return i;
+ if ( i == 0 )
+ return -1;
+ i--;
+ hthis -= uthis[i + lstr].lower().cell();
+ hthis += uthis[i].lower().cell();
+ }
+ }
+#if defined(Q_SPURIOUS_NON_VOID_WARNING)
+ return -1;
+#endif
+}
+
+
+/*!
+ Returns the number of times the character \a c occurs in the string.
+
+ The match is case sensitive if \a cs is TRUE, or case insensitive if \a cs
+ is FALSE.
+*/
+
+int QString::contains( QChar c, bool cs ) const
+{
+ int count = 0;
+ const QChar *uc = unicode();
+ if ( !uc )
+ return 0;
+ int n = length();
+ if ( cs ) { // case sensitive
+ while ( n-- )
+ if ( *uc++ == c )
+ count++;
+ } else { // case insensitive
+ c = c.lower();
+ while ( n-- ) {
+ if ( uc->lower() == c )
+ count++;
+ uc++;
+ }
+ }
+ return count;
+}
+
+/*!
+ \overload
+*/
+int QString::contains( const char* str, bool cs ) const
+{
+ return contains(QString(str),cs);
+}
+
+/*!
+ \overload int QString::contains (char c, bool cs) const
+*/
+
+/*!
+ \overload int QString::find (char c, int index, bool cs) const
+
+*/
+
+/*!
+ \overload int QString::findRev (char c, int index, bool cs) const
+
+*/
+
+/*!
+ Returns the number of times \a str occurs in the string.
+
+ The match is case sensitive if \a cs is TRUE, or case insensitive if \e
+ cs is FALSE.
+
+ This function counts overlapping substrings, for example, "banana"
+ contains two occurrences of "ana".
+
+ \sa findRev()
+*/
+
+int QString::contains( const QString &str, bool cs ) const
+{
+ int count = 0;
+ const QChar *uc = unicode();
+ if ( !uc )
+ return 0;
+ int len = str.length();
+ int n = length();
+ while ( n-- ) { // counts overlapping strings
+ // ### Doesn't account for length of this - searches over "end"
+ if ( cs ) {
+ if ( ucstrncmp( uc, str.unicode(), len ) == 0 )
+ count++;
+ } else {
+ if ( ucstrnicmp(uc, str.unicode(), len) == 0 )
+ count++;
+ }
+ uc++;
+ }
+ return count;
+}
+
+/*!
+ Returns a substring that contains the \a len leftmost characters
+ of the string.
+
+ The whole string is returned if \a len exceeds the length of the
+ string.
+
+
+ Example:
+ \code
+ QString s = "Pineapple";
+ QString t = s.left( 4 ); // t == "Pine"
+ \endcode
+
+ \sa right(), mid(), isEmpty()
+*/
+
+QString QString::left( uint len ) const
+{
+ if ( isEmpty() ) {
+ return QString();
+ } else if ( len == 0 ) { // ## just for 1.x compat:
+ return QString::fromLatin1("");
+ } else if ( len > length() ) {
+ return *this;
+ } else {
+ QString s( len, TRUE );
+ memcpy( s.d->unicode, d->unicode, len*sizeof(QChar) );
+ s.d->len = len;
+ return s;
+ }
+}
+
+/*!
+ Returns a substring that contains the \a len rightmost characters
+ of the string.
+
+ The whole string is returned if \a len exceeds the length of the
+ string.
+
+ Example:
+ \code
+ QString s = "Pineapple";
+ QString t = s.right( 5 ); // t == "apple"
+ \endcode
+
+ \sa left(), mid(), isEmpty()
+*/
+
+QString QString::right( uint len ) const
+{
+ if ( isEmpty() ) {
+ return QString();
+ } else if ( len == 0 ) { // ## just for 1.x compat:
+ return QString::fromLatin1("");
+ } else {
+ uint l = length();
+ if ( len > l )
+ len = l;
+ QString s( len, TRUE );
+ memcpy( s.d->unicode, d->unicode+(l-len), len*sizeof(QChar) );
+ s.d->len = len;
+ return s;
+ }
+}
+
+/*!
+ Returns a substring that contains the \a len characters of this
+ string, starting at position \a index.
+
+ Returns a null string if the string is empty or \a index is out
+ of range. Returns the whole string from \a index if \a index+len exceeds
+ the length of the string.
+
+ Example:
+ \code
+ QString s = "Five pineapples";
+ QString t = s.mid( 5, 4 ); // t == "pine"
+ \endcode
+
+ \sa left(), right()
+*/
+
+QString QString::mid( uint index, uint len ) const
+{
+ uint slen = length();
+ if ( isEmpty() || index >= slen ) {
+ return QString();
+ } else if ( len == 0 ) { // ## just for 1.x compat:
+ return QString::fromLatin1("");
+ } else {
+ if ( len > slen-index )
+ len = slen - index;
+ if ( index == 0 && len == length() )
+ return *this;
+ register const QChar *p = unicode()+index;
+ QString s( len, TRUE );
+ memcpy( s.d->unicode, p, len*sizeof(QChar) );
+ s.d->len = len;
+ return s;
+ }
+}
+
+/*!
+ Returns a string of length \a width that contains this
+ string and padded by the \a fill character.
+
+ If the length of the string exceeds \a width and \a truncate is FALSE,
+ then the returned string is a copy of the string.
+ If the length of the string exceeds \a width and \a truncate is TRUE,
+ then the returned string is a left(\a width).
+
+ Example:
+ \code
+ QString s("apple");
+ QString t = s.leftJustify(8, '.'); // t == "apple..."
+ \endcode
+
+ \sa rightJustify()
+*/
+
+QString QString::leftJustify( uint width, QChar fill, bool truncate ) const
+{
+ QString result;
+ int len = length();
+ int padlen = width - len;
+ if ( padlen > 0 ) {
+ result.setLength(len+padlen);
+ if ( len )
+ memcpy( result.d->unicode, unicode(), sizeof(QChar)*len );
+ QChar* uc = result.d->unicode + len;
+ while (padlen--)
+ *uc++ = fill;
+ } else {
+ if ( truncate )
+ result = left( width );
+ else
+ result = *this;
+ }
+ return result;
+}
+
+/*!
+ Returns a string of length \a width that contains pad
+ characters followed by the string.
+
+ If the length of the string exceeds \a width and \a truncate is FALSE,
+ then the returned string is a copy of the string.
+ If the length of the string exceeds \a width and \a truncate is TRUE,
+ then the returned string is a left(\a width).
+
+ Example:
+ \code
+ QString s("pie");
+ QString t = s.rightJustify(8, '.'); // t == ".....pie"
+ \endcode
+
+ \sa leftJustify()
+*/
+
+QString QString::rightJustify( uint width, QChar fill, bool truncate ) const
+{
+ QString result;
+ int len = length();
+ int padlen = width - len;
+ if ( padlen > 0 ) {
+ result.setLength( len+padlen );
+ QChar* uc = result.d->unicode;
+ while (padlen--)
+ *uc++ = fill;
+ if ( len )
+ memcpy( uc, unicode(), sizeof(QChar)*len );
+ } else {
+ if ( truncate )
+ result = left( width );
+ else
+ result = *this;
+ }
+ return result;
+}
+
+/*!
+ Returns a new string that is the string converted to lower case.
+
+ Example:
+ \code
+ QString s("TeX");
+ QString t = s.lower(); // t == "tex"
+ \endcode
+
+ \sa upper()
+*/
+
+QString QString::lower() const
+{
+ QString s(*this);
+ int l=length();
+ if ( l ) {
+ s.real_detach(); // could do this only when we find a change
+ register QChar *p=s.d->unicode;
+ if ( p ) {
+ while ( l-- ) {
+ *p = p->lower();
+ p++;
+ }
+ }
+ }
+ return s;
+}
+
+/*!
+ Returns a new string that is the string converted to upper case.
+
+ Example:
+ \code
+ QString s("TeX");
+ QString t = s.upper(); // t == "TEX"
+ \endcode
+
+ \sa lower()
+*/
+
+QString QString::upper() const
+{
+ QString s(*this);
+ int l=length();
+ if ( l ) {
+ s.real_detach(); // could do this only when we find a change
+ register QChar *p=s.d->unicode;
+ if ( p ) {
+ while ( l-- ) {
+ *p = p->upper();
+ p++;
+ }
+ }
+ }
+ return s;
+}
+
+
+/*!
+ Returns a new string that has white space removed from the start and the end.
+
+ White space means any character for which QChar::isSpace() returns
+ TRUE. This includes ASCII characters 9 (TAB), 10 (LF), 11 (VT), 12
+ (FF), 13 (CR), and 32 (Space).
+
+ Example:
+ \code
+ QString s = " space ";
+ QString t = s.stripWhiteSpace(); // t == "space"
+ \endcode
+
+ \sa simplifyWhiteSpace()
+*/
+
+QString QString::stripWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return *this;
+ if ( !at(0).isSpace() && !at(length()-1).isSpace() )
+ return *this;
+
+ register const QChar *s = unicode();
+ QString result = fromLatin1("");
+
+ int start = 0;
+ int end = length() - 1;
+ while ( start<=end && s[start].isSpace() ) // skip white space from start
+ start++;
+ if ( start > end ) { // only white space
+ return result;
+ }
+ while ( end && s[end].isSpace() ) // skip white space from end
+ end--;
+ int l = end - start + 1;
+ result.setLength( l );
+ if ( l )
+ memcpy( result.d->unicode, &s[start], sizeof(QChar)*l );
+ return result;
+}
+
+
+/*!
+ Returns a new string that has white space removed from the start and the end,
+ plus any sequence of internal white space replaced with a single space
+ (ASCII 32).
+
+ White space means any character for which QChar::isSpace() returns
+ TRUE. This includes ASCII characters 9 (TAB), 10 (LF), 11 (VT), 12
+ (FF), 13 (CR), and 32 (Space).
+
+ \code
+ QString s = " lots\t of\nwhite space ";
+ QString t = s.simplifyWhiteSpace(); // t == "lots of white space"
+ \endcode
+
+ \sa stripWhiteSpace()
+*/
+
+QString QString::simplifyWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return *this;
+ QString result;
+ result.setLength( length() );
+ const QChar *from = unicode();
+ const QChar *fromend = from+length();
+ int outc=0;
+ QChar *to = result.d->unicode;
+ while ( TRUE ) {
+ while ( from!=fromend && from->isSpace() )
+ from++;
+ while ( from!=fromend && !from->isSpace() )
+ to[outc++] = *from++;
+ if ( from!=fromend )
+ to[outc++] = ' ';
+ else
+ break;
+ }
+ if ( outc > 0 && to[outc-1] == ' ' )
+ outc--;
+ result.truncate( outc );
+ return result;
+}
+
+
+/*!
+ Insert \a s into the string before position \a index.
+
+ If \a index is beyond the end of the string, the string is extended with
+ spaces (ASCII 32) to length \a index and \a s is then appended.
+
+ \code
+ QString s = "I like fish";
+ s.insert( 2, "don't "); // s == "I don't like fish"
+ s = "x";
+ s.insert( 3, "yz" ); // s == "x yz"
+ \endcode
+*/
+
+QString &QString::insert( uint index, const QString &s )
+{
+ // the sub function takes care of &s == this case.
+ return insert( index, s.unicode(), s.length() );
+}
+
+/*!
+ Insert \a len units of QChar data from \a s into the string before
+ position \a index.
+*/
+
+QString &QString::insert( uint index, const QChar* s, uint len )
+{
+ if ( len == 0 )
+ return *this;
+ uint olen = length();
+ int nlen = olen + len;
+
+ int df = s - d->unicode; // ### pointer subtraction, cast down to int
+ if ( df >= 0 && (uint)df < d->maxl ) {
+ // Part of me - take a copy.
+ QChar *tmp = QT_ALLOC_QCHAR_VEC( len );
+ memcpy(tmp,s,len*sizeof(QChar));
+ insert(index,tmp,len);
+ QT_DELETE_QCHAR_VEC( tmp );
+ return *this;
+ }
+
+ if ( index >= olen ) { // insert after end of string
+ setLength( len+index );
+ int n = index-olen;
+ QChar* uc = d->unicode+olen;
+ while (n--)
+ *uc++ = ' ';
+ memcpy( d->unicode+index, s, sizeof(QChar)*len );
+ } else { // normal insert
+ setLength( nlen );
+ memmove( d->unicode+index+len, unicode()+index,
+ sizeof(QChar)*(olen-index) );
+ memcpy( d->unicode+index, s, sizeof(QChar)*len );
+ }
+ return *this;
+}
+
+/*!
+ Insert \a c into the string at (before) position \a index and returns
+ a reference to the string.
+
+ If \a index is beyond the end of the string, the string is extended with
+ spaces (ASCII 32) to length \a index and \a c is then appended.
+
+ Example:
+ \code
+ QString s = "Ys";
+ s.insert( 1, 'e' ); // s == "Yes"
+ s.insert( 3, '!'); // s == "Yes!"
+ \endcode
+
+ \sa remove(), replace()
+*/
+
+QString &QString::insert( uint index, QChar c ) // insert char
+{
+ QString s( c );
+ return insert( index, s );
+}
+
+/*!
+ \overload QString& QString::insert( uint index, char c )
+*/
+
+/*!
+ \fn QString &QString::prepend( const QString &s )
+
+ Prepend \a s to the string. Equivalent to insert(0,s).
+
+ \sa insert()
+*/
+
+/*!
+ \fn QString& QString::prepend( char ch )
+ Prepends \a ch to the string and returns a reference to the result.
+
+ \sa insert()
+ */
+
+/*!
+ \fn QString& QString::prepend( QChar ch )
+ Prepends \a ch to the string and returns a reference to the result.
+
+ \sa insert()
+ */
+
+
+/*!
+ Removes \a len characters starting at position \a index from the
+ string and returns a reference to the string.
+
+ If \a index is too big, nothing happens. If \a index is valid, but
+ \a len is too large, the rest of the string is removed.
+
+ \code
+ QString s = "Montreal";
+ s.remove( 1, 4 );
+ // s == "Meal"
+ \endcode
+
+ \sa insert(), replace()
+*/
+
+QString &QString::remove( uint index, uint len )
+{
+ uint olen = length();
+ if ( index + len >= olen ) { // range problems
+ if ( index < olen ) { // index ok
+ setLength( index );
+ }
+ } else if ( len != 0 ) {
+ real_detach();
+ memmove( d->unicode+index, d->unicode+index+len,
+ sizeof(QChar)*(olen-index-len) );
+ setLength( olen-len );
+ }
+ return *this;
+}
+
+/*!
+ Replaces \a len characters starting at position \a index from the
+ string with \a s, and returns a reference to the string.
+
+ If \a index is too big, nothing is deleted and \a s is inserted at the
+ end of the string. If \a index is valid, but \a len is too large, \e
+ str replaces the rest of the string.
+
+ \code
+ QString s = "Say yes!";
+ s.replace( 4, 3, "NO" ); // s == "Say NO!"
+ \endcode
+
+ \sa insert(), remove()
+*/
+
+QString &QString::replace( uint index, uint len, const QString &s )
+{
+ return replace( index, len, s.unicode(), s.length() );
+}
+
+
+/*!
+ Replaces \a len characters starting at position \a index by
+ \a slen units ot QChar data from \a s, and returns a reference to the string.
+
+ \sa insert(), remove()
+*/
+
+QString &QString::replace( uint index, uint len, const QChar* s, uint slen )
+{
+ if ( len == slen && index + len <= length() ) {
+ // Optimized common case: replace without size change
+ real_detach();
+ memcpy( d->unicode+index, s, len*sizeof(QChar) );
+ } else {
+ int df = s - d->unicode; // ### pointer subtraction, cast down to int
+ if ( df >= 0 && (uint)df < d->maxl ) {
+ // Part of me - take a copy.
+ QChar *tmp = QT_ALLOC_QCHAR_VEC( slen );
+ memcpy(tmp,s,slen*sizeof(QChar));
+ replace(index,len,tmp,slen);
+ QT_DELETE_QCHAR_VEC( tmp );
+ return *this;
+ }
+
+ remove( index, len );
+ insert( index, s, slen );
+ }
+ return *this;
+}
+
+
+
+/*!
+ Finds the first occurrence of the regular expression \a rx, starting at
+ position \a index. If \a index is -1, the search starts at the last
+ character; if -2, at the next to last character; etc.
+
+ Returns the position of the next match, or -1 if \a rx was not found.
+
+ \sa findRev() replace() contains()
+*/
+
+int QString::find( const QRegExp &rx, int index ) const
+{
+ if ( index < 0 )
+ index += length();
+ return rx.match( *this, index );
+}
+
+/*!
+ Finds the first occurrence of the regular expression \a rx, starting at
+ position \a index and searching backwards. If \a index is -1, the
+ search starts at the last character; if -2, at the next to last
+ character; etc.
+
+ Returns the position of the next match (backwards), or -1 if \a rx was not
+ found.
+
+ \sa find()
+*/
+
+int QString::findRev( const QRegExp &rx, int index ) const
+{
+ if ( index < 0 ) // neg index ==> start from end
+ index += length();
+ if ( (uint)index > length() ) // bad index
+ return -1;
+ while( index >= 0 ) {
+ if ( rx.match( *this, index ) == index )
+ return index;
+ index--;
+ }
+ return -1;
+}
+
+/*!
+ Counts the number of overlapping occurrences of \a rx in the string.
+
+ Example:
+ \code
+ QString s = "banana and panama";
+ QRegExp r = QRegExp("a[nm]a", TRUE, FALSE);
+ s.contains( r ); // 4 matches
+ \endcode
+
+ \sa find() findRev()
+*/
+
+int QString::contains( const QRegExp &rx ) const
+{
+ if ( isEmpty() )
+ return rx.match( *this ) < 0 ? 0 : 1;
+ int count = 0;
+ int index = -1;
+ int len = length();
+ while ( index < len-1 ) { // count overlapping matches
+ index = rx.match( *this, index+1 );
+ if ( index < 0 )
+ break;
+ count++;
+ }
+ return count;
+}
+
+
+/*!
+ Replaces every occurrence of \a rx in the string with \a str.
+ Returns a reference to the string.
+
+ Examples:
+ \code
+ QString s = "banana";
+ s.replace( QRegExp("a.*a"), "" ); // becomes "b"
+
+ QString s = "banana";
+ s.replace( QRegExp("^[bn]a"), " " ); // becomes " nana"
+
+ QString s = "banana";
+ s.replace( QRegExp("^[bn]a"), "" ); // NOTE! becomes ""
+ \endcode
+
+ \sa find() findRev()
+*/
+
+QString &QString::replace( const QRegExp &rx, const QString &str )
+{
+ if ( isEmpty() )
+ return *this;
+ int index = 0;
+ int slen = str.length();
+ int len;
+ while ( index < (int)length() ) {
+ index = rx.match( *this, index, &len, FALSE );
+ if ( index >= 0 ) {
+ replace( index, len, str );
+ index += slen;
+ if ( !len )
+ break; // Avoid infinite loop on 0-length matches, e.g. [a-z]*
+ }
+ else
+ break;
+ }
+ return *this;
+}
+
+static bool
+ok_in_base( QChar c, int base )
+{
+ if ( base <= 10 )
+ return c.isDigit() && c.digitValue() < base;
+ else
+ return c.isDigit() || (c >= 'a' && c < char('a'+base-10))
+ || (c >= 'A' && c < char('A'+base-10));
+}
+
+/*!
+ Returns the string converted to a <code>long</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all, or if
+ it has trailing garbage.
+*/
+
+long QString::toLong( bool *ok, int base ) const
+{
+ const QChar *p = unicode();
+ long val=0;
+ int l = length();
+ const long max_mult = INT_MAX / base;
+ bool is_ok = FALSE;
+ int neg = 0;
+ if ( !p )
+ goto bye;
+ while ( l && p->isSpace() ) // skip leading space
+ l--,p++;
+ if ( l && *p == '-' ) {
+ l--;
+ p++;
+ neg = 1;
+ } else if ( *p == '+' ) {
+ l--;
+ p++;
+ }
+
+ // NOTE: toULong() code is similar
+ if ( !l || !ok_in_base(*p,base) )
+ goto bye;
+ while ( l && ok_in_base(*p,base) ) {
+ l--;
+ int dv;
+ if ( p->isDigit() ) {
+ dv = p->digitValue();
+ } else {
+ if ( *p >= 'a' && *p <= 'z' )
+ dv = *p - 'a' + 10;
+ else
+ dv = *p - 'A' + 10;
+ }
+ if ( val > max_mult || (val == max_mult && dv > (INT_MAX%base)+neg) )
+ goto bye;
+ val = base*val + dv;
+ p++;
+ }
+ if ( neg )
+ val = -val;
+ while ( l && p->isSpace() ) // skip trailing space
+ l--,p++;
+ if ( !l )
+ is_ok = TRUE;
+bye:
+ if ( ok )
+ *ok = is_ok;
+ return is_ok ? val : 0;
+}
+
+/*!
+ Returns the string converted to an <code>unsigned long</code>
+ value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all,
+ or if it has trailing garbage.
+*/
+
+ulong QString::toULong( bool *ok, int base ) const
+{
+ const QChar *p = unicode();
+ ulong val=0;
+ int l = length();
+ const ulong max_mult = 429496729; // UINT_MAX/10, rounded down
+ bool is_ok = FALSE;
+ if ( !p )
+ goto bye;
+ while ( l && p->isSpace() ) // skip leading space
+ l--,p++;
+ if ( *p == '+' )
+ l--,p++;
+
+ // NOTE: toLong() code is similar
+ if ( !l || !ok_in_base(*p,base) )
+ goto bye;
+ while ( l && ok_in_base(*p,base) ) {
+ l--;
+ uint dv;
+ if ( p->isDigit() ) {
+ dv = p->digitValue();
+ } else {
+ if ( *p >= 'a' && *p <= 'z' )
+ dv = *p - 'a' + 10;
+ else
+ dv = *p - 'A' + 10;
+ }
+ if ( val > max_mult || (val == max_mult && dv > (UINT_MAX%base)) )
+ goto bye;
+ val = base*val + dv;
+ p++;
+ }
+
+ while ( l && p->isSpace() ) // skip trailing space
+ l--,p++;
+ if ( !l )
+ is_ok = TRUE;
+bye:
+ if ( ok )
+ *ok = is_ok;
+ return is_ok ? val : 0;
+}
+
+/*!
+ Returns the string converted to a <code>short</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all, or if
+ it has trailing garbage.
+*/
+
+short QString::toShort( bool *ok, int base ) const
+{
+ long v = toLong( ok, base );
+ if ( ok && *ok && (v < -32768 || v > 32767) ) {
+ *ok = FALSE;
+ v = 0;
+ }
+ return (short)v;
+}
+
+/*!
+ Returns the string converted to an <code>unsigned short</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all, or if
+ it has trailing garbage.
+*/
+
+ushort QString::toUShort( bool *ok, int base ) const
+{
+ ulong v = toULong( ok, base );
+ if ( ok && *ok && (v > 65535) ) {
+ *ok = FALSE;
+ v = 0;
+ }
+ return (ushort)v;
+}
+
+
+/*!
+ Returns the string converted to a <code>int</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all,
+ or if it has trailing garbage.
+*/
+
+int QString::toInt( bool *ok, int base ) const
+{
+ return (int)toLong( ok, base );
+}
+
+/*!
+ Returns the string converted to an <code>unsigned int</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all,
+ or if it has trailing garbage.
+*/
+
+uint QString::toUInt( bool *ok, int base ) const
+{
+ return (uint)toULong( ok, base );
+}
+
+/*!
+ Returns the string converted to a <code>double</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no conceivable
+ errors, and FALSE if the string is not a number at all, or if it has
+ trailing garbage.
+*/
+
+double QString::toDouble( bool *ok ) const
+{
+ char *end;
+ const char *a = latin1();
+ double val = strtod( a ? a : "", &end );
+ if ( ok )
+ *ok = ( a && *a && ( end == 0 || *end == '\0' ) );
+ return val;
+}
+
+/*!
+ Returns the string converted to a <code>float</code> value.
+
+ If \a ok is non-null, \a *ok is set to TRUE if there are no
+ conceivable errors, and FALSE if the string is not a number at all,
+ or if it has trailing garbage.
+*/
+
+float QString::toFloat( bool *ok ) const
+{
+ return (float)toDouble( ok );
+}
+
+
+/*!
+ Sets the string to the printed value of \a n and returns a
+ reference to the string.
+
+ The value is converted to \a base notation (default is decimal).
+ The base must be a value from 2 to 36.
+*/
+
+QString &QString::setNum( long n, int base )
+{
+#if defined(CHECK_RANGE)
+ if ( base < 2 || base > 36 ) {
+ qWarning( "QString::setNum: Invalid base %d", base );
+ base = 10;
+ }
+#endif
+ char charbuf[65*sizeof(QChar)];
+ QChar *buf = (QChar*)charbuf;
+ QChar *p = &buf[64];
+ int len = 0;
+ bool neg;
+ if ( n < 0 ) {
+ neg = TRUE;
+ if ( n == INT_MIN ) {
+ // Cannot always negate this special case
+ QString s1, s2;
+ s1.setNum(n/base);
+ s2.setNum((-(n+base))%base);
+ *this = s1 + s2;
+ return *this;
+ }
+ n = -n;
+ } else {
+ neg = FALSE;
+ }
+ do {
+ *--p = "0123456789abcdefghijklmnopqrstuvwxyz"[((int)(n%base))];
+ n /= base;
+ len++;
+ } while ( n );
+ if ( neg ) {
+ *--p = '-';
+ len++;
+ }
+ return setUnicode( p, len );
+}
+
+/*!
+ Sets the string to the printed unsigned value of \a n and
+ returns a reference to the string.
+
+ The value is converted to \a base notation (default is decimal).
+ The base must be a value from 2 to 36.
+*/
+
+QString &QString::setNum( ulong n, int base )
+{
+#if defined(CHECK_RANGE)
+ if ( base < 2 || base > 36 ) {
+ qWarning( "QString::setNum: Invalid base %d", base );
+ base = 10;
+ }
+#endif
+ char charbuf[65*sizeof(QChar)];
+ QChar *buf = (QChar*)charbuf;
+ QChar *p = &buf[64];
+ int len = 0;
+ do {
+ *--p = "0123456789abcdefghijklmnopqrstuvwxyz"[((int)(n%base))];
+ n /= base;
+ len++;
+ } while ( n );
+ return setUnicode(p,len);
+}
+
+/*!
+ \fn QString &QString::setNum( int n, int base )
+ Sets the string to the printed value of \a n and returns a reference
+ to the string.
+*/
+
+/*!
+ \fn QString &QString::setNum( uint n, int base )
+ Sets the string to the printed unsigned value of \a n and returns a
+ reference to the string.
+*/
+
+/*!
+ \fn QString &QString::setNum( short n, int base )
+ Sets the string to the printed value of \a n and returns a reference
+ to the string.
+*/
+
+/*!
+ \fn QString &QString::setNum( ushort n, int base )
+ Sets the string to the printed unsigned value of \a n and returns a
+ reference to the string.
+*/
+
+/*! Sets the string to the printed value of \a n, formatted in the \a f
+ format with \a prec precision, and returns a reference to the
+ string.
+
+ \a f can be 'f', 'F', 'e', 'E', 'g' or 'G', all of which have the
+ same meaning as for sprintf().
+*/
+
+QString &QString::setNum( double n, char f, int prec )
+{
+#if defined(CHECK_RANGE)
+ if ( !(f=='f' || f=='F' || f=='e' || f=='E' || f=='g' || f=='G') ) {
+ qWarning( "QString::setNum: Invalid format char '%c'", f );
+ f = 'f';
+ }
+#endif
+ char format[20];
+ char buf[120]; // enough for 99 precision?
+ char *fs = format; // generate format string
+ *fs++ = '%'; // "%.<prec>l<f>"
+ if ( prec >= 0 ) {
+ if ( prec > 99 ) // buf big enough for precision?
+ prec = 99;
+ *fs++ = '.';
+ if ( prec >= 10 ) {
+ *fs++ = prec / 10 + '0';
+ *fs++ = prec % 10 + '0';
+ } else {
+ *fs++ = prec + '0';
+ }
+ }
+ *fs++ = 'l';
+ *fs++ = f;
+ *fs = '\0';
+ ::sprintf( buf, format, n );
+ return setLatin1(buf);
+}
+
+/*!
+ \overload QString &QString::setNum( float n, char f, int prec )
+*/
+
+
+/*!
+ A convenience factory function that returns a string representation
+ of the number \a n.
+
+ \sa setNum()
+ */
+QString QString::number( long n, int base )
+{
+ QString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ A convenience factory function that returns a string representation
+ of the number \a n.
+
+ \sa setNum()
+ */
+QString QString::number( ulong n, int base )
+{
+ QString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ A convenience factory function that returns a string representation
+ of the number \a n.
+
+ \sa setNum()
+ */
+QString QString::number( int n, int base )
+{
+ QString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ A convenience factory function that returns a string representation
+ of the number \a n.
+
+ \sa setNum()
+ */
+QString QString::number( uint n, int base )
+{
+ QString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ This static function returns the printed value of \a n, formatted in the \f
+ format with \a prec precision.
+
+ \a f can be 'f', 'F', 'e', 'E', 'g' or 'G', all of which have the
+ same meaning as for sprintf().
+
+ \sa setNum()
+ */
+QString QString::number( double n, char f, int prec )
+{
+ QString s;
+ s.setNum( n, f, prec );
+ return s;
+}
+
+
+/*! \obsolete
+
+ Sets the character at position \a index to \a c and expands the
+ string if necessary, filling with spaces.
+
+ This method is redundant in Qt 2.x, because operator[] will expand
+ the string as necessary.
+*/
+
+void QString::setExpand( uint index, QChar c )
+{
+ int spaces = index - d->len;
+ at(index) = c;
+ while (spaces-->0)
+ d->unicode[--index]=' ';
+}
+
+
+/*!
+ \fn const char* QString::data() const
+
+ \obsolete
+
+ Returns a pointer to a 0-terminated classic C string.
+
+ In Qt 1.x, this returned a char* allowing direct manipulation of the
+ string as a sequence of bytes. In Qt 2.x where QString is a Unicode
+ string, char* conversion constructs a temporary string, and hence
+ direct character operations are meaningless.
+*/
+
+/*!
+ \fn bool QString::operator!() const
+ Returns TRUE if it is a null string, otherwise FALSE. Thus
+ you can write:
+
+\code
+ QString name = getName();
+ if ( !name )
+ name = "Rodney";
+\endcode
+
+ Note that if you say:
+
+\code
+ QString name = getName();
+ if ( name )
+ doSomethingWith(name);
+\endcode
+
+ Then this will call <tt>operator const char*()</tt>, which will do what
+ you want, but rather inefficiently - you may wish to define the macro
+ QT_NO_ASCII_CAST when writing code which you wish to strictly remain
+ Unicode-clean.
+
+ When you want the above semantics, use <tt>!isNull()</tt>
+ or even <tt>!!</tt>:
+
+\code
+ QString name = getName();
+ if ( !!name )
+ doSomethingWith(name);
+\endcode
+*/
+
+
+/*!
+ \fn QString& QString::append( const QString& str )
+ Appends \a str to the string and returns a reference to the result.
+ Equivalent to operator+=().
+ */
+
+/*!
+ \fn QString& QString::append( char ch )
+ Appends \a ch to the string and returns a reference to the result.
+ Equivalent to operator+=().
+ */
+
+/*!
+ \fn QString& QString::append( QChar ch )
+ Appends \a ch to the string and returns a reference to the result.
+ Equivalent to operator+=().
+ */
+
+/*!
+ Appends \a str to the string and returns a reference to the string.
+*/
+QString& QString::operator+=( const QString &str )
+{
+ uint len1 = length();
+ uint len2 = str.length();
+ if ( len2 ) {
+ setLength(len1+len2);
+ memcpy( d->unicode+len1, str.unicode(), sizeof(QChar)*len2 );
+ } else if ( isNull() && !str.isNull() ) { // ## just for 1.x compat:
+ *this = fromLatin1("");
+ }
+ return *this;
+}
+
+/*!
+ Appends \a c to the string and returns a reference to the string.
+*/
+
+QString &QString::operator+=( QChar c )
+{
+ setLength(length()+1);
+ d->unicode[length()-1] = c;
+ return *this;
+}
+
+/*!
+ Appends \a c to the string and returns a reference to the string.
+*/
+
+QString &QString::operator+=( char c )
+{
+ setLength(length()+1);
+ d->unicode[length()-1] = c;
+ return *this;
+}
+
+
+
+/*! \fn char QChar::latin1() const
+
+ Returns a latin-1 copy of this character, if this character is in
+ the latin-1 character set. If not, this function returns 0.
+*/
+
+
+/*!
+ Returns a Latin-1 representation of the string. Note that the returned
+ value is undefined if the string contains non-Latin-1 characters. If you
+ want to convert strings into formats other than Unicode, see the
+ QTextCodec classes.
+
+ This function is mainly useful for boot-strapping legacy code to
+ use Unicode.
+
+ The result remains valid so long as one unmodified
+ copy of the source string exists.
+
+ \sa utf8(), local8Bit()
+*/
+const char* QString::latin1() const
+{
+ if ( d->ascii ) {
+ if ( d->dirtyascii )
+ delete [] d->ascii;
+ else
+ return d->ascii;
+ }
+ Q2HELPER(stat_get_ascii++)
+ Q2HELPER(stat_get_ascii_size+=d->len)
+ d->ascii = unicodeToAscii( d->unicode, d->len );
+ d->dirtyascii = 0;
+ return d->ascii;
+}
+
+/*! \obsolete
+
+ This functions simply calls latin1() and returns the result.
+*/
+const char* QString::ascii() const
+{
+ return latin1();
+}
+
+#ifndef QT_NO_TEXTCODEC
+/*!
+ Returns the string encoded in UTF8 format.
+
+ See QTextCodec for more diverse coding/decoding of Unicode strings.
+
+ \sa QString::fromUtf8(), local8Bit(), latin1()
+*/
+QCString QString::utf8() const
+{
+ static QTextCodec* codec = QTextCodec::codecForMib(106);
+ return codec
+ ? codec->fromUnicode(*this)
+ : QCString(latin1());
+}
+
+/*!
+ Returns the unicode string decoded from the
+ first \a len bytes of \a utf8. If \a len is -1 (the default), the
+ length of \a utf8 is used. If trailing partial characters are in
+ \a utf8, they are ignored.
+
+ See QTextCodec for more diverse coding/decoding of Unicode strings.
+*/
+QString QString::fromUtf8(const char* utf8, int len)
+{
+ static QTextCodec* codec = QTextCodec::codecForMib(106);
+ if ( len < 0 ) len = qstrlen(utf8);
+ return codec
+ ? codec->toUnicode(utf8, len)
+ : QString::fromLatin1(utf8, len);
+}
+#endif // QT_NO_TEXTCODEC
+/*!
+ Creates a QString from Latin1 text. This is the same as the
+ QString(const char*) constructor, but you can make that constructor
+ invisible if you compile with the define QT_NO_CAST_ASCII, in which
+ case you can explicitly create a QString from Latin-1 text using
+ this function.
+*/
+QString QString::fromLatin1(const char* chars, int len)
+{
+ uint l;
+ QChar *uc;
+ if ( len < 0 ) {
+ uc = internalAsciiToUnicode(chars,&l);
+ } else {
+ uc = internalAsciiToUnicode(chars,&l,len);
+ }
+ return QString(new QStringData(uc,l,l), TRUE);
+}
+
+/*!
+ \fn const QChar* QString::unicode() const
+
+ Returns the Unicode representation of the string. The result
+ remains valid until the string is modified.
+*/
+
+/*!
+ Returns the string encoded in a locale-specific format. On X11, this
+ is the QTextCodec::codecForLocale(). On Windows, it is a system-defined
+ encoding.
+
+ See QTextCodec for more diverse coding/decoding of Unicode strings.
+
+ \sa QString::fromLocal8Bit(), latin1(), utf8()
+*/
+
+
+QCString QString::local8Bit() const
+{
+#ifdef QT_NO_TEXTCODEC
+ return latin1();
+#else
+#ifdef _WS_X11_
+ static QTextCodec* codec = QTextCodec::codecForLocale();
+ return codec
+ ? codec->fromUnicode(*this)
+ : QCString(latin1());
+#endif
+#ifdef _WS_MAC_
+ static QTextCodec* codec = QTextCodec::codecForLocale();
+ return codec
+ ? codec->fromUnicode(*this)
+ : QCString(latin1());
+#endif
+#ifdef _WS_WIN_
+ return qt_winQString2MB( *this );
+#endif
+#ifdef _WS_QWS_
+ return utf8(); // ##### if there is ANY 8 bit format supported?
+#endif
+#endif
+}
+
+/*!
+ Returns the unicode string decoded from the
+ first \a len bytes of \a local8Bit. If \a len is -1 (the default), the
+ length of \a local8Bit is used. If trailing partial characters are in
+ \a local8Bit, they are ignored.
+
+ \a local8Bit is assumed to be encoded in a locale-specific format.
+
+ See QTextCodec for more diverse coding/decoding of Unicode strings.
+*/
+QString QString::fromLocal8Bit(const char* local8Bit, int len)
+{
+#ifdef QT_NO_TEXTCODEC
+ return fromLatin1( local8Bit, len );
+#else
+
+ if ( !local8Bit )
+ return QString::null;
+#ifdef _WS_X11_
+ static QTextCodec* codec = QTextCodec::codecForLocale();
+ if ( len < 0 ) len = qstrlen(local8Bit);
+ return codec
+ ? codec->toUnicode(local8Bit, len)
+ : QString::fromLatin1(local8Bit,len);
+#endif
+#ifdef _WS_MAC_
+ static QTextCodec* codec = QTextCodec::codecForLocale();
+ if ( len < 0 ) len = qstrlen(local8Bit);
+ return codec
+ ? codec->toUnicode(local8Bit, len)
+ : QString::fromLatin1(local8Bit,len);
+#endif
+// Should this be OS_WIN32?
+#ifdef _WS_WIN_
+ if ( len >= 0 ) {
+ QCString s(local8Bit,len+1);
+ return qt_winMB2QString(s);
+ }
+ return qt_winMB2QString( local8Bit );
+#endif
+#ifdef _WS_QWS_
+ return fromUtf8(local8Bit,len);
+#endif
+#endif // QT_NO_TEXTCODEC
+}
+
+/*!
+ \fn QString::operator const char *() const
+
+ Returns latin1(). Be sure to see the warnings documented there.
+ Note that for new code which you wish to be strictly Unicode-clean,
+ you can define the macro QT_NO_ASCII_CAST when compiling your code
+ to hide this function so that automatic casts are not done. This
+ has the added advantage that you catch the programming error
+ described under operator!().
+*/
+
+/*!
+ \fn QChar QString::at( uint ) const
+
+ Returns the character at \a i, or 0 if \a i is beyond the length
+ of the string.
+
+ Note: If this QString is not const or const&, the non-const at()
+ will be used instead, which will expand the string if \a i is beyond
+ the length of the string.
+*/
+
+/*!
+ \fn QChar QString::constref(uint i) const
+ Equivalent to at(i), this returns the QChar at \a i by value.
+
+ \sa ref()
+*/
+
+/*!
+ \fn QChar& QString::ref(uint i)
+ Returns the QChar at \a i by reference.
+
+ \sa constref()
+*/
+
+/*!
+ \fn QChar QString::operator[](int) const
+
+ Returns the character at \a i, or QChar::null if \a i is beyond the
+ length of the string.
+
+ Note: If this QString is not const or const&, the non-const operator[]
+ will be used instead, which will expand the string if \a i is beyond
+ the length of the string.
+*/
+
+/*!
+ \fn QCharRef QString::operator[](int)
+
+ Returns an object that references the character at \a i.
+ This reference
+ can then be assigned to, or otherwise used immediately, but
+ becomes invalid once further modifications are made to the string.
+ The QCharRef internal class can be used much like a constant QChar, but
+ if you assign to it, you change the original string (which enlarges
+ and detaches itself). You will get compilation errors if you try to
+ use the result as anything but a QChar.
+*/
+
+/*!
+ \fn QCharRef QString::at( uint i )
+ Returns a reference to the character at \a i, expanding
+ the string with QChar::null if necessary. The resulting reference
+ can then be assigned to, or otherwise used immediately, but
+ becomes invalid once further modifications are made to the string.
+*/
+
+/*!
+ Internal chunk of code to handle the
+ uncommon cases of at() above.
+*/
+void QString::subat( uint i )
+{
+ uint olen = d->len;
+ if ( i >= olen ) {
+ setLength( i+1 ); // i is index; i+1 is needed length
+ for ( uint j=olen; j<=i; j++ )
+ d->unicode[j] = QChar::null;
+ } else {
+ // Just be sure to detach
+ real_detach();
+ }
+}
+
+
+/*!
+ Resizes the string to \a len unicode characters and copies \a unicode
+ into the string. If \a unicode is null, nothing is copied, but the
+ string is resized to \a len anyway. If \a len is zero, the string
+ becomes a \link isNull() null\endlink string.
+
+ \sa setLatin1(), isNull()
+*/
+
+QString& QString::setUnicode( const QChar *unicode, uint len )
+{
+ if ( len == 0 ) { // set to null string
+ if ( d != shared_null ) { // beware of nullstring being set to nullstring
+ deref();
+ d = shared_null ? shared_null : makeSharedNull();
+ }
+ } else if ( d->count != 1 || len > d->maxl ||
+ ( len*4 < d->maxl && d->maxl > 4 ) ) { // detach, grown or shrink
+ Q2HELPER(stat_copy_on_write++)
+ Q2HELPER(stat_copy_on_write_size+=d->len)
+ uint newMax = 4;
+ while ( newMax < len )
+ newMax *= 2;
+ QChar* nd = QT_ALLOC_QCHAR_VEC( newMax );
+ if ( unicode )
+ memcpy( nd, unicode, sizeof(QChar)*len );
+ deref();
+ d = new QStringData( nd, len, newMax );
+ } else {
+ d->len = len;
+ d->dirtyascii = 1;
+ if ( unicode )
+ memcpy( d->unicode, unicode, sizeof(QChar)*len );
+ }
+ return *this;
+}
+
+/*!
+ Resizes the string to \a len unicode characters and copies
+ \a unicode_as_ushorts into the string (on some X11 client
+ platforms this will involve a byte-swapping pass).
+
+ If \a unicode is null, nothing is copied, but the
+ string is resized to \a len anyway. If \a len is zero, the string
+ becomes a \link isNull() null\endlink string.
+
+ \sa setLatin1(), isNull()
+*/
+QString& QString::setUnicodeCodes( const ushort* unicode_as_ushorts, uint len )
+{
+ setUnicode((const QChar*)unicode_as_ushorts, len);
+ QChar t(0x1234);
+ if ( unicode_as_ushorts && *((ushort*)&t) == 0x3412 ) {
+ // Need to byteswap
+ char* b = (char*)d->unicode;
+ while ( len-- ) {
+ char c = b[0];
+ b[0] = b[1];
+ b[1] = c;
+ b += sizeof(QChar);
+ }
+ }
+ return *this;
+}
+
+
+/*!
+ Sets this string to \a str, interpreted as a classic Latin 1 C string.
+ If the \a len argument is negative (default), it is set to strlen(str).
+
+ If \a str is 0 a null string is created. If \a str is "" an empty
+ string is created.
+
+ \sa isNull(), isEmpty()
+*/
+
+QString &QString::setLatin1( const char *str, int len )
+{
+ if ( str == 0 )
+ return setUnicode(0,0);
+ if ( len < 0 )
+ len = qstrlen(str);
+ if ( len == 0 ) { // won't make a null string
+ deref();
+ uint l;
+ QChar *uc = internalAsciiToUnicode(str,&l);
+ d = new QStringData(uc,l,l);
+ } else {
+ setUnicode( 0, len ); // resize but not copy
+ QChar *p = d->unicode;
+ while ( len-- )
+ *p++ = *str++;
+ }
+ return *this;
+}
+
+
+/*!
+ \fn int QString::compare (const QString & s1, const QString & s2)
+
+ Compare \a s1 to \a s2 returning an integer less than, equal to, or
+ greater than zero if s1 is, respectively, lexically less than, equal to,
+ or greater than s2.
+*/
+
+/*!
+ Compares this string to \a s, returning an integer less than, equal to, or
+ greater than zero if it is, respectively, lexically less than, equal to,
+ or greater than \a s.
+*/
+int QString::compare( const QString& s ) const
+{
+ return ucstrcmp(*this,s);
+}
+
+bool operator==( const QString &s1, const QString &s2 )
+{
+ return (s1.length() == s2.length()) && s1.isNull() == s2.isNull() &&
+ (memcmp((char*)s1.unicode(),(char*)s2.unicode(),
+ s1.length()*sizeof(QChar)) ==0);
+}
+
+bool operator!=( const QString &s1, const QString &s2 )
+{ return !(s1==s2); }
+
+bool operator<( const QString &s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) < 0; }
+
+bool operator<=( const QString &s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) <= 0; }
+
+bool operator>( const QString &s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) > 0; }
+
+bool operator>=( const QString &s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) >= 0; }
+
+
+bool operator==( const QString &s1, const char *s2 )
+{ return s1==QString(s2); }
+
+bool operator==( const char *s1, const QString &s2 )
+{ return QString(s1)==s2; }
+
+bool operator!=( const QString &s1, const char *s2 )
+{ return !(s1==s2); }
+
+bool operator!=( const char *s1, const QString &s2 )
+{ return !(s1==s2); }
+
+bool operator<( const QString &s1, const char *s2 )
+{ return ucstrcmp(s1,s2) < 0; }
+
+bool operator<( const char *s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) < 0; }
+
+bool operator<=( const QString &s1, const char *s2 )
+{ return ucstrcmp(s1,s2) <= 0; }
+
+bool operator<=( const char *s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) <= 0; }
+
+bool operator>( const QString &s1, const char *s2 )
+{ return ucstrcmp(s1,s2) > 0; }
+
+bool operator>( const char *s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) > 0; }
+
+bool operator>=( const QString &s1, const char *s2 )
+{ return ucstrcmp(s1,s2) >= 0; }
+
+bool operator>=( const char *s1, const QString &s2 )
+{ return ucstrcmp(s1,s2) >= 0; }
+
+
+/*****************************************************************************
+ Documentation for QString related functions
+ *****************************************************************************/
+
+/*!
+ \fn bool operator==( const QString &s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if the two strings are equal, or FALSE if they are different.
+ A null string is different from an empty, non-null string.
+
+ Equivalent to <code>qstrcmp(s1,s2) == 0</code>.
+*/
+
+/*!
+ \fn bool operator==( const QString &s1, const char *s2 )
+ \relates QString
+ Returns TRUE if the two strings are equal, or FALSE if they are different.
+
+ Equivalent to <code>qstrcmp(s1,s2) == 0</code>.
+*/
+
+/*!
+ \fn bool operator==( const char *s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if the two strings are equal, or FALSE if they are different.
+
+ Equivalent to <code>qstrcmp(s1,s2) == 0</code>.
+*/
+
+/*!
+ \fn bool operator!=( const QString &s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if the two strings are different, or FALSE if they are equal.
+
+ Equivalent to <code>qstrcmp(s1,s2) != 0</code>.
+*/
+
+/*!
+ \fn bool operator!=( const QString &s1, const char *s2 )
+ \relates QString
+ Returns TRUE if the two strings are different, or FALSE if they are equal.
+
+ Equivalent to <code>qstrcmp(s1,s2) != 0</code>.
+*/
+
+/*!
+ \fn bool operator!=( const char *s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if the two strings are different, or FALSE if they are equal.
+
+ Equivalent to <code>qstrcmp(s1,s2) != 0</code>.
+*/
+
+/*!
+ \fn bool operator<( const QString &s1, const char *s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically less than \a s2, otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \< 0</code>.
+*/
+
+/*!
+ \fn bool operator<( const char *s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically less than \a s2, otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \< 0</code>.
+*/
+
+/*!
+ \fn bool operator<=( const QString &s1, const char *s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically less than or equal to \a s2,
+ otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \<= 0</code>.
+*/
+
+/*!
+ \fn bool operator<=( const char *s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically less than or equal to \a s2,
+ otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \<= 0</code>.
+*/
+
+/*!
+ \fn bool operator>( const QString &s1, const char *s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically greater than \a s2, otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \> 0</code>.
+*/
+
+/*!
+ \fn bool operator>( const char *s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically greater than \a s2, otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \> 0</code>.
+*/
+
+/*!
+ \fn bool operator>=( const QString &s1, const char *s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically greater than or equal to \a s2,
+ otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \>= 0</code>.
+*/
+
+/*!
+ \fn bool operator>=( const char *s1, const QString &s2 )
+ \relates QString
+ Returns TRUE if \a s1 is alphabetically greater than or equal to \a s2,
+ otherwise FALSE.
+
+ Equivalent to <code>qstrcmp(s1,s2) \>= 0</code>.
+*/
+
+/*!
+ \fn QString operator+( const QString &s1, const QString &s2 )
+ \relates QString
+ Returns the concatenated string of s1 and s2.
+*/
+
+/*!
+ \fn QString operator+( const QString &s1, const char *s2 )
+ \relates QString
+ Returns the concatenated string of s1 and s2.
+*/
+
+/*!
+ \fn QString operator+( const char *s1, const QString &s2 )
+ \relates QString
+ Returns the concatenated string of s1 and s2.
+*/
+
+/*!
+ \fn QString operator+( const QString &s, char c )
+ \relates QString
+ Returns the concatenated string of s and c.
+*/
+
+/*!
+ \fn QString operator+( char c, const QString &s )
+ \relates QString
+ Returns the concatenated string of c and s.
+*/
+
+
+/*****************************************************************************
+ QString stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+/*!
+ \relates QString
+ Writes a string to the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator<<( QDataStream &s, const QString &str )
+{
+ if ( s.version() == 1 ) {
+ QCString l( str.latin1() );
+ s << l;
+ }
+ else {
+ const char* ub = (const char*)str.unicode();
+ if ( ub || s.version() < 3 ) {
+ if ( QChar::networkOrdered() ==
+ (s.byteOrder()==QDataStream::BigEndian) ) {
+ s.writeBytes( ub, sizeof(QChar)*str.length() );
+ } else {
+ static const uint auto_size = 1024;
+ char t[auto_size];
+ char *b;
+ if ( str.length()*sizeof(QChar) > auto_size ) {
+ b = new char[str.length()*sizeof(QChar)];
+ } else {
+ b = t;
+ }
+ int l = str.length();
+ char *c=b;
+ while ( l-- ) {
+ *c++ = ub[1];
+ *c++ = ub[0];
+ ub+=sizeof(QChar);
+ }
+ s.writeBytes( b, sizeof(QChar)*str.length() );
+ if ( str.length()*sizeof(QChar) > auto_size )
+ delete [] b;
+ }
+ } else {
+ // write null marker
+ s << (Q_UINT32)0xffffffff;
+ }
+ }
+ return s;
+}
+
+/*!
+ \relates QString
+ Reads a string from the stream.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+
+QDataStream &operator>>( QDataStream &s, QString &str )
+{
+#ifdef QT_QSTRING_UCS_4
+#warning "operator>> not working properly"
+#endif
+ if ( s.version() == 1 ) {
+ QCString l;
+ s >> l;
+ str = QString( l );
+ }
+ else {
+ Q_UINT32 bytes;
+ s >> bytes; // read size of string
+ if ( bytes == 0xffffffff ) { // null string
+ str = QString::null;
+ } else if ( bytes > 0 ) { // not empty
+ str.setLength( bytes/2 );
+ char* b = (char*)str.d->unicode;
+ s.readRawBytes( b, bytes );
+ if ( QChar::networkOrdered() !=
+ (s.byteOrder()==QDataStream::BigEndian) ) {
+ bytes /= 2;
+ while ( bytes-- ) {
+ char c = b[0];
+ b[0] = b[1];
+ b[1] = c;
+ b += 2;
+ }
+ }
+ } else {
+ str = "";
+ }
+ }
+ return s;
+}
+#endif // QT_NO_DATASTREAM
+
+/*****************************************************************************
+ QConstString member functions
+ *****************************************************************************/
+
+/*!
+ \class QConstString qstring.h
+ \brief A QString which uses constant Unicode data.
+
+ In order to minimize copying, highly optimized applications can use
+ QConstString to provide a QString-compatible object from existing
+ Unicode data. It is then the user's responsibility to make sure
+ that the Unicode data must exist for the entire lifetime of the
+ QConstString object.
+*/
+
+/*!
+ Constructs a QConstString that uses the first \a length Unicode
+ characters in the array \a unicode. Any attempt to modify
+ copies of the string will cause it to create a copy of the
+ data, thus it remains forever unmodified.
+
+ Note that \a unicode is \e not \e copied. The caller \e must be
+ able to guarantee that \a unicode will not be deleted or
+ modified. Since that is generally not the case with \c const strings
+ (they are references), this constructor demands a non-const pointer
+ even though it never modifies \a unicode.
+*/
+QConstString::QConstString( QChar* unicode, uint length ) :
+ QString(new QStringData(unicode, length, length),TRUE)
+{
+}
+
+/*!
+ Destroys the QConstString, creating a copy of the data if
+ other strings are still using it.
+*/
+QConstString::~QConstString()
+{
+ if ( d->count > 1 ) {
+ QChar* cp = QT_ALLOC_QCHAR_VEC( d->len );
+ memcpy( cp, d->unicode, d->len*sizeof(QChar) );
+ d->unicode = cp;
+ } else {
+ d->unicode = 0;
+ }
+
+ // The original d->unicode is now unlinked.
+}
+
+/*!
+ \fn const QString& QConstString::string() const
+
+ Returns a constant string referencing the data passed during
+ construction.
+*/
+
+/*!
+ Returns whether the strings starts with \a s, or not.
+ */
+bool QString::startsWith( const QString& s ) const
+{
+ for ( int i =0; i < (int) s.length(); i++ ) {
+ if ( i >= (int) length() || d->unicode[i] != s[i] )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+
+#if defined(_OS_WIN32_)
+
+#include <windows.h>
+
+/*!
+ Returns a static Windows TCHAR* from a QString, possibly adding NUL.
+
+ The lifetime of the return value is until the next call to this function.
+*/
+const void* qt_winTchar(const QString& str_in, bool addnul)
+{
+ // So that the return value lives long enough.
+ static QString str;
+ str = str_in;
+
+#ifdef UNICODE
+ static uint buflen = 256;
+ static TCHAR *buf = new TCHAR[buflen];
+
+ const QChar* uc = str.unicode();
+
+#define EXTEND if (str.length() > buflen) { delete buf; buf = new TCHAR[buflen=str.length()+1]; }
+
+#if defined(_WS_X11_) || defined(_OS_WIN32_BYTESWAP_)
+ EXTEND
+ for ( int i=str.length(); i--; )
+ buf[i] = uc[i].row() << 8 | uc[i].cell();
+ if ( addnul )
+ buf[str.length()] = 0;
+#else
+ // Same endianness of TCHAR
+ if ( addnul ) {
+ EXTEND
+ memcpy(buf,uc,sizeof(TCHAR)*str.length());
+ buf[str.length()] = 0;
+ } else {
+ return uc;
+ }
+#endif
+ return buf;
+#undef EXTEND
+
+#else
+ return str.latin1();
+#endif
+}
+
+/*!
+ Makes a new null terminated Windows TCHAR* from a QString.
+*/
+void* qt_winTchar_new(const QString& str)
+{
+ TCHAR* result = new TCHAR[str.length()+1];
+ memcpy(result, qt_winTchar(str,FALSE), sizeof(TCHAR)*str.length());
+ result[str.length()] = 0;
+ return result;
+}
+
+/*!
+ Makes a QString from a Windows TCHAR*.
+*/
+QString qt_winQString(void* tc)
+{
+#ifdef UNICODE
+
+ int len=0;
+ while ( ((TCHAR*)tc)[len] )
+ len++;
+#if defined(_WS_X11_) || defined(_OS_WIN32_BYTESWAP_)
+ QString r;
+ for ( int i=0; i<len; i++ )
+ r += QChar(((TCHAR*)tc)[i]&0xff,((TCHAR*)tc)[i]>>8);
+ return r;
+#else
+ // Same endianness of TCHAR
+ return QString((QChar*)tc,len);
+#endif
+#undef EXTEND
+#else
+ return (TCHAR*)tc;
+#endif
+}
+
+QCString qt_winQString2MB( const QString& s, int uclen )
+{
+ if ( uclen < 0 )
+ uclen = s.length();
+ if ( uclen == 0 )
+ return QCString();
+ BOOL used_def;
+ QCString mb(4096);
+ int len;
+ while ( !(len=WideCharToMultiByte(CP_ACP, 0, (const WCHAR*)s.unicode(), uclen,
+ mb.data(), mb.size()-1, 0, &used_def)) )
+ {
+ int r = GetLastError();
+ if ( r == ERROR_INSUFFICIENT_BUFFER ) {
+ mb.resize(1+WideCharToMultiByte( CP_ACP, 0,
+ (const WCHAR*)s.unicode(), uclen,
+ 0, 0, 0, &used_def));
+ // and try again...
+ } else {
+ // Fail.
+ qWarning("WideCharToMultiByte cannot convert multibyte text (error %d): %s (UTF8)",
+ r, s.utf8().data());
+ break;
+ }
+ }
+ mb[len]='\0';
+ return mb;
+}
+
+// WATCH OUT: mblen must include the NUL (or just use -1)
+QString qt_winMB2QString( const char* mb, int mblen )
+{
+ if ( !mb || !mblen )
+ return QString::null;
+ const int wclen_auto = 4096;
+ WCHAR wc_auto[wclen_auto];
+ int wclen = wclen_auto;
+ WCHAR *wc = wc_auto;
+ int len;
+ while ( !(len=MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
+ mb, mblen, wc, wclen )) )
+ {
+ int r = GetLastError();
+ if ( r == ERROR_INSUFFICIENT_BUFFER ) {
+ if ( wc != wc_auto ) {
+ qWarning("Size changed in MultiByteToWideChar");
+ break;
+ } else {
+ wclen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
+ mb, mblen, 0, 0 );
+ wc = new WCHAR[wclen];
+ // and try again...
+ }
+ } else {
+ // Fail.
+ qWarning("MultiByteToWideChar cannot convert multibyte text");
+ break;
+ }
+ }
+ if ( len <= 0 )
+ return QString::null;
+ QString s( (QChar*)wc, len-1 ); // len-1: we don't want terminator
+ if ( wc != wc_auto )
+ delete [] wc;
+ return s;
+}
+
+
+#endif // _OS_WIN32_
diff --git a/qtools/qstring.h b/qtools/qstring.h
new file mode 100644
index 0000000..f955f32
--- /dev/null
+++ b/qtools/qstring.h
@@ -0,0 +1,821 @@
+/****************************************************************************
+**
+**
+** Definition of the QString class, and related Unicode
+** functions.
+**
+** Created : 920609
+**
+** Copyright (C) 1992-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 QSTRING_H
+#define QSTRING_H
+
+#ifndef QT_H
+#include "qcstring.h"
+#endif // QT_H
+
+
+/*****************************************************************************
+ QString class
+ *****************************************************************************/
+
+class QRegExp;
+class QString;
+class QCharRef;
+
+class Q_EXPORT Q_PACKED QChar {
+public:
+ QChar();
+ QChar( char c );
+ QChar( uchar c );
+ QChar( uchar c, uchar r );
+ QChar( const QChar& c );
+ QChar( ushort rc );
+ QChar( short rc );
+ QChar( uint rc );
+ QChar( int rc );
+
+ QT_STATIC_CONST QChar null; // 0000
+ QT_STATIC_CONST QChar replacement; // FFFD
+ QT_STATIC_CONST QChar byteOrderMark; // FEFF
+ QT_STATIC_CONST QChar byteOrderSwapped; // FFFE
+ QT_STATIC_CONST QChar nbsp; // 00A0
+
+ // Unicode information
+
+ enum Category
+ {
+ NoCategory,
+
+ Mark_NonSpacing, // Mn
+ Mark_SpacingCombining, // Mc
+ Mark_Enclosing, // Me
+
+ Number_DecimalDigit, // Nd
+ Number_Letter, // Nl
+ Number_Other, // No
+
+ Separator_Space, // Zs
+ Separator_Line, // Zl
+ Separator_Paragraph, // Zp
+
+ Other_Control, // Cc
+ Other_Format, // Cf
+ Other_Surrogate, // Cs
+ Other_PrivateUse, // Co
+ Other_NotAssigned, // Cn
+
+ Letter_Uppercase, // Lu
+ Letter_Lowercase, // Ll
+ Letter_Titlecase, // Lt
+ Letter_Modifier, // Lm
+ Letter_Other, // Lo
+
+ Punctuation_Connector, // Pc
+ Punctuation_Dask, // Pd
+ Punctuation_Open, // Ps
+ Punctuation_Close, // Pe
+ Punctuation_InitialQuote, // Pi
+ Punctuation_FinalQuote, // Pf
+ Punctuation_Other, // Po
+
+ Symbol_Math, // Sm
+ Symbol_Currency, // Sc
+ Symbol_Modifier, // Sk
+ Symbol_Other // So
+ };
+
+ enum Direction
+ {
+ DirL, DirR, DirEN, DirES, DirET, DirAN, DirCS, DirB, DirS, DirWS, DirON,
+ DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN
+ };
+
+ enum Decomposition
+ {
+ Single, Canonical, Font, NoBreak, Initial, Medial,
+ Final, Isolated, Circle, Super, Sub, Vertical,
+ Wide, Narrow, Small, Square, Compat, Fraction
+ };
+
+ enum Joining
+ {
+ OtherJoining, Dual, Right, Center
+ };
+
+ // ****** WHEN ADDING FUNCTIONS, CONSIDER ADDING TO QCharRef TOO
+
+ int digitValue() const;
+ QChar lower() const;
+ QChar upper() const;
+
+ Category category() const;
+ Direction direction() const;
+ Joining joining() const;
+ bool mirrored() const;
+ QChar mirroredChar() const;
+ QString decomposition() const;
+ Decomposition decompositionTag() const;
+
+ char latin1() const { return rw ? 0 : cl; }
+ ushort unicode() const { return (rw << 8) | cl; }
+#ifndef QT_NO_CAST_ASCII
+ // like all ifdef'd code this is undocumented
+ operator char() const { return latin1(); }
+#endif
+
+ bool isNull() const { return unicode()==0; }
+ bool isPrint() const;
+ bool isPunct() const;
+ bool isSpace() const;
+ bool isMark() const;
+ bool isLetter() const;
+ bool isNumber() const;
+ bool isLetterOrNumber() const;
+ bool isDigit() const;
+
+ uchar& cell() { return cl; }
+ uchar& row() { return rw; }
+ uchar cell() const { return cl; }
+ uchar row() const { return rw; }
+
+ static bool networkOrdered() { return (int)net_ordered == 1; }
+
+ friend inline int operator==( char ch, QChar c );
+ friend inline int operator==( QChar c, char ch );
+ friend inline int operator==( QChar c1, QChar c2 );
+ friend inline int operator!=( QChar c1, QChar c2 );
+ friend inline int operator!=( char ch, QChar c );
+ friend inline int operator!=( QChar c, char ch );
+ friend inline int operator<=( QChar c, char ch );
+ friend inline int operator<=( char ch, QChar c );
+ friend inline int operator<=( QChar c1, QChar c2 );
+
+private:
+#if defined(_WS_X11_) || defined(_OS_WIN32_BYTESWAP_) || defined( _WS_QWS_ )
+ // XChar2b on X11, ushort on _OS_WIN32_BYTESWAP_
+ //### QWS must be defined on a platform by platform basis
+ uchar rw;
+ uchar cl;
+#if defined(QT_QSTRING_UCS_4)
+ ushort grp;
+#endif
+ enum { net_ordered = 1 };
+#else
+ // ushort on _OS_WIN32_
+ uchar cl;
+ uchar rw;
+#if defined(QT_QSTRING_UCS_4)
+ ushort grp;
+#endif
+ enum { net_ordered = 0 };
+#endif
+};
+
+inline QChar::QChar()
+{
+ rw = 0; cl = 0;
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( char c )
+{
+ rw = 0; cl = (uchar)c;
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( uchar c )
+{
+ rw = 0; cl = c;
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( uchar c, uchar r )
+{
+ rw = r; cl = c;
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( const QChar& c )
+{
+ rw = c.rw; cl = c.cl;
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( ushort rc )
+{
+ rw = (uchar)((rc>>8)&0xff); cl = (uchar)(rc&0xff);
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( short rc )
+{
+ rw = (uchar)((rc>>8)&0xff); cl = (uchar)(rc&0xff);
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( uint rc )
+{
+ rw = (uchar)((rc>>8)&0xff); cl = (uchar)(rc&0xff);
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+inline QChar::QChar( int rc )
+{
+ rw = (uchar)((rc>>8)&0xff); cl = (uchar)(rc&0xff);
+#ifdef QT_QSTRING_UCS_4
+ grp = 0;
+#endif
+}
+
+
+inline int operator==( char ch, QChar c )
+{
+ return ch == c.cl && !c.rw;
+}
+
+inline int operator==( QChar c, char ch )
+{
+ return ch == c.cl && !c.rw;
+}
+
+inline int operator==( QChar c1, QChar c2 )
+{
+ return c1.cl == c2.cl
+ && c1.rw == c2.rw;
+}
+
+inline int operator!=( QChar c1, QChar c2 )
+{
+ return c1.cl != c2.cl
+ || c1.rw != c2.rw;
+}
+
+inline int operator!=( char ch, QChar c )
+{
+ return ch != c.cl || c.rw;
+}
+
+inline int operator!=( QChar c, char ch )
+{
+ return ch != c.cl || c.rw;
+}
+
+inline int operator<=( QChar c, char ch )
+{
+ return !(ch < c.cl || c.rw);
+}
+
+inline int operator<=( char ch, QChar c )
+{
+ return ch <= c.cl || c.rw;
+}
+
+inline int operator<=( QChar c1, QChar c2 )
+{
+ return c1.rw > c2.rw
+ ? FALSE
+ : c1.rw < c2.rw
+ ? TRUE
+ : c1.cl <= c2.cl;
+}
+
+inline int operator>=( QChar c, char ch ) { return ch <= c; }
+inline int operator>=( char ch, QChar c ) { return c <= ch; }
+inline int operator>=( QChar c1, QChar c2 ) { return c2 <= c1; }
+inline int operator<( QChar c, char ch ) { return !(ch<=c); }
+inline int operator<( char ch, QChar c ) { return !(c<=ch); }
+inline int operator<( QChar c1, QChar c2 ) { return !(c2<=c1); }
+inline int operator>( QChar c, char ch ) { return !(ch>=c); }
+inline int operator>( char ch, QChar c ) { return !(c>=ch); }
+inline int operator>( QChar c1, QChar c2 ) { return !(c2>=c1); }
+
+// internal
+struct Q_EXPORT QStringData : public QShared {
+ QStringData() :
+ unicode(0), ascii(0), len(0), maxl(0), dirtyascii(0) { ref(); }
+ QStringData(QChar *u, uint l, uint m) :
+ unicode(u), ascii(0), len(l), maxl(m), dirtyascii(0) { }
+
+ ~QStringData() { if ( unicode ) delete[] ((char*)unicode);
+ if ( ascii ) delete[] ascii; }
+
+ void deleteSelf();
+ QChar *unicode;
+ char *ascii;
+ uint len;
+ uint maxl:30;
+ uint dirtyascii:1;
+};
+
+
+class Q_EXPORT QString
+{
+public:
+ QString(); // make null string
+ QString( QChar ); // one-char string
+ QString( const QString & ); // impl-shared copy
+ QString( const QByteArray& ); // deep copy
+ QString( const QChar* unicode, uint length ); // deep copy
+#ifndef QT_NO_CAST_ASCII
+ QString( const char *str ); // deep copy
+#endif
+ ~QString();
+
+ QString &operator=( const QString & ); // impl-shared copy
+#ifndef QT_NO_CAST_ASCII
+ QString &operator=( const char * ); // deep copy
+#endif
+ QString &operator=( const QCString& ); // deep copy
+ QString &operator=( QChar c );
+ QString &operator=( char c );
+
+ QT_STATIC_CONST QString null;
+
+ bool isNull() const;
+ bool isEmpty() const;
+ uint length() const;
+ void truncate( uint pos );
+
+#if QT_VERSION >= 300
+#error "fill() Should return *this, or QChar constructor should take count=1"
+#endif
+ void fill( QChar c, int len = -1 );
+
+ QString copy() const;
+
+ QString arg(long a, int fieldwidth=0, int base=10) const;
+ QString arg(ulong a, int fieldwidth=0, int base=10) const;
+ QString arg(int a, int fieldwidth=0, int base=10) const;
+ QString arg(uint a, int fieldwidth=0, int base=10) const;
+ QString arg(short a, int fieldwidth=0, int base=10) const;
+ QString arg(ushort a, int fieldwidth=0, int base=10) const;
+ QString arg(char a, int fieldwidth=0) const;
+ QString arg(QChar a, int fieldwidth=0) const;
+ QString arg(const QString& a, int fieldwidth=0) const;
+ QString arg(double a, int fieldwidth=0, char fmt='g', int prec=-1) const;
+
+ QString &sprintf( const char* format, ... )
+#if defined(_CC_GNU_) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+
+ int find( QChar c, int index=0, bool cs=TRUE ) const;
+ int find( char c, int index=0, bool cs=TRUE ) const;
+ int find( const QString &str, int index=0, bool cs=TRUE ) const;
+ int find( const QRegExp &, int index=0 ) const;
+#ifndef QT_NO_CAST_ASCII
+ int find( const char* str, int index=0 ) const;
+#endif
+ int findRev( QChar c, int index=-1, bool cs=TRUE) const;
+ int findRev( char c, int index=-1, bool cs=TRUE) const;
+ int findRev( const QString &str, int index=-1, bool cs=TRUE) const;
+ int findRev( const QRegExp &, int index=-1 ) const;
+#ifndef QT_NO_CAST_ASCII
+ int findRev( const char* str, int index=-1 ) const;
+#endif
+ int contains( QChar c, bool cs=TRUE ) const;
+ int contains( char c, bool cs=TRUE ) const
+ { return contains(QChar(c), cs); }
+#ifndef QT_NO_CAST_ASCII
+ int contains( const char* str, bool cs=TRUE ) const;
+#endif
+ int contains( const QString &str, bool cs=TRUE ) const;
+ int contains( const QRegExp & ) const;
+
+ QString left( uint len ) const;
+ QString right( uint len ) const;
+ QString mid( uint index, uint len=0xffffffff) const;
+
+ QString leftJustify( uint width, QChar fill=' ', bool trunc=FALSE)const;
+ QString rightJustify( uint width, QChar fill=' ',bool trunc=FALSE)const;
+
+ QString lower() const;
+ QString upper() const;
+
+ QString stripWhiteSpace() const;
+ QString simplifyWhiteSpace() const;
+
+ QString &insert( uint index, const QString & );
+ QString &insert( uint index, const QChar*, uint len );
+ QString &insert( uint index, QChar );
+ QString &insert( uint index, char c ) { return insert(index,QChar(c)); }
+ QString &append( char );
+ QString &append( QChar );
+ QString &append( const QString & );
+ QString &prepend( char );
+ QString &prepend( QChar );
+ QString &prepend( const QString & );
+ QString &remove( uint index, uint len );
+ QString &replace( uint index, uint len, const QString & );
+ QString &replace( uint index, uint len, const QChar*, uint clen );
+ QString &replace( const QRegExp &, const QString & );
+
+ short toShort( bool *ok=0, int base=10 ) const;
+ ushort toUShort( bool *ok=0, int base=10 ) const;
+ int toInt( bool *ok=0, int base=10 ) const;
+ uint toUInt( bool *ok=0, int base=10 ) const;
+ long toLong( bool *ok=0, int base=10 ) const;
+ ulong toULong( bool *ok=0, int base=10 ) const;
+ float toFloat( bool *ok=0 ) const;
+ double toDouble( bool *ok=0 ) const;
+
+ QString &setNum( short, int base=10 );
+ QString &setNum( ushort, int base=10 );
+ QString &setNum( int, int base=10 );
+ QString &setNum( uint, int base=10 );
+ QString &setNum( long, int base=10 );
+ QString &setNum( ulong, int base=10 );
+ QString &setNum( float, char f='g', int prec=6 );
+ QString &setNum( double, char f='g', int prec=6 );
+
+ static QString number( long, int base=10 );
+ static QString number( ulong, int base=10);
+ static QString number( int, int base=10 );
+ static QString number( uint, int base=10);
+ static QString number( double, char f='g', int prec=6 );
+
+ void setExpand( uint index, QChar c );
+
+ QString &operator+=( const QString &str );
+ QString &operator+=( QChar c );
+ QString &operator+=( char c );
+
+ // Your compiler is smart enough to use the const one if it can.
+ QChar at( uint i ) const
+ { return i<d->len ? d->unicode[i] : QChar::null; }
+ QChar operator[]( int i ) const { return at((uint)i); }
+ QCharRef at( uint i );
+ QCharRef operator[]( int i );
+
+ QChar constref(uint i) const
+ { return at(i); }
+ QChar& ref(uint i)
+ { // Optimized for easy-inlining by simple compilers.
+ if (d->count!=1 || i>=d->len)
+ subat(i);
+ d->dirtyascii=1;
+ return d->unicode[i];
+ }
+
+ const QChar* unicode() const { return d->unicode; }
+ const char* ascii() const;
+ const char* latin1() const;
+ static QString fromLatin1(const char*, int len=-1);
+#ifndef QT_NO_TEXTCODEC
+ QCString utf8() const;
+ static QString fromUtf8(const char*, int len=-1);
+#endif
+ QCString local8Bit() const;
+ static QString fromLocal8Bit(const char*, int len=-1);
+ bool operator!() const;
+#ifndef QT_NO_ASCII_CAST
+ operator const char *() const { return latin1(); }
+#endif
+
+ QString &setUnicode( const QChar* unicode, uint len );
+ QString &setUnicodeCodes( const ushort* unicode_as_ushorts, uint len );
+ QString &setLatin1( const char*, int len=-1 );
+
+ int compare( const QString& s ) const;
+ static int compare( const QString& s1, const QString& s2 )
+ { return s1.compare(s2); }
+
+#ifndef QT_NO_DATASTREAM
+ friend Q_EXPORT QDataStream &operator>>( QDataStream &, QString & );
+#endif
+ // new functions for BiDi
+ void compose();
+ QChar::Direction basicDirection();
+ QString visual(int index = 0, int len = -1);
+
+#ifndef QT_NO_COMPAT
+ const char* data() const { return latin1(); }
+#endif
+
+ bool startsWith( const QString& ) const;
+
+private:
+ QString( int size, bool dummy ); // allocate size incl. \0
+
+ void deref();
+ void real_detach();
+ void setLength( uint pos );
+ void subat( uint );
+ bool findArg(int& pos, int& len) const;
+
+ static QChar* asciiToUnicode( const char*, uint * len, uint maxlen=(uint)-1 );
+ static QChar* asciiToUnicode( const QByteArray&, uint * len );
+ static char* unicodeToAscii( const QChar*, uint len );
+
+ QStringData *d;
+ static QStringData* shared_null;
+ static QStringData* makeSharedNull();
+
+ friend class QConstString;
+ QString(QStringData* dd, bool /*dummy*/) : d(dd) { }
+};
+
+class Q_EXPORT QCharRef {
+ friend class QString;
+ QString& s;
+ uint p;
+ QCharRef(QString* str, uint pos) : s(*str), p(pos) { }
+
+public:
+ // Most QChar operations repeated here...
+
+ // all this is not documented: We just say "like QChar" and let it be.
+#if 1
+ ushort unicode() const { return s.constref(p).unicode(); }
+ char latin1() const { return s.constref(p).latin1(); }
+
+ // An operator= for each QChar cast constructor...
+ QCharRef operator=(char c ) { s.ref(p)=c; return *this; }
+ QCharRef operator=(uchar c ) { s.ref(p)=c; return *this; }
+ QCharRef operator=(QChar c ) { s.ref(p)=c; return *this; }
+ QCharRef operator=(const QCharRef& c ) { s.ref(p)=c.unicode(); return *this; }
+ QCharRef operator=(ushort rc ) { s.ref(p)=rc; return *this; }
+ QCharRef operator=(short rc ) { s.ref(p)=rc; return *this; }
+ QCharRef operator=(uint rc ) { s.ref(p)=rc; return *this; }
+ QCharRef operator=(int rc ) { s.ref(p)=rc; return *this; }
+
+ operator QChar () const { return s.constref(p); }
+
+ // each function...
+ bool isNull() const { return unicode()==0; }
+ bool isPrint() const { return s.constref(p).isPrint(); }
+ bool isPunct() const { return s.constref(p).isPunct(); }
+ bool isSpace() const { return s.constref(p).isSpace(); }
+ bool isMark() const { return s.constref(p).isMark(); }
+ bool isLetter() const { return s.constref(p).isLetter(); }
+ bool isNumber() const { return s.constref(p).isNumber(); }
+ bool isLetterOrNumber() { return s.constref(p).isLetterOrNumber(); }
+ bool isDigit() const { return s.constref(p).isDigit(); }
+
+ int digitValue() const { return s.constref(p).digitValue(); }
+ QChar lower() { return s.constref(p).lower(); }
+ QChar upper() { return s.constref(p).upper(); }
+
+ QChar::Category category() const { return s.constref(p).category(); }
+ QChar::Direction direction() const { return s.constref(p).direction(); }
+ QChar::Joining joining() const { return s.constref(p).joining(); }
+ bool mirrored() const { return s.constref(p).mirrored(); }
+ QChar mirroredChar() const { return s.constref(p).mirroredChar(); }
+ QString decomposition() const { return s.constref(p).decomposition(); }
+ QChar::Decomposition decompositionTag() const { return s.constref(p).decompositionTag(); }
+
+ // Not the non-const ones of these.
+ uchar cell() const { return s.constref(p).cell(); }
+ uchar row() const { return s.constref(p).row(); }
+#endif
+};
+
+inline QCharRef QString::at( uint i ) { return QCharRef(this,i); }
+inline QCharRef QString::operator[]( int i ) { return at((uint)i); }
+
+
+class Q_EXPORT QConstString : private QString {
+public:
+ QConstString( QChar* unicode, uint length );
+ ~QConstString();
+ const QString& string() const { return *this; }
+};
+
+
+/*****************************************************************************
+ QString stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator<<( QDataStream &, const QString & );
+Q_EXPORT QDataStream &operator>>( QDataStream &, QString & );
+#endif
+
+/*****************************************************************************
+ QString inline functions
+ *****************************************************************************/
+
+// These two move code into makeSharedNull() and deletesData()
+// to improve cache-coherence (and reduce code bloat), while
+// keeping the common cases fast.
+//
+// No safe way to pre-init shared_null on ALL compilers/linkers.
+inline QString::QString() :
+ d(shared_null ? shared_null : makeSharedNull())
+{
+ d->ref();
+}
+//
+inline QString::~QString()
+{
+ if ( d->deref() )
+ d->deleteSelf();
+}
+
+inline QString &QString::operator=( QChar c )
+{ return *this = QString(c); }
+
+inline QString &QString::operator=( char c )
+{ return *this = QString(QChar(c)); }
+
+inline bool QString::isNull() const
+{ return unicode() == 0; }
+
+inline bool QString::operator!() const
+{ return isNull(); }
+
+inline uint QString::length() const
+{ return d->len; }
+
+inline bool QString::isEmpty() const
+{ return length() == 0; }
+
+inline QString QString::copy() const
+{ return QString( *this ); }
+
+inline QString &QString::prepend( const QString & s )
+{ return insert(0,s); }
+
+inline QString &QString::prepend( QChar c )
+{ return insert(0,c); }
+
+inline QString &QString::prepend( char c )
+{ return insert(0,c); }
+
+inline QString &QString::append( const QString & s )
+{ return operator+=(s); }
+
+inline QString &QString::append( QChar c )
+{ return operator+=(c); }
+
+inline QString &QString::append( char c )
+{ return operator+=(c); }
+
+inline QString &QString::setNum( short n, int base )
+{ return setNum((long)n, base); }
+
+inline QString &QString::setNum( ushort n, int base )
+{ return setNum((ulong)n, base); }
+
+inline QString &QString::setNum( int n, int base )
+{ return setNum((long)n, base); }
+
+inline QString &QString::setNum( uint n, int base )
+{ return setNum((ulong)n, base); }
+
+inline QString &QString::setNum( float n, char f, int prec )
+{ return setNum((double)n,f,prec); }
+
+inline QString QString::arg(int a, int fieldwidth, int base) const
+{ return arg((long)a, fieldwidth, base); }
+
+inline QString QString::arg(uint a, int fieldwidth, int base) const
+{ return arg((ulong)a, fieldwidth, base); }
+
+inline QString QString::arg(short a, int fieldwidth, int base) const
+{ return arg((long)a, fieldwidth, base); }
+
+inline QString QString::arg(ushort a, int fieldwidth, int base) const
+{ return arg((ulong)a, fieldwidth, base); }
+
+inline int QString::find( char c, int index, bool cs ) const
+{ return find(QChar(c), index, cs); }
+
+inline int QString::findRev( char c, int index, bool cs) const
+{ return findRev( QChar(c), index, cs ); }
+
+
+#ifndef QT_NO_CAST_ASCII
+inline int QString::find( const char* str, int index ) const
+{ return find(QString::fromLatin1(str), index); }
+
+inline int QString::findRev( const char* str, int index ) const
+{ return findRev(QString::fromLatin1(str), index); }
+#endif
+
+
+/*****************************************************************************
+ QString non-member operators
+ *****************************************************************************/
+
+Q_EXPORT bool operator!=( const QString &s1, const QString &s2 );
+Q_EXPORT bool operator<( const QString &s1, const QString &s2 );
+Q_EXPORT bool operator<=( const QString &s1, const QString &s2 );
+Q_EXPORT bool operator==( const QString &s1, const QString &s2 );
+Q_EXPORT bool operator>( const QString &s1, const QString &s2 );
+Q_EXPORT bool operator>=( const QString &s1, const QString &s2 );
+#ifndef QT_NO_CAST_ASCII
+Q_EXPORT bool operator!=( const QString &s1, const char *s2 );
+Q_EXPORT bool operator<( const QString &s1, const char *s2 );
+Q_EXPORT bool operator<=( const QString &s1, const char *s2 );
+Q_EXPORT bool operator==( const QString &s1, const char *s2 );
+Q_EXPORT bool operator>( const QString &s1, const char *s2 );
+Q_EXPORT bool operator>=( const QString &s1, const char *s2 );
+Q_EXPORT bool operator!=( const char *s1, const QString &s2 );
+Q_EXPORT bool operator<( const char *s1, const QString &s2 );
+Q_EXPORT bool operator<=( const char *s1, const QString &s2 );
+Q_EXPORT bool operator==( const char *s1, const QString &s2 );
+//Q_EXPORT bool operator>( const char *s1, const QString &s2 ); // MSVC++
+Q_EXPORT bool operator>=( const char *s1, const QString &s2 );
+#endif
+
+Q_EXPORT inline QString operator+( const QString &s1, const QString &s2 )
+{
+ QString tmp( s1 );
+ tmp += s2;
+ return tmp;
+}
+
+#ifndef QT_NO_CAST_ASCII
+Q_EXPORT inline QString operator+( const QString &s1, const char *s2 )
+{
+ QString tmp( s1 );
+ tmp += QString::fromLatin1(s2);
+ return tmp;
+}
+
+Q_EXPORT inline QString operator+( const char *s1, const QString &s2 )
+{
+ QString tmp = QString::fromLatin1( s1 );
+ tmp += s2;
+ return tmp;
+}
+#endif
+
+Q_EXPORT inline QString operator+( const QString &s1, QChar c2 )
+{
+ QString tmp( s1 );
+ tmp += c2;
+ return tmp;
+}
+
+Q_EXPORT inline QString operator+( const QString &s1, char c2 )
+{
+ QString tmp( s1 );
+ tmp += c2;
+ return tmp;
+}
+
+Q_EXPORT inline QString operator+( QChar c1, const QString &s2 )
+{
+ QString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+Q_EXPORT inline QString operator+( char c1, const QString &s2 )
+{
+ QString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+#if defined(_OS_WIN32_)
+extern Q_EXPORT QString qt_winQString(void*);
+extern Q_EXPORT const void* qt_winTchar(const QString& str, bool addnul);
+extern Q_EXPORT void* qt_winTchar_new(const QString& str);
+extern Q_EXPORT QCString qt_winQString2MB( const QString& s, int len=-1 );
+extern Q_EXPORT QString qt_winMB2QString( const char* mb, int len=-1 );
+#endif
+
+#endif // QSTRING_H
diff --git a/qtools/qstringlist.cpp b/qtools/qstringlist.cpp
new file mode 100644
index 0000000..ff4f33e
--- /dev/null
+++ b/qtools/qstringlist.cpp
@@ -0,0 +1,302 @@
+/****************************************************************************
+**
+**
+** Implementation of QStringList
+**
+** Created : 990406
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qstringlist.h"
+
+#ifndef QT_NO_STRINGLIST
+#include "qstrlist.h"
+#include "qdatastream.h"
+#include "qtl.h"
+
+// NOT REVISED
+/*!
+ \class QStringList qstringlist.h
+ \brief A list of strings.
+
+ \ingroup qtl
+ \ingroup tools
+ \ingroup shared
+
+ QStringList is basically a QValueList of QString objects. As opposed
+ to QStrList, that stores pointers to characters, QStringList deals
+ with real QString objects. It is the class of choice whenever you
+ work with unicode strings.
+
+ Like QString itself, QStringList objects are implicit shared.
+ Passing them around as value-parameters is both fast and safe.
+
+ Example:
+ \code
+ QStringList list;
+
+ // three different ways of appending values:
+ list.append( "Torben");
+ list += "Warwick";
+ list << "Matthias" << "Arnt" << "Paul";
+
+ // sort the list, Arnt's now first
+ list.sort();
+
+ // print it out
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
+ printf( "%s \n", (*it).latin1() );
+ }
+ \endcode
+
+ Convenience methods such as sort(), split(), join() and grep() make
+ working with QStringList easy.
+*/
+
+/*!
+ \fn QStringList::QStringList()
+ Creates an empty list.
+*/
+
+/*! \fn QStringList::QStringList( const QStringList& l )
+ Creates a copy of the list. This function is very fast since
+ QStringList is implicit shared. However, for the programmer this
+ is the same as a deep copy. If this list or the original one or some
+ other list referencing the same shared data is modified, then the
+ modifying list makes a copy first.
+*/
+
+/*!
+ \fn QStringList::QStringList (const QString & i)
+ Constructs a string list consisting of the single string \a i.
+ To make longer lists easily, use:
+ \code
+ QString s1,s2,s3;
+ ...
+ QStringList mylist = QStringList() << s1 << s2 << s3;
+ \endcode
+*/
+
+/*!
+ \fn QStringList::QStringList (const char* i)
+ Constructs a string list consisting of the single latin-1 string \a i.
+*/
+
+/*! \fn QStringList::QStringList( const QValueList<QString>& l )
+
+ Constructs a new string list that is a copy of \a l.
+*/
+
+/*!
+ Sorts the list of strings in ascending order.
+
+ Sorting is very fast. It uses the Qt Template Library's
+ efficient HeapSort implementation that operates in O(n*log n).
+*/
+void QStringList::sort()
+{
+ qHeapSort(*this);
+}
+
+/*!
+ Splits the string \a str using \a sep as separator. Returns the
+ list of strings. If \a allowEmptyEntries is TRUE, also empty
+ entries are inserted into the list, else not. So if you have
+ a string 'abc..d.e.', a list which contains 'abc', 'd', and 'e'
+ would be returned if \a allowEmptyEntries is FALSE, but
+ a list containing 'abc', '', 'd', 'e' and '' would be returned if
+ \a allowEmptyEntries is TRUE.
+ If \a str doesn't contain \a sep, a stringlist
+ with one item, which is the same as \a str, is returned.
+
+ \sa join()
+*/
+
+QStringList QStringList::split( const QChar &sep, const QString &str, bool allowEmptyEntries )
+{
+ return split( QString( sep ), str, allowEmptyEntries );
+}
+
+/*!
+ Splits the string \a str using \a sep as separator. Returns the
+ list of strings. If \a allowEmptyEntries is TRUE, also empty
+ entries are inserted into the list, else not. So if you have
+ a string 'abc..d.e.', a list which contains 'abc', 'd', and 'e'
+ would be returned if \a allowEmptyEntries is FALSE, but
+ a list containing 'abc', '', 'd', 'e' and '' would be returned if
+ \a allowEmptyEntries is TRUE.
+ If \a str doesn't contain \a sep, a stringlist
+ with one item, which is the same as \a str, is returned.
+
+ \sa join()
+*/
+
+QStringList QStringList::split( const QString &sep, const QString &str, bool allowEmptyEntries )
+{
+ QStringList lst;
+
+ int j = 0;
+ int i = str.find( sep, j );
+
+ while ( i != -1 ) {
+ if ( str.mid( j, i - j ).length() > 0 )
+ lst << str.mid( j, i - j );
+ else if ( allowEmptyEntries )
+ lst << QString::null;
+ j = i + sep.length();
+ i = str.find( sep, j );
+ }
+
+ int l = str.length() - 1;
+ if ( str.mid( j, l - j + 1 ).length() > 0 )
+ lst << str.mid( j, l - j + 1 );
+ else if ( allowEmptyEntries )
+ lst << QString::null;
+
+ return lst;
+}
+
+/*!
+ Splits the string \a str using the regular expression \a sep as separator. Returns the
+ list of strings. If \a allowEmptyEntries is TRUE, also empty
+ entries are inserted into the list, else not. So if you have
+ a string 'abc..d.e.', a list which contains 'abc', 'd', and 'e'
+ would be returned if \a allowEmptyEntries is FALSE, but
+ a list containing 'abc', '', 'd', 'e' and '' would be returned if
+ \a allowEmptyEntries is TRUE.
+ If \a str doesn't contain \a sep, a stringlist
+ with one item, which is the same as \a str, is returned.
+
+ \sa join()
+*/
+
+QStringList QStringList::split( const QRegExp &sep, const QString &str, bool allowEmptyEntries )
+{
+ QStringList lst;
+
+ int j = 0;
+ int len = 0;
+ int i = sep.match( str, j, &len );
+
+ while ( i != -1 ) {
+ if ( str.mid( j, i - j ).length() > 0 )
+ lst << str.mid( j, i - j );
+ else if ( allowEmptyEntries )
+ lst << QString::null;
+ j = i + len;
+ i = sep.match( str, j, &len );
+ }
+
+ int l = str.length() - 1;
+ if ( str.mid( j, l - j + 1 ).length() > 0 )
+ lst << str.mid( j, l - j + 1 );
+ else if ( allowEmptyEntries )
+ lst << QString::null;
+
+ return lst;
+}
+
+/*!
+ Returns a list of all strings containing the substring \a str.
+
+ If \a cs is TRUE, the grep is done case sensitively, else not.
+*/
+
+QStringList QStringList::grep( const QString &str, bool cs ) const
+{
+ QStringList res;
+ for ( QStringList::ConstIterator it = begin(); it != end(); ++it )
+ if ( (*it).contains( str, cs ) )
+ res << *it;
+
+ return res;
+}
+
+/*!
+ Returns a list of all strings containing a substring that matches
+ the regular expression \a expr.
+*/
+
+QStringList QStringList::grep( const QRegExp &expr ) const
+{
+ QStringList res;
+ for ( QStringList::ConstIterator it = begin(); it != end(); ++it )
+ if ( (*it).contains( expr ) )
+ res << *it;
+
+ return res;
+}
+
+/*!
+ Joins the stringlist into a single string with each element
+ separated by \a sep.
+
+ \sa split()
+*/
+QString QStringList::join( const QString &sep ) const
+{
+ QString res;
+ bool alredy = FALSE;
+ for ( QStringList::ConstIterator it = begin(); it != end(); ++it ) {
+ if ( alredy )
+ res += sep;
+ alredy = TRUE;
+ res += *it;
+ }
+
+ return res;
+}
+
+#ifndef QT_NO_DATASTREAM
+Q_EXPORT QDataStream &operator>>( QDataStream & s, QStringList& l )
+{
+ return s >> (QValueList<QString>&)l;
+}
+
+Q_EXPORT QDataStream &operator<<( QDataStream & s, const QStringList& l )
+{
+ return s << (const QValueList<QString>&)l;
+}
+#endif
+
+/*!
+ Converts from a QStrList (ASCII) to a QStringList (Unicode).
+*/
+QStringList QStringList::fromStrList(const QStrList& ascii)
+{
+ QStringList res;
+ const char * s;
+ for ( QStrListIterator it(ascii); (s=it.current()); ++it )
+ res << s;
+ return res;
+}
+
+#endif //QT_NO_STRINGLIST
diff --git a/qtools/qstringlist.h b/qtools/qstringlist.h
new file mode 100644
index 0000000..03342c5
--- /dev/null
+++ b/qtools/qstringlist.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+**
+** Definition of QStringList class
+**
+** Created : 990406
+**
+** Copyright (C) 1992-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 QSTRINGLIST_H
+#define QSTRINGLIST_H
+
+#ifndef QT_H
+#include "qvaluelist.h"
+#include "qstring.h"
+#include "qregexp.h"
+#endif // QT_H
+
+#ifndef QT_NO_STRINGLIST
+
+class QStrList;
+
+class Q_EXPORT QStringList : public QValueList<QString>
+{
+public:
+ QStringList() { }
+ QStringList( const QStringList& l ) : QValueList<QString>(l) { }
+ QStringList( const QValueList<QString>& l ) : QValueList<QString>(l) { }
+ QStringList( const QString& i ) { append(i); }
+#ifndef QT_NO_CAST_ASCII
+ QStringList( const char* i ) { append(i); }
+#endif
+
+ static QStringList fromStrList(const QStrList&);
+
+ void sort();
+
+ static QStringList split( const QString &sep, const QString &str, bool allowEmptyEntries = FALSE );
+ static QStringList split( const QChar &sep, const QString &str, bool allowEmptyEntries = FALSE );
+ static QStringList split( const QRegExp &sep, const QString &str, bool allowEmptyEntries = FALSE );
+ QString join( const QString &sep ) const;
+
+ QStringList grep( const QString &str, bool cs = TRUE ) const;
+ QStringList grep( const QRegExp &expr ) const;
+};
+
+#ifndef QT_NO_DATASTREAM
+class QDataStream;
+extern Q_EXPORT QDataStream &operator>>( QDataStream &, QStringList& );
+extern Q_EXPORT QDataStream &operator<<( QDataStream &, const QStringList& );
+#endif
+#endif // QT_NO_STRINGLIST
+#endif // QSTRINGLIST_H
diff --git a/qtools/qstrlist.h b/qtools/qstrlist.h
new file mode 100644
index 0000000..c6a1864
--- /dev/null
+++ b/qtools/qstrlist.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+**
+** Definition of QStrList, QStrIList and QStrListIterator classes
+**
+** Created : 920730
+**
+** Copyright (C) 1992-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 QSTRLIST_H
+#define QSTRLIST_H
+
+#ifndef QT_H
+#include "qstring.h"
+#include "qlist.h"
+#include "qdatastream.h"
+#endif // QT_H
+
+
+#if defined(Q_TEMPLATEDLL)
+template class Q_EXPORT QList<char>;
+template class Q_EXPORT QListIterator<char>;
+#endif
+
+typedef QList<char> QStrListBase;
+typedef QListIterator<char> QStrListIterator;
+
+
+class Q_EXPORT QStrList : public QStrListBase
+{
+public:
+ QStrList( bool deepCopies=TRUE ) { dc = deepCopies; del_item = deepCopies; }
+ QStrList( const QStrList & );
+ ~QStrList() { clear(); }
+ QStrList& operator=( const QStrList & );
+
+private:
+ QCollection::Item newItem( QCollection::Item d ) { return dc ? qstrdup( (const char*)d ) : d; }
+ void deleteItem( QCollection::Item d ) { if ( del_item ) delete[] (char*)d; }
+ int compareItems( QCollection::Item s1, QCollection::Item s2 ) { return qstrcmp((const char*)s1,
+ (const char*)s2); }
+#ifndef QT_NO_DATASTREAM
+ QDataStream &read( QDataStream &s, QCollection::Item &d )
+ { s >> (char *&)d; return s; }
+ QDataStream &write( QDataStream &s, QCollection::Item d ) const
+ { return s << (const char *)d; }
+#endif
+ bool dc;
+};
+
+
+class Q_EXPORT QStrIList : public QStrList // case insensitive string list
+{
+public:
+ QStrIList( bool deepCopies=TRUE ) : QStrList( deepCopies ) {}
+ ~QStrIList() { clear(); }
+private:
+ int compareItems( QCollection::Item s1, QCollection::Item s2 )
+ { return qstricmp((const char*)s1,
+ (const char*)s2); }
+};
+
+
+inline QStrList & QStrList::operator=( const QStrList &strList )
+{
+ clear();
+ dc = strList.dc;
+ del_item = dc;
+ QStrListBase::operator=(strList);
+ return *this;
+}
+
+inline QStrList::QStrList( const QStrList &strList )
+ : QStrListBase( strList )
+{
+ dc = FALSE;
+ operator=(strList);
+}
+
+
+#endif // QSTRLIST_H
diff --git a/qtools/qstrvec.h b/qtools/qstrvec.h
new file mode 100644
index 0000000..15d3abb
--- /dev/null
+++ b/qtools/qstrvec.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+**
+** Definition of QStrVec and QStrIVec classes
+**
+** Created : 931203
+**
+** Copyright (C) 1992-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 QSTRVEC_H
+#define QSTRVEC_H
+
+#ifndef QT_H
+#include "qstring.h"
+#include "qvector.h"
+#include "qdatastream.h"
+#endif // QT_H
+
+
+#if defined(Q_TEMPLATEDLL)
+template class Q_EXPORT QVector<char>
+#endif
+
+typedef QVector<char> QStrVecBase;
+
+
+class Q_EXPORT QStrVec : public QStrVecBase
+{
+public:
+ QStrVec() { dc = TRUE; }
+ QStrVec( uint size, bool deepc = TRUE ) : QStrVecBase(size) {dc=deepc;}
+ ~QStrVec() { clear(); }
+private:
+ Item newItem( Item d ) { return dc ? qstrdup( (const char*)d ) : d; }
+ void deleteItem( Item d ) { if ( dc ) delete[] (char*)d; }
+ int compareItems( Item s1, Item s2 )
+ { return qstrcmp((const char*)s1,
+ (const char*)s2); }
+#ifndef QT_NO_DATASTREAM
+ QDataStream &read( QDataStream &s, Item &d )
+ { s >> (char *&)d; return s; }
+ QDataStream &write( QDataStream &s, Item d ) const
+ { return s << (const char*)d; }
+#endif
+ bool dc;
+};
+
+
+class Q_EXPORT QStrIVec : public QStrVec // case insensitive string vec
+{
+public:
+ QStrIVec() {}
+ QStrIVec( uint size, bool dc = TRUE ) : QStrVec( size, dc ) {}
+ ~QStrIVec() { clear(); }
+private:
+ int compareItems( Item s1, Item s2 )
+ { return qstricmp((const char*)s1,
+ (const char*)s2); }
+};
+
+
+#endif // QSTRVEC_H
diff --git a/qtools/qtextcodec.cpp b/qtools/qtextcodec.cpp
new file mode 100644
index 0000000..af43a3a
--- /dev/null
+++ b/qtools/qtextcodec.cpp
@@ -0,0 +1,2019 @@
+/****************************************************************************
+**
+**
+** Implementation of QTextCodec class
+**
+** Created : 981015
+**
+** Copyright (C)1998-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.
+**
+**********************************************************************/
+
+#include "qtextcodec.h"
+#ifndef QT_NO_TEXTCODEC
+
+#include "qlist.h"
+#ifndef QT_NO_CODECS
+#include "qutfcodec.h"
+#include "qgbkcodec.h"
+#include "qeucjpcodec.h"
+#include "qjiscodec.h"
+#include "qsjiscodec.h"
+#include "qeuckrcodec.h"
+#include "qbig5codec.h"
+#include "qrtlcodec.h"
+#include "qtsciicodec.h"
+#endif
+
+#include "qfile.h"
+#include "qstrlist.h"
+#include "qstring.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <locale.h>
+
+
+static QList<QTextCodec> * all = 0;
+static bool destroying_is_ok; // starts out as 0
+
+/*! Deletes all the created codecs.
+
+ \warning Do not call this function.
+
+ QApplication calls this just before exiting, to delete any
+ QTextCodec objects that may be lying around. Since various other
+ classes hold pointers to QTextCodec objects, it is not safe to call
+ this function earlier.
+
+ If you are using the utility classes (like QString) but not using
+ QApplication, calling this function at the very end of your
+ application can be helpful to chasing down memory leaks, as
+ QTextCodec objects will not show up.
+*/
+
+void QTextCodec::deleteAllCodecs()
+{
+ if ( !all )
+ return;
+
+ destroying_is_ok = TRUE;
+ QList<QTextCodec> * ball = all;
+ all = 0;
+ ball->clear();
+ delete ball;
+ destroying_is_ok = FALSE;
+}
+
+
+static void setupBuiltinCodecs();
+
+
+static void realSetup()
+{
+#if defined(CHECK_STATE)
+ if ( destroying_is_ok )
+ qWarning( "creating new codec during codec cleanup" );
+#endif
+ all = new QList<QTextCodec>;
+ all->setAutoDelete( TRUE );
+ setupBuiltinCodecs();
+}
+
+
+static inline void setup()
+{
+ if ( !all )
+ realSetup();
+}
+
+
+class QTextStatelessEncoder: public QTextEncoder {
+ const QTextCodec* codec;
+public:
+ QTextStatelessEncoder(const QTextCodec*);
+ QCString fromUnicode(const QString& uc, int& lenInOut);
+};
+
+
+class QTextStatelessDecoder : public QTextDecoder {
+ const QTextCodec* codec;
+public:
+ QTextStatelessDecoder(const QTextCodec*);
+ QString toUnicode(const char* chars, int len);
+};
+
+QTextStatelessEncoder::QTextStatelessEncoder(const QTextCodec* c) :
+ codec(c)
+{
+}
+
+
+QCString QTextStatelessEncoder::fromUnicode(const QString& uc, int& lenInOut)
+{
+ return codec->fromUnicode(uc,lenInOut);
+}
+
+
+QTextStatelessDecoder::QTextStatelessDecoder(const QTextCodec* c) :
+ codec(c)
+{
+}
+
+
+QString QTextStatelessDecoder::toUnicode(const char* chars, int len)
+{
+ return codec->toUnicode(chars,len);
+}
+
+
+
+// NOT REVISED
+/*!
+ \class QTextCodec qtextcodec.h
+ \brief Provides conversion between text encodings.
+
+ By making objects of subclasses of QTextCodec, support for
+ new text encodings can be added to Qt.
+
+ The abstract virtual functions describe the encoder to the
+ system and the coder is used as required in the different
+ text file formats supported QTextStream and, under X11 for the
+ locale-specific character input and output (under Windows NT
+ codecs are not needed for GUI I/O since the system works
+ with Unicode already, and Windows 95/98 has built-in convertors
+ for the 8-bit local encoding).
+
+ More recently created QTextCodec objects take precedence
+ over earlier ones.
+
+ To add support for another 8-bit encoding to Qt, make a subclass
+ or QTextCodec and implement at least the following methods:
+ <dl>
+ <dt>\c const char* name() const
+ <dd>Return the official name for the encoding.
+ <dt>\c int mibEnum() const
+ <dd>Return the MIB enum for the encoding if it is listed in the
+ <a href=ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets>
+ IANA character-sets encoding file</a>.
+ </dl>
+ If the encoding is multi-byte then it will have "state"; that is,
+ the interpretation of some bytes will be dependent on some preceding
+ bytes. For such an encoding, you will need to implement
+ <dl>
+ <dt> \c QTextDecoder* makeDecoder() const
+ <dd>Return a QTextDecoder that remembers incomplete multibyte
+ sequence prefixes or other required state.
+ </dl>
+ If the encoding does \e not require state, you should implement:
+ <dl>
+ <dt> \c QString toUnicode(const char* chars, int len) const
+ <dd>Converts \e len characters from \e chars to Unicode.
+ </dl>
+ The base QTextCodec class has default implementations of the above
+ two functions, <i>but they are mutually recursive</i>, so you must
+ re-implement at least one of them, or both for improved efficiency.
+
+ For conversion from Unicode to 8-bit encodings, it is rarely necessary
+ to maintain state. However, two functions similar to the two above
+ are used for encoding:
+ <dl>
+ <dt> \c QTextEncoder* makeEncoder() const
+ <dd>Return a QTextDecoder.
+ <dt> \c QCString fromUnicode(const QString& uc, int& lenInOut ) const;
+ <dd>Converts \e lenInOut characters (of type QChar) from the start
+ of the string \a uc, returning a QCString result, and also returning
+ the \link QCString::length() length\endlink
+ of the result in lenInOut.
+ </dl>
+ Again, these are mutually recursive so only one needs to be implemented,
+ or both if better efficiency is possible.
+
+ Finally, you must implement:
+ <dl>
+ <dt> \c int heuristicContentMatch(const char* chars, int len) const
+ <dd>Gives a value indicating how likely it is that \e len characters
+ from \e chars are in the encoding.
+ </dl>
+ A good model for this function is the
+ QWindowsLocalCodec::heuristicContentMatch function found in the Qt sources.
+
+ A QTextCodec subclass might have improved performance if you also
+ re-implement:
+ <dl>
+ <dt> \c bool canEncode( QChar ) const
+ <dd>Test if a Unicode character can be encoded.
+ <dt> \c bool canEncode( const QString& ) const
+ <dd>Test if a string of Unicode characters can be encoded.
+ <dt> \c int heuristicNameMatch(const char* hint) const
+ <dd>Test if a possibly non-standard name is referring to the codec.
+ </dl>
+*/
+
+
+/*!
+ Constructs a QTextCodec, making it of highest precedence.
+ The QTextCodec should always be constructed on the heap
+ (with new), and once constructed it becomes the responsibility
+ of Qt to delete it (which is done at QApplication destruction).
+*/
+QTextCodec::QTextCodec()
+{
+ setup();
+ all->insert(0,this);
+}
+
+
+/*!
+ Destructs the QTextCodec. Note that you should not delete
+ codecs yourself - once created they become the responsibility
+ of Qt to delete.
+*/
+QTextCodec::~QTextCodec()
+{
+ if ( !destroying_is_ok )
+ qWarning("QTextCodec::~QTextCodec() called by application");
+ if ( all )
+ all->remove( this );
+}
+
+
+/*!
+ Returns a value indicating how likely this decoder is
+ for decoding some format that has the given name.
+
+ A good match returns a positive number around
+ the length of the string. A bad match is negative.
+
+ The default implementation calls simpleHeuristicNameMatch()
+ with the name of the codec.
+*/
+int QTextCodec::heuristicNameMatch(const char* hint) const
+{
+ return simpleHeuristicNameMatch(name(),hint);
+}
+
+
+// returns a string cotnaining the letters and numbers from input,
+// with a space separating run of a character class. e.g. "iso8859-1"
+// becomes "iso 8859 1"
+static QString lettersAndNumbers( const char * input )
+{
+ QString result;
+ QChar c;
+
+ while( input && *input ) {
+ c = *input;
+ if ( c.isLetter() || c.isNumber() )
+ result += c.lower();
+ if ( input[1] ) {
+ // add space at character class transition, except
+ // transition from upper-case to lower-case letter
+ QChar n( input[1] );
+ if ( c.isLetter() && n.isLetter() ) {
+ if ( c == c.lower() && n == n.upper() )
+ result += ' ';
+ } else if ( c.category() != n.category() ) {
+ result += ' ';
+ }
+ }
+ input++;
+ }
+ return result.simplifyWhiteSpace();
+}
+
+/*!
+ A simple utility function for heuristicNameMatch() - it
+ does some very minor character-skipping
+ so that almost-exact matches score high.
+*/
+int QTextCodec::simpleHeuristicNameMatch(const char* name, const char* hint)
+{
+ // if they're the same, return a perfect score.
+ if ( name && hint && qstrcmp( name, hint ) == 0 )
+ return qstrlen( hint );
+
+ // if the letters and numbers are the same, we have an "almost"
+ // perfect match.
+ QString h( lettersAndNumbers( hint ) );
+ QString n( lettersAndNumbers( name ) );
+ if ( h == n )
+ return qstrlen( hint )-1;
+
+ if ( h.stripWhiteSpace() == n.stripWhiteSpace() )
+ return qstrlen( hint )-2;
+
+ // could do some more here, but I don't think it's worth it
+
+ return 0;
+}
+
+
+/*!
+ Returns the QTextCodec \a i places from the more recently
+ inserted, or NULL if there is no such QTextCodec. Thus,
+ codecForIndex(0) returns the most recently created QTextCodec.
+*/
+QTextCodec* QTextCodec::codecForIndex(int i)
+{
+ setup();
+ return (uint)i >= all->count() ? 0 : all->at(i);
+}
+
+
+/*!
+ Returns the QTextCodec which matches the
+ \link QTextCodec::mibEnum() MIBenum\endlink \a mib.
+*/
+QTextCodec* QTextCodec::codecForMib(int mib)
+{
+ setup();
+ QListIterator<QTextCodec> i(*all);
+ QTextCodec* result;
+ for ( ; (result=i); ++i ) {
+ if ( result->mibEnum()==mib )
+ break;
+ }
+ return result;
+}
+
+
+
+
+
+#ifdef _OS_WIN32_
+class QWindowsLocalCodec: public QTextCodec
+{
+public:
+ QWindowsLocalCodec();
+ ~QWindowsLocalCodec();
+
+ QString toUnicode(const char* chars, int len) const;
+ QCString fromUnicode(const QString& uc, int& lenInOut ) const;
+
+ const char* name() const;
+ int mibEnum() const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+};
+
+QWindowsLocalCodec::QWindowsLocalCodec()
+{
+}
+
+QWindowsLocalCodec::~QWindowsLocalCodec()
+{
+}
+
+
+QString QWindowsLocalCodec::toUnicode(const char* chars, int len) const
+{
+ if ( len == 1 && chars ) { // Optimization; avoids allocation
+ char c[2];
+ c[0] = *chars;
+ c[1] = 0;
+ return qt_winMB2QString( c, 2 );
+ }
+ if ( len < 0 )
+ return qt_winMB2QString( chars );
+ QCString s(chars,len+1);
+ return qt_winMB2QString(s);
+}
+
+QCString QWindowsLocalCodec::fromUnicode(const QString& uc, int& lenInOut ) const
+{
+ QCString r = qt_winQString2MB( uc, lenInOut );
+ lenInOut = r.length();
+ return r;
+}
+
+
+const char* QWindowsLocalCodec::name() const
+{
+ return "System";
+}
+
+int QWindowsLocalCodec::mibEnum() const
+{
+ return 0;
+}
+
+
+int QWindowsLocalCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ // ### Not a bad default implementation?
+ QString t = toUnicode(chars,len);
+ int l = t.length();
+ QCString mb = fromUnicode(t,l);
+ int i=0;
+ while ( i < len )
+ if ( chars[i] == mb[i] )
+ i++;
+ return i;
+}
+
+#else
+
+/* locale names mostly copied from XFree86 */
+static const char * const iso8859_2locales[] = {
+ "croatian", "cs", "cs_CS", "cs_CZ","cz", "cz_CZ", "czech", "hr",
+ "hr_HR", "hu", "hu_HU", "hungarian", "pl", "pl_PL", "polish", "ro",
+ "ro_RO", "rumanian", "serbocroatian", "sh", "sh_SP", "sh_YU", "sk",
+ "sk_SK", "sl", "sl_CS", "sl_SI", "slovak", "slovene", "sr_SP", 0 };
+
+static const char * const iso8859_3locales[] = {
+ "eo", 0 };
+
+static const char * const iso8859_5locales[] = {
+ "bg", "bg_BG", "bulgarian", "mk", "mk_MK",
+ "sp", "sp_YU", 0 };
+
+static const char * const iso8859_6locales[] = {
+ "ar_AA", "ar_SA", "arabic", 0 };
+
+static const char * const iso8859_7locales[] = {
+ "el", "el_GR", "greek", 0 };
+
+static const char * const iso8859_8locales[] = {
+ "hebrew", "iw", "iw_IL", 0 };
+
+static const char * const iso8859_9locales[] = {
+ "tr", "tr_TR", "turkish", 0 };
+
+static const char * const iso8859_15locales[] = {
+ "fr", "fi", "french", "finnish", 0 };
+
+
+static bool try_locale_list( const char * const locale[], const char * lang )
+{
+ int i;
+ for( i=0; locale[i] && qstrcmp(locale[i], lang); i++ )
+ { }
+ return locale[i] != 0;
+}
+
+// For the probably_koi8_locales we have to look. the standard says
+// these are 8859-5, but almsot all Russion users uses KOI8-R and
+// incorrectly set $LANG to ru_RU. We'll check tolower() to see what
+// tolower() thinks ru_RU means.
+
+// If you read the history, it seems that many Russians blame ISO and
+// Peristroika for the confusion.
+//
+// The real bug is that some programs break if the user specifies
+// ru_RU.KOI8-R.
+
+static const char * const probably_koi8_rlocales[] = {
+ "ru", "ru_SU", "ru_RU", "russian", 0 };
+
+// this means ANY of these locale aliases. if they're aliases for
+// different locales, the code breaks.
+static QTextCodec * ru_RU_codec = 0;
+
+static QTextCodec * ru_RU_hack( const char * i ) {
+ if ( ! ru_RU_codec ) {
+ QCString origlocale = setlocale( LC_CTYPE, i );
+ // unicode koi8r latin5 name
+ // 0x044E 0xC0 0xEE CYRILLIC SMALL LETTER YU
+ // 0x042E 0xE0 0xCE CYRILLIC CAPITAL LETTER YU
+ int latin5 = tolower( 0xCE );
+ int koi8r = tolower( 0xE0 );
+ if ( koi8r == 0xC0 && latin5 != 0xEE ) {
+ ru_RU_codec = QTextCodec::codecForName( "KOI8-R" );
+ } else if ( koi8r != 0xC0 && latin5 == 0xEE ) {
+ ru_RU_codec = QTextCodec::codecForName( "ISO 8859-5" );
+ } else {
+ // something else again... let's assume... *throws dice*
+ ru_RU_codec = QTextCodec::codecForName( "KOI8-R" );
+ qWarning( "QTextCodec: using KOI8-R, probe failed (%02x %02x %s)",
+ koi8r, latin5, i );
+ }
+ setlocale( LC_CTYPE, origlocale.data() );
+ }
+ return ru_RU_codec;
+}
+
+#endif
+
+static QTextCodec * localeMapper = 0;
+
+/*! Returns a pointer to the codec most suitable for this locale. */
+
+QTextCodec* QTextCodec::codecForLocale()
+{
+ if ( localeMapper )
+ return localeMapper;
+
+ setup();
+
+#ifdef _OS_WIN32_
+ localeMapper = new QWindowsLocalCodec;
+#else
+ // Very poorly defined and followed standards causes lots of code
+ // to try to get all the cases...
+
+ char * lang = qstrdup( getenv("LANG") );
+
+ char * p = lang ? strchr( lang, '.' ) : 0;
+ if ( !p || *p != '.' ) {
+ // Some versions of setlocale return encoding, others not.
+ char *ctype = qstrdup( setlocale( LC_CTYPE, 0 ) );
+ // Some Linux distributions have broken locales which will return
+ // "C" for LC_CTYPE
+ if ( qstrcmp( ctype, "C" ) == 0 ) {
+ delete [] ctype;
+ } else {
+ if ( lang )
+ delete [] lang;
+ lang = ctype;
+ p = lang ? strchr( lang, '.' ) : 0;
+ }
+ }
+
+ if( p && *p == '.' ) {
+ // if there is an encoding and we don't know it, we return 0
+ // User knows what they are doing. Codecs will believe them.
+ localeMapper = codecForName( lang );
+ if ( !localeMapper ) {
+ // Use or codec disagree.
+ localeMapper = codecForName( p+1 );
+ }
+ }
+ if ( !localeMapper || !(p && *p == '.') ) {
+ // if there is none, we default to 8859-1
+ // We could perhaps default to 8859-15.
+ if ( try_locale_list( iso8859_2locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-2" );
+ else if ( try_locale_list( iso8859_3locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-3" );
+ else if ( try_locale_list( iso8859_5locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-5" );
+ else if ( try_locale_list( iso8859_6locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-6" );
+ else if ( try_locale_list( iso8859_7locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-7" );
+ else if ( try_locale_list( iso8859_8locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-8" );
+ else if ( try_locale_list( iso8859_9locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-9" );
+ else if ( try_locale_list( iso8859_15locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-15" );
+ else if ( try_locale_list( probably_koi8_rlocales, lang ) )
+ localeMapper = ru_RU_hack( lang );
+ else if (!lang || !(localeMapper = codecForName(lang) ))
+ localeMapper = codecForName( "ISO 8859-1" );
+ }
+ delete[] lang;
+#endif
+
+ return localeMapper;
+}
+
+
+/*!
+ Searches all installed QTextCodec objects, returning the one
+ which best matches given name. Returns NULL if no codec has
+ a match closeness above \a accuracy.
+
+ \sa heuristicNameMatch()
+*/
+QTextCodec* QTextCodec::codecForName(const char* hint, int accuracy)
+{
+ setup();
+ QListIterator<QTextCodec> i(*all);
+ QTextCodec* result = 0;
+ int best=accuracy;
+ for ( QTextCodec* cursor; (cursor=i); ++i ) {
+ int s = cursor->heuristicNameMatch(hint);
+ if ( s > best ) {
+ best = s;
+ result = cursor;
+ }
+ }
+ return result;
+}
+
+
+/*!
+ Searches all installed QTextCodec objects, returning the one
+ which most recognizes the given content. May return 0.
+
+ Note that this is often a poor choice, since character
+ encodings often use most of the available character sequences,
+ and so only by linguistic analysis could a true match be made.
+
+ \sa heuristicContentMatch()
+*/
+QTextCodec* QTextCodec::codecForContent(const char* chars, int len)
+{
+ setup();
+ QListIterator<QTextCodec> i(*all);
+ QTextCodec* result = 0;
+ int best=0;
+ for ( QTextCodec* cursor; (cursor=i); ++i ) {
+ int s = cursor->heuristicContentMatch(chars,len);
+ if ( s > best ) {
+ best = s;
+ result = cursor;
+ }
+ }
+ return result;
+}
+
+
+/*!
+ \fn const char* QTextCodec::name() const
+ Subclasses of QTextCodec must reimplement this function. It returns
+ the name of the encoding supported by the subclass. When choosing
+ a name for an encoding, consider these points:
+ <ul>
+ <li>On X11, heuristicNameMatch( const char * hint )
+ is used to test if a the QTextCodec
+ can convert between Unicode and the encoding of a font
+ with encoding \e hint, such as "iso8859-1" for Latin-1 fonts,
+ "koi8-r" for Russian KOI8 fonts.
+ The default algorithm of heuristicNameMatch() uses name().
+ <li>Some applications may use this function to present
+ encodings to the end user.
+ </ul>
+*/
+
+/*!
+ \fn int QTextCodec::mibEnum() const
+
+ Subclasses of QTextCodec must reimplement this function. It returns the
+ MIBenum (see
+ <a href="ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets">
+ the IANA character-sets encoding file</a> for more information).
+ It is important that each QTextCodec subclass return the correct unique
+ value for this function.
+*/
+
+
+/*!
+ \fn int QTextCodec::heuristicContentMatch(const char* chars, int len) const
+
+ Subclasses of QTextCodec must reimplement this function. It examines
+ the first \a len bytes of \a chars and returns a value indicating how
+ likely it is that the string is a prefix of text encoded in the
+ encoding of the subclass. Any negative return value indicates that the text
+ is detectably not in the encoding (eg. it contains undefined characters).
+ A return value of 0 indicates that the text should be decoded with this
+ codec rather than as ASCII, but there
+ is no particular evidence. The value should range up to \a len. Thus,
+ most decoders will return -1, 0, or -\a len.
+
+ The characters are not null terminated.
+
+ \sa codecForContent().
+*/
+
+
+/*!
+ Creates a QTextDecoder which stores enough state to decode chunks
+ of char* data to create chunks of Unicode data. The default implementation
+ creates a stateless decoder, which is sufficient for only the simplest
+ encodings where each byte corresponds to exactly one Unicode character.
+
+ The caller is responsible for deleting the returned object.
+*/
+QTextDecoder* QTextCodec::makeDecoder() const
+{
+ return new QTextStatelessDecoder(this);
+}
+
+
+/*!
+ Creates a QTextEncoder which stores enough state to encode chunks
+ of Unicode data as char* data. The default implementation
+ creates a stateless encoder, which is sufficient for only the simplest
+ encodings where each Unicode character corresponds to exactly one char.
+
+ The caller is responsible for deleting the returned object.
+*/
+QTextEncoder* QTextCodec::makeEncoder() const
+{
+ return new QTextStatelessEncoder(this);
+}
+
+
+/*!
+ Subclasses of QTextCodec must reimplement this function or
+ makeDecoder(). It converts the first \a len characters of \a chars
+ to Unicode.
+
+ The default implementation makes a decoder with makeDecoder() and
+ converts the input with that. Note that the default makeDecoder()
+ implementation makes a decoder that simply calls
+ this function, hence subclasses \e must reimplement one function or
+ the other to avoid infinite recursion.
+*/
+QString QTextCodec::toUnicode(const char* chars, int len) const
+{
+ QTextDecoder* i = makeDecoder();
+ QString result = i->toUnicode(chars,len);
+ delete i;
+ return result;
+}
+
+
+/*!
+ Subclasses of QTextCodec must reimplement either this function or
+ makeEncoder(). It converts the first \a lenInOut characters of \a
+ uc from Unicode to the encoding of the subclass. If \a lenInOut
+ is negative or too large, the length of \a uc is used instead.
+
+ The value returned is the property of the caller, which is
+ responsible for deleting it with "delete []". The length of the
+ resulting Unicode character sequence is returned in \a lenInOut.
+
+ The default implementation makes an encoder with makeEncoder() and
+ converts the input with that. Note that the default makeEncoder()
+ implementation makes an encoder that simply calls
+ this function, hence subclasses \e must reimplement one function or
+ the other to avoid infinite recursion.
+*/
+
+QCString QTextCodec::fromUnicode(const QString& uc, int& lenInOut) const
+{
+ QTextEncoder* i = makeEncoder();
+ QCString result = i->fromUnicode(uc, lenInOut);
+ delete i;
+ return result;
+}
+
+/*!
+ \overload QCString QTextCodec::fromUnicode(const QString& uc) const
+*/
+QCString QTextCodec::fromUnicode(const QString& uc) const
+{
+ int l = uc.length();
+ return fromUnicode(uc,l);
+}
+
+/*!
+ \overload QString QTextCodec::toUnicode(const QByteArray& a, int len) const
+*/
+QString QTextCodec::toUnicode(const QByteArray& a, int len) const
+{
+ return toUnicode(a.data(),len);
+}
+
+/*!
+ \overload QString QTextCodec::toUnicode(const QByteArray& a) const
+*/
+QString QTextCodec::toUnicode(const QByteArray& a) const
+{
+ return toUnicode(a.data(),a.size());
+}
+
+/*!
+ \overload QString QTextCodec::toUnicode(const char* chars) const
+*/
+QString QTextCodec::toUnicode(const char* chars) const
+{
+ return toUnicode(chars,qstrlen(chars));
+}
+
+/*!
+ Returns TRUE if the unicode character \a ch can be fully encoded
+ with this codec. The default implementation tests if the result of
+ toUnicode(fromUnicode(ch)) is the original \a ch. Subclasses may be
+ able to improve the efficiency.
+*/
+bool QTextCodec::canEncode( QChar ch ) const
+{
+ return toUnicode(fromUnicode(ch)) == ch;
+}
+
+/*!
+ Returns TRUE if the unicode string \a s can be fully encoded
+ with this codec. The default implementation tests if the result of
+ toUnicode(fromUnicode(s)) is the original \a s. Subclasses may be
+ able to improve the efficiency.
+*/
+bool QTextCodec::canEncode( const QString& s ) const
+{
+ return toUnicode(fromUnicode(s)) == s;
+}
+
+
+
+/*!
+ \class QTextEncoder qtextcodec.h
+ \brief State-based encoder
+
+ A QTextEncoder converts Unicode into another format, remembering
+ any state that is required between calls.
+
+ \sa QTextCodec::makeEncoder()
+*/
+
+/*!
+ Destructs the encoder.
+*/
+QTextEncoder::~QTextEncoder()
+{
+}
+/*!
+ \fn QCString QTextEncoder::fromUnicode(const QString& uc, int& lenInOut)
+
+ Converts \a lenInOut characters (not bytes) from \a uc, producing
+ a QCString. \a lenInOut will also be set to the
+ \link QCString::length() length\endlink of the result (in bytes).
+
+ The encoder is free to record state to use when subsequent calls are
+ made to this function (for example, it might change modes with escape
+ sequences if needed during the encoding of one string, then assume that
+ mode applies when a subsequent call begins).
+*/
+
+/*!
+ \class QTextDecoder qtextcodec.h
+ \brief State-based decoder
+
+ A QTextEncoder converts a text format into Unicode, remembering
+ any state that is required between calls.
+
+ \sa QTextCodec::makeEncoder()
+*/
+
+
+/*!
+ Destructs the decoder.
+*/
+QTextDecoder::~QTextDecoder()
+{
+}
+
+/*!
+ \fn QString QTextDecoder::toUnicode(const char* chars, int len)
+
+ Converts the first \a len bytes at \a chars to Unicode, returning the
+ result.
+
+ If not all characters are used (eg. only part of a multi-byte
+ encoding is at the end of the characters), the decoder remembers
+ enough state to continue with the next call to this function.
+*/
+
+#define CHAINED 0xffff
+
+struct QMultiByteUnicodeTable {
+ // If multibyte, ignore unicode and index into multibyte
+ // with the next character.
+ QMultiByteUnicodeTable() : unicode(0xfffd), multibyte(0) { }
+
+ ~QMultiByteUnicodeTable()
+ {
+ if ( multibyte )
+ delete [] multibyte;
+ }
+
+ ushort unicode;
+ QMultiByteUnicodeTable* multibyte;
+};
+
+static int getByte(char* &cursor)
+{
+ int byte = 0;
+ if ( *cursor ) {
+ if ( cursor[1] == 'x' )
+ byte = strtol(cursor+2,&cursor,16);
+ else if ( cursor[1] == 'd' )
+ byte = strtol(cursor+2,&cursor,10);
+ else
+ byte = strtol(cursor+2,&cursor,8);
+ }
+ return byte&0xff;
+}
+
+#ifndef QT_NO_CODECS
+class QTextCodecFromIOD;
+
+class QTextCodecFromIODDecoder : public QTextDecoder {
+ const QTextCodecFromIOD* codec;
+ QMultiByteUnicodeTable* mb;
+public:
+ QTextCodecFromIODDecoder(const QTextCodecFromIOD* c);
+ QString toUnicode(const char* chars, int len);
+};
+
+class QTextCodecFromIOD : public QTextCodec {
+ friend class QTextCodecFromIODDecoder;
+
+ QCString n;
+
+ // If from_unicode_page[row()][cell()] is 0 and from_unicode_page_multibyte,
+ // use from_unicode_page_multibyte[row()][cell()] as string.
+ char** from_unicode_page;
+ char*** from_unicode_page_multibyte;
+ char unkn;
+
+ // Only one of these is used
+ ushort* to_unicode;
+ QMultiByteUnicodeTable* to_unicode_multibyte;
+ int max_bytes_per_char;
+ QStrList aliases;
+
+ bool stateless() const { return !to_unicode_multibyte; }
+
+public:
+ QTextCodecFromIOD(QIODevice* iod)
+ {
+ from_unicode_page = 0;
+ to_unicode_multibyte = 0;
+ to_unicode = 0;
+ from_unicode_page_multibyte = 0;
+ max_bytes_per_char = 1;
+
+ const int maxlen=100;
+ char line[maxlen];
+ char esc='\\';
+ bool incmap = FALSE;
+ while (iod->readLine(line,maxlen) > 0) {
+ if (0==qstrnicmp(line,"<code_set_name>",15))
+ n = line+15;
+ else if (0==qstrnicmp(line,"<escape_char>",13))
+ esc = line[14];
+ else if (0==qstrnicmp(line,"% alias ",8)) {
+ aliases.append(line+8);
+ } else if (0==qstrnicmp(line,"CHARMAP",7)) {
+ if (!from_unicode_page) {
+ from_unicode_page = new char*[256];
+ for (int i=0; i<256; i++)
+ from_unicode_page[i]=0;
+ }
+ if (!to_unicode) {
+ to_unicode = new ushort[256];
+ }
+ incmap = TRUE;
+ } else if (0==qstrnicmp(line,"END CHARMAP",11))
+ break;
+ else if (incmap) {
+ char* cursor = line;
+ int byte,unicode=-1;
+ ushort* mb_unicode=0;
+ const int maxmb=8; // more -> we'll need to improve datastructures
+ char mb[maxmb+1];
+ int nmb=0;
+
+ while (*cursor && *cursor!=' ')
+ cursor++;
+ while (*cursor && *cursor!=esc)
+ cursor++;
+ byte = getByte(cursor);
+
+ if ( *cursor == esc ) {
+ if ( !to_unicode_multibyte ) {
+ to_unicode_multibyte = new QMultiByteUnicodeTable[256];
+ for (int i=0; i<256; i++) {
+ to_unicode_multibyte[i].unicode = to_unicode[i];
+ to_unicode_multibyte[i].multibyte = 0;
+ }
+ delete [] to_unicode;
+ to_unicode = 0;
+ }
+ QMultiByteUnicodeTable* mbut = to_unicode_multibyte+byte;
+ mb[nmb++] = byte;
+ while ( nmb < maxmb && *cursor == esc ) {
+ // Always at least once
+
+ mbut->unicode = CHAINED;
+ byte = getByte(cursor);
+ mb[nmb++] = byte;
+ if (!mbut->multibyte) {
+ mbut->multibyte =
+ new QMultiByteUnicodeTable[256];
+ }
+ mbut = mbut->multibyte+byte;
+ mb_unicode = & mbut->unicode;
+ }
+
+ if ( nmb > max_bytes_per_char )
+ max_bytes_per_char = nmb;
+ }
+ while (*cursor && (*cursor!='<' || cursor[1]!='U'))
+ cursor++;
+ if ( *cursor )
+ unicode = strtol(cursor+2,&cursor,16);
+ if (unicode >= 0 && unicode <= 0xffff)
+ {
+ QChar ch((ushort)unicode);
+ if (!from_unicode_page[ch.row()]) {
+ from_unicode_page[ch.row()] = new char[256];
+ for (int i=0; i<256; i++)
+ from_unicode_page[ch.row()][i]=0;
+ }
+ if ( mb_unicode ) {
+ from_unicode_page[ch.row()][ch.cell()] = 0;
+ if (!from_unicode_page_multibyte) {
+ from_unicode_page_multibyte = new char**[256];
+ for (int i=0; i<256; i++)
+ from_unicode_page_multibyte[i]=0;
+ }
+ if (!from_unicode_page_multibyte[ch.row()]) {
+ from_unicode_page_multibyte[ch.row()] = new char*[256];
+ for (int i=0; i<256; i++)
+ from_unicode_page_multibyte[ch.row()][i] = 0;
+ }
+ mb[nmb++] = 0;
+ from_unicode_page_multibyte[ch.row()][ch.cell()]
+ = qstrdup(mb);
+ *mb_unicode = unicode;
+ } else {
+ from_unicode_page[ch.row()][ch.cell()] = (char)byte;
+ if ( to_unicode )
+ to_unicode[byte] = unicode;
+ else
+ to_unicode_multibyte[byte].unicode = unicode;
+ }
+ } else {
+ }
+ }
+ }
+ n = n.stripWhiteSpace();
+
+ unkn = '?'; // ##### Might be a bad choice.
+ }
+
+ ~QTextCodecFromIOD()
+ {
+ if ( from_unicode_page ) {
+ for (int i=0; i<256; i++)
+ if (from_unicode_page[i])
+ delete [] from_unicode_page[i];
+ }
+ if ( from_unicode_page_multibyte ) {
+ for (int i=0; i<256; i++)
+ if (from_unicode_page_multibyte[i])
+ for (int j=0; j<256; j++)
+ if (from_unicode_page_multibyte[i][j])
+ delete [] from_unicode_page_multibyte[i][j];
+ }
+ if ( to_unicode )
+ delete [] to_unicode;
+ if ( to_unicode_multibyte )
+ delete [] to_unicode_multibyte;
+ }
+
+ bool ok() const
+ {
+ return !!from_unicode_page;
+ }
+
+ QTextDecoder* makeDecoder() const
+ {
+ if ( stateless() )
+ return QTextCodec::makeDecoder();
+ else
+ return new QTextCodecFromIODDecoder(this);
+ }
+
+ const char* name() const
+ {
+ return n;
+ }
+
+ int mibEnum() const
+ {
+ return 0; // #### Unknown.
+ }
+
+ int heuristicContentMatch(const char*, int) const
+ {
+ return 0;
+ }
+
+ int heuristicNameMatch(const char* hint) const
+ {
+ int bestr = QTextCodec::heuristicNameMatch(hint);
+ QStrListIterator it(aliases);
+ char* a;
+ while ((a=it.current())) {
+ ++it;
+ int r = simpleHeuristicNameMatch(a,hint);
+ if (r > bestr)
+ bestr = r;
+ }
+ return bestr;
+ }
+
+ QString toUnicode(const char* chars, int len) const
+ {
+ const uchar* uchars = (const uchar*)chars;
+ QString result;
+ QMultiByteUnicodeTable* multibyte=to_unicode_multibyte;
+ if ( multibyte ) {
+ while (len--) {
+ QMultiByteUnicodeTable& mb = multibyte[*uchars];
+ if ( mb.multibyte ) {
+ // Chained multi-byte
+ multibyte = mb.multibyte;
+ } else {
+ result += QChar(mb.unicode);
+ multibyte=to_unicode_multibyte;
+ }
+ uchars++;
+ }
+ } else {
+ while (len--)
+ result += QChar(to_unicode[*uchars++]);
+ }
+ return result;
+ }
+
+ QCString fromUnicode(const QString& uc, int& lenInOut) const
+ {
+ if (lenInOut > (int)uc.length())
+ lenInOut = uc.length();
+ int rlen = lenInOut*max_bytes_per_char;
+ QCString rstr(rlen);
+ char* cursor = rstr.data();
+ char* s=0;
+ int l = lenInOut;
+ int lout = 0;
+ for (int i=0; i<l; i++) {
+ QChar ch = uc[i];
+ if ( ch == QChar::null ) {
+ // special
+ *cursor++ = 0;
+ } else if ( from_unicode_page[ch.row()] &&
+ from_unicode_page[ch.row()][ch.cell()] )
+ {
+ *cursor++ = from_unicode_page[ch.row()][ch.cell()];
+ lout++;
+ } else if ( from_unicode_page_multibyte &&
+ from_unicode_page_multibyte[ch.row()] &&
+ (s=from_unicode_page_multibyte[ch.row()][ch.cell()]) )
+ {
+ while (*s) {
+ *cursor++ = *s++;
+ lout++;
+ }
+ } else {
+ *cursor++ = unkn;
+ lout++;
+ }
+ }
+ *cursor = 0;
+ lenInOut = lout;
+ return rstr;
+ }
+};
+
+QTextCodecFromIODDecoder::QTextCodecFromIODDecoder(const QTextCodecFromIOD* c) :
+ codec(c)
+{
+ mb = codec->to_unicode_multibyte;
+}
+
+QString QTextCodecFromIODDecoder::toUnicode(const char* chars, int len)
+{
+ const uchar* uchars = (const uchar*)chars;
+ QString result;
+ while (len--) {
+ QMultiByteUnicodeTable& t = mb[*uchars];
+ if ( t.multibyte ) {
+ // Chained multi-byte
+ mb = t.multibyte;
+ } else {
+ if ( t.unicode )
+ result += QChar(t.unicode);
+ mb=codec->to_unicode_multibyte;
+ }
+ uchars++;
+ }
+ return result;
+}
+
+/*!
+ Reads a POSIX2 charmap definition from \a iod.
+ The parser recognizes the following lines:
+<pre>
+ &lt;code_set_name&gt; <i>name</i>
+ &lt;escape_char&gt; <i>character</i>
+ % alias <i>alias</i>
+ CHARMAP
+ &lt;<i>token</i>&gt; /x<i>hexbyte</i> &lt;U<i>unicode</i>&gt; ...
+ &lt;<i>token</i>&gt; /d<i>decbyte</i> &lt;U<i>unicode</i>&gt; ...
+ &lt;<i>token</i>&gt; /<i>octbyte</i> &lt;U<i>unicode</i>&gt; ...
+ &lt;<i>token</i>&gt; /<i>any</i>/<i>any</i>... &lt;U<i>unicode</i>&gt; ...
+ END CHARMAP
+</pre>
+
+ The resulting QTextCodec is returned (and also added to the
+ global list of codecs). The name() of the result is taken
+ from the code_set_name.
+
+ Note that a codec constructed in this way uses much more memory
+ and is slower than a hand-written QTextCodec subclass, since
+ tables in code are in memory shared by all applications simultaneously
+ using Qt.
+
+ \sa loadCharmapFile()
+*/
+QTextCodec* QTextCodec::loadCharmap(QIODevice* iod)
+{
+ QTextCodecFromIOD* r = new QTextCodecFromIOD(iod);
+ if ( !r->ok() ) {
+ delete r;
+ r = 0;
+ }
+ return r;
+}
+
+/*!
+ A convenience function for loadCharmap().
+*/
+QTextCodec* QTextCodec::loadCharmapFile(QString filename)
+{
+ QFile f(filename);
+ if (f.open(IO_ReadOnly)) {
+ QTextCodecFromIOD* r = new QTextCodecFromIOD(&f);
+ if ( !r->ok() )
+ delete r;
+ else
+ return r;
+ }
+ return 0;
+}
+#endif //QT_NO_CODECS
+
+
+/*!
+ Returns a string representing the current language.
+*/
+
+const char* QTextCodec::locale()
+{
+ static QCString lang;
+ if ( lang.isEmpty() ) {
+ lang = getenv( "LANG" ); //########Windows??
+ if ( lang.isEmpty() )
+ lang = "C";
+ }
+ return lang;
+}
+
+
+
+#ifndef QT_NO_CODECS
+
+class QSimpleTextCodec: public QTextCodec
+{
+public:
+ QSimpleTextCodec( int );
+ ~QSimpleTextCodec();
+
+ QString toUnicode(const char* chars, int len) const;
+ QCString fromUnicode(const QString& uc, int& lenInOut ) const;
+
+ const char* name() const;
+ int mibEnum() const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+
+ int heuristicNameMatch(const char* hint) const;
+
+private:
+ int forwardIndex;
+};
+
+
+#define LAST_MIB 2259
+
+static struct {
+ const char * cs;
+ int mib;
+ Q_UINT16 values[128];
+} unicodevalues[] = {
+ // from RFC 1489, ftp://ftp.isi.edu/in-notes/rfc1489.txt
+ { "KOI8-R", 2084,
+ { 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
+ 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
+ 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219/**/, 0x221A, 0x2248,
+ 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
+ 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556,
+ 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
+ 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565,
+ 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9,
+ 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
+ 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
+ 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
+ 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
+ 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
+ 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
+ 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
+ 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A } },
+ // /**/ - The BULLET OPERATOR is confused. Some people think
+ // it should be 0x2022 (BULLET).
+
+ // next bits generated from tables on the Unicode 2.0 CD. we can
+ // use these tables since this is part of the transition to using
+ // unicode everywhere in qt.
+
+ // $ for A in 8 9 A B C D E F ; do for B in 0 1 2 3 4 5 6 7 8 9 A B C D E F ; do echo 0x${A}${B} 0xFFFD ; done ; done > /tmp/digits ; for a in 8859-* ; do ( awk '/^0x[89ABCDEF]/{ print $1, $2 }' < $a ; cat /tmp/digits ) | sort | uniq -w4 | cut -c6- | paste '-d ' - - - - - - - - | sed -e 's/ /, /g' -e 's/$/,/' -e '$ s/,$/} },/' -e '1 s/^/{ /' > ~/tmp/$a ; done
+
+ // then I inserted the files manually.
+ { "ISO 8859-1", 4,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF} },
+ { "ISO 8859-2", 5,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7,
+ 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
+ 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7,
+ 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
+ 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
+ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
+ 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
+ 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
+ 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
+ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
+ 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
+ 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9} },
+ { "ISO 8859-3", 6,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0xFFFD, 0x0124, 0x00A7,
+ 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0xFFFD, 0x017B,
+ 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7,
+ 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0xFFFD, 0x017C,
+ 0x00C0, 0x00C1, 0x00C2, 0xFFFD, 0x00C4, 0x010A, 0x0108, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0xFFFD, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7,
+ 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0xFFFD, 0x00E4, 0x010B, 0x0109, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0xFFFD, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7,
+ 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9} },
+ { "ISO 8859-4", 7,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7,
+ 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF,
+ 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7,
+ 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B,
+ 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
+ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A,
+ 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF,
+ 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
+ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B,
+ 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9} },
+ { "ISO 8859-5", 8,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
+ 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+ 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
+ 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F} },
+ { "ISO 8859-6-I", 82,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0xFFFD, 0xFFFD, 0xFFFD, 0x00A4, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x060C, 0x00AD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0x061B, 0xFFFD, 0xFFFD, 0xFFFD, 0x061F,
+ 0xFFFD, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
+ 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
+ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637,
+ 0x0638, 0x0639, 0x063A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647,
+ 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F,
+ 0x0650, 0x0651, 0x0652, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
+ { "ISO 8859-7", 10,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x2018, 0x2019, 0x00A3, 0xFFFD, 0xFFFD, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0xFFFD, 0x00AB, 0x00AC, 0x00AD, 0xFFFD, 0x2015,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7,
+ 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
+ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03A0, 0x03A1, 0xFFFD, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0xFFFD} },
+ { "ISO 8859-8-I", 85,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0xFFFD, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x203E,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2017,
+ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
+ 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
+ 0x05E8, 0x05E9, 0x05EA, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
+ { "ISO 8859-9", 12,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF} },
+ { "ISO 8859-10", 13,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7,
+ 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A,
+ 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7,
+ 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2015, 0x016B, 0x014B,
+ 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
+ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168,
+ 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
+ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169,
+ 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138} },
+ { "ISO 8859-13", 0, // ############# what is the mib?
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x201D, 0x00A2, 0x00A3, 0x00A4, 0x201E, 0x00A6, 0x00A7,
+ 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x201C, 0x00B5, 0x00B6, 0x00B7,
+ 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
+ 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
+ 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
+ 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
+ 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
+ 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
+ 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
+ 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
+ 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019} },
+ { "ISO 8859-14", 0, // ############# what is the mib?
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x1E02, 0x1E03, 0x00A3, 0x010A, 0x010B, 0x1E0A, 0x00A7,
+ 0x1E80, 0x00A9, 0x1E82, 0x1E0B, 0x1EF2, 0x00AD, 0x00AE, 0x0178,
+ 0x1E1E, 0x1E1F, 0x0120, 0x0121, 0x1E40, 0x1E41, 0x00B6, 0x1E56,
+ 0x1E81, 0x1E57, 0x1E83, 0x1E60, 0x1EF3, 0x1E84, 0x1E85, 0x1E61,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x0174, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x1E6A,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x0176, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF} },
+ { "ISO 8859-15", 0, // ############# what is the mib?
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7,
+ 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7,
+ 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF} },
+
+ // next bits generated again from tables on the Unicode 3.0 CD.
+
+ // $ for a in CP* ; do ( awk '/^0x[89ABCDEF]/{ print $1, $2 }' < $a ) | sort | sed -e 's/#UNDEF.*$/0xFFFD/' | cut -c6- | paste '-d ' - - - - - - - - | sed -e 's/ /, /g' -e 's/$/,/' -e '$ s/,$/} },/' -e '1 s/^/{ /' > ~/tmp/$a ; done
+
+ { "CP 874", 0, //### what is the mib?
+ { 0x20AC, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2026, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
+ 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
+ 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
+ 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
+ 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
+ 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
+ 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
+ 0x0E38, 0x0E39, 0x0E3A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0E3F,
+ 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
+ 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
+ 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
+ 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
+ { "CP 1250", 2250,
+ { 0x20AC, 0xFFFD, 0x201A, 0xFFFD, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0xFFFD, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
+ 0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
+ 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
+ 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
+ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
+ 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
+ 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
+ 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
+ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
+ 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
+ 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9} },
+ { "CP 1251", 2251,
+ { 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
+ 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
+ 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
+ 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
+ 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
+ 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F} },
+ { "CP 1252", 2252,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0x017D, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0x017E, 0x0178,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF} },
+ { "CP 1253", 2253,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0xFFFD, 0x2030, 0xFFFD, 0x2039, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0xFFFD, 0x203A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0xFFFD, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
+ 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
+ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03A0, 0x03A1, 0xFFFD, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0xFFFD} },
+ { "CP 1254", 2254,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0xFFFD, 0x0178,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF} },
+ { "CP 1255", 2255,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0xFFFD, 0x2039, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0xFFFD, 0x203A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AA, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
+ 0x05B8, 0x05B9, 0xFFFD, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
+ 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
+ 0x05F4, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
+ 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
+ 0x05E8, 0x05E9, 0x05EA, 0xFFFD, 0xFFFD, 0x200E, 0x200F, 0xFFFD} },
+ { "CP 1256", 2256,
+ { 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
+ 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
+ 0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
+ 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
+ 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
+ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
+ 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643,
+ 0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
+ 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
+ 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2} },
+ { "CP 1257", 2257,
+ { 0x20AC, 0xFFFD, 0x201A, 0xFFFD, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0xFFFD, 0x2030, 0xFFFD, 0x2039, 0xFFFD, 0x00A8, 0x02C7, 0x00B8,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0xFFFD, 0x203A, 0xFFFD, 0x00AF, 0x02DB, 0xFFFD,
+ 0x00A0, 0xFFFD, 0x00A2, 0x00A3, 0x00A4, 0xFFFD, 0x00A6, 0x00A7,
+ 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
+ 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
+ 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
+ 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
+ 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
+ 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
+ 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
+ 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
+ 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9} },
+ { "CP 1258", 2258,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0xFFFD, 0x2039, 0x0152, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0xFFFD, 0x203A, 0x0153, 0xFFFD, 0xFFFD, 0x0178,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
+ 0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
+ 0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF} },
+
+ // this one is generated from the charmap file located in /usr/share/i18n/charmaps
+ // on most Linux distributions. The thai character set tis620 is byte by byte equivalent
+ // to iso8859-11, so we name it 8859-11 here, but recognise the name tis620 too.
+
+ // $ for A in 8 9 A B C D E F ; do for B in 0 1 2 3 4 5 6 7 8 9 A B C D E F ; do echo x${A}${B} 0xFFFD ; done ; done > /tmp/digits ; ( cut -c25- < TIS-620 ; cat /tmp/digits ) | awk '/^x[89ABCDEF]/{ print $1, $2 }' | sed -e 's/<U/0x/' -e 's/>//' | sort | uniq -w4 | cut -c5- | paste '-d ' - - - - - - - - | sed -e 's/ /, /g' -e 's/$/,/' -e '$ s/,$/} },/' -e '1 s/^/{ /' > ~/tmp/tis-620
+ { "ISO 8859-11", 2259, // Thai character set mib enum taken from tis620 (which is byte by byte equivalent)
+ { 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
+ 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
+ 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
+ 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
+ 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
+ 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
+ 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
+ 0x0E38, 0x0E39, 0x0E3A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0E3F,
+ 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
+ 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
+ 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
+ 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
+
+};
+
+
+static const QSimpleTextCodec * reverseOwner = 0;
+static QArray<char> * reverseMap = 0;
+
+
+QSimpleTextCodec::QSimpleTextCodec( int i )
+ : QTextCodec(), forwardIndex( i )
+{
+}
+
+
+QSimpleTextCodec::~QSimpleTextCodec()
+{
+ if ( reverseOwner == this ) {
+ delete reverseMap;
+ reverseMap = 0;
+ reverseOwner = 0;
+ }
+}
+
+// what happens if strlen(chars)<len? what happens if !chars? if len<1?
+QString QSimpleTextCodec::toUnicode(const char* chars, int len) const
+{
+ QString r;
+ const unsigned char * c = (const unsigned char *)chars;
+ for( int i=0; i<len && c[i]; i++ ) { // Note: NUL ends string
+ if ( c[i] > 127 )
+ r[i] = unicodevalues[forwardIndex].values[c[i]-128];
+ else
+ r[i] = c[i];
+ }
+ return r;
+}
+
+
+QCString QSimpleTextCodec::fromUnicode(const QString& uc, int& len ) const
+{
+ if ( reverseOwner != this ) {
+ int m = 0;
+ int i = 0;
+ while( i < 128 ) {
+ if ( unicodevalues[forwardIndex].values[i] > m &&
+ unicodevalues[forwardIndex].values[i] < 0xfffd )
+ m = unicodevalues[forwardIndex].values[i];
+ i++;
+ }
+ m++;
+ if ( !reverseMap )
+ reverseMap = new QArray<char>( m );
+ if ( m > (int)(reverseMap->size()) )
+ reverseMap->resize( m );
+ for( i = 0; i < 128 && i < m; i++ )
+ (*reverseMap)[i] = (char)i;
+ for( ;i < m; i++ )
+ (*reverseMap)[i] = '?';
+ for( i=128; i<256; i++ ) {
+ int u = unicodevalues[forwardIndex].values[i-128];
+ if ( u < m )
+ (*reverseMap)[u] = (char)(unsigned char)(i);
+ }
+ reverseOwner = this;
+ }
+ if ( len <0 || len > (int)uc.length() )
+ len = uc.length();
+ QCString r( len+1 );
+ int i;
+ int u;
+ for( i=0; i<len; i++ ) {
+ u = uc[i].cell() + 256* uc[i].row();
+ r[i] = u < 128 ? u : (
+ ( u < (int)reverseMap->size() ) ? (*reverseMap)[u] : '?' );
+ }
+ r[len] = 0;
+ return r;
+}
+
+
+const char* QSimpleTextCodec::name() const
+{
+ return unicodevalues[forwardIndex].cs;
+}
+
+
+int QSimpleTextCodec::mibEnum() const
+{
+ return unicodevalues[forwardIndex].mib;
+}
+
+int QSimpleTextCodec::heuristicNameMatch(const char* hint) const
+{
+ if ( hint[0]=='k' ) {
+ // Help people with messy fonts
+ if ( QCString(hint) == "koi8-1" )
+ return QTextCodec::heuristicNameMatch("koi8-r")-1;
+ if ( QCString(hint) == "koi8-ru" )
+ return QTextCodec::heuristicNameMatch("koi8-r")-1;
+ } else if ( hint[0] == 't' && QCString(name()) == "ISO 8859-11" ) {
+ // 8859-11 and tis620 are byte by bute equivalent
+ int i = simpleHeuristicNameMatch("tis-620", hint);
+ if( i ) return i;
+ }
+ return QTextCodec::heuristicNameMatch(hint);
+}
+
+int QSimpleTextCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ if ( len<1 || !chars )
+ return -1;
+ int i = 0;
+ const uchar * c = (const unsigned char *)chars;
+ int r = 0;
+ while( i<len && c && *c ) {
+ if ( *c >= 128 ) {
+ if ( unicodevalues[forwardIndex].values[(*c)-128] == 0xfffd )
+ return -1;
+ }
+ if ( (*c >= ' ' && *c < 127) ||
+ *c == '\n' || *c == '\t' || *c == '\r' )
+ r++;
+ i++;
+ c++;
+ }
+ if ( mibEnum()==4 )
+ r+=1;
+ return r;
+}
+
+
+static void setupBuiltinCodecs()
+{
+ int i = 0;
+ do {
+ (void)new QSimpleTextCodec( i );
+ } while( unicodevalues[i++].mib != LAST_MIB );
+
+ (void)new QEucJpCodec;
+ (void)new QSjisCodec;
+ (void)new QJisCodec;
+ (void)new QEucKrCodec;
+ (void)new QGbkCodec;
+ (void)new QBig5Codec;
+ (void)new QUtf8Codec;
+ (void)new QUtf16Codec;
+ (void)new QHebrewCodec;
+ (void)new QArabicCodec;
+ (void)new QTsciiCodec;
+}
+
+#else
+
+class QLatin1Codec: public QTextCodec
+{
+public:
+ QLatin1Codec();
+ ~QLatin1Codec();
+
+ QString toUnicode(const char* chars, int len) const;
+ QCString fromUnicode(const QString& uc, int& lenInOut ) const;
+
+ const char* name() const;
+ int mibEnum() const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+
+ int heuristicNameMatch(const char* hint) const;
+
+private:
+ int forwardIndex;
+};
+
+
+QLatin1Codec::QLatin1Codec()
+ : QTextCodec()
+{
+}
+
+
+QLatin1Codec::~QLatin1Codec()
+{
+}
+
+// what happens if strlen(chars)<len? what happens if !chars? if len<1?
+QString QLatin1Codec::toUnicode(const char* chars, int len) const
+{
+ QString r;
+ const unsigned char * c = (const unsigned char *)chars;
+ for( int i=0; i<len && c[i]; i++ ) { // Note: NUL ends string
+ r[i] = c[i];
+ }
+ return r;
+}
+
+
+QCString QLatin1Codec::fromUnicode(const QString& uc, int& len ) const
+{
+ if ( len <0 || len > (int)uc.length() )
+ len = uc.length();
+ QCString r( len+1 );
+ int i;
+ int u;
+ for( i=0; i<len; i++ ) {
+ u = uc[i].cell() + 256* uc[i].row();
+ r[i] = u < 255 ? u : '?';
+ }
+ r[len] = 0;
+ return r;
+}
+
+
+const char* QLatin1Codec::name() const
+{
+ return "iso8859-1";
+}
+
+
+int QLatin1Codec::mibEnum() const
+{
+ return 4;
+}
+
+int QLatin1Codec::heuristicNameMatch(const char* hint) const
+{
+ return QTextCodec::heuristicNameMatch(hint);
+}
+
+int QLatin1Codec::heuristicContentMatch(const char* chars, int len) const
+{
+ if ( len<1 || !chars )
+ return -1;
+ int i = 0;
+ const uchar * c = (const unsigned char *)chars;
+ int r = 0;
+ while( i<len && c && *c ) {
+ if ( *c >= 0x80 && *c < 0xa0 )
+ return -1;
+ if ( (*c >= ' ' && *c < 127) ||
+ *c == '\n' || *c == '\t' || *c == '\r' )
+ r++;
+ i++;
+ c++;
+ }
+ return r;
+}
+
+
+
+static void setupBuiltinCodecs()
+{
+ (void)new QLatin1Codec;
+}
+#endif // QT_NO_CODECS
+
+#endif // QT_NO_TEXTCODEC
diff --git a/qtools/qtextcodec.h b/qtools/qtextcodec.h
new file mode 100644
index 0000000..18ece20
--- /dev/null
+++ b/qtools/qtextcodec.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+**
+** Definition of QTextCodec class
+**
+** Created : 981015
+**
+** Copyright (C) 1998-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 QTEXTCODEC_H
+#define QTEXTCODEC_H
+
+#ifndef QT_H
+#include "qstring.h"
+#endif // QT_H
+
+#ifndef QT_NO_TEXTCODEC
+
+class QTextCodec;
+class QIODevice;
+
+class Q_EXPORT QTextEncoder {
+public:
+ virtual ~QTextEncoder();
+ virtual QCString fromUnicode(const QString& uc, int& lenInOut) = 0;
+};
+
+class Q_EXPORT QTextDecoder {
+public:
+ virtual ~QTextDecoder();
+ virtual QString toUnicode(const char* chars, int len) = 0;
+};
+
+class Q_EXPORT QTextCodec {
+public:
+ virtual ~QTextCodec();
+
+#ifndef QT_NO_CODECS
+ static QTextCodec* loadCharmap(QIODevice*);
+ static QTextCodec* loadCharmapFile(QString filename);
+#endif
+ static QTextCodec* codecForMib(int mib);
+ static QTextCodec* codecForName(const char* hint, int accuracy=0);
+ static QTextCodec* codecForContent(const char* chars, int len);
+ static QTextCodec* codecForIndex(int i);
+ static QTextCodec* codecForLocale();
+
+ static void deleteAllCodecs();
+
+ static const char* locale();
+
+ virtual const char* name() const = 0;
+ virtual int mibEnum() const = 0;
+
+ virtual QTextDecoder* makeDecoder() const;
+ virtual QTextEncoder* makeEncoder() const;
+
+ virtual QString toUnicode(const char* chars, int len) const;
+ virtual QCString fromUnicode(const QString& uc, int& lenInOut) const;
+
+ QCString fromUnicode(const QString& uc) const;
+ QString toUnicode(const QByteArray&, int len) const;
+ QString toUnicode(const QByteArray&) const;
+ QString toUnicode(const char* chars) const;
+ virtual bool canEncode( QChar ) const;
+ virtual bool canEncode( const QString& ) const;
+
+ virtual int heuristicContentMatch(const char* chars, int len) const = 0;
+ virtual int heuristicNameMatch(const char* hint) const;
+
+protected:
+ QTextCodec();
+ static int simpleHeuristicNameMatch(const char* name, const char* hint);
+};
+#endif // QT_NO_TEXTCODEC
+#endif // QTEXTCODEC_H
diff --git a/qtools/qtextstream.cpp b/qtools/qtextstream.cpp
new file mode 100644
index 0000000..774b730
--- /dev/null
+++ b/qtools/qtextstream.cpp
@@ -0,0 +1,2145 @@
+/****************************************************************************
+**
+**
+** Implementation of QTextStream class
+**
+** Created : 940922
+**
+** Copyright (C) 1992-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.
+**
+**********************************************************************/
+
+#include "qtextstream.h"
+
+#ifndef QT_NO_TEXTSTREAM
+#include "qtextcodec.h"
+#include "qregexp.h"
+#include "qbuffer.h"
+#include "qfile.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#if defined(_OS_WIN32_)
+#include <windows.h>
+#endif
+
+// NOT REVISED
+/*!
+ \class QTextStream qtextstream.h
+
+ \brief The QTextStream class provides basic functions for reading and
+ writing text using a QIODevice.
+
+ \ingroup io
+
+ \define endl
+ \define bin
+ \define oct
+ \define dec
+ \define hex
+ \define flush
+ \define ws
+
+ The text stream class has a functional interface that is very
+ similar to that of the standard C++ iostream class. The difference
+ between iostream and QTextStream is that our stream operates on a
+ QIODevice, which is easily subclassed, while iostream operates on
+ FILE * pointers, which can not be subclassed.
+
+ Qt provides several global functions similar to the ones in iostream:
+ <ul>
+ <li> \c bin sets the QTextStream to read/write binary numbers
+ <li> \c oct sets the QTextStream to read/write octal numbers
+ <li> \c dec sets the QTextStream to read/write decimal numbers
+ <li> \c hex sets the QTextStream to read/write hexadecimal numbers
+ <li> \c endl forces a line break
+ <li> \c flush forces the QIODevice to flush any buffered data
+ <li> \c ws eats any available white space (on input)
+ <li> \c reset resets the QTextStream to its default mode (see reset()).
+ </ul>
+
+ \warning By default, QTextStream will automatically detect whether
+ integers in the stream are in decimal, octal, hexadecimal or binary
+ format when reading from the stream. In particular, a leading '0'
+ signifies octal, ie. the sequence "0100" will be interpreted as
+ 64.
+
+ The QTextStream class reads and writes text and it is not
+ appropriate for dealing with binary data (but QDataStream is).
+
+ By default output of Unicode text (ie. QString) is done using the
+ local 8-bit encoding. This can be changed using the setEncoding()
+ method. For input, the QTextStream will auto-detect standard
+ Unicode "byte order marked" text files, but otherwise the local
+ 8-bit encoding is used.
+
+ \sa QDataStream
+*/
+
+/*
+ \class QTSManip qtextstream.h
+
+ \brief The QTSManip class is an internal helper class for the
+ QTextStream.
+
+ It is generally a very bad idea to use this class directly in
+ application programs.
+
+ \internal
+
+ This class makes it possible to give the QTextStream function objects
+ with arguments, like this:
+ \code
+ QTextStream cout( stdout, IO_WriteOnly );
+ cout << setprecision( 8 ); // QTSManip used here!
+ cout << 3.14159265358979323846;
+ \endcode
+
+ The setprecision() function returns a QTSManip object.
+ The QTSManip object contains a pointer to a member function in
+ QTextStream and an integer argument.
+ When serializing a QTSManip into a QTextStream, the function
+ is executed with the argument.
+*/
+
+/*! \fn QTSManip::QTSManip (QTSMFI m, int a)
+
+ Constructs a QTSManip object which will call \a m (a member function
+ in QTextStream which accepts a single int) with argument \a a when
+ QTSManip::exec() is called. Used internally in e.g. endl:
+
+ \code
+ s << "some text" << endl << "more text";
+ \endcode
+*/
+
+/*! \fn void QTSManip::exec (QTextStream& s)
+
+ Calls the member function specified in the constructor, for object
+ \a s. Used internally in e.g. endl:
+
+ \code
+ s << "some text" << endl << "more text";
+ \endcode
+*/
+
+
+/*****************************************************************************
+ QTextStream member functions
+ *****************************************************************************/
+
+#if defined(CHECK_STATE)
+#undef CHECK_STREAM_PRECOND
+#define CHECK_STREAM_PRECOND if ( !dev ) { \
+ qWarning( "QTextStream: No device" ); \
+ return *this; }
+#else
+#define CHECK_STREAM_PRECOND
+#endif
+
+
+#define I_SHORT 0x0010
+#define I_INT 0x0020
+#define I_LONG 0x0030
+#define I_TYPE_MASK 0x00f0
+
+#define I_BASE_2 QTS::bin
+#define I_BASE_8 QTS::oct
+#define I_BASE_10 QTS::dec
+#define I_BASE_16 QTS::hex
+#define I_BASE_MASK (QTS::bin | QTS::oct | QTS::dec | QTS::hex)
+
+#define I_SIGNED 0x0100
+#define I_UNSIGNED 0x0200
+#define I_SIGN_MASK 0x0f00
+
+
+static const QChar QEOF = QChar((ushort)0xffff); //guaranteed not to be a character.
+
+const int QTextStream::basefield = I_BASE_MASK;
+const int QTextStream::adjustfield = ( QTextStream::left |
+ QTextStream::right |
+ QTextStream::internal );
+const int QTextStream::floatfield = ( QTextStream::scientific |
+ QTextStream::fixed );
+
+
+class QTextStreamPrivate {
+public:
+ QTextStreamPrivate(): decoder( 0 ), sourceType( NotSet ) {}
+ ~QTextStreamPrivate() { delete decoder; }
+
+ QTextDecoder *decoder; //???
+ QString ungetcBuf;
+
+ enum SourceType { NotSet, IODevice, String, ByteArray, File };
+ SourceType sourceType;
+};
+
+
+// skips whitespace and returns the first non-whitespace character
+QChar QTextStream::eat_ws()
+{
+ QChar c;
+ do { c = ts_getc(); } while ( c != QEOF && ts_isspace(c) );
+ return c;
+}
+
+void QTextStream::init()
+{
+ // ### ungetcBuf = QEOF;
+ dev = 0; // no device set
+ fstrm = owndev = FALSE;
+ mapper = 0;
+ d = new QTextStreamPrivate;
+ doUnicodeHeader = TRUE; //default to autodetect
+ latin1 = TRUE; // ### should use local?
+ internalOrder = QChar::networkOrdered(); //default to network order
+}
+
+/*!
+ Constructs a data stream that has no IO device.
+*/
+
+QTextStream::QTextStream()
+{
+ init();
+ setEncoding( Locale ); //###
+ reset();
+ d->sourceType = QTextStreamPrivate::NotSet;
+}
+
+/*!
+ Constructs a text stream that uses the IO device \a iod.
+*/
+
+QTextStream::QTextStream( QIODevice *iod )
+{
+ init();
+ setEncoding( Locale ); //###
+ dev = iod; // set device
+ reset();
+ d->sourceType = QTextStreamPrivate::IODevice;
+}
+
+// TODO: use special-case handling of this case in QTextStream, and
+// simplify this class to only deal with QChar or QString data.
+class QStringBuffer : public QIODevice {
+public:
+ QStringBuffer( QString* str );
+ ~QStringBuffer();
+ bool open( int m );
+ void close();
+ void flush();
+ uint size() const;
+ int at() const;
+ bool at( int pos );
+ int readBlock( char *p, uint len );
+ int writeBlock( const char *p, uint len );
+ int getch();
+ int putch( int ch );
+ int ungetch( int ch );
+protected:
+ QString* s;
+
+private: // Disabled copy constructor and operator=
+ QStringBuffer( const QStringBuffer & );
+ QStringBuffer &operator=( const QStringBuffer & );
+};
+
+
+QStringBuffer::QStringBuffer( QString* str )
+{
+ s = str;
+}
+
+QStringBuffer::~QStringBuffer()
+{
+}
+
+
+bool QStringBuffer::open( int m )
+{
+ if ( !s ) {
+#if defined(CHECK_STATE)
+ qWarning( "QStringBuffer::open: No string" );
+#endif
+ return FALSE;
+ }
+ if ( isOpen() ) { // buffer already open
+#if defined(CHECK_STATE)
+ qWarning( "QStringBuffer::open: Buffer already open" );
+#endif
+ return FALSE;
+ }
+ setMode( m );
+ if ( m & IO_Truncate ) { // truncate buffer
+ s->truncate( 0 );
+ }
+ if ( m & IO_Append ) { // append to end of buffer
+ ioIndex = s->length()*sizeof(QChar);
+ } else {
+ ioIndex = 0;
+ }
+ setState( IO_Open );
+ setStatus( 0 );
+ return TRUE;
+}
+
+void QStringBuffer::close()
+{
+ if ( isOpen() ) {
+ setFlags( IO_Direct );
+ ioIndex = 0;
+ }
+}
+
+void QStringBuffer::flush()
+{
+}
+
+uint QStringBuffer::size() const
+{
+ return s ? s->length()*sizeof(QChar) : 0;
+}
+
+int QStringBuffer::at() const
+{
+ return ioIndex;
+}
+
+bool QStringBuffer::at( int pos )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "QStringBuffer::at: Buffer is not open" );
+ return FALSE;
+ }
+#endif
+ if ( (uint)pos >= s->length()*2 ) {
+#if defined(CHECK_RANGE)
+ qWarning( "QStringBuffer::at: Index %d out of range", pos );
+#endif
+ return FALSE;
+ }
+ ioIndex = pos;
+ return TRUE;
+}
+
+
+int QStringBuffer::readBlock( char *p, uint len )
+{
+#if defined(CHECK_STATE)
+ CHECK_PTR( p );
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QStringBuffer::readBlock: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QStringBuffer::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)ioIndex + len > s->length()*sizeof(QChar) ) {
+ // overflow
+ if ( (uint)ioIndex >= s->length()*sizeof(QChar) ) {
+ setStatus( IO_ReadError );
+ return -1;
+ } else {
+ len = s->length()*2 - (uint)ioIndex;
+ }
+ }
+ memcpy( p, ((const char*)(s->unicode()))+ioIndex, len );
+ ioIndex += len;
+ return len;
+}
+
+int QStringBuffer::writeBlock( const char *p, uint len )
+{
+#if defined(CHECK_NULL)
+ if ( p == 0 && len != 0 )
+ qWarning( "QStringBuffer::writeBlock: Null pointer error" );
+#endif
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QStringBuffer::writeBlock: Buffer not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "QStringBuffer::writeBlock: Write operation not permitted" );
+ return -1;
+ }
+ if ( ioIndex&1 ) {
+ qWarning( "QStringBuffer::writeBlock: non-even index - non Unicode" );
+ return -1;
+ }
+ if ( len&1 ) {
+ qWarning( "QStringBuffer::writeBlock: non-even length - non Unicode" );
+ return -1;
+ }
+#endif
+ s->replace(ioIndex/2, len/2, (QChar*)p, len/2);
+ ioIndex += len;
+ return len;
+}
+
+int QStringBuffer::getch()
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QStringBuffer::getch: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QStringBuffer::getch: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)ioIndex >= s->length()*2 ) { // overflow
+ setStatus( IO_ReadError );
+ return -1;
+ }
+ return *((char*)s->unicode() + ioIndex++);
+}
+
+int QStringBuffer::putch( int ch )
+{
+ char c = ch;
+ if ( writeBlock(&c,1) < 0 )
+ return -1;
+ else
+ return ch;
+}
+
+int QStringBuffer::ungetch( int ch )
+{
+#if defined(CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "QStringBuffer::ungetch: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "QStringBuffer::ungetch: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( ch != -1 ) { // something to do with eof
+ if ( ioIndex )
+ ioIndex--;
+ else
+ ch = -1;
+ }
+ return ch;
+}
+
+
+/*!
+ Constructs a text stream that operates on a Unicode QString through an
+ internal device.
+
+ If you set an encoding or codec with setEncoding() or setCodec(), this
+ setting is ignored for text streams that operate on QString.
+
+ Example:
+ \code
+ QString str;
+ QTextStream ts( &str, IO_WriteOnly );
+ ts << "pi = " << 3.14; // str == "pi = 3.14"
+ \endcode
+
+ Writing data to the text stream will modify the contents of the string.
+ The string will be expanded when data is written beyond the end of the
+ string. Note that the string will not be truncated:
+ \code
+ QString str = "pi = 3.14";
+ QTextStream ts( &str, IO_WriteOnly );
+ ts << "2+2 = " << 2+2; // str == "2+2 = 414"
+ \endcode
+
+ Note that since QString is Unicode, you should not use readRawBytes()
+ or writeRawBytes() on such a stream.
+*/
+
+QTextStream::QTextStream( QString* str, int filemode )
+{
+ // TODO: optimize for this case as it becomes more common
+ // (see QStringBuffer above)
+ init();
+ dev = new QStringBuffer( str );
+ ((QStringBuffer *)dev)->open( filemode );
+ owndev = TRUE;
+ setEncoding(RawUnicode);
+ reset();
+ d->sourceType = QTextStreamPrivate::String;
+}
+
+/*! \obsolete
+
+ This constructor is equivalent to the constructor taking a QString*
+ parameter.
+*/
+
+QTextStream::QTextStream( QString& str, int filemode )
+{
+ init();
+ dev = new QStringBuffer( &str );
+ ((QStringBuffer *)dev)->open( filemode );
+ owndev = TRUE;
+ setEncoding(RawUnicode);
+ reset();
+ d->sourceType = QTextStreamPrivate::String;
+}
+
+/*!
+ Constructs a text stream that operates on a byte array through an
+ internal QBuffer device.
+
+ Example:
+ \code
+ QByteArray array;
+ QTextStream ts( array, IO_WriteOnly );
+ ts << "pi = " << 3.14 << '\0'; // array == "pi = 3.14"
+ \endcode
+
+ Writing data to the text stream will modify the contents of the array.
+ The array will be expanded when data is written beyond the end of the
+ string.
+
+ Same example, using a QBuffer:
+ \code
+ QByteArray array;
+ QBuffer buf( array );
+ buf.open( IO_WriteOnly );
+ QTextStream ts( &buf );
+ ts << "pi = " << 3.14 << '\0'; // array == "pi = 3.14"
+ buf.close();
+ \endcode
+*/
+
+QTextStream::QTextStream( QByteArray a, int mode )
+{
+ init();
+ dev = new QBuffer( a );
+ ((QBuffer *)dev)->open( mode );
+ owndev = TRUE;
+ setEncoding( Latin1 ); //### Locale???
+ reset();
+ d->sourceType = QTextStreamPrivate::ByteArray;
+}
+
+/*!
+ Constructs a text stream that operates on an existing file handle \e fh
+ through an internal QFile device.
+
+ Example:
+ \code
+ QTextStream cout( stdout, IO_WriteOnly );
+ QTextStream cin ( stdin, IO_ReadOnly );
+ QTextStream cerr( stderr, IO_WriteOnly );
+ \endcode
+*/
+
+QTextStream::QTextStream( FILE *fh, int mode )
+{
+ init();
+ setEncoding( Locale ); //###
+ dev = new QFile;
+ ((QFile *)dev)->open( mode, fh );
+ fstrm = owndev = TRUE;
+ reset();
+ d->sourceType = QTextStreamPrivate::File;
+}
+
+/*!
+ Destructs the text stream.
+
+ The destructor does not affect the current IO device.
+*/
+
+QTextStream::~QTextStream()
+{
+ if ( owndev )
+ delete dev;
+ delete d;
+}
+
+/*!
+ Positions the read pointer at the first non-whitespace character.
+*/
+void QTextStream::skipWhiteSpace()
+{
+ ts_ungetc( eat_ws() );
+}
+
+
+/*!
+ \fn Encoding QTextStream::encoding() const
+
+ Returns the encoding mode of the stream.
+
+ \sa setEncoding()
+*/
+
+/*!
+ Tries to read len characters from the stream and stores them in \a buf.
+ Returns the number of characters really read.
+ Attention: There will no QEOF appended if the read reaches the end of
+ the file. EOF is reached when the return value does not equal \a len.
+*/
+uint QTextStream::ts_getbuf( QChar* buf, uint len )
+{
+ if( len<1 )
+ return 0;
+
+ uint rnum=0; // the number of QChars really read
+
+ if ( d && d->ungetcBuf.length() ) {
+ while( rnum < len && rnum < d->ungetcBuf.length() ) {
+ buf[rnum] = d->ungetcBuf.constref(rnum);
+ rnum++;
+ }
+ d->ungetcBuf = d->ungetcBuf.mid( rnum );
+ if ( rnum >= len )
+ return rnum;
+ }
+
+ // we use dev->ungetch() for one of the bytes of the unicode
+ // byte-order mark, but a local unget hack for the other byte:
+ int ungetHack = EOF;
+
+ if ( doUnicodeHeader ) {
+ doUnicodeHeader = FALSE; //only at the top
+ int c1 = dev->getch();
+ if ( c1 == EOF )
+ return rnum;
+ int c2 = dev->getch();
+ if ( c1 == 0xfe && c2 == 0xff ) {
+ mapper = 0;
+ latin1 = FALSE;
+ internalOrder = QChar::networkOrdered(); //network order
+ } else if ( c1 == 0xff && c2 == 0xfe ) {
+ mapper = 0;
+ latin1 = FALSE;
+ internalOrder = !QChar::networkOrdered(); //reverse network order
+ } else {
+ if ( c2 != EOF ) {
+ dev->ungetch( c2 );
+ ungetHack = c1;
+ } else {
+ dev->ungetch( c1 );
+ // note that a small possible bug might hide here
+ // here, if only the first byte of a file has made it
+ // so far, and that first byte is half of the
+ // byte-order mark, then the utfness will not be
+ // detected. whether or not this is a bug depends on
+ // taste. I can't really decide.
+ }
+ }
+ }
+
+ if ( mapper ) {
+ if ( !d->decoder )
+ d->decoder = mapper->makeDecoder();
+ while( rnum < len ) {
+ QString s;
+ while ( s.isEmpty() ) {
+ // TODO: can this getch() call be optimized to read
+ // more than one character after another? YES!
+ int c;
+ if ( ungetHack == EOF ) {
+ c = dev->getch();
+ } else {
+ c = ungetHack;
+ ungetHack = EOF;
+ }
+ if ( c == EOF )
+ return rnum;
+ char b = c;
+ s = d->decoder->toUnicode( &b, 1 );
+ }
+ uint i = 0;
+ while( rnum < len && i < s.length() )
+ buf[rnum++] = s.constref(i++);
+ if ( s.length() > i )
+ // could be = but append is clearer
+ d->ungetcBuf.append( s.mid( i ) );
+ }
+ } else if ( latin1 ) {
+ if ( len == 1+rnum ) {
+ // use this method for one character because it is more efficient
+ // (arnt doubts whether it makes a difference, but lets it stand)
+ int c = (ungetHack == EOF) ? dev->getch() : ungetHack;
+ if ( c != EOF )
+ buf[rnum++] = (char)c;
+ } else {
+ if ( (QChar)ungetHack != QEOF )
+ buf[rnum++] = (char)ungetHack;
+ uint rlen = len - rnum;
+ char *cbuf = new char[rlen];
+ rlen = dev->readBlock( cbuf, rlen );
+ uint i = 0;
+ while( i < rlen )
+ buf[rnum++] = cbuf[i++];
+ delete[] cbuf;
+ }
+ } else { // UCS-2 or UTF-16
+ if ( len == 1+rnum ) {
+ int c1 = (ungetHack == EOF) ? dev->getch() : ungetHack;
+ if ( c1 == EOF )
+ return rnum;
+ int c2 = dev->getch();
+ if ( c2 == EOF )
+ return rnum;
+ if ( isNetworkOrder() )
+ buf[rnum++] = QChar( c2, c1 );
+ else
+ buf[rnum++] = QChar( c1, c2 );
+ } else {
+ uint rlen = 2 * ( len-rnum );
+ char *cbuf = new char[rlen]; // for paranoids: overflow possible
+ if ( (QChar)ungetHack != QEOF ) {
+ rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
+ cbuf[0] = (char)ungetHack;
+ } else {
+ rlen = dev->readBlock( cbuf, rlen );
+ }
+ // is this right? we can't use an odd number of bytes, but
+ // if there -is- an odd number, with this code we'll never
+ // get to EOF.
+ if ( (rlen & 1) == 1 )
+ dev->ungetch( cbuf[--rlen] );
+ uint i = 0;
+ if ( isNetworkOrder() ) {
+ while( i < rlen ) {
+ buf[rnum++] = QChar( cbuf[i+1], cbuf[i] );
+ i+=2;
+ }
+ } else {
+ while( i < rlen ) {
+ buf[rnum++] = QChar( cbuf[i], cbuf[i+1] );
+ i+=2;
+ }
+ }
+ delete[] cbuf;
+ }
+ }
+ return rnum;
+}
+
+
+/*!
+ Puts one character to the stream.
+*/
+void QTextStream::ts_putc( QChar c )
+{
+ if ( mapper ) {
+ int len = 1;
+ QString s = c;
+ QCString block = mapper->fromUnicode( s, len );
+ dev->writeBlock( block, len );
+ } else if ( latin1 ) {
+ if( c.row() )
+ dev->putch( '?' ); //######unknown character???
+ else
+ dev->putch( c.cell() );
+ } else {
+ if ( doUnicodeHeader ) {
+ doUnicodeHeader = FALSE;
+ ts_putc( QChar::byteOrderMark );
+ }
+ if ( internalOrder ) {
+ dev->writeBlock( (char*)&c, sizeof(QChar) );
+ } else if ( isNetworkOrder() ) {
+ dev->putch(c.row());
+ dev->putch(c.cell());
+ } else {
+ dev->putch(c.cell());
+ dev->putch(c.row());
+ }
+ }
+}
+
+/*!
+ Puts one character to the stream.
+*/
+void QTextStream::ts_putc(int ch)
+{
+ ts_putc(QChar((ushort)ch));
+}
+
+bool QTextStream::ts_isdigit(QChar c)
+{
+ return c.isDigit();
+}
+
+bool QTextStream::ts_isspace( QChar c )
+{
+ return c.isSpace();
+}
+
+void QTextStream::ts_ungetc( QChar c )
+{
+ if ( c.unicode() == 0xffff )
+ return;
+
+ d->ungetcBuf.prepend( c );
+}
+
+
+
+/*!
+ Reads \e len bytes from the stream into \e e s and returns a reference to
+ the stream.
+
+ The buffer \e s must be preallocated.
+
+ \note No Encoding is done by this function.
+
+ \warning The behaviour of this function is undefined unless the
+ stream's encoding is set to Unicode or Latin1.
+
+ \sa QIODevice::readBlock()
+*/
+
+QTextStream &QTextStream::readRawBytes( char *s, uint len )
+{
+ dev->readBlock( s, len );
+ return *this;
+}
+
+/*!
+ Writes the \e len bytes from \e s to the stream and returns a reference to
+ the stream.
+
+ \note No Encoding is done by this function.
+
+ \sa QIODevice::writeBlock()
+*/
+
+QTextStream &QTextStream::writeRawBytes( const char* s, uint len )
+{
+ dev->writeBlock( s, len );
+ return *this;
+}
+
+
+QTextStream &QTextStream::writeBlock( const char* p, uint len )
+{
+ if ( doUnicodeHeader ) {
+ doUnicodeHeader = FALSE;
+ if ( !mapper && !latin1 )
+ ts_putc( QChar::byteOrderMark );
+ }
+ //All QCStrings and const char* are defined to be in Latin1
+ if ( !mapper && latin1 ) {
+ dev->writeBlock( p, len );
+ } else if ( !mapper && internalOrder ) {
+ QChar *u = new QChar[len];
+ for (uint i=0; i<len; i++)
+ u[i] = p[i];
+ dev->writeBlock( (char*)u, len*sizeof(QChar) );
+ delete [] u;
+ } else {
+ for (uint i=0; i<len; i++)
+ ts_putc( (uchar)p[i] );
+ }
+ return *this;
+}
+
+QTextStream &QTextStream::writeBlock( const QChar* p, uint len )
+{
+ if ( !mapper && !latin1 && internalOrder ) {
+ if ( doUnicodeHeader ) {
+ doUnicodeHeader = FALSE;
+ ts_putc( QChar::byteOrderMark );
+ }
+ dev->writeBlock( (char*)p, sizeof(QChar)*len );
+ } else {
+ for (uint i=0; i<len; i++)
+ ts_putc( p[i] );
+ }
+ return *this;
+}
+
+
+
+/*!
+ Resets the text stream.
+
+ <ul>
+ <li> All flags are set to 0.
+ <li> The field width is set to 0.
+ <li> The fill character is set to ' ' (space).
+ <li> The precision is set to 6.
+ </ul>
+
+ \sa setf(), width(), fill(), precision()
+*/
+
+void QTextStream::reset()
+{
+ fflags = 0;
+ fwidth = 0;
+ fillchar = ' ';
+ fprec = 6;
+}
+
+
+/*!
+ \fn QIODevice *QTextStream::device() const
+ Returns the IO device currently set.
+ \sa setDevice(), unsetDevice()
+*/
+
+/*!
+ Sets the IO device to \a iod.
+ \sa device(), unsetDevice()
+*/
+
+void QTextStream::setDevice( QIODevice *iod )
+{
+ if ( owndev ) {
+ delete dev;
+ owndev = FALSE;
+ }
+ dev = iod;
+ d->sourceType = QTextStreamPrivate::IODevice;
+}
+
+/*!
+ Unsets the IO device. Equivalent to setDevice( 0 ).
+ \sa device(), setDevice()
+*/
+
+void QTextStream::unsetDevice()
+{
+ setDevice( 0 );
+ d->sourceType = QTextStreamPrivate::NotSet;
+}
+
+/*!
+ \fn bool QTextStream::atEnd() const
+ Returns TRUE if the IO device has reached the end position (end of
+ stream or file) or if there is no IO device set.
+
+ Returns FALSE if the current position of the read/write head of the IO
+ device is somewhere before the end position.
+
+ \sa QIODevice::atEnd()
+*/
+
+/*!\fn bool QTextStream::eof() const
+
+ \obsolete
+
+ This function has been renamed to atEnd().
+
+ \sa QIODevice::atEnd()
+*/
+
+/*****************************************************************************
+ QTextStream read functions
+ *****************************************************************************/
+
+
+/*!
+ Reads a \c char from the stream and returns a reference to the stream.
+ Note that whitespace is skipped.
+*/
+
+QTextStream &QTextStream::operator>>( char &c )
+{
+ CHECK_STREAM_PRECOND
+ c = eat_ws();
+ return *this;
+}
+
+/*!
+ Reads a \c char from the stream and returns a reference to the stream.
+ Note that whitespace is \e not skipped.
+*/
+
+QTextStream &QTextStream::operator>>( QChar &c )
+{
+ CHECK_STREAM_PRECOND
+ c = ts_getc();
+ return *this;
+}
+
+
+ulong QTextStream::input_bin()
+{
+ ulong val = 0;
+ QChar ch = eat_ws();
+ int dv = ch.digitValue();
+ while ( dv == 0 || dv == 1 ) {
+ val = ( val << 1 ) + dv;
+ ch = ts_getc();
+ dv = ch.digitValue();
+ }
+ if ( ch != QEOF )
+ ts_ungetc( ch );
+ return val;
+}
+
+ulong QTextStream::input_oct()
+{
+ ulong val = 0;
+ QChar ch = eat_ws();
+ int dv = ch.digitValue();
+ while ( dv >= 0 && dv <= 7 ) {
+ val = ( val << 3 ) + dv;
+ ch = ts_getc();
+ dv = ch.digitValue();
+ }
+ if ( dv == 8 || dv == 9 ) {
+ while ( ts_isdigit(ch) )
+ ch = ts_getc();
+ }
+ if ( ch != QEOF )
+ ts_ungetc( ch );
+ return val;
+}
+
+ulong QTextStream::input_dec()
+{
+ ulong val = 0;
+ QChar ch = eat_ws();
+ int dv = ch.digitValue();
+ while ( ts_isdigit(ch) ) {
+ val = val * 10 + dv;
+ ch = ts_getc();
+ dv = ch.digitValue();
+ }
+ if ( ch != QEOF )
+ ts_ungetc( ch );
+ return val;
+}
+
+ulong QTextStream::input_hex()
+{
+ ulong val = 0;
+ QChar ch = eat_ws();
+ char c = ch;
+ while ( isxdigit(c) ) {
+ val <<= 4;
+ if ( ts_isdigit(c) )
+ val += c - '0';
+ else
+ val += 10 + tolower(c) - 'a';
+ c = ch = ts_getc();
+ }
+ if ( ch != QEOF )
+ ts_ungetc( ch );
+ return val;
+}
+
+long QTextStream::input_int()
+{
+ long val;
+ QChar ch;
+ char c;
+ switch ( flags() & basefield ) {
+ case bin:
+ val = (long)input_bin();
+ break;
+ case oct:
+ val = (long)input_oct();
+ break;
+ case dec:
+ c = ch = eat_ws();
+ if ( ch == QEOF ) {
+ val = 0;
+ } else {
+ if ( !(c == '-' || c == '+') )
+ ts_ungetc( ch );
+ if ( c == '-' ) {
+ ulong v = input_dec();
+ if ( v ) { // ensure that LONG_MIN can be read
+ v--;
+ val = -((long)v) - 1;
+ } else {
+ val = 0;
+ }
+ } else {
+ val = (long)input_dec();
+ }
+ }
+ break;
+ case hex:
+ val = (long)input_hex();
+ break;
+ default:
+ val = 0;
+ c = ch = eat_ws();
+ if ( c == '0' ) { // bin, oct or hex
+ c = ch = ts_getc();
+ if ( tolower(c) == 'x' )
+ val = (long)input_hex();
+ else if ( tolower(c) == 'b' )
+ val = (long)input_bin();
+ else { // octal
+ ts_ungetc( ch );
+ if ( c >= '0' && c <= '7' ) {
+ val = (long)input_oct();
+ } else {
+ val = 0;
+ }
+ }
+ } else if ( ts_isdigit(ch) ) {
+ ts_ungetc( ch );
+ val = (long)input_dec();
+ } else if ( c == '-' || c == '+' ) {
+ ulong v = input_dec();
+ if ( c == '-' ) {
+ if ( v ) { // ensure that LONG_MIN can be read
+ v--;
+ val = -((long)v) - 1;
+ } else {
+ val = 0;
+ }
+ } else {
+ val = (long)v;
+ }
+ }
+ }
+ return val;
+}
+
+//
+// We use a table-driven FSM to parse floating point numbers
+// strtod() cannot be used directly since we're reading from a QIODevice
+//
+
+double QTextStream::input_double()
+{
+ const int Init = 0; // states
+ const int Sign = 1;
+ const int Mantissa = 2;
+ const int Dot = 3;
+ const int Abscissa = 4;
+ const int ExpMark = 5;
+ const int ExpSign = 6;
+ const int Exponent = 7;
+ const int Done = 8;
+
+ const int InputSign = 1; // input tokens
+ const int InputDigit = 2;
+ const int InputDot = 3;
+ const int InputExp = 4;
+
+ static uchar table[8][5] = {
+ /* None InputSign InputDigit InputDot InputExp */
+ { 0, Sign, Mantissa, Dot, 0, }, // Init
+ { 0, 0, Mantissa, Dot, 0, }, // Sign
+ { Done, Done, Mantissa, Dot, ExpMark,}, // Mantissa
+ { 0, 0, Abscissa, 0, 0, }, // Dot
+ { Done, Done, Abscissa, Done, ExpMark,}, // Abscissa
+ { 0, ExpSign, Exponent, 0, 0, }, // ExpMark
+ { 0, 0, Exponent, 0, 0, }, // ExpSign
+ { Done, Done, Exponent, Done, Done } // Exponent
+ };
+
+ int state = Init; // parse state
+ int input; // input token
+
+ char buf[256];
+ int i = 0;
+ QChar c = eat_ws();
+
+ while ( TRUE ) {
+
+ switch ( c ) {
+ case '+':
+ case '-':
+ input = InputSign;
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ input = InputDigit;
+ break;
+ case '.':
+ input = InputDot;
+ break;
+ case 'e':
+ case 'E':
+ input = InputExp;
+ break;
+ default:
+ input = 0;
+ break;
+ }
+
+ state = table[state][input];
+
+ if ( state == 0 || state == Done || i > 250 ) {
+ if ( i > 250 ) { // ignore rest of digits
+ do { c = ts_getc(); } while ( c != QEOF && ts_isdigit(c) );
+ }
+ if ( c != QEOF )
+ ts_ungetc( c );
+ buf[i] = '\0';
+ char *end;
+ return strtod( buf, &end );
+ }
+
+ buf[i++] = c;
+ c = ts_getc();
+ }
+
+#if !defined(_CC_EGG_)
+ return 0.0;
+#endif
+}
+
+
+/*!
+ Reads a signed \c short integer from the stream and returns a reference to
+ the stream. See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( signed short &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (signed short)input_int();
+ return *this;
+}
+
+
+/*!
+ Reads an unsigned \c short integer from the stream and returns a reference to
+ the stream. See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( unsigned short &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (unsigned short)input_int();
+ return *this;
+}
+
+
+/*!
+ Reads a signed \c int from the stream and returns a reference to the
+ stream. See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( signed int &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (signed int)input_int();
+ return *this;
+}
+
+
+/*!
+ Reads an unsigned \c int from the stream and returns a reference to the
+ stream. See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( unsigned int &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (unsigned int)input_int();
+ return *this;
+}
+
+
+/*!
+ Reads a signed \c long int from the stream and returns a reference to the
+ stream. See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( signed long &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (signed long)input_int();
+ return *this;
+}
+
+
+/*!
+ Reads an unsigned \c long int from the stream and returns a reference to the
+ stream. See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( unsigned long &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (unsigned long)input_int();
+ return *this;
+}
+
+
+/*!
+ Reads a \c float from the stream and returns a reference to the stream.
+ See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( float &f )
+{
+ CHECK_STREAM_PRECOND
+ f = (float)input_double();
+ return *this;
+}
+
+
+/*!
+ Reads a \c double from the stream and returns a reference to the stream.
+ See flags() for an explanation of expected input format.
+*/
+
+QTextStream &QTextStream::operator>>( double &f )
+{
+ CHECK_STREAM_PRECOND
+ f = input_double();
+ return *this;
+}
+
+
+/*!
+ Reads a word from the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator>>( char *s )
+{
+ CHECK_STREAM_PRECOND
+ int maxlen = width( 0 );
+ QChar c = eat_ws();
+ if ( !maxlen )
+ maxlen = -1;
+ while ( c != QEOF ) {
+ if ( ts_isspace(c) || maxlen-- == 0 ) {
+ ts_ungetc( c );
+ break;
+ }
+ *s++ = c;
+ c = ts_getc();
+ }
+
+ *s = '\0';
+ return *this;
+}
+
+/*!
+ Reads a word from the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator>>( QString &str )
+{
+ CHECK_STREAM_PRECOND
+ str=QString::fromLatin1("");
+ QChar c = eat_ws();
+
+ while ( c != QEOF ) {
+ if ( ts_isspace(c) ) {
+ ts_ungetc( c );
+ break;
+ }
+ str += c;
+ c = ts_getc();
+ }
+ return *this;
+}
+
+/*!
+ Reads a word from the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator>>( QCString &str )
+{
+ CHECK_STREAM_PRECOND
+ QCString *dynbuf = 0;
+ const int buflen = 256;
+ char buffer[buflen];
+ char *s = buffer;
+ int i = 0;
+ QChar c = eat_ws();
+
+ while ( c != QEOF ) {
+ if ( ts_isspace(c) ) {
+ ts_ungetc( c );
+ break;
+ }
+ if ( i >= buflen-1 ) {
+ if ( !dynbuf ) { // create dynamic buffer
+ dynbuf = new QCString(buflen*2);
+ memcpy( dynbuf->data(), s, i ); // copy old data
+ } else if ( i >= (int)dynbuf->size()-1 ) {
+ dynbuf->resize( dynbuf->size()*2 );
+ }
+ s = dynbuf->data();
+ }
+ s[i++] = c;
+ c = ts_getc();
+ }
+ str.resize( i+1 );
+ memcpy( str.data(), s, i );
+ delete dynbuf;
+ return *this;
+}
+
+
+/*!
+ Reads a line from the stream and returns a string containing the text.
+
+ The returned string does not contain any trailing newline or carriage
+ return. Note that this is different from QIODevice::readLine(), which
+ does not strip the newline at the end of the line.
+
+ On EOF you will get a QString that is null. On reading an empty line the
+ returned QString is empty but not null.
+
+ \sa QIODevice::readLine()
+*/
+
+QString QTextStream::readLine()
+{
+#if defined(CHECK_STATE)
+ if ( !dev ) {
+ qWarning( "QTextStream::readLine: No device" );
+ return QString::null;
+ }
+#endif
+ QChar c = ts_getc();
+ if ( c == QEOF )
+ return QString::null;
+
+ QString result( "" );
+ while ( c != QEOF && c != '\n' ) {
+ result += c;
+ c = ts_getc();
+ }
+
+ int len = (int)result.length();
+ if ( len && result[len-1] == '\r' )
+ result.truncate(len-1); // (if there are two \r, let one stay)
+
+ return result;
+}
+
+
+/*!
+ Reads the entire stream and returns a string containing the text.
+
+ \sa QIODevice::readLine()
+*/
+
+QString QTextStream::read()
+{
+#if defined(CHECK_STATE)
+ if ( !dev ) {
+ qWarning( "QTextStream::readLine: No device" );
+ return QString::null;
+ }
+#endif
+ QString result;
+ const uint bufsize = 512;
+ QChar buf[bufsize];
+ uint i, num, start;
+ bool skipped_cr = FALSE;
+
+ while ( 1 ) {
+ num = ts_getbuf(buf,bufsize);
+ // do a s/\r\n/\n
+ start = 0;
+ for ( i=0; i<num; i++ ) {
+ if ( buf[i] == '\r' ) {
+ // Only skip single cr's preceding lf's
+ if ( skipped_cr ) {
+ result += buf[i];
+ start++;
+ } else {
+ result += QString( &buf[start], i-start );
+ start = i+1;
+ skipped_cr = TRUE;
+ }
+ } else {
+ if ( skipped_cr ) {
+ if ( buf[i] != '\n' ) {
+ // Should not have skipped it
+ result += '\r';
+ }
+ skipped_cr = FALSE;
+ }
+ }
+ }
+ if ( start < num )
+ result += QString( &buf[start], i-start );
+ if ( num != bufsize ) // if ( EOF )
+ break;
+ }
+ return result;
+}
+
+
+
+/*****************************************************************************
+ QTextStream write functions
+ *****************************************************************************/
+
+/*!
+ Writes a \c char to the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator<<( char c )
+{
+ CHECK_STREAM_PRECOND
+ unsigned char uc = (unsigned char) c;
+ ts_putc( uc );
+ return *this;
+}
+
+QTextStream &QTextStream::output_int( int format, ulong n, bool neg )
+{
+ static char hexdigits_lower[] = "0123456789abcdef";
+ static char hexdigits_upper[] = "0123456789ABCDEF";
+ CHECK_STREAM_PRECOND
+ char buf[76];
+ register char *p;
+ int len;
+ char *hexdigits;
+
+ switch ( flags() & I_BASE_MASK ) {
+
+ case I_BASE_2: // output binary number
+ switch ( format & I_TYPE_MASK ) {
+ case I_SHORT: len=16; break;
+ case I_INT: len=sizeof(int)*8; break;
+ case I_LONG: len=32; break;
+ default: len = 0;
+ }
+ p = &buf[74]; // go reverse order
+ *p = '\0';
+ while ( len-- ) {
+ *--p = (char)(n&1) + '0';
+ n >>= 1;
+ if ( !n )
+ break;
+ }
+ if ( flags() & showbase ) { // show base
+ *--p = (flags() & uppercase) ? 'B' : 'b';
+ *--p = '0';
+ }
+ break;
+
+ case I_BASE_8: // output octal number
+ p = &buf[74];
+ *p = '\0';
+ do {
+ *--p = (char)(n&7) + '0';
+ n >>= 3;
+ } while ( n );
+ if ( flags() & showbase )
+ *--p = '0';
+ break;
+
+ case I_BASE_16: // output hexadecimal number
+ p = &buf[74];
+ *p = '\0';
+ hexdigits = (flags() & uppercase) ?
+ hexdigits_upper : hexdigits_lower;
+ do {
+ *--p = hexdigits[(int)n&0xf];
+ n >>= 4;
+ } while ( n );
+ if ( flags() & showbase ) {
+ *--p = (flags() & uppercase) ? 'X' : 'x';
+ *--p = '0';
+ }
+ break;
+
+ default: // decimal base is default
+ p = &buf[74];
+ *p = '\0';
+ if ( neg )
+ n = (ulong)(-(long)n);
+ do {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ if ( neg )
+ *--p = '-';
+ else if ( flags() & showpos )
+ *--p = '+';
+ if ( (flags() & internal) && fwidth && !ts_isdigit(*p) ) {
+ ts_putc( *p ); // special case for internal
+ ++p; // padding
+ fwidth--;
+ return *this << (const char*)p;
+ }
+ }
+ if ( fwidth ) { // adjustment required
+ if ( !(flags() & left) ) { // but NOT left adjustment
+ len = qstrlen(p);
+ int padlen = fwidth - len;
+ if ( padlen <= 0 ) { // no padding required
+ writeBlock( p, len );
+ } else if ( padlen < (int)(p-buf) ) { // speeds up padding
+ memset( p-padlen, (char)fillchar, padlen );
+ writeBlock( p-padlen, padlen+len );
+ }
+ else // standard padding
+ *this << (const char*)p;
+ }
+ else
+ *this << (const char*)p;
+ fwidth = 0; // reset field width
+ }
+ else
+ writeBlock( p, qstrlen(p) );
+ return *this;
+}
+
+
+/*!
+ Writes a \c short integer to the stream and returns a reference to
+ the stream.
+*/
+
+QTextStream &QTextStream::operator<<( signed short i )
+{
+ return output_int( I_SHORT | I_SIGNED, i, i < 0 );
+}
+
+
+/*!
+ Writes an \c unsigned \c short integer to the stream and returns a reference
+ to the stream.
+*/
+
+QTextStream &QTextStream::operator<<( unsigned short i )
+{
+ return output_int( I_SHORT | I_UNSIGNED, i, FALSE );
+}
+
+
+/*!
+ Writes an \c int to the stream and returns a reference to
+ the stream.
+*/
+
+QTextStream &QTextStream::operator<<( signed int i )
+{
+ return output_int( I_INT | I_SIGNED, i, i < 0 );
+}
+
+
+/*!
+ Writes an \c unsigned \c int to the stream and returns a reference to
+ the stream.
+*/
+
+QTextStream &QTextStream::operator<<( unsigned int i )
+{
+ return output_int( I_INT | I_UNSIGNED, i, FALSE );
+}
+
+
+/*!
+ Writes a \c long \c int to the stream and returns a reference to
+ the stream.
+*/
+
+QTextStream &QTextStream::operator<<( signed long i )
+{
+ return output_int( I_LONG | I_SIGNED, i, i < 0 );
+}
+
+
+/*!
+ Writes an \c unsigned \c long \c int to the stream and returns a reference to
+ the stream.
+*/
+
+QTextStream &QTextStream::operator<<( unsigned long i )
+{
+ return output_int( I_LONG | I_UNSIGNED, i, FALSE );
+}
+
+
+/*!
+ Writes a \c float to the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator<<( float f )
+{
+ return *this << (double)f;
+}
+
+
+/*!
+ Writes a \c double to the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator<<( double f )
+{
+ CHECK_STREAM_PRECOND
+ char buf[64];
+ char f_char;
+ char format[16];
+ if ( (flags()&floatfield) == fixed )
+ f_char = 'f';
+ else if ( (flags()&floatfield) == scientific )
+ f_char = (flags() & uppercase) ? 'E' : 'e';
+ else
+ f_char = (flags() & uppercase) ? 'G' : 'g';
+ register char *fs = format; // generate format string
+ *fs++ = '%'; // "%.<prec>l<f_char>"
+ *fs++ = '.';
+ int prec = precision();
+ if ( prec > 99 )
+ prec = 99;
+ if ( prec >= 10 ) {
+ *fs++ = prec / 10 + '0';
+ *fs++ = prec % 10 + '0';
+ } else {
+ *fs++ = prec + '0';
+ }
+ *fs++ = 'l';
+ *fs++ = f_char;
+ *fs = '\0';
+ sprintf( buf, format, f ); // convert to text
+ if ( fwidth ) // padding
+ *this << (const char*)buf;
+ else // just write it
+ writeBlock( buf, qstrlen(buf) );
+ return *this;
+}
+
+
+/*!
+ Writes a string to the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator<<( const char* s )
+{
+ CHECK_STREAM_PRECOND
+ char padbuf[48];
+ uint len = qstrlen( s ); // don't write null terminator
+ if ( fwidth ) { // field width set
+ int padlen = fwidth - len;
+ fwidth = 0; // reset width
+ if ( padlen > 0 ) {
+ char *ppad;
+ if ( padlen > 46 ) { // create extra big fill buffer
+ ppad = new char[padlen];
+ CHECK_PTR( ppad );
+ } else {
+ ppad = padbuf;
+ }
+ memset( ppad, (char)fillchar, padlen ); // fill with fillchar
+ if ( !(flags() & left) ) {
+ writeBlock( ppad, padlen );
+ padlen = 0;
+ }
+ writeBlock( s, len );
+ if ( padlen )
+ writeBlock( ppad, padlen );
+ if ( ppad != padbuf ) // delete extra big fill buf
+ delete[] ppad;
+ return *this;
+ }
+ }
+ writeBlock( s, len );
+ return *this;
+}
+
+/*!
+ Writes \a s to the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator<<( const QCString & s )
+{
+ return operator<<(s.data());
+}
+
+/*!
+ Writes \a s to the stream and returns a reference to the stream.
+*/
+
+QTextStream &QTextStream::operator<<( const QString& s )
+{
+ CHECK_STREAM_PRECOND
+ uint len = s.length();
+ QString s1 = s;
+ if ( fwidth ) { // field width set
+ if ( !(flags() & left) ) {
+ s1 = s.rightJustify(fwidth, (char)fillchar);
+ } else {
+ s1 = s.leftJustify(fwidth, (char)fillchar);
+ }
+ fwidth = 0; // reset width
+ }
+ writeBlock( s1.unicode(), len );
+ return *this;
+}
+
+
+/*!
+ Writes a pointer to the stream and returns a reference to the stream.
+
+ The \e ptr is output as an unsigned long hexadecimal integer.
+*/
+
+QTextStream &QTextStream::operator<<( void *ptr )
+{
+ int f = flags();
+ setf( hex, basefield );
+ setf( showbase );
+ unsetf( uppercase );
+ output_int( I_LONG | I_UNSIGNED, (ulong)ptr, FALSE );
+ flags( f );
+ return *this;
+}
+
+
+/*!
+ \fn int QTextStream::flags() const
+ Returns the current stream flags. The default value is 0.
+
+ The meaning of the flags are:
+ <ul>
+ <li> \e skipws - Not currently used - whitespace always skipped
+ <li> \e left - Numeric fields are left-aligned
+ <li> \e right - Not currently used (by default numerics are right aligned)
+ <li> \e internal - Put any padding spaces between +/- and value
+ <li> \e bin - Output \e and input only in binary
+ <li> \e oct - Output \e and input only in octal
+ <li> \e dec - Output \e and input only in decimal
+ <li> \e hex - Output \e and input only in hexadecimal
+ <li> \e showbase - Annotate numeric outputs with 0b, 0, or 0x if in
+ \e bin, \e oct, or \e hex format
+ <li> \e showpoint - Not currently used
+ <li> \e uppercase - Use 0B and 0X rather than 0b and 0x
+ <li> \e showpos - Show + for positive numeric values
+ <li> \e scientific - Use scientific notation for floating point values
+ <li> \e fixed - Use fixed-point notation for floating point values
+ </ul>
+
+ Note that unless \e bin, \e oct, \e dec, or \e hex is set, the input base is
+ octal if the value starts with 0, hexadecimal if it starts with 0x, binary
+ if the value starts with 0b, and decimal otherwise.
+
+ \sa setf(), unsetf()
+*/
+
+/*!
+ \fn int QTextStream::flags( int f )
+ Sets the stream flags to \e f.
+ Returns the previous stream flags.
+
+ \sa setf(), unsetf(), flags()
+*/
+
+/*!
+ \fn int QTextStream::setf( int bits )
+ Sets the stream flag bits \e bits.
+ Returns the previous stream flags.
+
+ Equivalent to <code>flags( flags() | bits )</code>.
+
+ \sa setf(), unsetf()
+*/
+
+/*!
+ \fn int QTextStream::setf( int bits, int mask )
+ Sets the stream flag bits \e bits with a bit mask \e mask.
+ Returns the previous stream flags.
+
+ Equivalent to <code>flags( (flags() & ~mask) | (bits & mask) )</code>.
+
+ \sa setf(), unsetf()
+*/
+
+/*!
+ \fn int QTextStream::unsetf( int bits )
+ Clears the stream flag bits \e bits.
+ Returns the previous stream flags.
+
+ Equivalent to <code>flags( flags() & ~mask )</code>.
+
+ \sa setf()
+*/
+
+/*!
+ \fn int QTextStream::width() const
+ Returns the field width. The default value is 0.
+*/
+
+/*!
+ \fn int QTextStream::width( int w )
+ Sets the field width to \e w. Returns the previous field width.
+*/
+
+/*!
+ \fn int QTextStream::fill() const
+ Returns the fill character. The default value is ' ' (space).
+*/
+
+/*!
+ \fn int QTextStream::fill( int f )
+ Sets the fill character to \e f. Returns the previous fill character.
+*/
+
+/*!
+ \fn int QTextStream::precision() const
+ Returns the precision. The default value is 6.
+*/
+
+/*!
+ \fn int QTextStream::precision( int p )
+ Sets the precision to \e p. Returns the previous precision setting.
+*/
+
+
+ /*****************************************************************************
+ QTextStream manipulators
+ *****************************************************************************/
+
+QTextStream &bin( QTextStream &s )
+{
+ s.setf(QTS::bin,QTS::basefield);
+ return s;
+}
+
+QTextStream &oct( QTextStream &s )
+{
+ s.setf(QTS::oct,QTS::basefield);
+ return s;
+}
+
+QTextStream &dec( QTextStream &s )
+{
+ s.setf(QTS::dec,QTS::basefield);
+ return s;
+}
+
+QTextStream &hex( QTextStream &s )
+{
+ s.setf(QTS::hex,QTS::basefield);
+ return s;
+}
+
+QTextStream &endl( QTextStream &s )
+{
+ return s << '\n';
+}
+
+QTextStream &flush( QTextStream &s )
+{
+ if ( s.device() )
+ s.device()->flush();
+ return s;
+}
+
+QTextStream &ws( QTextStream &s )
+{
+ s.skipWhiteSpace();
+ return s;
+}
+
+QTextStream &reset( QTextStream &s )
+{
+ s.reset();
+ return s;
+}
+
+
+/*!
+ \class QTextIStream qtextstream.h
+ \brief A convenience class for input streams.
+
+ For simple tasks, code should be simple. Hence this
+ class is a shorthand to avoid passing the \e mode argument
+ to the normal QTextStream constructors.
+
+ This makes it easy for example, to write things like this:
+\code
+ QString data = "123 456";
+ int a, b;
+ QTextIStream(&data) >> a >> b;
+\endcode
+
+ \sa QTextOStream
+*/
+
+/*!
+ \fn QTextIStream::QTextIStream( QString *s )
+
+ Constructs a stream to read from string \a s.
+*/
+/*!
+ \fn QTextIStream::QTextIStream( QByteArray ba )
+
+ Constructs a stream to read from the array \a ba.
+*/
+/*!
+ \fn QTextIStream::QTextIStream( FILE *f )
+
+ Constructs a stream to read from the file \a f.
+*/
+
+
+/*!
+ \class QTextOStream qtextstream.h
+ \brief A convenience class for output streams.
+
+ For simple tasks, code should be simple. Hence this
+ class is a shorthand to avoid passing the \e mode argument
+ to the normal QTextStream constructors.
+
+ This makes it easy for example, to write things like this:
+\code
+ QString result;
+ QTextOStream(&result) << "pi = " << 3.14;
+\endcode
+*/
+
+/*!
+ \fn QTextOStream::QTextOStream( QString *s )
+
+ Constructs a stream to write to string \a s.
+*/
+/*!
+ \fn QTextOStream::QTextOStream( QByteArray ba )
+
+ Constructs a stream to write to the array \a ba.
+*/
+/*!
+ \fn QTextOStream::QTextOStream( FILE *f )
+
+ Constructs a stream to write to the file \a f.
+*/
+
+
+
+/*!
+ Sets the encoding of this stream to \a e, where \a e is one of:
+ <ul>
+ <li> \c Locale Using local file format (Latin1 if locale is not
+ set), but autodetecting Unicode(utf16) on input.
+ <li> \c Unicode Using Unicode(utf16) for input and output. Output
+ will be written in the order most efficient for the current platform
+ (i.e. the order used internally in QString).
+ <li> \c UnicodeUTF8 Using Unicode(utf8) for input and output. If you use it
+ for input it will autodetect utf16 and use it instead of utf8.
+ <li> \c Latin1 ISO-8859-1. Will not autodetect utf16.
+ <li> \c UnicodeNetworkOrder Using network order Unicode(utf16) for
+ input and output. Useful when reading Unicode data that does not
+ start with the byte order marker.
+ <li> \c UnicodeReverse Using reverse network order Unicode(utf16)
+ for input and output. Useful when reading Unicode data that does not
+ start with the byte order marker, or writing data that should be
+ read by buggy Windows applications.
+ <li> \c RawUnicode Like Unicode, but does not write the byte order
+ marker, nor does it autodetect the byte order. Only useful when
+ writing to non-persistent storage used by a single process.
+ </ul>
+
+ \c Locale and all Unicode encodings, except \c RawUnicode, will look
+ at the first two bytes in a input stream to determine the byte
+ order. The initial byte order marker will be stripped off before data is read.
+
+ \note This function should be called before any data is read to/written from the stream.
+ \sa setCodec()
+*/
+
+void QTextStream::setEncoding( Encoding e )
+{
+ if ( d->sourceType == QTextStreamPrivate::String )
+ return; // QString does not need any encoding
+ switch ( e ) {
+ case Unicode:
+ mapper = 0;
+ latin1 = FALSE;
+ doUnicodeHeader = TRUE;
+ internalOrder = TRUE;
+ break;
+ case UnicodeUTF8:
+ mapper = QTextCodec::codecForMib( 106 );
+ latin1 = FALSE;
+ doUnicodeHeader = TRUE;
+ internalOrder = TRUE;
+ break;
+ case UnicodeNetworkOrder:
+ mapper = 0;
+ latin1 = FALSE;
+ doUnicodeHeader = TRUE;
+ internalOrder = QChar::networkOrdered();
+ break;
+ case UnicodeReverse:
+ mapper = 0;
+ latin1 = FALSE;
+ doUnicodeHeader = TRUE;
+ internalOrder = !QChar::networkOrdered(); //reverse network ordered
+ break;
+ case RawUnicode:
+ mapper = 0;
+ latin1 = FALSE;
+ doUnicodeHeader = FALSE;
+ internalOrder = TRUE;
+ break;
+ case Locale:
+ latin1 = TRUE; // fallback to Latin 1
+ mapper = QTextCodec::codecForLocale();
+#if defined(_OS_WIN32_)
+ if ( GetACP() == 1252 )
+ mapper = 0; // Optimized latin1 processing
+#endif
+ if ( mapper && mapper->mibEnum() == 4 )
+ mapper = 0; // Optimized latin1 processing
+ doUnicodeHeader = TRUE; // If it reads as Unicode, accept it
+ break;
+ case Latin1:
+ mapper = 0;
+ doUnicodeHeader = FALSE;
+ latin1 = TRUE;
+ break;
+ }
+}
+
+
+/*!
+ Sets the codec for this stream to \a codec. Will not try to autodetect Unicode.
+
+ \note This function should be called before any data is read to/written from the stream.
+ \sa setEncoding()
+*/
+
+void QTextStream::setCodec( QTextCodec *codec )
+{
+ if ( d->sourceType == QTextStreamPrivate::String )
+ return; // QString does not need any codec
+ mapper = codec;
+ doUnicodeHeader = FALSE;
+}
+
+#endif // QT_NO_TEXTSTREAM
diff --git a/qtools/qtextstream.h b/qtools/qtextstream.h
new file mode 100644
index 0000000..d7adbd3
--- /dev/null
+++ b/qtools/qtextstream.h
@@ -0,0 +1,347 @@
+/****************************************************************************
+**
+**
+** Definition of QTextStream class
+**
+** Created : 940922
+**
+** Copyright (C) 1992-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 QTEXTSTREAM_H
+#define QTEXTSTREAM_H
+
+#ifndef QT_H
+#include "qiodevice.h"
+#include "qstring.h"
+#include <stdio.h>
+#endif // QT_H
+
+#ifndef QT_NO_TEXTSTREAM
+class QTextCodec;
+class QTextDecoder;
+
+class QTextStreamPrivate;
+
+class Q_EXPORT QTextStream // text stream class
+{
+public:
+ enum Encoding { Locale, Latin1, Unicode, UnicodeNetworkOrder,
+ UnicodeReverse, RawUnicode, UnicodeUTF8 };
+
+ void setEncoding( Encoding );
+ void setCodec( QTextCodec* );
+ // Encoding encoding() const { return cmode; }
+
+ QTextStream();
+ QTextStream( QIODevice * );
+ QTextStream( QString*, int mode );
+ QTextStream( QString&, int mode ); // obsolete
+ QTextStream( QByteArray, int mode );
+ QTextStream( FILE *, int mode );
+ virtual ~QTextStream();
+
+ QIODevice *device() const;
+ void setDevice( QIODevice * );
+ void unsetDevice();
+
+ bool atEnd() const;
+ bool eof() const;
+
+ QTextStream &operator>>( QChar & );
+ QTextStream &operator>>( char & );
+ QTextStream &operator>>( signed short & );
+ QTextStream &operator>>( unsigned short & );
+ QTextStream &operator>>( signed int & );
+ QTextStream &operator>>( unsigned int & );
+ QTextStream &operator>>( signed long & );
+ QTextStream &operator>>( unsigned long & );
+ QTextStream &operator>>( float & );
+ QTextStream &operator>>( double & );
+ QTextStream &operator>>( char * );
+ QTextStream &operator>>( QString & );
+ QTextStream &operator>>( QCString & );
+
+ QTextStream &operator<<( char );
+ QTextStream &operator<<( signed short );
+ QTextStream &operator<<( unsigned short );
+ QTextStream &operator<<( signed int );
+ QTextStream &operator<<( unsigned int );
+ QTextStream &operator<<( signed long );
+ QTextStream &operator<<( unsigned long );
+ QTextStream &operator<<( float );
+ QTextStream &operator<<( double );
+ QTextStream &operator<<( const char* );
+ QTextStream &operator<<( const QString & );
+ QTextStream &operator<<( const QCString & );
+ QTextStream &operator<<( void * ); // any pointer
+
+ QTextStream &readRawBytes( char *, uint len );
+ QTextStream &writeRawBytes( const char* , uint len );
+
+ QString readLine();
+ QString read();
+ void skipWhiteSpace();
+
+ enum {
+ skipws = 0x0001, // skip whitespace on input
+ left = 0x0002, // left-adjust output
+ right = 0x0004, // right-adjust output
+ internal = 0x0008, // pad after sign
+ bin = 0x0010, // binary format integer
+ oct = 0x0020, // octal format integer
+ dec = 0x0040, // decimal format integer
+ hex = 0x0080, // hex format integer
+ showbase = 0x0100, // show base indicator
+ showpoint = 0x0200, // force decimal point (float)
+ uppercase = 0x0400, // upper-case hex output
+ showpos = 0x0800, // add '+' to positive integers
+ scientific= 0x1000, // scientific float output
+ fixed = 0x2000 // fixed float output
+ };
+
+ static const int basefield; // bin | oct | dec | hex
+ static const int adjustfield; // left | right | internal
+ static const int floatfield; // scientific | fixed
+
+ int flags() const;
+ int flags( int f );
+ int setf( int bits );
+ int setf( int bits, int mask );
+ int unsetf( int bits );
+
+ void reset();
+
+ int width() const;
+ int width( int );
+ int fill() const;
+ int fill( int );
+ int precision() const;
+ int precision( int );
+
+private:
+ long input_int();
+ void init();
+ QTextStream &output_int( int, ulong, bool );
+ QIODevice *dev;
+ bool isNetworkOrder() { return internalOrder == QChar::networkOrdered(); }
+
+ int fflags;
+ int fwidth;
+ int fillchar;
+ int fprec;
+ bool fstrm;
+ bool owndev;
+ QTextCodec *mapper;
+ QTextStreamPrivate * d;
+ QChar ungetcBuf;
+ bool latin1;
+ bool internalOrder;
+ bool doUnicodeHeader;
+ void *reserved_ptr;
+
+ QChar eat_ws();
+ void ts_ungetc( QChar );
+ QChar ts_getc();
+ uint ts_getbuf( QChar*, uint );
+ void ts_putc(int);
+ void ts_putc(QChar);
+ bool ts_isspace(QChar);
+ bool ts_isdigit(QChar);
+ ulong input_bin();
+ ulong input_oct();
+ ulong input_dec();
+ ulong input_hex();
+ double input_double();
+ QTextStream &writeBlock( const char* p, uint len );
+ QTextStream &writeBlock( const QChar* p, uint len );
+
+private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ QTextStream( const QTextStream & );
+ QTextStream &operator=( const QTextStream & );
+#endif
+};
+
+typedef QTextStream QTS;
+
+class Q_EXPORT QTextIStream : public QTextStream {
+public:
+ QTextIStream( QString* s ) :
+ QTextStream(s,IO_ReadOnly) { }
+ QTextIStream( QByteArray ba ) :
+ QTextStream(ba,IO_ReadOnly) { }
+ QTextIStream( FILE *f ) :
+ QTextStream(f,IO_ReadOnly) { }
+};
+
+class Q_EXPORT QTextOStream : public QTextStream {
+public:
+ QTextOStream( QString* s ) :
+ QTextStream(s,IO_WriteOnly) { }
+ QTextOStream( QByteArray ba ) :
+ QTextStream(ba,IO_WriteOnly) { }
+ QTextOStream( FILE *f ) :
+ QTextStream(f,IO_WriteOnly) { }
+};
+
+/*****************************************************************************
+ QTextStream inline functions
+ *****************************************************************************/
+
+inline QIODevice *QTextStream::device() const
+{ return dev; }
+
+inline bool QTextStream::atEnd() const
+{ return dev ? dev->atEnd() : FALSE; }
+
+inline bool QTextStream::eof() const
+{ return atEnd(); }
+
+inline int QTextStream::flags() const
+{ return fflags; }
+
+inline int QTextStream::flags( int f )
+{ int oldf = fflags; fflags = f; return oldf; }
+
+inline int QTextStream::setf( int bits )
+{ int oldf = fflags; fflags |= bits; return oldf; }
+
+inline int QTextStream::setf( int bits, int mask )
+{ int oldf = fflags; fflags = (fflags & ~mask) | (bits & mask); return oldf; }
+
+inline int QTextStream::unsetf( int bits )
+{ int oldf = fflags; fflags &= ~bits; return oldf; }
+
+inline int QTextStream::width() const
+{ return fwidth; }
+
+inline int QTextStream::width( int w )
+{ int oldw = fwidth; fwidth = w; return oldw; }
+
+inline int QTextStream::fill() const
+{ return fillchar; }
+
+inline int QTextStream::fill( int f )
+{ int oldc = fillchar; fillchar = f; return oldc; }
+
+inline int QTextStream::precision() const
+{ return fprec; }
+
+inline int QTextStream::precision( int p )
+{ int oldp = fprec; fprec = p; return oldp; }
+
+/*!
+ Returns one character from the stream, or EOF.
+*/
+inline QChar QTextStream::ts_getc()
+{ QChar r; return ( ts_getbuf( &r,1 ) == 1 ? r : QChar((ushort)0xffff) ); }
+
+/*****************************************************************************
+ QTextStream manipulators
+ *****************************************************************************/
+
+typedef QTextStream & (*QTSFUNC)(QTextStream &);// manipulator function
+typedef int (QTextStream::*QTSMFI)(int); // manipulator w/int argument
+
+class Q_EXPORT QTSManip { // text stream manipulator
+public:
+ QTSManip( QTSMFI m, int a ) { mf=m; arg=a; }
+ void exec( QTextStream &s ) { (s.*mf)(arg); }
+private:
+ QTSMFI mf; // QTextStream member function
+ int arg; // member function argument
+};
+
+Q_EXPORT inline QTextStream &operator>>( QTextStream &s, QTSFUNC f )
+{ return (*f)( s ); }
+
+Q_EXPORT inline QTextStream &operator<<( QTextStream &s, QTSFUNC f )
+{ return (*f)( s ); }
+
+Q_EXPORT inline QTextStream &operator<<( QTextStream &s, QTSManip m )
+{ m.exec(s); return s; }
+
+Q_EXPORT QTextStream &bin( QTextStream &s ); // set bin notation
+Q_EXPORT QTextStream &oct( QTextStream &s ); // set oct notation
+Q_EXPORT QTextStream &dec( QTextStream &s ); // set dec notation
+Q_EXPORT QTextStream &hex( QTextStream &s ); // set hex notation
+Q_EXPORT QTextStream &endl( QTextStream &s ); // insert EOL ('\n')
+Q_EXPORT QTextStream &flush( QTextStream &s ); // flush output
+Q_EXPORT QTextStream &ws( QTextStream &s ); // eat whitespace on input
+Q_EXPORT QTextStream &reset( QTextStream &s ); // set default flags
+
+Q_EXPORT inline QTSManip qSetW( int w )
+{
+ QTSMFI func = &QTextStream::width;
+ return QTSManip(func,w);
+}
+
+Q_EXPORT inline QTSManip qSetFill( int f )
+{
+ QTSMFI func = &QTextStream::fill;
+ return QTSManip(func,f);
+}
+
+Q_EXPORT inline QTSManip qSetPrecision( int p )
+{
+ QTSMFI func = &QTextStream::precision;
+ return QTSManip(func,p);
+}
+
+
+#ifndef QT_ALTERNATE_QTSMANIP
+
+// These will go away in Qt 3.0, as they conflict with std libs
+//
+// If you get conflicts now, #define QT_ALTERNATE_QTSMANIP before
+// including this file.
+
+Q_EXPORT inline QTSManip setw( int w )
+{
+ QTSMFI func = &QTextStream::width;
+ return QTSManip(func,w);
+}
+
+Q_EXPORT inline QTSManip setfill( int f )
+{
+ QTSMFI func = &QTextStream::fill;
+ return QTSManip(func,f);
+}
+
+Q_EXPORT inline QTSManip setprecision( int p )
+{
+ QTSMFI func = &QTextStream::precision;
+ return QTSManip(func,p);
+}
+#endif
+
+#endif // QT_NO_TEXTSTREAM
+#endif // QTEXTSTREAM_H
diff --git a/qtools/qtl.h b/qtools/qtl.h
new file mode 100644
index 0000000..bd72e7d
--- /dev/null
+++ b/qtools/qtl.h
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+**
+** Definition of Qt template library classes
+**
+** Created : 990128
+**
+** Copyright (C) 1992-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 QTL_H
+#define QTL_H
+
+#ifndef QT_H
+#include "qtextstream.h"
+#include "qstring.h"
+#endif // QT_H
+
+#ifndef QT_NO_TEXTSTREAM
+template <class T>
+class QTextOStreamIterator
+{
+protected:
+ QTextOStream& stream;
+ QString separator;
+
+public:
+ QTextOStreamIterator( QTextOStream& s) : stream( s ) {}
+ QTextOStreamIterator( QTextOStream& s, const QString& sep )
+ : stream( s ), separator( sep ) {}
+ QTextOStreamIterator<T>& operator= ( const T& x ) {
+ stream << x;
+ if ( !separator.isEmpty() )
+ stream << separator;
+ return *this;
+ }
+ QTextOStreamIterator<T>& operator*() { return *this; }
+ QTextOStreamIterator<T>& operator++() { return *this; }
+ QTextOStreamIterator<T>& operator++(int) { return *this; }
+};
+#endif //QT_NO_TEXTSTREAM
+
+template <class InputIterator, class OutputIterator>
+inline OutputIterator qCopy( InputIterator _begin, InputIterator _end,
+ OutputIterator _dest )
+{
+ while( _begin != _end )
+ *_dest++ = *_begin++;
+ return _dest;
+}
+
+
+template <class T>
+inline void qSwap( T& _value1, T& _value2 )
+{
+ T tmp = _value1;
+ _value1 = _value2;
+ _value2 = tmp;
+}
+
+
+template <class InputIterator>
+inline void qBubbleSort( InputIterator b, InputIterator e )
+{
+ // Goto last element;
+ InputIterator last = e;
+ --last;
+ // only one element or no elements ?
+ if ( last == b )
+ return;
+
+ // So we have at least two elements in here
+ while( b != last ) {
+ bool swapped = FALSE;
+ InputIterator swap_pos = b;
+ InputIterator x = e;
+ InputIterator y = x;
+ y--;
+ do {
+ --x;
+ --y;
+ if ( *x < *y ) {
+ swapped = TRUE;
+ qSwap( *x, *y );
+ swap_pos = y;
+ }
+ } while( y != b );
+ if ( !swapped )
+ return;
+ b = swap_pos;
+ b++;
+ }
+}
+
+
+template <class Container>
+inline void qBubbleSort( Container &c )
+{
+ qBubbleSort( c.begin(), c.end() );
+}
+
+
+template <class Value>
+inline void qHeapSortPushDown( Value* heap, int first, int last )
+{
+ int r = first;
+ while( r <= last/2 ) {
+ // Node r has only one child ?
+ if ( last == 2*r ) {
+ // Need for swapping ?
+ if ( heap[r] > heap[ 2*r ] )
+ qSwap( heap[r], heap[ 2*r ] );
+ // That's it ...
+ r = last;
+ } else { // Node has two children
+ if ( heap[r] > heap[ 2*r ] && heap[ 2*r ] <= heap[ 2*r+1 ] ) {
+ // Swap with left child
+ qSwap( heap[r], heap[ 2*r ] );
+ r *= 2;
+ } else if ( heap[r] > heap[ 2*r+1 ] &&
+ heap[ 2*r+1 ] < heap[ 2*r ] ) {
+ // Swap with right child
+ qSwap( heap[r], heap[ 2*r+1 ] );
+ r = 2*r+1;
+ } else {
+ // We are done
+ r = last;
+ }
+ }
+ }
+}
+
+
+template <class InputIterator, class Value>
+inline void qHeapSortHelper( InputIterator b, InputIterator e, Value, uint n )
+{
+ // Create the heap
+ InputIterator insert = b;
+ Value* realheap = new Value[ n ];
+ // Wow, what a fake. But I want the heap to be indexed as 1...n
+ Value* heap = realheap - 1;
+ int size = 0;
+ for( ; insert != e; ++insert ) {
+ heap[++size] = *insert;
+ int i = size;
+ while( i > 1 && heap[i] < heap[ i / 2 ] ) {
+ qSwap( heap[i], heap[ i / 2 ] );
+ i /= 2;
+ }
+ }
+
+ // Now do the sorting
+ for( uint i = n; i > 0; i-- ) {
+ *b++ = heap[1];
+ if ( i > 1 ) {
+ heap[1] = heap[i];
+ qHeapSortPushDown( heap, 1, (int)i - 1 );
+ }
+ }
+
+ delete[] realheap;
+}
+
+
+template <class InputIterator>
+inline void qHeapSort( InputIterator b, InputIterator e )
+{
+ // Empty ?
+ if ( b == e )
+ return;
+
+ // How many entries have to be sorted ?
+ InputIterator it = b;
+ uint n = 0;
+ while ( it != e ) {
+ ++n;
+ ++it;
+ }
+
+ // The second last parameter is a hack to retrieve the value type
+ // Do the real sorting here
+ qHeapSortHelper( b, e, *b, n );
+}
+
+
+template <class Container>
+inline void qHeapSort( Container &c )
+{
+ if ( c.isEmpty() )
+ return;
+
+ // The second last parameter is a hack to retrieve the value type
+ // Do the real sorting here
+ qHeapSortHelper( c.begin(), c.end(), *(c.begin()), c.count() );
+}
+
+#endif
diff --git a/qtools/qtools.pro.in b/qtools/qtools.pro.in
new file mode 100644
index 0000000..17c6626
--- /dev/null
+++ b/qtools/qtools.pro.in
@@ -0,0 +1,71 @@
+TEMPLATE = lib
+CONFIG = warn_on staticlib $extraopts
+HEADERS = qarray.h \
+ qbuffer.h \
+ qcollection.h \
+ qconfig.h \
+ qcstring.h \
+ qdatastream.h \
+ qdatetime.h \
+ qdict.h \
+ qdir.h \
+ qfeatures.h \
+ qfile.h \
+ qfiledefs_p.h \
+ qfileinfo.h \
+ qgarray.h \
+ qfeatures.h \
+ qgdict.h \
+ qgeneric.h \
+ qglist.h \
+ qglobal.h \
+ qgvector.h \
+ qintdict.h \
+ qiodevice.h \
+ qlist.h \
+ qptrdict.h \
+ qqueue.h \
+ qregexp.h \
+ qshared.h \
+ qsortedlist.h \
+ qstack.h \
+ qstring.h \
+ qstringlist.h \
+ qstrlist.h \
+ qstrvec.h \
+ qtextstream.h \
+ qtl.h \
+ qvaluelist.h \
+ qvector.h
+SOURCES = qbuffer.cpp \
+ qcollection.cpp \
+ qcstring.cpp \
+ qdatastream.cpp \
+ qdatetime.cpp \
+ qdir.cpp \
+ qfile.cpp \
+ qfileinfo.cpp \
+ qgarray.cpp \
+ qgdict.cpp \
+ qglist.cpp \
+ qglobal.cpp \
+ qgvector.cpp \
+ qiodevice.cpp \
+ qregexp.cpp \
+ qstring.cpp \
+ qtextstream.cpp \
+ qtextcodec.cpp \
+ qstringlist.cpp
+
+unix:SOURCES += qfile_unix.cpp \
+ qdir_unix.cpp \
+ qfileinfo_unix.cpp
+
+win32:SOURCES += qfile_win32.cpp \
+ qdir_win32.cpp \
+ qfileinfo_win32.cpp
+
+INCLUDEPATH = .
+TMAKE_CXXFLAGS = -DQT_NO_CODECS -DQT_LITE_UNICODE
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+OBJECTS_DIR = ../objects
diff --git a/qtools/qvaluelist.h b/qtools/qvaluelist.h
new file mode 100644
index 0000000..a1014ed
--- /dev/null
+++ b/qtools/qvaluelist.h
@@ -0,0 +1,449 @@
+/****************************************************************************
+**
+**
+** Definition of QValueList class
+**
+** Created : 990406
+**
+** Copyright (C) 1992-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 QVALUELIST_H
+#define QVALUELIST_H
+
+#ifndef QT_H
+#include "qshared.h"
+#include "qdatastream.h"
+#endif // QT_H
+
+#if defined(_CC_MSVC_)
+#pragma warning(disable:4284) // "return type for operator -> is not a UDT"
+#endif
+
+template <class T>
+class Q_EXPORT QValueListNode
+{
+public:
+ QValueListNode( const T& t ) : data( t ) { }
+ QValueListNode() { }
+#if defined(Q_TEMPLATEDLL)
+ // Workaround MS bug in memory de/allocation in DLL vs. EXE
+ virtual ~QValueListNode() { }
+#endif
+
+ QValueListNode<T>* next;
+ QValueListNode<T>* prev;
+ T data;
+};
+
+template<class T>
+class Q_EXPORT QValueListIterator
+{
+ public:
+ /**
+ * Typedefs
+ */
+ typedef QValueListNode<T>* NodePtr;
+
+ /**
+ * Variables
+ */
+ NodePtr node;
+
+ /**
+ * Functions
+ */
+ QValueListIterator() : node( 0 ) {}
+ QValueListIterator( NodePtr p ) : node( p ) {}
+ QValueListIterator( const QValueListIterator<T>& it ) : node( it.node ) {}
+
+ bool operator==( const QValueListIterator<T>& it ) const { return node == it.node; }
+ bool operator!=( const QValueListIterator<T>& it ) const { return node != it.node; }
+ const T& operator*() const { return node->data; }
+ T& operator*() { return node->data; }
+
+ // Compilers are too dumb to understand this for QValueList<int>
+ //T* operator->() const { return &(node->data); }
+
+ QValueListIterator<T>& operator++() {
+ node = node->next;
+ return *this;
+ }
+
+ QValueListIterator<T> operator++(int) {
+ QValueListIterator<T> tmp = *this;
+ node = node->next;
+ return tmp;
+ }
+
+ QValueListIterator<T>& operator--() {
+ node = node->prev;
+ return *this;
+ }
+
+ QValueListIterator<T> operator--(int) {
+ QValueListIterator<T> tmp = *this;
+ node = node->prev;
+ return tmp;
+ }
+};
+
+template<class T>
+class Q_EXPORT QValueListConstIterator
+{
+ public:
+ /**
+ * Typedefs
+ */
+ typedef QValueListNode<T>* NodePtr;
+
+ /**
+ * Variables
+ */
+ NodePtr node;
+
+ /**
+ * Functions
+ */
+ QValueListConstIterator() : node( 0 ) {}
+ QValueListConstIterator( NodePtr p ) : node( p ) {}
+ QValueListConstIterator( const QValueListConstIterator<T>& it ) : node( it.node ) {}
+ QValueListConstIterator( const QValueListIterator<T>& it ) : node( it.node ) {}
+
+ bool operator==( const QValueListConstIterator<T>& it ) const { return node == it.node; }
+ bool operator!=( const QValueListConstIterator<T>& it ) const { return node != it.node; }
+ const T& operator*() const { return node->data; }
+
+ // Compilers are too dumb to understand this for QValueList<int>
+ //const T* operator->() const { return &(node->data); }
+
+ QValueListConstIterator<T>& operator++() {
+ node = node->next;
+ return *this;
+ }
+
+ QValueListConstIterator<T> operator++(int) {
+ QValueListConstIterator<T> tmp = *this;
+ node = node->next;
+ return tmp;
+ }
+
+ QValueListConstIterator<T>& operator--() {
+ node = node->prev;
+ return *this;
+ }
+
+ QValueListConstIterator<T> operator--(int) {
+ QValueListConstIterator<T> tmp = *this;
+ node = node->prev;
+ return tmp;
+ }
+};
+
+template <class T>
+class Q_EXPORT QValueListPrivate : public QShared
+{
+public:
+ /**
+ * Typedefs
+ */
+ typedef QValueListIterator<T> Iterator;
+ typedef QValueListConstIterator<T> ConstIterator;
+ typedef QValueListNode<T> Node;
+ typedef QValueListNode<T>* NodePtr;
+
+ /**
+ * Functions
+ */
+ QValueListPrivate() { node = new Node; node->next = node->prev = node; nodes = 0; }
+ QValueListPrivate( const QValueListPrivate<T>& _p ) : QShared() {
+ node = new Node; node->next = node->prev = node; nodes = 0;
+ Iterator b( _p.node->next );
+ Iterator e( _p.node );
+ Iterator i( node );
+ while( b != e )
+ insert( i, *b++ );
+ }
+
+ void derefAndDelete() // ### hack to get around hp-cc brain damage
+ {
+ if ( deref() )
+ delete this;
+ }
+
+#if defined(Q_TEMPLATEDLL)
+ // Workaround MS bug in memory de/allocation in DLL vs. EXE
+ virtual
+#endif
+ ~QValueListPrivate() {
+ NodePtr p = node->next;
+ while( p != node ) {
+ NodePtr x = p->next;
+ delete p;
+ p = x;
+ }
+ delete node;
+ }
+
+ Iterator insert( Iterator it, const T& x ) {
+ NodePtr p = new Node( x );
+ p->next = it.node;
+ p->prev = it.node->prev;
+ it.node->prev->next = p;
+ it.node->prev = p;
+ nodes++;
+ return p;
+ }
+
+ Iterator remove( Iterator it ) {
+ ASSERT ( it.node != node );
+ NodePtr next = it.node->next;
+ NodePtr prev = it.node->prev;
+ prev->next = next;
+ next->prev = prev;
+ delete it.node;
+ nodes--;
+ return Iterator( next );
+ }
+
+ NodePtr find( NodePtr start, const T& x ) const {
+ ConstIterator first( start );
+ ConstIterator last( node );
+ while( first != last) {
+ if ( *first == x )
+ return first.node;
+ ++first;
+ }
+ return last.node;
+ }
+
+ int findIndex( NodePtr start, const T& x ) const {
+ ConstIterator first( start );
+ ConstIterator last( node );
+ int pos = 0;
+ while( first != last) {
+ if ( *first == x )
+ return pos;
+ ++first;
+ ++pos;
+ }
+ return -1;
+ }
+
+ uint contains( const T& x ) const {
+ uint result = 0;
+ Iterator first = Iterator( node->next );
+ Iterator last = Iterator( node );
+ while( first != last) {
+ if ( *first == x )
+ ++result;
+ ++first;
+ }
+ return result;
+ }
+
+ void remove( const T& x ) {
+ Iterator first = Iterator( node->next );
+ Iterator last = Iterator( node );
+ while( first != last) {
+ if ( *first == x )
+ first = remove( first );
+ else
+ ++first;
+ }
+ }
+
+ NodePtr at( uint i ) const {
+ ASSERT( i <= nodes );
+ NodePtr p = node->next;
+ for( uint x = 0; x < i; ++x )
+ p = p->next;
+ return p;
+ }
+
+ void clear() {
+ nodes = 0;
+ NodePtr p = node->next;
+ while( p != node ) {
+ NodePtr next = p->next;
+ delete p;
+ p = next;
+ }
+ node->next = node->prev = node;
+ }
+
+ NodePtr node;
+ uint nodes;
+};
+
+template <class T>
+class Q_EXPORT QValueList
+{
+public:
+ /**
+ * Typedefs
+ */
+ typedef QValueListIterator<T> Iterator;
+ typedef QValueListConstIterator<T> ConstIterator;
+ typedef T ValueType;
+
+ /**
+ * API
+ */
+ QValueList() { sh = new QValueListPrivate<T>; }
+ QValueList( const QValueList<T>& l ) { sh = l.sh; sh->ref(); }
+ ~QValueList() { sh->derefAndDelete(); }
+
+ QValueList<T>& operator= ( const QValueList<T>& l )
+ {
+ l.sh->ref();
+ sh->derefAndDelete();
+ sh = l.sh;
+ return *this;
+ }
+
+ QValueList<T> operator+ ( const QValueList<T>& l ) const
+ {
+ QValueList<T> l2( *this );
+ for( ConstIterator it = l.begin(); it != l.end(); ++it )
+ l2.append( *it );
+ return l2;
+ }
+
+ QValueList<T>& operator+= ( const QValueList<T>& l )
+ {
+ for( ConstIterator it = l.begin(); it != l.end(); ++it )
+ append( *it );
+ return *this;
+ }
+
+ bool operator== ( const QValueList<T>& l ) const
+ {
+ if ( count() != l.count() )
+ return FALSE;
+ ConstIterator it2 = begin();
+ ConstIterator it = l.begin();
+ for( ; it != l.end(); ++it, ++it2 )
+ if ( !( *it == *it2 ) )
+ return FALSE;
+ return TRUE;
+ }
+
+ bool operator!= ( const QValueList<T>& l ) const { return !( *this == l ); }
+
+ Iterator begin() { detach(); return Iterator( sh->node->next ); }
+ ConstIterator begin() const { return ConstIterator( sh->node->next ); }
+ Iterator end() { detach(); return Iterator( sh->node ); }
+ ConstIterator end() const { return ConstIterator( sh->node ); }
+ Iterator fromLast() { detach(); return Iterator( sh->node->prev ); }
+ ConstIterator fromLast() const { return ConstIterator( sh->node->prev ); }
+
+ bool isEmpty() const { return ( sh->nodes == 0 ); }
+
+ Iterator insert( Iterator it, const T& x ) { detach(); return sh->insert( it, x ); }
+
+ Iterator append( const T& x ) { detach(); return sh->insert( end(), x ); }
+ Iterator prepend( const T& x ) { detach(); return sh->insert( begin(), x ); }
+
+ Iterator remove( Iterator it ) { detach(); return sh->remove( it ); }
+ void remove( const T& x ) { detach(); sh->remove( x ); }
+
+ T& first() { detach(); return sh->node->next->data; }
+ const T& first() const { return sh->node->next->data; }
+ T& last() { detach(); return sh->node->prev->data; }
+ const T& last() const { return sh->node->prev->data; }
+
+ T& operator[] ( uint i ) { detach(); return sh->at(i)->data; }
+ const T& operator[] ( uint i ) const { return sh->at(i)->data; }
+ Iterator at( uint i ) { detach(); return Iterator( sh->at(i) ); }
+ ConstIterator at( uint i ) const { return ConstIterator( sh->at(i) ); }
+ Iterator find ( const T& x ) { detach(); return Iterator( sh->find( sh->node->next, x) ); }
+ ConstIterator find ( const T& x ) const { return ConstIterator( sh->find( sh->node->next, x) ); }
+ Iterator find ( Iterator it, const T& x ) { detach(); return Iterator( sh->find( it.node, x ) ); }
+ ConstIterator find ( ConstIterator it, const T& x ) const { return ConstIterator( sh->find( it.node, x ) ); }
+ int findIndex( const T& x ) const { return sh->findIndex( sh->node->next, x) ; }
+ uint contains( const T& x ) const { return sh->contains( x ); }
+
+ uint count() const { return sh->nodes; }
+
+ void clear() { if ( sh->count == 1 ) sh->clear(); else { sh->deref(); sh = new QValueListPrivate<T>; } }
+
+
+ QValueList<T>& operator+= ( const T& x )
+ {
+ append( x );
+ return *this;
+ }
+ QValueList<T>& operator<< ( const T& x )
+ {
+ append( x );
+ return *this;
+ }
+
+
+protected:
+ /**
+ * Helpers
+ */
+ void detach() { if ( sh->count > 1 ) { sh->deref(); sh = new QValueListPrivate<T>( *sh ); } }
+
+ /**
+ * Variables
+ */
+ QValueListPrivate<T>* sh;
+};
+
+#ifndef QT_NO_DATASTREAM
+template<class T>
+inline QDataStream& operator>>( QDataStream& s, QValueList<T>& l )
+{
+ l.clear();
+ Q_UINT32 c;
+ s >> c;
+ for( Q_UINT32 i = 0; i < c; ++i )
+ {
+ T t;
+ s >> t;
+ l.append( t );
+ }
+ return s;
+}
+
+template<class T>
+inline QDataStream& operator<<( QDataStream& s, const QValueList<T>& l )
+{
+ s << (Q_UINT32)l.count();
+ QValueListConstIterator<T> it = l.begin();
+ for( ; it != l.end(); ++it )
+ s << *it;
+ return s;
+}
+#endif // QT_NO_DATASTREAM
+#endif // QVALUELIST_H
diff --git a/qtools/qvector.h b/qtools/qvector.h
new file mode 100644
index 0000000..36f0be7
--- /dev/null
+++ b/qtools/qvector.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+**
+** Definition of QVector template/macro class
+**
+** Created : 930907
+**
+** Copyright (C) 1992-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 QVECTOR_H
+#define QVECTOR_H
+
+#ifndef QT_H
+#include "qgvector.h"
+#endif // QT_H
+
+
+template<class type> class QVector : public QGVector
+{
+public:
+ QVector() {}
+ QVector( uint size ) : QGVector(size) {}
+ QVector( const QVector<type> &v ) : QGVector(v) {}
+ ~QVector() { clear(); }
+ QVector<type> &operator=(const QVector<type> &v)
+ { return (QVector<type>&)QGVector::operator=(v); }
+ type **data() const { return (type **)QGVector::data(); }
+ uint size() const { return QGVector::size(); }
+ uint count() const { return QGVector::count(); }
+ bool isEmpty() const { return QGVector::count() == 0; }
+ bool isNull() const { return QGVector::size() == 0; }
+ bool resize( uint size ) { return QGVector::resize(size); }
+ bool insert( uint i, const type *d){ return QGVector::insert(i,(Item)d); }
+ bool remove( uint i ) { return QGVector::remove(i); }
+ type *take( uint i ) { return (type *)QGVector::take(i); }
+ void clear() { QGVector::clear(); }
+ bool fill( const type *d, int size=-1 )
+ { return QGVector::fill((Item)d,size);}
+ void sort() { QGVector::sort(); }
+ int bsearch( const type *d ) const{ return QGVector::bsearch((Item)d); }
+ int findRef( const type *d, uint i=0 ) const
+ { return QGVector::findRef((Item)d,i);}
+ int find( const type *d, uint i= 0 ) const
+ { return QGVector::find((Item)d,i); }
+ uint containsRef( const type *d ) const
+ { return QGVector::containsRef((Item)d); }
+ uint contains( const type *d ) const
+ { return QGVector::contains((Item)d); }
+ type *operator[]( int i ) const { return (type *)QGVector::at(i); }
+ type *at( uint i ) const { return (type *)QGVector::at(i); }
+ void toList( QGList *list ) const { QGVector::toList(list); }
+private:
+ void deleteItem( Item d ) { if ( del_item ) delete (type *)d; }
+};
+
+
+#endif // QVECTOR_H
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 6a505ec..9289375 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -50,10 +50,20 @@ ClassDef::ClassDef(
: Definition(defFileName,defLine,removeRedundantWhiteSpace(nm))
{
//name=n;
+
+ QCString compoundName;
+ switch(ct)
+ {
+ case Class: compoundName="class"; break;
+ case Struct: compoundName="struct"; break;
+ case Union: compoundName="union"; break;
+ case Interface: compoundName="interface"; break;
+ case Exception: compoundName="exception"; break;
+ }
if (fName)
fileName=stripExtension(fName);
else
- fileName="class_"+nameToFile(nm);
+ fileName=compoundName+"_"+nameToFile(nm);
if (lref)
{
//url=(QCString)"doxygen=\""+lref+":\" href=\""+fileName;
@@ -66,7 +76,7 @@ ClassDef::ClassDef(
exampleList = new ExampleList;
exampleDict = new ExampleDict(29);
}
- memListFileName="class_"+nameToFile(nm)+"-members";
+ memListFileName=compoundName+"_"+nameToFile(nm)+"-members";
inherits = new BaseClassList;
inherits->setAutoDelete(TRUE);
inheritedBy = new BaseClassList;
@@ -195,6 +205,7 @@ void ClassDef::addMembersToMemberGroup()
addMemberListToGroup(&priStaticAttribs);
addMemberListToGroup(&friends);
addMemberListToGroup(&related);
+ addMemberListToGroup(&properties);
}
// adds new member definition to the class
@@ -228,6 +239,10 @@ void ClassDef::insertMember(MemberDef *md)
dcopMethods.append(md);
md->setSectionList(&dcopMethods);
break;
+ case MemberDef::Property:
+ properties.append(md);
+ md->setSectionList(&properties);
+ break;
case MemberDef::Slot: // Qt specific
switch (md->protection())
{
@@ -363,6 +378,12 @@ void ClassDef::insertMember(MemberDef *md)
{
switch (md->memberType())
{
+ case MemberDef::Property:
+ if (Config::sortMembersFlag)
+ propertyMembers.inSort(md);
+ else
+ propertyMembers.append(md);
+ break;
case MemberDef::Signal: // fall through
case MemberDef::DCOP:
if (Config::sortMembersFlag)
@@ -521,6 +542,7 @@ void ClassDef::computeAnchors()
setAnchors('t',&proTypes);
setAnchors('u',&priTypes);
setAnchors('v',&dcopMethods);
+ setAnchors('w',&properties);
}
void ClassDef::distributeMemberGroupDocumentation()
@@ -789,6 +811,7 @@ void ClassDef::writeDocumentation(OutputList &ol)
ol.startDotGraph();
parseText(ol,theTranslator->trClassDiagram(name()));
ol.endDotGraph(inheritanceGraph);
+ if (Config::generateLegend)
{
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
@@ -821,6 +844,7 @@ void ClassDef::writeDocumentation(OutputList &ol)
ol.startDotGraph();
parseText(ol,theTranslator->trCollaborationDiagram(name()));
ol.endDotGraph(usageImplGraph);
+ if (Config::generateLegend)
{
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Html);
@@ -870,6 +894,7 @@ void ClassDef::writeDocumentation(OutputList &ol)
pubSlots.writeDeclarations(ol,this,0,0,0,theTranslator->trPublicSlots(),0);
signals.writeDeclarations(ol,this,0,0,0,theTranslator->trSignals(),0);
dcopMethods.writeDeclarations(ol,this,0,0,0,theTranslator->trDCOPMethods(),0);
+ properties.writeDeclarations(ol,this,0,0,0,theTranslator->trProperties(),0);
// static public members
pubStaticMembers.writeDeclarations(ol,this,0,0,0,theTranslator->trStaticPublicMembers(),0);
@@ -1051,6 +1076,16 @@ void ClassDef::writeDocumentation(OutputList &ol)
variableMembers.writeDocumentation(ol,name(),this);
}
+ propertyMembers.countDocMembers();
+ if (propertyMembers.totalCount()>0)
+ {
+ ol.writeRuler();
+ ol.startGroupHeader();
+ parseText(ol,theTranslator->trPropertyDocumentation());
+ ol.endGroupHeader();
+ propertyMembers.writeDocumentation(ol,name(),this);
+ }
+
ol.startTextBlock();
// write the list of used files (not for man pages)
@@ -1355,6 +1390,7 @@ void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup)
pubSlots.writePlainDeclarations(ol,this,0,0,0);
signals.writePlainDeclarations(ol,this,0,0,0);
dcopMethods.writePlainDeclarations(ol,this,0,0,0);
+ properties.writePlainDeclarations(ol,this,0,0,0);
pubStaticMembers.writePlainDeclarations(ol,this,0,0,0);
pubStaticAttribs.writePlainDeclarations(ol,this,0,0,0);
proTypes.writePlainDeclarations(ol,this,0,0,0);
@@ -1808,6 +1844,7 @@ void ClassDef::generateXMLSection(QTextStream &t,MemberList *ml,const char *type
void ClassDef::generateXML(QTextStream &t)
{
+ if (name().find('@')!=-1) return; // skip anonymous compounds
t << " <compounddef id=\""
<< getOutputFileBase() << "\" type=\"";
switch(compType)
@@ -1893,6 +1930,7 @@ void ClassDef::generateXML(QTextStream &t)
generateXMLSection(t,&pubSlots,"public-slot");
generateXMLSection(t,&signals,"signal");
generateXMLSection(t,&dcopMethods,"dcop-func");
+ generateXMLSection(t,&properties,"property");
generateXMLSection(t,&pubStaticMembers,"public-static-func");
generateXMLSection(t,&pubStaticAttribs,"public-static-attrib");
generateXMLSection(t,&proTypes,"protected-type");
diff --git a/src/classdef.h b/src/classdef.h
index dd4b16f..2bb6a66 100644
--- a/src/classdef.h
+++ b/src/classdef.h
@@ -169,6 +169,7 @@ class ClassDef : public Definition
MemberList signals;
MemberList friends;
MemberList dcopMethods;
+ MemberList properties;
/* member list by types */
MemberList constructors;
@@ -178,6 +179,7 @@ class ClassDef : public Definition
MemberList functionMembers;
MemberList relatedMembers;
MemberList variableMembers;
+ MemberList propertyMembers;
/* user defined member groups */
MemberGroupList *memberGroupList;
diff --git a/src/code.l b/src/code.l
index 6253507..10d706f 100644
--- a/src/code.l
+++ b/src/code.l
@@ -417,7 +417,8 @@ static bool getLink(const char *className,
QCString m=removeRedundantWhiteSpace(memberName);
QCString c=className;
//printf("Trying `%s'::`%s'\n",c.data(),m.data());
- if (getDefs(c,m,"()",md,cd,fd,nd,gd) && md->isLinkable())
+ if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,g_sourceFileDef) &&
+ md->isLinkable())
{
//printf("Found!\n");
if (g_exampleBlock)
diff --git a/src/config.h b/src/config.h
index 724f02b..a85fc68 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,4 +1,4 @@
-/* This file was generated by configgen on Sun Oct 1 13:51:26 2000
+/* This file was generated by configgen on Tue Oct 10 22:16:03 2000
* from config_templ.h
*
* DO NOT EDIT!
@@ -74,6 +74,7 @@ struct Config
static bool warningFlag; // generate warnings flag
static bool warningUndocFlag; // generate undocumented warnings
static QCString warnFormat; // format of the warning messages
+ static QCString warnLogFile; // log file to write warning to
static QStrList inputSources; // list of input files
static QStrList filePatternList; // list of file patterns
static bool recursiveFlag; // scan directories recursively
@@ -133,6 +134,7 @@ struct Config
static QCString dotPath; // path to the dot tool
static int maxDotGraphWidth; // max dot graph width
static int maxDotGraphHeight; // max dot graph height
+ static bool generateLegend; // generate legend page
static bool searchEngineFlag; // generate search engine flag
static QCString cgiName; // the name of the CGI binary
static QCString cgiURL; // the absolute URL to the CGI binary
diff --git a/src/config.l b/src/config.l
index 204531f..86b6578 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1,4 +1,4 @@
-/* This file was generated by configgen on Sun Oct 1 13:51:26 2000
+/* This file was generated by configgen on Tue Oct 10 22:16:03 2000
* from config_templ.l
*
* DO NOT EDIT!
@@ -111,6 +111,7 @@ bool Config::quietFlag = FALSE;
bool Config::warningFlag = TRUE;
bool Config::warningUndocFlag = TRUE;
QCString Config::warnFormat = "$file:$line: $text";
+QCString Config::warnLogFile;
QStrList Config::inputSources;
QStrList Config::filePatternList;
bool Config::recursiveFlag = FALSE;
@@ -170,6 +171,7 @@ bool Config::gfxHierarchyFlag = TRUE;
QCString Config::dotPath;
int Config::maxDotGraphWidth = 1024;
int Config::maxDotGraphHeight = 1024;
+bool Config::generateLegend = TRUE;
bool Config::searchEngineFlag = FALSE;
QCString Config::cgiName = "search.cgi";
QCString Config::cgiURL;
@@ -370,6 +372,7 @@ static void readIncludeFile(const char *incName)
<Start>"WARNINGS"[ \t]*"=" { BEGIN(GetBool); b=&Config::warningFlag; }
<Start>"WARN_IF_UNDOCUMENTED"[ \t]*"=" { BEGIN(GetBool); b=&Config::warningUndocFlag; }
<Start>"WARN_FORMAT"[ \t]*"=" { BEGIN(GetString); s=&Config::warnFormat; s->resize(0); }
+<Start>"WARN_LOGFILE"[ \t]*"=" { BEGIN(GetString); s=&Config::warnLogFile; s->resize(0); }
<Start>"INPUT"[ \t]*"=" { BEGIN(GetStrList); l=&Config::inputSources; l->clear(); elemStr=""; }
<Start>"INPUT"[ \t]*"+=" { BEGIN(GetStrList); l=&Config::inputSources; elemStr=""; }
<Start>"FILE_PATTERNS"[ \t]*"=" { BEGIN(GetStrList); l=&Config::filePatternList; l->clear(); elemStr=""; }
@@ -443,6 +446,7 @@ static void readIncludeFile(const char *incName)
<Start>"DOT_PATH"[ \t]*"=" { BEGIN(GetString); s=&Config::dotPath; s->resize(0); }
<Start>"MAX_DOT_GRAPH_WIDTH"[ \t]*"=" { BEGIN(GetString); s=&maxDotGraphWidthString; s->resize(0); }
<Start>"MAX_DOT_GRAPH_HEIGHT"[ \t]*"=" { BEGIN(GetString); s=&maxDotGraphHeightString; s->resize(0); }
+<Start>"GENERATE_LEGEND"[ \t]*"=" { BEGIN(GetBool); b=&Config::generateLegend; }
<Start>"SEARCHENGINE"[ \t]*"=" { BEGIN(GetBool); b=&Config::searchEngineFlag; }
<Start>"CGI_NAME"[ \t]*"=" { BEGIN(GetString); s=&Config::cgiName; s->resize(0); }
<Start>"CGI_URL"[ \t]*"=" { BEGIN(GetString); s=&Config::cgiURL; s->resize(0); }
@@ -614,6 +618,7 @@ void dumpConfig()
printf("warningFlag=`%d'\n",Config::warningFlag);
printf("warningUndocFlag=`%d'\n",Config::warningUndocFlag);
printf("warnFormat=`%s'\n",Config::warnFormat.data());
+ printf("warnLogFile=`%s'\n",Config::warnLogFile.data());
printf("# configuration options related to the input files\n");
{
char *is=Config::inputSources.first();
@@ -781,6 +786,7 @@ void dumpConfig()
printf("dotPath=`%s'\n",Config::dotPath.data());
printf("maxDotGraphWidth=`%d'\n",Config::maxDotGraphWidth);
printf("maxDotGraphHeight=`%d'\n",Config::maxDotGraphHeight);
+ printf("generateLegend=`%d'\n",Config::generateLegend);
printf("# Configuration::addtions related to the search engine \n");
printf("searchEngineFlag=`%d'\n",Config::searchEngineFlag);
printf("cgiName=`%s'\n",Config::cgiName.data());
@@ -837,6 +843,7 @@ void Config::init()
Config::warningFlag = TRUE;
Config::warningUndocFlag = TRUE;
Config::warnFormat = "$file:$line: $text";
+ Config::warnLogFile.resize(0);
Config::inputSources.clear();
Config::filePatternList.clear();
Config::recursiveFlag = FALSE;
@@ -896,6 +903,7 @@ void Config::init()
Config::dotPath.resize(0);
Config::maxDotGraphWidth = 1024;
Config::maxDotGraphHeight = 1024;
+ Config::generateLegend = TRUE;
Config::searchEngineFlag = FALSE;
Config::cgiName = "search.cgi";
Config::cgiURL.resize(0);
@@ -1405,6 +1413,17 @@ void writeTemplateConfig(QFile *f,bool sl)
if (!sl)
{
t << "\n";
+ t << "# The WARN_LOGFILE tag can be used to specify a file to which warning \n";
+ t << "# and error messages should be written. If left blank the output is written \n";
+ t << "# to stderr. \n";
+ t << "\n";
+ }
+ t << "WARN_LOGFILE = ";
+ writeStringValue(t,Config::warnLogFile);
+ t << "\n";
+ if (!sl)
+ {
+ t << "\n";
}
t << "#---------------------------------------------------------------------------\n";
t << "# configuration options related to the input files\n";
@@ -2141,6 +2160,17 @@ void writeTemplateConfig(QFile *f,bool sl)
if (!sl)
{
t << "\n";
+ t << "# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will \n";
+ t << "# generate a legend page explaining the meaning of the various boxes and \n";
+ t << "# arrows in the dot generated graphs. \n";
+ t << "\n";
+ }
+ t << "GENERATE_LEGEND = ";
+ writeBoolValue(t,Config::generateLegend);
+ t << "\n";
+ if (!sl)
+ {
+ t << "\n";
}
t << "#---------------------------------------------------------------------------\n";
t << "# Configuration::addtions related to the search engine \n";
@@ -2420,6 +2450,7 @@ void substituteEnvironmentVars()
substEnvVarsInStrList( Config::sectionFilterList );
substEnvVarsInStrList( Config::aliasList );
substEnvVarsInString( Config::warnFormat );
+ substEnvVarsInString( Config::warnLogFile );
substEnvVarsInStrList( Config::inputSources );
substEnvVarsInStrList( Config::filePatternList );
substEnvVarsInStrList( Config::excludeSources );
diff --git a/src/doc.l b/src/doc.l
index 3cc7891..41af1ee 100644
--- a/src/doc.l
+++ b/src/doc.l
@@ -92,12 +92,12 @@ static QCString sectionRef;
static bool insideVerbatim = FALSE;
static bool insidePre = FALSE;
static int depthIf;
-//static int currentListIndentLevel;
-static QStack<char> currentListIndent;
static QCString curImageName;
static QCString curImageCaption;
static QCString internalRefFile;
static QCString internalRefAnchor;
+static QStack<char> currentListIndent; // indent stack of all list items
+static bool insideItemList = FALSE;
//-----------------------------------------------------------------------------
@@ -456,6 +456,32 @@ static void showUntil(OutputList &ol,const char *key)
//-----------------------------------------------------------------
+static bool inBlock()
+{
+ return inParamBlock || inRetValBlock || inSeeBlock || inReturnBlock || inAuthorBlock ||
+ inVersionBlock || inSinceBlock || inDateBlock || inWarningBlock || inRemarkBlock ||
+ inAttentionBlock || inBugBlock || inNoteBlock ||
+ inParBlock || inExceptionBlock || inDeprecatedBlock || inPreBlock ||
+ inPostBlock || inInvarBlock;
+}
+
+static void endBlock()
+{
+ if (inParamBlock || inRetValBlock || inExceptionBlock)
+ {
+ outDoc->endDescTableData();
+ outDoc->endDescTable();
+ }
+ outDoc->endDescList();
+ currentListIndent.pop();
+ inParamBlock=inRetValBlock=inSeeBlock=inReturnBlock=inAuthorBlock=
+ inVersionBlock=inSinceBlock=inDateBlock=inBugBlock=inNoteBlock=inWarningBlock=
+ inParBlock=inExceptionBlock=inDeprecatedBlock=inPreBlock=inPostBlock=
+ inInvarBlock=inRemarkBlock=inAttentionBlock=FALSE;
+}
+
+//-----------------------------------------------------------------
+
struct IndentInfo
{
public:
@@ -477,8 +503,7 @@ struct IndentInfo
bool enumerated;
};
-static QStack<IndentInfo> listIndentStack;
-static bool insideItemList = FALSE;
+static QStack<IndentInfo> listIndentStack; // indent stack of - items
static void addListItemMarker(const char *marker,int dashPos,bool enumerated)
{
@@ -504,6 +529,7 @@ static void addListItemMarker(const char *marker,int dashPos,bool enumerated)
//printf("list marker found at column %d enumerated %d\n",indent,enumerated);
if (!insideItemList)
{
+ currentListIndent.push(enumerated ? "O" : "U");
listIndentStack.push(new IndentInfo(indent,enumerated));
listIndentStack.top()->startList();
listIndentStack.top()->writeItem();
@@ -528,6 +554,7 @@ static void addListItemMarker(const char *marker,int dashPos,bool enumerated)
}
else if (pPrevInfo->indent<indent) // start sub item list
{
+ currentListIndent.push(enumerated ? "O" : "U");
listIndentStack.push(new IndentInfo(indent,enumerated));
listIndentStack.top()->startList();
listIndentStack.top()->writeItem();
@@ -536,6 +563,7 @@ static void addListItemMarker(const char *marker,int dashPos,bool enumerated)
{
pPrevInfo->endList();
listIndentStack.pop();
+ currentListIndent.pop();
delete pPrevInfo;
// safe guard against wrong indenting
if (listIndentStack.isEmpty())
@@ -558,35 +586,27 @@ static void forceEndItemList()
IndentInfo *info;
while ((info=listIndentStack.pop())!=0)
{
- info->endList();
delete info;
}
- insideItemList=FALSE;
-}
-
-//-----------------------------------------------------------------
-
-static bool inBlock()
-{
- return inParamBlock || inRetValBlock || inSeeBlock || inReturnBlock || inAuthorBlock ||
- inVersionBlock || inSinceBlock || inDateBlock || inWarningBlock || inRemarkBlock ||
- inAttentionBlock || inBugBlock || inNoteBlock ||
- inParBlock || inExceptionBlock || inDeprecatedBlock || inPreBlock ||
- inPostBlock || inInvarBlock;
-}
-
-static void endBlock()
-{
- if (inParamBlock || inRetValBlock || inExceptionBlock)
+ while (!currentListIndent.isEmpty())
+ {
+ char c=*currentListIndent.pop();
+ switch(c)
{
- outDoc->endDescTableData();
- outDoc->endDescTable();
+ case 'O': outDoc->endEnumList(); break;
+ case 'U': outDoc->endItemList(); break;
+ case 'D':
+ if (inBlock())
+ {
+ currentListIndent.push("D"); // hack!
+ endBlock();
+ }
+ else
+ outDoc->endDescription();
+ break;
}
- outDoc->endDescList();
- inParamBlock=inRetValBlock=inSeeBlock=inReturnBlock=inAuthorBlock=
- inVersionBlock=inSinceBlock=inDateBlock=inBugBlock=inNoteBlock=inWarningBlock=
- inParBlock=inExceptionBlock=inDeprecatedBlock=inPreBlock=inPostBlock=
- inInvarBlock=inRemarkBlock=inAttentionBlock=FALSE;
+ }
+ insideItemList=FALSE;
}
//-----------------------------------------------------------------
@@ -999,6 +1019,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
endArgumentList();
if (b) endBlock();
inParBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
outDoc->docify(title);
@@ -1018,6 +1039,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inWarningBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trWarning()+": ");
@@ -1036,6 +1058,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inRemarkBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trRemarks()+": ");
@@ -1054,6 +1077,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inAttentionBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trAttention()+": ");
@@ -1072,6 +1096,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inBugBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trBugsAndLimitations()+": ");
@@ -1090,6 +1115,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inNoteBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trNote()+": ");
@@ -1108,6 +1134,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inPreBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trPrecondition()+": ");
@@ -1126,6 +1153,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inPostBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trPostcondition()+": ");
@@ -1144,6 +1172,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inInvarBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trInvariant()+": ");
@@ -1162,6 +1191,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inVersionBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trVersion()+": ");
@@ -1180,6 +1210,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inSinceBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trSince()+": ");
@@ -1198,6 +1229,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inDateBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trDate()+": ");
@@ -1220,6 +1252,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
ASSERT(item!=0);
endArgumentList();
if (inBlock()) endBlock();
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
outDoc->writeObjectLink(0,"todo",item->listAnchor,theTranslator->trTodo()+": ");
@@ -1228,6 +1261,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
outDoc->writeDescItem();
internalParseDocument(item->text);
outDoc->endDescList();
+ currentListIndent.pop();
}
}
<DocScan>"\\test "[0-9]+ { // this tag is generated in an earlier pass
@@ -1240,6 +1274,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
ASSERT(item!=0);
endArgumentList();
if (inBlock()) endBlock();
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
outDoc->writeObjectLink(0,"test",item->listAnchor,theTranslator->trTest()+": ");
@@ -1248,6 +1283,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
outDoc->writeDescItem();
internalParseDocument(item->text);
outDoc->endDescList();
+ currentListIndent.pop();
}
}
<DocScan>{CMD}"deprecated"/{BN} {
@@ -1256,6 +1292,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inDeprecatedBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trDeprecated()+": ");
@@ -1276,6 +1313,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
tagText=tagText.left(tagText.length()-1);
endArgumentList();
if (inBlock()) endBlock();
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(tagName+": ");
@@ -1284,6 +1322,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
outDoc->writeDescItem();
scanString(tagText);
outDoc->endDescList();
+ currentListIndent.pop();
}
<DocScan>{CMD}"author"/{BN} {
endArgumentList();
@@ -1291,6 +1330,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inAuthorBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trAuthors()+": ");
@@ -1309,6 +1349,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inReturnBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trReturns()+": ");
@@ -1323,6 +1364,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inSeeBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trSeeAlso()+": ");
@@ -1346,6 +1388,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inParamBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trParameters()+": ");
@@ -1371,6 +1414,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inRetValBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trReturnValues()+": ");
@@ -1396,6 +1440,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
{
if (inBlock()) endBlock();
inExceptionBlock=TRUE;
+ currentListIndent.push("D");
outDoc->startDescList();
outDoc->startBold();
scanString(theTranslator->trExceptions()+": ");
@@ -1819,7 +1864,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
"Warning in the documentation of this entity:\nMore </ol> tags than <ol> tags in the documentation of this entity."
);
}
- else if (currentListIndent.top()!="O")
+ else if (*currentListIndent.top()!='O')
{
warn(yyFileName,yyLineNr,
"Warning in the documentation of this entity:\nThe </ol> tag does not end a <ol> tag."
@@ -1841,7 +1886,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
"Warning in the documentation of this entity:\nMore </ul> tags than <ul> tags."
);
}
- else if (currentListIndent.top()!="U")
+ else if (*currentListIndent.top()!='U')
{
warn(yyFileName,yyLineNr,
"Warning in the documentation of this entity:\nThe </ul> tag does not end a <ul> tag."
@@ -1855,7 +1900,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
}
<DocScan>"<"{LI}{ATTR}">" {
if (/*currentListIndent.isEmpty() ||*/ //DvH: I removed this check because I use this in the manual (the <ul> is in a \htmlonly block!)
- currentListIndent.top()=="D")
+ !currentListIndent.isEmpty() && *currentListIndent.top()=='D')
{
warn(yyFileName,yyLineNr,
"Warning in the documentation of this entity:\nThe <li> tag can only be used inside a <ul> ... </ul> or a <ol> ... </ol> block."
@@ -1882,7 +1927,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
"Warning in the documentation of this entity:\nMore </dl> tags than <dl> tags in the documentation."
);
}
- else if (currentListIndent.top()!="D")
+ else if (*currentListIndent.top()!='D')
{
warn(yyFileName,yyLineNr,
"Warning in the documentation of this entity:\nThe </dl> tag does not end a <dl> tag in the documentation."
@@ -1896,7 +1941,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
}
<DocScan>"<"{DT}{ATTR}">" {
if (currentListIndent.isEmpty() ||
- currentListIndent.top()!="D")
+ *currentListIndent.top()!='D')
{
warn(yyFileName,yyLineNr,
"Warning in the documentation of this entity:\nThe <dt> tag can only be used inside a <dl> ... </dl> block."
@@ -1910,7 +1955,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
<DocScan>"</"{DT}{ATTR}">"
<DocScan>"<"{DD}{ATTR}">" {
if (currentListIndent.isEmpty() ||
- currentListIndent.top()!="D")
+ *currentListIndent.top()!='D')
{
warn(yyFileName,yyLineNr,
"Warning in the documentation of this entity:\nThe <dd> tag can only be used inside a <dl> ... </dl> block."
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index e01ef56..621039d 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -1174,7 +1174,7 @@ static MemberDef *addVariableToFile(
NamespaceDef *nd = 0;
if (!scope.isEmpty())
{
- QCString nscope=removeAnnonymousScopes(scope);
+ QCString nscope=removeAnonymousScopes(scope);
if (!nscope.isEmpty())
{
nd = getResolvedNamespace(nscope);
@@ -1219,7 +1219,7 @@ static MemberDef *addVariableToFile(
MemberDef *md;
for (mni.toFirst();(md=mni.current());++mni)
{
- QCString nscope=removeAnnonymousScopes(scope);
+ QCString nscope=removeAnonymousScopes(scope);
NamespaceDef *nd=0;
if (!nscope.isEmpty())
{
@@ -1395,6 +1395,8 @@ void buildVarList(Entry *root)
mtype=MemberDef::Typedef;
else if (type.left(7)=="friend ")
mtype=MemberDef::Friend;
+ else if (root->mtype==Property)
+ mtype=MemberDef::Property;
else
mtype=MemberDef::Variable;
@@ -1811,7 +1813,7 @@ static void buildMemberList(Entry *root)
NamespaceDef *nd = 0;
if (root->parent->section == Entry::NAMESPACE_SEC )
{
- QCString nscope=removeAnnonymousScopes(root->parent->name);
+ QCString nscope=removeAnonymousScopes(root->parent->name);
if (!nscope.isEmpty())
{
nd = getResolvedNamespace(nscope);
@@ -3044,7 +3046,7 @@ static void findMember(Entry *root,QCString funcDecl,QCString related,bool overl
//printf("result: scope=%s\n",scopeName.data());
}
- namespaceName=removeAnnonymousScopes(namespaceName);
+ namespaceName=removeAnonymousScopes(namespaceName);
//printf("namespaceName=`%s' className=`%s'\n",namespaceName.data(),className.data());
// merge class and namespace scopes again
scopeName.resize(0);
@@ -4135,9 +4137,8 @@ static void generateFileSources()
for (;(fd=fni.current());++fni)
{
bool src = !fd->isReference() &&
- (Config::verbatimHeaderFlag
- //fd->generateSource()
- || Config::sourceBrowseFlag);
+ fd->name().right(4)!=".doc" && fd->name().right(4)!=".txt" &&
+ (Config::verbatimHeaderFlag || Config::sourceBrowseFlag);
if (src)
{
msg("Generating code for file %s...\n",fd->name().data());
@@ -6044,8 +6045,11 @@ int main(int argc,char **argv)
msg("Generating page index...\n");
writePageIndex(*outputList);
- msg("Generating graph info page...\n");
- writeGraphInfo(*outputList);
+ if (Config::generateLegend)
+ {
+ msg("Generating graph info page...\n");
+ writeGraphInfo(*outputList);
+ }
msg("Generating search index...\n");
generateSearchIndex();
diff --git a/src/doxygen.dtd b/src/doxygen.dtd
index a479ee5..62727b8 100644
--- a/src/doxygen.dtd
+++ b/src/doxygen.dtd
@@ -1,4 +1,4 @@
-<?xml encoding="ISO-8859-1"?>
+<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- DTD describing the grammar used in doxygen's XML output -->
<!-- standard character entities -->
@@ -50,6 +50,8 @@
|friend
|related
|define|prototype|typedef|enum|func|var
+ |dcop-func
+ |property
) #REQUIRED
'
>
diff --git a/src/doxygen.pro.in b/src/doxygen.pro.in
index 30312b7..66d57a0 100644
--- a/src/doxygen.pro.in
+++ b/src/doxygen.pro.in
@@ -15,7 +15,7 @@
# TMake project file for doxygen
TEMPLATE = doxygen.t
-CONFIG = console qt warn_on $extraopts
+CONFIG = console warn_on $extraopts
HEADERS = doxygen.h scanner.h doc.h classdef.h classlist.h memberdef.h \
membername.h index.h memberlist.h definition.h \
entry.h logos.h instdox.h message.h code.h \
@@ -27,7 +27,7 @@ HEADERS = doxygen.h scanner.h doc.h classdef.h classlist.h memberdef.h \
translator_it.h formula.h debug.h membergroup.h htmlhelp.h \
translator_ru.h translator_pl.h dot.h rtfgen.h xml.h xml_dtd.h \
reflist.h page.h sortdict.h translator_hu.h translator_kr.h \
- translator_ro.h translator_si.h
+ translator_ro.h translator_si.h translator_cn.h
SOURCES = doxygen.cpp scanner.cpp doc.cpp classdef.cpp classlist.cpp \
memberdef.cpp membername.cpp index.cpp memberlist.cpp \
entry.cpp logos.cpp instdox.cpp message.cpp code.cpp \
@@ -39,7 +39,11 @@ SOURCES = doxygen.cpp scanner.cpp doc.cpp classdef.cpp classlist.cpp \
version.cpp language.cpp definition.cpp formula.cpp debug.cpp \
membergroup.cpp htmlhelp.cpp dot.cpp rtfgen.cpp xml.cpp \
reflist.cpp
+unix:LIBS += -L../qtools -lqtools
win32:INCLUDEPATH += .
-win32:LIBS += shell32.lib
+win32:LIBS += qtools.lib shell32.lib
+win32:TMAKE_LFLAGS += /LIBPATH:..\qtools
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+INCLUDEPATH += ../qtools
TARGET = ../bin/doxygen
OBJECTS_DIR = ../objects
diff --git a/src/doxytag.pro.in b/src/doxytag.pro.in
index 1032443..d91378d 100644
--- a/src/doxytag.pro.in
+++ b/src/doxytag.pro.in
@@ -15,11 +15,15 @@
# TMake project file for doxytag
TEMPLATE = doxytag.t
-CONFIG = console warn_on qt $extraopts
+CONFIG = console warn_on $extraopts
HEADERS = suffixtree.h searchindex.h logos.h version.h
SOURCES = doxytag.cpp suffixtree.cpp searchindex.cpp \
logos.cpp version.cpp
-TARGET = ../bin/doxytag
-win32:INCLUDEPATH += .
-#unix:INCLUDEPATH += /usr/include
+unix:LIBS += -L../qtools -lqtools
+win32:INCLUDEPATH += .
+win32:LIBS += qtools.lib
+win32:TMAKE_LFLAGS += /LIBPATH:..\qtools
+win32:TMAKE_CXXFLAGS += -DQT_NODLL
+INCLUDEPATH += ../qtools
OBJECTS_DIR = ../objects
+TARGET = ../bin/doxytag
diff --git a/src/entry.h b/src/entry.h
index 27035e2..c836d87 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -23,7 +23,7 @@
enum Protection { Public, Protected, Private } ;
enum Specifier { Normal, Virtual, Pure } ;
-enum MethodTypes { Method, Signal, Slot, DCOP };
+enum MethodTypes { Method, Signal, Slot, DCOP, Property };
struct BaseInfo
{
@@ -162,7 +162,7 @@ class Entry
int section; // entry type (see Sections);
Protection protection; // class protection
- MethodTypes mtype; // signal, slot or dcop method?
+ MethodTypes mtype; // signal, slot, (dcop) method, or property?
bool stat; // static ?
bool explicitExternal; // explicitly defined as external?
bool proto; // prototype ?
diff --git a/src/filedef.cpp b/src/filedef.cpp
index 3d20233..6ce4c86 100644
--- a/src/filedef.cpp
+++ b/src/filedef.cpp
@@ -220,6 +220,7 @@ void FileDef::writeDocumentation(OutputList &ol)
//incDepGraph.writeGraph(Config::htmlOutputDir,fd->getOutputFileBase());
}
+ //printf("%s: generateSourceFile()=%d\n",name().data(),generateSourceFile());
if (generateSourceFile())
{
ol.disableAllBut(OutputGenerator::Html);
diff --git a/src/groupdef.cpp b/src/groupdef.cpp
index eb0611f..5476dc1 100644
--- a/src/groupdef.cpp
+++ b/src/groupdef.cpp
@@ -285,7 +285,7 @@ void GroupDef::writeDocumentation(OutputList &ol)
while (nd)
{
ol.startMemberItem(0);
- ol.docify("namespace");
+ ol.docify("namespace ");
ol.insertMemberAlign();
ol.writeObjectLink(nd->getReference(),nd->getOutputFileBase(),0,nd->name());
ol.endMemberItem(FALSE);
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 40eed09..1b93b5a 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -89,7 +89,7 @@ void HtmlGenerator::init()
exit(1);
}
writeLogo(Config::htmlOutputDir);
- writeNullImage(Config::htmlOutputDir);
+ //writeNullImage(Config::htmlOutputDir);
}
void HtmlGenerator::writeStyleSheetFile(QFile &file)
diff --git a/src/index.cpp b/src/index.cpp
index 9bd0e37..f470341 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -320,6 +320,7 @@ void writeGraphicalClassHierarchy(OutputList &ol)
//----------------------------------------------------------------------------
+
void countFiles(int &htmlFiles,int &files)
{
htmlFiles=0;
@@ -334,13 +335,18 @@ void countFiles(int &htmlFiles,int &files)
{
bool doc = fd->isLinkableInProject();
bool src = fd->generateSourceFile();
- if (doc || src)
- {
- htmlFiles++;
- }
- if (doc)
+ bool nameOk = fd->name().right(4)!=".doc" &&
+ fd->name().right(4)!=".txt";
+ if (nameOk)
{
- files++;
+ if (doc || src)
+ {
+ htmlFiles++;
+ }
+ if (doc)
+ {
+ files++;
+ }
}
}
}
@@ -416,7 +422,10 @@ void writeFileIndex(OutputList &ol)
//printf("Found filedef %s\n",fd->name().data());
bool doc = fd->isLinkableInProject();
bool src = fd->generateSourceFile();
- if ((doc || src) && !fd->isReference())
+ bool nameOk = fd->name().right(4)!=".doc" &&
+ fd->name().right(4)!=".txt";
+ if (nameOk && (doc || src) &&
+ !fd->isReference())
{
QCString path;
if (Config::fullPathNameFlag)
@@ -1223,11 +1232,6 @@ void writeNamespaceMemberList(OutputList &ol,bool useSections)
first=FALSE;
}
}
- else if (first)
- {
- first=FALSE;
- ol.startItemList();
- }
ol.writeListItem();
ol.docify(md->name());
if (md->isFunction()) ol.docify("()");
diff --git a/src/language.cpp b/src/language.cpp
index 4fca8c7..e7a9576 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -35,6 +35,7 @@
#include "translator_kr.h"
#include "translator_ro.h"
#include "translator_si.h"
+#include "translator_cn.h"
#endif
#define L_EQUAL(a) !stricmp(langName,a)
@@ -120,6 +121,10 @@ bool setTranslator(const char *langName)
{
theTranslator=new TranslatorSlovene;
}
+ else if (L_EQUAL("chinese"))
+ {
+ theTranslator=new TranslatorChinese;
+ }
#endif
else // use the default language (i.e. english)
{
diff --git a/src/logos.cpp b/src/logos.cpp
index f598435..92bc08e 100644
--- a/src/logos.cpp
+++ b/src/logos.cpp
@@ -22,13 +22,13 @@
#include <qdir.h>
-unsigned char null_data[] = {
- 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0x80, 0xff,
- 0x00, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
- 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3b
-};
-unsigned int null_len = 43;
+//unsigned char null_data[] = {
+// 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0x80, 0xff,
+// 0x00, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x00,
+// 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
+// 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3b
+//};
+//unsigned int null_len = 43;
unsigned char logo_data[] = {
0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x6e, 0x00, 0x35, 0x00, 0xe7, 0x00,
@@ -3139,18 +3139,18 @@ unsigned char doxfont_data[] = {
};
unsigned int doxfont_len = 32760;
-void writeNullImage(const char *dir)
-{
- QCString fileName=(QCString)dir+"/null.gif";
- QFile f(fileName);
- if (f.open(IO_WriteOnly))
- f.writeBlock((char *)null_data,null_len);
- else
- {
- fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data());
- }
- f.close();
-}
+//void writeNullImage(const char *dir)
+//{
+// QCString fileName=(QCString)dir+"/null.gif";
+// QFile f(fileName);
+// if (f.open(IO_WriteOnly))
+// f.writeBlock((char *)null_data,null_len);
+// else
+// {
+// fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data());
+// }
+// f.close();
+//}
void writeLogo(const char *dir)
{
diff --git a/src/logos.h b/src/logos.h
index 5dbdf22..d8f84a5 100644
--- a/src/logos.h
+++ b/src/logos.h
@@ -19,7 +19,7 @@
#define LOGOS_H
extern void writeLogo(const char *dir);
-extern void writeNullImage(const char *dir);
+//extern void writeNullImage(const char *dir);
extern void writeSearchButton(const char *dir);
extern void writeDoxFont(const char *dir);
extern void removeDoxFont(const char *dir);
diff --git a/src/mangen.cpp b/src/mangen.cpp
index cd5718c..852a0f4 100644
--- a/src/mangen.cpp
+++ b/src/mangen.cpp
@@ -73,10 +73,29 @@ void ManGenerator::init()
void ManGenerator::startFile(const char *name,const char *,bool)
{
QCString fileName=name;
+
+ // TODO: do something sensible here.
if (fileName.left(6)=="class_")
{
fileName=fileName.right(fileName.length()-6);
}
+ else if (fileName.left(10)=="interface_")
+ {
+ fileName=fileName.right(fileName.length()-10);
+ }
+ else if (fileName.left(7)=="struct_")
+ {
+ fileName=fileName.right(fileName.length()-7);
+ }
+ else if (fileName.left(6)=="union_")
+ {
+ fileName=fileName.right(fileName.length()-6);
+ }
+ else if (fileName.left(10)=="exception_")
+ {
+ fileName=fileName.right(fileName.length()-10);
+ }
+
int i;
if ((i=fileName.findRev('.'))!=-1)
{
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index f9a8ff9..1c2e940 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -1411,6 +1411,7 @@ void MemberDef::generateXML(QTextStream &t,Definition *def)
{
case Define: t << "definedef"; xmlType=define_t; break;
case EnumValue: // fall through
+ case Property: // fall through
case Variable: t << "variabledef"; xmlType=variable_t; break;
case Typedef: t << "typedef"; xmlType=typedef_t; break;
case Enumeration: t << "enumdef"; xmlType=enum_t; break;
@@ -1423,7 +1424,8 @@ void MemberDef::generateXML(QTextStream &t,Definition *def)
}
t << " id=\"";
t << def->getOutputFileBase()
- << ":"
+ << "__" // can we change this to a non ID char?
+ // : do not seem allowed for some parsers!
<< anchor();
t << "\"";
if (xmlType==function_t && virtualness()!=Normal)
@@ -1444,15 +1446,13 @@ void MemberDef::generateXML(QTextStream &t,Definition *def)
(xmlType!=function_t || !type.isEmpty()) // Type is optional here.
)
{
+ QCString typeStr = replaceAnonymousScopes(type);
+ if (xmlType==typedef_t && typeStr.left(8)=="typedef ")
+ typeStr=typeStr.right(typeStr.length()-8);
+ if (xmlType==function_t && typeStr.left(8)=="virtual ")
+ typeStr=typeStr.right(typeStr.length()-8);
t << " <type>";
- if (xmlType==typedef_t && type.left(8)=="typedef ")
- linkifyText(TextGeneratorXMLImpl(t),scopeName,name(),
- type.right(type.length()-8)); // strip "typedef "
- else if (xmlType==function_t && type.left(8)=="virtual ")
- linkifyText(TextGeneratorXMLImpl(t),scopeName,name(),
- type.right(type.length()-8)); // strip "virtual "
- else
- linkifyText(TextGeneratorXMLImpl(t),scopeName,name(),type);
+ linkifyText(TextGeneratorXMLImpl(t),scopeName,name(),typeStr);
t << "</type>" << endl;
}
@@ -1560,6 +1560,7 @@ void MemberDef::generateXML(QTextStream &t,Definition *def)
{
case Define: t << "definedef"; break;
case EnumValue: // fall through
+ case Property: // fall through
case Variable: t << "variabledef"; break;
case Typedef: t << "typedef"; break;
case Enumeration: t << "enumdef"; break;
diff --git a/src/memberdef.h b/src/memberdef.h
index a0c655e..bee7ca4 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -58,7 +58,8 @@ class MemberDef : public Definition
Signal,
Slot,
Friend,
- DCOP
+ DCOP,
+ Property
};
enum
@@ -111,6 +112,7 @@ class MemberDef : public Definition
bool isDefine() const { return mtype==Define; }
bool isFriend() const { return mtype==Friend; }
bool isDCOP() const { return mtype==DCOP; }
+ bool isProperty() const { return mtype==Property; }
bool isRelated() const { return related; }
bool isStatic() const { return stat; }
bool isInline() const { return (memSpec&Entry::Inline)!=0; }
@@ -132,8 +134,8 @@ class MemberDef : public Definition
void setMemberSpecifiers(int s) { memSpec=s; }
void mergeMemberSpecifiers(int s) { memSpec|=s; }
void setInitializer(const char *i) { init=i;
- init=init.stripWhiteSpace();
- initLines=init.contains('\n');
+ init=init.stripWhiteSpace();
+ initLines=init.contains('\n');
}
void setBitfields(const char *s) { bitfields = s; }
void setMaxInitLines(int lines) { if (lines!=-1) maxInitLines=lines; }
diff --git a/src/memberlist.cpp b/src/memberlist.cpp
index 60a4e90..3e7b7a0 100644
--- a/src/memberlist.cpp
+++ b/src/memberlist.cpp
@@ -70,7 +70,9 @@ void MemberList::countDecMembers(bool inGroup,bool countSubGroups,bool sectionPe
{
switch(md->memberType())
{
- case MemberDef::Variable: varCnt++,m_count++; break;
+ case MemberDef::Variable: // fall through
+ case MemberDef::Property: varCnt++,m_count++;
+ break;
case MemberDef::Function: // fall through
case MemberDef::Signal: // fall through
case MemberDef::DCOP: // fall through
@@ -346,13 +348,13 @@ void MemberList::writePlainDeclarations(OutputList &ol,
typeDecl.enable(OutputGenerator::Man);
enumMemCount++;
}
- }
- if (fmdl->count()>MAX_ENUM_VALUES_FOR_ONE_LINE)
- {
- typeDecl.pushGeneratorState();
- typeDecl.disableAllBut(OutputGenerator::Html);
- typeDecl.lineBreak();
- typeDecl.popGeneratorState();
+ if (fmdl->count()>MAX_ENUM_VALUES_FOR_ONE_LINE)
+ {
+ typeDecl.pushGeneratorState();
+ typeDecl.disableAllBut(OutputGenerator::Html);
+ typeDecl.lineBreak();
+ typeDecl.popGeneratorState();
+ }
}
typeDecl.docify(" }");
md->setEnumDecl(typeDecl);
@@ -496,7 +498,8 @@ void MemberList::writePlainDeclarations(OutputList &ol,
MemberListIterator mli(*this);
for ( ; (md=mli.current()) ; ++mli )
{
- if (md->isVariable() && inGroup==md->visibleMemberGroup(sectionPerType))
+ if ((md->isVariable() || md->isProperty()) &&
+ inGroup==md->visibleMemberGroup(sectionPerType))
{
md->writeDeclaration(ol,cd,nd,fd,gd,inGroup);
}
diff --git a/src/message.cpp b/src/message.cpp
index 9554c02..112d5af 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -28,6 +28,8 @@ static int warnFormatOrder; // 1 = $file,$line,$text
// 5 = $text,$file,$line
// 6 = $line,$file,$text
+static FILE *warnFile = stderr;
+
void initWarningFormat()
{
int filePos = Config::warnFormat.find("$file");
@@ -78,6 +80,11 @@ void initWarningFormat()
// replace(QRegExp("\\$text"),"%s").
// replace(QRegExp("\\$line"),"%d")+
// '\n';
+
+ if (!Config::warnLogFile.isEmpty())
+ {
+ warnFile = fopen(Config::warnLogFile,"w");
+ }
}
@@ -104,12 +111,12 @@ void warn(const char *file,int line,const char *fmt, ...)
va_end(args);
switch(warnFormatOrder)
{
- case 1: fprintf(stderr,outputFormat,file,line,text); break;
- case 2: fprintf(stderr,outputFormat,text,line,file); break;
- case 3: fprintf(stderr,outputFormat,line,text,file); break;
- case 4: fprintf(stderr,outputFormat,file,text,line); break;
- case 5: fprintf(stderr,outputFormat,text,file,line); break;
- case 6: fprintf(stderr,outputFormat,line,file,text); break;
+ case 1: fprintf(warnFile,outputFormat,file,line,text); break;
+ case 2: fprintf(warnFile,outputFormat,text,line,file); break;
+ case 3: fprintf(warnFile,outputFormat,line,text,file); break;
+ case 4: fprintf(warnFile,outputFormat,file,text,line); break;
+ case 5: fprintf(warnFile,outputFormat,text,file,line); break;
+ case 6: fprintf(warnFile,outputFormat,line,file,text); break;
default:
printf("Error: warning format has not been initialized!\n");
}
@@ -122,7 +129,7 @@ void warn_cont(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
- vfprintf(stderr, fmt, args);
+ vfprintf(warnFile, fmt, args);
va_end(args);
}
}
@@ -139,12 +146,12 @@ void warn_undoc(const char *file,int line,const char *fmt, ...)
va_end(args);
switch(warnFormatOrder)
{
- case 1: fprintf(stderr,outputFormat,file,line,text); break;
- case 2: fprintf(stderr,outputFormat,text,line,file); break;
- case 3: fprintf(stderr,outputFormat,line,text,file); break;
- case 4: fprintf(stderr,outputFormat,file,text,line); break;
- case 5: fprintf(stderr,outputFormat,text,file,line); break;
- case 6: fprintf(stderr,outputFormat,line,file,text); break;
+ case 1: fprintf(warnFile,outputFormat,file,line,text); break;
+ case 2: fprintf(warnFile,outputFormat,text,line,file); break;
+ case 3: fprintf(warnFile,outputFormat,line,text,file); break;
+ case 4: fprintf(warnFile,outputFormat,file,text,line); break;
+ case 5: fprintf(warnFile,outputFormat,text,file,line); break;
+ case 6: fprintf(warnFile,outputFormat,line,file,text); break;
default:
printf("Error: warning format has not been initialized!\n");
}
@@ -155,6 +162,6 @@ void err(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
- vfprintf(stderr, fmt, args);
+ vfprintf(warnFile, fmt, args);
va_end(args);
}
diff --git a/src/message.h b/src/message.h
index 87022f6..df2bc94 100644
--- a/src/message.h
+++ b/src/message.h
@@ -18,6 +18,8 @@
#ifndef MESSAGE_H
#define MESSAGE_H
+#include <stdio.h>
+
extern void msg(const char *fmt, ...);
extern void warn(const char *file,int line,const char *fmt, ...);
extern void warn_cont(const char *fmt, ...);
diff --git a/src/scanner.l b/src/scanner.l
index c63de52..a12189b 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -519,6 +519,16 @@ TITLE [tT][iI][tT][lL][eE]
unput(*yytext);
BEGIN( FindMembers );
}
+<FindMembers>{B}*("properties"|"__property"){BN}*":"{BN}* { // IDL or Borland C++ builder property
+ current->mtype = mtype = Property;
+ current->protection = protection = Public ;
+ current->type.resize(0);
+ current->name.resize(0);
+ current->args.resize(0);
+ current->argList->clear();
+ lineCount() ;
+ }
+
<FindMembers>{B}*"k_dcop"{BN}*":"{BN}* { current->mtype = mtype = DCOP;
current->protection = protection = Public ;
current->type.resize(0);
@@ -566,9 +576,7 @@ TITLE [tT][iI][tT][lL][eE]
current->argList->clear();
lineCount();
}
-<FindMembers>{B}*"properties"{B}":" { /* M$-IDL only: ignored */ }
-<FindMembers>{B}*"methods"{B}":" { /* M$-IDL only: ignored */ }
-<FindMembers>{B}*"public"{BN}*":"{BN}* {
+<FindMembers>{B}*("public"|"methods"|"__published"){BN}*":"{BN}* {
current->protection = protection = Public ;
current->mtype = mtype = Method;
current->type.resize(0);
diff --git a/src/translator.h b/src/translator.h
index 5808ae1..4849c95 100644
--- a/src/translator.h
+++ b/src/translator.h
@@ -566,7 +566,9 @@ class Translator
virtual QCString trGeneratedBy()
{ return "Generated by"; }
- // new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
/*! used as the title of page containing all the index of all namespaces. */
virtual QCString trNamespaceList()
@@ -607,7 +609,6 @@ class Translator
bool isTemplate)
{
QCString result=(QCString)clName+" ";
- if (isTemplate) result+=" Template";
switch(compType)
{
case ClassDef::Class: result+=" Class"; break;
@@ -616,6 +617,7 @@ class Translator
case ClassDef::Interface: result+=" Interface"; break;
case ClassDef::Exception: result+=" Exception"; break;
}
+ if (isTemplate) result+=" Template";
result+=" Reference";
return result;
}
@@ -1086,6 +1088,20 @@ class Translator
return "DCOP Methods";
}
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Properties";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Property Documentation";
+ }
};
#endif
diff --git a/src/translator_cn.h b/src/translator_cn.h
new file mode 100644
index 0000000..9343695
--- /dev/null
+++ b/src/translator_cn.h
@@ -0,0 +1,707 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2000 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef TRANSLATOR_CN_H
+#define TRANSLATOR_CN_H
+
+#include "translator.h"
+
+/*!
+ If you want insert a space whenever Chinese meets English charactors, set
+ CN_SPC to " ", else null.
+*/
+#define CN_SPC
+
+class TranslatorChinese : public Translator
+{
+ public:
+ QCString idLanguage()
+ { return "chinese"; }
+ QCString idLanguageCharset()
+ { return "gb2312"; }
+ QCString latexBabelPackage()
+ { return "chinese"; }
+ QCString trRelatedFunctions()
+ { return "Ïà¹Øº¯Êý"; }
+ QCString trRelatedSubscript()
+ { return "£¨×¢Ò⣺ÕâЩ²»ÊdzÉÔ±º¯Êý£©"; }
+ QCString trDetailedDescription()
+ { return "ÏêϤÃèÊö"; }
+ QCString trMemberTypedefDocumentation()
+ { return "³ÉÔ±ÀàÐͶ¨ÒåÎĵµ"; }
+ QCString trMemberEnumerationDocumentation()
+ { return "³ÉԱö¾ÙÀàÐÍÎĵµ"; }
+ QCString trEnumerationValueDocumentation()
+ { return "³ÉԱö¾ÙÖµÎĵµ"; }
+ QCString trMemberFunctionDocumentation()
+ { return "³ÉÔ±º¯ÊýÎĵµ"; }
+ QCString trMemberDataDocumentation()
+ { return "³ÉÔ±Êý¾ÝÎĵµ"; }
+ QCString trMore()
+ { return "¸ü¶à..."; }
+ QCString trListOfAllMembers()
+ { return "ËùÓгÉÔ±µÄÁÐ±í¡£"; }
+ QCString trMemberList()
+ { return "³ÉÔ±Áбí"; }
+ QCString trThisIsTheListOfAllMembers()
+ { return "³ÉÔ±µÄÍêÕûÁÐ±í£¬ÕâЩ³ÉÔ±ÊôÓÚ"CN_SPC; }
+ QCString trIncludingInheritedMembers()
+ { return "£¬°üÀ¨ËùÓм̳жøÀ´µÄ³ÉÔ±"; }
+ QCString trGeneratedAutomatically(const char *s)
+ { QCString result;
+ if (s) result=(QCString)"Ϊ"CN_SPC+s+"£¬";
+ result+="ÓÉ"CN_SPC"Doyxgen"CN_SPC"ͨ¹ý·ÖÎöÔ´´úÂë×Ô¶¯Éú³É¡£";
+ return result;
+ }
+ QCString trEnumName()
+ { return "ö¾ÙÃû³Æ"; }
+ QCString trEnumValue()
+ { return "ö¾ÙÖµ"; }
+ QCString trDefinedIn()
+ { return "¶¨ÒåÓÚ"CN_SPC; }
+ QCString trVerbatimText(const char *f)
+ { return (QCString)"ÕâÊÇÍ·Îļþ"CN_SPC+f+CN_SPC"µÄÔ´´úÂë¡£"; }
+ QCString trModules()
+ { return "Ä£¿é"; }
+ QCString trClassHierarchy()
+ { return "Àà¼Ì³Ð¹Øϵ"; }
+ QCString trCompoundList()
+ { return "×éºÏÀàÐÍÁбí"; }
+ QCString trFileList()
+ { return "ÎļþÁбí"; }
+ QCString trHeaderFiles()
+ { return "Í·Îļþ"; }
+ QCString trCompoundMembers()
+ { return "×éºÏÀàÐͳÉÔ±"; }
+ QCString trFileMembers()
+ { return "Îļþ³ÉÔ±"; }
+ QCString trRelatedPages()
+ { return "Ïà¹ØÒ³Ãæ"; }
+ QCString trExamples()
+ { return "ʾÀý"; }
+ QCString trSearch()
+ { return "ËÑË÷"; }
+ QCString trClassHierarchyDescription()
+ { return "´ËÁбí»ù±¾°´×Öµä˳ÐòÅÅÐò£º"; }
+ QCString trFileListDescription(bool extractAll)
+ {
+ QCString result="ÕâÀïÁгöËùÓÐ";
+ if (!extractAll) result+="Îĵµ»¯µÄ";
+ result+="Îļþ£¬¸½´ø¼òҪ˵Ã÷£º";
+ return result;
+ }
+ QCString trCompoundListDescription()
+ { return "ÕâÀïÁгöËùÓÐÀà¡¢½á¹¹¡¢ÁªºÏÒÔ¼°½Ó¿Ú¶¨Ò壬¸½´ø¼òҪ˵Ã÷£º";
+ }
+ QCString trCompoundMembersDescription(bool extractAll)
+ {
+ QCString result="ÕâÀïÁгöËùÓÐ";
+ if (!extractAll) result+="Îĵµ»¯µÄ";
+ result+="Àà³ÉÔ±£¬¸½´ø";
+ if (extractAll) result+="ËùÔÚÀàµÄÎĵµµÄÁ´½Ó£º";
+ else result+="ËùÔÚÀàµÄÁ´½Ó£º";
+ return result;
+ }
+ QCString trFileMembersDescription(bool extractAll)
+ {
+ QCString result="ÕâÀïÁгöËùÓÐ";
+ if (!extractAll) result+="Îĵµ»¯µÄ";
+ result+="Îļþ³ÉÔ±£¬¸½´ø";
+ if (extractAll) result+="ËùÔÚÎļþµÄÎĵµµÄÁ´½Ó£º";
+ else result+="ËùÔÚÎļþµÄÁ´½Ó£º";
+ return result;
+ }
+ QCString trHeaderFilesDescription()
+ { return "ÕâÀïÁгö×é³ÉAPIµÄÍ·Îļþ£º"; }
+ QCString trExamplesDescription()
+ { return "ÕâÀïÁгöËùÓÐʾÀý£º"; }
+ QCString trRelatedPagesDescription()
+ { return "ÕâÀïÁгöËùÓÐÏà¹ØµÄÒ³Ã棺"; }
+ QCString trModulesDescription()
+ { return "ÕâÀïÁгöËùÓÐÄ£¿é"; }
+ QCString trNoDescriptionAvailable()
+ { return "ÎÞ¿ÉÓÃÎĵµ"; }
+
+ QCString trDocumentation()
+ { return "Îĵµ"; }
+ QCString trModuleIndex()
+ { return "Ä£¿éË÷Òý"; }
+ QCString trHierarchicalIndex()
+ { return "¼Ì³Ð¹ØϵË÷Òý"; }
+ QCString trCompoundIndex()
+ { return "×éºÏÀàÐÍË÷Òý"; }
+ QCString trFileIndex()
+ { return "ÎļþË÷Òý"; }
+ QCString trModuleDocumentation()
+ { return "Ä£¿éÎĵµ"; }
+ QCString trClassDocumentation()
+ { return "ÀàÎĵµ"; }
+ QCString trFileDocumentation()
+ { return "ÎļþÎĵµ"; }
+ QCString trExampleDocumentation()
+ { return "ʾÀýÎĵµ"; }
+ QCString trPageDocumentation()
+ { return "Ò³ÃæÎĵµ"; }
+ QCString trReferenceManual()
+ { return "²Î¿¼ÊÖ²á"; }
+
+ QCString trDefines()
+ { return "ºê¶¨Òå"; }
+ QCString trFuncProtos()
+ { return "º¯ÊýÔ­ÐÍ"; }
+ QCString trTypedefs()
+ { return "ÀàÐͶ¨Òå"; }
+ QCString trEnumerations()
+ { return "ö¾Ù"; }
+ QCString trFunctions()
+ { return "º¯Êý"; }
+ QCString trVariables()
+ { return "±äÁ¿"; }
+ QCString trEnumerationValues()
+ { return "ö¾ÙÖµ"; }
+ QCString trAuthor()
+ { return "×÷Õß"; }
+ QCString trDefineDocumentation()
+ { return "ºê¶¨ÒåÎĵµ"; }
+ QCString trFunctionPrototypeDocumentation()
+ { return "º¯ÊýÔ­ÐÍÎĵµ"; }
+ QCString trTypedefDocumentation()
+ { return "ÀàÐͶ¨ÒåÎĵµ"; }
+ QCString trEnumerationTypeDocumentation()
+ { return "ö¾ÙÀàÐÍÎĵµ"; }
+ QCString trFunctionDocumentation()
+ { return "º¯ÊýÎĵµ"; }
+ QCString trVariableDocumentation()
+ { return "±äÁ¿Îĵµ"; }
+ QCString trCompounds()
+ { return "×éºÏÀàÐÍ"; }
+ QCString trFiles()
+ { return "Îļþ"; }
+ QCString trGeneratedAt(const char *date,const char *projName)
+ {
+ QCString result=(QCString)"Generated at "+date;
+ if (projName) result+=(QCString)" for "+projName;
+ result+=(QCString)" by";
+ return result;
+ }
+ QCString trWrittenBy()
+ {
+ return "written by";
+ }
+ QCString trClassDiagram(const char *clName)
+ {
+ return (QCString)"¼Ì³Ðͼ£¬Àà"CN_SPC+clName;
+ }
+ QCString trForInternalUseOnly()
+ { return "½öÏÞÄÚ²¿Ê¹Óá£"; }
+ QCString trReimplementedForInternalReasons()
+ { return "ÓÉÓÚÄÚ²¿Ô­Òò±»ÖØÔØ£»µ«²»Ó°ÏìAPI";
+ }
+ QCString trWarning()
+ { return "¾¯¸æ"; }
+ QCString trBugsAndLimitations()
+ { return "BUG"CN_SPC"Óë¾ÖÏÞ"; }
+ QCString trVersion()
+ { return "°æ±¾"; }
+ QCString trDate()
+ { return "ÈÕÆÚ"; }
+ QCString trAuthors()
+ { return "×÷Õß"; }
+ QCString trReturns()
+ { return "·µ»Ø"; }
+ QCString trSeeAlso()
+ { return "²Î¼û"; }
+ QCString trParameters()
+ { return "²ÎÊý"; }
+ QCString trExceptions()
+ { return "Òì³£"; }
+ QCString trGeneratedBy()
+ { return "ÖÆ×÷Õß"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990307
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trNamespaceList()
+ { return "ÃüÃû¿Õ¼äÁбí"; }
+ QCString trNamespaceListDescription(bool extractAll)
+ {
+ QCString result="ÕâÀïÁгöËùÓÐ";
+ if (!extractAll) result+="Îĵµ»¯µÄ";
+ result+="ÃüÃû¿Õ¼ä¶¨Ò壬¸½´ø¼òҪ˵Ã÷£º";
+ return result;
+ }
+ QCString trFriends()
+ { return "ÓÑÔª"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990405
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trRelatedFunctionDocumentation()
+ { return "ÓÑÔª¼°Ïà¹Øº¯ÊýÎĵµ"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990425
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trCompoundReference(const char *clName,
+ ClassDef::CompoundType compType,
+ bool isTemplate)
+ // used as the title of the HTML page of a class/struct/union
+ {
+ QCString result=(QCString)clName;
+ if (isTemplate) result+=CN_SPC"Ä£°å";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="Àà"; break;
+ case ClassDef::Struct: result+="½á¹¹"; break;
+ case ClassDef::Union: result+="ÁªºÏ"; break;
+ case ClassDef::Interface: result+="½Ó¿Ú"; break;
+ case ClassDef::Exception: result+="Òì³£"; break;
+ }
+ result+="²Î¿¼";
+ return result;
+ }
+ QCString trFileReference(const char *fileName)
+ // used as the title of the HTML page of a file
+ {
+ QCString result=fileName;
+ result+=CN_SPC"Îļþ²Î¿¼";
+ return result;
+ }
+ QCString trNamespaceReference(const char *namespaceName)
+ // used as the title of the HTML page of a namespace
+ {
+ QCString result=namespaceName;
+ result+=CN_SPC"ÃüÃû¿Õ¼ä²Î¿¼";
+ return result;
+ }
+
+ // these are for the member sections of a class, struct or union
+ QCString trPublicMembers()
+ { return "¹«ÓгÉÔ±"; }
+ QCString trPublicSlots()
+ { return "¹«ÓвÛ"; }
+ QCString trSignals()
+ { return "ÐźÅ"; }
+ QCString trStaticPublicMembers()
+ { return "¾²Ì¬¹«ÓгÉÔ±"; }
+ QCString trProtectedMembers()
+ { return "±£»¤³ÉÔ±"; }
+ QCString trProtectedSlots()
+ { return "±£»¤²Û"; }
+ QCString trStaticProtectedMembers()
+ { return "¾²Ì¬±£»¤³ÉÔ±"; }
+ QCString trPrivateMembers()
+ { return "˽ÓгÉÔ±"; }
+ QCString trPrivateSlots()
+ { return "˽ÓвÛ"; }
+ QCString trStaticPrivateMembers()
+ { return "¾²Ì¬Ë½ÓгÉÔ±"; }
+ // end of member sections
+
+ QCString trWriteList(int numEntries)
+ {
+ // this function is used to produce a comma-separated list of items.
+ // use generateMarker(i) to indicate where item i should be put.
+ QCString result;
+ int i;
+ // the inherits list contain `numEntries' classes
+ for (i=0;i<numEntries;i++)
+ {
+ // use generateMarker to generate placeholders for the class links!
+ result+=generateMarker(i); // generate marker for entry i in the list
+ // (order is left to right)
+
+ if (i!=numEntries-1) // not the last entry, so we need a separator
+ {
+ if (i<numEntries-2) // not the fore last entry
+ result+="¡¢";
+ else // the fore last entry
+ result+=CN_SPC"¼°"CN_SPC;
+ }
+ }
+ return result;
+ }
+
+ QCString trInheritsList(int numEntries)
+ // used in class documentation to produce a list of base classes,
+ // if class diagrams are disabled.
+ {
+ return "¼Ì³Ð×Ô"CN_SPC+trWriteList(numEntries)+"¡£";
+ }
+ QCString trInheritedByList(int numEntries)
+ // used in class documentation to produce a list of super classes,
+ // if class diagrams are disabled.
+ {
+ return "±»"CN_SPC+trWriteList(numEntries)+CN_SPC"¼Ì³Ð.";
+ }
+ QCString trReimplementedFromList(int numEntries)
+ // used in member documentation blocks to produce a list of
+ // members that are hidden by this one.
+ {
+ return "ÖØÔØ"CN_SPC+trWriteList(numEntries)+"¡£";
+ }
+ QCString trReimplementedInList(int numEntries)
+ {
+ // used in member documentation blocks to produce a list of
+ // all member that overwrite the implementation of this member.
+ return "±»"CN_SPC+trWriteList(numEntries)+CN_SPC"ÖØÔØ¡£";
+ }
+
+ QCString trNamespaceMembers()
+ // This is put above each page as a link to all members of namespaces.
+ { return "ÃüÃû¿Õ¼ä³ÉÔ±"; }
+ QCString trNamespaceMemberDescription(bool extractAll)
+ // This is an introduction to the page with all namespace members
+ {
+ QCString result="ÕâÀïÁгöÁËËùÓÐ";
+ if (!extractAll) result+="Îĵµ»¯µÄ";
+ result+="ÃüÃû¿Õ¼ä³ÉÔ±£¬¸½´ø";
+ if (extractAll)
+ result+="ËùÔÚÀàµÄÎĵµµÄÁ´½Ó£º";
+ else
+ result+="ËùÔÚÀàµÄÁ´½Ó£º";
+ return result;
+ }
+ QCString trNamespaceIndex()
+ // This is used in LaTeX as the title of the chapter with the
+ // index of all namespaces.
+ { return "ÃüÃû¿Õ¼äË÷Òý"; }
+ QCString trNamespaceDocumentation()
+ // This is used in LaTeX as the title of the chapter containing
+ // the documentation of all namespaces.
+ { return "ÃüÃû¿Õ¼äÎĵµ"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990728
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is put at the bottom of a class documentation page and is
+ * followed by a list of files that were used to generate the page.
+ */
+ QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
+ bool)
+ { // here s is one of " Class", " Struct" or " Union"
+ // single is true implies a single file
+ QCString result=(QCString)"¸Ã";
+ switch(compType)
+ {
+ case ClassDef::Class: result+="Àà"; break;
+ case ClassDef::Struct: result+="½á¹¹"; break;
+ case ClassDef::Union: result+="ÁªºÏ"; break;
+ case ClassDef::Interface: result+="½Ó¿Ú"; break;
+ case ClassDef::Exception: result+="Òì³£"; break;
+ }
+ result+="µÄÎĵµÓÉÒÔÏÂÎļþÉú³É£º";
+ return result;
+ }
+
+ /*! This is in the (quick) index as a link to the alphabetical compound
+ * list.
+ */
+ QCString trAlphabeticalList()
+ { return "°´×Öµä˳ÐòÅÅÐòµÄÁбí"; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-990901
+//////////////////////////////////////////////////////////////////////////
+
+ /*! This is used as the heading text for the retval command. */
+ QCString trReturnValues()
+ { return "·µ»ØÖµ"; }
+
+ /*! This is in the (quick) index as a link to the main page (index.html)
+ */
+ QCString trMainPage()
+ { return "Ê×Ò³"; }
+
+ /*! This is used in references to page that are put in the LaTeX
+ * documentation. It should be an abbreviation of the word page.
+ */
+ QCString trPageAbbreviation()
+ { return "p."; }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991106
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trSources()
+ {
+ return "Ô´´úÂë";
+ }
+ QCString trDefinedAtLineInSourceFile()
+ {
+ return "ÔÚÎļþ"CN_SPC"@1"CN_SPC"µÚ"CN_SPC"@0"CN_SPC"Ðж¨Òå¡£";
+ }
+ QCString trDefinedInSourceFile()
+ {
+ return "ÔÚÎļþ"CN_SPC"@0"CN_SPC"Öж¨Òå¡£";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 0.49-991205
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trDeprecated()
+ {
+ return "Deprecated";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.0.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! this text is put before a collaboration diagram */
+ QCString trCollaborationDiagram(const char *clName)
+ {
+ return (QCString)clName+CN_SPC"ºÏ×÷ͼ£º";
+ }
+ /*! this text is put before an include dependency graph */
+ QCString trInclDepGraph(const char *fName)
+ {
+ return (QCString)fName+CN_SPC"°üº¬/ÒÀÀµ¹Øϵͼ£º";
+ }
+ /*! header that is put before the list of constructor/destructors. */
+ QCString trConstructorDocumentation()
+ {
+ return "¹¹Ôì¼°Îö¹¹º¯ÊýÎĵµ";
+ }
+ /*! Used in the file documentation to point to the corresponding sources. */
+ QCString trGotoSourceCode()
+ {
+ return "ä¯ÀÀ¸ÃÎļþµÄÔ´´úÂë¡£";
+ }
+ /*! Used in the file sources to point to the corresponding documentation. */
+ QCString trGotoDocumentation()
+ {
+ return "ä¯ÀÀ¸ÃÎļþµÄÎĵµ¡£";
+ }
+ /*! Text for the \pre command */
+ QCString trPrecondition()
+ {
+ return "Ç°ÌáÌõ¼þ";
+ }
+ /*! Text for the \post command */
+ QCString trPostcondition()
+ {
+ return "Postcondition";
+ }
+ /*! Text for the \invariant command */
+ QCString trInvariant()
+ {
+ return "Invariant";
+ }
+ /*! Text shown before a multi-line variable/enum initialization */
+ QCString trInitialValue()
+ {
+ return "³õʼ»¯ÐòÁУº";
+ }
+ /*! Text used the source code in the file index */
+ QCString trCode()
+ {
+ return "´úÂë";
+ }
+ QCString trGraphicalHierarchy()
+ {
+ return "Àà¼Ì³Ð¹Øϵͼ";
+ }
+ QCString trGotoGraphicalHierarchy()
+ {
+ return "ä¯ÀÀÀà¼Ì³Ð¹Øϵͼ";
+ }
+ QCString trGotoTextualHierarchy()
+ {
+ return "ä¯ÀÀÀà¼Ì³Ð¹Øϵ±í";
+ }
+ QCString trPageIndex()
+ {
+ return "Ò³ÃæË÷Òý";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.0
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trNote()
+ {
+ return "×¢½â";
+ }
+ QCString trPublicTypes()
+ {
+ return "¹«ÓÐÀàÐÍ";
+ }
+ QCString trPublicAttribs()
+ {
+ return "¹«ÓÐÊôÐÔ";
+ }
+ QCString trStaticPublicAttribs()
+ {
+ return "¾²Ì¬¹«ÓÐÊôÐÔ";
+ }
+ QCString trProtectedTypes()
+ {
+ return "±£»¤ÀàÐÍ";
+ }
+ QCString trProtectedAttribs()
+ {
+ return "±£»¤ÊôÐÔ";
+ }
+ QCString trStaticProtectedAttribs()
+ {
+ return "¾²Ì¬±£»¤ÊôÐÔ";
+ }
+ QCString trPrivateTypes()
+ {
+ return "˽ÓÐÀàÐÍ";
+ }
+ QCString trPrivateAttribs()
+ {
+ return "˽ÓÐÊôÐÔ";
+ }
+ QCString trStaticPrivateAttribs()
+ {
+ return "¾²Ì¬Ë½ÓÐÊôÐÔ";
+ }
+
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.3
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a todo item */
+ QCString trTodo()
+ {
+ return "TODO";
+ }
+ /*! Used as the header of the todo list */
+ QCString trTodoList()
+ {
+ return "TODO"CN_SPC"Áбí";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.4
+//////////////////////////////////////////////////////////////////////////
+
+ QCString trReferencedBy()
+ {
+ return "²Î¿¼×Ô";
+ }
+ QCString trRemarks()
+ {
+ return "ÆÀÂÛ";
+ }
+ QCString trAttention()
+ {
+ return "×¢Òâ";
+ }
+ QCString trInclByDepGraph()
+ {
+ return "´Ëͼչʾֱ½Ó»ò¼ä½Ó°üº¬¸ÃÎļþµÄÎļþ£º";
+ }
+ QCString trSince()
+ {
+ return "×Ô´Ó";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.1.5
+//////////////////////////////////////////////////////////////////////////
+
+ /*! title of the graph legend page */
+ QCString trLegendTitle()
+ {
+ return "ͼÀý";
+ }
+ /*! page explaining how the dot graph's should be interpreted */
+ QCString trLegendDocs()
+ {
+ return
+ "±¾Ò³ÏòÄúչʾÈçºÎÀí½âÓÉ"CN_SPC"Doxygen"CN_SPC"Éú³ÉµÄͼÐΡ£<p>\n"
+ "Ç뿼ÂÇÈçÏÂʾÀý£º\n"
+ "\\code\n"
+ "/*! ÓÉÓÚ½ØÈ¡¶øʹ¸ÃÀ಻¿É¼û */\n"
+ "class Invisible { };\n\n"
+ "/*! ±»½ØÈ¡µÄÀ࣬¼Ì³Ð¹Øϵ±»Òþ²ØÆðÀ´ÁË */\n"
+ "class Truncated : public Invisible { };\n\n"
+ "/* ûÓб»"CN_SPC"doxygen"CN_SPC"µÄ×¢ÊÍÎĵµ»¯µÄÀà */\n"
+ "class Undocumented { };\n\n"
+ "/*! ±»¹«Óм̳еÄÀà */\n"
+ "class PublicBase : public Truncated { };\n\n"
+ "/*! ±»±£»¤¼Ì³ÐµÄÀà */\n"
+ "class ProtectedBase { };\n\n"
+ "/*! ±»Ë½Óм̳еÄÀà */\n"
+ "class PrivateBase { };\n\n"
+ "/*! ±»Ê¹ÓõÄÀà */\n"
+ "class Used { };\n\n"
+ "/*! ¼Ì³ÐÁËÈô¸ÉÆäËüÀàµÄÀà */\n"
+ "class Inherited : public PublicBase,\n"
+ " protected ProtectedBase,\n"
+ " private PrivateBase,\n"
+ " public Undocumented\n"
+ "{\n"
+ " private:\n"
+ " Used *m_usedClass;\n"
+ "};\n"
+ "\\endcode\n"
+ "Èç¹ûÔÚÅäÖÃÎļþÖÐÖ¸¶¨ÁË"CN_SPC"MAX_DOT_GRAPH_HEIGHT"CN_SPC"µÄֵΪ200£¬"
+ "ÔòDoxygen½«Éú³ÉÈçϵÄͼÐΣº"
+ "<p><center><img src=\"graph_legend.gif\"></center>\n"
+ "<p>\n"
+ "ÒÔÉÏͼÐÎÖеľØÐÎÓÐÈçϵĺ¬Ò壺\n"
+ "<ul>\n"
+ "<li>±»ºÚÉ«Ìî³äµÄ¾ØÐδú±íµ±Ç°µÄÀà»ò½á¹¹¡£\n"
+ "<li>ºÚÉ«±ß¿òµÄ¾ØÐδú±í<i>Îĵµ»¯</i>µÄÀà»ò½á¹¹¡£\n"
+ "<li>»ÒÉ«±ß¿òµÄ¾ØÐδú±íûÓÐ<i>Îĵµ»¯</i>µÄÀà»ò½á¹¹¡£\n"
+ "<li>ºìÉ«±ß¿òµÄ¾ØÐδú±í¼Ì³Ð/°üº¬¹ØϵûÓб»ÍêÕûÏÔʾ³öµÄÀà»ò½á¹¹¡£Èç¹ûÒ»·ùͼÏñµÄ³ß"
+ "´ç´óÓÚÖ¸¶¨³ß´ç£¬Ëü½«±»½ØÈ¡¡£"
+ "</ul>\n"
+ "¸÷¸ö¼ýÍ·ÓÐÈçϵĺ¬Ò壺\n"
+ "<ul>\n"
+ "<li>ÉîÀ¶É«µÄ¼ýÍ·ÓÃÓÚÏÔʾÁ½¸öÀàÖ®¼äµÄ¹«Óм̳йØϵ¡£\n"
+ "<li>ÉîÂÌÉ«µÄ¼ýÍ·ÓÃÓÚÏÔʾ±£»¤¼Ì³Ð¹Øϵ¡£\n"
+ "<li>ÉîºìÉ«µÄ¼ýÍ·ÓÃÓÚÏÔʾ˽Óм̳йØϵ¡£\n"
+ "<li>×ÏÉ«µã×´ÏßÌõµÄ¼ýÍ·ÓÃÓÚÏÔʾÁ½¸öÀàÖ®¼ä°üº¬»òÕßʹÓõĹØϵ¡£Í¨¹ý¼ýÍ·ÅԱߵıäÁ¿¿ÉÒÔ"
+ "·ÃÎʵ½¼ýÍ·ËùÖ¸µÄÀà»ò½á¹¹¡£\n"
+ "</ul>\n";
+ }
+ /*! text for the link to the legend page */
+ QCString trLegend()
+ {
+ return "ͼÀý";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.0
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a marker that is put before a test item */
+ virtual QCString trTest()
+ {
+ return "²âÊÔ";
+ }
+ /*! Used as the header of the test list */
+ virtual QCString trTestList()
+ {
+ return "²âÊÔÁбí";
+ }
+
+};
+
+#endif
diff --git a/src/translator_cz.h b/src/translator_cz.h
index c833a15..9b758c4 100644
--- a/src/translator_cz.h
+++ b/src/translator_cz.h
@@ -65,7 +65,12 @@
// 2000/09/06 (Petr Prikryl)
// - Reimplementation of the method trInheritsList() which takes
// into account quantity of base classes.
-//
+//
+// 2000/09/11 (Petr Prikryl)
+// - Update for "new since 1.2.1" version. The text of trDCOPMethods()
+// was translated rather blindly (not knowing what exactly
+// the DCOP means).
+//
// Notices:
// --------
// The conditional compilation ensures or the neutral functionality
@@ -75,7 +80,7 @@
// the conditional definition of the inline Decode() using the
// method ISO88592ToWin1250() -- for conversion of strings for the
// Windows version. The version which does not call the function is
-// probably slightly faster (if the inline is well optimized).
+// probably slightly faster.
class TranslatorCzech : public Translator
{
@@ -1094,6 +1099,15 @@ class TranslatorCzech : public Translator
return Decode("Seznam testù");
}
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for KDE-2 IDL methods */
+ virtual QCString trDCOPMethods()
+ {
+ return Decode("Metody DCOP");
+ }
};
#endif // TRANSLATOR_CZ_H
diff --git a/src/translator_nl.h b/src/translator_nl.h
index 14db842..80a5030 100644
--- a/src/translator_nl.h
+++ b/src/translator_nl.h
@@ -37,19 +37,10 @@ class TranslatorDutch : public Translator
{ return "Documentatie van type definitie members"; }
QCString trMemberEnumerationDocumentation()
{ return "Documentatie van enumeratie members"; }
- QCString trEnumerationValueDocumentation()
- { return "Documentatie van enumeratie waarden"; }
QCString trMemberFunctionDocumentation()
{ return "Documentatie van functie members"; }
QCString trMemberDataDocumentation()
{ return "Documentatie van data members"; }
- QCString trGeneratedFrom(const char *s,bool single)
- {
- QCString result=(QCString)"De documentatie voor deze"+s+
- " is gegenereerd op grond van de volgende file";
- if (single) result+=":"; else result+="s:";
- return result;
- }
QCString trMore()
{ return "Meer..."; }
QCString trListOfAllMembers()
@@ -185,6 +176,8 @@ class TranslatorDutch : public Translator
{ return "Documentatie van typedefs"; }
QCString trEnumerationTypeDocumentation()
{ return "Documentatie van enumeratie types"; }
+ QCString trEnumerationValueDocumentation()
+ { return "Documentatie van enumeratie waarden"; }
QCString trFunctionDocumentation()
{ return "Documentatie van functies"; }
QCString trVariableDocumentation()
@@ -712,6 +705,30 @@ class TranslatorDutch : public Translator
return "Test Lijst";
}
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.1
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for KDE-2 IDL methods */
+ virtual QCString trDCOPMethods()
+ {
+ return "DCOP Methoden";
+ }
+
+//////////////////////////////////////////////////////////////////////////
+// new since 1.2.2
+//////////////////////////////////////////////////////////////////////////
+
+ /*! Used as a section header for IDL properties */
+ virtual QCString trProperties()
+ {
+ return "Properties";
+ }
+ /*! Used as a section header for IDL property documentation */
+ virtual QCString trPropertyDocumentation()
+ {
+ return "Property Documentatie";
+ }
};
#endif
diff --git a/src/util.cpp b/src/util.cpp
index e5c484e..02188c4 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -169,29 +169,66 @@ bool isId(char c)
// return result;
//}
-// remove all annoymous scopes from string s
-QCString removeAnnonymousScopes(const QCString &s)
+/*!
+ Removes all anoymous scopes from string s
+ Possible examples:
+\verbatim
+ "bla::@10::blep" => "bla::blep"
+ "bla::@10::@11::blep" => "bla::blep"
+ "@10::blep" => "blep"
+ " @10::blep" => "blep"
+ "@9::@10::blep" => "blep"
+ "bla::@1" => "bla"
+ "bla::@1::@2" => "bla"
+ "bla @1" => "bla"
+\endverbatim
+ */
+QCString removeAnonymousScopes(const QCString &s)
{
QCString result;
- int i,ni,l=s.length();
+ if (s.isEmpty()) return result;
+ static QRegExp re("[ :]*@[0-9]+[: ]*");
+ int i,l,sl=s.length();
int p=0;
- while ((i=s.find('@',p))!=-1)
- {
- if (i>p+2) result+=s.mid(p,i-p-2);
- if ((ni=s.find("::",i+1))!=-1)
- {
- p=ni+2;
- }
- else
- {
- p=l;
+ while ((i=re.match(s,p,&l))!=-1)
+ {
+ result+=s.mid(p,i-p);
+ int c=i;
+ bool b1=FALSE,b2=FALSE;
+ while (c<i+l && s.at(c)!='@') if (s.at(c++)==':') b1=TRUE;
+ c=i+l-1;
+ while (c>=i && s.at(c)!='@') if (s.at(c--)==':') b2=TRUE;
+ if (b1 && b2)
+ {
+ result+="::";
}
+ p=i+l;
+ }
+ result+=s.right(sl-p);
+ //printf("removeAnonymousScopes(`%s')=`%s'\n",s.data(),result.data());
+ return result;
+}
+
+// replace anonymous scopes with __anonymous__
+QCString replaceAnonymousScopes(const QCString &s)
+{
+ QCString result;
+ if (s.isEmpty()) return result;
+ static QRegExp re("@[0-9]+");
+ int i,l,sl=s.length();
+ int p=0;
+ while ((i=re.match(s,p,&l))!=-1)
+ {
+ result+=s.mid(p,i-p);
+ result+="__anonymous__";
+ p=i+l;
}
- if (p!=l) result+=s.mid(p,l-p);
- //printf("removeAnnonymousScopes(`%s')=`%s'\n",s.data(),result.data());
+ result+=s.right(sl-p);
+ //printf("replaceAnonymousScopes(`%s')=`%s'\n",s.data(),result.data());
return result;
}
+
// strip annonymous left hand side part of the scope
QCString stripAnnonymousNamespaceScope(const QCString &s)
{
@@ -1203,13 +1240,375 @@ void stripIrrelevantConstVolatile(QCString &s)
}
}
-//----------------------------------------------------------------------
-// Matches the arguments list srcAl with the argument list dstAl
-// Returns TRUE if the argument lists are equal. Two argument list are
-// considered equal if the number of arguments is equal and the types of all
-// arguments are equal. Furthermore the const and volatile specifiers
-// stored in the list should be equal.
+// a bit of debug support for matchArguments
+#define MATCH
+#define NOMATCH
+//#define MATCH printf("Match at line %d\n",__LINE__);
+//#define NOMATCH printf("Nomatch at line %d\n",__LINE__);
+
+static bool matchArgument(const Argument *srcA,const Argument *dstA,
+ const QCString &className,
+ const QCString &namespaceName,
+ NamespaceList *usingList)
+{
+ QCString srcAType=trimTemplateSpecifiers(className,srcA->type);
+ QCString dstAType=trimTemplateSpecifiers(className,dstA->type);
+ if (srcAType.left(6)=="class ") srcAType=srcAType.right(srcAType.length()-6);
+ if (dstAType.left(6)=="class ") dstAType=dstAType.right(dstAType.length()-6);
+ stripIrrelevantConstVolatile(srcAType);
+ stripIrrelevantConstVolatile(dstAType);
+
+ if (srcA->array!=dstA->array) // nomatch for char[] against char
+ {
+ NOMATCH
+ return FALSE;
+ }
+ if (srcAType!=dstAType) // check if the argument only differs on name
+ {
+ //printf("scope=`%s': `%s' <=> `%s'\n",className.data(),srcAType.data(),dstAType.data());
+
+ // remove a namespace scope that is only in one type
+ // (assuming a using statement was used)
+ trimNamespaceScope(srcAType,dstAType);
+
+ //QCString srcScope;
+ //QCString dstScope;
+
+ // strip redundant scope specifiers
+ if (!className.isEmpty())
+ {
+ srcAType=trimScope(className,srcAType);
+ dstAType=trimScope(className,dstAType);
+ //printf("trimScope: `%s' <=> `%s'\n",srcAType.data(),dstAType.data());
+ ClassDef *cd;
+ if (!namespaceName.isEmpty())
+ cd=getClass(namespaceName+"::"+className);
+ else
+ cd=getClass(className);
+ if (cd && cd->baseClasses()->count()>0)
+ {
+ trimBaseClassScope(cd->baseClasses(),srcAType);
+ trimBaseClassScope(cd->baseClasses(),dstAType);
+ }
+ //printf("trimBaseClassScope: `%s' <=> `%s'\n",srcAType.data(),dstAType.data());
+ }
+ if (!namespaceName.isEmpty())
+ {
+ srcAType=trimScope(namespaceName,srcAType);
+ dstAType=trimScope(namespaceName,dstAType);
+ }
+ if (usingList && usingList->count()>0)
+ {
+ NamespaceListIterator nli(*usingList);
+ NamespaceDef *nd;
+ for (;(nd=nli.current());++nli)
+ {
+ srcAType=trimScope(nd->name(),srcAType);
+ dstAType=trimScope(nd->name(),dstAType);
+ }
+ }
+
+ if (!srcA->name.isEmpty() && !dstA->type.isEmpty() &&
+ (srcAType+" "+srcA->name)==dstAType)
+ {
+ MATCH
+ return TRUE;
+ }
+ else if (!dstA->name.isEmpty() && !srcA->type.isEmpty() &&
+ (dstAType+" "+dstA->name)==srcAType)
+ {
+ MATCH
+ return TRUE;
+ }
+ //printf("srcA=%s::%s dstA=%s::%s\n",srcAType.data(),srcA->name.data(),
+ // dstAType.data(),dstA->name.data());
+
+ uint srcPos=0,dstPos=0;
+ bool equal=TRUE;
+ while (srcPos<srcAType.length() && dstPos<dstAType.length() && equal)
+ {
+ equal=srcAType.at(srcPos)==dstAType.at(dstPos);
+ if (equal) srcPos++,dstPos++;
+ }
+ if (srcPos<srcAType.length() && dstPos<dstAType.length())
+ {
+ // if nothing matches or the match ends in the middle or at the
+ // end of a string then there is no match
+ if (srcPos==0 || dstPos==0)
+ {
+ NOMATCH
+ return FALSE;
+ }
+ if (isId(srcAType.at(srcPos)) && isId(dstAType.at(dstPos)))
+ {
+ // check if a name if already found -> if no then there is no match
+ if (!srcA->name.isEmpty() || !dstA->name.isEmpty())
+ {
+ NOMATCH
+ return FALSE;
+ }
+ while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++;
+ while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++;
+ if (srcPos<srcAType.length() || dstPos<dstAType.length())
+ {
+ NOMATCH
+ return FALSE;
+ }
+ }
+ else
+ {
+ // otherwise we assume that a name starts at the current position.
+ while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++;
+ while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++;
+ // if nothing more follows for both types then we assume we have
+ // found a match. Note that now `signed int' and `signed' match, but
+ // seeing that int is not a name can only be done by looking at the
+ // semantics.
+
+ if (srcPos!=srcAType.length() || dstPos!=dstAType.length())
+ {
+ NOMATCH
+ return FALSE;
+ }
+ }
+ }
+ else if (dstPos<dstAType.length())
+ {
+ if (!isspace(dstAType.at(dstPos))) // maybe the names differ
+ {
+ while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++;
+ if (dstPos!=dstAType.length())
+ {
+ NOMATCH
+ return FALSE; // more than a difference in name -> no match
+ }
+ }
+ else // maybe dst has a name while src has not
+ {
+ dstPos++;
+ while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++;
+ if (dstPos!=dstAType.length())
+ {
+ NOMATCH
+ return FALSE; // nope not a name -> no match
+ }
+ }
+ }
+ else if (srcPos<srcAType.length())
+ {
+ if (!isspace(srcAType.at(srcPos))) // maybe the names differ
+ {
+ while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++;
+ if (srcPos!=srcAType.length())
+ {
+ NOMATCH
+ return FALSE; // more than a difference in name -> no match
+ }
+ }
+ else // maybe src has a name while dst has not
+ {
+ srcPos++;
+ while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++;
+ if (srcPos!=srcAType.length())
+ {
+ NOMATCH
+ return FALSE; // nope not a name -> no match
+ }
+ }
+ }
+ }
+ MATCH
+ return TRUE;
+}
+static void mergeArgument(Argument *srcA,Argument *dstA,
+ const QCString &className,
+ const QCString &namespaceName,
+ NamespaceList *usingList)
+{
+ QCString srcAType=trimTemplateSpecifiers(className,srcA->type);
+ QCString dstAType=trimTemplateSpecifiers(className,dstA->type);
+ if (srcAType.left(6)=="class ") srcAType=srcAType.right(srcAType.length()-6);
+ if (dstAType.left(6)=="class ") dstAType=dstAType.right(dstAType.length()-6);
+ stripIrrelevantConstVolatile(srcAType);
+ stripIrrelevantConstVolatile(dstAType);
+
+ if (srcAType!=dstAType) // check if the argument only differs on name
+ {
+ //printf("scope=`%s': `%s' <=> `%s'\n",className.data(),srcAType.data(),dstAType.data());
+
+ // remove a namespace scope that is only in one type
+ // (assuming a using statement was used)
+ trimNamespaceScope(srcAType,dstAType);
+
+ //QCString srcScope;
+ //QCString dstScope;
+
+ // strip redundant scope specifiers
+ if (!className.isEmpty())
+ {
+ srcAType=trimScope(className,srcAType);
+ dstAType=trimScope(className,dstAType);
+ //printf("trimScope: `%s' <=> `%s'\n",srcAType.data(),dstAType.data());
+ ClassDef *cd;
+ if (!namespaceName.isEmpty())
+ cd=getClass(namespaceName+"::"+className);
+ else
+ cd=getClass(className);
+ if (cd && cd->baseClasses()->count()>0)
+ {
+ trimBaseClassScope(cd->baseClasses(),srcAType);
+ trimBaseClassScope(cd->baseClasses(),dstAType);
+ }
+ //printf("trimBaseClassScope: `%s' <=> `%s'\n",srcAType.data(),dstAType.data());
+ }
+ if (!namespaceName.isEmpty())
+ {
+ srcAType=trimScope(namespaceName,srcAType);
+ dstAType=trimScope(namespaceName,dstAType);
+ }
+ if (usingList && usingList->count()>0)
+ {
+ NamespaceListIterator nli(*usingList);
+ NamespaceDef *nd;
+ for (;(nd=nli.current());++nli)
+ {
+ srcAType=trimScope(nd->name(),srcAType);
+ dstAType=trimScope(nd->name(),dstAType);
+ }
+ }
+
+ if (!srcA->name.isEmpty() && !dstA->type.isEmpty() &&
+ (srcAType+" "+srcA->name)==dstAType)
+ {
+ srcA->type=srcAType+" "+srcA->name;
+ srcA->name.resize(0);
+ return;
+ }
+ else if (!dstA->name.isEmpty() && !srcA->type.isEmpty() &&
+ (dstAType+" "+dstA->name)==srcAType)
+ {
+ dstA->type=dstAType+" "+dstA->name;
+ dstA->name.resize(0);
+ return;
+ }
+ //printf("srcA=%s::%s dstA=%s::%s\n",srcAType.data(),srcA->name.data(),
+ // dstAType.data(),dstA->name.data());
+
+ uint srcPos=0,dstPos=0;
+ bool equal=TRUE;
+ while (srcPos<srcAType.length() && dstPos<dstAType.length() && equal)
+ {
+ equal=srcAType.at(srcPos)==dstAType.at(dstPos);
+ if (equal) srcPos++,dstPos++;
+ }
+ if (srcPos<srcAType.length() && dstPos<dstAType.length())
+ {
+ // if nothing matches or the match ends in the middle or at the
+ // end of a string then there is no match
+ int srcStart=srcPos;
+ int dstStart=dstPos;
+ if (isId(srcAType.at(srcPos)) && isId(dstAType.at(dstPos)))
+ {
+ // find the start of the name
+ while (srcStart>=0 && isId(srcAType.at(srcStart))) srcStart--;
+ while (dstStart>=0 && isId(dstAType.at(dstStart))) dstStart--;
+ if (srcStart>0) // move the name from the type to the name field
+ {
+ srcA->name=srcAType.right(srcAType.length()-srcStart-1);
+ srcA->type=srcAType.left(srcStart+1).stripWhiteSpace();
+ }
+ if (dstStart>0) // move the name from the type to the name field
+ {
+ dstA->name=dstAType.right(dstAType.length()-dstStart-1);
+ dstA->type=dstAType.left(dstStart+1).stripWhiteSpace();
+ }
+ }
+ else
+ {
+ dstA->name=dstAType.right(dstAType.length()-dstStart);
+ dstA->type=dstAType.left(dstStart).stripWhiteSpace();
+ srcA->name=srcAType.right(dstAType.length()-srcStart);
+ srcA->type=srcAType.left(srcStart).stripWhiteSpace();
+ }
+ }
+ else if (dstPos<dstAType.length())
+ {
+ if (!isspace(dstAType.at(dstPos))) // maybe the names differ
+ {
+ int startPos=dstPos;
+ while (startPos>=0 && isId(dstAType.at(startPos))) startPos--;
+ if (startPos>0)
+ {
+ dstA->name=dstAType.right(dstAType.length()-startPos-1);
+ dstA->type=dstAType.left(startPos+1).stripWhiteSpace();
+ }
+ }
+ else // maybe dst has a name while src has not
+ {
+ dstPos++;
+ int startPos=dstPos;
+ dstA->name=dstAType.right(dstAType.length()-startPos);
+ dstA->type=dstAType.left(startPos).stripWhiteSpace();
+ }
+ }
+ else if (srcPos<srcAType.length())
+ {
+ if (!isspace(srcAType.at(srcPos))) // maybe the names differ
+ {
+ int startPos=srcPos;
+ while (startPos>=0 && isId(srcAType.at(startPos))) startPos--;
+ if (startPos>0)
+ {
+ srcA->name=srcAType.right(srcAType.length()-startPos-1);
+ srcA->type=srcAType.left(startPos+1).stripWhiteSpace();
+ }
+ }
+ else // maybe src has a name while dst has not
+ {
+ srcPos++;
+ int startPos=srcPos;
+ srcA->name=srcAType.right(srcAType.length()-startPos);
+ srcA->type=srcAType.left(startPos).stripWhiteSpace();
+ }
+ }
+ return;
+ }
+ //printf("match exactly\n");
+ if (srcA->name.isEmpty() && dstA->name.isEmpty())
+ // arguments match exactly but no name ->
+ // see if we can find the name
+ {
+ int i=srcAType.length()-1;
+ while (i>=0 && isId(srcAType.at(i))) i--;
+ if (i>0 && i<(int)srcAType.length()-1 && srcAType.at(i)!=':')
+ // there is (probably) a name
+ {
+ srcA->name=srcAType.right(srcAType.length()-i-1);
+ srcA->type=srcAType.left(i+1).stripWhiteSpace();
+ dstA->name=dstAType.right(dstAType.length()-i-1);
+ dstA->type=dstAType.left(i+1).stripWhiteSpace();
+ }
+ }
+ else if (!dstA->name.isEmpty())
+ {
+ srcA->name = dstA->name.copy();
+ }
+ else if (!srcA->name.isEmpty())
+ {
+ dstA->name = srcA->name.copy();
+ }
+ return;
+}
+
+
+/*!
+ * Matches the arguments list srcAl with the argument list dstAl
+ * Returns TRUE if the argument lists are equal. Two argument list are
+ * considered equal if the number of arguments is equal and the types of all
+ * arguments are equal. Furthermore the const and volatile specifiers
+ * stored in the list should be equal.
+ */
bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
const char *cl,const char *ns,bool checkCV,
NamespaceList *usingList)
@@ -1231,7 +1630,17 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
if (srcAl==0 || dstAl==0)
{
- return srcAl==dstAl; // at least one of the members is not a function
+ bool match = srcAl==dstAl; // at least one of the members is not a function
+ if (match)
+ {
+ MATCH
+ return TRUE;
+ }
+ else
+ {
+ NOMATCH
+ return FALSE;
+ }
}
// handle special case with void argument
@@ -1241,6 +1650,7 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
Argument *a=new Argument;
a->type = "void";
srcAl->append(a);
+ MATCH
return TRUE;
}
if ( dstAl->count()==0 && srcAl->count()==1 &&
@@ -1249,11 +1659,13 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
Argument *a=new Argument;
a->type = "void";
dstAl->append(a);
+ MATCH
return TRUE;
}
if (srcAl->count() != dstAl->count())
{
+ NOMATCH
return FALSE; // different number of arguments -> no match
}
@@ -1261,10 +1673,12 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
{
if (srcAl->constSpecifier != dstAl->constSpecifier)
{
+ NOMATCH
return FALSE; // one member is const, the other not -> no match
}
if (srcAl->volatileSpecifier != dstAl->volatileSpecifier)
{
+ NOMATCH
return FALSE; // one member is volatile, the other not -> no match
}
}
@@ -1274,200 +1688,22 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
ArgumentListIterator srcAli(*srcAl),dstAli(*dstAl);
Argument *srcA,*dstA;
for (;(srcA=srcAli.current(),dstA=dstAli.current());++srcAli,++dstAli)
- {
- QCString srcAType=trimTemplateSpecifiers(className,srcA->type);
- QCString dstAType=trimTemplateSpecifiers(className,dstA->type);
- if (srcAType.left(6)=="class ") srcAType=srcAType.right(srcAType.length()-6);
- if (dstAType.left(6)=="class ") dstAType=dstAType.right(dstAType.length()-6);
- stripIrrelevantConstVolatile(srcAType);
- stripIrrelevantConstVolatile(dstAType);
-
- if (srcA->array!=dstA->array) return FALSE;
- if (srcAType!=dstAType) // check if the argument only differs on name
+ {
+ if (!matchArgument(srcA,dstA,className,namespaceName,usingList))
{
- //printf("scope=`%s': `%s' <=> `%s'\n",className.data(),srcAType.data(),dstAType.data());
-
- // remove a namespace scope that is only in one type
- // (assuming a using statement was used)
- trimNamespaceScope(srcAType,dstAType);
-
- //QCString srcScope;
- //QCString dstScope;
-
- // strip redundant scope specifiers
- if (!className.isEmpty())
- {
- srcAType=trimScope(className,srcAType);
- dstAType=trimScope(className,dstAType);
- //printf("trimScope: `%s' <=> `%s'\n",srcAType.data(),dstAType.data());
- ClassDef *cd;
- if (!namespaceName.isEmpty())
- cd=getClass(namespaceName+"::"+className);
- else
- cd=getClass(className);
- if (cd && cd->baseClasses()->count()>0)
- {
- trimBaseClassScope(cd->baseClasses(),srcAType);
- trimBaseClassScope(cd->baseClasses(),dstAType);
- }
- //printf("trimBaseClassScope: `%s' <=> `%s'\n",srcAType.data(),dstAType.data());
- }
- if (!namespaceName.isEmpty())
- {
- srcAType=trimScope(namespaceName,srcAType);
- dstAType=trimScope(namespaceName,dstAType);
- }
- if (usingList && usingList->count()>0)
- {
- NamespaceListIterator nli(*usingList);
- NamespaceDef *nd;
- for (;(nd=nli.current());++nli)
- {
- srcAType=trimScope(nd->name(),srcAType);
- dstAType=trimScope(nd->name(),dstAType);
- }
- }
- //printf("srcAType=%s dstAType=%s\n",srcAType.data(),dstAType.data());
-
- uint srcPos=0,dstPos=0;
- bool equal=TRUE;
- while (srcPos<srcAType.length() && dstPos<dstAType.length() && equal)
- {
- equal=srcAType.at(srcPos)==dstAType.at(dstPos);
- if (equal) srcPos++,dstPos++;
- }
- if (srcPos<srcAType.length() && dstPos<dstAType.length())
- {
- // if nothing matches or the match ends in the middle or at the
- // end of a string then there is no match
- //if (srcPos==0 || isalnum(srcAType.at(srcPos-1)) ||
- // dstPos==0 || isalnum(dstAType.at(dstPos-1))) { printf("No match1\n"); return FALSE; }
- int srcStart=srcPos;
- int dstStart=dstPos;
- if (srcPos==0 || dstPos==0) return FALSE;
- if (isId(srcAType.at(srcPos)) && isId(dstAType.at(dstPos)))
- {
- // check if a name if already found -> if no then there is no match
- if (!srcA->name.isEmpty() || !dstA->name.isEmpty()) return FALSE;
- while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++;
- while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++;
- if (srcPos<srcAType.length() || dstPos<dstAType.length()) return FALSE;
- // find the start of the name
- while (srcStart>=0 && isId(srcAType.at(srcStart))) srcStart--;
- while (dstStart>=0 && isId(dstAType.at(dstStart))) dstStart--;
- if (srcStart>0) // move the name from the type to the name field
- {
- srcA->name=srcAType.right(srcAType.length()-srcStart-1);
- srcA->type=srcAType.left(srcStart+1).stripWhiteSpace();
- }
- if (dstStart>0) // move the name from the type to the name field
- {
- dstA->name=dstAType.right(dstAType.length()-dstStart-1);
- dstA->type=dstAType.left(dstStart+1).stripWhiteSpace();
- }
- }
- else
- {
- // otherwise we assume that a name starts at the current position.
- while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++;
- while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++;
- // if nothing more follows for both types then we assume we have
- // found a match. Note that now `signed int' and `signed' match, but
- // seeing that int is not a name can only be done by looking at the
- // semantics.
-
- if (srcPos!=srcAType.length() || dstPos!=dstAType.length()) { return FALSE; }
- dstA->name=dstAType.right(dstAType.length()-dstStart);
- dstA->type=dstAType.left(dstStart).stripWhiteSpace();
- srcA->name=srcAType.right(dstAType.length()-srcStart);
- srcA->type=srcAType.left(srcStart).stripWhiteSpace();
- }
- }
- else if (dstPos<dstAType.length())
- {
- if (!isspace(dstAType.at(dstPos))) // maybe the names differ
- {
- int startPos=dstPos;
- while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++;
- if (dstPos!=dstAType.length()) return FALSE; // more than a difference in name -> no match
- while (startPos>=0 && isId(dstAType.at(startPos))) startPos--;
- if (startPos>0)
- {
- dstA->name=dstAType.right(dstAType.length()-startPos-1);
- dstA->type=dstAType.left(startPos+1).stripWhiteSpace();
- }
- }
- else // maybe dst has a name while src has not
- {
- dstPos++;
- int startPos=dstPos;
- while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++;
- if (dstPos!=dstAType.length()) return FALSE; // nope not a name -> no match
- else // its a name (most probably) so move it
- {
- dstA->name=dstAType.right(dstAType.length()-startPos);
- dstA->type=dstAType.left(startPos).stripWhiteSpace();
- }
- }
- }
- else if (srcPos<srcAType.length())
- {
- if (!isspace(srcAType.at(srcPos))) // maybe the names differ
- {
- int startPos=srcPos;
- while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++;
- if (srcPos!=srcAType.length()) return FALSE; // more than a difference in name -> no match
- while (startPos>=0 && isId(srcAType.at(startPos))) startPos--;
- if (startPos>0)
- {
- srcA->name=srcAType.right(srcAType.length()-startPos-1);
- srcA->type=srcAType.left(startPos+1).stripWhiteSpace();
- }
- }
- else // maybe src has a name while dst has not
- {
- srcPos++;
- int startPos=srcPos;
- while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++;
- if (srcPos!=srcAType.length()) return FALSE; // nope not a name -> no match
- else // its a name (most probably) so move it
- {
- srcA->name=srcAType.right(srcAType.length()-startPos);
- srcA->type=srcAType.left(startPos).stripWhiteSpace();
- }
- }
- }
- else // without scopes the names match exactly
- {
- }
- return TRUE;
- }
- //printf("match exactly\n");
- if (srcA->name.isEmpty() && dstA->name.isEmpty())
- // arguments match exactly but no name ->
- // see if we can find the name
- {
- int i=srcAType.length()-1;
- while (i>=0 && isId(srcAType.at(i))) i--;
- if (i>0 && i<(int)srcAType.length()-1 && srcAType.at(i)!=':')
- // there is (probably) a name
- {
- srcA->name=srcAType.right(srcAType.length()-i-1);
- srcA->type=srcAType.left(i+1).stripWhiteSpace();
- dstA->name=dstAType.right(dstAType.length()-i-1);
- dstA->type=dstAType.left(i+1).stripWhiteSpace();
- }
- }
- else if (!dstA->name.isEmpty())
- {
- srcA->name=dstA->name.copy();
- }
- else if (!srcA->name.isEmpty())
- {
- dstA->name=srcA->name.copy();
+ NOMATCH
+ return FALSE;
}
}
- //printf("Match found!\n");
+ // merge/correct argument type/names
+ for (srcAli.toFirst(),dstAli.toFirst();
+ (srcA=srcAli.current(),dstA=dstAli.current());
+ ++srcAli,++dstAli
+ )
+ {
+ mergeArgument(srcA,dstA,className,namespaceName,usingList);
+ }
+ MATCH
return TRUE; // all arguments match
}
@@ -1572,7 +1808,9 @@ bool getDefs(const QCString &scName,const QCString &memberName,
const char *args,
MemberDef *&md,
ClassDef *&cd, FileDef *&fd, NamespaceDef *&nd, GroupDef *&gd,
- bool forceEmptyScope)
+ bool forceEmptyScope,
+ FileDef *currentFile
+ )
{
fd=0, md=0, cd=0, nd=0, gd=0;
if (memberName.isEmpty()) return FALSE; /* empty name => nothing to link */
@@ -1784,6 +2022,8 @@ bool getDefs(const QCString &scName,const QCString &memberName,
}
else // no scope => global function
{
+ QList<MemberDef> members;
+
//printf("Function with global scope `%s' args=`%s'\n",namespaceName.data(),args);
MemberListIterator mli(*mn);
for (mli.toFirst();(md=mli.current());++mli)
@@ -1794,12 +2034,10 @@ bool getDefs(const QCString &scName,const QCString &memberName,
gd=md->getGroupDef();
//printf("md->name()=`%s' md->args=`%s' fd=%p gd=%p\n",
// md->name().data(),args,fd,gd);
- bool inGroup=FALSE;
if ((fd && fd->isLinkable()) ||
- (inGroup=(gd && gd->isLinkable()))
+ (gd && gd->isLinkable())
)
{
- if (inGroup) fd=0;
//printf("fd=%p gd=%p inGroup=`%d' args=`%s'\n",fd,gd,inGroup,args);
bool match=TRUE;
ArgumentList *argList=0;
@@ -1813,7 +2051,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
if (match)
{
//printf("Found match!\n");
- return TRUE;
+ members.append(md);
}
}
}
@@ -1831,18 +2069,44 @@ bool getDefs(const QCString &scName,const QCString &memberName,
//printf("member is linkable md->name()=`%s'\n",md->name().data());
fd=md->getFileDef();
gd=md->getGroupDef();
- bool inGroup=FALSE;
if ((fd && fd->isLinkable()) ||
- (inGroup=(gd && gd->isLinkable()))
+ (gd && gd->isLinkable())
)
{
- if (inGroup) fd=0;
- return TRUE;
+ members.append(md);
}
}
md=mn->prev();
}
}
+ if (members.count()==1 || currentFile!=0)
+ {
+ md=members.first();
+ }
+ else if (members.count()>1)
+ {
+ // use some C scoping rules to determine the correct link
+ // 1. member in current file
+ // 2. non-static member in different file
+ MemberDef *bmd = 0;
+ for (md=members.first(); md; md=members.next())
+ {
+ if (md->getFileDef() == currentFile)
+ {
+ bmd = 0;
+ break;
+ }
+ if (!(md->isStatic())) bmd = md;
+ }
+ if (bmd) md=bmd;
+ }
+ if (md) // found a matching global member
+ {
+ fd=md->getFileDef();
+ gd=md->getGroupDef();
+ if (gd && gd->isLinkable()) fd=0; else gd=0;
+ return TRUE;
+ }
}
if (scopeOffset==0)
{
diff --git a/src/util.h b/src/util.h
index f0ed331..2c1ab3d 100644
--- a/src/util.h
+++ b/src/util.h
@@ -85,11 +85,16 @@ extern void linkifyText(const TextGeneratorIntf &ol,const char *clName,const cha
extern void setAnchors(char id,MemberList *ml,int groupId=-1);
extern QCString fileToString(const char *name);
extern QCString dateToString(bool);
-extern bool getDefs(const QCString &scopeName,const QCString &memberName,
- const char *, MemberDef *&md,
- ClassDef *&cd,FileDef *&fd,
- NamespaceDef *&nd,GroupDef *&gd,
- bool forceEmptyScope=FALSE
+extern bool getDefs(const QCString &scopeName,
+ const QCString &memberName,
+ const char *,
+ MemberDef *&md,
+ ClassDef *&cd,
+ FileDef *&fd,
+ NamespaceDef *&nd,
+ GroupDef *&gd,
+ bool forceEmptyScope=FALSE,
+ FileDef *currentFile=0
);
extern bool generateRef(OutputList &ol,const char *,
const char *,bool inSeeBlock,const char * =0);
@@ -133,7 +138,8 @@ bool leftScopeMatch(const QCString &scope, const QCString &name);
void writePageRef(OutputList &ol,const char *cn,const char *mn);
QCString substituteKeywords(const QCString &s,const char *title);
int getPrefixIndex(const QCString &name);
-QCString removeAnnonymousScopes(const QCString &s);
+QCString removeAnonymousScopes(const QCString &s);
+QCString replaceAnonymousScopes(const QCString &s);
void initClassHierarchy(ClassList *cl);
bool hasVisibleRoot(BaseClassList *bcl);
int minClassDistance(ClassDef *cd,ClassDef *bcd,int level=0);
diff --git a/src/xml_dtd.h b/src/xml_dtd.h
index f43db77..010a465 100644
--- a/src/xml_dtd.h
+++ b/src/xml_dtd.h
@@ -1,4 +1,4 @@
-"<?xml encoding=\"ISO-8859-1\"?>\n"
+"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
"<!-- DTD describing the grammar used in doxygen's XML output -->\n"
"\n"
"<!-- standard character entities -->\n"
@@ -50,6 +50,8 @@
" |friend\n"
" |related\n"
" |define|prototype|typedef|enum|func|var\n"
+" |dcop-func\n"
+" |property\n"
" ) #REQUIRED\n"
" '\n"
">\n"