summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>2000-12-03 19:13:07 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>2000-12-03 19:13:07 (GMT)
commit5167cf2076e30ed3f6ddd84b76543a0dff207496 (patch)
tree485fb83c5a301dd4b0edb3c534b1f31eeb08ab1f
parenta1995ea7b217edfe0a6ddf3d60ea7bde1e23c1d7 (diff)
downloadDoxygen-5167cf2076e30ed3f6ddd84b76543a0dff207496.zip
Doxygen-5167cf2076e30ed3f6ddd84b76543a0dff207496.tar.gz
Doxygen-5167cf2076e30ed3f6ddd84b76543a0dff207496.tar.bz2
Release-1.2.3-20001203
-rw-r--r--INSTALL4
-rw-r--r--README4
-rw-r--r--VERSION2
-rw-r--r--addon/configgen/config_templ.l17
-rw-r--r--addon/configgen/configgen.cpp10
-rw-r--r--doc/Makefile.win.in2
-rw-r--r--doc/config.doc18
-rw-r--r--doc/docblocks.doc2
-rw-r--r--doc/index.doc5
-rw-r--r--packages/rpm/doxygen.spec2
-rw-r--r--qtools/qcollection.h4
-rw-r--r--qtools/qconfig.h9
-rw-r--r--qtools/qcstring.cpp2
-rw-r--r--qtools/qdatetime.cpp2
-rw-r--r--qtools/qdir.cpp22
-rw-r--r--qtools/qdir_unix.cpp34
-rw-r--r--qtools/qfeatures.h605
-rw-r--r--qtools/qfile_unix.cpp42
-rw-r--r--qtools/qglobal.h49
-rw-r--r--qtools/qiodevice.cpp6
-rw-r--r--qtools/qlist.h1
-rw-r--r--qtools/qmap.cpp254
-rw-r--r--qtools/qmap.h606
-rw-r--r--qtools/qmodules.h11
-rw-r--r--qtools/qstring.cpp37
-rw-r--r--qtools/qstring.h5
-rw-r--r--qtools/qtextcodec.cpp173
-rw-r--r--qtools/qtextstream.cpp206
-rw-r--r--qtools/qtextstream.h4
-rw-r--r--qtools/qtools.pro.in10
-rw-r--r--qtools/qvaluestack.h64
-rw-r--r--qtools/qxml.cpp6007
-rw-r--r--qtools/qxml.h645
-rw-r--r--src/classdef.cpp6
-rw-r--r--src/config.h3
-rw-r--r--src/config.l35
-rw-r--r--src/doc.l14
-rw-r--r--src/doxygen.cpp94
-rw-r--r--src/filedef.cpp10
-rw-r--r--src/ftvhelp.cpp39
-rw-r--r--src/ftvhelp.h6
-rw-r--r--src/htmlgen.cpp1
-rw-r--r--src/index.cpp49
-rw-r--r--src/instdox.cpp15
-rw-r--r--src/pre.l29
-rw-r--r--src/scanner.l71
-rw-r--r--src/translator_cn.h13
-rw-r--r--src/treeview.h43
-rw-r--r--src/treeview.js43
49 files changed, 8789 insertions, 546 deletions
diff --git a/INSTALL b/INSTALL
index b97ceee..56ae336 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,6 +1,6 @@
-DOXYGEN Version 1.2.3-20001126
+DOXYGEN Version 1.2.3-20001203
Please read the installation section of the manual for instructions.
--------
-Dimitri van Heesch (26 November 2000)
+Dimitri van Heesch (03 December 2000)
diff --git a/README b/README
index ccd8256..7d5098d 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-DOXYGEN Version 1.2.3-20001126
+DOXYGEN Version 1.2.3-20001203
Please read INSTALL for compilation instructions.
@@ -7,4 +7,4 @@ The latest version of doxygen can be obtained at
Enjoy,
-Dimitri van Heesch (26 November 2000)
+Dimitri van Heesch (03 December 2000)
diff --git a/VERSION b/VERSION
index af626bc..d2f09f2 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.2.3-20001126
+1.2.3-20001203
diff --git a/addon/configgen/config_templ.l b/addon/configgen/config_templ.l
index 81d4acf..6cccca9 100644
--- a/addon/configgen/config_templ.l
+++ b/addon/configgen/config_templ.l
@@ -453,6 +453,23 @@ void configStrToVal()
Config::enumValuesPerLine=cols;
}
+ if (treeViewWidthString.isEmpty())
+ {
+ Config::treeViewWidth=250;
+ }
+ else
+ {
+ bool ok;
+ int width = treeViewWidthString.toInt(&ok);
+ if (!ok || width<0 || width>1500)
+ {
+ warn_cont("Warning: argument of TREEVIEW_WIDTH is not a valid number in the range [0..1500]!\n"
+ "Using the default of 250!\n");
+ width = 250;
+ }
+ Config::treeViewWidth=width;
+ }
+
if (maxDotGraphWidthString.isEmpty())
{
Config::maxDotGraphWidth=1024;
diff --git a/addon/configgen/configgen.cpp b/addon/configgen/configgen.cpp
index c05cca7..c7b4ab8 100644
--- a/addon/configgen/configgen.cpp
+++ b/addon/configgen/configgen.cpp
@@ -1313,6 +1313,16 @@ void init()
"or Internet explorer 4.0+). "
);
addDependency("ftvHelpFlag","generateHtml");
+ ConfigInt::add( "treeViewWidth",
+ "TREEVIEW_WIDTH",
+ "250",
+ "What is the width of the treeview panel?",
+ "If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be \n"
+ "used to set the initial width (in pixels) of the frame in which the tree \n"
+ "is shown. \n",
+ 0,1500
+ );
+ addDependency("treeViewWidth","generateHtml");
// TODO: integrate this option
// ConfigBool::add( "htmlHelpGroupsOnly",
diff --git a/doc/Makefile.win.in b/doc/Makefile.win.in
index fd2dbc7..0e7624d 100644
--- a/doc/Makefile.win.in
+++ b/doc/Makefile.win.in
@@ -13,7 +13,7 @@
# input used in their production; they are not affected by this license.
all: FORCE
- @xcopy /s /q ..\examples ..\html\examples
+ @xcopy /s /q /i ..\examples ..\html\examples
set DOXYGEN_DOCDIR=.
set VERSION=$(VERSION)
$(DOXYGEN)\bin\doxygen
diff --git a/doc/config.doc b/doc/config.doc
index 8debf84..684710f 100644
--- a/doc/config.doc
+++ b/doc/config.doc
@@ -110,6 +110,7 @@ followed by the descriptions of the tags grouped by category.
<li> \refitem cfg_generate_tagfile GENERATE_TAGFILE
<li> \refitem cfg_generate_testlist GENERATE_TESTLIST
<li> \refitem cfg_generate_todolist GENERATE_TODOLIST
+<li> \refitem cfg_generate_treeview GENERATE_TREEVIEW
<li> \refitem cfg_graphical_hierarchy GRAPHICAL_HIERARCHY
<li> \refitem cfg_have_dot HAVE_DOT
<li> \refitem cfg_hide_scope_names HIDE_SCOPE_NAMES
@@ -162,6 +163,7 @@ followed by the descriptions of the tags grouped by category.
<li> \refitem cfg_strip_from_path STRIP_FROM_PATH
<li> \refitem cfg_tab_size TAB_SIZE
<li> \refitem cfg_tagfiles TAGFILES
+<li> \refitem cfg_treeview_width TREEVIEW_WIDTH
<li> \refitem cfg_verbatim_headers VERBATIM_HEADERS
<li> \refitem cfg_warn_format WARN_FORMAT
<li> \refitem cfg_warn_if_undocumented WARN_IF_UNDOCUMENTED
@@ -737,6 +739,22 @@ followed by the descriptions of the tags grouped by category.
This tag can be used to set the number of enum values (range [1..20])
that doxygen will group on one line in the generated HTML documentation.
+\anchor cfg_generate_treeview
+<dt>\c GENERATE_TREEVIEW <dd>
+ \addindex GENERATE_TREEVIEW
+ If the \c GENERATE_TREEVIEW tag is set to YES, a side pannel will be
+ generated containing a tree-like index structure (just like the one that
+ is generated for HTML Help). For this to work a browser that supports
+ JavaScript and frames is required (for instance Netscape 4.0+
+ or Internet explorer 4.0+).
+
+\anchor cfg_treeview_width
+<dt>\c TREEVIEW_WIDTH <dd>
+ \addindex TREEVIEW_WIDTH
+ If the treeview is enabled (see \c GENERATE_TREEVIEW) then this tag can be
+ used to set the initial width (in pixels) of the frame in which the tree
+ is shown.
+
</dl>
\subsection latex_output LaTeX related options
\anchor cfg_generate_latex
diff --git a/doc/docblocks.doc b/doc/docblocks.doc
index 7500eb5..8241c43 100644
--- a/doc/docblocks.doc
+++ b/doc/docblocks.doc
@@ -151,7 +151,7 @@ Here is an example of a C header named \c structcmd.h that is documented
using structural commands:
\verbinclude structcmd.h
\htmlonly
- Click <a href="$(DOXYGEN_DOCDIR)/examples/structcmd/html/structcmd.h.html">here</a>
+ Click <a href="$(DOXYGEN_DOCDIR)/examples/structcmd/html/structcmd_h.html">here</a>
for the corresponding HTML documentation that is generated by doxygen.
\endhtmlonly
diff --git a/doc/index.doc b/doc/index.doc
index 39069ec..86e10bb 100644
--- a/doc/index.doc
+++ b/doc/index.doc
@@ -169,8 +169,9 @@ Thanks go to:
<li>Jens Breitenstein, Christophe Bordeaux, Samuel H鋑glund, Xet Erixon,
Vlastimil Havran, Petr Prikryl, Ahmed Also Faisal, Alessandro Falappa,
Kenji Nagamatsu, Francisco Oltra Thennet, Olli Korhonen,
- Boris Bralo, Nickolay Semyonov, and Grzegorz Kowal for providing
- translations into various languages.
+ Boris Bralo, Nickolay Semyonov, Richard Kim, F鰈dv醨i Gy鰎gy,
+ Grzegorz Kowal, and Wang Weihan
+ for providing translations into various languages.
<li>many, many others for suggestions, patches and bug reports.
</ul>
*/
diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec
index a426ee4..efbe6aca 100644
--- a/packages/rpm/doxygen.spec
+++ b/packages/rpm/doxygen.spec
@@ -1,5 +1,5 @@
Name: doxygen
-Version: 1.2.3-20001126
+Version: 1.2.3-20001203
Summary: documentation system for C, C++ and IDL
Release: 1
Source0: doxygen-%{version}.src.tar.gz
diff --git a/qtools/qcollection.h b/qtools/qcollection.h
index c7ba00f..a169b7c 100644
--- a/qtools/qcollection.h
+++ b/qtools/qcollection.h
@@ -66,8 +66,8 @@ protected:
bool del_item; // default FALSE
- virtual Item newItem( Item ); // create object
- virtual void deleteItem( Item ); // delete object
+ virtual Item newItem( Item ); // create object
+ virtual void deleteItem( Item ); // delete object
};
diff --git a/qtools/qconfig.h b/qtools/qconfig.h
index fe14e97..7a880f9 100644
--- a/qtools/qconfig.h
+++ b/qtools/qconfig.h
@@ -1,8 +1 @@
-// 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
+// Everything
diff --git a/qtools/qcstring.cpp b/qtools/qcstring.cpp
index 77dc386..2d2e0c5 100644
--- a/qtools/qcstring.cpp
+++ b/qtools/qcstring.cpp
@@ -183,7 +183,7 @@ int qstricmp( const char *str1, const char *str2 )
int res;
uchar c;
if ( !s1 || !s2 )
- return s1 == s1 ? 0 : (int)((long)s2 - (long)s1);
+ return s1 == s2 ? 0 : (int)((long)s2 - (long)s1);
for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
if ( !c ) // strings are equal
break;
diff --git a/qtools/qdatetime.cpp b/qtools/qdatetime.cpp
index 521a022..cecb855 100644
--- a/qtools/qdatetime.cpp
+++ b/qtools/qdatetime.cpp
@@ -355,7 +355,7 @@ bool QDate::setYMD( int y, int m, int d )
}
jd = greg2jul( y, m, d );
#if defined(DEBUG)
- ASSERT( year() == y && month() == m && day() == d );
+ ASSERT( year() == (y > 99 ? y : 1900+y) && month() == m && day() == d );
#endif
return TRUE;
}
diff --git a/qtools/qdir.cpp b/qtools/qdir.cpp
index c4b4987..185933a 100644
--- a/qtools/qdir.cpp
+++ b/qtools/qdir.cpp
@@ -241,7 +241,7 @@ QDir::~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(),
+ \sa path(), absPath(), exists(), cleanDirPath(), dirName(),
absFilePath(), isRelative(), convertToAbs()
*/
@@ -469,7 +469,6 @@ bool QDir::cdUp()
/*!
\fn QString QDir::nameFilter() const
Returns the string set by setNameFilter()
- \sa setNameFilter()
*/
/*!
@@ -481,7 +480,7 @@ bool QDir::cdUp()
".cpp" and all files ending with ".h", you simply call
dir.setNameFilter("*.cpp *.h") or dir.setNameFilter("*.cpp;*.h")
- \sa nameFilter()
+ \sa nameFilter(), setFilter()
*/
void QDir::setNameFilter( const QString &nameFilter )
@@ -495,7 +494,6 @@ void QDir::setNameFilter( const QString &nameFilter )
/*!
\fn QDir::FilterSpec QDir::filter() const
Returns the value set by setFilter()
- \sa setFilter()
*/
/*! \enum QDir::FilterSpec
@@ -533,7 +531,8 @@ void QDir::setNameFilter( const QString &nameFilter )
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()
+
+ \sa filter(), setNameFilter()
*/
void QDir::setFilter( int filterSpec )
@@ -1030,7 +1029,20 @@ QStringList qt_makeFilterList( const QString &filter )
QString s = *it;
if ( s[ (int)s.length() - 1 ] == ';' )
s.remove( s.length() - 1, 1 );
+ if ( s[0] == '\"' ) {
+ s.remove( 0, 1 );
+ while( ++it != lst.end() ) {
+ QString s2 = *it;
+ s += " "+s2;
+ if ( s2[(int)s2.length() -1] == '\"' ) {
+ s.remove( s.length() -1, 1 );
+ break;
+ }
+ }
+ }
lst2 << s;
+ if ( it == lst.end() )
+ break;
}
return lst2;
}
diff --git a/qtools/qdir_unix.cpp b/qtools/qdir_unix.cpp
index 3b12de9..46a3b69 100644
--- a/qtools/qdir_unix.cpp
+++ b/qtools/qdir_unix.cpp
@@ -243,23 +243,25 @@ bool QDir::readDirEntries( const QString &nameFilter,
}
// 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() );
+ if(fiList->count()) {
+ 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 );
}
- delete [] si;
- fiList->setAutoDelete( TRUE );
if ( filterSpec == (FilterSpec)filtS && sortSpec == (SortSpec)sortS &&
nameFilter == nameFilt )
diff --git a/qtools/qfeatures.h b/qtools/qfeatures.h
index 5f6f663..e2e356c 100644
--- a/qtools/qfeatures.h
+++ b/qtools/qfeatures.h
@@ -42,7 +42,29 @@
...
*/
+// Qt ships with a number of pre-defined configurations. If none suit
+// your needs, define QCONFIG_LOCAL and create a "qconfig-local.h" file.
+//
+// Note that disabling some features will produce a libqt that is not
+// compatible with other libqt builds. Such modifications are only
+// supported on Qt/Embedded where reducing the library size is important
+// and where the application-suite is often a fixed set.
+//
+#if defined(QCONFIG_LOCAL)
+#include <qconfig-local.h>
+#elif defined(QCONFIG_QPE)
+#include <qconfig-qpe.h>
+#elif defined(QCONFIG_MINIMAL)
+#include <qconfig-minimal.h>
+#elif defined(QCONFIG_SMALL)
+#include <qconfig-small.h>
+#elif defined(QCONFIG_MEDIUM)
+#include <qconfig-medium.h>
+#elif defined(QCONFIG_LARGE)
+#include <qconfig-large.h>
+#else // everything...
#include <qconfig.h>
+#endif
// Data structures
@@ -51,6 +73,13 @@
*/
//#define QT_NO_STRINGLIST
+#if defined(QT_NO_IMAGE_SMOOTHSCALE)
+/*!
+ QIconSet
+*/
+# define QT_NO_ICONSET
+#endif
+
// File I/O
#if defined(QT_NO_STRINGLIST)
/*!
@@ -60,6 +89,11 @@
#endif
/*!
+ Palettes
+*/
+//#define QT_NO_PALETTE
+
+/*!
QTextStream
*/
//#define QT_NO_TEXTSTREAM
@@ -68,6 +102,12 @@
*/
//#define QT_NO_DATASTREAM
+/*!
+ Dynamic module linking
+*/
+//#define QT_NO_PLUGIN
+
+
// Images
/*!
BMP image I/O
@@ -196,50 +236,112 @@
# 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)
+#if defined(QT_NO_MIME) || defined(QT_NO_TEXTSTREAM) || defined(QT_NO_DRAWUTIL) || defined(QT_NO_IMAGE_SMOOTHSCALE)
/*!
RichText (HTML) display
*/
# define QT_NO_RICHTEXT
#endif
-//XML
-
-#if defined(QT_NO_STRINGLIST)
+/*!
+ XML
+*/
+#if defined(QT_NO_STRINGLIST) || defined(QT_NO_TEXTSTREAM) || defined(QT_NO_TEXTCODEC)
# define QT_NO_XML
#endif
-/*! Document Object Model */
-#if defined(QT_NO_XML) ||defined(QT_NO_MIME)
+/*!
+ Document Object Model
+*/
+#if defined(QT_NO_XML) || defined(QT_NO_MIME)
# define QT_NO_DOM
#endif
// Sound
/*!
- QSound
+ Playing sounds
*/
//#define QT_NO_SOUND
-// Scripting
/*!
Properties
*/
-#if defined(QT_NO_STRINGLIST)
+#if defined(QT_NO_STRINGLIST) || defined(QT_NO_ICONSET)
# define QT_NO_PROPERTIES
#endif
+
+
+// Networking
+
+/*!
+ Network support
+*/
+//#define QT_NO_NETWORK
+
+#if defined(QT_NO_NETWORK) || defined(QT_NO_STRINGLIST) || defined(QT_NO_TEXTSTREAM)
+ /*!
+ DNS
+ */
+# define QT_NO_DNS
+#endif
+/*!
+ Network file access
+*/
+#if defined(QT_NO_NETWORK) || 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
+
+/*!
+ External process invocation.
+*/
+//#define QT_NO_PROCESS
+
+
// Qt/Embedded-specific
+
+#if defined(QT_NO_NETWORK)
+ /*!
+ Multi-process support.
+ */
+# define QT_NO_QWS_MULTIPROCESS
+#endif
+
+#if defined(QT_NO_QWS_MULTIPROCESS) || defined(QT_NO_DATASTREAM)
+ /*!
+ Palmtop Communication Protocol
+ */
+# define QT_NO_COP
+#endif
+
+/*!
+ Console keyboard support
+*/
+//#define QT_NO_QWS_KEYBOARD
+
/*!
Visible cursor
*/
-//#define QT_NO_QWS_CURSOR
+#if defined(QT_NO_CURSOR)
+# define QT_NO_QWS_CURSOR
+#endif
+
/*!
Alpha-blended cursor
*/
@@ -247,20 +349,25 @@
/*!
Mach64 acceleration
*/
-#define QT_NO_QWS_MACH64
+//#define QT_NO_QWS_MACH64
/*!
Voodoo3 acceleration
*/
-#define QT_NO_QWS_VOODOO3
+//#define QT_NO_QWS_VOODOO3
/*!
Matrox MGA acceleration (Millennium/Millennium II/Mystique/G200/G400)
*/
-#define QT_NO_QWS_MATROX
+//#define QT_NO_QWS_MATROX
/*!
Virtual frame buffer
*/
+
//#define QT_NO_QWS_VFB
/*!
+ Transformed frame buffer
+*/
+//#define QT_NO_QWS_TRANSFORMED
+/*!
Remote frame buffer (VNC)
*/
#define QT_NO_QWS_VNC
@@ -270,9 +377,13 @@
//#define QT_NO_QWS_DEPTH_1
/*!
4-bit VGA
- Not yet implemented
*/
-#define QT_NO_QWS_VGA_16
+//#define QT_NO_QWS_VGA_16
+/*!
+ SVGALib Support
+ Not implemented yet
+*/
+#define QT_NO_QWS_SVGALIB
/*!
8-bit grayscale
*/
@@ -282,11 +393,7 @@
*/
//#define QT_NO_QWS_DEPTH_8
/*!
- 15-bit color
-*/
-#define QT_NO_QWS_DEPTH_15
-/*!
- 16-bit color
+ 15 or 16-bit color (define QT_QWS_DEPTH16_RGB as 555 for 15-bit)
*/
//#define QT_NO_QWS_DEPTH_16
/*!
@@ -302,7 +409,7 @@
/*!
Saving of fonts
*/
-#define QT_NO_QWS_SAVEFONTS
+//#define QT_NO_QWS_SAVEFONTS
/*!
Favour code size over graphics speed
@@ -316,8 +423,10 @@
*/
//#define QT_NO_QWS_PROPERTIES
-#if defined(QT_NO_QWS_PROPERTIES) || defined(QT_NO_MIME) && !defined(_WS_QWS_)
-/*! Cut and paste */
+#if defined(QT_NO_QWS_PROPERTIES) || defined(QT_NO_MIME)
+ /*!
+ Cut and paste
+ */
# define QT_NO_CLIPBOARD
#endif
@@ -328,6 +437,13 @@
# define QT_NO_DRAGANDDROP
#endif
+#if defined(QT_NO_PROPERTIES)
+ /*!
+ SQL
+ */
+# define QT_NO_SQL
+#endif
+
#if defined(QT_NO_CLIPBOARD) || defined(QT_NO_MIME) || defined(_WS_QWS_)
/*!
Cut and paste of complex data types (non-text)
@@ -362,36 +478,10 @@
*/
# 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
+ Cursors
*/
-#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
+//#define QT_NO_CURSOR
// Painting
/*!
@@ -403,7 +493,6 @@
*/
//#define QT_NO_TRANSFORMATIONS
-// Printing
/*!
Printing
*/
@@ -411,7 +500,6 @@
# define QT_NO_PRINTER
#endif
-// Metafiles
/*!
QPicture
*/
@@ -426,64 +514,266 @@
//#define QT_NO_LAYOUT
// Widgets
+#if defined(QT_NO_DRAWUTIL) || defined(QT_NO_PALETTE)
/*!
QStyle
*/
-//#define QT_NO_STYLE
+# define QT_NO_STYLE
+#endif
-#if defined QT_NO_IMAGE_SMOOTHSCALE
/*!
- QIconSet
-*/
-# define QT_NO_ICONSET
-#endif
-/*!
- QDialog
+ Dialogs
*/
//#define QT_NO_DIALOG
/*!
- QSemiModal
+ Semi-modal dialogs
*/
//#define QT_NO_SEMIMODAL
/*!
- QFrame
+ Framed widgets
*/
//#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
+/*!
+ Special widget effects (fading, scrolling)
+*/
+//#define QT_NO_EFFECTS
-#if defined(QT_NO_SIMPLEWIDGETS)
- /*!
- QLabel
- */
+
+/*!
+ QLabel
+*/
+#ifdef QT_NO_FRAME
# define QT_NO_LABEL
- /*!
- QPushButton (not implemented).
- */
-# define QT_NO_PUSHBUTTON
- /*!
- QLineEdit (not implemented).
- */
+#endif
+
+/*!
+ Toolbars
+*/
+#ifdef QT_NO_LAYOUT
+# define QT_NO_TOOLBAR
+#endif
+
+/*!
+ Buttons
+*/
+#if defined(QT_NO_BUTTON) || defined(QT_NO_STYLE)
+/*!
+ Check-boxes
+*/
+# define QT_NO_CHECKBOX
+/*!
+ Radio-buttons
+*/
+# define QT_NO_RADIOBUTTON
+#endif
+#if defined(QT_NO_BUTTON) || defined(QT_NO_TOOLBAR) || defined(QT_NO_ICONSET)
+/*!
+ Tool-buttons
+*/
+# define QT_NO_TOOLBUTTON
+#endif
+/*!
+ Grid layout widgets
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_GRID
+#endif
+/*!
+ Group boxes
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_GROUPBOX
+#endif
+#if defined(QT_NO_GROUPBOX)
+/*!
+ Button groups
+*/
+# define QT_NO_BUTTONGROUP
+/*!
+ Horizontal group boxes
+*/
+# define QT_NO_HGROUPBOX
+#endif
+#if defined(QT_NO_HGROUPBOX)
+/*!
+ Vertical group boxes
+*/
+# define QT_NO_VGROUPBOX
+#endif
+#if defined(QT_NO_BUTTONGROUP)
+/*!
+ Horizontal button groups
+*/
+# define QT_NO_HBUTTONGROUP
+#endif
+#if defined(QT_NO_HBUTTONGROUP)
+/*!
+ Vertical button groups
+*/
+# define QT_NO_VBUTTONGROUP
+#endif
+/*!
+ Horizonal box layout widgets
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_HBOX
+#endif
+#if defined(QT_NO_HBOX)
+/*!
+ Vertical box layout widgets
+*/
+# define QT_NO_VBOX
+#endif
+/*!
+ Single-line edits
+*/
+#if defined(QT_NO_PALETTE)
# 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
+#if defined(QT_NO_TOOLBAR)
+/*!
+ Main-windows
+*/
+# define QT_NO_MAINWINDOW
+#endif
+#if defined(QT_NO_ICONSET)
+/*!
+ Menu-like widgets
+*/
+# define QT_NO_MENUDATA
+#endif
+#if defined(QT_NO_MENUDATA)
+/*!
+ Popup-menus
+*/
+# define QT_NO_POPUPMENU
+/*!
+ Menu bars
+*/
+# define QT_NO_MENUBAR
+#endif
+#if defined(QT_NO_BUTTON) || defined(QT_NO_ICONSET) || defined(QT_NO_POPUPMENU)
+/*!
+ Push-buttons
+*/
+# define QT_NO_PUSHBUTTON
+#endif
+/*!
+ Progress bars
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_PROGRESSBAR
+#endif
+/*!
+ Range-control widgets
+*/
+//#define QT_NO_RANGECONTROL
+#if defined(QT_NO_RANGECONTROL) || defined(QT_NO_STYLE)
+/*!
+ Scroll bars
+*/
+# define QT_NO_SCROLLBAR
+/*!
+ Sliders
+*/
+# define QT_NO_SLIDER
+/*!
+ Spin boxes
+*/
+# define QT_NO_SPINBOX
+/*!
+ Dials
+*/
+# define QT_NO_DIAL
+#endif
+
+
+#if defined(QT_NO_SCROLLBAR) || defined(QT_NO_FRAME)
+/*!
+ Scrollable view widgets
+*/
+# define QT_NO_SCROLLVIEW
+#endif
+#if defined(QT_NO_SCROLLVIEW)
+/*!
+ QCanvas
+*/
+# define QT_NO_CANVAS
+/*!
+ QIconView
+*/
+# define QT_NO_ICONVIEW
+#endif
+
+#if defined(QT_NO_SCROLLBAR)
+/*!
+ Table-like widgets
+*/
+# define QT_NO_TABLEVIEW
+#endif
+#if defined(QT_NO_TABLEVIEW)
+/*!
+ Multi-line edits
+*/
+# define QT_NO_MULTILINEEDIT
+#endif
+
+/*!
+ Splitters
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_SPLITTER
+#endif
+/*!
+ Status bars
+*/
+#ifdef QT_NO_LAYOUT
+# define QT_NO_STATUSBAR
+#endif
+/*!
+ Tab-bars
+*/
+#if defined(QT_NO_ICONSET)
+# define QT_NO_TABBAR
+#endif
+#if defined(QT_NO_TABBAR)
+/*!
+ Tab widgets
+*/
+# define QT_NO_TABWIDGET
+#endif
+/*!
+ Tool tips
+*/
+#if defined( QT_NO_LABEL ) || defined( QT_NO_PALETTE )
+# define QT_NO_TOOLTIP
+#endif
+/*!
+ Input validators
+*/
+//#define QT_NO_VALIDATOR
+/*!
+ "What's this" help
+*/
+#if defined( QT_NO_TOOLTIP )
+# define QT_NO_WHATSTHIS
+#endif
+/*!
+ Widget stacks
+*/
+#ifdef QT_NO_FRAME
+# define QT_NO_WIDGETSTACK
#endif
-#if defined(QT_NO_COMPLEXWIDGETS) || defined(QT_NO_RICHTEXT)
+
+#if defined(QT_NO_RICHTEXT) || defined(QT_NO_SCROLLVIEW)
/*!
QTextView
*/
# define QT_NO_TEXTVIEW
#endif
+
#if defined(QT_NO_TEXTVIEW)
/*!
QTextBrowser
@@ -503,84 +793,74 @@
#endif
#if defined(QT_NO_STYLE_MOTIF)
+ /*!
+ Motif-plus style
+ */
# define QT_NO_STYLE_MOTIFPLUS
#endif
-#if defined(QT_NO_COMPLEXWIDGETS) || defined(QT_NO_STRINGLIST)
+#if defined(QT_NO_SCROLLVIEW) || defined(QT_NO_STRINGLIST)
/*!
QListBox
*/
# define QT_NO_LISTBOX
#endif
-#if defined(QT_NO_COMPLEXWIDGETS)
- /*!
- QAccel
- */
-# define QT_NO_ACCEL
+/*!
+ QAccel
+*/
+//#define QT_NO_ACCEL
- /*!
- QSizeGrip
- */
+/*!
+ QSizeGrip
+*/
+#ifdef QT_NO_PALETTE
# define QT_NO_SIZEGRIP
- /*!
- QHeader
- */
+#endif
+/*!
+ QHeader
+*/
+#ifdef QT_NO_ICONSET
# define QT_NO_HEADER
- /*!
- QMenuBar
- */
-# define QT_NO_MENUBAR
- /*!
- QCanvas
- */
-# define QT_NO_CANVAS
- /*!
- QDial
- */
-# define QT_NO_DIAL
- /*!
- QWorkSpace
- */
+#endif
+/*!
+ QWorkSpace
+*/
+#ifdef QT_NO_FRAME
# define QT_NO_WORKSPACE
- /*!
- QLCDNumber
- */
+#endif
+/*!
+ QLCDNumber
+*/
+#ifdef QT_NO_FRAME
# define QT_NO_LCDNUMBER
- /*!
- QAction
- */
-# define QT_NO_ACTION
+#endif
+/*!
+ QAction
+*/
+//#define QT_NO_ACTION
+
+#if defined(QT_NO_HEADER)
/*!
QTable
*/
# define QT_NO_TABLE
#endif
-#if defined(QT_NO_LISTBOX) || defined(QT_NO_COMPLEXWIDGETS)
+
+#if defined(QT_NO_LISTBOX)
/*!
QComboBox
*/
# define QT_NO_COMBOBOX
#endif
-#if defined(QT_NO_COMPLEXWIDGETS)
- /*!
- QIconView
- */
-# define QT_NO_ICONVIEW
-#endif
-#if defined(QT_NO_HEADER)
+
+#if defined(QT_NO_HEADER) || defined(QT_NO_SCROLLVIEW)
/*!
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)
/*!
@@ -589,7 +869,7 @@
# define QT_NO_STYLE_COMPACT
#endif
-#if defined(QT_NO_STYLE_MOTIF)
+#if defined(QT_NO_STYLE_MOTIF) || defined(QT_NO_TRANSFORMATIONS)
/*!
CDE style
*/
@@ -606,53 +886,60 @@
# define QT_NO_STYLE_PLATINUM
#endif
-#if defined(QT_NO_DIALOGS)
- /*!
- QColorDialog
- */
+/*!
+ QColorDialog
+*/
+#if defined(QT_NO_LAYOUT) || defined(QT_NO_LABEL) || defined(QT_NO_PUSHBUTTON) || defined(QT_NO_DIALOG)
# define QT_NO_COLORDIALOG
- /*!
- QMessageBox
- */
+#endif
+#if defined(QT_NO_DIALOG)
+/*!
+ QMessageBox
+*/
# define QT_NO_MESSAGEBOX
- /*!
- QTabDialog
- */
-# define QT_NO_TABDIALOG
- /*!
- QWizard
- */
+#endif
+#if defined(QT_NO_DIALOG) || defined(QT_NO_TABBAR)
+/*!
+ QTabDialog
+*/
+#define QT_NO_TABDIALOG
+#endif
+
+#if defined(QT_NO_DIALOG)
+/*!
+ 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)
+#if defined(QT_NO_DIALOG) || defined(QT_NO_LISTVIEW) || defined(QT_NO_NETWORKPROTOCOL) || defined(QT_NO_COMBOBOX) || defined(QT_NO_DIR) || defined(QT_NO_MESSAGEBOX) || defined(QT_NO_SEMIMODAL)
/*!
QFileDialog
*/
# define QT_NO_FILEDIALOG
#endif
-#if defined(QT_NO_DIALOGS) || defined(QT_NO_FONTDATABASE) || defined(QT_NO_COMBOBOX)
+#if defined(QT_NO_DIALOG) || 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)
+#if defined(QT_NO_DIALOG) || defined(QT_NO_LISTVIEW) || defined(QT_NO_PRINTER) || defined(QT_NO_COMBOBOX) || defined(QT_NO_DIR) || defined(QT_NO_LAYOUT) || defined(QT_NO_LABEL)
/*!
QPrintDialog
*/
# define QT_NO_PRINTDIALOG
#endif
-#if defined(QT_NO_DIALOGS) || defined(QT_NO_SEMIMODAL)
+#if defined(QT_NO_SEMIMODAL)
/*!
QProgressDialog
*/
# define QT_NO_PROGRESSDIALOG
#endif
-#if defined(QT_NO_DIALOGS) || defined(QT_NO_COMBOBOX)
+#if defined(QT_NO_DIALOG) || defined(QT_NO_COMBOBOX)
/*!
QInputDialog
*/
@@ -660,12 +947,10 @@
#endif
#if defined(QT_NO_STRINGLIST)
- // Desktop features
- /*! Session management support */
+ /*!
+ 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_unix.cpp b/qtools/qfile_unix.cpp
index 5c27988..e074eed 100644
--- a/qtools/qfile_unix.cpp
+++ b/qtools/qfile_unix.cpp
@@ -236,7 +236,7 @@ bool QFile::open( int m )
} else {
length = (int)st.st_size;
ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
- if ( (flags() & !IO_Truncate) && length == 0 && isReadable() ) {
+ 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();
@@ -300,13 +300,13 @@ bool QFile::open( int m, FILE *f )
STATBUF st;
FSTAT( FILENO(fh), &st );
ioIndex = (int)ftell( fh );
- if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+ if ( (st.st_mode & STAT_MASK) != STAT_REG || f == stdin ) { //stdin is non seekable
// non-seekable
setType( IO_Sequential );
length = INT_MAX;
} else {
length = (int)st.st_size;
- if ( (flags() & !IO_Truncate) && length == 0 && isReadable() ) {
+ 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();
@@ -350,7 +350,7 @@ bool QFile::open( int m, int f )
STATBUF st;
FSTAT( fd, &st );
ioIndex = (int)LSEEK(fd, 0, SEEK_CUR);
- if ( (st.st_mode & STAT_MASK) != STAT_REG ) {
+ if ( (st.st_mode & STAT_MASK) != STAT_REG || f == 0 ) { // stdin is not seekable...
// non-seekable
setType( IO_Sequential );
length = INT_MAX;
@@ -365,6 +365,7 @@ bool QFile::open( int m, int f )
setType( IO_Sequential );
length = INT_MAX;
}
+ resetStatus();
}
}
return TRUE;
@@ -466,18 +467,31 @@ int QFile::readBlock( char *p, uint len )
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);
+ int nread = 0; // number of bytes read
+ if ( !ungetchBuffer.isEmpty() ) {
+ // need to add these to the returned string.
+ int l = ungetchBuffer.length();
+ while( nread < l ) {
+ *p = ungetchBuffer[ l - nread - 1 ];
+ p++;
+ nread++;
}
- } else { // buffered file
- nread = fread( p, 1, len, fh );
- if ( (uint)nread != len ) {
- if ( ferror( fh ) || nread==0 )
+ ungetchBuffer.truncate( l - nread );
+ }
+
+ if ( nread < (int)len ) {
+ if ( isRaw() ) { // raw file
+ nread += READ( fd, p, len-nread );
+ if ( len && nread <= 0 ) {
+ nread = 0;
setStatus(IO_ReadError);
+ }
+ } else { // buffered file
+ nread += fread( p, 1, len-nread, fh );
+ if ( (uint)nread != len ) {
+ if ( ferror( fh ) || nread==0 )
+ setStatus(IO_ReadError);
+ }
}
}
ioIndex += nread;
diff --git a/qtools/qglobal.h b/qtools/qglobal.h
index 314043a..c58e466 100644
--- a/qtools/qglobal.h
+++ b/qtools/qglobal.h
@@ -39,8 +39,8 @@
#define QGLOBAL_H
-#define QT_VERSION 220
-#define QT_VERSION_STR "2.2.0"
+#define QT_VERSION 222
+#define QT_VERSION_STR "2.2.2"
//
@@ -98,9 +98,6 @@
#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__)
@@ -153,18 +150,19 @@
//
// SYM - Symantec C++ for both PC and Macintosh
// MPW - MPW C++
-// MWERKS - Metroworks CodeWarrior
+// MWERKS - Metrowerks 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++
+// OC - CenterLine C++
// SUN - Sun C++
// DEC - DEC C++
// HP - HPUX C++
-// USLC - SCO UnixWare C++
+// USLC - SCO UnixWare7 C++
+// CDS - Reliant C++
// KAI - KAI C++
//
@@ -175,6 +173,7 @@
#define _CC_SYM_
#elif defined( __KCC )
#define _CC_KAI_
+#define _CC_EDG_
#define Q_HAS_BOOL_TYPE
#elif defined(applec)
#define _CC_MPW_
@@ -196,6 +195,9 @@
#define Q_TEMPLATE_NEEDS_EXPLICIT_CONVERSION
#define Q_SPURIOUS_NON_VOID_WARNING
#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 95
+#define Q_DELETING_VOID_UNDEFINED
+#endif
#if __GNUC__ == 2 && __GNUC_MINOR__ >= 96
#define Q_DELETING_VOID_UNDEFINED
#define Q_FP_CCAST_BROKEN
@@ -206,9 +208,17 @@
#elif defined(__xlC__)
#define _CC_XLC_
#define Q_FULL_TEMPLATE_INSTANTIATION
+#if __xlC__ >= 0x400
+#define Q_HAS_BOOL_TYPE
+#endif
+#if __xlC__ <= 0x0306
+#define Q_TEMPLATE_NEEDS_EXPLICIT_CONVERSION
+#endif
#elif defined(como40)
#define _CC_EDG_
#define _CC_COMEAU_
+#define Q_HAS_BOOL_TYPE
+#define Q_C_CALLBACKS
#elif defined(__USLC__)
#define _CC_USLC_
#ifdef __EDG__ // UnixWare7
@@ -216,19 +226,24 @@
#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_
+#if defined(_BOOL)
+#define Q_HAS_BOOL_TYPE
+#endif
#elif defined(__SUNPRO_CC)
#define _CC_SUN_
#if __SUNPRO_CC >= 0x500
#define Q_HAS_BOOL_TYPE
-#define Q_SPARCWORKS_FUNCP_BUG
+#define Q_FP_CCAST_BROKEN
#define Q_C_CALLBACKS
#endif
#elif defined(__DECCXX)
#define _CC_DEC_
+#if __DECCXX_VER >= 60060005
+#define Q_HAS_BOOL_TYPE
+#endif
#elif defined(__CDS__)
#define _CC_CDS_
#define Q_HAS_BOOL_TYPE
@@ -248,10 +263,6 @@
#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
@@ -302,13 +313,7 @@
#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)
+#elif defined(sgi) && defined(_BOOL)
#define Q_HAS_BOOL_TYPE
#endif
@@ -478,6 +483,8 @@ Q_EXPORT bool qSysInfo( int *wordSize, bool *bigEndian );
#pragma warning(disable: 4275)
#pragma warning(disable: 4514)
#pragma warning(disable: 4800)
+#pragma warning(disable: 4097)
+#pragma warning(disable: 4706)
#elif defined(_CC_BOR_)
#pragma option -w-inl
#pragma option -w-aus
diff --git a/qtools/qiodevice.cpp b/qtools/qiodevice.cpp
index b2a6751..43b2787 100644
--- a/qtools/qiodevice.cpp
+++ b/qtools/qiodevice.cpp
@@ -425,8 +425,10 @@ void QIODevice::setStatus( int s )
<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.
+ for text files under MS-DOS, Window, OS/2 and Macintosh. On Unix systems
+ this flag has no effect. Use with caution as it will also transform every linefeed
+ written to the file into a CRLF pair. This is likely to corrupt your file when
+ writing binary data to it. Cannot be combined with \c IO_Raw.
</ul>
This virtual function must be reimplemented by all subclasses.
diff --git a/qtools/qlist.h b/qtools/qlist.h
index 678e92d..a4608fb 100644
--- a/qtools/qlist.h
+++ b/qtools/qlist.h
@@ -105,7 +105,6 @@ template<class type> inline void QList<type>::deleteItem( QCollection::Item d )
}
-
template<class type> class Q_EXPORT QListIterator : public QGListIterator
{
public:
diff --git a/qtools/qmap.cpp b/qtools/qmap.cpp
new file mode 100644
index 0000000..1d2510a
--- /dev/null
+++ b/qtools/qmap.cpp
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+**
+** Implementation of QMap
+**
+** 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 "qmap.h"
+
+typedef QMapNodeBase* NodePtr;
+typedef QMapNodeBase Node;
+
+
+void QMapPrivateBase::rotateLeft( NodePtr x, NodePtr& root)
+{
+ NodePtr y = x->right;
+ x->right = y->left;
+ if (y->left !=0)
+ y->left->parent = x;
+ y->parent = x->parent;
+ if (x == root)
+ root = y;
+ else if (x == x->parent->left)
+ x->parent->left = y;
+ else
+ x->parent->right = y;
+ y->left = x;
+ x->parent = y;
+}
+
+
+void QMapPrivateBase::rotateRight( NodePtr x, NodePtr& root )
+{
+ NodePtr y = x->left;
+ x->left = y->right;
+ if (y->right != 0)
+ y->right->parent = x;
+ y->parent = x->parent;
+ if (x == root)
+ root = y;
+ else if (x == x->parent->right)
+ x->parent->right = y;
+ else
+ x->parent->left = y;
+ y->right = x;
+ x->parent = y;
+}
+
+
+void QMapPrivateBase::rebalance( NodePtr x, NodePtr& root)
+{
+ x->color = Node::Red;
+ while ( x != root && x->parent->color == Node::Red ) {
+ if ( x->parent == x->parent->parent->left ) {
+ NodePtr y = x->parent->parent->right;
+ if (y && y->color == Node::Red) {
+ x->parent->color = Node::Black;
+ y->color = Node::Black;
+ x->parent->parent->color = Node::Red;
+ x = x->parent->parent;
+ } else {
+ if (x == x->parent->right) {
+ x = x->parent;
+ rotateLeft( x, root );
+ }
+ x->parent->color = Node::Black;
+ x->parent->parent->color = Node::Red;
+ rotateRight (x->parent->parent, root );
+ }
+ } else {
+ NodePtr y = x->parent->parent->left;
+ if ( y && y->color == Node::Red ) {
+ x->parent->color = Node::Black;
+ y->color = Node::Black;
+ x->parent->parent->color = Node::Red;
+ x = x->parent->parent;
+ } else {
+ if (x == x->parent->left) {
+ x = x->parent;
+ rotateRight( x, root );
+ }
+ x->parent->color = Node::Black;
+ x->parent->parent->color = Node::Red;
+ rotateLeft( x->parent->parent, root );
+ }
+ }
+ }
+ root->color = Node::Black;
+}
+
+
+NodePtr QMapPrivateBase::removeAndRebalance( NodePtr z, NodePtr& root,
+ NodePtr& leftmost,
+ NodePtr& rightmost )
+{
+ NodePtr y = z;
+ NodePtr x;
+ NodePtr x_parent;
+ if (y->left == 0) {
+ x = y->right;
+ } else {
+ if (y->right == 0)
+ x = y->left;
+ else
+ {
+ y = y->right;
+ while (y->left != 0)
+ y = y->left;
+ x = y->right;
+ }
+ }
+ if (y != z) {
+ z->left->parent = y;
+ y->left = z->left;
+ if (y != z->right) {
+ x_parent = y->parent;
+ if (x)
+ x->parent = y->parent;
+ y->parent->left = x;
+ y->right = z->right;
+ z->right->parent = y;
+ } else {
+ x_parent = y;
+ }
+ if (root == z)
+ root = y;
+ else if (z->parent->left == z)
+ z->parent->left = y;
+ else
+ z->parent->right = y;
+ y->parent = z->parent;
+ // Swap the colors
+ Node::Color c = y->color;
+ y->color = z->color;
+ z->color = c;
+ y = z;
+ } else {
+ x_parent = y->parent;
+ if (x)
+ x->parent = y->parent;
+ if (root == z)
+ root = x;
+ else if (z->parent->left == z)
+ z->parent->left = x;
+ else
+ z->parent->right = x;
+ if ( leftmost == z ) {
+ if (z->right == 0)
+ leftmost = z->parent;
+ else
+ leftmost = x->minimum();
+ }
+ if (rightmost == z) {
+ if (z->left == 0)
+ rightmost = z->parent;
+ else
+ rightmost = x->maximum();
+ }
+ }
+ if (y->color != Node::Red) {
+ while (x != root && (x == 0 || x->color == Node::Black)) {
+ if (x == x_parent->left) {
+ NodePtr w = x_parent->right;
+ if (w->color == Node::Red) {
+ w->color = Node::Black;
+ x_parent->color = Node::Red;
+ rotateLeft(x_parent, root);
+ w = x_parent->right;
+ }
+ if ((w->left == 0 || w->left->color == Node::Black) &&
+ (w->right == 0 || w->right->color == Node::Black)) {
+ w->color = Node::Red;
+ x = x_parent;
+ x_parent = x_parent->parent;
+ } else {
+ if (w->right == 0 || w->right->color == Node::Black) {
+ if (w->left)
+ w->left->color = Node::Black;
+ w->color = Node::Red;
+ rotateRight(w, root);
+ w = x_parent->right;
+ }
+ w->color = x_parent->color;
+ x_parent->color = Node::Black;
+ if (w->right)
+ w->right->color = Node::Black;
+ rotateLeft(x_parent, root);
+ break;
+ }
+ } else {
+ NodePtr w = x_parent->left;
+ if (w->color == Node::Red) {
+ w->color = Node::Black;
+ x_parent->color = Node::Red;
+ rotateRight(x_parent, root);
+ w = x_parent->left;
+ }
+ if ((w->right == 0 || w->right->color == Node::Black) &&
+ (w->left == 0 || w->left->color == Node::Black)) {
+ w->color = Node::Red;
+ x = x_parent;
+ x_parent = x_parent->parent;
+ } else {
+ if (w->left == 0 || w->left->color == Node::Black) {
+ if (w->right)
+ w->right->color = Node::Black;
+ w->color = Node::Red;
+ rotateLeft(w, root);
+ w = x_parent->left;
+ }
+ w->color = x_parent->color;
+ x_parent->color = Node::Black;
+ if (w->left)
+ w->left->color = Node::Black;
+ rotateRight(x_parent, root);
+ break;
+ }
+ }
+ }
+ if (x)
+ x->color = Node::Black;
+ }
+ return y;
+}
diff --git a/qtools/qmap.h b/qtools/qmap.h
new file mode 100644
index 0000000..f384a3d
--- /dev/null
+++ b/qtools/qmap.h
@@ -0,0 +1,606 @@
+/****************************************************************************
+**
+**
+** Definition of QMap 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 QMAP_H
+#define QMAP_H
+
+#ifndef QT_H
+#include "qshared.h"
+#include "qdatastream.h"
+#endif // QT_H
+
+
+struct QMapNodeBase
+{
+ enum Color { Red, Black };
+
+ QMapNodeBase* left;
+ QMapNodeBase* right;
+ QMapNodeBase* parent;
+
+ Color color;
+
+ QMapNodeBase* minimum() {
+ QMapNodeBase* x = this;
+ while ( x->left )
+ x = x->left;
+ return x;
+ }
+
+ QMapNodeBase* maximum() {
+ QMapNodeBase* x = this;
+ while ( x->right )
+ x = x->right;
+ return x;
+ }
+};
+
+
+template <class K, class T>
+struct QMapNode : public QMapNodeBase
+{
+ QMapNode( const K& _key, const T& _data ) { data = _data; key = _key; }
+ QMapNode( const K& _key ) { key = _key; }
+ QMapNode( const QMapNode<K,T>& _n ) { key = _n.key; data = _n.data; }
+ QMapNode() { }
+ T data;
+ K key;
+};
+
+
+template<class K, class T>
+class Q_EXPORT QMapIterator
+{
+ public:
+ /**
+ * Typedefs
+ */
+ typedef QMapNode< K, T >* NodePtr;
+
+ /**
+ * Variables
+ */
+ QMapNode<K,T>* node;
+
+ /**
+ * Functions
+ */
+ QMapIterator() : node( 0 ) {}
+ QMapIterator( QMapNode<K,T>* p ) : node( p ) {}
+ QMapIterator( const QMapIterator<K,T>& it ) : node( it.node ) {}
+
+ bool operator==( const QMapIterator<K,T>& it ) const { return node == it.node; }
+ bool operator!=( const QMapIterator<K,T>& it ) const { return node != it.node; }
+ T& operator*() { return node->data; }
+ const T& operator*() const { return node->data; }
+
+ // Cannot have this - some compilers are too stupid
+ //T* operator->() const { return &(node->data); }
+
+ const K& key() const { return node->key; }
+ T& data() { return node->data; }
+ const T& data() const { return node->data; }
+
+private:
+ int inc() {
+ QMapNodeBase* tmp = node;
+ if ( tmp->right ) {
+ tmp = tmp->right;
+ while ( tmp->left )
+ tmp = tmp->left;
+ } else {
+ QMapNodeBase* y = tmp->parent;
+ while (tmp == y->right) {
+ tmp = y;
+ y = y->parent;
+ }
+ if (tmp->right != y)
+ tmp = y;
+ }
+ node = (NodePtr)tmp;
+ return 0;
+ }
+
+ int dec() {
+ QMapNodeBase* tmp = node;
+ if (tmp->color == QMapNodeBase::Red &&
+ tmp->parent->parent == tmp ) {
+ tmp = tmp->right;
+ } else if (tmp->left != 0) {
+ QMapNodeBase* y = tmp->left;
+ while ( y->right )
+ y = y->right;
+ tmp = y;
+ } else {
+ QMapNodeBase* y = tmp->parent;
+ while (tmp == y->left) {
+ tmp = y;
+ y = y->parent;
+ }
+ tmp = y;
+ }
+ node = (NodePtr)tmp;
+ return 0;
+ }
+
+public:
+ QMapIterator<K,T>& operator++() {
+ inc();
+ return *this;
+ }
+
+ QMapIterator<K,T> operator++(int) {
+ QMapIterator<K,T> tmp = *this;
+ inc();
+ return tmp;
+ }
+
+ QMapIterator<K,T>& operator--() {
+ dec();
+ return *this;
+ }
+
+ QMapIterator<K,T> operator--(int) {
+ QMapIterator<K,T> tmp = *this;
+ dec();
+ return tmp;
+ }
+};
+
+template<class K, class T>
+class Q_EXPORT QMapConstIterator
+{
+ public:
+ /**
+ * Typedefs
+ */
+ typedef QMapNode< K, T >* NodePtr;
+
+ /**
+ * Variables
+ */
+ QMapNode<K,T>* node;
+
+ /**
+ * Functions
+ */
+ QMapConstIterator() : node( 0 ) {}
+ QMapConstIterator( QMapNode<K,T>* p ) : node( p ) {}
+ QMapConstIterator( const QMapConstIterator<K,T>& it ) : node( it.node ) {}
+ QMapConstIterator( const QMapIterator<K,T>& it ) : node( it.node ) {}
+
+ bool operator==( const QMapConstIterator<K,T>& it ) const { return node == it.node; }
+ bool operator!=( const QMapConstIterator<K,T>& it ) const { return node != it.node; }
+ const T& operator*() const { return node->data; }
+
+ // Cannot have this - some compilers are too stupid
+ //const T* operator->() const { return &(node->data); }
+
+ const K& key() const { return node->key; }
+ const T& data() const { return node->data; }
+
+private:
+ int inc() {
+ QMapNodeBase* tmp = node;
+ if ( tmp->right ) {
+ tmp = tmp->right;
+ while ( tmp->left )
+ tmp = tmp->left;
+ } else {
+ QMapNodeBase* y = tmp->parent;
+ while (tmp == y->right) {
+ tmp = y;
+ y = y->parent;
+ }
+ if (tmp->right != y)
+ tmp = y;
+ }
+ node = (NodePtr)tmp;
+ return 0;
+ }
+
+ int dec() {
+ QMapNodeBase* tmp = node;
+ if (tmp->color == QMapNodeBase::Red &&
+ tmp->parent->parent == tmp ) {
+ tmp = tmp->right;
+ } else if (tmp->left != 0) {
+ QMapNodeBase* y = tmp->left;
+ while ( y->right )
+ y = y->right;
+ tmp = y;
+ } else {
+ QMapNodeBase* y = tmp->parent;
+ while (tmp == y->left) {
+ tmp = y;
+ y = y->parent;
+ }
+ tmp = y;
+ }
+ node = (NodePtr)tmp;
+ return 0;
+ }
+
+public:
+ QMapConstIterator<K,T>& operator++() {
+ inc();
+ return *this;
+ }
+
+ QMapConstIterator<K,T> operator++(int) {
+ QMapConstIterator<K,T> tmp = *this;
+ inc();
+ return tmp;
+ }
+
+ QMapConstIterator<K,T>& operator--() {
+ dec();
+ return *this;
+ }
+
+ QMapConstIterator<K,T> operator--(int) {
+ QMapConstIterator<K,T> tmp = *this;
+ dec();
+ return tmp;
+ }
+};
+
+
+class Q_EXPORT QMapPrivateBase : public QShared
+{
+public:
+ QMapPrivateBase() {
+ node_count = 0;
+ }
+ QMapPrivateBase( const QMapPrivateBase* _map) {
+ node_count = _map->node_count;
+ }
+
+ /**
+ * Implementations of basic tree algorithms
+ */
+ void rotateLeft( QMapNodeBase* x, QMapNodeBase*& root);
+ void rotateRight( QMapNodeBase* x, QMapNodeBase*& root );
+ void rebalance( QMapNodeBase* x, QMapNodeBase*& root );
+ QMapNodeBase* removeAndRebalance( QMapNodeBase* z, QMapNodeBase*& root,
+ QMapNodeBase*& leftmost,
+ QMapNodeBase*& rightmost );
+
+ /**
+ * Variables
+ */
+ int node_count;
+};
+
+
+template <class Key, class T>
+class QMapPrivate : public QMapPrivateBase
+{
+public:
+ /**
+ * Typedefs
+ */
+ typedef QMapIterator< Key, T > Iterator;
+ typedef QMapConstIterator< Key, T > ConstIterator;
+ typedef QMapNode< Key, T > Node;
+ typedef QMapNode< Key, T >* NodePtr;
+
+ /**
+ * Functions
+ */
+ QMapPrivate() {
+ header = new Node;
+ header->color = QMapNodeBase::Red; // Mark the header
+ header->parent = 0;
+ header->left = header->right = header;
+ }
+ QMapPrivate( const QMapPrivate< Key, T >* _map ) : QMapPrivateBase( _map ) {
+ header = new Node;
+ header->color = QMapNodeBase::Red; // Mark the header
+ if ( _map->header->parent == 0 ) {
+ header->parent = 0;
+ header->left = header->right = header;
+ } else {
+ header->parent = copy( (NodePtr)(_map->header->parent) );
+ header->parent->parent = header;
+ header->left = header->parent->minimum();
+ header->right = header->parent->maximum();
+ }
+ }
+ ~QMapPrivate() { clear(); delete header; }
+
+ NodePtr copy( NodePtr p ) {
+ if ( !p )
+ return 0;
+ NodePtr n = new Node( *p );
+ n->color = p->color;
+ if ( p->left ) {
+ n->left = copy( (NodePtr)(p->left) );
+ n->left->parent = n;
+ } else {
+ n->left = 0;
+ }
+ if ( p->right ) {
+ n->right = copy( (NodePtr)(p->right) );
+ n->right->parent = n;
+ } else {
+ n->right = 0;
+ }
+ return n;
+ }
+
+ void clear() {
+ clear( (NodePtr)(header->parent) );
+ header->color = QMapNodeBase::Red;
+ header->parent = 0;
+ header->left = header->right = header;
+ node_count = 0;
+ }
+
+ void clear( NodePtr p ) {
+ while ( p != 0 ) {
+ clear( (NodePtr)p->right );
+ NodePtr y = (NodePtr)p->left;
+ delete p;
+ p = y;
+ }
+ }
+
+ Iterator begin() { return Iterator( (NodePtr)(header->left ) ); }
+ Iterator end() { return Iterator( header ); }
+ ConstIterator begin() const { return ConstIterator( (NodePtr)(header->left ) ); }
+ ConstIterator end() const { return ConstIterator( header ); }
+
+ ConstIterator find(const Key& k) const {
+ QMapNodeBase* y = header; // Last node
+ QMapNodeBase* x = header->parent; // Root node.
+
+ while ( x != 0 ) {
+ // If as k <= key(x) go left
+ if ( !( key(x) < k ) ) {
+ y = x;
+ x = x->left;
+ } else {
+ x = x->right;
+ }
+ }
+
+ // Was k bigger/smaller then the biggest/smallest
+ // element of the tree ? Return end()
+ if ( y == header || k < key(y) )
+ return ConstIterator( header );
+ return ConstIterator( (NodePtr)y );
+ }
+
+ void remove( Iterator it ) {
+ NodePtr del = (NodePtr) removeAndRebalance( it.node, header->parent, header->left, header->right );
+ delete del;
+ --node_count;
+ }
+
+#ifdef QT_QMAP_DEBUG
+ void inorder( QMapNodeBase* x = 0, int level = 0 ){
+ if ( !x )
+ x = header->parent;
+ if ( x->left )
+ inorder( x->left, level + 1 );
+ //cout << level << " Key=" << key(x) << " Value=" << ((NodePtr)x)->data << endl;
+ if ( x->right )
+ inorder( x->right, level + 1 );
+ }
+#endif
+
+ Iterator insertMulti(const Key& v){
+ QMapNodeBase* y = header;
+ QMapNodeBase* x = header->parent;
+ while (x != 0){
+ y = x;
+ x = ( v < key(x) ) ? x->left : x->right;
+ }
+ return insert(x, y, v);
+ }
+
+ Iterator insertSingle( const Key& k ) {
+ // Search correct position in the tree
+ QMapNodeBase* y = header;
+ QMapNodeBase* x = header->parent;
+ bool result = TRUE;
+ while ( x != 0 ) {
+ result = ( k < key(x) );
+ y = x;
+ x = result ? x->left : x->right;
+ }
+ // Get iterator on the last not empty one
+ Iterator j( (NodePtr)y );
+ if ( result ) {
+ // Smaller then the leftmost one ?
+ if ( j == begin() ) {
+ return insert(x, y, k );
+ } else {
+ // Perhaps daddy is the right one ?
+ --j;
+ }
+ }
+ // Really bigger ?
+ if ( (j.node->key) < k )
+ return insert(x, y, k );
+ // We are going to replace a node
+ return j;
+ }
+
+ Iterator insert( QMapNodeBase* x, QMapNodeBase* y, const Key& k ) {
+ NodePtr z = new Node( k );
+ if (y == header || x != 0 || k < key(y) ) {
+ y->left = z; // also makes leftmost = z when y == header
+ if ( y == header ) {
+ header->parent = z;
+ header->right = z;
+ } else if ( y == header->left )
+ header->left = z; // maintain leftmost pointing to min node
+ } else {
+ y->right = z;
+ if ( y == header->right )
+ header->right = z; // maintain rightmost pointing to max node
+ }
+ z->parent = y;
+ z->left = 0;
+ z->right = 0;
+ rebalance( z, header->parent );
+ ++node_count;
+ return Iterator(z);
+ }
+
+protected:
+ /**
+ * Helpers
+ */
+ const Key& key( QMapNodeBase* b ) const { return ((NodePtr)b)->key; }
+
+ /**
+ * Variables
+ */
+ NodePtr header;
+};
+
+
+template<class Key, class T>
+class Q_EXPORT QMap
+{
+public:
+ /**
+ * Typedefs
+ */
+ typedef QMapIterator< Key, T > Iterator;
+ typedef QMapConstIterator< Key, T > ConstIterator;
+ typedef T ValueType;
+ typedef QMapPrivate< Key, T > Priv;
+
+ /**
+ * API
+ */
+ QMap() { sh = new QMapPrivate< Key, T >; }
+ QMap( const QMap<Key,T>& m ) { sh = m.sh; sh->ref(); }
+ ~QMap() { if ( sh->deref() ) delete sh; }
+
+ QMap<Key,T>& operator= ( const QMap<Key,T>& m )
+ { m.sh->ref(); if ( sh->deref() ) delete sh; sh = m.sh; return *this; }
+
+ Iterator begin() { detach(); return sh->begin(); }
+ Iterator end() { detach(); return sh->end(); }
+ ConstIterator begin() const { return ((const Priv*)sh)->begin(); }
+ ConstIterator end() const { return ((const Priv*)sh)->end(); }
+
+ Iterator find ( const Key& k )
+ { detach(); return Iterator( sh->find( k ).node ); }
+ ConstIterator find ( const Key& k ) const
+ { return sh->find( k ); }
+ T& operator[] ( const Key& k ) {
+ detach(); QMapNode<Key,T>* p = sh->find( k ).node;
+ if ( p != sh->end().node ) return p->data;
+ return insert( k, T() ).data(); }
+ const T& operator[] ( const Key& k ) const
+ { return sh->find( k ).data(); }
+ bool contains ( const Key& k ) const
+ { return find( k ) != end(); }
+ //{ return sh->find( k ) != ((const Priv*)sh)->end(); }
+
+ uint count() const { return sh->node_count; }
+
+ bool isEmpty() const { return sh->node_count == 0; }
+
+ Iterator insert( const Key& key, const T& value ) {
+ detach();
+ Iterator it = sh->insertSingle( key );
+ it.data() = value;
+ return it;
+ }
+
+ void remove( Iterator it ) { detach(); sh->remove( it ); }
+ void remove( const Key& k ) {
+ detach();
+ Iterator it( sh->find( k ).node );
+ if ( it != end() )
+ sh->remove( it );
+ }
+
+ Iterator replace( const Key& k, const T& v ) {
+ remove( k );
+ return insert( k, v );
+ }
+
+ void clear() { if ( sh->count == 1 ) sh->clear(); else { sh->deref(); sh = new QMapPrivate<Key,T>; } }
+
+#if defined(Q_FULL_TEMPLATE_INSTANTIATION)
+ bool operator==( const QMap<Key,T>& ) const { return FALSE; }
+#endif
+
+protected:
+ /**
+ * Helpers
+ */
+ void detach() { if ( sh->count > 1 ) { sh->deref(); sh = new QMapPrivate<Key,T>( sh ); } }
+
+ Priv* sh;
+};
+
+
+#ifndef QT_NO_DATASTREAM
+template<class Key, class T>
+inline QDataStream& operator>>( QDataStream& s, QMap<Key,T>& m ) {
+ m.clear();
+ Q_UINT32 c;
+ s >> c;
+ for( Q_UINT32 i = 0; i < c; ++i ) {
+ Key k; T t;
+ s >> k >> t;
+ m.insert( k, t );
+ }
+ return s;
+}
+
+
+template<class Key, class T>
+inline QDataStream& operator<<( QDataStream& s, const QMap<Key,T>& m ) {
+ s << (Q_UINT32)m.count();
+ QMapConstIterator<Key,T> it = m.begin();
+ for( ; it != m.end(); ++it )
+ s << it.key() << it.data();
+ return s;
+}
+#endif
+
+#endif // QMAP_H
diff --git a/qtools/qmodules.h b/qtools/qmodules.h
new file mode 100644
index 0000000..08f0baf
--- /dev/null
+++ b/qtools/qmodules.h
@@ -0,0 +1,11 @@
+// These modules are licensed to you
+#define QT_MODULE_TOOLS
+#define QT_MODULE_KERNEL
+#define QT_MODULE_WIDGETS
+#define QT_MODULE_DIALOGS
+#define QT_MODULE_ICONVIEW
+#define QT_MODULE_WORKSPACE
+#define QT_MODULE_NETWORK
+#define QT_MODULE_CANVAS
+#define QT_MODULE_TABLE
+#define QT_MODULE_XML
diff --git a/qtools/qstring.cpp b/qtools/qstring.cpp
index 44d4e6b..85962b2 100644
--- a/qtools/qstring.cpp
+++ b/qtools/qstring.cpp
@@ -367,8 +367,6 @@ __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,
@@ -404,6 +402,8 @@ static const Q_UINT8 ui_00[] = {
16, 16, 16, 16, 16, 16, 16, 16,
};
+#ifndef QT_NO_UNICODETABLES
+
static const Q_UINT8 ui_01[] = {
15, 16, 15, 16, 15, 16, 15, 16,
15, 16, 15, 16, 15, 16, 15, 16,
@@ -11100,19 +11100,7 @@ QChar::Category QChar::category() const
#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 (Category)(ui_00[cell()]);
}
return Letter_Uppercase; //#######
#endif
@@ -12241,6 +12229,7 @@ QString::QString( const QChar* unicode, uint length )
{
if ( !unicode && !length ) {
d = shared_null ? shared_null : makeSharedNull();
+ d->ref();
} else {
QChar* uc = QT_ALLOC_QCHAR_VEC( length );
if ( unicode )
@@ -12295,6 +12284,8 @@ void QString::real_detach()
void QString::deref()
{
if ( d->deref() ) {
+ if ( d == shared_null )
+ shared_null = 0;
delete d;
d = 0; // helps debugging
}
@@ -12749,7 +12740,7 @@ QString &QString::sprintf( const char* cformat, ... )
case 2: ::sprintf( out, in, width, decimals, value ); break;
}
} break;
- case 'e': case 'E': case 'f': case 'g': {
+ case 'e': case 'E': case 'f': case 'g': case 'G': {
double value = va_arg(ap, double);
switch (params) {
case 0: ::sprintf( out, in, value ); break;
@@ -13896,6 +13887,13 @@ ushort QString::toUShort( bool *ok, int base ) const
/*!
Returns the string converted to a <code>int</code> value.
+ \code
+ QString str("FF");
+ bool ok;
+ int hex = str.toInt( &ok, 16 ); // will return 255, and ok set to TRUE
+ int dec = str.toInt( &ok, 10 ); // will return 0, and ok set to FALSE
+ \endcode
+
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.
@@ -14146,8 +14144,8 @@ QString QString::number( uint n, int base )
}
/*!
- This static function returns the printed value of \a n, formatted in the \f
- format with \a prec precision.
+ This static function returns the printed value of \a n, formatted in the
+ \a 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().
@@ -14574,6 +14572,7 @@ QString& QString::setUnicode( const QChar *unicode, uint len )
if ( d != shared_null ) { // beware of nullstring being set to nullstring
deref();
d = shared_null ? shared_null : makeSharedNull();
+ d->ref();
}
} else if ( d->count != 1 || len > d->maxl ||
( len*4 < d->maxl && d->maxl > 4 ) ) { // detach, grown or shrink
@@ -14947,8 +14946,10 @@ QDataStream &operator<<( QDataStream &s, const QString &str )
QDataStream &operator>>( QDataStream &s, QString &str )
{
#ifdef QT_QSTRING_UCS_4
+#if defined(_CC_GNU_)
#warning "operator>> not working properly"
#endif
+#endif
if ( s.version() == 1 ) {
QCString l;
s >> l;
diff --git a/qtools/qstring.h b/qtools/qstring.h
index f955f32..f131446 100644
--- a/qtools/qstring.h
+++ b/qtools/qstring.h
@@ -646,8 +646,11 @@ inline QString::QString() :
//
inline QString::~QString()
{
- if ( d->deref() )
+ if ( d->deref() ) {
+ if ( d == shared_null )
+ shared_null = 0;
d->deleteSelf();
+ }
}
inline QString &QString::operator=( QChar c )
diff --git a/qtools/qtextcodec.cpp b/qtools/qtextcodec.cpp
index af43a3a..9f94cb6 100644
--- a/qtools/qtextcodec.cpp
+++ b/qtools/qtextcodec.cpp
@@ -450,6 +450,9 @@ static const char * const iso8859_2locales[] = {
static const char * const iso8859_3locales[] = {
"eo", 0 };
+static const char * const iso8859_4locales[] = {
+ "ee", "ee_EE", "lt", "lt_LT", "lv", "lv_LV", 0 };
+
static const char * const iso8859_5locales[] = {
"bg", "bg_BG", "bulgarian", "mk", "mk_MK",
"sp", "sp_YU", 0 };
@@ -461,13 +464,19 @@ static const char * const iso8859_7locales[] = {
"el", "el_GR", "greek", 0 };
static const char * const iso8859_8locales[] = {
- "hebrew", "iw", "iw_IL", 0 };
+ "hebrew", "he", "he_IL", "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 };
+ "fr", "fi", "french", "finnish", "et", "et_EE", 0 };
+
+static const char * const koi8_ulocales[] = {
+ "uk", "uk_UA", "ru_UA", "ukrainian", 0 };
+
+static const char * const tis_620locales[] = {
+ "th", "th_TH", "thai", 0 };
static bool try_locale_list( const char * const locale[], const char * lang )
@@ -523,6 +532,11 @@ static QTextCodec * ru_RU_hack( const char * i ) {
static QTextCodec * localeMapper = 0;
+void qt_set_locale_codec( QTextCodec *codec )
+{
+ localeMapper = codec;
+}
+
/*! Returns a pointer to the codec most suitable for this locale. */
QTextCodec* QTextCodec::codecForLocale()
@@ -572,19 +586,25 @@ QTextCodec* QTextCodec::codecForLocale()
localeMapper = codecForName( "ISO 8859-2" );
else if ( try_locale_list( iso8859_3locales, lang ) )
localeMapper = codecForName( "ISO 8859-3" );
+ else if ( try_locale_list( iso8859_4locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-4" );
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" );
+ localeMapper = codecForName( "ISO 8859-6-I" );
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" );
+ localeMapper = codecForName( "ISO 8859-8-I" );
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 ) )
+ else if ( try_locale_list( tis_620locales, lang ) )
+ localeMapper = codecForName( "ISO 8859-11" );
+ else if ( try_locale_list( koi8_ulocales, lang ) )
+ localeMapper = codecForName( "KOI8-U" );
+ 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" );
@@ -1335,6 +1355,25 @@ static struct {
// /**/ - The BULLET OPERATOR is confused. Some people think
// it should be 0x2022 (BULLET).
+ // from RFC 2319, ftp://ftp.isi.edu/in-notes/rfc2319.txt
+ { "KOI8-U", 2088,
+ { 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, 0x0454, 0x2554, 0x0456, 0x0457,
+ 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x0491, 0x255D, 0x255E,
+ 0x255F, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407,
+ 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x0490, 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 } },
+
// 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.
@@ -1342,23 +1381,6 @@ static struct {
// $ 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,
@@ -1512,7 +1534,7 @@ static struct {
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?
+ { "ISO 8859-13", 109,
{ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -1529,7 +1551,7 @@ static struct {
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?
+ { "ISO 8859-14", 110,
{ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -1546,7 +1568,7 @@ static struct {
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?
+ { "ISO 8859-15", 111,
{ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
@@ -1762,6 +1784,8 @@ static struct {
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
+ // change LAST_MIB if you add more, and edit unicodevalues in
+ // kernel/qpsprinter.cpp too.
};
@@ -1787,13 +1811,21 @@ QSimpleTextCodec::~QSimpleTextCodec()
// what happens if strlen(chars)<len? what happens if !chars? if len<1?
QString QSimpleTextCodec::toUnicode(const char* chars, int len) const
{
+ if(len <= 0)
+ return QString::null;
+
+ int clen = qstrlen(chars);
+ len = QMIN(len, clen); // Note: NUL ends string
+
QString r;
+ r.setUnicode(0, len);
+ QChar* uc = (QChar*)r.unicode(); // const_cast
const unsigned char * c = (const unsigned char *)chars;
- for( int i=0; i<len && c[i]; i++ ) { // Note: NUL ends string
+ for( int i=0; i<len; i++ ) {
if ( c[i] > 127 )
- r[i] = unicodevalues[forwardIndex].values[c[i]-128];
+ uc[i] = unicodevalues[forwardIndex].values[c[i]-128];
else
- r[i] = c[i];
+ uc[i] = c[i];
}
return r;
}
@@ -1829,12 +1861,17 @@ QCString QSimpleTextCodec::fromUnicode(const QString& uc, int& len ) const
if ( len <0 || len > (int)uc.length() )
len = uc.length();
QCString r( len+1 );
- int i;
+ int i = len;
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] : '?' );
+ const QChar* ucp = uc.unicode();
+ char* rp = r.data();
+ char* rmp = reverseMap->data();
+ int rmsize = (int) reverseMap->size();
+ while( i-- )
+ {
+ u = ucp->unicode();
+ *rp++ = u < 128 ? u : (( u < rmsize ) ? (*(rmp+u)) : '?' );
+ ucp++;
}
r[len] = 0;
return r;
@@ -1862,7 +1899,9 @@ int QSimpleTextCodec::heuristicNameMatch(const char* hint) const
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);
+ int i = simpleHeuristicNameMatch("tis620-0", hint);
+ if( !i )
+ i = simpleHeuristicNameMatch("tis-620", hint);
if( i ) return i;
}
return QTextCodec::heuristicNameMatch(hint);
@@ -1892,27 +1931,7 @@ int QSimpleTextCodec::heuristicContentMatch(const char* chars, int len) const
}
-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
+#endif // QT_NO_CODECS
class QLatin1Codec: public QTextCodec
{
@@ -1948,12 +1967,10 @@ 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;
+ if(len <= 0)
+ return QString::null;
+
+ return QString::fromLatin1(chars, len);
}
@@ -1962,11 +1979,12 @@ 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 : '?';
+ int i = 0;
+ const QChar *ch = uc.unicode();
+ while ( i < len ) {
+ r[i] = ch->row() ? '?' : ch->cell();
+ i++;
+ ch++;
}
r[len] = 0;
return r;
@@ -1975,7 +1993,7 @@ QCString QLatin1Codec::fromUnicode(const QString& uc, int& len ) const
const char* QLatin1Codec::name() const
{
- return "iso8859-1";
+ return "ISO 8859-1";
}
@@ -2009,11 +2027,28 @@ int QLatin1Codec::heuristicContentMatch(const char* chars, int len) const
}
-
static void setupBuiltinCodecs()
{
(void)new QLatin1Codec;
-}
+
+#ifndef QT_NO_CODECS
+ 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;
#endif // QT_NO_CODECS
+}
#endif // QT_NO_TEXTCODEC
diff --git a/qtools/qtextstream.cpp b/qtools/qtextstream.cpp
index 774b730..6686f81 100644
--- a/qtools/qtextstream.cpp
+++ b/qtools/qtextstream.cpp
@@ -193,10 +193,14 @@ const int QTextStream::floatfield = ( QTextStream::scientific |
class QTextStreamPrivate {
public:
- QTextStreamPrivate(): decoder( 0 ), sourceType( NotSet ) {}
+#ifndef QT_NO_TEXTCODEC
+ QTextStreamPrivate() : decoder( 0 ), sourceType( NotSet ) {}
~QTextStreamPrivate() { delete decoder; }
-
QTextDecoder *decoder; //???
+#else
+ QTextStreamPrivate() : sourceType( NotSet ) {}
+ ~QTextStreamPrivate() { }
+#endif
QString ungetcBuf;
enum SourceType { NotSet, IODevice, String, ByteArray, File };
@@ -664,14 +668,41 @@ uint QTextStream::ts_getbuf( QChar* buf, uint len )
}
}
+#ifndef QT_NO_TEXTCODEC
if ( mapper ) {
+ bool shortRead = FALSE;
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!
+ bool readBlock = !( len == 1+rnum );
+ while ( TRUE ) {
+ // for efficiency: normally read a whole block
+ if ( readBlock ) {
+ // guess buffersize; this may be wrong (too small or too
+ // big). But we can handle this (either iterate reading
+ // or use ungetcBuf).
+ // Note that this might cause problems for codecs where
+ // one byte can result in >1 Unicode Characters if bytes
+ // are written to the stream in the meantime (loss of
+ // synchronicity).
+ uint rlen = len - rnum;
+ char *cbuf = new char[ rlen ];
+ if ( ungetHack != EOF ) {
+ rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
+ cbuf[0] = (char)ungetHack;
+ ungetHack = EOF;
+ } else {
+ rlen = dev->readBlock( cbuf, rlen );
+ }
+ s += d->decoder->toUnicode( cbuf, rlen );
+ delete[] cbuf;
+ // use buffered reading only for the first time, because we
+ // have to get the stream synchronous again (this is easier
+ // with single character reading)
+ readBlock = FALSE;
+ }
+ // get stream (and codec) in sync
int c;
if ( ungetHack == EOF ) {
c = dev->getch();
@@ -679,10 +710,15 @@ uint QTextStream::ts_getbuf( QChar* buf, uint len )
c = ungetHack;
ungetHack = EOF;
}
- if ( c == EOF )
- return rnum;
+ if ( c == EOF ) {
+ shortRead = TRUE;
+ break;
+ }
char b = c;
- s = d->decoder->toUnicode( &b, 1 );
+ uint lengthBefore = s.length();
+ s += d->decoder->toUnicode( &b, 1 );
+ if ( s.length() > lengthBefore )
+ break; // it seems we are in sync now
}
uint i = 0;
while( rnum < len && i < s.length() )
@@ -690,8 +726,12 @@ uint QTextStream::ts_getbuf( QChar* buf, uint len )
if ( s.length() > i )
// could be = but append is clearer
d->ungetcBuf.append( s.mid( i ) );
+ if ( shortRead )
+ return rnum;
}
- } else if ( latin1 ) {
+ } else
+#endif
+ 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)
@@ -699,14 +739,18 @@ uint QTextStream::ts_getbuf( QChar* buf, uint len )
if ( c != EOF )
buf[rnum++] = (char)c;
} else {
- if ( (QChar)ungetHack != QEOF )
+ if ( ungetHack != EOF ) {
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++];
+ ungetHack = EOF;
+ }
+ char *cbuf = new char[len - rnum];
+ while ( !dev->atEnd() && rnum < len ) {
+ uint rlen = len - rnum;
+ rlen = dev->readBlock( cbuf, rlen );
+ uint i = 0;
+ while( i < rlen )
+ buf[rnum++] = cbuf[i++];
+ }
delete[] cbuf;
}
} else { // UCS-2 or UTF-16
@@ -722,29 +766,34 @@ uint QTextStream::ts_getbuf( QChar* buf, uint len )
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;
+ char *cbuf = new char[ 2*( len - rnum ) ]; // for paranoids: overflow possible
+ while ( !dev->atEnd() && rnum < len ) {
+ uint rlen = 2 * ( len-rnum );
+ if ( ungetHack != EOF ) {
+ rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
+ cbuf[0] = (char)ungetHack;
+ ungetHack = EOF;
+ } else {
+ rlen = dev->readBlock( cbuf, rlen );
}
- } else {
- while( i < rlen ) {
- buf[rnum++] = QChar( cbuf[i], cbuf[i+1] );
- i+=2;
+ // We can't use an odd number of bytes, so put it back. But
+ // do it only if we are capable of reading more -- normally
+ // there should not be an odd number, but the file might be
+ // truncated or not in UTF-16...
+ if ( (rlen & 1) == 1 )
+ if ( !dev->atEnd() )
+ 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;
@@ -759,12 +808,15 @@ uint QTextStream::ts_getbuf( QChar* buf, uint len )
*/
void QTextStream::ts_putc( QChar c )
{
+#ifndef QT_NO_TEXTCODEC
if ( mapper ) {
int len = 1;
QString s = c;
QCString block = mapper->fromUnicode( s, len );
dev->writeBlock( block, len );
- } else if ( latin1 ) {
+ } else
+#endif
+ if ( latin1 ) {
if( c.row() )
dev->putch( '?' ); //######unknown character???
else
@@ -820,7 +872,7 @@ void QTextStream::ts_ungetc( QChar c )
The buffer \e s must be preallocated.
- \note No Encoding is done by this function.
+ Note that 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.
@@ -838,7 +890,7 @@ QTextStream &QTextStream::readRawBytes( char *s, uint len )
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.
+ Note that no encoding is done by this function.
\sa QIODevice::writeBlock()
*/
@@ -1428,19 +1480,28 @@ QString QTextStream::readLine()
return QString::null;
}
#endif
- QChar c = ts_getc();
- if ( c == QEOF )
+ QString result( "" );
+ const int buf_size = 256;
+ QChar c[buf_size];
+ int pos = 0;
+
+ c[pos] = ts_getc();
+ if ( c[pos] == QEOF )
return QString::null;
- QString result( "" );
- while ( c != QEOF && c != '\n' ) {
- result += c;
- c = ts_getc();
+ while ( c[pos] != QEOF && c[pos] != '\n' ) {
+ pos++;
+ if ( pos >= buf_size ) {
+ result += QString( c, pos );
+ pos = 0;
+ }
+ c[pos] = ts_getc();
}
+ result += QString( c, pos );
int len = (int)result.length();
if ( len && result[len-1] == '\r' )
- result.truncate(len-1); // (if there are two \r, let one stay)
+ result.truncate(len-1); // (if there are two \r, let one stay)
return result;
}
@@ -1456,7 +1517,7 @@ QString QTextStream::read()
{
#if defined(CHECK_STATE)
if ( !dev ) {
- qWarning( "QTextStream::readLine: No device" );
+ qWarning( "QTextStream::read: No device" );
return QString::null;
}
#endif
@@ -1507,8 +1568,20 @@ QString QTextStream::read()
/*!
Writes a \c char to the stream and returns a reference to the stream.
+
+ The character \a c is assumed to be Latin1 encoded independent of the Encoding set
+ for the QTextStream.
*/
+QTextStream &QTextStream::operator<<( QChar c )
+{
+ CHECK_STREAM_PRECOND
+ ts_putc( c );
+ return *this;
+}
+/*!
+ Writes a \c char to the stream and returns a reference to the stream.
+*/
QTextStream &QTextStream::operator<<( char c )
{
CHECK_STREAM_PRECOND
@@ -1737,6 +1810,9 @@ QTextStream &QTextStream::operator<<( double f )
/*!
Writes a string to the stream and returns a reference to the stream.
+
+ The string \a s is assumed to be Latin1 encoded independent of the Encoding set
+ for the QTextStream.
*/
QTextStream &QTextStream::operator<<( const char* s )
@@ -1774,6 +1850,9 @@ QTextStream &QTextStream::operator<<( const char* s )
/*!
Writes \a s to the stream and returns a reference to the stream.
+
+ The string \a s is assumed to be Latin1 encoded independent of the Encoding set
+ for the QTextStream.
*/
QTextStream &QTextStream::operator<<( const QCString & s )
@@ -2064,11 +2143,12 @@ QTextStream &reset( QTextStream &s )
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.
+ \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.
+ Note that this function should be called before any data is read
+ to/written from the stream.
\sa setCodec()
*/
@@ -2084,10 +2164,16 @@ void QTextStream::setEncoding( Encoding e )
internalOrder = TRUE;
break;
case UnicodeUTF8:
+#ifndef QT_NO_CODECS
mapper = QTextCodec::codecForMib( 106 );
latin1 = FALSE;
doUnicodeHeader = TRUE;
internalOrder = TRUE;
+#else
+ mapper = 0;
+ latin1 = TRUE;
+ doUnicodeHeader = TRUE;
+#endif
break;
case UnicodeNetworkOrder:
mapper = 0;
@@ -2109,12 +2195,14 @@ void QTextStream::setEncoding( Encoding e )
break;
case Locale:
latin1 = TRUE; // fallback to Latin 1
+#ifndef QT_NO_TEXTCODEC
mapper = QTextCodec::codecForLocale();
#if defined(_OS_WIN32_)
if ( GetACP() == 1252 )
mapper = 0; // Optimized latin1 processing
#endif
if ( mapper && mapper->mibEnum() == 4 )
+#endif
mapper = 0; // Optimized latin1 processing
doUnicodeHeader = TRUE; // If it reads as Unicode, accept it
break;
@@ -2127,11 +2215,14 @@ void QTextStream::setEncoding( Encoding e )
}
-/*!
- Sets the codec for this stream to \a codec. Will not try to autodetect Unicode.
+#ifndef QT_NO_TEXTCODEC
+/*! 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()
+ Note that this function should be called before any data is read
+ to/written from the stream.
+
+ \sa setEncoding()
*/
void QTextStream::setCodec( QTextCodec *codec )
@@ -2141,5 +2232,6 @@ void QTextStream::setCodec( QTextCodec *codec )
mapper = codec;
doUnicodeHeader = FALSE;
}
+#endif
#endif // QT_NO_TEXTSTREAM
diff --git a/qtools/qtextstream.h b/qtools/qtextstream.h
index d7adbd3..c5f5ba1 100644
--- a/qtools/qtextstream.h
+++ b/qtools/qtextstream.h
@@ -57,7 +57,10 @@ public:
UnicodeReverse, RawUnicode, UnicodeUTF8 };
void setEncoding( Encoding );
+#ifndef QT_NO_TEXTCODEC
void setCodec( QTextCodec* );
+#endif
+
// Encoding encoding() const { return cmode; }
QTextStream();
@@ -89,6 +92,7 @@ public:
QTextStream &operator>>( QString & );
QTextStream &operator>>( QCString & );
+ QTextStream &operator<<( QChar );
QTextStream &operator<<( char );
QTextStream &operator<<( signed short );
QTextStream &operator<<( unsigned short );
diff --git a/qtools/qtools.pro.in b/qtools/qtools.pro.in
index 17c6626..156ad09 100644
--- a/qtools/qtools.pro.in
+++ b/qtools/qtools.pro.in
@@ -36,7 +36,11 @@ HEADERS = qarray.h \
qtextstream.h \
qtl.h \
qvaluelist.h \
- qvector.h
+ qvector.h \
+ qxml.h \
+ qvaluestack.h \
+ qmap.h \
+ qmodules.h
SOURCES = qbuffer.cpp \
qcollection.cpp \
qcstring.cpp \
@@ -55,7 +59,9 @@ SOURCES = qbuffer.cpp \
qstring.cpp \
qtextstream.cpp \
qtextcodec.cpp \
- qstringlist.cpp
+ qstringlist.cpp \
+ qxml.cpp \
+ qmap.cpp
unix:SOURCES += qfile_unix.cpp \
qdir_unix.cpp \
diff --git a/qtools/qvaluestack.h b/qtools/qvaluestack.h
new file mode 100644
index 0000000..9728d6c
--- /dev/null
+++ b/qtools/qvaluestack.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+**
+** Definition of QValueStack class
+**
+** Created : 990925
+**
+** 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 QVALUESTACK_H
+#define QVALUESTACK_H
+
+#ifndef QT_H
+#include "qvaluelist.h"
+#endif // QT_H
+
+
+template<class T>
+class Q_EXPORT QValueStack : public QValueList<T>
+{
+public:
+ QValueStack() {}
+ ~QValueStack() {}
+ void push( const T& d ) { append(d); }
+ T pop()
+ {
+ T elem( this->last() );
+ if ( !this->isEmpty() )
+ remove( this->fromLast() );
+ return elem;
+ }
+ T& top() { return this->last(); }
+ const T& top() const { return this->last(); }
+};
+
+#endif
diff --git a/qtools/qxml.cpp b/qtools/qxml.cpp
new file mode 100644
index 0000000..d171828
--- /dev/null
+++ b/qtools/qxml.cpp
@@ -0,0 +1,6007 @@
+/****************************************************************************
+**
+**
+** Implementation of QXmlSimpleReader and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the XML module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qxml.h"
+#include "qtextcodec.h"
+#include "qbuffer.h"
+
+#ifndef QT_NO_XML
+// NOT REVISED
+
+// Error strings for the XML reader
+#define XMLERR_OK "no error occured"
+#define XMLERR_TAGMISMATCH "tag mismatch"
+#define XMLERR_UNEXPECTEDEOF "unexpected end of file"
+#define XMLERR_FINISHEDPARSINGWHILENOTEOF "parsing is finished but end of file is not reached"
+#define XMLERR_LETTEREXPECTED "letter is expected"
+#define XMLERR_ERRORPARSINGELEMENT "error while parsing element"
+#define XMLERR_ERRORPARSINGPROLOG "error while parsing prolog"
+#define XMLERR_ERRORPARSINGMAINELEMENT "error while parsing main element"
+#define XMLERR_ERRORPARSINGCONTENT "error while parsing content"
+#define XMLERR_ERRORPARSINGNAME "error while parsing name"
+#define XMLERR_ERRORPARSINGNMTOKEN "error while parsing Nmtoken"
+#define XMLERR_ERRORPARSINGATTRIBUTE "error while parsing attribute"
+#define XMLERR_ERRORPARSINGMISC "error while parsing misc"
+#define XMLERR_ERRORPARSINGCHOICE "error while parsing choice or seq"
+#define XMLERR_ERRORBYCONSUMER "error triggered by consumer"
+#define XMLERR_UNEXPECTEDCHARACTER "unexpected character"
+#define XMLERR_EQUALSIGNEXPECTED "expected '=' but not found"
+#define XMLERR_QUOTATIONEXPECTED "expected \" or ' but not found"
+#define XMLERR_ERRORPARSINGREFERENCE "error while parsing reference"
+#define XMLERR_ERRORPARSINGPI "error while parsing processing instruction"
+#define XMLERR_ERRORPARSINGATTLISTDECL "error while parsing attribute list declaration"
+#define XMLERR_ERRORPARSINGATTTYPE "error while parsing attribute type declaration"
+#define XMLERR_ERRORPARSINGATTVALUE "error while parsing attribute value declaration"
+#define XMLERR_ERRORPARSINGELEMENTDECL "error while parsing element declaration"
+#define XMLERR_ERRORPARSINGENTITYDECL "error while parsing entity declaration"
+#define XMLERR_ERRORPARSINGNOTATIONDECL "error while parsing notation declaration"
+#define XMLERR_ERRORPARSINGEXTERNALID "error while parsing external id"
+#define XMLERR_ERRORPARSINGCOMMENT "error while parsing comment"
+#define XMLERR_ERRORPARSINGENTITYVALUE "error while parsing entity value declaration"
+#define XMLERR_CDSECTHEADEREXPECTED "expected the header for a cdata section"
+#define XMLERR_MORETHANONEDOCTYPE "more than one document type definition"
+#define XMLERR_ERRORPARSINGDOCTYPE "error while parsing document type definition"
+#define XMLERR_INVALIDNAMEFORPI "invalid name for processing instruction"
+#define XMLERR_VERSIONEXPECTED "version expected while reading the XML declaration"
+#define XMLERR_EDECLORSDDECLEXPECTED "EDecl or SDDecl expected while reading the XML declaration"
+#define XMLERR_SDDECLEXPECTED "SDDecl expected while reading the XML declaration"
+#define XMLERR_WRONGVALUEFORSDECL "wrong value for standalone declaration"
+#define XMLERR_UNPARSEDENTITYREFERENCE "unparsed entity reference"
+#define XMLERR_INTERNALGENERALENTITYINDTD "internal general entity reference not allowed in DTD"
+#define XMLERR_EXTERNALGENERALENTITYINDTD "external parsed general entity reference not allowed in DTD"
+#define XMLERR_EXTERNALGENERALENTITYINAV "external parsed general entity reference not allowed in attribute value"
+
+
+// the constants for the lookup table
+static const signed char cltWS = 0; // white space
+static const signed char cltPer = 1; // %
+static const signed char cltAmp = 2; // &
+static const signed char cltGt = 3; // >
+static const signed char cltLt = 4; // <
+static const signed char cltSlash = 5; // /
+static const signed char cltQm = 6; // ?
+static const signed char cltEm = 7; // !
+static const signed char cltDash = 8; // -
+static const signed char cltCB = 9; // ]
+static const signed char cltOB = 10; // [
+static const signed char cltEq = 11; // =
+static const signed char cltDq = 12; // "
+static const signed char cltSq = 13; // '
+static const signed char cltUnknown = 14;
+
+// character lookup table
+static const signed char charLookupTable[256]={
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x00 - 0x07
+ cltUnknown, // 0x08
+ cltWS, // 0x09 \t
+ cltWS, // 0x0A \n
+ cltUnknown, // 0x0B
+ cltUnknown, // 0x0C
+ cltWS, // 0x0D \r
+ cltUnknown, // 0x0E
+ cltUnknown, // 0x0F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x17 - 0x16
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x18 - 0x1F
+ cltWS, // 0x20 Space
+ cltEm, // 0x21 !
+ cltDq, // 0x22 "
+ cltUnknown, // 0x23
+ cltUnknown, // 0x24
+ cltPer, // 0x25 %
+ cltAmp, // 0x26 &
+ cltSq, // 0x27 '
+ cltUnknown, // 0x28
+ cltUnknown, // 0x29
+ cltUnknown, // 0x2A
+ cltUnknown, // 0x2B
+ cltUnknown, // 0x2C
+ cltDash, // 0x2D -
+ cltUnknown, // 0x2E
+ cltSlash, // 0x2F /
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x30 - 0x37
+ cltUnknown, // 0x38
+ cltUnknown, // 0x39
+ cltUnknown, // 0x3A
+ cltUnknown, // 0x3B
+ cltLt, // 0x3C <
+ cltEq, // 0x3D =
+ cltGt, // 0x3E >
+ cltQm, // 0x3F ?
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x40 - 0x47
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x48 - 0x4F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x50 - 0x57
+ cltUnknown, // 0x58
+ cltUnknown, // 0x59
+ cltUnknown, // 0x5A
+ cltOB, // 0x5B [
+ cltUnknown, // 0x5C
+ cltCB, // 0x5D ]
+ cltUnknown, // 0x5E
+ cltUnknown, // 0x5F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x60 - 0x67
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x68 - 0x6F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x70 - 0x77
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x78 - 0x7F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x80 - 0x87
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x88 - 0x8F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x90 - 0x97
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x98 - 0x9F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA0 - 0xA7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA8 - 0xAF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB0 - 0xB7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB8 - 0xBF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC0 - 0xC7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC8 - 0xCF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD0 - 0xD7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD8 - 0xDF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE0 - 0xE7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE8 - 0xEF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xF0 - 0xF7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown // 0xF8 - 0xFF
+};
+
+
+class QXmlNamespaceSupportPrivate
+{
+};
+class QXmlAttributesPrivate
+{
+};
+class QXmlInputSourcePrivate
+{
+};
+class QXmlParseExceptionPrivate
+{
+};
+class QXmlLocatorPrivate
+{
+};
+class QXmlDefaultHandlerPrivate
+{
+};
+
+#if defined(Q_FULL_TEMPLATE_INSTANTIATION)
+bool operator==( const QMap<QString, QString>, const QMap<QString, QString> )
+{
+ return FALSE;
+}
+#endif
+
+/*!
+ \class QXmlParseException qxml.h
+ \brief The QXmlParseException class is used to report errors with the
+ QXmlErrorHandler interface.
+
+ \module XML
+
+ \sa QXmlErrorHandler
+*/
+/*!
+ \fn QXmlParseException::QXmlParseException( const QString& name, int c, int l, const QString& p, const QString& s )
+
+ Constructs a parse exception with the error string \a name in the column
+ \a c and line \a l for the public identifier \a p and the system identifier
+ \a s.
+*/
+/*!
+ Returns the error message.
+*/
+QString QXmlParseException::message() const
+{
+ return msg;
+}
+/*!
+ Returns the column number the error occured.
+*/
+int QXmlParseException::columnNumber() const
+{
+ return column;
+}
+/*!
+ Returns the line number the error occured.
+*/
+int QXmlParseException::lineNumber() const
+{
+ return line;
+}
+/*!
+ Returns the public identifier the error occured.
+*/
+QString QXmlParseException::publicId() const
+{
+ return pub;
+}
+/*!
+ Returns the system identifier the error occured.
+*/
+QString QXmlParseException::systemId() const
+{
+ return sys;
+}
+
+
+/*!
+ \class QXmlLocator qxml.h
+ \brief The QXmlLocator class provides the XML handler classes with
+ information about the actual parsing position.
+
+ \module XML
+
+ The reader reports a QXmlLocator to the content handler before he starts to
+ parse the document. This is done with the
+ QXmlContentHandler::setDocumentLocator() function. The handler classes can
+ now use this locator to get the actual position the reader is at.
+*/
+/*!
+ \fn QXmlLocator::QXmlLocator( QXmlSimpleReader* parent )
+
+ Constructor.
+*/
+/*!
+ \fn QXmlLocator::~QXmlLocator()
+
+ Destructor.
+*/
+/*!
+ Gets the column number (starting with 1) or -1 if there is no column number
+ available.
+*/
+int QXmlLocator::columnNumber()
+{
+ return ( reader->columnNr == -1 ? -1 : reader->columnNr + 1 );
+}
+/*!
+ Gets the line number (starting with 1) or -1 if there is no line number
+ available.
+*/
+int QXmlLocator::lineNumber()
+{
+ return ( reader->lineNr == -1 ? -1 : reader->lineNr + 1 );
+}
+
+
+/*********************************************
+ *
+ * QXmlNamespaceSupport
+ *
+ *********************************************/
+
+/*!
+ \class QXmlNamespaceSupport qxml.h
+ \brief The QXmlNamespaceSupport class is a helper class for XML readers which
+ want to include namespace support.
+
+ \module XML
+
+ It provides some functions that makes it easy to handle namespaces. Its main
+ use is for subclasses of QXmlReader which want to provide namespace
+ support.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+
+/*!
+ Constructs a QXmlNamespaceSupport.
+*/
+QXmlNamespaceSupport::QXmlNamespaceSupport()
+{
+ reset();
+}
+
+/*!
+ Destructs a QXmlNamespaceSupport.
+*/
+QXmlNamespaceSupport::~QXmlNamespaceSupport()
+{
+}
+
+/*!
+ This function declares a prefix in the current namespace context; the prefix
+ will remain in force until this context is popped, unless it is shadowed in a
+ descendant context.
+
+ Note that there is an asymmetry in this library: while prefix() will not
+ return the default "" prefix, even if you have declared one; to check for a
+ default prefix, you have to look it up explicitly using uri(). This
+ asymmetry exists to make it easier to look up prefixes for attribute names,
+ where the default prefix is not allowed.
+*/
+void QXmlNamespaceSupport::setPrefix( const QString& pre, const QString& uri )
+{
+ if( pre.isNull() ) {
+ ns.insert( "", uri );
+ } else {
+ ns.insert( pre, uri );
+ }
+}
+
+/*!
+ Returns one of the prefixes mapped to a namespace URI.
+
+ If more than one prefix is currently mapped to the same URI, this function
+ will make an arbitrary selection; if you want all of the prefixes, use the
+ prefixes() function instead.
+
+ Note: this will never return the empty (default) prefix; to check for a
+ default prefix, use the uri() function with an argument of "".
+*/
+QString QXmlNamespaceSupport::prefix( const QString& uri ) const
+{
+ QMap<QString, QString>::ConstIterator itc, it = ns.begin();
+ while ( (itc=it) != ns.end() ) {
+ ++it;
+ if ( itc.data() == uri && !itc.key().isEmpty() )
+ return itc.key();
+ }
+ return "";
+}
+
+/*!
+ Looks up a prefix in the current context and returns the currently-mapped
+ namespace URI. Use the empty string ("") for the default namespace.
+*/
+QString QXmlNamespaceSupport::uri( const QString& prefix ) const
+{
+ const QString& returi = ns[ prefix ];
+ return returi;
+}
+
+/*!
+ Splits the name at the ':' and returns the prefix and the local name.
+*/
+void QXmlNamespaceSupport::splitName( const QString& qname,
+ QString& prefix, QString& localname ) const
+{
+ uint pos;
+ // search the ':'
+ for( pos=0; pos<qname.length(); pos++ ) {
+ if ( qname.at(pos) == ':' )
+ break;
+ }
+ // and split
+ prefix = qname.left( pos );
+ localname = qname.mid( pos+1 );
+}
+
+/*!
+ Processes a raw XML 1.0 name in the current context by removing the prefix
+ and looking it up among the prefixes currently declared.
+
+ First parameter is the raw XML 1.0 name to be processed. The second parameter
+ is a flag wheter the name is the name of an attribute (TRUE) or not (FALSE).
+
+ The return values will be stored in the last two parameters as follows:
+ <ul>
+ <li> The namespace URI, or an empty string if none is in use.
+ <li> The local name (without prefix).
+ </ul>
+
+ If the raw name has a prefix that has not been declared, then the return
+ value will be empty.
+
+ Note that attribute names are processed differently than element names: an
+ unprefixed element name will received the default namespace (if any), while
+ an unprefixed element name will not
+*/
+void QXmlNamespaceSupport::processName( const QString& qname,
+ bool isAttribute,
+ QString& nsuri, QString& localname ) const
+{
+ uint pos;
+ // search the ':'
+ for( pos=0; pos<qname.length(); pos++ ) {
+ if ( qname.at(pos) == ':' )
+ break;
+ }
+ if ( pos < qname.length() ) {
+ // there was a ':'
+ nsuri = uri( qname.left( pos ) );
+ localname = qname.mid( pos+1 );
+ } else {
+ // there was no ':'
+ if ( isAttribute ) {
+ nsuri = ""; // attributes don't take default namespace
+ } else {
+ nsuri = uri( "" ); // get default namespace
+ }
+ localname = qname;
+ }
+}
+
+/*!
+ Returns an enumeration of all prefixes currently declared.
+
+ Note: if there is a default prefix, it will not be returned in this
+ enumeration; check for the default prefix using uri() with an argument
+ of "".
+*/
+QStringList QXmlNamespaceSupport::prefixes() const
+{
+ QStringList list;
+
+ QMap<QString, QString>::ConstIterator itc, it = ns.begin();
+ while ( (itc=it) != ns.end() ) {
+ ++it;
+ if ( !itc.key().isEmpty() )
+ list.append( itc.key() );
+ }
+ return list;
+}
+
+/*!
+ Returns a list of all prefixes currently declared for a URI.
+
+ The xml: prefix will be included. If you want only one prefix that's
+ mapped to the namespace URI, and you don't care which one you get, use the
+ prefix() function instead.
+
+ Note: the empty (default) prefix is never included in this enumeration; to
+ check for the presence of a default namespace, use uri() with an
+ argument of "".
+*/
+QStringList QXmlNamespaceSupport::prefixes( const QString& uri ) const
+{
+ QStringList list;
+
+ QMap<QString, QString>::ConstIterator itc, it = ns.begin();
+ while ( (itc=it) != ns.end() ) {
+ ++it;
+ if ( itc.data() == uri && !itc.key().isEmpty() )
+ list.append( itc.key() );
+ }
+ return list;
+}
+
+/*!
+ Starts a new namespace context.
+
+ Normally, you should push a new context at the beginning of each XML element:
+ the new context will automatically inherit the declarations of its parent
+ context, but it will also keep track of which declarations were made within
+ this context.
+*/
+void QXmlNamespaceSupport::pushContext()
+{
+ nsStack.push( ns );
+}
+
+/*!
+ Reverts to the previous namespace context.
+
+ Normally, you should pop the context at the end of each XML element. After
+ popping the context, all namespace prefix mappings that were previously in
+ force are restored.
+*/
+void QXmlNamespaceSupport::popContext()
+{
+ if( !nsStack.isEmpty() )
+ ns = nsStack.pop();
+}
+
+/*!
+ Resets this namespace support object for reuse.
+*/
+void QXmlNamespaceSupport::reset()
+{
+ nsStack.clear();
+ ns.clear();
+ ns.insert( "xml", "http://www.w3.org/XML/1998/namespace" ); // the XML namespace
+}
+
+
+
+/*********************************************
+ *
+ * QXmlAttributes
+ *
+ *********************************************/
+
+/*!
+ \class QXmlAttributes qxml.h
+ \brief The QXmlAttributes class provides XML attributes.
+
+ \module XML
+
+ If attributes are reported by QXmlContentHandler::startElement() this
+ class is used to pass the attribute values. It provides you with different
+ functions to access the attribute names and values.
+*/
+/*!
+ \fn QXmlAttributes::QXmlAttributes()
+
+ Constructs an empty attribute list.
+*/
+/*!
+ \fn QXmlAttributes::~QXmlAttributes()
+
+ Destructs attributes.
+*/
+
+/*!
+ Look up the index of an attribute by an XML 1.0 qualified name.
+
+ Returns the index of the attribute (starting with 0) or -1 if it wasn't
+ found.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+int QXmlAttributes::index( const QString& qName ) const
+{
+ return qnameList.findIndex( qName );
+}
+
+/*!
+ Looks up the index of an attribute by a namespace name.
+
+ \a uri specifies the namespace URI, or the empty string if the name has no
+ namespace URI. \a localPart specifies the attribute's local name.
+
+ Returns the index of the attribute (starting with 0) or -1 if it wasn't
+ found.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+int QXmlAttributes::index( const QString& uri, const QString& localPart ) const
+{
+ uint count = uriList.count();
+ for ( uint i=0; i<count; i++ ) {
+ if ( uriList[i] == uri && localnameList[i] == localPart )
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ Returns the number of attributes in the list.
+*/
+int QXmlAttributes::length() const
+{
+ return valueList.count();
+}
+
+/*!
+ Looks up an attribute's local name by index (starting with 0).
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::localName( int index ) const
+{
+ return localnameList[index];
+}
+
+/*!
+ Looks up an attribute's XML 1.0 qualified name by index (starting with 0).
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::qName( int index ) const
+{
+ return qnameList[index];
+}
+
+/*!
+ Looks up an attribute's namespace URI by index (starting with 0).
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::uri( int index ) const
+{
+ return uriList[index];
+}
+
+/*!
+ Looks up an attribute's type by index (starting with 0).
+
+ At the moment only 'CDATA' is returned.
+*/
+QString QXmlAttributes::type( int ) const
+{
+ return "CDATA";
+}
+
+/*!
+ Looks up an attribute's type by XML 1.0 qualified name.
+
+ At the moment only 'CDATA' is returned.
+*/
+QString QXmlAttributes::type( const QString& ) const
+{
+ return "CDATA";
+}
+
+/*!
+ Looks up an attribute's type by namespace name.
+
+ The first parameter specifies the namespace URI, or the empty string if
+ the name has no namespace URI. The second parameter specifies the
+ attribute's local name.
+
+ At the moment only 'CDATA' is returned.
+*/
+QString QXmlAttributes::type( const QString&, const QString& ) const
+{
+ return "CDATA";
+}
+
+/*!
+ Looks up an attribute's value by index (starting with 0).
+*/
+QString QXmlAttributes::value( int index ) const
+{
+ return valueList[index];
+}
+
+/*!
+ Looks up an attribute's value by XML 1.0 qualified name.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::value( const QString& qName ) const
+{
+ int i = index( qName );
+ if ( i == -1 )
+ return QString::null;
+ return valueList[ i ];
+}
+
+/*!
+ Looks up an attribute's value by namespace name.
+
+ \a uri specifies the namespace URI, or the empty string if the name has no
+ namespace URI. \a localName specifies the attribute's local name.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+*/
+QString QXmlAttributes::value( const QString& uri, const QString& localName ) const
+{
+ int i = index( uri, localName );
+ if ( i == -1 )
+ return QString::null;
+ return valueList[ i ];
+}
+
+
+/*********************************************
+ *
+ * QXmlInputSource
+ *
+ *********************************************/
+
+/*!
+ \class QXmlInputSource qxml.h
+ \brief The QXmlInputSource class is the source where XML data is read from.
+
+ \module XML
+
+ All subclasses of QXmlReader read the input from this class.
+*/
+
+/*!
+ Returns all the data this input source contains.
+*/
+const QString& QXmlInputSource::data() const
+{
+ return input;
+}
+
+/*!
+ Constructs a input source which contains no data.
+*/
+QXmlInputSource::QXmlInputSource( )
+{
+ input = "";
+}
+
+/*!
+ Constructs a input source and get the data from the text stream.
+*/
+QXmlInputSource::QXmlInputSource( QTextStream& stream )
+{
+ QByteArray rawData;
+ if ( stream.device()->isDirectAccess() ) {
+ rawData = stream.device()->readAll();
+ } else {
+ int nread = 0;
+ const int bufsize = 512;
+ while ( !stream.device()->atEnd() ) {
+ rawData.resize( nread + bufsize );
+ nread += stream.device()->readBlock( rawData.data()+nread, bufsize );
+ }
+ rawData.resize( nread );
+ }
+ readInput( rawData );
+}
+
+/*!
+ Constructs a input source and get the data from a file. If the file cannot be
+ read the input source is empty.
+*/
+QXmlInputSource::QXmlInputSource( QFile& file )
+{
+ if ( !file.open(IO_ReadOnly) ) {
+ input = "";
+ return;
+ }
+ QByteArray rawData = file.readAll();
+ readInput( rawData );
+ file.close();
+}
+
+/*!
+ Destructor.
+*/
+QXmlInputSource::~QXmlInputSource()
+{
+}
+
+/*!
+ Sets the data of the input source to \a dat.
+*/
+void QXmlInputSource::setData( const QString& dat )
+{
+ input = dat;
+}
+
+/*!
+ Read the XML file from the byte array; try to recoginize the encoding.
+*/
+// ### The input source should not do the encoding detection!
+void QXmlInputSource::readInput( QByteArray& rawData )
+{
+ QBuffer buf( rawData );
+ buf.open( IO_ReadOnly );
+ QTextStream *stream = new QTextStream( &buf );
+ QChar tmp;
+ // assume UTF8 or UTF16 at first
+ stream->setEncoding( QTextStream::UnicodeUTF8 );
+ input = "";
+ // read the first 5 characters
+ for ( int i=0; i<5; i++ ) {
+ *stream >> tmp;
+ input += tmp;
+ }
+ // starts the document with an XML declaration?
+ if ( input == "<?xml" ) {
+ // read the whole XML declaration
+ do {
+ *stream >> tmp;
+ input += tmp;
+ } while( tmp != '>' );
+ // and try to find out if there is an encoding
+ int pos = input.find( "encoding" );
+ if ( pos != -1 ) {
+ QString encoding;
+ do {
+ pos++;
+ if ( pos > (int)input.length() )
+ goto finished;
+ } while( input[pos] != '"' && input[pos] != '\'' );
+ pos++;
+ while( input[pos] != '"' && input[pos] != '\'' ) {
+ encoding += input[pos];
+ pos++;
+ if ( pos > (int)input.length() )
+ goto finished;
+ }
+ delete stream;
+ stream = new QTextStream( &buf );
+ stream->setCodec( QTextCodec::codecForName( encoding ) );
+ buf.reset();
+ input = "";
+ }
+ }
+finished:
+ input += stream->read();
+ delete stream;
+ buf.close();
+}
+
+
+/*********************************************
+ *
+ * QXmlDefaultHandler
+ *
+ *********************************************/
+
+/*!
+ \class QXmlContentHandler qxml.h
+ \brief The QXmlContentHandler class provides an interface to report logical
+ content of XML data.
+
+ \module XML
+
+ If the application needs to be informed of basic parsing events, it
+ implements this interface and sets it with QXmlReader::setContentHandler().
+ The reader reports basic document-related events like the start and end of
+ elements and character data through this interface.
+
+ The order of events in this interface is very important, and mirrors the
+ order of information in the document itself. For example, all of an element's
+ content (character data, processing instructions, and/or subelements) will
+ appear, in order, between the startElement() event and the corresponding
+ endElement() event.
+
+ The class QXmlDefaultHandler gives a default implementation for this
+ interface; subclassing from this class is very convenient if you want only be
+ informed of some parsing events.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlEntityResolver QXmlErrorHandler
+ QXmlLexicalHandler
+*/
+/*!
+ \fn void QXmlContentHandler::setDocumentLocator( QXmlLocator* locator )
+
+ The reader calls this function before he starts parsing the document. The
+ argument \a locator is a pointer to a QXmlLocator which allows the
+ application to get the actual position of the parsing in the document.
+
+ Do not destroy the \a locator; it is destroyed when the reader is destroyed
+ (do not use the \a locator after the reader got destroyed).
+*/
+/*!
+ \fn bool QXmlContentHandler::startDocument()
+
+ The reader calls this function when he starts parsing the document.
+ The reader will call this function only once before any other functions in
+ this class or in the QXmlDTDHandler class are called (except
+ QXmlContentHandler::setDocumentLocator()).
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa endDocument()
+*/
+/*!
+ \fn bool QXmlContentHandler::endDocument()
+
+ The reader calls this function after he has finished the parsing. It
+ is only called once. It is the last function of all handler functions that is
+ called. It is called after the reader has read all input or has abandoned
+ parsing because of a fatal error.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa startDocument()
+*/
+/*!
+ \fn bool QXmlContentHandler::startPrefixMapping( const QString& prefix, const QString& uri )
+
+ The reader calls this function to signal the begin of a prefix-URI
+ namespace mapping scope. This information is not necessary for normal
+ namespace processing since the reader automatically replaces prefixes for
+ element and attribute names.
+
+ Note that startPrefixMapping and endPrefixMapping calls are not guaranteed to
+ be properly nested relative to each-other: all startPrefixMapping events will
+ occur before the corresponding startElement event, and all endPrefixMapping
+ events will occur after the corresponding endElement event, but their order
+ is not otherwise guaranteed.
+
+ The argument \a prefix is the namespace prefix being declared and the
+ argument \a uri is the namespace URI the prefix is mapped to.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+ \sa endPrefixMapping()
+*/
+/*!
+ \fn bool QXmlContentHandler::endPrefixMapping( const QString& prefix )
+
+ The reader calls this function to signal the end of a prefix mapping.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+ \sa startPrefixMapping()
+*/
+/*!
+ \fn bool QXmlContentHandler::startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts )
+
+ The reader calls this function when he has parsed a start element tag.
+
+ There will be a corresponding endElement() call when the corresponding end
+ element tag was read. The startElement() and endElement() calls are always
+ nested correctly. Empty element tags (e.g. &lt;a/&gt;) are reported by
+ startElement() directly followed by a call to endElement().
+
+ The attribute list provided will contain only attributes with explicit
+ values. The attribute list will contain attributes used for namespace
+ declaration (i.e. attributes starting with xmlns) only if the
+ namespace-prefix property of the reader is TRUE.
+
+ The argument \a uri is the namespace URI, or the empty string if the element
+ has no namespace URI or if namespace processing is not being performed, \a
+ localName is the local name (without prefix), or the empty string if
+ namespace processing is not being performed, \a qName is the qualified name
+ (with prefix), or the empty string if qualified names are not available and
+ \a atts are the attributes attached to the element. If there are no
+ attributes, \a atts is an empty attributes object
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+ \sa endElement()
+*/
+/*!
+ \fn bool QXmlContentHandler::endElement( const QString& namespaceURI, const QString& localName, const QString& qName )
+
+ The reader calls this function when he has parsed an end element tag.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ See also the <a href="xml-sax.html#namespaces">namespace description</a>.
+
+ \sa startElement()
+*/
+/*!
+ \fn bool QXmlContentHandler::characters( const QString& ch )
+
+ The reader calls this function when he has parsed a chunk of character
+ data (either normal character data or character data inside a CDATA section;
+ if you have to distinguish between those two types you have to use
+ QXmlLexicalHandler::startCDATA() and QXmlLexicalHandler::endCDATA() in
+ addition).
+
+ Some readers will report whitespace in element content using the
+ ignorableWhitespace() function rather than this one (QXmlSimpleReader will
+ do it not though).
+
+ A reader is allowed to report the character data of an element in more than
+ one chunk; e.g. a reader might want to report "a &amp;lt; b" in three
+ characters() events ("a ", "<" and " b").
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlContentHandler::ignorableWhitespace( const QString& ch )
+
+ Some readers may use this function to report each chunk of whitespace in
+ element content (QXmlSimpleReader does not though).
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlContentHandler::processingInstruction( const QString& target, const QString& data )
+
+ The reader calls this function when he has parsed a processing
+ instruction.
+
+ \a target is the target name of the processing instruction and \a data is the
+ data of the processing instruction.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlContentHandler::skippedEntity( const QString& name )
+
+ Some readers may skip entities if they have not seen the declarations (e.g.
+ because they are in an external DTD). If they do so they will report it by
+ calling this function.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlContentHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlErrorHandler qxml.h
+ \brief The QXmlErrorHandler class provides an interface to report errors in
+ XML data.
+
+ \module XML
+
+ If the application is interested in reporting errors to the user or any other
+ customized error handling, you should subclass this class.
+
+ You can set the error handler with QXmlReader::setErrorHandler().
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
+ QXmlLexicalHandler
+*/
+/*!
+ \fn bool QXmlErrorHandler::warning( const QXmlParseException& exception )
+
+ A reader might use this function to report a warning. Warnings are conditions
+ that are not errors or fatal errors as defined by the XML 1.0 specification.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlErrorHandler::error( const QXmlParseException& exception )
+
+ A reader might use this function to report a recoverable error. A recoverable
+ error corresponds to the definiton of "error" in section 1.2 of the XML 1.0
+ specification.
+
+ The reader must continue to provide normal parsing events after invoking this
+ function.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlErrorHandler::fatalError( const QXmlParseException& exception )
+
+ A reader must use this function to report a non-recoverable error.
+
+ If this function returns TRUE the reader might try to go on parsing and
+ reporting further errors; but no regular parsing events are reported.
+*/
+/*!
+ \fn QString QXmlErrorHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlDTDHandler qxml.h
+ \brief The QXmlDTDHandler class provides an interface to report DTD content
+ of XML data.
+
+ \module XML
+
+ If an application needs information about notations and unparsed entities,
+ then the application implements this interface and registers an instance with
+ QXmlReader::setDTDHandler().
+
+ Note that this interface includes only those DTD events that the XML
+ recommendation requires processors to report: notation and unparsed entity
+ declarations.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDeclHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler
+ QXmlLexicalHandler
+*/
+/*!
+ \fn bool QXmlDTDHandler::notationDecl( const QString& name, const QString& publicId, const QString& systemId )
+
+ The reader calls this function when he has parsed a notation
+ declaration.
+
+ The argument \a name is the notation name, \a publicId is the notations's
+ public identifier and \a systemId is the notations's system identifier.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlDTDHandler::unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName )
+
+ The reader calls this function when he finds an unparsed entity declaration.
+
+ The argument \a name is the unparsed entity's name, \a publicId is the
+ entity's public identifier, \a systemId is the entity's system identifier and
+ \a notation is the name of the associated notation.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlDTDHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlEntityResolver qxml.h
+ \brief The QXmlEntityResolver class provides an interface to resolve extern
+ entities contained in XML data.
+
+ \module XML
+
+ If an application needs to implement customized handling for external
+ entities, it must implement this interface and register it with
+ QXmlReader::setEntityResolver().
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlErrorHandler
+ QXmlLexicalHandler
+*/
+/*!
+ \fn bool QXmlEntityResolver::resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* ret )
+
+ The reader will call this function before he opens any external entity,
+ except the top-level document entity. The application may request the reader
+ to resolve the entity itself (\a ret is 0) or to use an entirely different
+ input source (\a ret points to the input source).
+
+ The reader will delete the input source \a ret when he no longer needs it. So
+ you should allocate it on the heap with \c new.
+
+ The argument \a publicId is the public identifier of the external entity, \a
+ systemId is the system identifier of the external entity and \a ret is the
+ return value of this function: if it is 0 the reader should resolve the
+ entity itself, if it is non-zero it must point to an input source which the
+ reader will use instead.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlEntityResolver::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlLexicalHandler qxml.h
+ \brief The QXmlLexicalHandler class provides an interface to report lexical
+ content of XML data.
+
+ \module XML
+
+ The events in the lexical handler apply to the entire document, not just to
+ the document element, and all lexical handler events appear between the
+ content handler's startDocument and endDocument events.
+
+ You can set the lexical handler with QXmlReader::setLexicalHandler().
+
+ This interface is designed after the SAX2 extension LexicalHandler. The
+ functions startEntity() and endEntity() are not included though.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
+ QXmlErrorHandler
+*/
+/*!
+ \fn bool QXmlLexicalHandler::startDTD( const QString& name, const QString& publicId, const QString& systemId )
+
+ The reader calls this function to report the start of a DTD declaration, if
+ any.
+
+ All declarations reported through QXmlDTDHandler or QXmlDeclHandler appear
+ between the startDTD() and endDTD() calls.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa endDTD()
+*/
+/*!
+ \fn bool QXmlLexicalHandler::endDTD()
+
+ The reader calls this function to report the end of a DTD declaration, if
+ any.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa startDTD()
+*/
+/*!
+ \fn bool QXmlLexicalHandler::startCDATA()
+
+ The reader calls this function to report the start of a CDATA section. The
+ content of the CDATA section will be reported through the regular
+ QXmlContentHandler::characters(). This function is intended only to report
+ the boundary.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa endCDATA()
+*/
+/*!
+ \fn bool QXmlLexicalHandler::endCDATA()
+
+ The reader calls this function to report the end of a CDATA section.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+
+ \sa startCDATA()
+*/
+/*!
+ \fn bool QXmlLexicalHandler::comment( const QString& ch )
+
+ The reader calls this function to report an XML comment anywhere in the
+ document.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlLexicalHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlDeclHandler qxml.h
+ \brief The QXmlDeclHandler class provides an interface to report declaration
+ content of XML data.
+
+ \module XML
+
+ You can set the declaration handler with QXmlReader::setDeclHandler().
+
+ This interface is designed after the SAX2 extension DeclHandler.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlContentHandler QXmlEntityResolver QXmlErrorHandler
+ QXmlLexicalHandler
+*/
+/*!
+ \fn bool QXmlDeclHandler::attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value )
+
+ The reader calls this function to report an attribute type declaration. Only
+ the effective (first) declaration for an attribute will be reported.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlDeclHandler::internalEntityDecl( const QString& name, const QString& value )
+
+ The reader calls this function to report an internal entity declaration. Only
+ the effective (first) declaration will be reported.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn bool QXmlDeclHandler::externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId )
+
+ The reader calls this function to report a parsed external entity
+ declaration. Only the effective (first) declaration for each entity will be
+ reported.
+
+ If this function returns FALSE the reader will stop parsing and will report
+ an error. The reader will use the function errorString() to get the error
+ message that will be used for reporting the error.
+*/
+/*!
+ \fn QString QXmlDeclHandler::errorString()
+
+ The reader calls this function to get an error string if any of the handler
+ functions returns FALSE to him.
+*/
+
+
+/*!
+ \class QXmlDefaultHandler qxml.h
+ \brief The QXmlDefaultHandler class provides a default implementation of all
+ XML handler classes.
+
+ \module XML
+
+ Very often you are only interested in parts of the things that that the
+ reader reports to you. This class simply implements a default behaviour of
+ the handler classes (most of the time: do nothing). Normally this is the
+ class you subclass for implementing your customized handler.
+
+ See also the <a href="xml.html#introSAX2">Introduction to SAX2</a>.
+
+ \sa QXmlDTDHandler QXmlDeclHandler QXmlContentHandler QXmlEntityResolver
+ QXmlErrorHandler QXmlLexicalHandler
+*/
+/*!
+ \fn QXmlDefaultHandler::QXmlDefaultHandler()
+
+ Constructor.
+*/
+/*!
+ \fn QXmlDefaultHandler::~QXmlDefaultHandler()
+
+ Destructor.
+*/
+
+/*!
+ Does nothing.
+*/
+void QXmlDefaultHandler::setDocumentLocator( QXmlLocator* )
+{
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startDocument()
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endDocument()
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startPrefixMapping( const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endPrefixMapping( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startElement( const QString&, const QString&,
+ const QString&, const QXmlAttributes& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endElement( const QString&, const QString&,
+ const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::characters( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::ignorableWhitespace( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::processingInstruction( const QString&,
+ const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::skippedEntity( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::warning( const QXmlParseException& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::error( const QXmlParseException& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::fatalError( const QXmlParseException& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::notationDecl( const QString&, const QString&,
+ const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::unparsedEntityDecl( const QString&, const QString&,
+ const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Always sets \a ret to 0, so that the reader will use the system identifier
+ provided in the XML document.
+*/
+bool QXmlDefaultHandler::resolveEntity( const QString&, const QString&,
+ QXmlInputSource* ret )
+{
+ ret = 0;
+ return TRUE;
+}
+
+/*!
+ Returns the default error string.
+*/
+QString QXmlDefaultHandler::errorString()
+{
+ return QString( XMLERR_ERRORBYCONSUMER );
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startDTD( const QString&, const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endDTD()
+{
+ return TRUE;
+}
+
+#if 0
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startEntity( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endEntity( const QString& )
+{
+ return TRUE;
+}
+#endif
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::startCDATA()
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::endCDATA()
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::comment( const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::attributeDecl( const QString&, const QString&, const QString&, const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::internalEntityDecl( const QString&, const QString& )
+{
+ return TRUE;
+}
+
+/*!
+ Does nothing.
+*/
+bool QXmlDefaultHandler::externalEntityDecl( const QString&, const QString&, const QString& )
+{
+ return TRUE;
+}
+
+
+/*********************************************
+ *
+ * QXmlSimpleReaderPrivate
+ *
+ *********************************************/
+
+class QXmlSimpleReaderPrivate
+{
+private:
+ // constructor
+ QXmlSimpleReaderPrivate()
+ { }
+
+
+ // used for entity declarations
+ struct ExternParameterEntity
+ {
+ ExternParameterEntity( ) {}
+ ExternParameterEntity( const QString &p, const QString &s )
+ : publicId(p), systemId(s) {}
+ QString publicId;
+ QString systemId;
+ };
+ struct ExternEntity
+ {
+ ExternEntity( ) {}
+ ExternEntity( const QString &p, const QString &s, const QString &n )
+ : publicId(p), systemId(s), notation(n) {}
+ QString publicId;
+ QString systemId;
+ QString notation;
+ };
+ QMap<QString,ExternParameterEntity> externParameterEntities;
+ QMap<QString,QString> parameterEntities;
+ QMap<QString,ExternEntity> externEntities;
+ QMap<QString,QString> entities;
+
+ // used for standalone declaration
+ enum Standalone { Yes, No, Unknown };
+
+ QString doctype; // only used for the doctype
+ QString xmlVersion; // only used to store the version information
+ QString encoding; // only used to store the encoding
+ Standalone standalone; // used to store the value of the standalone declaration
+
+ QString publicId; // used by parseExternalID() to store the public ID
+ QString systemId; // used by parseExternalID() to store the system ID
+ QString attDeclEName; // use by parseAttlistDecl()
+ QString attDeclAName; // use by parseAttlistDecl()
+
+ // flags for some features support
+ bool useNamespaces;
+ bool useNamespacePrefixes;
+ bool reportWhitespaceCharData;
+
+ // used to build the attribute list
+ QXmlAttributes attList;
+
+ // helper classes
+ QXmlLocator *locator;
+ QXmlNamespaceSupport namespaceSupport;
+
+ // error string
+ QString error;
+
+ // friend declarations
+ friend class QXmlSimpleReader;
+};
+
+
+/*********************************************
+ *
+ * QXmlSimpleReader
+ *
+ *********************************************/
+
+/*!
+ \class QXmlReader qxml.h
+ \brief The QXmlReader class provides an interface for XML readers (i.e.
+ parsers).
+
+ \module XML
+
+ This abstract class describes an interface for all XML readers in Qt. At the
+ moment there is only one implementation of a reader included in the XML
+ module of Qt (QXmlSimpleReader). In future releases there might be more
+ readers with different properties available (e.g. a validating parser).
+
+ The design of the XML classes follow the
+ <a href="http://www.megginson.com/SAX/">SAX2 java interface</a>.
+ It was adopted to fit into the Qt naming conventions; so it should be very
+ easy for anybody who has worked with SAX2 to get started with the Qt XML
+ classes.
+
+ All readers use the class QXmlInputSource to read the input document from.
+ Since you are normally interested in certain contents of the XML document,
+ the reader reports those contents through special handler classes
+ (QXmlDTDHandler, QXmlDeclHandler, QXmlContentHandler, QXmlEntityResolver,
+ QXmlErrorHandler and QXmlLexicalHandler).
+
+ You have to subclass these classes. Since the handler classes describe only
+ interfaces you must implement all functions; there is a class
+ (QXmlDefaultHandler) to make this easier; it implements a default behaviour
+ (do nothing) for all functions.
+
+ For getting started see also the
+ <a href="xml-sax.html#quickStart">Quick start</a>.
+
+ \sa QXmlSimpleReader
+*/
+/*!
+ \fn bool QXmlReader::feature( const QString& name, bool *ok ) const
+
+ If the reader has the feature \a name, this function returns the value of the
+ feature.
+
+ If the reader has not the feature \a name, the return value may be anything.
+
+ If \a ok is not 0, then \a ok is set to TRUE if the reader has the feature
+ \a name, otherwise \a ok is set to FALSE.
+
+ \sa setFeature() hasFeature()
+*/
+/*!
+ \fn void QXmlReader::setFeature( const QString& name, bool value )
+
+ Sets the feature \a name to \a value. If the reader has not the feature \a
+ name, this value is ignored.
+
+ \sa feature() hasFeature()
+*/
+/*!
+ \fn bool QXmlReader::hasFeature( const QString& name ) const
+
+ Returns \c TRUE if the reader has the feature \a name, otherwise FALSE.
+
+ \sa feature() setFeature()
+*/
+/*!
+ \fn void* QXmlReader::property( const QString& name, bool *ok ) const
+
+ If the reader has the property \a name, this function returns the value of
+ the property.
+
+ If the reader has not the property \a name, the return value is 0.
+
+ If \a ok is not 0, then \a ok is set to TRUE if the reader has the property
+ \a name, otherwise \a ok is set to FALSE.
+
+ \sa setProperty() hasProperty()
+*/
+/*!
+ \fn void QXmlReader::setProperty( const QString& name, void* value )
+
+ Sets the property \a name to \a value. If the reader has not the property \a
+ name, this value is ignored.
+
+ \sa property() hasProperty()
+*/
+/*!
+ \fn bool QXmlReader::hasProperty( const QString& name ) const
+
+ Returns TRUE if the reader has the property \a name, otherwise FALSE.
+
+ \sa property() setProperty()
+*/
+/*!
+ \fn void QXmlReader::setEntityResolver( QXmlEntityResolver* handler )
+
+ Sets the entity resolver to \a handler.
+
+ \sa entityResolver()
+*/
+/*!
+ \fn QXmlEntityResolver* QXmlReader::entityResolver() const
+
+ Returns the entity resolver or 0 if none was set.
+
+ \sa setEntityResolver()
+*/
+/*!
+ \fn void QXmlReader::setDTDHandler( QXmlDTDHandler* handler )
+
+ Sets the DTD handler to \a handler.
+
+ \sa DTDHandler()
+*/
+/*!
+ \fn QXmlDTDHandler* QXmlReader::DTDHandler() const
+
+ Returns the DTD handler or 0 if none was set.
+
+ \sa setDTDHandler()
+*/
+/*!
+ \fn void QXmlReader::setContentHandler( QXmlContentHandler* handler )
+
+ Sets the content handler to \a handler.
+
+ \sa contentHandler()
+*/
+/*!
+ \fn QXmlContentHandler* QXmlReader::contentHandler() const
+
+ Returns the content handler or 0 if none was set.
+
+ \sa setContentHandler()
+*/
+/*!
+ \fn void QXmlReader::setErrorHandler( QXmlErrorHandler* handler )
+
+ Sets the error handler to \a handler.
+
+ \sa errorHandler()
+*/
+/*!
+ \fn QXmlErrorHandler* QXmlReader::errorHandler() const
+
+ Returns the error handler or 0 if none was set
+
+ \sa setErrorHandler()
+*/
+/*!
+ \fn void QXmlReader::setLexicalHandler( QXmlLexicalHandler* handler )
+
+ Sets the lexical handler to \a handler.
+
+ \sa lexicalHandler()
+*/
+/*!
+ \fn QXmlLexicalHandler* QXmlReader::lexicalHandler() const
+
+ Returns the lexical handler or 0 if none was set.
+
+ \sa setLexicalHandler()
+*/
+/*!
+ \fn void QXmlReader::setDeclHandler( QXmlDeclHandler* handler )
+
+ Sets the declaration handler to \a handler.
+
+ \sa declHandler()
+*/
+/*!
+ \fn QXmlDeclHandler* QXmlReader::declHandler() const
+
+ Returns the declaration handler or 0 if none was set.
+
+ \sa setDeclHandler()
+*/
+/*!
+ \fn bool QXmlReader::parse( const QXmlInputSource& input )
+
+ Parses the XML document \a input. Returns TRUE if the parsing was successful,
+ otherwise FALSE.
+*/
+/*!
+ \fn bool QXmlReader::parse( const QString& systemId )
+
+ Parses the XML document at the location \a systemId. Returns TRUE if the
+ parsing was successful, otherwise FALSE.
+*/
+
+
+/*!
+ \class QXmlSimpleReader qxml.h
+ \brief The QXmlSimpleReader class provides an implementation of a simple XML
+ reader (i.e. parser).
+
+ \module XML
+
+ This XML reader is sufficient for simple parsing tasks. Here is a short list
+ of the properties of this reader:
+ <ul>
+ <li> well-formed parser
+ <li> does not parse any external entities
+ <li> can do namespace processing
+ </ul>
+
+ For getting started see also the
+ <a href="xml-sax.html#quickStart">Quick start</a>.
+*/
+
+//guaranteed not to be a characater
+const QChar QXmlSimpleReader::QEOF = QChar((ushort)0xffff);
+
+/*!
+ Constructs a simple XML reader.
+*/
+QXmlSimpleReader::QXmlSimpleReader()
+{
+ d = new QXmlSimpleReaderPrivate();
+ d->locator = new QXmlLocator( this );
+
+ entityRes = 0;
+ dtdHnd = 0;
+ contentHnd = 0;
+ errorHnd = 0;
+ lexicalHnd = 0;
+ declHnd = 0;
+
+ // default feature settings
+ d->useNamespaces = TRUE;
+ d->useNamespacePrefixes = FALSE;
+ d->reportWhitespaceCharData = TRUE;
+}
+
+/*!
+ Destroys a simple XML reader.
+*/
+QXmlSimpleReader::~QXmlSimpleReader()
+{
+ delete d->locator;
+ delete d;
+}
+
+/*!
+ Gets the state of a feature.
+
+ \sa setFeature() hasFeature()
+*/
+bool QXmlSimpleReader::feature( const QString& name, bool *ok ) const
+{
+ if ( ok != 0 )
+ *ok = TRUE;
+ if ( name == "http://xml.org/sax/features/namespaces" ) {
+ return d->useNamespaces;
+ } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
+ return d->useNamespacePrefixes;
+ } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+ return d->reportWhitespaceCharData;
+ } else {
+ qWarning( "Unknown feature " + name );
+ if ( ok != 0 )
+ *ok = FALSE;
+ }
+ return FALSE;
+}
+
+/*!
+ Sets the state of a feature.
+
+ Supported features are:
+ <ul>
+ <li> http://xml.org/sax/features/namespaces:
+ if this feature is TRUE, namespace processing is performed
+ <li> http://xml.org/sax/features/namespace-prefixes:
+ if this feature is TRUE, the the original prefixed names and attributes
+ used for namespace declarations are reported
+ <li> http://trolltech.com/xml/features/report-whitespace-only-CharData:
+ if this feature is TRUE, CharData that consists only of whitespace (and
+ no other characters) is not reported via
+ QXmlContentHandler::characters()
+ </ul>
+
+ \sa feature() hasFeature()
+*/
+void QXmlSimpleReader::setFeature( const QString& name, bool value )
+{
+ if ( name == "http://xml.org/sax/features/namespaces" ) {
+ d->useNamespaces = value;
+ } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
+ d->useNamespacePrefixes = value;
+ } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+ d->reportWhitespaceCharData = value;
+ } else {
+ qWarning( "Unknown feature " + name );
+ }
+}
+
+/*!
+ Returns TRUE if the class has a feature named \a feature, otherwise FALSE.
+
+ \sa setFeature() feature()
+*/
+bool QXmlSimpleReader::hasFeature( const QString& name ) const
+{
+ if ( name == "http://xml.org/sax/features/namespaces" ||
+ name == "http://xml.org/sax/features/namespace-prefixes" ||
+ name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/*!
+ Returns 0 since this class does not support any properties.
+*/
+void* QXmlSimpleReader::property( const QString&, bool *ok ) const
+{
+ if ( ok != 0 )
+ *ok = FALSE;
+ return 0;
+}
+
+/*!
+ Does nothing since this class does not support any properties.
+*/
+void QXmlSimpleReader::setProperty( const QString&, void* )
+{
+}
+
+/*!
+ Returns FALSE since this class does not support any properties.
+*/
+bool QXmlSimpleReader::hasProperty( const QString& ) const
+{
+ return FALSE;
+}
+
+/*! \reimp */
+void QXmlSimpleReader::setEntityResolver( QXmlEntityResolver* handler )
+{ entityRes = handler; }
+
+/*! \reimp */
+QXmlEntityResolver* QXmlSimpleReader::entityResolver() const
+{ return entityRes; }
+
+/*! \reimp */
+void QXmlSimpleReader::setDTDHandler( QXmlDTDHandler* handler )
+{ dtdHnd = handler; }
+
+/*! \reimp */
+QXmlDTDHandler* QXmlSimpleReader::DTDHandler() const
+{ return dtdHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setContentHandler( QXmlContentHandler* handler )
+{ contentHnd = handler; }
+
+/*! \reimp */
+QXmlContentHandler* QXmlSimpleReader::contentHandler() const
+{ return contentHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setErrorHandler( QXmlErrorHandler* handler )
+{ errorHnd = handler; }
+
+/*! \reimp */
+QXmlErrorHandler* QXmlSimpleReader::errorHandler() const
+{ return errorHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setLexicalHandler( QXmlLexicalHandler* handler )
+{ lexicalHnd = handler; }
+
+/*! \reimp */
+QXmlLexicalHandler* QXmlSimpleReader::lexicalHandler() const
+{ return lexicalHnd; }
+
+/*! \reimp */
+void QXmlSimpleReader::setDeclHandler( QXmlDeclHandler* handler )
+{ declHnd = handler; }
+
+/*! \reimp */
+QXmlDeclHandler* QXmlSimpleReader::declHandler() const
+{ return declHnd; }
+
+
+
+/*! \reimp */
+bool QXmlSimpleReader::parse( const QXmlInputSource& input )
+{
+ init( input );
+ // call the handler
+ if ( contentHnd ) {
+ contentHnd->setDocumentLocator( d->locator );
+ if ( !contentHnd->startDocument() ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ // parse prolog
+ if ( !parseProlog() ) {
+ d->error = XMLERR_ERRORPARSINGPROLOG;
+ goto parseError;
+ }
+ // parse element
+ if ( !parseElement() ) {
+ d->error = XMLERR_ERRORPARSINGMAINELEMENT;
+ goto parseError;
+ }
+ // parse Misc*
+ while ( !atEnd() ) {
+ if ( !parseMisc() ) {
+ d->error = XMLERR_ERRORPARSINGMISC;
+ goto parseError;
+ }
+ }
+ // is stack empty?
+ if ( !tags.isEmpty() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ if ( !contentHnd->endDocument() ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+
+ return TRUE;
+
+ // error handling
+
+parseError:
+ reportParseError();
+ tags.clear();
+ return FALSE;
+}
+
+/*!
+ Parses the prolog [22].
+*/
+bool QXmlSimpleReader::parseProlog()
+{
+ bool xmldecl_possible = TRUE;
+ bool doctype_read = FALSE;
+
+ const signed char Init = 0;
+ const signed char EatWS = 1; // eat white spaces
+ const signed char Lt = 2; // '<' read
+ const signed char Em = 3; // '!' read
+ const signed char DocType = 4; // read doctype
+ const signed char Comment = 5; // read comment
+ const signed char PI = 6; // read PI
+ const signed char Done = 7;
+
+ const signed char InpWs = 0;
+ const signed char InpLt = 1; // <
+ const signed char InpQm = 2; // ?
+ const signed char InpEm = 3; // !
+ const signed char InpD = 4; // D
+ const signed char InpDash = 5; // -
+ const signed char InpUnknown = 6;
+
+ // use some kind of state machine for parsing
+ static signed char table[7][7] = {
+ /* InpWs InpLt InpQm InpEm InpD InpDash InpUnknown */
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // Init
+ { -1, Lt, -1, -1, -1, -1, -1 }, // EatWS
+ { -1, -1, PI, Em, Done, -1, Done }, // Lt
+ { -1, -1, -1, -1, DocType, Comment, -1 }, // Em
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // DocType
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // Comment
+ { EatWS, Lt, -1, -1, -1, -1, -1 } // PI
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // read input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '<' ) {
+ input = InpLt;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '!' ) {
+ input = InpEm;
+ } else if ( c == 'D' ) {
+ input = InpD;
+ } else if ( c == '-' ) {
+ input = InpDash;
+ } else {
+ input = InpUnknown;
+ }
+ // get new state
+ state = table[state][input];
+
+ // in some cases do special actions depending on state
+ switch ( state ) {
+ case EatWS:
+ // XML declaration only on first position possible
+ xmldecl_possible = FALSE;
+ // eat white spaces
+ eat_ws();
+ break;
+ case Lt:
+ // next character
+ next();
+ break;
+ case Em:
+ // XML declaration only on first position possible
+ xmldecl_possible = FALSE;
+ // next character
+ next();
+ break;
+ case DocType:
+ parseOk = parseDoctype();
+ break;
+ case Comment:
+ parseOk = parseComment();
+ break;
+ case PI:
+ parseOk = parsePI( xmldecl_possible );
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case DocType:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPROLOG;
+ goto parseError;
+ }
+ if ( doctype_read ) {
+ d->error = XMLERR_MORETHANONEDOCTYPE;
+ goto parseError;
+ } else {
+ doctype_read = FALSE;
+ }
+ break;
+ case Comment:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPROLOG;
+ goto parseError;
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case PI:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPROLOG;
+ goto parseError;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ if ( xmldecl_possible && !d->xmlVersion.isEmpty() ) {
+ QString value( "version = '" );
+ value += d->xmlVersion;
+ value += "'";
+ if ( !d->encoding.isEmpty() ) {
+ value += " encoding = '";
+ value += d->encoding;
+ value += "'";
+ }
+ if ( d->standalone == QXmlSimpleReaderPrivate::Yes ) {
+ value += " standalone = 'yes'";
+ } else if ( d->standalone == QXmlSimpleReaderPrivate::No ) {
+ value += " standalone = 'no'";
+ }
+ if ( !contentHnd->processingInstruction( "xml", value ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ } else {
+ if ( !contentHnd->processingInstruction( name(), string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ // XML declaration only on first position possible
+ xmldecl_possible = FALSE;
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ d->error = XMLERR_ERRORPARSINGELEMENT;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse an element [39].
+
+ Precondition: the opening '<' is already read.
+*/
+bool QXmlSimpleReader::parseElement()
+{
+ static QString uri, lname, prefix;
+ static bool t;
+
+ const signed char Init = 0;
+ const signed char ReadName = 1;
+ const signed char Ws1 = 2;
+ const signed char STagEnd = 3;
+ const signed char STagEnd2 = 4;
+ const signed char ETagBegin = 5;
+ const signed char ETagBegin2 = 6;
+ const signed char Ws2 = 7;
+ const signed char EmptyTag = 8;
+ const signed char Attribute = 9;
+ const signed char Ws3 = 10;
+ const signed char Done = 11;
+
+ const signed char InpWs = 0; // whitespace
+ const signed char InpNameBe = 1; // is_NameBeginning()
+ const signed char InpGt = 2; // >
+ const signed char InpSlash = 3; // /
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static signed char table[11][5] = {
+ /* InpWs InpNameBe InpGt InpSlash InpUnknown */
+ { -1, ReadName, -1, -1, -1 }, // Init
+ { Ws1, Attribute, STagEnd, EmptyTag, -1 }, // ReadName
+ { -1, Attribute, STagEnd, EmptyTag, -1 }, // Ws1
+ { STagEnd2, STagEnd2, STagEnd2, STagEnd2, STagEnd2 }, // STagEnd
+ { -1, -1, -1, ETagBegin, -1 }, // STagEnd2
+ { -1, ETagBegin2, -1, -1, -1 }, // ETagBegin
+ { Ws2, -1, Done, -1, -1 }, // ETagBegin2
+ { -1, -1, Done, -1, -1 }, // Ws2
+ { -1, -1, Done, -1, -1 }, // EmptyTag
+ { Ws3, Attribute, STagEnd, EmptyTag, -1 }, // Attribute
+ { -1, Attribute, STagEnd, EmptyTag, -1 } // Ws3
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // read input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( is_NameBeginning(c) ) {
+ input = InpNameBe;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == '/' ) {
+ input = InpSlash;
+ } else {
+ input = InpUnknown;
+ }
+ // get new state
+//qDebug( "%d -%d(%c)-> %d", state, input, c.latin1(), table[state][input] );
+ state = table[state][input];
+
+ // in some cases do special actions depending on state
+ switch ( state ) {
+ case ReadName:
+ parseOk = parseName();
+ break;
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ eat_ws();
+ break;
+ case STagEnd:
+ // call the handler
+ if ( contentHnd ) {
+ if ( d->useNamespaces ) {
+ d->namespaceSupport.processName( tags.top(), FALSE, uri, lname );
+ t = contentHnd->startElement( uri, lname, tags.top(), d->attList );
+ } else {
+ t = contentHnd->startElement( "", "", tags.top(), d->attList );
+ }
+ if ( !t ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ next();
+ break;
+ case STagEnd2:
+ parseOk = parseContent();
+ break;
+ case ETagBegin:
+ next();
+ break;
+ case ETagBegin2:
+ // get the name of the tag
+ parseOk = parseName();
+ break;
+ case EmptyTag:
+ if ( tags.isEmpty() ) {
+ d->error = XMLERR_TAGMISMATCH;
+ goto parseError;
+ }
+ if ( !parseElementEmptyTag( t, uri, lname ) )
+ goto parseError;
+ // next character
+ next();
+ break;
+ case Attribute:
+ // get name and value of attribute
+ parseOk = parseAttribute();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case ReadName:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ // store it on the stack
+ tags.push( name() );
+ // empty the attributes
+ d->attList.qnameList.clear();
+ d->attList.uriList.clear();
+ d->attList.localnameList.clear();
+ d->attList.valueList.clear();
+ // namespace support?
+ if ( d->useNamespaces ) {
+ d->namespaceSupport.pushContext();
+ }
+ break;
+ case STagEnd2:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCONTENT;
+ goto parseError;
+ }
+ break;
+ case ETagBegin2:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ if ( !parseElementETagBegin2() )
+ goto parseError;
+ break;
+ case Attribute:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTRIBUTE;
+ goto parseError;
+ }
+ if ( !parseElementAttribute( prefix, uri, lname ) )
+ goto parseError;
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ d->error = XMLERR_ERRORPARSINGELEMENT;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+/*!
+ Helper to break down the size of the code in the case statement.
+ Return FALSE on error, otherwise TRUE.
+*/
+bool QXmlSimpleReader::parseElementEmptyTag( bool &t, QString &uri, QString &lname )
+{
+ // pop the stack and call the handler
+ if ( contentHnd ) {
+ // report startElement first...
+ if ( d->useNamespaces ) {
+ d->namespaceSupport.processName( tags.top(), FALSE, uri, lname );
+ t = contentHnd->startElement( uri, lname, tags.top(), d->attList );
+ } else {
+ t = contentHnd->startElement( "", "", tags.top(), d->attList );
+ }
+ if ( !t ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ // ... followed by endElement
+ // ### missing namespace support!
+ if ( !contentHnd->endElement( "","",tags.pop() ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ // namespace support?
+ if ( d->useNamespaces ) {
+ QStringList prefixesBefore, prefixesAfter;
+ if ( contentHnd ) {
+ prefixesBefore = d->namespaceSupport.prefixes();
+ }
+ d->namespaceSupport.popContext();
+ // call the handler for prefix mapping
+ if ( contentHnd ) {
+ prefixesAfter = d->namespaceSupport.prefixes();
+ for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
+ if ( prefixesAfter.contains(*it) == 0 ) {
+ if ( !contentHnd->endPrefixMapping( *it ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ tags.pop();
+ }
+ return TRUE;
+}
+/*!
+ Helper to break down the size of the code in the case statement.
+ Return FALSE on error, otherwise TRUE.
+*/
+bool QXmlSimpleReader::parseElementETagBegin2()
+{
+
+ // pop the stack and compare it with the name
+ if ( tags.pop() != name() ) {
+ d->error = XMLERR_TAGMISMATCH;
+ return FALSE;
+ }
+ // call the handler
+ // ### missing namespace support!
+ if ( contentHnd ) {
+ if ( !contentHnd->endElement("","",name()) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ // namespace support?
+ if ( d->useNamespaces ) {
+ QStringList prefixesBefore, prefixesAfter;
+ if ( contentHnd ) {
+ prefixesBefore = d->namespaceSupport.prefixes();
+ }
+ d->namespaceSupport.popContext();
+ // call the handler for prefix mapping
+ if ( contentHnd ) {
+ prefixesAfter = d->namespaceSupport.prefixes();
+ for ( QStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
+ if ( prefixesAfter.contains(*it) == 0 ) {
+ if ( !contentHnd->endPrefixMapping( *it ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+/*!
+ Helper to break down the size of the code in the case statement.
+ Return FALSE on error, otherwise TRUE.
+*/
+bool QXmlSimpleReader::parseElementAttribute( QString &prefix, QString &uri, QString &lname )
+{
+ // add the attribute to the list
+ if ( d->useNamespaces ) {
+ // is it a namespace declaration?
+ d->namespaceSupport.splitName( name(), prefix, lname );
+ if ( prefix == "xmlns" ) {
+ // namespace declaration
+ d->namespaceSupport.setPrefix( lname, string() );
+ if ( d->useNamespacePrefixes ) {
+ d->attList.qnameList.append( name() );
+ d->attList.uriList.append( "" );
+ d->attList.localnameList.append( "" );
+ d->attList.valueList.append( string() );
+ }
+ // call the handler for prefix mapping
+ if ( contentHnd ) {
+ if ( !contentHnd->startPrefixMapping( lname, string() ) ) {
+ d->error = contentHnd->errorString();
+ return FALSE;
+ }
+ }
+ } else {
+ // no namespace delcaration
+ d->namespaceSupport.processName( name(), TRUE, uri, lname );
+ d->attList.qnameList.append( name() );
+ d->attList.uriList.append( uri );
+ d->attList.localnameList.append( lname );
+ d->attList.valueList.append( string() );
+ }
+ } else {
+ // no namespace support
+ d->attList.qnameList.append( name() );
+ d->attList.uriList.append( "" );
+ d->attList.localnameList.append( "" );
+ d->attList.valueList.append( string() );
+ }
+ return TRUE;
+}
+
+/*!
+ Parse a content [43].
+
+ A content is only used between tags. If a end tag is found the < is already
+ read and the head stand on the '/' of the end tag '</name>'.
+*/
+bool QXmlSimpleReader::parseContent()
+{
+ bool charDataRead = FALSE;
+
+ const signed char Init = 0;
+ const signed char ChD = 1; // CharData
+ const signed char ChD1 = 2; // CharData help state
+ const signed char ChD2 = 3; // CharData help state
+ const signed char Ref = 4; // Reference
+ const signed char Lt = 5; // '<' read
+ const signed char PI = 6; // PI
+ const signed char Elem = 7; // Element
+ const signed char Em = 8; // '!' read
+ const signed char Com = 9; // Comment
+ const signed char CDS = 10; // CDSect
+ const signed char CDS1 = 11; // read a CDSect
+ const signed char CDS2 = 12; // read a CDSect (help state)
+ const signed char CDS3 = 13; // read a CDSect (help state)
+ const signed char Done = 14; // finished reading content
+
+ const signed char InpLt = 0; // <
+ const signed char InpGt = 1; // >
+ const signed char InpSlash = 2; // /
+ const signed char InpQMark = 3; // ?
+ const signed char InpEMark = 4; // !
+ const signed char InpAmp = 5; // &
+ const signed char InpDash = 6; // -
+ const signed char InpOpenB = 7; // [
+ const signed char InpCloseB = 8; // ]
+ const signed char InpUnknown = 9;
+
+ static signed char mapCLT2FSMChar[] = {
+ InpUnknown, // white space
+ InpUnknown, // %
+ InpAmp, // &
+ InpGt, // >
+ InpLt, // <
+ InpSlash, // /
+ InpQMark, // ?
+ InpEMark, // !
+ InpDash, // -
+ InpCloseB, // ]
+ InpOpenB, // [
+ InpUnknown, // =
+ InpUnknown, // "
+ InpUnknown, // '
+ InpUnknown // unknown
+ };
+
+ // use some kind of state machine for parsing
+ static signed char const table[14][10] = {
+ /* InpLt InpGt InpSlash InpQMark InpEMark InpAmp InpDash InpOpenB InpCloseB InpUnknown */
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // Init
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // ChD
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD1
+ { Lt, -1, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD2
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Ref (same as Init)
+ { -1, -1, Done, PI, Em, -1, -1, -1, -1, Elem }, // Lt
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PI (same as Init)
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Elem (same as Init)
+ { -1, -1, -1, -1, -1, -1, Com, CDS, -1, -1 }, // Em
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Com (same as Init)
+ { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS
+ { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS1
+ { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 }, // CDS2
+ { CDS1, Init, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 } // CDS3
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input (use lookup-table instead of nested ifs for performance
+ // reasons)
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c.row() ) {
+ input = InpUnknown;
+ } else {
+ input = mapCLT2FSMChar[ charLookupTable[ c.cell() ] ];
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Init:
+ // next character
+ next();
+ break;
+ case ChD:
+ // on first call: clear string
+ if ( !charDataRead ) {
+ charDataRead = TRUE;
+ stringClear();
+ }
+ stringAddC();
+ next();
+ break;
+ case ChD1:
+ // on first call: clear string
+ if ( !charDataRead ) {
+ charDataRead = TRUE;
+ stringClear();
+ }
+ stringAddC();
+ next();
+ break;
+ case ChD2:
+ stringAddC();
+ next();
+ break;
+ case Ref:
+ // reference may be CharData; so clear string to be safe
+ if ( !charDataRead) {
+ charDataRead = TRUE;
+ stringClear();
+ }
+ // parse reference
+ parseOk = parseReference( charDataRead, InContent );
+ break;
+ case Lt:
+ // call the handler for CharData
+ if ( contentHnd ) {
+ if ( charDataRead ) {
+ if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+ if ( !contentHnd->characters( string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ }
+ charDataRead = FALSE;
+ // next character
+ next();
+ break;
+ case PI:
+ parseOk = parsePI();
+ break;
+ case Elem:
+ parseOk = parseElement();
+ break;
+ case Em:
+ // next character
+ next();
+ break;
+ case Com:
+ parseOk = parseComment();
+ break;
+ case CDS:
+ parseOk = parseString( "[CDATA[" );
+ break;
+ case CDS1:
+ // read one character and add it
+ stringAddC();
+ next();
+ break;
+ case CDS2:
+ // skip ']'
+ next();
+ break;
+ case CDS3:
+ // skip ']'...
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Ref:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ break;
+ case PI:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPI;
+ goto parseError;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ if ( !contentHnd->processingInstruction(name(),string()) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case Elem:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGELEMENT;
+ goto parseError;
+ }
+ break;
+ case Com:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCOMMENT;
+ goto parseError;
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case CDS:
+ if( !parseOk ) {
+ d->error = XMLERR_CDSECTHEADEREXPECTED;
+ goto parseError;
+ }
+ // empty string
+ stringClear();
+ break;
+ case CDS2:
+ if (c != ']') {
+ stringAddC( ']' );
+ }
+ break;
+ case CDS3:
+ // test if this skipping was legal
+ if ( c == '>' ) {
+ // the end of the CDSect
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->startCDATA() ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ if ( contentHnd ) {
+ if ( !contentHnd->characters( string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->endCDATA() ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ } else if (c == ']') {
+ // three or more ']'
+ stringAddC( ']' );
+ } else {
+ // after ']]' comes another character
+ stringAddC( ']' );
+ stringAddC( ']' );
+ }
+ break;
+ case Done:
+ // call the handler for CharData
+ if ( contentHnd ) {
+ if ( charDataRead ) {
+ if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+ if ( !contentHnd->characters( string() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ }
+ // Done
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_ERRORPARSINGCONTENT;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse Misc [27].
+*/
+bool QXmlSimpleReader::parseMisc()
+{
+ const signed char Init = 0;
+ const signed char Lt = 1; // '<' was read
+ const signed char Comment = 2; // read comment
+ const signed char eatWS = 3; // eat whitespaces
+ const signed char PI = 4; // read PI
+ const signed char Comment2 = 5; // read comment
+
+ const signed char InpWs = 0; // S
+ const signed char InpLt = 1; // <
+ const signed char InpQm = 2; // ?
+ const signed char InpEm = 3; // !
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static signed char table[3][5] = {
+ /* InpWs InpLt InpQm InpEm InpUnknown */
+ { eatWS, Lt, -1, -1, -1 }, // Init
+ { -1, -1, PI, Comment, -1 }, // Lt
+ { -1, -1, -1, -1, Comment2 } // Comment
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '<' ) {
+ input = InpLt;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '!' ) {
+ input = InpEm;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case eatWS:
+ eat_ws();
+ break;
+ case Lt:
+ next();
+ break;
+ case PI:
+ parseOk = parsePI();
+ break;
+ case Comment:
+ next();
+ break;
+ case Comment2:
+ parseOk = parseComment();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case eatWS:
+ return TRUE;
+ case PI:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPI;
+ goto parseError;
+ }
+ return TRUE;
+ case Comment2:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCOMMENT;
+ goto parseError;
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a processing instruction [16].
+
+ If xmldec is TRUE, it tries to parse a PI or a XML declaration [23].
+
+ Precondition: the beginning '<' of the PI is already read and the head stand
+ on the '?' of '<?'.
+
+ If this funktion was successful, the head-position is on the first
+ character after the PI.
+*/
+bool QXmlSimpleReader::parsePI( bool xmldecl )
+{
+ const signed char Init = 0;
+ const signed char QmI = 1; // ? was read
+ const signed char Name = 2; // read Name
+ const signed char XMLDecl = 3; // read XMLDecl
+ const signed char Ws1 = 4; // eat ws after "xml" of XMLDecl
+ const signed char PI = 5; // read PI
+ const signed char Ws2 = 6; // eat ws after Name of PI
+ const signed char Version = 7; // read versionInfo
+ const signed char Ws3 = 8; // eat ws after versionInfo
+ const signed char EorSD = 9; // read EDecl or SDDecl
+ const signed char Ws4 = 10; // eat ws after EDecl or SDDecl
+ const signed char SD = 11; // read SDDecl
+ const signed char Ws5 = 12; // eat ws after SDDecl
+ const signed char ADone = 13; // almost done
+ const signed char Char = 14; // Char was read
+ const signed char Qm = 15; // Qm was read
+ const signed char Done = 16; // finished reading content
+
+ const signed char InpWs = 0; // whitespace
+ const signed char InpNameBe = 1; // is_nameBeginning()
+ const signed char InpGt = 2; // >
+ const signed char InpQm = 3; // ?
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static signed char table[16][5] = {
+ /* InpWs, InpNameBe InpGt InpQm InpUnknown */
+ { -1, -1, -1, QmI, -1 }, // Init
+ { -1, Name, -1, -1, -1 }, // QmI
+ { -1, -1, -1, -1, -1 }, // Name (this state is left not through input)
+ { Ws1, -1, -1, -1, -1 }, // XMLDecl
+ { -1, Version, -1, -1, -1 }, // Ws1
+ { Ws2, -1, -1, Qm, -1 }, // PI
+ { Char, Char, Char, Qm, Char }, // Ws2
+ { Ws3, -1, -1, ADone, -1 }, // Version
+ { -1, EorSD, -1, ADone, -1 }, // Ws3
+ { Ws4, -1, -1, ADone, -1 }, // EorSD
+ { -1, SD, -1, ADone, -1 }, // Ws4
+ { Ws5, -1, -1, ADone, -1 }, // SD
+ { -1, -1, -1, ADone, -1 }, // Ws5
+ { -1, -1, Done, -1, -1 }, // ADone
+ { Char, Char, Char, Qm, Char }, // Char
+ { Char, Char, Done, Qm, Char }, // Qm
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( is_NameBeginning(c) ) {
+ input = InpNameBe;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case QmI:
+ next();
+ break;
+ case Name:
+ parseOk = parseName();
+ break;
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ case Ws4:
+ case Ws5:
+ eat_ws();
+ break;
+ case Version:
+ parseOk = parseAttribute();
+ break;
+ case EorSD:
+ parseOk = parseAttribute();
+ break;
+ case SD:
+ // get the SDDecl (syntax like an attribute)
+ if ( d->standalone != QXmlSimpleReaderPrivate::Unknown ) {
+ // already parsed the standalone declaration
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ parseOk = parseAttribute();
+ break;
+ case ADone:
+ next();
+ break;
+ case Char:
+ stringAddC();
+ next();
+ break;
+ case Qm:
+ // skip the '?'
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ // test what name was read and determine the next state
+ // (not very beautiful, I admit)
+ if ( name().lower() == "xml" ) {
+ if ( xmldecl && name()=="xml" ) {
+ state = XMLDecl;
+ } else {
+ d->error = XMLERR_INVALIDNAMEFORPI;
+ goto parseError;
+ }
+ } else {
+ state = PI;
+ stringClear();
+ }
+ break;
+ case Version:
+ // get version (syntax like an attribute)
+ if ( !parseOk ) {
+ d->error = XMLERR_VERSIONEXPECTED;
+ goto parseError;
+ }
+ if ( name() != "version" ) {
+ d->error = XMLERR_VERSIONEXPECTED;
+ goto parseError;
+ }
+ d->xmlVersion = string();
+ break;
+ case EorSD:
+ // get the EDecl or SDDecl (syntax like an attribute)
+ if ( !parseOk ) {
+ d->error = XMLERR_EDECLORSDDECLEXPECTED;
+ goto parseError;
+ }
+ if ( name() == "standalone" ) {
+ if ( string()=="yes" ) {
+ d->standalone = QXmlSimpleReaderPrivate::Yes;
+ } else if ( string()=="no" ) {
+ d->standalone = QXmlSimpleReaderPrivate::No;
+ } else {
+ d->error = XMLERR_WRONGVALUEFORSDECL;
+ goto parseError;
+ }
+ } else if ( name() == "encoding" ) {
+ d->encoding = string();
+ } else {
+ d->error = XMLERR_EDECLORSDDECLEXPECTED;
+ goto parseError;
+ }
+ break;
+ case SD:
+ if ( !parseOk ) {
+ d->error = XMLERR_SDDECLEXPECTED;
+ goto parseError;
+ }
+ if ( name() != "standalone" ) {
+ d->error = XMLERR_SDDECLEXPECTED;
+ goto parseError;
+ }
+ if ( string()=="yes" ) {
+ d->standalone = QXmlSimpleReaderPrivate::Yes;
+ } else if ( string()=="no" ) {
+ d->standalone = QXmlSimpleReaderPrivate::No;
+ } else {
+ d->error = XMLERR_WRONGVALUEFORSDECL;
+ goto parseError;
+ }
+ break;
+ case Qm:
+ // test if the skipping was legal
+ if ( c != '>' ) {
+ stringAddC( '?' );
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a document type definition (doctypedecl [28]).
+
+ Precondition: the beginning '<!' of the doctype is already read the head
+ stands on the 'D' of '<!DOCTYPE'.
+
+ If this funktion was successful, the head-position is on the first
+ character after the document type definition.
+*/
+bool QXmlSimpleReader::parseDoctype()
+{
+ // some init-stuff
+ d->systemId = "";
+ d->publicId = "";
+
+ const signed char Init = 0;
+ const signed char Doctype = 1; // read the doctype
+ const signed char Ws1 = 2; // eat_ws
+ const signed char Doctype2 = 3; // read the doctype, part 2
+ const signed char Ws2 = 4; // eat_ws
+ const signed char Sys = 5; // read SYSTEM
+ const signed char Ws3 = 6; // eat_ws
+ const signed char MP = 7; // markupdecl or PEReference
+ const signed char PER = 8; // PERReference
+ const signed char Mup = 9; // markupdecl
+ const signed char Ws4 = 10; // eat_ws
+ const signed char MPE = 11; // end of markupdecl or PEReference
+ const signed char Done = 12;
+
+ const signed char InpWs = 0;
+ const signed char InpD = 1; // 'D'
+ const signed char InpS = 2; // 'S' or 'P'
+ const signed char InpOB = 3; // [
+ const signed char InpCB = 4; // ]
+ const signed char InpPer = 5; // %
+ const signed char InpGt = 6; // >
+ const signed char InpUnknown = 7;
+
+ // use some kind of state machine for parsing
+ static signed char table[12][8] = {
+ /* InpWs, InpD InpS InpOB InpCB InpPer InpGt InpUnknown */
+ { -1, Doctype, -1, -1, -1, -1, -1, -1 }, // Init
+ { Ws1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Doctype
+ { -1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Ws1
+ { Ws2, -1, Sys, MP, -1, -1, Done, -1 }, // Doctype2
+ { -1, -1, Sys, MP, -1, -1, Done, -1 }, // Ws2
+ { Ws3, -1, -1, MP, -1, -1, Done, -1 }, // Sys
+ { -1, -1, -1, MP, -1, -1, Done, -1 }, // Ws3
+ { -1, -1, -1, -1, MPE, PER, -1, Mup }, // MP
+ { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // PER
+ { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // Mup
+ { -1, -1, -1, -1, MPE, PER, -1, Mup }, // Ws4
+ { -1, -1, -1, -1, -1, -1, Done, -1 } // MPE
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == 'D' ) {
+ input = InpD;
+ } else if ( c == 'S' ) {
+ input = InpS;
+ } else if ( c == 'P' ) {
+ input = InpS;
+ } else if ( c == '[' ) {
+ input = InpOB;
+ } else if ( c == ']' ) {
+ input = InpCB;
+ } else if ( c == '%' ) {
+ input = InpPer;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Doctype:
+ parseOk = parseString( "DOCTYPE" );
+ break;
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ case Ws4:
+ eat_ws();
+ break;
+ case Doctype2:
+ parseName();
+ break;
+ case Sys:
+ parseOk = parseExternalID();
+ break;
+ case MP:
+ next_eat_ws();
+ break;
+ case PER:
+ parseOk = parsePEReference( InDTD );
+ break;
+ case Mup:
+ parseOk = parseMarkupdecl();
+ break;
+ case MPE:
+ next_eat_ws();
+ break;
+ case Done:
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->endDTD() ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Doctype:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ if ( !is_S(c) ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case Doctype2:
+ d->doctype = name();
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->startDTD( d->doctype, d->publicId, d->systemId ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case Sys:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case PER:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case Mup:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a ExternalID [75].
+
+ If allowPublicID is TRUE parse ExternalID [75] or PublicID [83].
+*/
+bool QXmlSimpleReader::parseExternalID( bool allowPublicID )
+{
+ // some init-stuff
+ d->systemId = "";
+ d->publicId = "";
+
+ const signed char Init = 0;
+ const signed char Sys = 1; // parse 'SYSTEM'
+ const signed char SysWS = 2; // parse the whitespace after 'SYSTEM'
+ const signed char SysSQ = 3; // parse SystemLiteral with '
+ const signed char SysSQ2 = 4; // parse SystemLiteral with '
+ const signed char SysDQ = 5; // parse SystemLiteral with "
+ const signed char SysDQ2 = 6; // parse SystemLiteral with "
+ const signed char Pub = 7; // parse 'PUBLIC'
+ const signed char PubWS = 8; // parse the whitespace after 'PUBLIC'
+ const signed char PubSQ = 9; // parse PubidLiteral with '
+ const signed char PubSQ2 = 10; // parse PubidLiteral with '
+ const signed char PubDQ = 11; // parse PubidLiteral with "
+ const signed char PubDQ2 = 12; // parse PubidLiteral with "
+ const signed char PubE = 13; // finished parsing the PubidLiteral
+ const signed char PubWS2 = 14; // parse the whitespace after the PubidLiteral
+ const signed char PDone = 15; // done if allowPublicID is TRUE
+ const signed char Done = 16;
+
+ const signed char InpSQ = 0; // '
+ const signed char InpDQ = 1; // "
+ const signed char InpS = 2; // S
+ const signed char InpP = 3; // P
+ const signed char InpWs = 4; // white space
+ const signed char InpUnknown = 5;
+
+ // use some kind of state machine for parsing
+ static signed char table[15][6] = {
+ /* InpSQ InpDQ InpS InpP InpWs InpUnknown */
+ { -1, -1, Sys, Pub, -1, -1 }, // Init
+ { -1, -1, -1, -1, SysWS, -1 }, // Sys
+ { SysSQ, SysDQ, -1, -1, -1, -1 }, // SysWS
+ { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ
+ { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ2
+ { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ
+ { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ2
+ { -1, -1, -1, -1, PubWS, -1 }, // Pub
+ { PubSQ, PubDQ, -1, -1, -1, -1 }, // PubWS
+ { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ
+ { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ2
+ { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ
+ { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ2
+ { PDone, PDone, PDone, PDone, PubWS2, PDone }, // PubE
+ { SysSQ, SysDQ, PDone, PDone, PDone, PDone } // PubWS2
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '\'' ) {
+ input = InpSQ;
+ } else if ( c == '"' ) {
+ input = InpDQ;
+ } else if ( c == 'S' ) {
+ input = InpS;
+ } else if ( c == 'P' ) {
+ input = InpP;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Sys:
+ parseOk = parseString( "SYSTEM" );
+ break;
+ case SysWS:
+ eat_ws();
+ break;
+ case SysSQ:
+ case SysDQ:
+ stringClear();
+ next();
+ break;
+ case SysSQ2:
+ case SysDQ2:
+ stringAddC();
+ next();
+ break;
+ case Pub:
+ parseOk = parseString( "PUBLIC" );
+ break;
+ case PubWS:
+ eat_ws();
+ break;
+ case PubSQ:
+ case PubDQ:
+ stringClear();
+ next();
+ break;
+ case PubSQ2:
+ case PubDQ2:
+ stringAddC();
+ next();
+ break;
+ case PubE:
+ next();
+ break;
+ case PubWS2:
+ d->publicId = string();
+ eat_ws();
+ break;
+ case Done:
+ d->systemId = string();
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Sys:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Pub:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case PDone:
+ if ( allowPublicID ) {
+ d->publicId = string();
+ return TRUE;
+ } else {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a markupdecl [29].
+*/
+bool QXmlSimpleReader::parseMarkupdecl()
+{
+ const signed char Init = 0;
+ const signed char Lt = 1; // < was read
+ const signed char Em = 2; // ! was read
+ const signed char CE = 3; // E was read
+ const signed char Qm = 4; // ? was read
+ const signed char Dash = 5; // - was read
+ const signed char CA = 6; // A was read
+ const signed char CEL = 7; // EL was read
+ const signed char CEN = 8; // EN was read
+ const signed char CN = 9; // N was read
+ const signed char Done = 10;
+
+ const signed char InpLt = 0; // <
+ const signed char InpQm = 1; // ?
+ const signed char InpEm = 2; // !
+ const signed char InpDash = 3; // -
+ const signed char InpA = 4; // A
+ const signed char InpE = 5; // E
+ const signed char InpL = 6; // L
+ const signed char InpN = 7; // N
+ const signed char InpUnknown = 8;
+
+ // use some kind of state machine for parsing
+ static signed char table[4][9] = {
+ /* InpLt InpQm InpEm InpDash InpA InpE InpL InpN InpUnknown */
+ { Lt, -1, -1, -1, -1, -1, -1, -1, -1 }, // Init
+ { -1, Qm, Em, -1, -1, -1, -1, -1, -1 }, // Lt
+ { -1, -1, -1, Dash, CA, CE, -1, CN, -1 }, // Em
+ { -1, -1, -1, -1, -1, -1, CEL, CEN, -1 } // CE
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == '<' ) {
+ input = InpLt;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '!' ) {
+ input = InpEm;
+ } else if ( c == '-' ) {
+ input = InpDash;
+ } else if ( c == 'A' ) {
+ input = InpA;
+ } else if ( c == 'E' ) {
+ input = InpE;
+ } else if ( c == 'L' ) {
+ input = InpL;
+ } else if ( c == 'N' ) {
+ input = InpN;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Lt:
+ next();
+ break;
+ case Em:
+ next();
+ break;
+ case CE:
+ next();
+ break;
+ case Qm:
+ parseOk = parsePI();
+ break;
+ case Dash:
+ parseOk = parseComment();
+ break;
+ case CA:
+ parseOk = parseAttlistDecl();
+ break;
+ case CEL:
+ parseOk = parseElementDecl();
+ break;
+ case CEN:
+ parseOk = parseEntityDecl();
+ break;
+ case CN:
+ parseOk = parseNotationDecl();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Qm:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGPI;
+ goto parseError;
+ }
+ return TRUE;
+ case Dash:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCOMMENT;
+ goto parseError;
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ d->error = lexicalHnd->errorString();
+ goto parseError;
+ }
+ }
+ return TRUE;
+ case CA:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTLISTDECL;
+ goto parseError;
+ }
+ return TRUE;
+ case CEL:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGELEMENTDECL;
+ goto parseError;
+ }
+ return TRUE;
+ case CEN:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGENTITYDECL;
+ goto parseError;
+ }
+ return TRUE;
+ case CN:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNOTATIONDECL;
+ goto parseError;
+ }
+ return TRUE;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a PEReference [69]
+*/
+bool QXmlSimpleReader::parsePEReference( EntityRecognitionContext context )
+{
+ const signed char Init = 0;
+ const signed char Next = 1;
+ const signed char Name = 2;
+ const signed char Done = 3;
+
+ const signed char InpSemi = 0; // ;
+ const signed char InpPer = 1; // %
+ const signed char InpUnknown = 2;
+
+ // use some kind of state machine for parsing
+ static signed char table[3][3] = {
+ /* InpSemi InpPer InpUnknown */
+ { -1, Next, -1 }, // Init
+ { -1, -1, Name }, // Next
+ { Done, -1, -1 } // Name
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == ';' ) {
+ input = InpSemi;
+ } else if ( c == '%' ) {
+ input = InpPer;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Next:
+ next();
+ break;
+ case Name:
+ parseOk = parseName( TRUE );
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ if ( d->parameterEntities.find( ref() ) == d->parameterEntities.end() ) {
+ // ### skip it???
+ if ( contentHnd ) {
+ if ( !contentHnd->skippedEntity( QString("%") + ref() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ } else {
+ if ( context == InEntityValue ) {
+ // Included in literal
+ xmlRef = d->parameterEntities.find( ref() )
+ .data().replace( QRegExp("\""), "&quot;" ).replace( QRegExp("'"), "&apos;" )
+ + xmlRef;
+ } else if ( context == InDTD ) {
+ // Included as PE ### correct???
+ xmlRef = QString(" ") +
+ d->parameterEntities.find( ref() ).data() +
+ QString(" ") + xmlRef;
+ }
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a AttlistDecl [52].
+
+ Precondition: the beginning '<!' is already read and the head
+ stands on the 'A' of '<!ATTLIST'
+*/
+bool QXmlSimpleReader::parseAttlistDecl()
+{
+ const signed char Init = 0;
+ const signed char Attlist = 1; // parse the string "ATTLIST"
+ const signed char Ws = 2; // whitespace read
+ const signed char Name = 3; // parse name
+ const signed char Ws1 = 4; // whitespace read
+ const signed char Attdef = 5; // parse the AttDef
+ const signed char Ws2 = 6; // whitespace read
+ const signed char Atttype = 7; // parse the AttType
+ const signed char Ws3 = 8; // whitespace read
+ const signed char DDecH = 9; // DefaultDecl with #
+ const signed char DefReq = 10; // parse the string "REQUIRED"
+ const signed char DefImp = 11; // parse the string "IMPLIED"
+ const signed char DefFix = 12; // parse the string "FIXED"
+ const signed char Attval = 13; // parse the AttValue
+ const signed char Ws4 = 14; // whitespace read
+ const signed char Done = 15;
+
+ const signed char InpWs = 0; // white space
+ const signed char InpGt = 1; // >
+ const signed char InpHash = 2; // #
+ const signed char InpA = 3; // A
+ const signed char InpI = 4; // I
+ const signed char InpF = 5; // F
+ const signed char InpR = 6; // R
+ const signed char InpUnknown = 7;
+
+ // use some kind of state machine for parsing
+ static signed char table[15][8] = {
+ /* InpWs InpGt InpHash InpA InpI InpF InpR InpUnknown */
+ { -1, -1, -1, Attlist, -1, -1, -1, -1 }, // Init
+ { Ws, -1, -1, -1, -1, -1, -1, -1 }, // Attlist
+ { -1, -1, -1, Name, Name, Name, Name, Name }, // Ws
+ { Ws1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Name
+ { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Ws1
+ { Ws2, -1, -1, -1, -1, -1, -1, -1 }, // Attdef
+ { -1, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype }, // Ws2
+ { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // Attype
+ { -1, Attval, DDecH, Attval, Attval, Attval, Attval, Attval }, // Ws3
+ { -1, -1, -1, -1, DefImp, DefFix, DefReq, -1 }, // DDecH
+ { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefReq
+ { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefImp
+ { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // DefFix
+ { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // Attval
+ { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef } // Ws4
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == '#' ) {
+ input = InpHash;
+ } else if ( c == 'A' ) {
+ input = InpA;
+ } else if ( c == 'I' ) {
+ input = InpI;
+ } else if ( c == 'F' ) {
+ input = InpF;
+ } else if ( c == 'R' ) {
+ input = InpR;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Attlist:
+ parseOk = parseString( "ATTLIST" );
+ break;
+ case Ws:
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ eat_ws();
+ break;
+ case Name:
+ parseOk = parseName();
+ break;
+ case Attdef:
+ parseOk = parseName();
+ break;
+ case Atttype:
+ parseOk = parseAttType();
+ break;
+ case DDecH:
+ next();
+ break;
+ case DefReq:
+ parseOk = parseString( "REQUIRED" );
+ break;
+ case DefImp:
+ parseOk = parseString( "IMPLIED" );
+ break;
+ case DefFix:
+ parseOk = parseString( "FIXED" );
+ break;
+ case Attval:
+ parseOk = parseAttValue();
+ break;
+ case Ws4:
+ if ( declHnd ) {
+ // TODO: not all values are computed yet...
+ if ( !declHnd->attributeDecl( d->attDeclEName, d->attDeclAName, "", "", "" ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ eat_ws();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Attlist:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ d->attDeclEName = name();
+ break;
+ case Attdef:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ d->attDeclAName = name();
+ break;
+ case Atttype:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTTYPE;
+ goto parseError;
+ }
+ break;
+ case DefReq:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case DefImp:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case DefFix:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Attval:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTVALUE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a AttType [54]
+*/
+bool QXmlSimpleReader::parseAttType()
+{
+ const signed char Init = 0;
+ const signed char ST = 1; // StringType
+ const signed char TTI = 2; // TokenizedType starting with 'I'
+ const signed char TTI2 = 3; // TokenizedType helpstate
+ const signed char TTI3 = 4; // TokenizedType helpstate
+ const signed char TTE = 5; // TokenizedType starting with 'E'
+ const signed char TTEY = 6; // TokenizedType starting with 'ENTITY'
+ const signed char TTEI = 7; // TokenizedType starting with 'ENTITI'
+ const signed char N = 8; // N read (TokenizedType or Notation)
+ const signed char TTNM = 9; // TokenizedType starting with 'NM'
+ const signed char TTNM2 = 10; // TokenizedType helpstate
+ const signed char NO = 11; // Notation
+ const signed char NO2 = 12; // Notation helpstate
+ const signed char NO3 = 13; // Notation helpstate
+ const signed char NOName = 14; // Notation, read name
+ const signed char NO4 = 15; // Notation helpstate
+ const signed char EN = 16; // Enumeration
+ const signed char ENNmt = 17; // Enumeration, read Nmtoken
+ const signed char EN2 = 18; // Enumeration helpstate
+ const signed char ADone = 19; // almost done (make next and accept)
+ const signed char Done = 20;
+
+ const signed char InpWs = 0; // whitespace
+ const signed char InpOp = 1; // (
+ const signed char InpCp = 2; // )
+ const signed char InpPipe = 3; // |
+ const signed char InpC = 4; // C
+ const signed char InpE = 5; // E
+ const signed char InpI = 6; // I
+ const signed char InpM = 7; // M
+ const signed char InpN = 8; // N
+ const signed char InpO = 9; // O
+ const signed char InpR = 10; // R
+ const signed char InpS = 11; // S
+ const signed char InpY = 12; // Y
+ const signed char InpUnknown = 13;
+
+ // use some kind of state machine for parsing
+ static signed char table[19][14] = {
+ /* InpWs InpOp InpCp InpPipe InpC InpE InpI InpM InpN InpO InpR InpS InpY InpUnknown */
+ { -1, EN, -1, -1, ST, TTE, TTI, -1, N, -1, -1, -1, -1, -1 }, // Init
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // ST
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI2, Done, Done, Done }, // TTI
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI3, Done, Done }, // TTI2
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTI3
+ { -1, -1, -1, -1, -1, -1, TTEI, -1, -1, -1, -1, -1, TTEY, -1 }, // TTE
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEY
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEI
+ { -1, -1, -1, -1, -1, -1, -1, TTNM, -1, NO, -1, -1, -1, -1 }, // N
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTNM2, Done, Done }, // TTNM
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTNM2
+ { NO2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO
+ { -1, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO2
+ { NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName }, // NO3
+ { NO4, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NOName
+ { -1, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO4
+ { -1, -1, ENNmt, -1, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt }, // EN
+ { EN2, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // ENNmt
+ { -1, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // EN2
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '(' ) {
+ input = InpOp;
+ } else if ( c == ')' ) {
+ input = InpCp;
+ } else if ( c == '|' ) {
+ input = InpPipe;
+ } else if ( c == 'C' ) {
+ input = InpC;
+ } else if ( c == 'E' ) {
+ input = InpE;
+ } else if ( c == 'I' ) {
+ input = InpI;
+ } else if ( c == 'M' ) {
+ input = InpM;
+ } else if ( c == 'N' ) {
+ input = InpN;
+ } else if ( c == 'O' ) {
+ input = InpO;
+ } else if ( c == 'R' ) {
+ input = InpR;
+ } else if ( c == 'S' ) {
+ input = InpS;
+ } else if ( c == 'Y' ) {
+ input = InpY;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case ST:
+ parseOk = parseString( "CDATA" );
+ break;
+ case TTI:
+ parseOk = parseString( "ID" );
+ break;
+ case TTI2:
+ parseOk = parseString( "REF" );
+ break;
+ case TTI3:
+ next(); // S
+ break;
+ case TTE:
+ parseOk = parseString( "ENTIT" );
+ break;
+ case TTEY:
+ next(); // Y
+ break;
+ case TTEI:
+ parseOk = parseString( "IES" );
+ break;
+ case N:
+ next(); // N
+ break;
+ case TTNM:
+ parseOk = parseString( "MTOKEN" );
+ break;
+ case TTNM2:
+ next(); // S
+ break;
+ case NO:
+ parseOk = parseString( "OTATION" );
+ break;
+ case NO2:
+ eat_ws();
+ break;
+ case NO3:
+ next_eat_ws();
+ break;
+ case NOName:
+ parseOk = parseName();
+ break;
+ case NO4:
+ eat_ws();
+ break;
+ case EN:
+ next_eat_ws();
+ break;
+ case ENNmt:
+ parseOk = parseNmtoken();
+ break;
+ case EN2:
+ eat_ws();
+ break;
+ case ADone:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case ST:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTI:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTI2:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTE:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTEI:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case TTNM:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case NO:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case NOName:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case ENNmt:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNMTOKEN;
+ goto parseError;
+ }
+ break;
+ case ADone:
+ return TRUE;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a AttValue [10]
+
+ Precondition: the head stands on the beginning " or '
+
+ If this function was successful, the head stands on the first
+ character after the closing " or ' and the value of the attribute
+ is in string().
+*/
+bool QXmlSimpleReader::parseAttValue()
+{
+ bool tmp;
+
+ const signed char Init = 0;
+ const signed char Dq = 1; // double quotes were read
+ const signed char DqRef = 2; // read references in double quotes
+ const signed char DqC = 3; // signed character read in double quotes
+ const signed char Sq = 4; // single quotes were read
+ const signed char SqRef = 5; // read references in single quotes
+ const signed char SqC = 6; // signed character read in single quotes
+ const signed char Done = 7;
+
+ const signed char InpDq = 0; // "
+ const signed char InpSq = 1; // '
+ const signed char InpAmp = 2; // &
+ const signed char InpLt = 3; // <
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static signed char table[7][5] = {
+ /* InpDq InpSq InpAmp InpLt InpUnknown */
+ { Dq, Sq, -1, -1, -1 }, // Init
+ { Done, DqC, DqRef, -1, DqC }, // Dq
+ { Done, DqC, DqRef, -1, DqC }, // DqRef
+ { Done, DqC, DqRef, -1, DqC }, // DqC
+ { SqC, Done, SqRef, -1, SqC }, // Sq
+ { SqC, Done, SqRef, -1, SqC }, // SqRef
+ { SqC, Done, SqRef, -1, SqC } // SqRef
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == '"' ) {
+ input = InpDq;
+ } else if ( c == '\'' ) {
+ input = InpSq;
+ } else if ( c == '&' ) {
+ input = InpAmp;
+ } else if ( c == '<' ) {
+ input = InpLt;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Dq:
+ case Sq:
+ stringClear();
+ next();
+ break;
+ case DqRef:
+ case SqRef:
+ parseOk = parseReference( tmp, InAttributeValue );
+ break;
+ case DqC:
+ case SqC:
+ stringAddC();
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case DqRef:
+ case SqRef:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a elementdecl [45].
+
+ Precondition: the beginning '<!E' is already read and the head
+ stands on the 'L' of '<!ELEMENT'
+*/
+bool QXmlSimpleReader::parseElementDecl()
+{
+ const signed char Init = 0;
+ const signed char Elem = 1; // parse the beginning string
+ const signed char Ws1 = 2; // whitespace required
+ const signed char Nam = 3; // parse Name
+ const signed char Ws2 = 4; // whitespace required
+ const signed char Empty = 5; // read EMPTY
+ const signed char Any = 6; // read ANY
+ const signed char Cont = 7; // read contentspec (except ANY or EMPTY)
+ const signed char Mix = 8; // read Mixed
+ const signed char Mix2 = 9; //
+ const signed char Mix3 = 10; //
+ const signed char MixN1 = 11; //
+ const signed char MixN2 = 12; //
+ const signed char MixN3 = 13; //
+ const signed char MixN4 = 14; //
+ const signed char Cp = 15; // parse cp
+ const signed char Cp2 = 16; //
+ const signed char WsD = 17; // eat whitespace before Done
+ const signed char Done = 18;
+
+ const signed char InpWs = 0;
+ const signed char InpGt = 1; // >
+ const signed char InpPipe = 2; // |
+ const signed char InpOp = 3; // (
+ const signed char InpCp = 4; // )
+ const signed char InpHash = 5; // #
+ const signed char InpQm = 6; // ?
+ const signed char InpAst = 7; // *
+ const signed char InpPlus = 8; // +
+ const signed char InpA = 9; // A
+ const signed char InpE = 10; // E
+ const signed char InpL = 11; // L
+ const signed char InpUnknown = 12;
+
+ // use some kind of state machine for parsing
+ static signed char table[18][13] = {
+ /* InpWs InpGt InpPipe InpOp InpCp InpHash InpQm InpAst InpPlus InpA InpE InpL InpUnknown */
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, Elem, -1 }, // Init
+ { Ws1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Elem
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, Nam, Nam, Nam, Nam }, // Ws1
+ { Ws2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Nam
+ { -1, -1, -1, Cont, -1, -1, -1, -1, -1, Any, Empty, -1, -1 }, // Ws2
+ { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Empty
+ { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Any
+ { -1, -1, -1, Cp, Cp, Mix, -1, -1, -1, Cp, Cp, Cp, Cp }, // Cont
+ { Mix2, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix
+ { -1, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix2
+ { WsD, Done, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // Mix3
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, MixN2, MixN2, MixN2, MixN2 }, // MixN1
+ { MixN3, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN2
+ { -1, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN3
+ { -1, -1, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // MixN4
+ { WsD, Done, -1, -1, -1, -1, Cp2, Cp2, Cp2, -1, -1, -1, -1 }, // Cp
+ { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Cp2
+ { -1, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // WsD
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // read input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == '|' ) {
+ input = InpPipe;
+ } else if ( c == '(' ) {
+ input = InpOp;
+ } else if ( c == ')' ) {
+ input = InpCp;
+ } else if ( c == '#' ) {
+ input = InpHash;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '*' ) {
+ input = InpAst;
+ } else if ( c == '+' ) {
+ input = InpPlus;
+ } else if ( c == 'A' ) {
+ input = InpA;
+ } else if ( c == 'E' ) {
+ input = InpE;
+ } else if ( c == 'L' ) {
+ input = InpL;
+ } else {
+ input = InpUnknown;
+ }
+ // get new state
+//qDebug( "%d -%d(%c)-> %d", state, input, c.latin1(), table[state][input] );
+ state = table[state][input];
+
+ // in some cases do special actions depending on state
+ switch ( state ) {
+ case Elem:
+ parseOk = parseString( "LEMENT" );
+ break;
+ case Ws1:
+ eat_ws();
+ break;
+ case Nam:
+ parseOk = parseName();
+ break;
+ case Ws2:
+ eat_ws();
+ break;
+ case Empty:
+ parseOk = parseString( "EMPTY" );
+ break;
+ case Any:
+ parseOk = parseString( "ANY" );
+ break;
+ case Cont:
+ next_eat_ws();
+ break;
+ case Mix:
+ parseOk = parseString( "#PCDATA" );
+ break;
+ case Mix2:
+ eat_ws();
+ break;
+ case Mix3:
+ next();
+ break;
+ case MixN1:
+ next_eat_ws();
+ break;
+ case MixN2:
+ parseOk = parseName();
+ break;
+ case MixN3:
+ eat_ws();
+ break;
+ case MixN4:
+ next();
+ break;
+ case Cp:
+ parseOk = parseChoiceSeq();
+ break;
+ case Cp2:
+ next();
+ break;
+ case WsD:
+ next_eat_ws();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Elem:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Nam:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case Empty:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Any:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Mix:
+ if( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case MixN2:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case Cp:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCHOICE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a NotationDecl [82].
+
+ Precondition: the beginning '<!' is already read and the head
+ stands on the 'N' of '<!NOTATION'
+*/
+bool QXmlSimpleReader::parseNotationDecl()
+{
+ const signed char Init = 0;
+ const signed char Not = 1; // read NOTATION
+ const signed char Ws1 = 2; // eat whitespaces
+ const signed char Nam = 3; // read Name
+ const signed char Ws2 = 4; // eat whitespaces
+ const signed char ExtID = 5; // parse ExternalID
+ const signed char Ws3 = 6; // eat whitespaces
+ const signed char Done = 7;
+
+ const signed char InpWs = 0;
+ const signed char InpGt = 1; // >
+ const signed char InpN = 2; // N
+ const signed char InpUnknown = 3;
+
+ // use some kind of state machine for parsing
+ static signed char table[7][4] = {
+ /* InpWs InpGt InpN InpUnknown */
+ { -1, -1, Not, -1 }, // Init
+ { Ws1, -1, -1, -1 }, // Not
+ { -1, -1, Nam, Nam }, // Ws1
+ { Ws2, Done, -1, -1 }, // Nam
+ { -1, Done, ExtID, ExtID }, // Ws2
+ { Ws3, Done, -1, -1 }, // ExtID
+ { -1, Done, -1, -1 } // Ws3
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == 'N' ) {
+ input = InpN;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Not:
+ parseOk = parseString( "NOTATION" );
+ break;
+ case Ws1:
+ eat_ws();
+ break;
+ case Nam:
+ parseOk = parseName();
+ break;
+ case Ws2:
+ eat_ws();
+ break;
+ case ExtID:
+ parseOk = parseExternalID( TRUE );
+ break;
+ case Ws3:
+ eat_ws();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Not:
+ if ( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Nam:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case ExtID:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGEXTERNALID;
+ goto parseError;
+ }
+ // call the handler
+ if ( dtdHnd ) {
+ if ( !dtdHnd->notationDecl( name(), d->publicId, d->systemId ) ) {
+ d->error = dtdHnd->errorString();
+ goto parseError;
+ }
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse choice [49] or seq [50].
+
+ Precondition: the beginning '('S? is already read and the head
+ stands on the first non-whitespace character after it.
+*/
+bool QXmlSimpleReader::parseChoiceSeq()
+{
+ const signed char Init = 0;
+ const signed char Ws1 = 1; // eat whitespace
+ const signed char CS = 2; // choice or set
+ const signed char Ws2 = 3; // eat whitespace
+ const signed char More = 4; // more cp to read
+ const signed char Name = 5; // read name
+ const signed char Done = 6; //
+
+ const signed char InpWs = 0; // S
+ const signed char InpOp = 1; // (
+ const signed char InpCp = 2; // )
+ const signed char InpQm = 3; // ?
+ const signed char InpAst = 4; // *
+ const signed char InpPlus = 5; // +
+ const signed char InpPipe = 6; // |
+ const signed char InpComm = 7; // ,
+ const signed char InpUnknown = 8;
+
+ // use some kind of state machine for parsing
+ static signed char table[6][9] = {
+ /* InpWs InpOp InpCp InpQm InpAst InpPlus InpPipe InpComm InpUnknown */
+ { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // Init
+ { -1, CS, -1, -1, -1, -1, -1, -1, CS }, // Ws1
+ { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 }, // CS
+ { -1, -1, Done, -1, -1, -1, More, More, -1 }, // Ws2
+ { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // More (same as Init)
+ { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 } // Name (same as CS)
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '(' ) {
+ input = InpOp;
+ } else if ( c == ')' ) {
+ input = InpCp;
+ } else if ( c == '?' ) {
+ input = InpQm;
+ } else if ( c == '*' ) {
+ input = InpAst;
+ } else if ( c == '+' ) {
+ input = InpPlus;
+ } else if ( c == '|' ) {
+ input = InpPipe;
+ } else if ( c == ',' ) {
+ input = InpComm;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Ws1:
+ next_eat_ws();
+ break;
+ case CS:
+ parseOk = parseChoiceSeq();
+ break;
+ case Ws2:
+ next_eat_ws();
+ break;
+ case More:
+ next_eat_ws();
+ break;
+ case Name:
+ parseOk = parseName();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case CS:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGCHOICE;
+ goto parseError;
+ }
+ break;
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a EntityDecl [70].
+
+ Precondition: the beginning '<!E' is already read and the head
+ stand on the 'N' of '<!ENTITY'
+*/
+bool QXmlSimpleReader::parseEntityDecl()
+{
+ const signed char Init = 0;
+ const signed char Ent = 1; // parse "ENTITY"
+ const signed char Ws1 = 2; // white space read
+ const signed char Name = 3; // parse name
+ const signed char Ws2 = 4; // white space read
+ const signed char EValue = 5; // parse entity value
+ const signed char ExtID = 6; // parse ExternalID
+ const signed char Ws3 = 7; // white space read
+ const signed char Ndata = 8; // parse "NDATA"
+ const signed char Ws4 = 9; // white space read
+ const signed char NNam = 10; // parse name
+ const signed char PEDec = 11; // parse PEDecl
+ const signed char Ws6 = 12; // white space read
+ const signed char PENam = 13; // parse name
+ const signed char Ws7 = 14; // white space read
+ const signed char PEVal = 15; // parse entity value
+ const signed char PEEID = 16; // parse ExternalID
+ const signed char WsE = 17; // white space read
+ const signed char Done = 18;
+
+ const signed char InpWs = 0; // white space
+ const signed char InpPer = 1; // %
+ const signed char InpQuot = 2; // " or '
+ const signed char InpGt = 3; // >
+ const signed char InpN = 4; // N
+ const signed char InpUnknown = 5;
+
+ // use some kind of state machine for parsing
+ static signed char table[18][6] = {
+ /* InpWs InpPer InpQuot InpGt InpN InpUnknown */
+ { -1, -1, -1, -1, Ent, -1 }, // Init
+ { Ws1, -1, -1, -1, -1, -1 }, // Ent
+ { -1, PEDec, -1, -1, Name, Name }, // Ws1
+ { Ws2, -1, -1, -1, -1, -1 }, // Name
+ { -1, -1, EValue, -1, -1, ExtID }, // Ws2
+ { WsE, -1, -1, Done, -1, -1 }, // EValue
+ { Ws3, -1, -1, Done, -1, -1 }, // ExtID
+ { -1, -1, -1, Done, Ndata, -1 }, // Ws3
+ { Ws4, -1, -1, -1, -1, -1 }, // Ndata
+ { -1, -1, -1, -1, NNam, NNam }, // Ws4
+ { WsE, -1, -1, Done, -1, -1 }, // NNam
+ { Ws6, -1, -1, -1, -1, -1 }, // PEDec
+ { -1, -1, -1, -1, PENam, PENam }, // Ws6
+ { Ws7, -1, -1, -1, -1, -1 }, // PENam
+ { -1, -1, PEVal, -1, -1, PEEID }, // Ws7
+ { WsE, -1, -1, Done, -1, -1 }, // PEVal
+ { WsE, -1, -1, Done, -1, -1 }, // PEEID
+ { -1, -1, -1, Done, -1, -1 } // WsE
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c == '%' ) {
+ input = InpPer;
+ } else if ( c == '"' || c == '\'' ) {
+ input = InpQuot;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else if ( c == 'N' ) {
+ input = InpN;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Ent:
+ parseOk = parseString( "NTITY" );
+ break;
+ case Ws1:
+ eat_ws();
+ break;
+ case Name:
+ parseOk = parseName();
+ break;
+ case Ws2:
+ eat_ws();
+ break;
+ case EValue:
+ parseOk = parseEntityValue();
+ break;
+ case ExtID:
+ parseOk = parseExternalID();
+ break;
+ case Ws3:
+ eat_ws();
+ break;
+ case Ndata:
+ parseOk = parseString( "NDATA" );
+ break;
+ case Ws4:
+ eat_ws();
+ break;
+ case NNam:
+ parseOk = parseName( TRUE );
+ break;
+ case PEDec:
+ next();
+ break;
+ case Ws6:
+ eat_ws();
+ break;
+ case PENam:
+ parseOk = parseName();
+ break;
+ case Ws7:
+ eat_ws();
+ break;
+ case PEVal:
+ parseOk = parseEntityValue();
+ break;
+ case PEEID:
+ parseOk = parseExternalID();
+ break;
+ case WsE:
+ eat_ws();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Ent:
+ if ( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case Name:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case EValue:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGENTITYVALUE;
+ goto parseError;
+ }
+ if ( d->entities.find( name() ) == d->entities.end() &&
+ d->externEntities.find( name() ) == d->externEntities.end() ) {
+ d->entities.insert( name(), string() );
+ if ( declHnd ) {
+ if ( !declHnd->internalEntityDecl( name(), string() ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case ExtID:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGEXTERNALID;
+ goto parseError;
+ }
+ if ( d->entities.find( name() ) == d->entities.end() &&
+ d->externEntities.find( name() ) == d->externEntities.end() ) {
+ d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, "" ) );
+ if ( declHnd ) {
+ if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case Ndata:
+ if ( !parseOk ) {
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+ break;
+ case NNam:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ if ( d->entities.find( name() ) == d->entities.end() &&
+ d->externEntities.find( name() ) == d->externEntities.end() ) {
+ d->externEntities.insert( name(), QXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, ref() ) );
+ if ( declHnd ) {
+ if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case PENam:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case PEVal:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGENTITYVALUE;
+ goto parseError;
+ }
+ if ( d->parameterEntities.find( name() ) == d->parameterEntities.end() &&
+ d->externParameterEntities.find( name() ) == d->externParameterEntities.end() ) {
+ d->parameterEntities.insert( name(), string() );
+ if ( declHnd ) {
+ if ( !declHnd->internalEntityDecl( QString("%")+name(), string() ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case PEEID:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGEXTERNALID;
+ goto parseError;
+ }
+ if ( d->parameterEntities.find( name() ) == d->parameterEntities.end() &&
+ d->externParameterEntities.find( name() ) == d->externParameterEntities.end() ) {
+ d->externParameterEntities.insert( name(), QXmlSimpleReaderPrivate::ExternParameterEntity( d->publicId, d->systemId ) );
+ if ( declHnd ) {
+ if ( !declHnd->externalEntityDecl( QString("%")+name(), d->publicId, d->systemId ) ) {
+ d->error = declHnd->errorString();
+ goto parseError;
+ }
+ }
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a EntityValue [9]
+*/
+bool QXmlSimpleReader::parseEntityValue()
+{
+ bool tmp;
+
+ const signed char Init = 0;
+ const signed char Dq = 1; // EntityValue is double quoted
+ const signed char DqC = 2; // signed character
+ const signed char DqPER = 3; // PERefence
+ const signed char DqRef = 4; // Reference
+ const signed char Sq = 5; // EntityValue is double quoted
+ const signed char SqC = 6; // signed character
+ const signed char SqPER = 7; // PERefence
+ const signed char SqRef = 8; // Reference
+ const signed char Done = 9;
+
+ const signed char InpDq = 0; // "
+ const signed char InpSq = 1; // '
+ const signed char InpAmp = 2; // &
+ const signed char InpPer = 3; // %
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static signed char table[9][5] = {
+ /* InpDq InpSq InpAmp InpPer InpUnknown */
+ { Dq, Sq, -1, -1, -1 }, // Init
+ { Done, DqC, DqRef, DqPER, DqC }, // Dq
+ { Done, DqC, DqRef, DqPER, DqC }, // DqC
+ { Done, DqC, DqRef, DqPER, DqC }, // DqPER
+ { Done, DqC, DqRef, DqPER, DqC }, // DqRef
+ { SqC, Done, SqRef, SqPER, SqC }, // Sq
+ { SqC, Done, SqRef, SqPER, SqC }, // SqC
+ { SqC, Done, SqRef, SqPER, SqC }, // SqPER
+ { SqC, Done, SqRef, SqPER, SqC } // SqRef
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == '"' ) {
+ input = InpDq;
+ } else if ( c == '\'' ) {
+ input = InpSq;
+ } else if ( c == '&' ) {
+ input = InpAmp;
+ } else if ( c == '%' ) {
+ input = InpPer;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Dq:
+ case Sq:
+ stringClear();
+ next();
+ break;
+ case DqC:
+ case SqC:
+ stringAddC();
+ next();
+ break;
+ case DqPER:
+ case SqPER:
+ parseOk = parsePEReference( InEntityValue );
+ break;
+ case DqRef:
+ case SqRef:
+ parseOk = parseReference( tmp, InEntityValue );
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case DqPER:
+ case SqPER:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGDOCTYPE;
+ goto parseError;
+ }
+ break;
+ case DqRef:
+ case SqRef:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a comment [15].
+
+ Precondition: the beginning '<!' of the comment is already read and the head
+ stands on the first '-' of '<!--'.
+
+ If this funktion was successful, the head-position is on the first
+ character after the comment.
+*/
+bool QXmlSimpleReader::parseComment()
+{
+ const signed char Init = 0;
+ const signed char Dash1 = 1; // the first dash was read
+ const signed char Dash2 = 2; // the second dash was read
+ const signed char Com = 3; // read comment
+ const signed char Com2 = 4; // read comment (help state)
+ const signed char ComE = 5; // finished reading comment
+ const signed char Done = 6;
+
+ const signed char InpDash = 0; // -
+ const signed char InpGt = 1; // >
+ const signed char InpUnknown = 2;
+
+ // use some kind of state machine for parsing
+ static signed char table[6][3] = {
+ /* InpDash InpGt InpUnknown */
+ { Dash1, -1, -1 }, // Init
+ { Dash2, -1, -1 }, // Dash1
+ { Com2, Com, Com }, // Dash2
+ { Com2, Com, Com }, // Com
+ { ComE, Com, Com }, // Com2
+ { -1, Done, -1 } // ComE
+ };
+ signed char state = Init;
+ signed char input;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == '-' ) {
+ input = InpDash;
+ } else if ( c == '>' ) {
+ input = InpGt;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Dash1:
+ next();
+ break;
+ case Dash2:
+ next();
+ break;
+ case Com:
+ stringAddC();
+ next();
+ break;
+ case Com2:
+ next();
+ break;
+ case ComE:
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Dash2:
+ stringClear();
+ break;
+ case Com2:
+ // if next character is not a dash than don't skip it
+ if ( c != '-' ) {
+ stringAddC( '-' );
+ }
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_ERRORPARSINGCOMMENT;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a Attribute [41].
+
+ Precondition: the head stands on the first character of the name of the
+ attribute (i.e. all whitespaces are already parsed).
+
+ The head stand on the next character after the end quotes. The variable name
+ contains the name of the attribute and the variable string contains the value
+ of the attribute.
+*/
+bool QXmlSimpleReader::parseAttribute()
+{
+ const signed char Init = 0;
+ const signed char PName = 1; // parse name
+ const signed char Ws = 2; // eat ws
+ const signed char Eq = 3; // the '=' was read
+ const signed char Quotes = 4; // " or ' were read
+
+ const signed char InpNameBe = 0;
+ const signed char InpEq = 1; // =
+ const signed char InpDq = 2; // "
+ const signed char InpSq = 3; // '
+ const signed char InpUnknown = 4;
+
+ // use some kind of state machine for parsing
+ static signed char table[4][5] = {
+ /* InpNameBe InpEq InpDq InpSq InpUnknown */
+ { PName, -1, -1, -1, -1 }, // Init
+ { -1, Eq, -1, -1, Ws }, // PName
+ { -1, Eq, -1, -1, -1 }, // Ws
+ { -1, -1, Quotes, Quotes, -1 } // Eq
+ };
+ signed char state = Init;
+ signed char input;
+ bool parseOk = TRUE;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_NameBeginning(c) ) {
+ input = InpNameBe;
+ } else if ( c == '=' ) {
+ input = InpEq;
+ } else if ( c == '"' ) {
+ input = InpDq;
+ } else if ( c == '\'' ) {
+ input = InpSq;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case PName:
+ parseOk = parseName();
+ break;
+ case Ws:
+ eat_ws();
+ break;
+ case Eq:
+ next_eat_ws();
+ break;
+ case Quotes:
+ parseOk = parseAttValue();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case PName:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGNAME;
+ goto parseError;
+ }
+ break;
+ case Quotes:
+ if ( !parseOk ) {
+ d->error = XMLERR_ERRORPARSINGATTVALUE;
+ goto parseError;
+ }
+ // Done
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a Name [5] and store the name in name or ref (if useRef is TRUE).
+*/
+bool QXmlSimpleReader::parseName( bool useRef )
+{
+ const signed char Init = 0;
+ const signed char Name1 = 1; // parse first signed character of the name
+ const signed char Name = 2; // parse name
+ const signed char Done = 3;
+
+ const signed char InpNameBe = 0; // name beginning signed characters
+ const signed char InpNameCh = 1; // NameChar without InpNameBe
+ const signed char InpUnknown = 2;
+
+ // use some kind of state machine for parsing
+ static signed char table[3][3] = {
+ /* InpNameBe InpNameCh InpUnknown */
+ { Name1, -1, -1 }, // Init
+ { Name, Name, Done }, // Name1
+ { Name, Name, Done } // Name
+ };
+ signed char state = Init;
+ signed char input;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_NameBeginning(c) ) {
+ input = InpNameBe;
+ } else if ( is_NameChar(c) ) {
+ input = InpNameCh;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case Name1:
+ if ( useRef ) {
+ refClear();
+ refAddC();
+ } else {
+ nameClear();
+ nameAddC();
+ }
+ next();
+ break;
+ case Name:
+ if ( useRef ) {
+ refAddC();
+ } else {
+ nameAddC();
+ }
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a Nmtoken [7] and store the name in name.
+*/
+bool QXmlSimpleReader::parseNmtoken()
+{
+ const signed char Init = 0;
+ const signed char NameF = 1;
+ const signed char Name = 2;
+ const signed char Done = 3;
+
+ const signed char InpNameCh = 0; // NameChar without InpNameBe
+ const signed char InpUnknown = 1;
+
+ // use some kind of state machine for parsing
+ static signed char table[3][2] = {
+ /* InpNameCh InpUnknown */
+ { NameF, -1 }, // Init
+ { Name, Done }, // NameF
+ { Name, Done } // Name
+ };
+ signed char state = Init;
+ signed char input;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( is_NameChar(c) ) {
+ input = InpNameCh;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case NameF:
+ nameClear();
+ nameAddC();
+ next();
+ break;
+ case Name:
+ nameAddC();
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_LETTEREXPECTED;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse a Reference [67].
+
+ charDataRead is set to TRUE if the reference must not be parsed. The
+ character(s) which the reference mapped to are appended to string. The
+ head stands on the first character after the reference.
+
+ charDataRead is set to FALSE if the reference must be parsed. The
+ charachter(s) which the reference mapped to are inserted at the reference
+ position. The head stands on the first character of the replacement).
+*/
+bool QXmlSimpleReader::parseReference( bool &charDataRead, EntityRecognitionContext context )
+{
+ // temporary variables
+ uint tmp;
+ bool ok;
+
+ const signed char Init = 0;
+ const signed char SRef = 1; // start of a reference
+ const signed char ChRef = 2; // parse CharRef
+ const signed char ChDec = 3; // parse CharRef decimal
+ const signed char ChHexS = 4; // start CharRef hexadecimal
+ const signed char ChHex = 5; // parse CharRef hexadecimal
+ const signed char Name = 6; // parse name
+ const signed char DoneD = 7; // done CharRef decimal
+ const signed char DoneH = 8; // done CharRef hexadecimal
+ const signed char DoneN = 9; // done EntityRef
+
+ const signed char InpAmp = 0; // &
+ const signed char InpSemi = 1; // ;
+ const signed char InpHash = 2; // #
+ const signed char InpX = 3; // x
+ const signed char InpNum = 4; // 0-9
+ const signed char InpHex = 5; // a-f A-F
+ const signed char InpUnknown = 6;
+
+ // use some kind of state machine for parsing
+ static signed char table[8][7] = {
+ /* InpAmp InpSemi InpHash InpX InpNum InpHex InpUnknown */
+ { SRef, -1, -1, -1, -1, -1, -1 }, // Init
+ { -1, -1, ChRef, Name, Name, Name, Name }, // SRef
+ { -1, -1, -1, ChHexS, ChDec, -1, -1 }, // ChRef
+ { -1, DoneD, -1, -1, ChDec, -1, -1 }, // ChDec
+ { -1, -1, -1, -1, ChHex, ChHex, -1 }, // ChHexS
+ { -1, DoneH, -1, -1, ChHex, ChHex, -1 }, // ChHex
+ { -1, DoneN, -1, -1, -1, -1, -1 } // Name
+ };
+ signed char state = Init;
+ signed char input;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c.row() ) {
+ input = InpUnknown;
+ } else if ( c.cell() == '&' ) {
+ input = InpAmp;
+ } else if ( c.cell() == ';' ) {
+ input = InpSemi;
+ } else if ( c.cell() == '#' ) {
+ input = InpHash;
+ } else if ( c.cell() == 'x' ) {
+ input = InpX;
+ } else if ( '0' <= c.cell() && c.cell() <= '9' ) {
+ input = InpNum;
+ } else if ( 'a' <= c.cell() && c.cell() <= 'f' ) {
+ input = InpHex;
+ } else if ( 'A' <= c.cell() && c.cell() <= 'F' ) {
+ input = InpHex;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ state = table[state][input];
+
+ // do some actions according to state
+ switch ( state ) {
+ case SRef:
+ refClear();
+ next();
+ break;
+ case ChRef:
+ next();
+ break;
+ case ChDec:
+ refAddC();
+ next();
+ break;
+ case ChHexS:
+ next();
+ break;
+ case ChHex:
+ refAddC();
+ next();
+ break;
+ case Name:
+ // read the name into the ref
+ parseName( TRUE );
+ break;
+ case DoneD:
+ tmp = ref().toUInt( &ok, 10 );
+ if ( ok ) {
+ stringAddC( QChar(tmp) );
+ } else {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ charDataRead = TRUE;
+ next();
+ break;
+ case DoneH:
+ tmp = ref().toUInt( &ok, 16 );
+ if ( ok ) {
+ stringAddC( QChar(tmp) );
+ } else {
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+ charDataRead = TRUE;
+ next();
+ break;
+ case DoneN:
+ if ( ref() == "amp" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'm' ); stringAddC( 'p' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '&' );
+ }
+ charDataRead = TRUE;
+ } else if ( ref() == "lt" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'l' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '<' );
+ }
+ charDataRead = TRUE;
+ } else if ( ref() == "gt" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'g' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '>' );
+ }
+ charDataRead = TRUE;
+ } else if ( ref() == "apos" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'p' ); stringAddC( 'o' ); stringAddC( 's' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '\'' );
+ }
+ charDataRead = TRUE;
+ } else if ( ref() == "quot" ) {
+ if ( context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'q' ); stringAddC( 'u' ); stringAddC( 'o' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '"' );
+ }
+ charDataRead = TRUE;
+ } else {
+ QMap<QString,QString>::Iterator it;
+ it = d->entities.find( ref() );
+ if ( it != d->entities.end() ) {
+ // "Internal General"
+ switch ( context ) {
+ case InContent:
+ // Included
+ xmlRef = it.data() + xmlRef;
+ charDataRead = FALSE;
+ break;
+ case InAttributeValue:
+ // Included in literal
+ xmlRef = it.data().replace( QRegExp("\""), "&quot;" ).replace( QRegExp("'"), "&apos;" )
+ + xmlRef;
+ charDataRead = FALSE;
+ break;
+ case InEntityValue:
+ {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)ref().length(); i++ ) {
+ stringAddC( ref()[i] );
+ }
+ stringAddC( ';');
+ charDataRead = TRUE;
+ }
+ break;
+ case InDTD:
+ // Forbidden
+ d->error = XMLERR_INTERNALGENERALENTITYINDTD;
+ charDataRead = FALSE;
+ break;
+ }
+ } else {
+ QMap<QString,QXmlSimpleReaderPrivate::ExternEntity>::Iterator itExtern;
+ itExtern = d->externEntities.find( ref() );
+ if ( itExtern != d->externEntities.end() ) {
+ // "External Parsed General"
+ switch ( context ) {
+ case InContent:
+ // Included if validating
+ if ( contentHnd ) {
+ if ( !contentHnd->skippedEntity( ref() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+ charDataRead = FALSE;
+ break;
+ case InAttributeValue:
+ // Forbidden
+ d->error = XMLERR_EXTERNALGENERALENTITYINAV;
+ charDataRead = FALSE;
+ break;
+ case InEntityValue:
+ {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)ref().length(); i++ ) {
+ stringAddC( ref()[i] );
+ }
+ stringAddC( ';');
+ charDataRead = TRUE;
+ }
+ break;
+ case InDTD:
+ // Forbidden
+ d->error = XMLERR_EXTERNALGENERALENTITYINDTD;
+ charDataRead = FALSE;
+ break;
+ }
+ } else {
+ // "Unparsed" ### or is the definition of unparsed entities different?
+ if ( context == InEntityValue ) {
+ // Bypassed
+ // (this does not conform with the table 4.4 of the XML specification;
+ // on the other hand: in this case it is not really an unparsed entity)
+ stringAddC( '&' );
+ for ( int i=0; i<(int)ref().length(); i++ ) {
+ stringAddC( ref()[i] );
+ }
+ stringAddC( ';');
+ charDataRead = TRUE;
+ } else {
+#if 0
+ // Forbidden
+ d->error = XMLERR_UNPARSEDENTITYREFERENCE;
+ goto parseError;
+ charDataRead = FALSE;
+#else
+ // ### skip it???
+ if ( contentHnd ) {
+ if ( !contentHnd->skippedEntity( ref() ) ) {
+ d->error = contentHnd->errorString();
+ goto parseError;
+ }
+ }
+#endif
+ }
+ }
+ }
+ }
+ next();
+ break;
+ }
+ // no input is read after this
+ switch ( state ) {
+ case DoneD:
+ return TRUE;
+ case DoneH:
+ return TRUE;
+ case DoneN:
+ return TRUE;
+ case -1:
+ // Error
+ d->error = XMLERR_ERRORPARSINGREFERENCE;
+ goto parseError;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+/*!
+ Parse over a simple string.
+
+ After the string was successfully parsed, the head is on the first
+ character after the string.
+*/
+bool QXmlSimpleReader::parseString( const QString& s )
+{
+ signed char Done = s.length();
+
+ const signed char InpCharExpected = 0; // the character that was expected
+ const signed char InpUnknown = 1;
+
+ signed char state = 0; // state in this function is the position in the string s
+ signed char input;
+
+ while ( TRUE ) {
+
+ // get input
+ if ( atEnd() ) {
+ d->error = XMLERR_UNEXPECTEDEOF;
+ goto parseError;
+ }
+ if ( c == s[(int)state] ) {
+ input = InpCharExpected;
+ } else {
+ input = InpUnknown;
+ }
+
+ // set state according to input
+ if ( input == InpCharExpected ) {
+ state++;
+ } else {
+ // Error
+ d->error = XMLERR_UNEXPECTEDCHARACTER;
+ goto parseError;
+ }
+
+ // do some actions according to state
+ next();
+ // no input is read after this
+ if ( state == Done ) {
+ return TRUE;
+ }
+
+ }
+
+ return TRUE;
+
+parseError:
+ reportParseError();
+ return FALSE;
+}
+
+
+/*
+ Init the data values.
+*/
+void QXmlSimpleReader::init( const QXmlInputSource& i )
+{
+ xml = i.data();
+ xmlLength = xml.length();
+ xmlRef = "";
+
+ d->externParameterEntities.clear();
+ d->parameterEntities.clear();
+ d->externEntities.clear();
+ d->entities.clear();
+
+ tags.clear();
+
+ d->doctype = "";
+ d->xmlVersion = "";
+ d->encoding = "";
+ d->standalone = QXmlSimpleReaderPrivate::Unknown;
+
+ lineNr = 0;
+ columnNr = -1;
+ pos = 0;
+ next();
+ d->error = XMLERR_OK;
+}
+
+void QXmlSimpleReader::reportParseError()
+{
+ if ( errorHnd )
+ errorHnd->fatalError( QXmlParseException( d->error, columnNr+1, lineNr+1 ) );
+}
+
+#endif //QT_NO_XML
diff --git a/qtools/qxml.h b/qtools/qxml.h
new file mode 100644
index 0000000..c23430c
--- /dev/null
+++ b/qtools/qxml.h
@@ -0,0 +1,645 @@
+/****************************************************************************
+**
+**
+** Definition of QXmlSimpleReader and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the XML module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QXML_H
+#define QXML_H
+
+#include <qmodules.h>
+
+#if !defined(QT_MODULE_XML)
+#define QM_EXPORT
+#else
+#define QM_EXPORT Q_EXPORT
+#endif
+
+#ifndef QT_H
+#include <qtextstream.h>
+#include <qfile.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qvaluestack.h>
+#include <qmap.h>
+#endif // QT_H
+
+#ifndef QT_NO_XML
+
+class QXmlNamespaceSupport;
+class QXmlAttributes;
+class QXmlContentHandler;
+class QXmlDefaultHandler;
+class QXmlDTDHandler;
+class QXmlEntityResolver;
+class QXmlErrorHandler;
+class QXmlLexicalHandler;
+class QXmlDeclHandler;
+class QXmlInputSource;
+class QXmlLocator;
+class QXmlNamespaceSupport;
+class QXmlParseException;
+
+class QXmlReader;
+class QXmlSimpleReader;
+
+class QXmlSimpleReaderPrivate;
+class QXmlNamespaceSupportPrivate;
+class QXmlAttributesPrivate;
+class QXmlInputSourcePrivate;
+class QXmlParseExceptionPrivate;
+class QXmlLocatorPrivate;
+class QXmlDefaultHandlerPrivate;
+
+
+//
+// SAX Namespace Support
+//
+
+#if defined(Q_TEMPLATEDLL)
+// MOC_SKIP_BEGIN
+template class QM_EXPORT QMap<QString, QString>;
+template class QM_EXPORT QValueStack<QMap<QString, QString> >;
+template class QM_EXPORT QValueStack<QString>;
+// MOC_SKIP_END
+#endif
+
+class QM_EXPORT QXmlNamespaceSupport
+{
+public:
+ QXmlNamespaceSupport();
+ ~QXmlNamespaceSupport();
+
+ void setPrefix( const QString&, const QString& );
+
+ QString prefix( const QString& ) const;
+ QString uri( const QString& ) const;
+ void splitName( const QString&, QString&, QString& ) const;
+ void processName( const QString&, bool, QString&, QString& ) const;
+ QStringList prefixes() const;
+ QStringList prefixes( const QString& ) const;
+
+ void pushContext();
+ void popContext();
+ void reset();
+private:
+ QValueStack<QMap<QString, QString> > nsStack;
+ QMap<QString, QString> ns;
+
+ QXmlNamespaceSupportPrivate *d;
+};
+
+
+//
+// SAX Attributes
+//
+
+class QM_EXPORT QXmlAttributes
+{
+public:
+ QXmlAttributes() {}
+ virtual ~QXmlAttributes() {}
+
+ int index( const QString& qName ) const;
+ int index( const QString& uri, const QString& localPart ) const;
+ int length() const;
+ QString localName( int index ) const;
+ QString qName( int index ) const;
+ QString uri( int index ) const;
+ QString type( int index ) const;
+ QString type( const QString& qName ) const;
+ QString type( const QString& uri, const QString& localName ) const;
+ QString value( int index ) const;
+ QString value( const QString& qName ) const;
+ QString value( const QString& uri, const QString& localName ) const;
+
+private:
+ QStringList qnameList;
+ QStringList uriList;
+ QStringList localnameList;
+ QStringList valueList;
+
+ QXmlAttributesPrivate *d;
+
+ friend class QXmlSimpleReader;
+};
+
+//
+// SAX Input Source
+//
+
+class QM_EXPORT QXmlInputSource
+{
+public:
+ QXmlInputSource();
+ QXmlInputSource( QTextStream& stream );
+ QXmlInputSource( QFile& file );
+ virtual ~QXmlInputSource();
+
+ virtual const QString& data() const;
+ virtual void setData( const QString& d );
+
+private:
+ void readInput( QByteArray& rawData );
+
+ QString input;
+
+ QXmlInputSourcePrivate *d;
+};
+
+//
+// SAX Exception Classes
+//
+
+class QM_EXPORT QXmlParseException
+{
+public:
+ QXmlParseException( const QString& name="", int c=-1, int l=-1, const QString& p="", const QString& s="" )
+ : msg( name ), column( c ), line( l ), pub( p ), sys( s )
+ { }
+
+ int columnNumber() const;
+ int lineNumber() const;
+ QString publicId() const;
+ QString systemId() const;
+ QString message() const;
+
+private:
+ QString msg;
+ int column;
+ int line;
+ QString pub;
+ QString sys;
+
+ QXmlParseExceptionPrivate *d;
+};
+
+
+//
+// XML Reader
+//
+
+class QM_EXPORT QXmlReader
+{
+public:
+ virtual bool feature( const QString& name, bool *ok = 0 ) const = 0;
+ virtual void setFeature( const QString& name, bool value ) = 0;
+ virtual bool hasFeature( const QString& name ) const = 0;
+ virtual void* property( const QString& name, bool *ok = 0 ) const = 0;
+ virtual void setProperty( const QString& name, void* value ) = 0;
+ virtual bool hasProperty( const QString& name ) const = 0;
+ virtual void setEntityResolver( QXmlEntityResolver* handler ) = 0;
+ virtual QXmlEntityResolver* entityResolver() const = 0;
+ virtual void setDTDHandler( QXmlDTDHandler* handler ) = 0;
+ virtual QXmlDTDHandler* DTDHandler() const = 0;
+ virtual void setContentHandler( QXmlContentHandler* handler ) = 0;
+ virtual QXmlContentHandler* contentHandler() const = 0;
+ virtual void setErrorHandler( QXmlErrorHandler* handler ) = 0;
+ virtual QXmlErrorHandler* errorHandler() const = 0;
+ virtual void setLexicalHandler( QXmlLexicalHandler* handler ) = 0;
+ virtual QXmlLexicalHandler* lexicalHandler() const = 0;
+ virtual void setDeclHandler( QXmlDeclHandler* handler ) = 0;
+ virtual QXmlDeclHandler* declHandler() const = 0;
+ virtual bool parse( const QXmlInputSource& input ) = 0;
+};
+
+class QM_EXPORT QXmlSimpleReader : public QXmlReader
+{
+public:
+ QXmlSimpleReader();
+ virtual ~QXmlSimpleReader();
+
+ bool feature( const QString& name, bool *ok = 0 ) const;
+ void setFeature( const QString& name, bool value );
+ bool hasFeature( const QString& name ) const;
+
+ void* property( const QString& name, bool *ok = 0 ) const;
+ void setProperty( const QString& name, void* value );
+ bool hasProperty( const QString& name ) const;
+
+ void setEntityResolver( QXmlEntityResolver* handler );
+ QXmlEntityResolver* entityResolver() const;
+ void setDTDHandler( QXmlDTDHandler* handler );
+ QXmlDTDHandler* DTDHandler() const;
+ void setContentHandler( QXmlContentHandler* handler );
+ QXmlContentHandler* contentHandler() const;
+ void setErrorHandler( QXmlErrorHandler* handler );
+ QXmlErrorHandler* errorHandler() const;
+ void setLexicalHandler( QXmlLexicalHandler* handler );
+ QXmlLexicalHandler* lexicalHandler() const;
+ void setDeclHandler( QXmlDeclHandler* handler );
+ QXmlDeclHandler* declHandler() const;
+
+ bool parse( const QXmlInputSource& input );
+
+private:
+ // variables
+ QXmlContentHandler* contentHnd;
+ QXmlErrorHandler* errorHnd;
+ QXmlDTDHandler* dtdHnd;
+ QXmlEntityResolver* entityRes;
+ QXmlLexicalHandler* lexicalHnd;
+ QXmlDeclHandler* declHnd;
+
+ QChar c; // the character at reading position
+ int lineNr; // number of line
+ int columnNr; // position in line
+ int pos; // position in string
+
+ int namePos;
+ QChar nameArray[256]; // only used for names
+ QString nameValue; // only used for names
+ int refPos;
+ QChar refArray[256]; // only used for references
+ QString refValue; // only used for references
+ int stringPos;
+ QChar stringArray[256]; // used for any other strings that are parsed
+ QString stringValue; // used for any other strings that are parsed
+
+ QString xml;
+ int xmlLength;
+ QString xmlRef; // used for parsing of entity references
+
+ QValueStack<QString> tags;
+
+ QXmlSimpleReaderPrivate* d;
+
+ static const QChar QEOF;
+
+ // inlines
+ virtual bool is_S( const QChar& );
+ virtual bool is_Letter( const QChar& );
+ virtual bool is_NameBeginning( const QChar& );
+ virtual bool is_Digit( const QChar& );
+ virtual bool is_CombiningChar( const QChar& );
+ virtual bool is_Extender( const QChar& );
+ virtual bool is_NameChar( const QChar& );
+
+ QString& string();
+ void stringClear();
+ void stringAddC();
+ void stringAddC(const QChar&);
+ QString& name();
+ void nameClear();
+ void nameAddC();
+ void nameAddC(const QChar&);
+ QString& ref();
+ void refClear();
+ void refAddC();
+ void refAddC(const QChar&);
+
+ // used by parseReference() and parsePEReference()
+ enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD };
+
+ // private methods
+ void eat_ws();
+ void next_eat_ws();
+
+ void next();
+ bool atEnd();
+
+ void init( const QXmlInputSource& i );
+
+ bool parseProlog();
+ bool parseElement();
+ bool parseElementEmptyTag( bool &t, QString &uri, QString &lname );
+ bool parseElementETagBegin2();
+ bool parseElementAttribute( QString &prefix, QString &uri, QString &lname );
+ bool parseMisc();
+ bool parseContent();
+
+ bool parsePI(bool xmldecl=FALSE);
+ bool parseDoctype();
+ bool parseComment();
+
+ bool parseName( bool useRef=FALSE );
+ bool parseNmtoken();
+ bool parseAttribute();
+ bool parseReference( bool &charDataRead, EntityRecognitionContext context );
+
+ bool parseExternalID( bool allowPublicID = FALSE );
+ bool parsePEReference( EntityRecognitionContext context );
+ bool parseMarkupdecl();
+ bool parseAttlistDecl();
+ bool parseAttType();
+ bool parseAttValue();
+ bool parseElementDecl();
+ bool parseNotationDecl();
+ bool parseChoiceSeq();
+ bool parseEntityDecl();
+ bool parseEntityValue();
+
+ bool parseString( const QString& s );
+
+ void reportParseError();
+
+ friend class QXmlSimpleReaderPrivate;
+ friend class QXmlLocator;
+};
+
+//
+// SAX Locator
+//
+
+class QM_EXPORT QXmlLocator
+{
+public:
+ QXmlLocator( QXmlSimpleReader* parent )
+ { reader = parent; }
+ ~QXmlLocator()
+ { }
+
+ int columnNumber();
+ int lineNumber();
+// QString getPublicId()
+// QString getSystemId()
+
+private:
+ QXmlSimpleReader* reader;
+
+ QXmlLocatorPrivate *d;
+};
+
+//
+// SAX handler classes
+//
+
+class QM_EXPORT QXmlContentHandler
+{
+public:
+ virtual void setDocumentLocator( QXmlLocator* locator ) = 0;
+ virtual bool startDocument() = 0;
+ virtual bool endDocument() = 0;
+ virtual bool startPrefixMapping( const QString& prefix, const QString& uri ) = 0;
+ virtual bool endPrefixMapping( const QString& prefix ) = 0;
+ virtual bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts ) = 0;
+ virtual bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName ) = 0;
+ virtual bool characters( const QString& ch ) = 0;
+ virtual bool ignorableWhitespace( const QString& ch ) = 0;
+ virtual bool processingInstruction( const QString& target, const QString& data ) = 0;
+ virtual bool skippedEntity( const QString& name ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlErrorHandler
+{
+public:
+ virtual bool warning( const QXmlParseException& exception ) = 0;
+ virtual bool error( const QXmlParseException& exception ) = 0;
+ virtual bool fatalError( const QXmlParseException& exception ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlDTDHandler
+{
+public:
+ virtual bool notationDecl( const QString& name, const QString& publicId, const QString& systemId ) = 0;
+ virtual bool unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlEntityResolver
+{
+public:
+ virtual bool resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* ret ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlLexicalHandler
+{
+public:
+ virtual bool startDTD( const QString& name, const QString& publicId, const QString& systemId ) = 0;
+ virtual bool endDTD() = 0;
+// virtual bool startEntity( const QString& name ) = 0;
+// virtual bool endEntity( const QString& name ) = 0;
+ virtual bool startCDATA() = 0;
+ virtual bool endCDATA() = 0;
+ virtual bool comment( const QString& ch ) = 0;
+ virtual QString errorString() = 0;
+};
+
+class QM_EXPORT QXmlDeclHandler
+{
+public:
+ virtual bool attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value ) = 0;
+ virtual bool internalEntityDecl( const QString& name, const QString& value ) = 0;
+ virtual bool externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId ) = 0;
+ virtual QString errorString() = 0;
+};
+
+
+class QM_EXPORT QXmlDefaultHandler : public QXmlContentHandler, public QXmlErrorHandler, public QXmlDTDHandler, public QXmlEntityResolver, public QXmlLexicalHandler, public QXmlDeclHandler
+{
+public:
+ QXmlDefaultHandler() { }
+ virtual ~QXmlDefaultHandler() { }
+
+ void setDocumentLocator( QXmlLocator* locator );
+ bool startDocument();
+ bool endDocument();
+ bool startPrefixMapping( const QString& prefix, const QString& uri );
+ bool endPrefixMapping( const QString& prefix );
+ bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts );
+ bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName );
+ bool characters( const QString& ch );
+ bool ignorableWhitespace( const QString& ch );
+ bool processingInstruction( const QString& target, const QString& data );
+ bool skippedEntity( const QString& name );
+
+ bool warning( const QXmlParseException& exception );
+ bool error( const QXmlParseException& exception );
+ bool fatalError( const QXmlParseException& exception );
+
+ bool notationDecl( const QString& name, const QString& publicId, const QString& systemId );
+ bool unparsedEntityDecl( const QString& name, const QString& publicId, const QString& systemId, const QString& notationName );
+
+ bool resolveEntity( const QString& publicId, const QString& systemId, QXmlInputSource* ret );
+
+ bool startDTD( const QString& name, const QString& publicId, const QString& systemId );
+ bool endDTD();
+// bool startEntity( const QString& name );
+// bool endEntity( const QString& name );
+ bool startCDATA();
+ bool endCDATA();
+ bool comment( const QString& ch );
+
+ bool attributeDecl( const QString& eName, const QString& aName, const QString& type, const QString& valueDefault, const QString& value );
+ bool internalEntityDecl( const QString& name, const QString& value );
+ bool externalEntityDecl( const QString& name, const QString& publicId, const QString& systemId );
+
+ QString errorString();
+
+private:
+ QXmlDefaultHandlerPrivate *d;
+};
+
+
+//
+// inlines
+//
+
+inline bool QXmlSimpleReader::is_S(const QChar& ch)
+{ return ch==' ' || ch=='\t' || ch=='\n' || ch=='\r'; }
+
+inline bool QXmlSimpleReader::is_Letter( const QChar& ch )
+{ return ch.isLetter(); }
+
+inline bool QXmlSimpleReader::is_NameBeginning( const QChar& ch )
+{ return ch=='_' || ch==':' || ch.isLetter(); }
+
+inline bool QXmlSimpleReader::is_Digit( const QChar& ch )
+{ return ch.isDigit(); }
+
+inline bool QXmlSimpleReader::is_CombiningChar( const QChar& )
+{ return FALSE; }
+
+inline bool QXmlSimpleReader::is_Extender( const QChar& )
+{ return FALSE; }
+
+inline bool QXmlSimpleReader::is_NameChar( const QChar& ch )
+{
+ return ch=='.' || ch=='-' || ch=='_' || ch==':' ||
+ is_Letter(ch) || is_Digit(ch) ||
+ is_CombiningChar(ch) || is_Extender(ch);
+}
+
+inline void QXmlSimpleReader::next()
+{
+ if ( !xmlRef.isEmpty() ) {
+ c = xmlRef[0];
+ xmlRef.remove( 0, 1 );
+ } else {
+ if ( c=='\n' || c=='\r' ) {
+ lineNr++;
+ columnNr = -1;
+ }
+ if ( pos >= xmlLength ) {
+ c = QEOF;
+ } else {
+ c = xml[pos];
+ columnNr++;
+ pos++;
+ }
+ }
+}
+
+inline bool QXmlSimpleReader::atEnd()
+{ return c == QEOF; }
+
+inline void QXmlSimpleReader::eat_ws()
+{ while ( !atEnd() && is_S(c) ) next(); }
+
+inline void QXmlSimpleReader::next_eat_ws()
+{ next(); eat_ws(); }
+
+
+// use buffers instead of QString::operator+= when single characters are read
+inline QString& QXmlSimpleReader::string()
+{
+ stringValue += QString( stringArray, stringPos );
+ stringPos = 0;
+ return stringValue;
+}
+inline QString& QXmlSimpleReader::name()
+{
+ nameValue += QString( nameArray, namePos );
+ namePos = 0;
+ return nameValue;
+}
+inline QString& QXmlSimpleReader::ref()
+{
+ refValue += QString( refArray, refPos );
+ refPos = 0;
+ return refValue;
+}
+
+inline void QXmlSimpleReader::stringClear()
+{ stringValue = ""; stringPos = 0; }
+inline void QXmlSimpleReader::nameClear()
+{ nameValue = ""; namePos = 0; }
+inline void QXmlSimpleReader::refClear()
+{ refValue = ""; refPos = 0; }
+
+inline void QXmlSimpleReader::stringAddC()
+{
+ if ( stringPos >= 256 ) {
+ stringValue += QString( stringArray, stringPos );
+ stringPos = 0;
+ }
+ stringArray[stringPos++] = c;
+}
+inline void QXmlSimpleReader::nameAddC()
+{
+ if ( namePos >= 256 ) {
+ nameValue += QString( nameArray, namePos );
+ namePos = 0;
+ }
+ nameArray[namePos++] = c;
+}
+inline void QXmlSimpleReader::refAddC()
+{
+ if ( refPos >= 256 ) {
+ refValue += QString( refArray, refPos );
+ refPos = 0;
+ }
+ refArray[refPos++] = c;
+}
+
+inline void QXmlSimpleReader::stringAddC(const QChar& ch)
+{
+ if ( stringPos >= 256 ) {
+ stringValue += QString( stringArray, stringPos );
+ stringPos = 0;
+ }
+ stringArray[stringPos++] = ch;
+}
+inline void QXmlSimpleReader::nameAddC(const QChar& ch)
+{
+ if ( namePos >= 256 ) {
+ nameValue += QString( nameArray, namePos );
+ namePos = 0;
+ }
+ nameArray[namePos++] = ch;
+}
+inline void QXmlSimpleReader::refAddC(const QChar& ch)
+{
+ if ( refPos >= 256 ) {
+ refValue += QString( refArray, refPos );
+ refPos = 0;
+ }
+ refArray[refPos++] = ch;
+}
+#endif //QT_NO_XML
+
+#endif
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 239ae3f..775b84f 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -604,6 +604,7 @@ ArgumentList *ClassDef::outerTemplateArguments() const
int ti;
ClassDef *pcd=0;
int pi=0;
+ if (tempArgs) return tempArgs;
// find the outer most class scope
while ((ti=name().find("::",pi))!=-1 &&
(pcd=getClass(name().left(ti)))==0
@@ -612,10 +613,7 @@ ArgumentList *ClassDef::outerTemplateArguments() const
{
return pcd->templateArguments();
}
- else
- {
- return tempArgs;
- }
+ return 0;
}
diff --git a/src/config.h b/src/config.h
index 176c1ad..9e5c906 100644
--- a/src/config.h
+++ b/src/config.h
@@ -1,4 +1,4 @@
-/* This file was generated by configgen on Sat Nov 25 21:38:08 2000
+/* This file was generated by configgen on Sun Dec 3 18:27:54 2000
* from config_templ.h
*
* DO NOT EDIT!
@@ -98,6 +98,7 @@ struct Config
static bool noIndexFlag; // generate condensed index flag
static int enumValuesPerLine; // number of enum values that are put on one line
static bool ftvHelpFlag; // should a folder tree view be generated?
+ static int treeViewWidth; // What is the width of the treeview panel?
static bool generateLatex; // generate Latex output
static QCString latexOutputDir; // the directory to put the Latex files
static bool compactLatexFlag; // generate compact LaTeX documentation.
diff --git a/src/config.l b/src/config.l
index 6d4d834..2fcef2f 100644
--- a/src/config.l
+++ b/src/config.l
@@ -1,4 +1,4 @@
-/* This file was generated by configgen on Sat Nov 25 21:38:08 2000
+/* This file was generated by configgen on Sun Dec 3 19:18:43 2000
* from config_templ.l
*
* DO NOT EDIT!
@@ -135,6 +135,7 @@ bool Config::htmlHelpFlag = FALSE;
bool Config::noIndexFlag = FALSE;
int Config::enumValuesPerLine = 4;
bool Config::ftvHelpFlag = FALSE;
+int Config::treeViewWidth = 250;
bool Config::generateLatex = TRUE;
QCString Config::latexOutputDir = "latex";
bool Config::compactLatexFlag = FALSE;
@@ -215,6 +216,7 @@ static int includeDepth;
static QCString tabSizeString;
static QCString colsInAlphaIndexString;
static QCString enumValuesPerLineString;
+static QCString treeViewWidthString;
static QCString maxDotGraphWidthString;
static QCString maxDotGraphHeightString;
@@ -413,6 +415,7 @@ static void readIncludeFile(const char *incName)
<Start>"DISABLE_INDEX"[ \t]*"=" { BEGIN(GetBool); b=&Config::noIndexFlag; }
<Start>"ENUM_VALUES_PER_LINE"[ \t]*"=" { BEGIN(GetString); s=&enumValuesPerLineString; s->resize(0); }
<Start>"GENERATE_TREEVIEW"[ \t]*"=" { BEGIN(GetBool); b=&Config::ftvHelpFlag; }
+<Start>"TREEVIEW_WIDTH"[ \t]*"=" { BEGIN(GetString); s=&treeViewWidthString; s->resize(0); }
<Start>"GENERATE_LATEX"[ \t]*"=" { BEGIN(GetBool); b=&Config::generateLatex; }
<Start>"LATEX_OUTPUT"[ \t]*"=" { BEGIN(GetString); s=&Config::latexOutputDir; s->resize(0); }
<Start>"COMPACT_LATEX"[ \t]*"=" { BEGIN(GetBool); b=&Config::compactLatexFlag; }
@@ -713,6 +716,7 @@ void dumpConfig()
printf("noIndexFlag=`%d'\n",Config::noIndexFlag);
printf("enumValuesPerLine=`%d'\n",Config::enumValuesPerLine);
printf("ftvHelpFlag=`%d'\n",Config::ftvHelpFlag);
+ printf("treeViewWidth=`%d'\n",Config::treeViewWidth);
printf("# configuration options related to the LaTeX output\n");
printf("generateLatex=`%d'\n",Config::generateLatex);
printf("latexOutputDir=`%s'\n",Config::latexOutputDir.data());
@@ -882,6 +886,7 @@ void Config::init()
Config::noIndexFlag = FALSE;
Config::enumValuesPerLine = 4;
Config::ftvHelpFlag = FALSE;
+ Config::treeViewWidth = 250;
Config::generateLatex = TRUE;
Config::latexOutputDir = "latex";
Config::compactLatexFlag = FALSE;
@@ -1725,6 +1730,17 @@ void writeTemplateConfig(QFile *f,bool sl)
if (!sl)
{
t << "\n";
+ t << "# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be \n";
+ t << "# used to set the initial width (in pixels) of the frame in which the tree \n";
+ t << "# is shown. \n";
+ t << "\n";
+ }
+ t << "TREEVIEW_WIDTH = ";
+ writeIntValue(t,Config::treeViewWidth);
+ t << "\n";
+ if (!sl)
+ {
+ t << "\n";
}
t << "#---------------------------------------------------------------------------\n";
t << "# configuration options related to the LaTeX output\n";
@@ -2356,6 +2372,23 @@ void configStrToVal()
Config::enumValuesPerLine=cols;
}
+ if (treeViewWidthString.isEmpty())
+ {
+ Config::treeViewWidth=250;
+ }
+ else
+ {
+ bool ok;
+ int width = treeViewWidthString.toInt(&ok);
+ if (!ok || width<0 || width>1500)
+ {
+ warn_cont("Warning: argument of TREEVIEW_WIDTH is not a valid number in the range [0..1500]!\n"
+ "Using the default of 250!\n");
+ width = 250;
+ }
+ Config::treeViewWidth=width;
+ }
+
if (maxDotGraphWidthString.isEmpty())
{
Config::maxDotGraphWidth=1024;
diff --git a/src/doc.l b/src/doc.l
index 274844f..82883ee 100644
--- a/src/doc.l
+++ b/src/doc.l
@@ -561,10 +561,14 @@ static void addListItemMarker(const char *marker,int dashPos,bool enumerated)
}
else // end sub item list
{
- pPrevInfo->endList();
- listIndentStack.pop();
- currentListIndent.pop();
- delete pPrevInfo;
+ while (pPrevInfo && pPrevInfo->indent>indent)
+ {
+ pPrevInfo->endList();
+ listIndentStack.pop();
+ currentListIndent.pop();
+ delete pPrevInfo;
+ pPrevInfo = listIndentStack.top();
+ }
// safe guard against wrong indenting
if (listIndentStack.isEmpty())
{
@@ -855,7 +859,7 @@ DOCPARAM ([a-z_A-Z0-9:\<\>\=\.\-]+)|("\"".*"\"")
int dashPos = text.findRev('-');
//printf("dashPos=%d char='%c'\n",dashPos,text.at(dashPos+1));
bool isEnumerated = text.at(dashPos+1)=='#';
- addListItemMarker(yytext,dashPos,isEnumerated);
+ addListItemMarker(yytext,dashPos+1,isEnumerated);
}
<DocScan>\n{B}*(("//"{B}*)?)"*"*{B}*"-"("#")?{B}+ { /* found list item marker */
QCString text=yytext;
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 14901c7..4e951bd 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -731,7 +731,7 @@ static void buildClassList(Entry *root)
ClassDef *cd=new ClassDef(root->fileName,root->startLine,fullName,sec);
cd->setDocumentation(root->doc); // copy docs to definition
cd->setBriefDescription(root->brief);
- //printf("new ClassDef tempArgList=%p specScope=%s\n",root->tArgList,root->scopeSpec.data());
+ //printf("new ClassDef %s tempArgList=%p specScope=%s\n",fullName.data(),root->tArgList,root->scopeSpec.data());
cd->setTemplateArguments(root->tArgList);
cd->setProtection(root->protection);
cd->addSectionsToDefinition(root->anchors);
@@ -1364,7 +1364,7 @@ static MemberDef *addVariableToFile(
void buildVarList(Entry *root)
{
- QRegExp re("([^)]*)");
+ static const QRegExp re("([^)]*)");
int i=-1;
if (!root->name.isEmpty() &&
//root->type!="class" && root->type!="interface" &&
@@ -1397,9 +1397,9 @@ void buildVarList(Entry *root)
{
// recover from parse error caused by redundant braces
root->type=root->name;
- QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*");
+ static const QRegExp reName("[a-z_A-Z][a-z_A-Z0-9]*");
int l;
- i=root->args.isEmpty() ? -1 : re.match(root->args,0,&l);
+ i=root->args.isEmpty() ? -1 : reName.match(root->args,0,&l);
root->name=root->args.mid(i,l);
root->args=root->args.mid(i+l,root->args.find(')',i+l)-i-l);
//printf("new: type=`%s' name=`%s' args=`%s'\n",
@@ -1408,10 +1408,19 @@ void buildVarList(Entry *root)
else
{
i=root->type.find(re,0);
- if (i!=-1) // function variable
+ if (i!=-1) // function pointer
{
- root->type=root->type.left(root->type.length()-1);
- root->args.prepend(")");
+ int ai = root->type.find('[',i);
+ if (ai>i) // function pointer array
+ {
+ root->args.prepend(root->type.right(root->type.length()-ai));
+ root->type=root->type.left(ai);
+ }
+ else
+ {
+ root->type=root->type.left(root->type.length()-1);
+ root->args.prepend(")");
+ }
}
}
@@ -2047,39 +2056,48 @@ static void transferFunctionDocumentation()
matchArguments(mdef->argumentList(),mdec->argumentList())
) /* match found */
{
- //printf("Found member %s: def in %s and dec in %s\n",
- // mn->memberName(),mdef->getFileDef()->name().data(),
- // mdec->getFileDef()->name().data());
-
- /* copy documentation between function definition and declaration */
- if (mdec->briefDescription())
- {
- mdef->setBriefDescription(mdec->briefDescription());
- }
- else if (mdef->briefDescription())
- {
- mdec->setBriefDescription(mdef->briefDescription());
- }
- if (mdef->documentation())
- {
- mdec->setDocumentation(mdef->documentation());
- }
- else if (mdec->documentation())
- {
- mdef->setDocumentation(mdec->documentation());
- }
- if (mdec->getStartBodyLine()!=-1 && mdef->getStartBodyLine()==-1)
- {
- mdef->setBodySegment(mdec->getStartBodyLine(),mdec->getEndBodyLine());
- mdef->setBodyDef(mdec->getFileDef());
- }
- else if (mdef->getStartBodyLine()!=-1 && mdec->getStartBodyLine()==-1)
+ FileDef *fdef = mdef->getFileDef();
+ FileDef *fdec = mdec->getFileDef();
+
+ // check if not in different but documented files
+ if (Config::extractAllFlag ||
+ fdef==fdec ||
+ !fdef->hasDocumentation() || !mdec->hasDocumentation())
{
- mdec->setBodySegment(mdef->getStartBodyLine(),mdef->getEndBodyLine());
- mdec->setBodyDef(mdef->getFileDef());
+ //printf("Found member %s: def in %s and dec in %s\n",
+ // mn->memberName(),mdef->getFileDef()->name().data(),
+ // mdec->getFileDef()->name().data());
+
+ /* copy documentation between function definition and declaration */
+ if (mdec->briefDescription())
+ {
+ mdef->setBriefDescription(mdec->briefDescription());
+ }
+ else if (mdef->briefDescription())
+ {
+ mdec->setBriefDescription(mdef->briefDescription());
+ }
+ if (mdef->documentation())
+ {
+ mdec->setDocumentation(mdef->documentation());
+ }
+ else if (mdec->documentation())
+ {
+ mdef->setDocumentation(mdec->documentation());
+ }
+ if (mdec->getStartBodyLine()!=-1 && mdef->getStartBodyLine()==-1)
+ {
+ mdef->setBodySegment(mdec->getStartBodyLine(),mdec->getEndBodyLine());
+ mdef->setBodyDef(mdec->getFileDef());
+ }
+ else if (mdef->getStartBodyLine()!=-1 && mdec->getStartBodyLine()==-1)
+ {
+ mdec->setBodySegment(mdef->getStartBodyLine(),mdef->getEndBodyLine());
+ mdec->setBodyDef(mdef->getFileDef());
+ }
+ mdec->mergeMemberSpecifiers(mdef->getMemberSpecifiers());
+ mdef->mergeMemberSpecifiers(mdec->getMemberSpecifiers());
}
- mdec->mergeMemberSpecifiers(mdef->getMemberSpecifiers());
- mdef->mergeMemberSpecifiers(mdec->getMemberSpecifiers());
}
}
}
diff --git a/src/filedef.cpp b/src/filedef.cpp
index 580749d..bb75335 100644
--- a/src/filedef.cpp
+++ b/src/filedef.cpp
@@ -164,6 +164,10 @@ void FileDef::writeDocumentation(OutputList &ol)
ol.docify(ii->includeName);
ol.enableAll();
ol.disableAllBut(OutputGenerator::Html);
+
+ // Here we use the include file name as it appears in the file.
+ // we could also we the name as it is used within doxygen,
+ // then we should have used fd->docName() instead of ii->includeName
if (fd && fd->isLinkable() && fd->generateSourceFile())
{
ol.writeObjectLink(fd->getReference(),fd->includeName(),0,ii->includeName);
@@ -172,6 +176,7 @@ void FileDef::writeDocumentation(OutputList &ol)
{
ol.docify(ii->includeName);
}
+
ol.enableAll();
if (ii->local)
ol.docify("\"");
@@ -438,7 +443,10 @@ void FileDef::writeSource(OutputList &ol)
initParseCodeContext();
ol.startCodeFragment();
- parseCode(ol,0,fileToString(absFilePath(),TRUE),FALSE,0,this);
+ parseCode(ol,0,
+ fileToString(absFilePath(),Config::filterForSourceFlag),
+ FALSE,0,this
+ );
ol.endCodeFragment();
endFile(ol);
ol.enableAll();
diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp
index 25ca875..cac212b 100644
--- a/src/ftvhelp.cpp
+++ b/src/ftvhelp.cpp
@@ -16,6 +16,7 @@
#include "ftvhelp.h"
#include "config.h"
#include "message.h"
+#include "doxygen.h"
const char treeview_data[]=
@@ -272,7 +273,7 @@ static void generateFolderTreeViewData()
{
QTextStream t(&f);
t << "<html><head><title>" << Config::projectName << "</title></head>" << endl;
- t << "<frameset cols=\"250,*\">" << endl;
+ t << "<frameset cols=\"" << Config::treeViewWidth << ",*\">" << endl;
t << " <frame src=\"tree.html\" name=\"treefrm\">" << endl;
t << " <frame src=\"main.html\" name=\"basefrm\">" << endl;
t << "</frameset>" << endl;
@@ -360,7 +361,7 @@ void FTVHelp::initialize()
}
/* Write the header of the contents file */
m_cts.setDevice(m_cf);
- m_cts << "foldersTree = gFld(\"<b>";
+ m_cts << "foldersTree = gFld(\"\", \"<b>";
if (Config::projectName.isEmpty())
{
m_cts << "Root";
@@ -409,18 +410,35 @@ int FTVHelp::decContentsDepth()
* \param name the name of the item.
* \param ref the URL of to the item.
*/
-void FTVHelp::addContentsItem(bool isDir,const char *name,const char *ref,
- const char *anchor)
+void FTVHelp::addContentsItem(bool isDir,
+ const char *ref,
+ const char *file,
+ const char *anchor,
+ const char *name
+ )
{
int i; for (i=0;i<m_dc;i++) m_cts << " ";
QCString parent;
+ QCString tagName = ref;
+ QCString tagDir;
+ if (ref)
+ {
+ tagName += ":";
+ QCString *s = tagDestinationDict[ref];
+ if (s)
+ {
+ tagDir = *s + "/";
+ tagName += tagDir;
+ }
+ }
if (m_dc==0) parent="foldersTree"; else parent.sprintf("aux%d",m_dc);
if (isDir) // directory entry
{
- m_cts << "aux" << m_dc+1 << " = insFld(" << parent << ", gFld(\"" << name << "\", ";
- if (ref) // ref optional param
+ m_cts << "aux" << m_dc+1 << " = insFld(" << parent << ", gFld(\""
+ << name << "\", \"" << tagName << "\", ";
+ if (file) // file optional param
{
- m_cts << "\"" << ref << ".html\"))";
+ m_cts << "\"" << tagDir << file << ".html\"))";
}
else
{
@@ -429,10 +447,11 @@ void FTVHelp::addContentsItem(bool isDir,const char *name,const char *ref,
}
else // text entry
{
- m_cts << " insDoc(" << parent << ", gLnk(0, \"" << name << "\", ";
- if (ref) // ref optional param
+ m_cts << " insDoc(" << parent << ", gLnk(\""
+ << name << "\", \"" << tagName << "\", ";
+ if (file) // ref optional param
{
- m_cts << "\"" << ref << ".html";
+ m_cts << "\"" << tagDir << file << ".html";
if (anchor) m_cts << "#" << anchor;
m_cts << "\"))";
}
diff --git a/src/ftvhelp.h b/src/ftvhelp.h
index 4e58ce1..1d6ccdf 100644
--- a/src/ftvhelp.h
+++ b/src/ftvhelp.h
@@ -32,8 +32,10 @@ class FTVHelp
/*! return the current depth of the contents tree */
int contentsDepth() { return m_dc; }
void addContentsItem(bool isDir,
- const char *name, const char *ref = 0,
- const char *anchor = 0);
+ const char *ref,
+ const char *file,
+ const char *anchor,
+ const char *name);
private:
FTVHelp();
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index a962d9f..a077ab2 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -540,6 +540,7 @@ void HtmlGenerator::codify(const char *str)
break;
case '\n': t << '\n'; col=0;
break;
+ case '\r': break;
case '<': t << "&lt;"; col++;
break;
case '>': t << "&gt;"; col++;
diff --git a/src/index.cpp b/src/index.cpp
index 9df60ad..09b2e71 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -144,7 +144,7 @@ void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper)
}
if (hasFtvHelp)
{
- ftvHelp->addContentsItem(hasChildren,cd->name(),cd->getOutputFileBase());
+ ftvHelp->addContentsItem(hasChildren,cd->getReference(),cd->getOutputFileBase(),0,cd->name());
}
}
else
@@ -156,7 +156,7 @@ void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper)
}
if (hasFtvHelp)
{
- ftvHelp->addContentsItem(hasChildren,cd->name(),0);
+ ftvHelp->addContentsItem(hasChildren,0,0,0,cd->name());
}
}
if (hasChildren)
@@ -271,7 +271,7 @@ void writeClassTree(ClassList *cl)
}
if (hasFtvHelp)
{
- ftvHelp->addContentsItem(hasChildren,cd->name(),cd->getOutputFileBase());
+ ftvHelp->addContentsItem(hasChildren,cd->getReference(),cd->getOutputFileBase(),0,cd->name());
}
}
if (hasChildren)
@@ -340,7 +340,7 @@ void writeClassHierarchy(OutputList &ol)
}
if (hasFtvHelp)
{
- ftvHelp->addContentsItem(hasChildren,cd->name(),cd->getOutputFileBase());
+ ftvHelp->addContentsItem(hasChildren,cd->getReference(),cd->getOutputFileBase(),0,cd->name());
}
}
else
@@ -352,7 +352,7 @@ void writeClassHierarchy(OutputList &ol)
}
if (hasFtvHelp)
{
- ftvHelp->addContentsItem(hasChildren,cd->name(),0);
+ ftvHelp->addContentsItem(hasChildren,0,0,0,cd->name());
}
}
if (hasChildren)
@@ -412,7 +412,7 @@ void writeHierarchicalIndex(OutputList &ol)
if (Config::generateHtml && Config::ftvHelpFlag /*&& !Config::htmlHelpGroupsOnly*/)
{
ftvHelp = FTVHelp::getInstance();
- ftvHelp->addContentsItem(TRUE,ftvHelpTitle,"hierarchy");
+ ftvHelp->addContentsItem(TRUE,0,"hierarchy",0,ftvHelpTitle);
}
if (Config::haveDotFlag && Config::gfxHierarchyFlag)
{
@@ -459,7 +459,7 @@ void writeGraphicalClassHierarchy(OutputList &ol)
if (Config::generateHtml && Config::ftvHelpFlag)
{
ftvHelp = FTVHelp::getInstance();
- ftvHelp->addContentsItem(FALSE,ftvHelpTitle,"inherits");
+ ftvHelp->addContentsItem(FALSE,0,"inherits",0,ftvHelpTitle);
}
ol.startTextLink("hierarchy",0);
parseText(ol,theTranslator->trGotoTextualHierarchy());
@@ -538,7 +538,7 @@ void writeFileIndex(OutputList &ol)
if (hasFtvHelp)
{
ftvHelp = FTVHelp::getInstance();
- ftvHelp->addContentsItem(TRUE,ftvHelpTitle,"files");
+ ftvHelp->addContentsItem(TRUE,0,"files",0,ftvHelpTitle);
ftvHelp->incContentsDepth();
}
//ol.newParagraph();
@@ -638,7 +638,7 @@ void writeFileIndex(OutputList &ol)
}
if (hasFtvHelp)
{
- ftvHelp->addContentsItem(FALSE,fd->name(),fd->getOutputFileBase());
+ ftvHelp->addContentsItem(FALSE,fd->getReference(),fd->getOutputFileBase(),0,fd->name());
}
}
else
@@ -652,7 +652,7 @@ void writeFileIndex(OutputList &ol)
}
if (hasFtvHelp)
{
- ftvHelp->addContentsItem(FALSE,fd->name(),0);
+ ftvHelp->addContentsItem(FALSE,0,0,0,fd->name());
}
}
if (src)
@@ -738,7 +738,7 @@ void writeNamespaceIndex(OutputList &ol)
if (hasFtvHelp)
{
ftvHelp = FTVHelp::getInstance();
- ftvHelp->addContentsItem(TRUE,ftvHelpTitle,"namespaces");
+ ftvHelp->addContentsItem(TRUE,0,"namespaces",0,ftvHelpTitle);
ftvHelp->incContentsDepth();
}
//ol.newParagraph();
@@ -771,7 +771,7 @@ void writeNamespaceIndex(OutputList &ol)
}
if (hasFtvHelp)
{
- ftvHelp->addContentsItem(FALSE,nd->name(),nd->getOutputFileBase());
+ ftvHelp->addContentsItem(FALSE,nd->getReference(),nd->getOutputFileBase(),0,nd->name());
}
}
nd=namespaceList.next();
@@ -851,7 +851,7 @@ void writeAnnotatedClassList(OutputList &ol)
}
if (hasFtvHelp)
{
- FTVHelp::getInstance()->addContentsItem(FALSE,cd->name(),cd->getOutputFileBase());
+ FTVHelp::getInstance()->addContentsItem(FALSE,cd->getReference(),cd->getOutputFileBase(),0,cd->name());
}
}
cd=classList.next();
@@ -1060,7 +1060,7 @@ void writeAnnotatedIndex(OutputList &ol)
if (hasFtvHelp)
{
ftvHelp = FTVHelp::getInstance();
- ftvHelp->addContentsItem(TRUE,ftvHelpTitle,"annotated");
+ ftvHelp->addContentsItem(TRUE,0,"annotated",0,ftvHelpTitle);
ftvHelp->incContentsDepth();
}
parseText(ol,theTranslator->trCompoundListDescription());
@@ -1536,7 +1536,7 @@ void writeExampleIndex(OutputList &ol)
if (hasFtvHelp)
{
ftvHelp = FTVHelp::getInstance();
- ftvHelp->addContentsItem(TRUE,ftvHelpTitle,"examples");
+ ftvHelp->addContentsItem(TRUE,0,"examples",0,ftvHelpTitle);
ftvHelp->incContentsDepth();
}
parseText(ol,theTranslator->trExamplesDescription());
@@ -1553,13 +1553,13 @@ void writeExampleIndex(OutputList &ol)
{
ol.writeObjectLink(0,n,0,pi->title);
if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pi->title,n);
- if (hasFtvHelp) ftvHelp->addContentsItem(FALSE,pi->title,n);
+ if (hasFtvHelp) ftvHelp->addContentsItem(FALSE,0,n,0,pi->title);
}
else
{
ol.writeObjectLink(0,n,0,pi->name);
if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pi->name,n);
- if (hasFtvHelp) ftvHelp->addContentsItem(FALSE,pi->name,n);
+ if (hasFtvHelp) ftvHelp->addContentsItem(FALSE,0,n,0,pi->name);
}
ol.writeString("\n");
}
@@ -1620,7 +1620,7 @@ void writePageIndex(OutputList &ol)
if (hasFtvHelp)
{
ftvHelp = FTVHelp::getInstance();
- ftvHelp->addContentsItem(TRUE,ftvHelpTitle,"pages");
+ ftvHelp->addContentsItem(TRUE,0,"pages",0,ftvHelpTitle);
ftvHelp->incContentsDepth();
}
parseText(ol,theTranslator->trRelatedPagesDescription());
@@ -1651,7 +1651,7 @@ void writePageIndex(OutputList &ol)
ol.writeEndAnnoItem(pageName);
ol.writeString("\n");
if (hasHtmlHelp) htmlHelp->addContentsItem(FALSE,pageTitle,pageName);
- if (hasFtvHelp) ftvHelp->addContentsItem(FALSE,pageTitle,pageName);
+ if (hasFtvHelp) ftvHelp->addContentsItem(FALSE,0,pageName,0,pageTitle);
}
}
ol.endIndexList();
@@ -1742,7 +1742,7 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd)
}
if(ftvHelp)
{
- ftvHelp->addContentsItem(hasSubGroups || hasSubPages,gd->groupTitle(),gd->getOutputFileBase());
+ ftvHelp->addContentsItem(hasSubGroups || hasSubPages,gd->getReference(),gd->getOutputFileBase(),0,gd->groupTitle());
ftvHelp->incContentsDepth();
}
@@ -1770,9 +1770,10 @@ void writeGroupTreeNode(OutputList &ol, GroupDef *gd)
si ? si->label.data() : 0
);
if(ftvHelp) ftvHelp->addContentsItem(FALSE,
- convertToHtml(pi->title),
+ gd->getReference(),
gd->getOutputFileBase(),
- si ? si->label.data() : 0
+ si ? si->label.data() : 0,
+ convertToHtml(pi->title)
);
}
@@ -1972,7 +1973,7 @@ void writeGroupIndex(OutputList &ol)
ftvHelp = FTVHelp::getInstance();
//if(!Config::htmlHelpGroupsOnly)
//{
- ftvHelp->addContentsItem(TRUE,htmlHelpTitle,"modules");
+ ftvHelp->addContentsItem(TRUE,0,"modules",0,htmlHelpTitle);
ftvHelp->incContentsDepth();
//}
}
@@ -2042,7 +2043,7 @@ void writeIndex(OutputList &ol)
}
if (Config::generateHtml && Config::ftvHelpFlag)
{
- FTVHelp::getInstance()->addContentsItem(FALSE,title,indexName);
+ FTVHelp::getInstance()->addContentsItem(FALSE,0,indexName,0,title);
}
if (!Config::noIndexFlag) writeQuickLinks(ol,TRUE);
diff --git a/src/instdox.cpp b/src/instdox.cpp
index 0ef6b6e..e891f3c 100644
--- a/src/instdox.cpp
+++ b/src/instdox.cpp
@@ -120,6 +120,7 @@ void writeInstallScript()
t << " $match = \".html\";\n";
t << " next if ( $file =~ /^\\.\\.?$/ );\n";
t << " ($file =~ /$match/) && (push @files, $file);\n";
+ t << " ($file =~ \"tree.js\") && (push @files, $file);\n";
t << " }\n";
t << " closedir(D);\n";
t << " }\n";
@@ -145,9 +146,17 @@ void writeInstallScript()
t << " print STDERR \"Error: opening file $oldf for writing\\n\";\n";
t << " exit 1;\n";
t << " }\n";
- t << " while (<F>) {\n";
- t << " s/doxygen\\=\\\"([^ \\\"\\:\\t\\>\\<]*)\\:([^ \\\"\\t\\>\\<]*)\\\" (href|src)=\\\"\\2/doxygen\\=\\\"$1:$subst{$1}\\\" \\3=\\\"$subst{$1}/g;\n";
- t << " print G \"$_\";\n";
+ t << " if ($oldf!=\"tree.js\") {\n";
+ t << " while (<F>) {\n";
+ t << " s/doxygen\\=\\\"([^ \\\"\\:\\t\\>\\<]*)\\:([^ \\\"\\t\\>\\<]*)\\\" (href|src)=\\\"\\2/doxygen\\=\\\"$1:$subst{$1}\\\" \\3=\\\"$subst{$1}/g;\n";
+ t << " print G \"$_\";\n";
+ t << " }\n";
+ t << " }\n";
+ t << " else {\n";
+ t << " while (<F>) {\n";
+ t << " s/\\\"([^ \\\"\\:\\t\\>\\<]*)\\:([^ \\\"\\t\\>\\<]*)\\\", \\\"\\2/\\\"$1:$subst{$1}\\\" ,\\\"$subst{$1}/g;\n";
+ t << " print G \"$_\";\n";
+ t << " }\n";
t << " }\n";
t << " } \n";
t << " else {\n";
diff --git a/src/pre.l b/src/pre.l
index 823e6e7..2c3c67b 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -93,6 +93,7 @@ static QCString g_lastGuardName;
static QCString g_incName;
static QCString g_guardExpr;
static int g_curlyCount;
+static bool g_nospaces; // add extra spaces during macro expansion
static void setFileName(const char *name)
{
@@ -494,6 +495,7 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int
if (key.length()>1 && (subst=argTable[key]))
{
QCString substArg=*subst;
+ //printf("substArg=`%s'\n",substArg.data());
// only if no ## operator is before or after the argument
// marker we do macro expansion.
if (!hash) expandExpression(substArg,0,0);
@@ -507,7 +509,14 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int
}
else
{
- resExpr+=" "+substArg+" ";
+ if (g_nospaces)
+ {
+ resExpr+=substArg;
+ }
+ else
+ {
+ resExpr+=" "+substArg+" ";
+ }
}
}
}
@@ -597,7 +606,15 @@ static void expandExpression(QCString &expr,QCString *rest,int pos)
{
// substitute the definition of the macro
//printf("macro `%s'->`%s'\n",macroName.data(),def->definition.data());
- expMacro=" "+def->definition.stripWhiteSpace()+" ";
+ if (g_nospaces)
+ {
+ expMacro=def->definition.stripWhiteSpace();
+ }
+ else
+ {
+ expMacro=" "+def->definition.stripWhiteSpace()+" ";
+ }
+ //expMacro=def->definition.stripWhiteSpace();
replaced=TRUE;
len=l;
//printf("simple macro expansion=`%s'->`%s'\n",macroName.data(),expMacro.data());
@@ -1086,6 +1103,7 @@ BN [ \t\r\n]
else // g_findDefArgContext==IncludeID
{
readIncludeFile(result);
+ g_nospaces=FALSE;
BEGIN(Start);
}
}
@@ -1339,12 +1357,14 @@ BN [ \t\r\n]
BEGIN(SkipCPPBlock);
}
<IncludeID>{ID}{B}*/"(" {
+ g_nospaces=TRUE;
g_roundCount=0;
g_defArgsStr=yytext;
g_findDefArgContext = IncludeID;
BEGIN(FindDefineArgs);
}
<IncludeID>{ID} {
+ g_nospaces=TRUE;
readIncludeFile(expandMacro(yytext));
BEGIN(Start);
}
@@ -1529,12 +1549,12 @@ BN [ \t\r\n]
int *n;
if ((n=(*g_argDict)[yytext]))
{
- if (!g_quoteArg) g_defText+=' ';
+ //if (!g_quoteArg) g_defText+=' ';
g_defText+='@';
QCString numStr;
numStr.sprintf("%d",*n);
g_defText+=numStr;
- if (!g_quoteArg) g_defText+=' ';
+ //if (!g_quoteArg) g_defText+=' ';
}
else
{
@@ -1768,6 +1788,7 @@ void preprocessFile(const char *fileName,BufStr &output)
//#endif
g_curlyCount=0;
+ g_nospaces=FALSE;
g_outputBuf=&output;
g_includeStack.setAutoDelete(TRUE);
g_includeStack.clear();
diff --git a/src/scanner.l b/src/scanner.l
index 3bee67e..eb5c5f6 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -693,6 +693,11 @@ TITLE [tT][iI][tT][lL][eE]
current->fileName = yyFileName;
current->startLine = yyLineNr;
current->bodyLine = yyLineNr;
+ if (current->mtArgList) // transfer template arguments
+ {
+ current->tArgList = current->mtArgList;
+ current->mtArgList = 0;
+ }
lineCount() ;
BEGIN( CompoundName ) ;
}
@@ -749,9 +754,9 @@ TITLE [tT][iI][tT][lL][eE]
lineCount();
// class template specifier already found => member template specifier
// already inside class => member template specifier
- if (current->tArgList || (current_root->section&Entry::COMPOUND_MASK))
- {
- //printf("-------> member template\n");
+ //if (current->tArgList /*|| (current_root->section&Entry::COMPOUND_MASK)*/)
+ //{
+ // printf("-------> member template \n");
if (current->mtArgList)
{
current->mtArgList->clear();
@@ -762,26 +767,25 @@ TITLE [tT][iI][tT][lL][eE]
current->mtArgList->setAutoDelete(TRUE);
}
currentArgumentList = current->mtArgList;
- }
- else // class template specifier
- {
- //printf("-------> class template\n");
- if (current->tArgList)
- {
- current->tArgList->clear();
- }
- else
- {
- current->tArgList = new ArgumentList;
- current->tArgList->setAutoDelete(TRUE);
- }
- currentArgumentList = current->tArgList;
- }
+ //}
+ //else // class template specifier
+ //{
+ // printf("-------> class template\n");
+ // if (current->tArgList)
+ // {
+ // current->tArgList->clear();
+ // }
+ // else
+ // {
+ // current->tArgList = new ArgumentList;
+ // current->tArgList->setAutoDelete(TRUE);
+ // }
+ // currentArgumentList = current->tArgList;
+ //}
templateStr="<";
fullArgString = templateStr.copy();
copyArgString = &templateStr;
currentArgumentContext = FindMembers;
- //printf("Start template list\n");
BEGIN( ReadTempArgs );
}
<FindMembers>"namespace"{BN}+/{ID}{BN}*"=" { // namespace alias
@@ -793,7 +797,7 @@ TITLE [tT][iI][tT][lL][eE]
BEGIN( NSAliasArg );
}
<NSAliasArg>({ID}"::")*{ID} {
- printf("Inserting namespace alias %s::%s->%s\n",current_root->name.data(),aliasName.data(),yytext);
+ //printf("Inserting namespace alias %s::%s->%s\n",current_root->name.data(),aliasName.data(),yytext);
if (current_root->name.isEmpty())
{
namespaceAliasDict.insert(aliasName,new QCString(yytext));
@@ -1616,6 +1620,7 @@ TITLE [tT][iI][tT][lL][eE]
lineCount();
addType(current);
funcPtrType=yytext;
+ roundCount=0;
//current->type += yytext;
BEGIN( FuncPtr );
}
@@ -1638,12 +1643,12 @@ TITLE [tT][iI][tT][lL][eE]
current->type+=funcPtrType.data()+1;
BEGIN(FindMembers);
}
-<EndFuncPtr>")"{BN}*/"(" { // a variable function
+<EndFuncPtr>")"{BN}*/"(" { // a function pointer
lineCount();
current->type+=funcPtrType+")";
BEGIN(FindMembers);
}
-<EndFuncPtr>")"{BN}*/"[" {
+<EndFuncPtr>")"{BN}*/"[" { // an array of variables
lineCount();
current->type+=funcPtrType.data();
current->args += ")";
@@ -1654,6 +1659,9 @@ TITLE [tT][iI][tT][lL][eE]
roundCount=0;
BEGIN( FuncFunc );
}
+<EndFuncPtr>"["[^\n\]]*"]" {
+ funcPtrType+=yytext;
+ }
<EndFuncPtr>")" {
BEGIN(FindMembers);
}
@@ -1790,7 +1798,7 @@ TITLE [tT][iI][tT][lL][eE]
<ReadTempArgs>"<" {
*copyArgString+=*yytext;
fullArgString+=*yytext;
- argSharpCount=0;
+ argSharpCount=1;
BEGIN( CopyArgSharp );
}
<ReadTempArgs>">" {
@@ -1815,16 +1823,23 @@ TITLE [tT][iI][tT][lL][eE]
}
<CopyArgSharp>"<" {
argSharpCount++;
+ //printf("argSharpCount++=%d copy\n",argSharpCount);
*copyArgString+=*yytext;
fullArgString+=*yytext;
}
<CopyArgSharp>">" {
*copyArgString+=*yytext;
fullArgString+=*yytext;
- if (argRoundCount>0)
- argRoundCount--;
+ argSharpCount--;
+ if (argSharpCount>0)
+ {
+ //printf("argSharpCount--=%d copy\n",argSharpCount);
+ }
else
+ {
BEGIN( ReadTempArgs );
+ //printf("end of argSharpCount\n");
+ }
}
<CopyArgString>\\. {
*copyArgString+=yytext;
@@ -2631,6 +2646,8 @@ TITLE [tT][iI][tT][lL][eE]
BEGIN(ClassDocBrief);
}
<TodoParam>\n |
+<TodoParam>"//" |
+<TodoParam>"/*" |
<TodoParam>. {
if (current->todoId!=0)
{
@@ -2659,6 +2676,8 @@ TITLE [tT][iI][tT][lL][eE]
BEGIN(todoStartContext);
}
<TestParam>\n |
+<TestParam>"//" |
+<TestParam>"/*" |
<TestParam>. {
if (current->testId!=0)
{
@@ -3008,7 +3027,7 @@ TITLE [tT][iI][tT][lL][eE]
<ExampleDoc,PageDoc,ClassDoc>. { current->doc += yytext; }
<Doc,JavaDoc,LineDoc,ExampleDoc,PageDoc,ClassDoc>^{B}*"//"
<Doc,ExampleDoc,PageDoc,ClassDoc>"//" { current->doc += yytext; }
-<LineDoc,JavaDoc>"//" { current->brief += yytext; }
+<LineDoc,JavaDoc,ClassDocBrief>"//" { current->brief += yytext; }
<Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc,AfterDoc,AfterDocLine,AfterDocBrief>("\\\\"|"@@")"f"[$\[\]] {
current->doc += &yytext[1];
}
diff --git a/src/translator_cn.h b/src/translator_cn.h
index 9343695..dfe5a78 100644
--- a/src/translator_cn.h
+++ b/src/translator_cn.h
@@ -51,6 +51,13 @@ class TranslatorChinese : public Translator
{ return "成员函数文档"; }
QCString trMemberDataDocumentation()
{ return "成员数据文档"; }
+ 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 "更多..."; }
QCString trListOfAllMembers()
@@ -495,17 +502,17 @@ class TranslatorChinese : public Translator
/*! Text for the \pre command */
QCString trPrecondition()
{
- return "前提条件";
+ return "前置条件";
}
/*! Text for the \post command */
QCString trPostcondition()
{
- return "Postcondition";
+ return "后置条件";
}
/*! Text for the \invariant command */
QCString trInvariant()
{
- return "Invariant";
+ return "不变性";
}
/*! Text shown before a multi-line variable/enum initialization */
QCString trInitialValue()
diff --git a/src/treeview.h b/src/treeview.h
index e74408a..213bc82 100644
--- a/src/treeview.h
+++ b/src/treeview.h
@@ -11,14 +11,17 @@
"// 27 Jan 98 - Root folder starts open; support for USETEXTLINKS; \n"
"// make the ftien4 a js file \n"
"// \n"
+"// DvH: Dec 2000 - Made some minor changes to support external \n"
+"// references\n"
" \n"
"// Definition of class Folder \n"
"// ***************************************************************** \n"
" \n"
-"function Folder(folderDescription, hreference) //constructor \n"
+"function Folder(folderDescription, tagName, hreference) //constructor \n"
"{ \n"
" //constant data \n"
" this.desc = folderDescription \n"
+" this.tagName = tagName\n"
" this.hreference = hreference \n"
" this.id = -1 \n"
" this.navObj = 0 \n"
@@ -186,6 +189,10 @@
" } \n"
" else \n"
" doc.write(this.desc) \n"
+" if (this.tagName!=\"\")\n"
+" {\n"
+" doc.write(\" [external]\")\n"
+" }\n"
" doc.write(\"</td>\") \n"
" doc.write(\"\\n</table>\\n\") \n"
" \n"
@@ -209,7 +216,12 @@
"{ \n"
" if (this.hreference) \n"
" { \n"
-" doc.write(\"<a href='\" + this.hreference + \"' TARGET=\\\"basefrm\\\" \") \n"
+" doc.write(\"<a \")\n"
+" if (this.tagName)\n"
+" {\n"
+" doc.write(\"doxygen='\" + this.tagName + \"' \");\n"
+" }\n"
+" doc.write(\"href='\" + this.hreference + \"' TARGET=\\\"basefrm\\\" \") \n"
" if (browserVersion > 0) \n"
" doc.write(\"onClick='javascript:clickOnFolder(\"+this.id+\")'\") \n"
" doc.write(\">\") \n"
@@ -242,10 +254,11 @@
"// Definition of class Item (a document or link inside a Folder) \n"
"// ************************************************************* \n"
" \n"
-"function Item(itemDescription, itemLink) // Constructor \n"
+"function Item(itemDescription, tagName, itemLink) // Constructor \n"
"{ \n"
" // constant data \n"
" this.desc = itemDescription \n"
+" this.tagName = tagName\n"
" this.link = itemLink \n"
" this.id = -1 //initialized in initalize() \n"
" this.navObj = 0 //initialized in render() \n"
@@ -319,6 +332,10 @@
" doc.write(\"<a href=\" + this.link + \">\" + this.desc + \"</a>\") \n"
" else \n"
" doc.write(this.desc) \n"
+" if (this.tagName!=\"\")\n"
+" {\n"
+" doc.write(\" [external]\");\n"
+" }\n"
" doc.write(\"\\n</table>\\n\") \n"
" \n"
" if (browserVersion == 2) \n"
@@ -422,32 +439,22 @@
"// Auxiliary Functions for Folder-Treee backward compatibility \n"
"// ********************************************************* \n"
" \n"
-"function gFld(description, hreference) \n"
+"function gFld(description, tagName, hreference) \n"
"{ \n"
-" folder = new Folder(description, hreference) \n"
+" folder = new Folder(description, tagName, hreference) \n"
" return folder \n"
"} \n"
" \n"
-"function gLnk(target, description, linkData) \n"
+"function gLnk(description, tagName, linkData) \n"
"{ \n"
" fullLink = \"\" \n"
" \n"
" if (linkData!=\"\")\n"
" {\n"
-" if (target==0) \n"
-" { \n"
-" fullLink = \"'\"+linkData+\"' target=\\\"basefrm\\\"\" \n"
-" } \n"
-" else \n"
-" { \n"
-" if (target==1) \n"
-" fullLink = \"'http://\"+linkData+\"' target=_blank\" \n"
-" else \n"
-" fullLink = \"'http://\"+linkData+\"' target=\\\"basefrm\\\"\" \n"
-" }\n"
+" fullLink = \"'\"+linkData+\"' target=\\\"basefrm\\\"\" \n"
" } \n"
" \n"
-" linkItem = new Item(description, fullLink) \n"
+" linkItem = new Item(description, tagName, fullLink) \n"
" return linkItem \n"
"} \n"
" \n"
diff --git a/src/treeview.js b/src/treeview.js
index 8fd91b1..58ca384 100644
--- a/src/treeview.js
+++ b/src/treeview.js
@@ -11,14 +11,17 @@
// 27 Jan 98 - Root folder starts open; support for USETEXTLINKS;
// make the ftien4 a js file
//
+// DvH: Dec 2000 - Made some minor changes to support external
+// references
// Definition of class Folder
// *****************************************************************
-function Folder(folderDescription, hreference) //constructor
+function Folder(folderDescription, tagName, hreference) //constructor
{
//constant data
this.desc = folderDescription
+ this.tagName = tagName
this.hreference = hreference
this.id = -1
this.navObj = 0
@@ -186,6 +189,10 @@ function drawFolder(leftSide)
}
else
doc.write(this.desc)
+ if (this.tagName!="")
+ {
+ doc.write(" [external]")
+ }
doc.write("</td>")
doc.write("\n</table>\n")
@@ -209,7 +216,12 @@ function outputFolderLink()
{
if (this.hreference)
{
- doc.write("<a href='" + this.hreference + "' TARGET=\"basefrm\" ")
+ doc.write("<a ")
+ if (this.tagName)
+ {
+ doc.write("doxygen='" + this.tagName + "' ");
+ }
+ doc.write("href='" + this.hreference + "' TARGET=\"basefrm\" ")
if (browserVersion > 0)
doc.write("onClick='javascript:clickOnFolder("+this.id+")'")
doc.write(">")
@@ -242,10 +254,11 @@ function folderSubEntries()
// Definition of class Item (a document or link inside a Folder)
// *************************************************************
-function Item(itemDescription, itemLink) // Constructor
+function Item(itemDescription, tagName, itemLink) // Constructor
{
// constant data
this.desc = itemDescription
+ this.tagName = tagName
this.link = itemLink
this.id = -1 //initialized in initalize()
this.navObj = 0 //initialized in render()
@@ -319,6 +332,10 @@ function drawItem(leftSide)
doc.write("<a href=" + this.link + ">" + this.desc + "</a>")
else
doc.write(this.desc)
+ if (this.tagName!="")
+ {
+ doc.write(" [external]");
+ }
doc.write("\n</table>\n")
if (browserVersion == 2)
@@ -422,32 +439,22 @@ function initializeDocument()
// Auxiliary Functions for Folder-Treee backward compatibility
// *********************************************************
-function gFld(description, hreference)
+function gFld(description, tagName, hreference)
{
- folder = new Folder(description, hreference)
+ folder = new Folder(description, tagName, hreference)
return folder
}
-function gLnk(target, description, linkData)
+function gLnk(description, tagName, linkData)
{
fullLink = ""
if (linkData!="")
{
- if (target==0)
- {
- fullLink = "'"+linkData+"' target=\"basefrm\""
- }
- else
- {
- if (target==1)
- fullLink = "'http://"+linkData+"' target=_blank"
- else
- fullLink = "'http://"+linkData+"' target=\"basefrm\""
- }
+ fullLink = "'"+linkData+"' target=\"basefrm\""
}
- linkItem = new Item(description, fullLink)
+ linkItem = new Item(description, tagName, fullLink)
return linkItem
}