]> git.saurik.com Git - wxWidgets.git/commitdiff
changed wxXML to XRC, wx/xml/*.h->wx/xrc/*.h
authorVáclav Slavík <vslavik@fastmail.fm>
Sat, 9 Jun 2001 22:43:51 +0000 (22:43 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Sat, 9 Jun 2001 22:43:51 +0000 (22:43 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10490 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

130 files changed:
contrib/src/xrc/FORMAT.txt [new file with mode: 0644]
contrib/src/xrc/Makefile.in [new file with mode: 0644]
contrib/src/xrc/README.EXPAT [new file with mode: 0644]
contrib/src/xrc/expat/copying.txt [new file with mode: 0644]
contrib/src/xrc/expat/xmlparse/xmlparse.c [new file with mode: 0644]
contrib/src/xrc/expat/xmlparse/xmlparse.h [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/ascii.h [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/asciitab.h [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/dllmain.c [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/iasciitab.h [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/latin1tab.h [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/nametab.h [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/utf8tab.h [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/xmldef.h [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/xmlrole.c [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/xmlrole.h [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/xmltok.c [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/xmltok.h [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/xmltok_impl.c [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/xmltok_impl.h [new file with mode: 0644]
contrib/src/xrc/expat/xmltok/xmltok_ns.c [new file with mode: 0644]
contrib/src/xrc/makefile.b32 [new file with mode: 0644]
contrib/src/xrc/makefile.g95 [new file with mode: 0644]
contrib/src/xrc/makefile.vc [new file with mode: 0644]
contrib/src/xrc/makefile.wat [new file with mode: 0644]
contrib/src/xrc/wxXMLVC.dsp [new file with mode: 0644]
contrib/src/xrc/wxXMLVC.dsw [new file with mode: 0644]
contrib/src/xrc/xh_bmp.cpp [new file with mode: 0644]
contrib/src/xrc/xh_bmpbt.cpp [new file with mode: 0644]
contrib/src/xrc/xh_bttn.cpp [new file with mode: 0644]
contrib/src/xrc/xh_cald.cpp [new file with mode: 0644]
contrib/src/xrc/xh_chckb.cpp [new file with mode: 0644]
contrib/src/xrc/xh_chckl.cpp [new file with mode: 0644]
contrib/src/xrc/xh_choic.cpp [new file with mode: 0644]
contrib/src/xrc/xh_combo.cpp [new file with mode: 0644]
contrib/src/xrc/xh_dlg.cpp [new file with mode: 0644]
contrib/src/xrc/xh_frame.cpp [new file with mode: 0644]
contrib/src/xrc/xh_gauge.cpp [new file with mode: 0644]
contrib/src/xrc/xh_html.cpp [new file with mode: 0644]
contrib/src/xrc/xh_listb.cpp [new file with mode: 0644]
contrib/src/xrc/xh_listc.cpp [new file with mode: 0644]
contrib/src/xrc/xh_menu.cpp [new file with mode: 0644]
contrib/src/xrc/xh_notbk.cpp [new file with mode: 0644]
contrib/src/xrc/xh_panel.cpp [new file with mode: 0644]
contrib/src/xrc/xh_radbt.cpp [new file with mode: 0644]
contrib/src/xrc/xh_radbx.cpp [new file with mode: 0644]
contrib/src/xrc/xh_scrol.cpp [new file with mode: 0644]
contrib/src/xrc/xh_sizer.cpp [new file with mode: 0644]
contrib/src/xrc/xh_slidr.cpp [new file with mode: 0644]
contrib/src/xrc/xh_spin.cpp [new file with mode: 0644]
contrib/src/xrc/xh_stbmp.cpp [new file with mode: 0644]
contrib/src/xrc/xh_stbox.cpp [new file with mode: 0644]
contrib/src/xrc/xh_stlin.cpp [new file with mode: 0644]
contrib/src/xrc/xh_sttxt.cpp [new file with mode: 0644]
contrib/src/xrc/xh_text.cpp [new file with mode: 0644]
contrib/src/xrc/xh_toolb.cpp [new file with mode: 0644]
contrib/src/xrc/xh_tree.cpp [new file with mode: 0644]
contrib/src/xrc/xh_unkwn.cpp [new file with mode: 0644]
contrib/src/xrc/xml.cpp [new file with mode: 0644]
contrib/src/xrc/xmlbin.cpp [new file with mode: 0644]
contrib/src/xrc/xmlbinz.cpp [new file with mode: 0644]
contrib/src/xrc/xmlexpat.cpp [new file with mode: 0644]
contrib/src/xrc/xmlres.cpp [new file with mode: 0644]
contrib/src/xrc/xmlrsall.cpp [new file with mode: 0644]
contrib/src/xrc/xmlwrite.cpp [new file with mode: 0644]
src/xrc/FORMAT.txt [new file with mode: 0644]
src/xrc/Makefile.in [new file with mode: 0644]
src/xrc/README.EXPAT [new file with mode: 0644]
src/xrc/expat/copying.txt [new file with mode: 0644]
src/xrc/expat/xmlparse/xmlparse.c [new file with mode: 0644]
src/xrc/expat/xmlparse/xmlparse.h [new file with mode: 0644]
src/xrc/expat/xmltok/ascii.h [new file with mode: 0644]
src/xrc/expat/xmltok/asciitab.h [new file with mode: 0644]
src/xrc/expat/xmltok/dllmain.c [new file with mode: 0644]
src/xrc/expat/xmltok/iasciitab.h [new file with mode: 0644]
src/xrc/expat/xmltok/latin1tab.h [new file with mode: 0644]
src/xrc/expat/xmltok/nametab.h [new file with mode: 0644]
src/xrc/expat/xmltok/utf8tab.h [new file with mode: 0644]
src/xrc/expat/xmltok/xmldef.h [new file with mode: 0644]
src/xrc/expat/xmltok/xmlrole.c [new file with mode: 0644]
src/xrc/expat/xmltok/xmlrole.h [new file with mode: 0644]
src/xrc/expat/xmltok/xmltok.c [new file with mode: 0644]
src/xrc/expat/xmltok/xmltok.h [new file with mode: 0644]
src/xrc/expat/xmltok/xmltok_impl.c [new file with mode: 0644]
src/xrc/expat/xmltok/xmltok_impl.h [new file with mode: 0644]
src/xrc/expat/xmltok/xmltok_ns.c [new file with mode: 0644]
src/xrc/makefile.b32 [new file with mode: 0644]
src/xrc/makefile.g95 [new file with mode: 0644]
src/xrc/makefile.vc [new file with mode: 0644]
src/xrc/makefile.wat [new file with mode: 0644]
src/xrc/wxXMLVC.dsp [new file with mode: 0644]
src/xrc/wxXMLVC.dsw [new file with mode: 0644]
src/xrc/xh_bmp.cpp [new file with mode: 0644]
src/xrc/xh_bmpbt.cpp [new file with mode: 0644]
src/xrc/xh_bttn.cpp [new file with mode: 0644]
src/xrc/xh_cald.cpp [new file with mode: 0644]
src/xrc/xh_chckb.cpp [new file with mode: 0644]
src/xrc/xh_chckl.cpp [new file with mode: 0644]
src/xrc/xh_choic.cpp [new file with mode: 0644]
src/xrc/xh_combo.cpp [new file with mode: 0644]
src/xrc/xh_dlg.cpp [new file with mode: 0644]
src/xrc/xh_frame.cpp [new file with mode: 0644]
src/xrc/xh_gauge.cpp [new file with mode: 0644]
src/xrc/xh_html.cpp [new file with mode: 0644]
src/xrc/xh_listb.cpp [new file with mode: 0644]
src/xrc/xh_listc.cpp [new file with mode: 0644]
src/xrc/xh_menu.cpp [new file with mode: 0644]
src/xrc/xh_notbk.cpp [new file with mode: 0644]
src/xrc/xh_panel.cpp [new file with mode: 0644]
src/xrc/xh_radbt.cpp [new file with mode: 0644]
src/xrc/xh_radbx.cpp [new file with mode: 0644]
src/xrc/xh_scrol.cpp [new file with mode: 0644]
src/xrc/xh_sizer.cpp [new file with mode: 0644]
src/xrc/xh_slidr.cpp [new file with mode: 0644]
src/xrc/xh_spin.cpp [new file with mode: 0644]
src/xrc/xh_stbmp.cpp [new file with mode: 0644]
src/xrc/xh_stbox.cpp [new file with mode: 0644]
src/xrc/xh_stlin.cpp [new file with mode: 0644]
src/xrc/xh_sttxt.cpp [new file with mode: 0644]
src/xrc/xh_text.cpp [new file with mode: 0644]
src/xrc/xh_toolb.cpp [new file with mode: 0644]
src/xrc/xh_tree.cpp [new file with mode: 0644]
src/xrc/xh_unkwn.cpp [new file with mode: 0644]
src/xrc/xml.cpp [new file with mode: 0644]
src/xrc/xmlbin.cpp [new file with mode: 0644]
src/xrc/xmlbinz.cpp [new file with mode: 0644]
src/xrc/xmlexpat.cpp [new file with mode: 0644]
src/xrc/xmlres.cpp [new file with mode: 0644]
src/xrc/xmlrsall.cpp [new file with mode: 0644]
src/xrc/xmlwrite.cpp [new file with mode: 0644]

diff --git a/contrib/src/xrc/FORMAT.txt b/contrib/src/xrc/FORMAT.txt
new file mode 100644 (file)
index 0000000..6d93b5d
--- /dev/null
@@ -0,0 +1,324 @@
+
+                         XML resources file format
+                      ===============================
+                      
+ 1. Basics
+-----------
+
+XML resource is well-formed XML document, i.e. all tags are paired
+and there is only one root node, which is always <resource>.
+
+In the following text, I will use standard XML terminology:
+
+<tag_one prop1="prop" prop2='yes'>
+   <tag_two/>
+</tag_one>
+
+Here, tag_one is a node (the word 'tag' refers to the type of the node),
+prop1 and prop2 are properties and tag_two is a child node of tag_one.
+Property's default value is the value that will be assigned to the property
+if you do not specify it explicitly.
+
+I will use the term "primary node" to refer to nodes than represent controls,
+dialogs etc. "Secondary nodes" are nodes used to store data: 
+
+<dialog name="my_dlg">                primary
+  <title>Demo Dialog...</title>       secondary
+  <size>100,200d</size>               secondary
+  <children>                          secondary
+    <button name="wxID_OK">           primary
+      <label>Ok</label>               secondary
+      <pos>10,10d</pos>               secondary
+    </button>
+  </children>
+</dialog>
+
+In the example above, <label>, <pos>, <size> and <title> are "variables",
+i.e. they contain a value and not a list of children (unlike <children> node).
+
+Any node (but the root one) may have property "platform" with possible 
+values "unix", "win", "mac" or "os2". All nodes with "platform" property
+specified and other than the platform the program is currently being executed
+on will be removed when reading XML resource file.
+
+Root node may have children of these and only these types: <menu>, <menubar>,
+<dialog>, <panel>
+
+
+
+ 2. IDs
+--------
+
+Any primary node may have property "name" used to identify it. Default value
+is "-1", any string is legal name. Names 
+    wxID_OPEN, wxID_CLOSE, wxID_NEW,
+    wxID_SAVE, wxID_SAVEAS, wxID_REVERT, 
+    wxID_EXIT, wxID_UNDO, wxID_REDO,
+    wxID_HELP, wxID_PRINT, wxID_PRINT_SETUP, 
+    wxID_PREVIEW, wxID_ABOUT, wxID_HELP_CONTENTS,
+    wxID_HELP_COMMANDS, wxID_HELP_PROCEDURES,
+    wxID_CUT, wxID_COPY, wxID_PASTE,
+    wxID_CLEAR, wxID_FIND, wxID_DUPLICATE,
+    wxID_SELECTALL, wxID_OK, wxID_CANCEL,
+    wxID_APPLY, wxID_YES, wxID_NO,
+    wxID_STATIC, wxID_FORWARD, wxID_BACKWARD,
+    wxID_DEFAULT, wxID_MORE, wxID_SETUP,
+    wxID_RESET, wxID_HELP_CONTEXT
+are translated into corresponding wxWindows ID constant, XMLID macro is used
+otherwise to generate unique ID. wxWindows control created from named node
+will have name=name and id=XMLID(name) or wxID_XXXX.
+
+
+ 3. Common variables types
+--------------------------- 
+
+Variables are always of a known type:
+
+bool       - boolean value. "1", "true", "t", "on" mean TRUE, anything
+             else (namely "0", "false", "f", "off") means FALSE.
+             FIXME: maybe use only 1/0 ??
+             
+integer    - integer value, i.e. digits 0-9 plus optional minus sign.
+             
+text       - anything. Within text node all occurences of $ are replaced 
+             by & (used for shortcuts, e.g. "E&xit"), $$ by $, \\, \n, \r,
+             \t as usual in C++.
+
+style      - (also called flags) list of flags delimined by any combination 
+             of spaces and | characters. Resources parser accepts only 
+             _registered_ flags -- i.e. flags that are valid for given 
+             node/control. Example:
+                  <flag>wxEXPAND | wxTOP|wxBOTTOM</flag>
+                  
+color      - color in HTML format: #rrggbb where rr,gg,bb are hexadecimal 
+             values (00-FF) for red, green and blue components in 
+             the RGB color model
+             
+coord      - size or position information. Consists of two integers
+             separated by comma ("x,y"). The values are in pixels 
+             unless "d" is attached to the right side of it -- 
+             in which case the values are interpreted as dialog units.
+             Value of -1 means "use default". Examples: 
+                  30,30
+                  -1,-1
+                  50,-1
+                  145,56d
+                  67,-1d
+
+
+
+ 4. Layout
+----------- 
+
+Most common nodes layout is as follows:
+
+<primary_node name="name" platform="platform">
+    <var_1>...</var_1>
+    .
+    .
+    .
+    <var_n>...</var_n>
+    <children>
+        (n primary nodes)
+    </children>
+</primary_node>
+
+where children node is supported only by panels, dialogs etc. -- see 
+nodes description for details.
+
+In the following text, 
+
+   TYPE var_name [ (= default_value) ]
+   
+means that given primary node may have child node with name var_name
+and content type TYPE. If default value is given, the node is optional
+and default_value will be used if not specified. Otherwise, the node
+is mandatory and must always be present. For example, "color fg" means
+than variable tag fg, e.g. <fg>#rr0000</fg> is expected.
+
+
+
+ 5. Common controls variables
+------------------------------
+
+_All_ nodes that represent wxWindows controls (gauge, panel, dialog, 
+textctrl etc.) accept the following properties:
+
+coord   pos       (= -1,-1) position of the control. Default value 
+                  equals to wxDefaultPosition
+coord   size      (= -1,-1) size of the control. Default value equals to 
+                  wxDefaultSize
+text    tooltip   window's tooltip
+color   bg        background color of the control
+color   fg        foreground/text color of the control
+style   style     control style flag. Default value is 
+                  control-dependent (but 0 is common value)
+style   exstyle   control extended style flag
+bool    enabled   (= 1) is the control enabled?
+bool    hidden    (= 0) is the control hidden?
+bool    focused   (= 0) has the control focus?
+
+
+_Usually_ (but not always, only when it makes sense) controls support text
+variable label which contains displayed text and/or value which contains
+editable text. These are always explicitly mentioned in tag description.
+
+
+
+
+ 6. Tags description
+---------------------
+
+If 'Control' is derived from wxControl, it supports all variables from '5.'
+'Styles' section lists all acceptable flags for style and exstyle variables.
+
+
+ <panel>
+--------- 
+      Control:
+         wxPanel
+
+      Variables:
+         only common controls variables
+
+      Styles:
+         wxNO_3D, wxTAB_TRAVERSAL, wxWS_EX_VALIDATE_RECURSIVELY
+
+
+
+ <dialog>
+----------
+      Control:
+         wxDialog
+
+      Variables:
+         style    style     (= wxDEFAULT_DIALOG_style)
+         text     title     dialog's title         
+
+      Styles:
+         wxSTAY_ON_TOP, wxCAPTION, wxDEFAULT_DIALOG_style, wxTHICK_FRAME,
+         wxSYSTEM_MENU, wxRESIZE_BORDER, wxRESIZE_BOX, wxDIALOG_MODAL,
+         wxDIALOG_MODELESS, wxNO_3D, wxTAB_TRAVERSAL, 
+         wxWS_EX_VALIDATE_RECURSIVELY
+
+
+
+ <boxsizer>
+--------------
+      Control:
+         wxBoxSizer (not a control)
+
+      Behaviour:
+         boxsizer's parent must be either <panel>, <dialog> or another
+         sizer, nothing else!
+         
+         If the sizer does not have parent sizer, the sizer will attach itself
+         to the parent panel/dialog using SetAutoLayout(TRUE) and SetSizer().
+         If the parent panel/dialog has default size (i.e. not specified in
+         the resource), the sizer will fit it using wxSizer::Fit(). If the
+         parent panel/dialog is resizable, size hints will be set 
+         automatically.
+
+      Variables:
+         style    orient    (= wxHORIZONTAL) orientation, either 
+                            wxHORIZONTAL or wxVERTICAL
+
+      Styles:
+         wxHORIZONTAL, wxVERTICAL (for orient variable)
+
+         wxLEFT, wxRIGHT, wxTOP, wxBOTTOM, wxNORTH, wxSOUTH, wxEAST, wxWEST,
+         wxALL, wxGROW, wxEXPAND, wxSHAPED, wxSTRETCH_NOT, wxALIGN_CENTER,
+         wxALIGN_CENTRE, wxALIGN_LEFT, wxALIGN_TOP, wxALIGN_RIGHT, 
+         wxALIGN_BOTTOM, wxALIGN_CENTER_HORIZONTAL, wxALIGN_CENTRE_HORIZONTAL,
+         wxALIGN_CENTER_HORIZONTAL, wxALIGN_CENTRE_HORIZONTAL (for flag
+         variable of <item> or <spacer> child nodes)
+
+      Child nodes:
+         Contains child node <children> which has arbitrary number of
+         <sizeritem> and <spacer> child nodes.
+         
+          <sizeritem>
+         -------------
+            Variables:
+               integer  option    (= 0) relative size of the widget
+               style    flag      (= 0) style flag
+               integer  border    (= 0) surrounding border
+               
+            Has exactly one child node <window> that contains the control
+            (or child sizer because sizers may be nested) 
+            to be inserted into the sizer.
+
+          <spacer>
+         ----------
+            Variables:
+               integer  option    (= 0) relative size of the widget
+               style    flag      (= 0) style flag
+               integer  border    (= 0) surrounding border
+
+            Inserts empty space into the sizer
+            
+
+
+ <staticboxsizer>
+------------------
+      Control:
+         wxStaticBoxSizer (not a control)
+
+      Same as <boxsizer> except that it has additional variable:
+      
+               text     label     (= "") label of surrounding static box
+
+      wxStaticBox required by wxStaticBoxSizer is created automatically!
+
+
+
+ <notebooksizer>
+-----------------
+      Control:
+         wxNotebookSizer (not a control)
+
+      Behaviour:
+         notebooksizer's parent must be a sizer (not notebooksizer,
+         see below)!
+
+      Variables:
+         none
+
+      Styles:
+         none
+
+      Child nodes:
+         Has exactly one child node <window> that contains the notebook
+         (nothing else is allowed!) to be inserted into the sizer.
+
+
+
+ <textctrl>
+------------ 
+      Control:
+         wxTextCtrl
+
+      Variables:
+         text     value     (= "")default text of the control
+
+      Styles:
+         wxTE_PROCESS_ENTER, wxTE_PROCESS_TAB, wxTE_MULTILINE, wxTE_PASSWORD,
+         wxTE_READONLY, wxHSCROLL
+
+
+
+ <htmlwindow>
+--------------
+      Control:
+         wxHtmlWindow
+
+      Variables:
+         integer  borders   (= 0) window's borders 
+                            (see wxHtmlWindow::SetBorders)
+         text     url       (= "") if present, given page will be loaded
+         text     htmlcode  (= "") if present, given _text_ will be displayed                            
+                            (you will have to use CDATA section
+                            to embed HTML code into XML document)
+
+      Styles:
+         wxHW_SCROLLBAR_NEVER, wxHW_SCROLLBAR_AUTO
diff --git a/contrib/src/xrc/Makefile.in b/contrib/src/xrc/Makefile.in
new file mode 100644 (file)
index 0000000..0748bc4
--- /dev/null
@@ -0,0 +1,41 @@
+# $Id$
+
+top_srcdir = @top_srcdir@/..
+top_builddir = ../../..
+
+expat_dir = $(top_srcdir)/contrib/src/xrc/expat
+libsrc_dir = contrib/src/xrc@PATH_IFS@$(expat_dir)/xmlparse@PATH_IFS@$(expat_dir)/xmltok
+
+
+TARGET_LIBNAME=libwxxrc
+
+LIBVERSION_CURRENT=0
+LIBVERSION_REVISION=1
+LIBVERSION_AGE=0
+
+HEADER_PATH=$(top_srcdir)/contrib/include/wx
+HEADER_SUBDIR=xrc
+
+EXPAT_DEFS=-I$(expat_dir)/xmlparse -I$(expat_dir)/xmltok
+EXPAT_OBJECTS=xmltok.o xmlrole.o xmlparse.o
+
+HEADERS=xh_all.h xh_bttn.h xh_chckb.h xh_chckl.h xh_choic.h xh_combo.h \
+        xh_dlg.h xh_gauge.h xh_html.h xh_menu.h xh_notbk.h xh_panel.h \
+        xh_radbt.h xh_radbx.h xh_sizer.h xh_slidr.h xh_spin.h xh_stbmp.h \
+        xh_sttxt.h xh_text.h xh_listb.h xml.h xmlio.h xmlres.h xh_toolb.h \
+        xh_bmpbt.h xh_cald.h xh_listc.h xh_scrol.h xh_stbox.h xh_tree.h \
+        xh_stlin.h xh_bmp.h xh_unkwn.h xh_frame.h
+
+OBJECTS=$(EXPAT_OBJECTS) \
+        xml.o xmlbin.o xmlbinz.o xmlexpat.o xmlwrite.o xmlres.o xmlrsall.o \
+        xh_bttn.o xh_chckb.o xh_chckl.o xh_choic.o xh_combo.o xh_dlg.o \
+        xh_gauge.o xh_html.o xh_menu.o xh_notbk.o xh_panel.o xh_radbt.o \
+        xh_radbx.o xh_sizer.o xh_slidr.o xh_spin.o xh_stbmp.o xh_sttxt.o \
+        xh_text.o xh_listb.o xh_toolb.o xh_stlin.o xh_bmp.o xh_unkwn.o \
+        xh_bmpbt.o xh_cald.o xh_listc.o xh_scrol.o xh_stbox.o xh_tree.o \
+        xh_frame.o
+
+APPEXTRADEFS=-I$(top_srcdir)/contrib/include $(EXPAT_DEFS)
+
+include $(top_builddir)/src/makelib.env
+
diff --git a/contrib/src/xrc/README.EXPAT b/contrib/src/xrc/README.EXPAT
new file mode 100644 (file)
index 0000000..a85c615
--- /dev/null
@@ -0,0 +1,39 @@
+
+./expat directory contains stripped-down version of Expat parser distribution
+by J. Clark. I removed stuff not neccessary for wxXML (docs, samples), if you
+are interested in it, please download full distribution from Clark's site
+(http://www.jclark.com).
+
+Version used is expat-1.2.
+
+The Expat parser is available is licensed under the MIT license as follows:
+
+
+
+      Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+
+      Permission is hereby granted, free of charge, to any person obtaining
+      a copy of this software and associated documentation files (the
+      "Software"), to deal in the Software without restriction, including
+      without limitation the rights to use, copy, modify, merge, publish,
+      distribute, sublicense, and/or sell copies of the Software, and to
+      permit persons to whom the Software is furnished to do so, subject to
+      the following conditions:
+
+      The above copyright notice and this permission notice shall be included
+      in all copies or substantial portions of the Software.
+
+      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+      EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+      IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+      CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+      TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+      SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+In other words, there shouldn't be any legal issues with using Expat in
+your application.
+
+                         Vaclav Slavik <v.slavik@volny.cz>
diff --git a/contrib/src/xrc/expat/copying.txt b/contrib/src/xrc/expat/copying.txt
new file mode 100644 (file)
index 0000000..bf0f567
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/contrib/src/xrc/expat/xmlparse/xmlparse.c b/contrib/src/xrc/expat/xmlparse/xmlparse.c
new file mode 100644 (file)
index 0000000..d11a146
--- /dev/null
@@ -0,0 +1,3925 @@
+/*
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#include "xmldef.h"
+#include "xmlparse.h"
+#include <stddef.h>
+
+#ifdef XML_UNICODE
+#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
+#define XmlConvert XmlUtf16Convert
+#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
+#define XmlEncode XmlUtf16Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
+typedef unsigned short ICHAR;
+#else
+#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
+#define XmlConvert XmlUtf8Convert
+#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
+#define XmlEncode XmlUtf8Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
+typedef char ICHAR;
+#endif
+
+
+#ifndef XML_NS
+
+#define XmlInitEncodingNS XmlInitEncoding
+#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
+#undef XmlGetInternalEncodingNS
+#define XmlGetInternalEncodingNS XmlGetInternalEncoding
+#define XmlParseXmlDeclNS XmlParseXmlDecl
+
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_T(x) L ## x
+#else
+#define XML_T(x) x
+#endif
+
+/* Round up n to be a multiple of sz, where sz is a power of 2. */
+#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
+
+#include "xmltok.h"
+#include "xmlrole.h"
+
+typedef const XML_Char *KEY;
+
+typedef struct {
+  KEY name;
+} NAMED;
+
+typedef struct {
+  NAMED **v;
+  size_t size;
+  size_t used;
+  size_t usedLim;
+} HASH_TABLE;
+
+typedef struct {
+  NAMED **p;
+  NAMED **end;
+} HASH_TABLE_ITER;
+
+#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
+#define INIT_DATA_BUF_SIZE 1024
+#define INIT_ATTS_SIZE 16
+#define INIT_BLOCK_SIZE 1024
+#define INIT_BUFFER_SIZE 1024
+
+#define EXPAND_SPARE 24
+
+typedef struct binding {
+  struct prefix *prefix;
+  struct binding *nextTagBinding;
+  struct binding *prevPrefixBinding;
+  const struct attribute_id *attId;
+  XML_Char *uri;
+  int uriLen;
+  int uriAlloc;
+} BINDING;
+
+typedef struct prefix {
+  const XML_Char *name;
+  BINDING *binding;
+} PREFIX;
+
+typedef struct {
+  const XML_Char *str;
+  const XML_Char *localPart;
+  int uriLen;
+} TAG_NAME;
+
+typedef struct tag {
+  struct tag *parent;
+  const char *rawName;
+  int rawNameLength;
+  TAG_NAME name;
+  char *buf;
+  char *bufEnd;
+  BINDING *bindings;
+} TAG;
+
+typedef struct {
+  const XML_Char *name;
+  const XML_Char *textPtr;
+  int textLen;
+  const XML_Char *systemId;
+  const XML_Char *base;
+  const XML_Char *publicId;
+  const XML_Char *notation;
+  char open;
+} ENTITY;
+
+typedef struct block {
+  struct block *next;
+  int size;
+  XML_Char s[1];
+} BLOCK;
+
+typedef struct {
+  BLOCK *blocks;
+  BLOCK *freeBlocks;
+  const XML_Char *end;
+  XML_Char *ptr;
+  XML_Char *start;
+} STRING_POOL;
+
+/* The XML_Char before the name is used to determine whether
+an attribute has been specified. */
+typedef struct attribute_id {
+  XML_Char *name;
+  PREFIX *prefix;
+  char maybeTokenized;
+  char xmlns;
+} ATTRIBUTE_ID;
+
+typedef struct {
+  const ATTRIBUTE_ID *id;
+  char isCdata;
+  const XML_Char *value;
+} DEFAULT_ATTRIBUTE;
+
+typedef struct {
+  const XML_Char *name;
+  PREFIX *prefix;
+  const ATTRIBUTE_ID *idAtt;
+  int nDefaultAtts;
+  int allocDefaultAtts;
+  DEFAULT_ATTRIBUTE *defaultAtts;
+} ELEMENT_TYPE;
+
+typedef struct {
+  HASH_TABLE generalEntities;
+  HASH_TABLE elementTypes;
+  HASH_TABLE attributeIds;
+  HASH_TABLE prefixes;
+  STRING_POOL pool;
+  int complete;
+  int standalone;
+#ifdef XML_DTD
+  HASH_TABLE paramEntities;
+#endif /* XML_DTD */
+  PREFIX defaultPrefix;
+} DTD;
+
+typedef struct open_internal_entity {
+  const char *internalEventPtr;
+  const char *internalEventEndPtr;
+  struct open_internal_entity *next;
+  ENTITY *entity;
+} OPEN_INTERNAL_ENTITY;
+
+typedef enum XML_Error Processor(XML_Parser parser,
+                                const char *start,
+                                const char *end,
+                                const char **endPtr);
+
+static Processor prologProcessor;
+static Processor prologInitProcessor;
+static Processor contentProcessor;
+static Processor cdataSectionProcessor;
+#ifdef XML_DTD
+static Processor ignoreSectionProcessor;
+#endif /* XML_DTD */
+static Processor epilogProcessor;
+static Processor errorProcessor;
+static Processor externalEntityInitProcessor;
+static Processor externalEntityInitProcessor2;
+static Processor externalEntityInitProcessor3;
+static Processor externalEntityContentProcessor;
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
+static enum XML_Error
+initializeEncoding(XML_Parser parser);
+static enum XML_Error
+doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
+        const char *end, int tok, const char *next, const char **nextPtr);
+static enum XML_Error
+processInternalParamEntity(XML_Parser parser, ENTITY *entity);
+static enum XML_Error
+doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
+         const char *start, const char *end, const char **endPtr);
+static enum XML_Error
+doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
+#ifdef XML_DTD
+static enum XML_Error
+doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
+#endif /* XML_DTD */
+static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
+                               TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
+static
+int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, int isId, const XML_Char *dfltValue);
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
+                   STRING_POOL *);
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
+                   STRING_POOL *);
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
+static enum XML_Error
+storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static int
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+
+static const XML_Char *getContext(XML_Parser parser);
+static int setContext(XML_Parser parser, const XML_Char *context);
+static void normalizePublicId(XML_Char *s);
+static int dtdInit(DTD *);
+static void dtdDestroy(DTD *);
+static int dtdCopy(DTD *newDtd, const DTD *oldDtd);
+static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
+#ifdef XML_DTD
+static void dtdSwap(DTD *, DTD *);
+#endif /* XML_DTD */
+static NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
+static void hashTableInit(HASH_TABLE *);
+static void hashTableDestroy(HASH_TABLE *);
+static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
+static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
+static void poolInit(STRING_POOL *);
+static void poolClear(STRING_POOL *);
+static void poolDestroy(STRING_POOL *);
+static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
+                           const char *ptr, const char *end);
+static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+                                 const char *ptr, const char *end);
+static int poolGrow(STRING_POOL *pool);
+static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
+static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
+
+#define poolStart(pool) ((pool)->start)
+#define poolEnd(pool) ((pool)->ptr)
+#define poolLength(pool) ((pool)->ptr - (pool)->start)
+#define poolChop(pool) ((void)--(pool->ptr))
+#define poolLastChar(pool) (((pool)->ptr)[-1])
+#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
+#define poolFinish(pool) ((pool)->start = (pool)->ptr)
+#define poolAppendChar(pool, c) \
+  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
+   ? 0 \
+   : ((*((pool)->ptr)++ = c), 1))
+
+typedef struct {
+  /* The first member must be userData so that the XML_GetUserData macro works. */
+  void *m_userData;
+  void *m_handlerArg;
+  char *m_buffer;
+  /* first character to be parsed */
+  const char *m_bufferPtr;
+  /* past last character to be parsed */
+  char *m_bufferEnd;
+  /* allocated end of buffer */
+  const char *m_bufferLim;
+  long m_parseEndByteIndex;
+  const char *m_parseEndPtr;
+  XML_Char *m_dataBuf;
+  XML_Char *m_dataBufEnd;
+  XML_StartElementHandler m_startElementHandler;
+  XML_EndElementHandler m_endElementHandler;
+  XML_CharacterDataHandler m_characterDataHandler;
+  XML_ProcessingInstructionHandler m_processingInstructionHandler;
+  XML_CommentHandler m_commentHandler;
+  XML_StartCdataSectionHandler m_startCdataSectionHandler;
+  XML_EndCdataSectionHandler m_endCdataSectionHandler;
+  XML_DefaultHandler m_defaultHandler;
+  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
+  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
+  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
+  XML_NotationDeclHandler m_notationDeclHandler;
+  XML_ExternalParsedEntityDeclHandler m_externalParsedEntityDeclHandler;
+  XML_InternalParsedEntityDeclHandler m_internalParsedEntityDeclHandler;
+  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
+  XML_NotStandaloneHandler m_notStandaloneHandler;
+  XML_ExternalEntityRefHandler m_externalEntityRefHandler;
+  void *m_externalEntityRefHandlerArg;
+  XML_UnknownEncodingHandler m_unknownEncodingHandler;
+  const ENCODING *m_encoding;
+  INIT_ENCODING m_initEncoding;
+  const ENCODING *m_internalEncoding;
+  const XML_Char *m_protocolEncodingName;
+  int m_ns;
+  void *m_unknownEncodingMem;
+  void *m_unknownEncodingData;
+  void *m_unknownEncodingHandlerData;
+  void (*m_unknownEncodingRelease)(void *);
+  PROLOG_STATE m_prologState;
+  Processor *m_processor;
+  enum XML_Error m_errorCode;
+  const char *m_eventPtr;
+  const char *m_eventEndPtr;
+  const char *m_positionPtr;
+  OPEN_INTERNAL_ENTITY *m_openInternalEntities;
+  int m_defaultExpandInternalEntities;
+  int m_tagLevel;
+  ENTITY *m_declEntity;
+  const XML_Char *m_declNotationName;
+  const XML_Char *m_declNotationPublicId;
+  ELEMENT_TYPE *m_declElementType;
+  ATTRIBUTE_ID *m_declAttributeId;
+  char m_declAttributeIsCdata;
+  char m_declAttributeIsId;
+  DTD m_dtd;
+  const XML_Char *m_curBase;
+  TAG *m_tagStack;
+  TAG *m_freeTagList;
+  BINDING *m_inheritedBindings;
+  BINDING *m_freeBindingList;
+  int m_attsSize;
+  int m_nSpecifiedAtts;
+  int m_idAttIndex;
+  ATTRIBUTE *m_atts;
+  POSITION m_position;
+  STRING_POOL m_tempPool;
+  STRING_POOL m_temp2Pool;
+  char *m_groupConnector;
+  unsigned m_groupSize;
+  int m_hadExternalDoctype;
+  XML_Char m_namespaceSeparator;
+#ifdef XML_DTD
+  enum XML_ParamEntityParsing m_paramEntityParsing;
+  XML_Parser m_parentParser;
+#endif
+} Parser;
+
+#define userData (((Parser *)parser)->m_userData)
+#define handlerArg (((Parser *)parser)->m_handlerArg)
+#define startElementHandler (((Parser *)parser)->m_startElementHandler)
+#define endElementHandler (((Parser *)parser)->m_endElementHandler)
+#define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
+#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
+#define commentHandler (((Parser *)parser)->m_commentHandler)
+#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
+#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
+#define defaultHandler (((Parser *)parser)->m_defaultHandler)
+#define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
+#define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
+#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
+#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
+#define externalParsedEntityDeclHandler (((Parser *)parser)->m_externalParsedEntityDeclHandler)
+#define internalParsedEntityDeclHandler (((Parser *)parser)->m_internalParsedEntityDeclHandler)
+#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
+#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
+#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
+#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
+#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
+#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
+#define encoding (((Parser *)parser)->m_encoding)
+#define initEncoding (((Parser *)parser)->m_initEncoding)
+#define internalEncoding (((Parser *)parser)->m_internalEncoding)
+#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
+#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
+#define unknownEncodingHandlerData \
+  (((Parser *)parser)->m_unknownEncodingHandlerData)
+#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
+#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
+#define ns (((Parser *)parser)->m_ns)
+#define prologState (((Parser *)parser)->m_prologState)
+#define processor (((Parser *)parser)->m_processor)
+#define errorCode (((Parser *)parser)->m_errorCode)
+#define eventPtr (((Parser *)parser)->m_eventPtr)
+#define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
+#define positionPtr (((Parser *)parser)->m_positionPtr)
+#define position (((Parser *)parser)->m_position)
+#define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
+#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
+#define tagLevel (((Parser *)parser)->m_tagLevel)
+#define buffer (((Parser *)parser)->m_buffer)
+#define bufferPtr (((Parser *)parser)->m_bufferPtr)
+#define bufferEnd (((Parser *)parser)->m_bufferEnd)
+#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
+#define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
+#define bufferLim (((Parser *)parser)->m_bufferLim)
+#define dataBuf (((Parser *)parser)->m_dataBuf)
+#define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
+#define dtd (((Parser *)parser)->m_dtd)
+#define curBase (((Parser *)parser)->m_curBase)
+#define declEntity (((Parser *)parser)->m_declEntity)
+#define declNotationName (((Parser *)parser)->m_declNotationName)
+#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
+#define declElementType (((Parser *)parser)->m_declElementType)
+#define declAttributeId (((Parser *)parser)->m_declAttributeId)
+#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
+#define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
+#define freeTagList (((Parser *)parser)->m_freeTagList)
+#define freeBindingList (((Parser *)parser)->m_freeBindingList)
+#define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
+#define tagStack (((Parser *)parser)->m_tagStack)
+#define atts (((Parser *)parser)->m_atts)
+#define attsSize (((Parser *)parser)->m_attsSize)
+#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
+#define idAttIndex (((Parser *)parser)->m_idAttIndex)
+#define tempPool (((Parser *)parser)->m_tempPool)
+#define temp2Pool (((Parser *)parser)->m_temp2Pool)
+#define groupConnector (((Parser *)parser)->m_groupConnector)
+#define groupSize (((Parser *)parser)->m_groupSize)
+#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
+#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
+#ifdef XML_DTD
+#define parentParser (((Parser *)parser)->m_parentParser)
+#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
+#endif /* XML_DTD */
+
+#ifdef _MSC_VER
+#ifdef _DEBUG
+Parser *asParser(XML_Parser parser)
+{
+  return parser;
+}
+#endif
+#endif
+
+XML_Parser XML_ParserCreate(const XML_Char *encodingName)
+{
+  XML_Parser parser = malloc(sizeof(Parser));
+  if (!parser)
+    return parser;
+  processor = prologInitProcessor;
+  XmlPrologStateInit(&prologState);
+  userData = 0;
+  handlerArg = 0;
+  startElementHandler = 0;
+  endElementHandler = 0;
+  characterDataHandler = 0;
+  processingInstructionHandler = 0;
+  commentHandler = 0;
+  startCdataSectionHandler = 0;
+  endCdataSectionHandler = 0;
+  defaultHandler = 0;
+  startDoctypeDeclHandler = 0;
+  endDoctypeDeclHandler = 0;
+  unparsedEntityDeclHandler = 0;
+  notationDeclHandler = 0;
+  externalParsedEntityDeclHandler = 0;
+  internalParsedEntityDeclHandler = 0;
+  startNamespaceDeclHandler = 0;
+  endNamespaceDeclHandler = 0;
+  notStandaloneHandler = 0;
+  externalEntityRefHandler = 0;
+  externalEntityRefHandlerArg = parser;
+  unknownEncodingHandler = 0;
+  buffer = 0;
+  bufferPtr = 0;
+  bufferEnd = 0;
+  parseEndByteIndex = 0;
+  parseEndPtr = 0;
+  bufferLim = 0;
+  declElementType = 0;
+  declAttributeId = 0;
+  declEntity = 0;
+  declNotationName = 0;
+  declNotationPublicId = 0;
+  memset(&position, 0, sizeof(POSITION));
+  errorCode = XML_ERROR_NONE;
+  eventPtr = 0;
+  eventEndPtr = 0;
+  positionPtr = 0;
+  openInternalEntities = 0;
+  tagLevel = 0;
+  tagStack = 0;
+  freeTagList = 0;
+  freeBindingList = 0;
+  inheritedBindings = 0;
+  attsSize = INIT_ATTS_SIZE;
+  atts = malloc(attsSize * sizeof(ATTRIBUTE));
+  nSpecifiedAtts = 0;
+  dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+  groupSize = 0;
+  groupConnector = 0;
+  hadExternalDoctype = 0;
+  unknownEncodingMem = 0;
+  unknownEncodingRelease = 0;
+  unknownEncodingData = 0;
+  unknownEncodingHandlerData = 0;
+  namespaceSeparator = '!';
+#ifdef XML_DTD
+  parentParser = 0;
+  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+  ns = 0;
+  poolInit(&tempPool);
+  poolInit(&temp2Pool);
+  protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
+  curBase = 0;
+  if (!dtdInit(&dtd) || !atts || !dataBuf
+      || (encodingName && !protocolEncodingName)) {
+    XML_ParserFree(parser);
+    return 0;
+  }
+  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
+  XmlInitEncoding(&initEncoding, &encoding, 0);
+  internalEncoding = XmlGetInternalEncoding();
+  return parser;
+}
+
+XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
+{
+  static
+  const XML_Char implicitContext[] = {
+    XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
+    XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
+    XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
+    XML_T('.'), XML_T('w'), XML_T('3'),
+    XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
+    XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
+    XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
+    XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
+    XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
+    XML_T('\0')
+  };
+
+  XML_Parser parser = XML_ParserCreate(encodingName);
+  if (parser) {
+    XmlInitEncodingNS(&initEncoding, &encoding, 0);
+    ns = 1;
+    internalEncoding = XmlGetInternalEncodingNS();
+    namespaceSeparator = nsSep;
+  }
+  if (!setContext(parser, implicitContext)) {
+    XML_ParserFree(parser);
+    return 0;
+  }
+  return parser;
+}
+
+int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+  if (!encodingName)
+    protocolEncodingName = 0;
+  else {
+    protocolEncodingName = poolCopyString(&tempPool, encodingName);
+    if (!protocolEncodingName)
+      return 0;
+  }
+  return 1;
+}
+
+XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
+                                         const XML_Char *context,
+                                         const XML_Char *encodingName)
+{
+  XML_Parser parser = oldParser;
+  DTD *oldDtd = &dtd;
+  XML_StartElementHandler oldStartElementHandler = startElementHandler;
+  XML_EndElementHandler oldEndElementHandler = endElementHandler;
+  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
+  XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
+  XML_CommentHandler oldCommentHandler = commentHandler;
+  XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
+  XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
+  XML_DefaultHandler oldDefaultHandler = defaultHandler;
+  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
+  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
+  XML_ExternalParsedEntityDeclHandler oldExternalParsedEntityDeclHandler = externalParsedEntityDeclHandler;
+  XML_InternalParsedEntityDeclHandler oldInternalParsedEntityDeclHandler = internalParsedEntityDeclHandler;
+  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
+  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
+  XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
+  XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
+  void *oldUserData = userData;
+  void *oldHandlerArg = handlerArg;
+  int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+  void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+#ifdef XML_DTD
+  int oldParamEntityParsing = paramEntityParsing;
+#endif
+  parser = (ns
+            ? XML_ParserCreateNS(encodingName, namespaceSeparator)
+           : XML_ParserCreate(encodingName));
+  if (!parser)
+    return 0;
+  startElementHandler = oldStartElementHandler;
+  endElementHandler = oldEndElementHandler;
+  characterDataHandler = oldCharacterDataHandler;
+  processingInstructionHandler = oldProcessingInstructionHandler;
+  commentHandler = oldCommentHandler;
+  startCdataSectionHandler = oldStartCdataSectionHandler;
+  endCdataSectionHandler = oldEndCdataSectionHandler;
+  defaultHandler = oldDefaultHandler;
+  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
+  notationDeclHandler = oldNotationDeclHandler;
+  externalParsedEntityDeclHandler = oldExternalParsedEntityDeclHandler;
+  internalParsedEntityDeclHandler = oldInternalParsedEntityDeclHandler;
+  startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
+  endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
+  notStandaloneHandler = oldNotStandaloneHandler;
+  externalEntityRefHandler = oldExternalEntityRefHandler;
+  unknownEncodingHandler = oldUnknownEncodingHandler;
+  userData = oldUserData;
+  if (oldUserData == oldHandlerArg)
+    handlerArg = userData;
+  else
+    handlerArg = parser;
+  if (oldExternalEntityRefHandlerArg != oldParser)
+    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
+  defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
+#ifdef XML_DTD
+  paramEntityParsing = oldParamEntityParsing;
+  if (context) {
+#endif /* XML_DTD */
+    if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) {
+      XML_ParserFree(parser);
+      return 0;
+    }
+    processor = externalEntityInitProcessor;
+#ifdef XML_DTD
+  }
+  else {
+    dtdSwap(&dtd, oldDtd);
+    parentParser = oldParser;
+    XmlPrologStateInitExternalEntity(&prologState);
+    dtd.complete = 1;
+    hadExternalDoctype = 1;
+  }
+#endif /* XML_DTD */
+  return parser;
+}
+
+static
+void destroyBindings(BINDING *bindings)
+{
+  for (;;) {
+    BINDING *b = bindings;
+    if (!b)
+      break;
+    bindings = b->nextTagBinding;
+    free(b->uri);
+    free(b);
+  }
+}
+
+void XML_ParserFree(XML_Parser parser)
+{
+  for (;;) {
+    TAG *p;
+    if (tagStack == 0) {
+      if (freeTagList == 0)
+       break;
+      tagStack = freeTagList;
+      freeTagList = 0;
+    }
+    p = tagStack;
+    tagStack = tagStack->parent;
+    free(p->buf);
+    destroyBindings(p->bindings);
+    free(p);
+  }
+  destroyBindings(freeBindingList);
+  destroyBindings(inheritedBindings);
+  poolDestroy(&tempPool);
+  poolDestroy(&temp2Pool);
+#ifdef XML_DTD
+  if (parentParser) {
+    if (hadExternalDoctype)
+      dtd.complete = 0;
+    dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
+  }
+#endif /* XML_DTD */
+  dtdDestroy(&dtd);
+  free((void *)atts);
+  free(groupConnector);
+  free(buffer);
+  free(dataBuf);
+  free(unknownEncodingMem);
+  if (unknownEncodingRelease)
+    unknownEncodingRelease(unknownEncodingData);
+  free(parser);
+}
+
+void XML_UseParserAsHandlerArg(XML_Parser parser)
+{
+  handlerArg = parser;
+}
+
+void XML_SetUserData(XML_Parser parser, void *p)
+{
+  if (handlerArg == userData)
+    handlerArg = userData = p;
+  else
+    userData = p;
+}
+
+int XML_SetBase(XML_Parser parser, const XML_Char *p)
+{
+  if (p) {
+    p = poolCopyString(&dtd.pool, p);
+    if (!p)
+      return 0;
+    curBase = p;
+  }
+  else
+    curBase = 0;
+  return 1;
+}
+
+const XML_Char *XML_GetBase(XML_Parser parser)
+{
+  return curBase;
+}
+
+int XML_GetSpecifiedAttributeCount(XML_Parser parser)
+{
+  return nSpecifiedAtts;
+}
+
+int XML_GetIdAttributeIndex(XML_Parser parser)
+{
+  return idAttIndex;
+}
+
+void XML_SetElementHandler(XML_Parser parser,
+                          XML_StartElementHandler start,
+                          XML_EndElementHandler end)
+{
+  startElementHandler = start;
+  endElementHandler = end;
+}
+
+void XML_SetCharacterDataHandler(XML_Parser parser,
+                                XML_CharacterDataHandler handler)
+{
+  characterDataHandler = handler;
+}
+
+void XML_SetProcessingInstructionHandler(XML_Parser parser,
+                                        XML_ProcessingInstructionHandler handler)
+{
+  processingInstructionHandler = handler;
+}
+
+void XML_SetCommentHandler(XML_Parser parser,
+                          XML_CommentHandler handler)
+{
+  commentHandler = handler;
+}
+
+void XML_SetCdataSectionHandler(XML_Parser parser,
+                               XML_StartCdataSectionHandler start,
+                               XML_EndCdataSectionHandler end)
+{
+  startCdataSectionHandler = start;
+  endCdataSectionHandler = end;
+}
+
+void XML_SetDefaultHandler(XML_Parser parser,
+                          XML_DefaultHandler handler)
+{
+  defaultHandler = handler;
+  defaultExpandInternalEntities = 0;
+}
+
+void XML_SetDefaultHandlerExpand(XML_Parser parser,
+                                XML_DefaultHandler handler)
+{
+  defaultHandler = handler;
+  defaultExpandInternalEntities = 1;
+}
+
+void XML_SetDoctypeDeclHandler(XML_Parser parser,
+                              XML_StartDoctypeDeclHandler start,
+                              XML_EndDoctypeDeclHandler end)
+{
+  startDoctypeDeclHandler = start;
+  endDoctypeDeclHandler = end;
+}
+
+void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+                                     XML_UnparsedEntityDeclHandler handler)
+{
+  unparsedEntityDeclHandler = handler;
+}
+
+void XML_SetExternalParsedEntityDeclHandler(XML_Parser parser,
+                                           XML_ExternalParsedEntityDeclHandler handler)
+{
+  externalParsedEntityDeclHandler = handler;
+}
+
+void XML_SetInternalParsedEntityDeclHandler(XML_Parser parser,
+                                           XML_InternalParsedEntityDeclHandler handler)
+{
+  internalParsedEntityDeclHandler = handler;
+}
+
+void XML_SetNotationDeclHandler(XML_Parser parser,
+                               XML_NotationDeclHandler handler)
+{
+  notationDeclHandler = handler;
+}
+
+void XML_SetNamespaceDeclHandler(XML_Parser parser,
+                                XML_StartNamespaceDeclHandler start,
+                                XML_EndNamespaceDeclHandler end)
+{
+  startNamespaceDeclHandler = start;
+  endNamespaceDeclHandler = end;
+}
+
+void XML_SetNotStandaloneHandler(XML_Parser parser,
+                                XML_NotStandaloneHandler handler)
+{
+  notStandaloneHandler = handler;
+}
+
+void XML_SetExternalEntityRefHandler(XML_Parser parser,
+                                    XML_ExternalEntityRefHandler handler)
+{
+  externalEntityRefHandler = handler;
+}
+
+void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
+{
+  if (arg)
+    externalEntityRefHandlerArg = arg;
+  else
+    externalEntityRefHandlerArg = parser;
+}
+
+void XML_SetUnknownEncodingHandler(XML_Parser parser,
+                                  XML_UnknownEncodingHandler handler,
+                                  void *data)
+{
+  unknownEncodingHandler = handler;
+  unknownEncodingHandlerData = data;
+}
+
+int XML_SetParamEntityParsing(XML_Parser parser,
+                             enum XML_ParamEntityParsing parsing)
+{
+#ifdef XML_DTD
+  paramEntityParsing = parsing;
+  return 1;
+#else
+  return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
+
+int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
+{
+  if (len == 0) {
+    if (!isFinal)
+      return 1;
+    positionPtr = bufferPtr;
+    errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
+    if (errorCode == XML_ERROR_NONE)
+      return 1;
+    eventEndPtr = eventPtr;
+    processor = errorProcessor;
+    return 0;
+  }
+  else if (bufferPtr == bufferEnd) {
+    const char *end;
+    int nLeftOver;
+    parseEndByteIndex += len;
+    positionPtr = s;
+    if (isFinal) {
+      errorCode = processor(parser, s, parseEndPtr = s + len, 0);
+      if (errorCode == XML_ERROR_NONE)
+       return 1;
+      eventEndPtr = eventPtr;
+      processor = errorProcessor;
+      return 0;
+    }
+    errorCode = processor(parser, s, parseEndPtr = s + len, &end);
+    if (errorCode != XML_ERROR_NONE) {
+      eventEndPtr = eventPtr;
+      processor = errorProcessor;
+      return 0;
+    }
+    XmlUpdatePosition(encoding, positionPtr, end, &position);
+    nLeftOver = s + len - end;
+    if (nLeftOver) {
+      if (buffer == 0 || nLeftOver > bufferLim - buffer) {
+       /* FIXME avoid integer overflow */
+       buffer = buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2);
+       /* FIXME storage leak if realloc fails */
+       if (!buffer) {
+         errorCode = XML_ERROR_NO_MEMORY;
+         eventPtr = eventEndPtr = 0;
+         processor = errorProcessor;
+         return 0;
+       }
+       bufferLim = buffer + len * 2;
+      }
+      memcpy(buffer, end, nLeftOver);
+      bufferPtr = buffer;
+      bufferEnd = buffer + nLeftOver;
+    }
+    return 1;
+  }
+  else {
+    memcpy(XML_GetBuffer(parser, len), s, len);
+    return XML_ParseBuffer(parser, len, isFinal);
+  }
+}
+
+int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
+{
+  const char *start = bufferPtr;
+  positionPtr = start;
+  bufferEnd += len;
+  parseEndByteIndex += len;
+  errorCode = processor(parser, start, parseEndPtr = bufferEnd,
+                       isFinal ? (const char **)0 : &bufferPtr);
+  if (errorCode == XML_ERROR_NONE) {
+    if (!isFinal)
+      XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+    return 1;
+  }
+  else {
+    eventEndPtr = eventPtr;
+    processor = errorProcessor;
+    return 0;
+  }
+}
+
+void *XML_GetBuffer(XML_Parser parser, int len)
+{
+  if (len > bufferLim - bufferEnd) {
+    /* FIXME avoid integer overflow */
+    int neededSize = len + (bufferEnd - bufferPtr);
+    if (neededSize  <= bufferLim - buffer) {
+      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
+      bufferEnd = buffer + (bufferEnd - bufferPtr);
+      bufferPtr = buffer;
+    }
+    else {
+      char *newBuf;
+      int bufferSize = bufferLim - bufferPtr;
+      if (bufferSize == 0)
+       bufferSize = INIT_BUFFER_SIZE;
+      do {
+       bufferSize *= 2;
+      } while (bufferSize < neededSize);
+      newBuf = malloc(bufferSize);
+      if (newBuf == 0) {
+       errorCode = XML_ERROR_NO_MEMORY;
+       return 0;
+      }
+      bufferLim = newBuf + bufferSize;
+      if (bufferPtr) {
+       memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
+       free(buffer);
+      }
+      bufferEnd = newBuf + (bufferEnd - bufferPtr);
+      bufferPtr = buffer = newBuf;
+    }
+  }
+  return bufferEnd;
+}
+
+enum XML_Error XML_GetErrorCode(XML_Parser parser)
+{
+  return errorCode;
+}
+
+long XML_GetCurrentByteIndex(XML_Parser parser)
+{
+  if (eventPtr)
+    return parseEndByteIndex - (parseEndPtr - eventPtr);
+  return -1;
+}
+
+int XML_GetCurrentByteCount(XML_Parser parser)
+{
+  if (eventEndPtr && eventPtr)
+    return eventEndPtr - eventPtr;
+  return 0;
+}
+
+int XML_GetCurrentLineNumber(XML_Parser parser)
+{
+  if (eventPtr) {
+    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+    positionPtr = eventPtr;
+  }
+  return position.lineNumber + 1;
+}
+
+int XML_GetCurrentColumnNumber(XML_Parser parser)
+{
+  if (eventPtr) {
+    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+    positionPtr = eventPtr;
+  }
+  return position.columnNumber;
+}
+
+void XML_DefaultCurrent(XML_Parser parser)
+{
+  if (defaultHandler) {
+    if (openInternalEntities)
+      reportDefault(parser,
+                   internalEncoding,
+                   openInternalEntities->internalEventPtr,
+                   openInternalEntities->internalEventEndPtr);
+    else
+      reportDefault(parser, encoding, eventPtr, eventEndPtr);
+  }
+}
+
+const XML_LChar *XML_ErrorString(int code)
+{
+  static const XML_LChar *message[] = {
+    0,
+    XML_T("out of memory"),
+    XML_T("syntax error"),
+    XML_T("no element found"),
+    XML_T("not well-formed"),
+    XML_T("unclosed token"),
+    XML_T("unclosed token"),
+    XML_T("mismatched tag"),
+    XML_T("duplicate attribute"),
+    XML_T("junk after document element"),
+    XML_T("illegal parameter entity reference"),
+    XML_T("undefined entity"),
+    XML_T("recursive entity reference"),
+    XML_T("asynchronous entity"),
+    XML_T("reference to invalid character number"),
+    XML_T("reference to binary entity"),
+    XML_T("reference to external entity in attribute"),
+    XML_T("xml processing instruction not at start of external entity"),
+    XML_T("unknown encoding"),
+    XML_T("encoding specified in XML declaration is incorrect"),
+    XML_T("unclosed CDATA section"),
+    XML_T("error in processing external entity reference"),
+    XML_T("document is not standalone")
+  };
+  if (code > 0 && code < sizeof(message)/sizeof(message[0]))
+    return message[code];
+  return 0;
+}
+
+static
+enum XML_Error contentProcessor(XML_Parser parser,
+                               const char *start,
+                               const char *end,
+                               const char **endPtr)
+{
+  return doContent(parser, 0, encoding, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor(XML_Parser parser,
+                                          const char *start,
+                                          const char *end,
+                                          const char **endPtr)
+{
+  enum XML_Error result = initializeEncoding(parser);
+  if (result != XML_ERROR_NONE)
+    return result;
+  processor = externalEntityInitProcessor2;
+  return externalEntityInitProcessor2(parser, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
+                                           const char *start,
+                                           const char *end,
+                                           const char **endPtr)
+{
+  const char *next;
+  int tok = XmlContentTok(encoding, start, end, &next);
+  switch (tok) {
+  case XML_TOK_BOM:
+    start = next;
+    break;
+  case XML_TOK_PARTIAL:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_UNCLOSED_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_PARTIAL_CHAR;
+  }
+  processor = externalEntityInitProcessor3;
+  return externalEntityInitProcessor3(parser, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
+                                           const char *start,
+                                           const char *end,
+                                           const char **endPtr)
+{
+  const char *next;
+  int tok = XmlContentTok(encoding, start, end, &next);
+  switch (tok) {
+  case XML_TOK_XML_DECL:
+    {
+      enum XML_Error result = processXmlDecl(parser, 1, start, next);
+      if (result != XML_ERROR_NONE)
+       return result;
+      start = next;
+    }
+    break;
+  case XML_TOK_PARTIAL:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_UNCLOSED_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_PARTIAL_CHAR;
+  }
+  processor = externalEntityContentProcessor;
+  tagLevel = 1;
+  return doContent(parser, 1, encoding, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityContentProcessor(XML_Parser parser,
+                                             const char *start,
+                                             const char *end,
+                                             const char **endPtr)
+{
+  return doContent(parser, 1, encoding, start, end, endPtr);
+}
+
+static enum XML_Error
+doContent(XML_Parser parser,
+         int startTagLevel,
+         const ENCODING *enc,
+         const char *s,
+         const char *end,
+         const char **nextPtr)
+{
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  for (;;) {
+    const char *next = s; /* XmlContentTok doesn't always set the last arg */
+    int tok = XmlContentTok(enc, s, end, &next);
+    *eventEndPP = next;
+    switch (tok) {
+    case XML_TOK_TRAILING_CR:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      *eventEndPP = end;
+      if (characterDataHandler) {
+       XML_Char c = 0xA;
+       characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, end);
+      if (startTagLevel == 0)
+       return XML_ERROR_NO_ELEMENTS;
+      if (tagLevel != startTagLevel)
+       return XML_ERROR_ASYNC_ENTITY;
+      return XML_ERROR_NONE;
+    case XML_TOK_NONE:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      if (startTagLevel > 0) {
+       if (tagLevel != startTagLevel)
+         return XML_ERROR_ASYNC_ENTITY;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_NO_ELEMENTS;
+    case XML_TOK_INVALID:
+      *eventPP = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    case XML_TOK_ENTITY_REF:
+      {
+       const XML_Char *name;
+       ENTITY *entity;
+       XML_Char ch = XmlPredefinedEntityName(enc,
+                                             s + enc->minBytesPerChar,
+                                             next - enc->minBytesPerChar);
+       if (ch) {
+         if (characterDataHandler)
+           characterDataHandler(handlerArg, &ch, 1);
+         else if (defaultHandler)
+           reportDefault(parser, enc, s, next);
+         break;
+       }
+       name = poolStoreString(&dtd.pool, enc,
+                               s + enc->minBytesPerChar,
+                               next - enc->minBytesPerChar);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
+       poolDiscard(&dtd.pool);
+       if (!entity) {
+         if (dtd.complete || dtd.standalone)
+           return XML_ERROR_UNDEFINED_ENTITY;
+         if (defaultHandler)
+           reportDefault(parser, enc, s, next);
+         break;
+       }
+       if (entity->open)
+         return XML_ERROR_RECURSIVE_ENTITY_REF;
+       if (entity->notation)
+         return XML_ERROR_BINARY_ENTITY_REF;
+       if (entity) {
+         if (entity->textPtr) {
+           enum XML_Error result;
+           OPEN_INTERNAL_ENTITY openEntity;
+           if (defaultHandler && !defaultExpandInternalEntities) {
+             reportDefault(parser, enc, s, next);
+             break;
+           }
+           entity->open = 1;
+           openEntity.next = openInternalEntities;
+           openInternalEntities = &openEntity;
+           openEntity.entity = entity;
+           openEntity.internalEventPtr = 0;
+           openEntity.internalEventEndPtr = 0;
+           result = doContent(parser,
+                              tagLevel,
+                              internalEncoding,
+                              (char *)entity->textPtr,
+                              (char *)(entity->textPtr + entity->textLen),
+                              0);
+           entity->open = 0;
+           openInternalEntities = openEntity.next;
+           if (result)
+             return result;
+         }
+         else if (externalEntityRefHandler) {
+           const XML_Char *context;
+           entity->open = 1;
+           context = getContext(parser);
+           entity->open = 0;
+           if (!context)
+             return XML_ERROR_NO_MEMORY;
+           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                         context,
+                                         entity->base,
+                                         entity->systemId,
+                                         entity->publicId))
+             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+           poolDiscard(&tempPool);
+         }
+         else if (defaultHandler)
+           reportDefault(parser, enc, s, next);
+       }
+       break;
+      }
+    case XML_TOK_START_TAG_WITH_ATTS:
+      if (!startElementHandler) {
+       enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
+       if (result)
+         return result;
+      }
+      /* fall through */
+    case XML_TOK_START_TAG_NO_ATTS:
+      {
+       TAG *tag;
+       if (freeTagList) {
+         tag = freeTagList;
+         freeTagList = freeTagList->parent;
+       }
+       else {
+         tag = malloc(sizeof(TAG));
+         if (!tag)
+           return XML_ERROR_NO_MEMORY;
+         tag->buf = malloc(INIT_TAG_BUF_SIZE);
+         if (!tag->buf)
+           return XML_ERROR_NO_MEMORY;
+         tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
+       }
+       tag->bindings = 0;
+       tag->parent = tagStack;
+       tagStack = tag;
+       tag->name.localPart = 0;
+       tag->rawName = s + enc->minBytesPerChar;
+       tag->rawNameLength = XmlNameLength(enc, tag->rawName);
+       if (nextPtr) {
+         /* Need to guarantee that:
+            tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
+         if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
+           int bufSize = tag->rawNameLength * 4;
+           bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
+           tag->buf = realloc(tag->buf, bufSize);
+           if (!tag->buf)
+             return XML_ERROR_NO_MEMORY;
+           tag->bufEnd = tag->buf + bufSize;
+         }
+         memcpy(tag->buf, tag->rawName, tag->rawNameLength);
+         tag->rawName = tag->buf;
+       }
+       ++tagLevel;
+       if (startElementHandler) {
+         enum XML_Error result;
+         XML_Char *toPtr;
+         for (;;) {
+           const char *rawNameEnd = tag->rawName + tag->rawNameLength;
+           const char *fromPtr = tag->rawName;
+           int bufSize;
+           if (nextPtr)
+             toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
+           else
+             toPtr = (XML_Char *)tag->buf;
+           tag->name.str = toPtr;
+           XmlConvert(enc,
+                      &fromPtr, rawNameEnd,
+                      (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
+           if (fromPtr == rawNameEnd)
+             break;
+           bufSize = (tag->bufEnd - tag->buf) << 1;
+           tag->buf = realloc(tag->buf, bufSize);
+           if (!tag->buf)
+             return XML_ERROR_NO_MEMORY;
+           tag->bufEnd = tag->buf + bufSize;
+           if (nextPtr)
+             tag->rawName = tag->buf;
+         }
+         *toPtr = XML_T('\0');
+         result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
+         if (result)
+           return result;
+         startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
+         poolClear(&tempPool);
+       }
+       else {
+         tag->name.str = 0;
+         if (defaultHandler)
+           reportDefault(parser, enc, s, next);
+       }
+       break;
+      }
+    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
+      if (!startElementHandler) {
+       enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
+       if (result)
+         return result;
+      }
+      /* fall through */
+    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
+      if (startElementHandler || endElementHandler) {
+       const char *rawName = s + enc->minBytesPerChar;
+       enum XML_Error result;
+       BINDING *bindings = 0;
+       TAG_NAME name;
+       name.str = poolStoreString(&tempPool, enc, rawName,
+                                  rawName + XmlNameLength(enc, rawName));
+       if (!name.str)
+         return XML_ERROR_NO_MEMORY;
+       poolFinish(&tempPool);
+       result = storeAtts(parser, enc, s, &name, &bindings);
+       if (result)
+         return result;
+       poolFinish(&tempPool);
+       if (startElementHandler)
+         startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
+       if (endElementHandler) {
+         if (startElementHandler)
+           *eventPP = *eventEndPP;
+         endElementHandler(handlerArg, name.str);
+       }
+       poolClear(&tempPool);
+       while (bindings) {
+         BINDING *b = bindings;
+         if (endNamespaceDeclHandler)
+           endNamespaceDeclHandler(handlerArg, b->prefix->name);
+         bindings = bindings->nextTagBinding;
+         b->nextTagBinding = freeBindingList;
+         freeBindingList = b;
+         b->prefix->binding = b->prevPrefixBinding;
+       }
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      if (tagLevel == 0)
+       return epilogProcessor(parser, next, end, nextPtr);
+      break;
+    case XML_TOK_END_TAG:
+      if (tagLevel == startTagLevel)
+        return XML_ERROR_ASYNC_ENTITY;
+      else {
+       int len;
+       const char *rawName;
+       TAG *tag = tagStack;
+       tagStack = tag->parent;
+       tag->parent = freeTagList;
+       freeTagList = tag;
+       rawName = s + enc->minBytesPerChar*2;
+       len = XmlNameLength(enc, rawName);
+       if (len != tag->rawNameLength
+           || memcmp(tag->rawName, rawName, len) != 0) {
+         *eventPP = rawName;
+         return XML_ERROR_TAG_MISMATCH;
+       }
+       --tagLevel;
+       if (endElementHandler && tag->name.str) {
+         if (tag->name.localPart) {
+           XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
+           const XML_Char *from = tag->name.localPart;
+           while ((*to++ = *from++) != 0)
+             ;
+         }
+         endElementHandler(handlerArg, tag->name.str);
+       }
+       else if (defaultHandler)
+         reportDefault(parser, enc, s, next);
+       while (tag->bindings) {
+         BINDING *b = tag->bindings;
+         if (endNamespaceDeclHandler)
+           endNamespaceDeclHandler(handlerArg, b->prefix->name);
+         tag->bindings = tag->bindings->nextTagBinding;
+         b->nextTagBinding = freeBindingList;
+         freeBindingList = b;
+         b->prefix->binding = b->prevPrefixBinding;
+       }
+       if (tagLevel == 0)
+         return epilogProcessor(parser, next, end, nextPtr);
+      }
+      break;
+    case XML_TOK_CHAR_REF:
+      {
+       int n = XmlCharRefNumber(enc, s);
+       if (n < 0)
+         return XML_ERROR_BAD_CHAR_REF;
+       if (characterDataHandler) {
+         XML_Char buf[XML_ENCODE_MAX];
+         characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
+       }
+       else if (defaultHandler)
+         reportDefault(parser, enc, s, next);
+      }
+      break;
+    case XML_TOK_XML_DECL:
+      return XML_ERROR_MISPLACED_XML_PI;
+    case XML_TOK_DATA_NEWLINE:
+      if (characterDataHandler) {
+       XML_Char c = 0xA;
+       characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_CDATA_SECT_OPEN:
+      {
+       enum XML_Error result;
+       if (startCdataSectionHandler)
+         startCdataSectionHandler(handlerArg);
+#if 0
+       /* Suppose you doing a transformation on a document that involves
+          changing only the character data.  You set up a defaultHandler
+          and a characterDataHandler.  The defaultHandler simply copies
+          characters through.  The characterDataHandler does the transformation
+          and writes the characters out escaping them as necessary.  This case
+          will fail to work if we leave out the following two lines (because &
+          and < inside CDATA sections will be incorrectly escaped).
+
+          However, now we have a start/endCdataSectionHandler, so it seems
+          easier to let the user deal with this. */
+
+       else if (characterDataHandler)
+         characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+       else if (defaultHandler)
+         reportDefault(parser, enc, s, next);
+       result = doCdataSection(parser, enc, &next, end, nextPtr);
+       if (!next) {
+         processor = cdataSectionProcessor;
+         return result;
+       }
+      }
+      break;
+    case XML_TOK_TRAILING_RSQB:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      if (characterDataHandler) {
+       if (MUST_CONVERT(enc, s)) {
+         ICHAR *dataPtr = (ICHAR *)dataBuf;
+         XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+         characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+       }
+       else
+         characterDataHandler(handlerArg,
+                              (XML_Char *)s,
+                              (XML_Char *)end - (XML_Char *)s);
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, end);
+      if (startTagLevel == 0) {
+        *eventPP = end;
+       return XML_ERROR_NO_ELEMENTS;
+      }
+      if (tagLevel != startTagLevel) {
+       *eventPP = end;
+       return XML_ERROR_ASYNC_ENTITY;
+      }
+      return XML_ERROR_NONE;
+    case XML_TOK_DATA_CHARS:
+      if (characterDataHandler) {
+       if (MUST_CONVERT(enc, s)) {
+         for (;;) {
+           ICHAR *dataPtr = (ICHAR *)dataBuf;
+           XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+           *eventEndPP = s;
+           characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+           if (s == next)
+             break;
+           *eventPP = s;
+         }
+       }
+       else
+         characterDataHandler(handlerArg,
+                              (XML_Char *)s,
+                              (XML_Char *)next - (XML_Char *)s);
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_PI:
+      if (!reportProcessingInstruction(parser, enc, s, next))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_COMMENT:
+      if (!reportComment(parser, enc, s, next))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    default:
+      if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      break;
+    }
+    *eventPP = s = next;
+  }
+  /* not reached */
+}
+
+/* If tagNamePtr is non-null, build a real list of attributes,
+otherwise just check the attributes for well-formedness. */
+
+static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
+                               const char *attStr, TAG_NAME *tagNamePtr,
+                               BINDING **bindingsPtr)
+{
+  ELEMENT_TYPE *elementType = 0;
+  int nDefaultAtts = 0;
+  const XML_Char **appAtts;   /* the attribute list to pass to the application */
+  int attIndex = 0;
+  int i;
+  int n;
+  int nPrefixes = 0;
+  BINDING *binding;
+  const XML_Char *localPart;
+
+  /* lookup the element type name */
+  if (tagNamePtr) {
+    elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, 0);
+    if (!elementType) {
+      tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
+      if (!tagNamePtr->str)
+       return XML_ERROR_NO_MEMORY;
+      elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
+      if (!elementType)
+        return XML_ERROR_NO_MEMORY;
+      if (ns && !setElementTypePrefix(parser, elementType))
+        return XML_ERROR_NO_MEMORY;
+    }
+    nDefaultAtts = elementType->nDefaultAtts;
+  }
+  /* get the attributes from the tokenizer */
+  n = XmlGetAttributes(enc, attStr, attsSize, atts);
+  if (n + nDefaultAtts > attsSize) {
+    int oldAttsSize = attsSize;
+    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
+    atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
+    if (!atts)
+      return XML_ERROR_NO_MEMORY;
+    if (n > oldAttsSize)
+      XmlGetAttributes(enc, attStr, n, atts);
+  }
+  appAtts = (const XML_Char **)atts;
+  for (i = 0; i < n; i++) {
+    /* add the name and value to the attribute list */
+    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
+                                        atts[i].name
+                                        + XmlNameLength(enc, atts[i].name));
+    if (!attId)
+      return XML_ERROR_NO_MEMORY;
+    /* detect duplicate attributes */
+    if ((attId->name)[-1]) {
+      if (enc == encoding)
+       eventPtr = atts[i].name;
+      return XML_ERROR_DUPLICATE_ATTRIBUTE;
+    }
+    (attId->name)[-1] = 1;
+    appAtts[attIndex++] = attId->name;
+    if (!atts[i].normalized) {
+      enum XML_Error result;
+      int isCdata = 1;
+
+      /* figure out whether declared as other than CDATA */
+      if (attId->maybeTokenized) {
+       int j;
+       for (j = 0; j < nDefaultAtts; j++) {
+         if (attId == elementType->defaultAtts[j].id) {
+           isCdata = elementType->defaultAtts[j].isCdata;
+           break;
+         }
+       }
+      }
+
+      /* normalize the attribute value */
+      result = storeAttributeValue(parser, enc, isCdata,
+                                  atts[i].valuePtr, atts[i].valueEnd,
+                                  &tempPool);
+      if (result)
+       return result;
+      if (tagNamePtr) {
+       appAtts[attIndex] = poolStart(&tempPool);
+       poolFinish(&tempPool);
+      }
+      else
+       poolDiscard(&tempPool);
+    }
+    else if (tagNamePtr) {
+      /* the value did not need normalizing */
+      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
+      if (appAtts[attIndex] == 0)
+       return XML_ERROR_NO_MEMORY;
+      poolFinish(&tempPool);
+    }
+    /* handle prefixed attribute names */
+    if (attId->prefix && tagNamePtr) {
+      if (attId->xmlns) {
+       /* deal with namespace declarations here */
+        if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
+          return XML_ERROR_NO_MEMORY;
+        --attIndex;
+      }
+      else {
+       /* deal with other prefixed names later */
+        attIndex++;
+        nPrefixes++;
+        (attId->name)[-1] = 2;
+      }
+    }
+    else
+      attIndex++;
+  }
+  if (tagNamePtr) {
+    int j;
+    nSpecifiedAtts = attIndex;
+    if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
+      for (i = 0; i < attIndex; i += 2)
+       if (appAtts[i] == elementType->idAtt->name) {
+         idAttIndex = i;
+         break;
+       }
+    }
+    else
+      idAttIndex = -1;
+    /* do attribute defaulting */
+    for (j = 0; j < nDefaultAtts; j++) {
+      const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
+      if (!(da->id->name)[-1] && da->value) {
+        if (da->id->prefix) {
+          if (da->id->xmlns) {
+           if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
+             return XML_ERROR_NO_MEMORY;
+         }
+          else {
+           (da->id->name)[-1] = 2;
+           nPrefixes++;
+           appAtts[attIndex++] = da->id->name;
+           appAtts[attIndex++] = da->value;
+         }
+       }
+       else {
+         (da->id->name)[-1] = 1;
+         appAtts[attIndex++] = da->id->name;
+         appAtts[attIndex++] = da->value;
+       }
+      }
+    }
+    appAtts[attIndex] = 0;
+  }
+  i = 0;
+  if (nPrefixes) {
+    /* expand prefixed attribute names */
+    for (; i < attIndex; i += 2) {
+      if (appAtts[i][-1] == 2) {
+        ATTRIBUTE_ID *id;
+        ((XML_Char *)(appAtts[i]))[-1] = 0;
+       id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
+       if (id->prefix->binding) {
+         int j;
+         const BINDING *b = id->prefix->binding;
+         const XML_Char *s = appAtts[i];
+         for (j = 0; j < b->uriLen; j++) {
+           if (!poolAppendChar(&tempPool, b->uri[j]))
+             return XML_ERROR_NO_MEMORY;
+         }
+         while (*s++ != ':')
+           ;
+         do {
+           if (!poolAppendChar(&tempPool, *s))
+             return XML_ERROR_NO_MEMORY;
+         } while (*s++);
+         appAtts[i] = poolStart(&tempPool);
+         poolFinish(&tempPool);
+       }
+       if (!--nPrefixes)
+         break;
+      }
+      else
+       ((XML_Char *)(appAtts[i]))[-1] = 0;
+    }
+  }
+  /* clear the flags that say whether attributes were specified */
+  for (; i < attIndex; i += 2)
+    ((XML_Char *)(appAtts[i]))[-1] = 0;
+  if (!tagNamePtr)
+    return XML_ERROR_NONE;
+  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
+    binding->attId->name[-1] = 0;
+  /* expand the element type name */
+  if (elementType->prefix) {
+    binding = elementType->prefix->binding;
+    if (!binding)
+      return XML_ERROR_NONE;
+    localPart = tagNamePtr->str;
+    while (*localPart++ != XML_T(':'))
+      ;
+  }
+  else if (dtd.defaultPrefix.binding) {
+    binding = dtd.defaultPrefix.binding;
+    localPart = tagNamePtr->str;
+  }
+  else
+    return XML_ERROR_NONE;
+  tagNamePtr->localPart = localPart;
+  tagNamePtr->uriLen = binding->uriLen;
+  for (i = 0; localPart[i++];)
+    ;
+  n = i + binding->uriLen;
+  if (n > binding->uriAlloc) {
+    TAG *p;
+    XML_Char *uri = malloc((n + EXPAND_SPARE) * sizeof(XML_Char));
+    if (!uri)
+      return XML_ERROR_NO_MEMORY;
+    binding->uriAlloc = n + EXPAND_SPARE;
+    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
+    for (p = tagStack; p; p = p->parent)
+      if (p->name.str == binding->uri)
+       p->name.str = uri;
+    free(binding->uri);
+    binding->uri = uri;
+  }
+  memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
+  tagNamePtr->str = binding->uri;
+  return XML_ERROR_NONE;
+}
+
+static
+int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
+{
+  BINDING *b;
+  int len;
+  for (len = 0; uri[len]; len++)
+    ;
+  if (namespaceSeparator)
+    len++;
+  if (freeBindingList) {
+    b = freeBindingList;
+    if (len > b->uriAlloc) {
+      b->uri = realloc(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
+      if (!b->uri)
+       return 0;
+      b->uriAlloc = len + EXPAND_SPARE;
+    }
+    freeBindingList = b->nextTagBinding;
+  }
+  else {
+    b = malloc(sizeof(BINDING));
+    if (!b)
+      return 0;
+    b->uri = malloc(sizeof(XML_Char) * (len + EXPAND_SPARE));
+    if (!b->uri) {
+      free(b);
+      return 0;
+    }
+    b->uriAlloc = len + EXPAND_SPARE;
+  }
+  b->uriLen = len;
+  memcpy(b->uri, uri, len * sizeof(XML_Char));
+  if (namespaceSeparator)
+    b->uri[len - 1] = namespaceSeparator;
+  b->prefix = prefix;
+  b->attId = attId;
+  b->prevPrefixBinding = prefix->binding;
+  if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
+    prefix->binding = 0;
+  else
+    prefix->binding = b;
+  b->nextTagBinding = *bindingsPtr;
+  *bindingsPtr = b;
+  if (startNamespaceDeclHandler)
+    startNamespaceDeclHandler(handlerArg, prefix->name,
+                             prefix->binding ? uri : 0);
+  return 1;
+}
+
+/* The idea here is to avoid using stack for each CDATA section when
+the whole file is parsed with one call. */
+
+static
+enum XML_Error cdataSectionProcessor(XML_Parser parser,
+                                    const char *start,
+                                    const char *end,
+                                    const char **endPtr)
+{
+  enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
+  if (start) {
+    processor = contentProcessor;
+    return contentProcessor(parser, start, end, endPtr);
+  }
+  return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null if
+the section is not yet closed. */
+
+static
+enum XML_Error doCdataSection(XML_Parser parser,
+                             const ENCODING *enc,
+                             const char **startPtr,
+                             const char *end,
+                             const char **nextPtr)
+{
+  const char *s = *startPtr;
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    *eventPP = s;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  *startPtr = 0;
+  for (;;) {
+    const char *next;
+    int tok = XmlCdataSectionTok(enc, s, end, &next);
+    *eventEndPP = next;
+    switch (tok) {
+    case XML_TOK_CDATA_SECT_CLOSE:
+      if (endCdataSectionHandler)
+       endCdataSectionHandler(handlerArg);
+#if 0
+      /* see comment under XML_TOK_CDATA_SECT_OPEN */
+      else if (characterDataHandler)
+       characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      *startPtr = next;
+      return XML_ERROR_NONE;
+    case XML_TOK_DATA_NEWLINE:
+      if (characterDataHandler) {
+       XML_Char c = 0xA;
+       characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_DATA_CHARS:
+      if (characterDataHandler) {
+       if (MUST_CONVERT(enc, s)) {
+         for (;;) {
+           ICHAR *dataPtr = (ICHAR *)dataBuf;
+           XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+           *eventEndPP = next;
+           characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+           if (s == next)
+             break;
+           *eventPP = s;
+         }
+       }
+       else
+         characterDataHandler(handlerArg,
+                              (XML_Char *)s,
+                              (XML_Char *)next - (XML_Char *)s);
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_INVALID:
+      *eventPP = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    case XML_TOK_PARTIAL:
+    case XML_TOK_NONE:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_CDATA_SECTION;
+    default:
+      abort();
+    }
+    *eventPP = s = next;
+  }
+  /* not reached */
+}
+
+#ifdef XML_DTD
+
+/* The idea here is to avoid using stack for each IGNORE section when
+the whole file is parsed with one call. */
+
+static
+enum XML_Error ignoreSectionProcessor(XML_Parser parser,
+                                     const char *start,
+                                     const char *end,
+                                     const char **endPtr)
+{
+  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
+  if (start) {
+    processor = prologProcessor;
+    return prologProcessor(parser, start, end, endPtr);
+  }
+  return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null if
+the section is not yet closed. */
+
+static
+enum XML_Error doIgnoreSection(XML_Parser parser,
+                              const ENCODING *enc,
+                              const char **startPtr,
+                              const char *end,
+                              const char **nextPtr)
+{
+  const char *next;
+  int tok;
+  const char *s = *startPtr;
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    *eventPP = s;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  *startPtr = 0;
+  tok = XmlIgnoreSectionTok(enc, s, end, &next);
+  *eventEndPP = next;
+  switch (tok) {
+  case XML_TOK_IGNORE_SECT:
+    if (defaultHandler)
+      reportDefault(parser, enc, s, next);
+    *startPtr = next;
+    return XML_ERROR_NONE;
+  case XML_TOK_INVALID:
+    *eventPP = next;
+    return XML_ERROR_INVALID_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (nextPtr) {
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    }
+    return XML_ERROR_PARTIAL_CHAR;
+  case XML_TOK_PARTIAL:
+  case XML_TOK_NONE:
+    if (nextPtr) {
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    }
+    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
+  default:
+    abort();
+  }
+  /* not reached */
+}
+
+#endif /* XML_DTD */
+
+static enum XML_Error
+initializeEncoding(XML_Parser parser)
+{
+  const char *s;
+#ifdef XML_UNICODE
+  char encodingBuf[128];
+  if (!protocolEncodingName)
+    s = 0;
+  else {
+    int i;
+    for (i = 0; protocolEncodingName[i]; i++) {
+      if (i == sizeof(encodingBuf) - 1
+         || (protocolEncodingName[i] & ~0x7f) != 0) {
+       encodingBuf[0] = '\0';
+       break;
+      }
+      encodingBuf[i] = (char)protocolEncodingName[i];
+    }
+    encodingBuf[i] = '\0';
+    s = encodingBuf;
+  }
+#else
+  s = protocolEncodingName;
+#endif
+  if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
+    return XML_ERROR_NONE;
+  return handleUnknownEncoding(parser, protocolEncodingName);
+}
+
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+              const char *s, const char *next)
+{
+  const char *encodingName = 0;
+  const ENCODING *newEncoding = 0;
+  const char *version;
+  int standalone = -1;
+  if (!(ns
+        ? XmlParseXmlDeclNS
+       : XmlParseXmlDecl)(isGeneralTextEntity,
+                          encoding,
+                          s,
+                          next,
+                          &eventPtr,
+                          &version,
+                          &encodingName,
+                          &newEncoding,
+                          &standalone))
+    return XML_ERROR_SYNTAX;
+  if (!isGeneralTextEntity && standalone == 1) {
+    dtd.standalone = 1;
+#ifdef XML_DTD
+    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
+      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif /* XML_DTD */
+  }
+  if (defaultHandler)
+    reportDefault(parser, encoding, s, next);
+  if (!protocolEncodingName) {
+    if (newEncoding) {
+      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
+       eventPtr = encodingName;
+       return XML_ERROR_INCORRECT_ENCODING;
+      }
+      encoding = newEncoding;
+    }
+    else if (encodingName) {
+      enum XML_Error result;
+      const XML_Char *s = poolStoreString(&tempPool,
+                                         encoding,
+                                         encodingName,
+                                         encodingName
+                                         + XmlNameLength(encoding, encodingName));
+      if (!s)
+       return XML_ERROR_NO_MEMORY;
+      result = handleUnknownEncoding(parser, s);
+      poolDiscard(&tempPool);
+      if (result == XML_ERROR_UNKNOWN_ENCODING)
+       eventPtr = encodingName;
+      return result;
+    }
+  }
+  return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+  if (unknownEncodingHandler) {
+    XML_Encoding info;
+    int i;
+    for (i = 0; i < 256; i++)
+      info.map[i] = -1;
+    info.convert = 0;
+    info.data = 0;
+    info.release = 0;
+    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
+      ENCODING *enc;
+      unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding());
+      if (!unknownEncodingMem) {
+       if (info.release)
+         info.release(info.data);
+       return XML_ERROR_NO_MEMORY;
+      }
+      enc = (ns
+            ? XmlInitUnknownEncodingNS
+            : XmlInitUnknownEncoding)(unknownEncodingMem,
+                                      info.map,
+                                      info.convert,
+                                      info.data);
+      if (enc) {
+       unknownEncodingData = info.data;
+       unknownEncodingRelease = info.release;
+       encoding = enc;
+       return XML_ERROR_NONE;
+      }
+    }
+    if (info.release)
+      info.release(info.data);
+  }
+  return XML_ERROR_UNKNOWN_ENCODING;
+}
+
+static enum XML_Error
+prologInitProcessor(XML_Parser parser,
+                   const char *s,
+                   const char *end,
+                   const char **nextPtr)
+{
+  enum XML_Error result = initializeEncoding(parser);
+  if (result != XML_ERROR_NONE)
+    return result;
+  processor = prologProcessor;
+  return prologProcessor(parser, s, end, nextPtr);
+}
+
+static enum XML_Error
+prologProcessor(XML_Parser parser,
+               const char *s,
+               const char *end,
+               const char **nextPtr)
+{
+  const char *next;
+  int tok = XmlPrologTok(encoding, s, end, &next);
+  return doProlog(parser, encoding, s, end, tok, next, nextPtr);
+}
+
+static enum XML_Error
+doProlog(XML_Parser parser,
+        const ENCODING *enc,
+        const char *s,
+        const char *end,
+        int tok,
+        const char *next,
+        const char **nextPtr)
+{
+#ifdef XML_DTD
+  static const XML_Char externalSubsetName[] = { '#' , '\0' };
+#endif /* XML_DTD */
+
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  for (;;) {
+    int role;
+    *eventPP = s;
+    *eventEndPP = next;
+    if (tok <= 0) {
+      if (nextPtr != 0 && tok != XML_TOK_INVALID) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      switch (tok) {
+      case XML_TOK_INVALID:
+       *eventPP = next;
+       return XML_ERROR_INVALID_TOKEN;
+      case XML_TOK_PARTIAL:
+       return XML_ERROR_UNCLOSED_TOKEN;
+      case XML_TOK_PARTIAL_CHAR:
+       return XML_ERROR_PARTIAL_CHAR;
+      case XML_TOK_NONE:
+#ifdef XML_DTD
+       if (enc != encoding)
+         return XML_ERROR_NONE;
+       if (parentParser) {
+         if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
+             == XML_ROLE_ERROR)
+           return XML_ERROR_SYNTAX;
+         hadExternalDoctype = 0;
+         return XML_ERROR_NONE;
+       }
+#endif /* XML_DTD */
+       return XML_ERROR_NO_ELEMENTS;
+      default:
+       tok = -tok;
+       next = end;
+       break;
+      }
+    }
+    role = XmlTokenRole(&prologState, tok, s, next, enc);
+    switch (role) {
+    case XML_ROLE_XML_DECL:
+      {
+       enum XML_Error result = processXmlDecl(parser, 0, s, next);
+       if (result != XML_ERROR_NONE)
+         return result;
+       enc = encoding;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_NAME:
+      if (startDoctypeDeclHandler) {
+       const XML_Char *name = poolStoreString(&tempPool, enc, s, next);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       startDoctypeDeclHandler(handlerArg, name);
+       poolClear(&tempPool);
+      }
+      break;
+#ifdef XML_DTD
+    case XML_ROLE_TEXT_DECL:
+      {
+       enum XML_Error result = processXmlDecl(parser, 1, s, next);
+       if (result != XML_ERROR_NONE)
+         return result;
+       enc = encoding;
+      }
+      break;
+#endif /* XML_DTD */
+    case XML_ROLE_DOCTYPE_PUBLIC_ID:
+#ifdef XML_DTD
+      declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+                                   externalSubsetName,
+                                   sizeof(ENTITY));
+      if (!declEntity)
+       return XML_ERROR_NO_MEMORY;
+#endif /* XML_DTD */
+      /* fall through */
+    case XML_ROLE_ENTITY_PUBLIC_ID:
+      if (!XmlIsPublicId(enc, s, next, eventPP))
+       return XML_ERROR_SYNTAX;
+      if (declEntity) {
+       XML_Char *tem = poolStoreString(&dtd.pool,
+                                       enc,
+                                       s + enc->minBytesPerChar,
+                                       next - enc->minBytesPerChar);
+       if (!tem)
+         return XML_ERROR_NO_MEMORY;
+       normalizePublicId(tem);
+       declEntity->publicId = tem;
+       poolFinish(&dtd.pool);
+      }
+      break;
+    case XML_ROLE_DOCTYPE_CLOSE:
+      if (dtd.complete && hadExternalDoctype) {
+       dtd.complete = 0;
+#ifdef XML_DTD
+       if (paramEntityParsing && externalEntityRefHandler) {
+         ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
+                                           externalSubsetName,
+                                           0);
+         if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                       0,
+                                       entity->base,
+                                       entity->systemId,
+                                       entity->publicId))
+          return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+       }
+#endif /* XML_DTD */
+       if (!dtd.complete
+           && !dtd.standalone
+           && notStandaloneHandler
+           && !notStandaloneHandler(handlerArg))
+         return XML_ERROR_NOT_STANDALONE;
+      }
+      if (endDoctypeDeclHandler)
+       endDoctypeDeclHandler(handlerArg);
+      break;
+    case XML_ROLE_INSTANCE_START:
+      processor = contentProcessor;
+      return contentProcessor(parser, s, end, nextPtr);
+    case XML_ROLE_ATTLIST_ELEMENT_NAME:
+      {
+       const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
+       if (!declElementType)
+         return XML_ERROR_NO_MEMORY;
+       if (declElementType->name != name)
+         poolDiscard(&dtd.pool);
+       else {
+         poolFinish(&dtd.pool);
+         if (!setElementTypePrefix(parser, declElementType))
+            return XML_ERROR_NO_MEMORY;
+       }
+       break;
+      }
+    case XML_ROLE_ATTRIBUTE_NAME:
+      declAttributeId = getAttributeId(parser, enc, s, next);
+      if (!declAttributeId)
+       return XML_ERROR_NO_MEMORY;
+      declAttributeIsCdata = 0;
+      declAttributeIsId = 0;
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
+      declAttributeIsCdata = 1;
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_ID:
+      declAttributeIsId = 1;
+      break;
+    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
+    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
+      if (dtd.complete
+         && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata,
+                             declAttributeIsId, 0))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
+    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
+      {
+       const XML_Char *attVal;
+       enum XML_Error result
+         = storeAttributeValue(parser, enc, declAttributeIsCdata,
+                               s + enc->minBytesPerChar,
+                               next - enc->minBytesPerChar,
+                               &dtd.pool);
+       if (result)
+         return result;
+       attVal = poolStart(&dtd.pool);
+       poolFinish(&dtd.pool);
+       if (dtd.complete
+           // ID attributes aren't allowed to have a default
+           && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal))
+         return XML_ERROR_NO_MEMORY;
+       break;
+      }
+    case XML_ROLE_ENTITY_VALUE:
+      {
+       enum XML_Error result = storeEntityValue(parser, enc,
+                                                s + enc->minBytesPerChar,
+                                                next - enc->minBytesPerChar);
+       if (declEntity) {
+         declEntity->textPtr = poolStart(&dtd.pool);
+         declEntity->textLen = poolLength(&dtd.pool);
+         poolFinish(&dtd.pool);
+         if (internalParsedEntityDeclHandler
+             // Check it's not a parameter entity
+             && ((ENTITY *)lookup(&dtd.generalEntities, declEntity->name, 0)
+                 == declEntity)) {
+           *eventEndPP = s;
+           internalParsedEntityDeclHandler(handlerArg,
+                                           declEntity->name,
+                                           declEntity->textPtr,
+                                           declEntity->textLen);
+         }
+       }
+       else
+         poolDiscard(&dtd.pool);
+       if (result != XML_ERROR_NONE)
+         return result;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_SYSTEM_ID:
+      if (!dtd.standalone
+#ifdef XML_DTD
+         && !paramEntityParsing
+#endif /* XML_DTD */
+         && notStandaloneHandler
+         && !notStandaloneHandler(handlerArg))
+       return XML_ERROR_NOT_STANDALONE;
+      hadExternalDoctype = 1;
+#ifndef XML_DTD
+      break;
+#else /* XML_DTD */
+      if (!declEntity) {
+       declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+                                     externalSubsetName,
+                                     sizeof(ENTITY));
+       if (!declEntity)
+         return XML_ERROR_NO_MEMORY;
+      }
+      /* fall through */
+#endif /* XML_DTD */
+    case XML_ROLE_ENTITY_SYSTEM_ID:
+      if (declEntity) {
+       declEntity->systemId = poolStoreString(&dtd.pool, enc,
+                                              s + enc->minBytesPerChar,
+                                              next - enc->minBytesPerChar);
+       if (!declEntity->systemId)
+         return XML_ERROR_NO_MEMORY;
+       declEntity->base = curBase;
+       poolFinish(&dtd.pool);
+      }
+      break;
+    case XML_ROLE_ENTITY_NOTATION_NAME:
+      if (declEntity) {
+       declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
+       if (!declEntity->notation)
+         return XML_ERROR_NO_MEMORY;
+       poolFinish(&dtd.pool);
+       if (unparsedEntityDeclHandler) {
+         *eventEndPP = s;
+         unparsedEntityDeclHandler(handlerArg,
+                                   declEntity->name,
+                                   declEntity->base,
+                                   declEntity->systemId,
+                                   declEntity->publicId,
+                                   declEntity->notation);
+       }
+
+      }
+      break;
+    case XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION:
+      if (declEntity && externalParsedEntityDeclHandler) {
+       *eventEndPP = s;
+       externalParsedEntityDeclHandler(handlerArg,
+                                       declEntity->name,
+                                       declEntity->base,
+                                       declEntity->systemId,
+                                       declEntity->publicId);
+      }
+      break;
+    case XML_ROLE_GENERAL_ENTITY_NAME:
+      {
+       const XML_Char *name;
+       if (XmlPredefinedEntityName(enc, s, next)) {
+         declEntity = 0;
+         break;
+       }
+       name = poolStoreString(&dtd.pool, enc, s, next);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       if (dtd.complete) {
+         declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
+         if (!declEntity)
+           return XML_ERROR_NO_MEMORY;
+         if (declEntity->name != name) {
+           poolDiscard(&dtd.pool);
+           declEntity = 0;
+         }
+         else
+           poolFinish(&dtd.pool);
+       }
+       else {
+         poolDiscard(&dtd.pool);
+         declEntity = 0;
+       }
+      }
+      break;
+    case XML_ROLE_PARAM_ENTITY_NAME:
+#ifdef XML_DTD
+      if (dtd.complete) {
+       const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       declEntity = (ENTITY *)lookup(&dtd.paramEntities, name, sizeof(ENTITY));
+       if (!declEntity)
+         return XML_ERROR_NO_MEMORY;
+       if (declEntity->name != name) {
+         poolDiscard(&dtd.pool);
+         declEntity = 0;
+       }
+       else
+         poolFinish(&dtd.pool);
+      }
+#else /* not XML_DTD */
+      declEntity = 0;
+#endif /* not XML_DTD */
+      break;
+    case XML_ROLE_NOTATION_NAME:
+      declNotationPublicId = 0;
+      declNotationName = 0;
+      if (notationDeclHandler) {
+       declNotationName = poolStoreString(&tempPool, enc, s, next);
+       if (!declNotationName)
+         return XML_ERROR_NO_MEMORY;
+       poolFinish(&tempPool);
+      }
+      break;
+    case XML_ROLE_NOTATION_PUBLIC_ID:
+      if (!XmlIsPublicId(enc, s, next, eventPP))
+       return XML_ERROR_SYNTAX;
+      if (declNotationName) {
+       XML_Char *tem = poolStoreString(&tempPool,
+                                       enc,
+                                       s + enc->minBytesPerChar,
+                                       next - enc->minBytesPerChar);
+       if (!tem)
+         return XML_ERROR_NO_MEMORY;
+       normalizePublicId(tem);
+       declNotationPublicId = tem;
+       poolFinish(&tempPool);
+      }
+      break;
+    case XML_ROLE_NOTATION_SYSTEM_ID:
+      if (declNotationName && notationDeclHandler) {
+       const XML_Char *systemId
+         = poolStoreString(&tempPool, enc,
+                           s + enc->minBytesPerChar,
+                           next - enc->minBytesPerChar);
+       if (!systemId)
+         return XML_ERROR_NO_MEMORY;
+       *eventEndPP = s;
+       notationDeclHandler(handlerArg,
+                           declNotationName,
+                           curBase,
+                           systemId,
+                           declNotationPublicId);
+      }
+      poolClear(&tempPool);
+      break;
+    case XML_ROLE_NOTATION_NO_SYSTEM_ID:
+      if (declNotationPublicId && notationDeclHandler) {
+       *eventEndPP = s;
+       notationDeclHandler(handlerArg,
+                           declNotationName,
+                           curBase,
+                           0,
+                           declNotationPublicId);
+      }
+      poolClear(&tempPool);
+      break;
+    case XML_ROLE_ERROR:
+      switch (tok) {
+      case XML_TOK_PARAM_ENTITY_REF:
+       return XML_ERROR_PARAM_ENTITY_REF;
+      case XML_TOK_XML_DECL:
+       return XML_ERROR_MISPLACED_XML_PI;
+      default:
+       return XML_ERROR_SYNTAX;
+      }
+#ifdef XML_DTD
+    case XML_ROLE_IGNORE_SECT:
+      {
+       enum XML_Error result;
+       if (defaultHandler)
+         reportDefault(parser, enc, s, next);
+       result = doIgnoreSection(parser, enc, &next, end, nextPtr);
+       if (!next) {
+         processor = ignoreSectionProcessor;
+         return result;
+       }
+      }
+      break;
+#endif /* XML_DTD */
+    case XML_ROLE_GROUP_OPEN:
+      if (prologState.level >= groupSize) {
+       if (groupSize)
+         groupConnector = realloc(groupConnector, groupSize *= 2);
+       else
+         groupConnector = malloc(groupSize = 32);
+       if (!groupConnector)
+         return XML_ERROR_NO_MEMORY;
+      }
+      groupConnector[prologState.level] = 0;
+      break;
+    case XML_ROLE_GROUP_SEQUENCE:
+      if (groupConnector[prologState.level] == '|')
+       return XML_ERROR_SYNTAX;
+      groupConnector[prologState.level] = ',';
+      break;
+    case XML_ROLE_GROUP_CHOICE:
+      if (groupConnector[prologState.level] == ',')
+       return XML_ERROR_SYNTAX;
+      groupConnector[prologState.level] = '|';
+      break;
+    case XML_ROLE_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+    case XML_ROLE_INNER_PARAM_ENTITY_REF:
+      if (paramEntityParsing
+         && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
+       const XML_Char *name;
+       ENTITY *entity;
+       name = poolStoreString(&dtd.pool, enc,
+                               s + enc->minBytesPerChar,
+                               next - enc->minBytesPerChar);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
+       poolDiscard(&dtd.pool);
+       if (!entity) {
+         /* FIXME what to do if !dtd.complete? */
+         return XML_ERROR_UNDEFINED_ENTITY;
+       }
+       if (entity->open)
+         return XML_ERROR_RECURSIVE_ENTITY_REF;
+       if (entity->textPtr) {
+         enum XML_Error result;
+         result = processInternalParamEntity(parser, entity);
+         if (result != XML_ERROR_NONE)
+           return result;
+         break;
+       }
+       if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
+         return XML_ERROR_PARAM_ENTITY_REF;
+       if (externalEntityRefHandler) {
+         dtd.complete = 0;
+         entity->open = 1;
+         if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                       0,
+                                       entity->base,
+                                       entity->systemId,
+                                       entity->publicId)) {
+           entity->open = 0;
+           return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+         }
+         entity->open = 0;
+         if (dtd.complete)
+           break;
+       }
+      }
+#endif /* XML_DTD */
+      if (!dtd.standalone
+         && notStandaloneHandler
+         && !notStandaloneHandler(handlerArg))
+       return XML_ERROR_NOT_STANDALONE;
+      dtd.complete = 0;
+      if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      break;
+    case XML_ROLE_NONE:
+      switch (tok) {
+      case XML_TOK_PI:
+       if (!reportProcessingInstruction(parser, enc, s, next))
+         return XML_ERROR_NO_MEMORY;
+       break;
+      case XML_TOK_COMMENT:
+       if (!reportComment(parser, enc, s, next))
+         return XML_ERROR_NO_MEMORY;
+       break;
+      }
+      break;
+    }
+    if (defaultHandler) {
+      switch (tok) {
+      case XML_TOK_PI:
+      case XML_TOK_COMMENT:
+      case XML_TOK_BOM:
+      case XML_TOK_XML_DECL:
+#ifdef XML_DTD
+      case XML_TOK_IGNORE_SECT:
+#endif /* XML_DTD */
+      case XML_TOK_PARAM_ENTITY_REF:
+       break;
+      default:
+#ifdef XML_DTD
+       if (role != XML_ROLE_IGNORE_SECT)
+#endif /* XML_DTD */
+         reportDefault(parser, enc, s, next);
+      }
+    }
+    s = next;
+    tok = XmlPrologTok(enc, s, end, &next);
+  }
+  /* not reached */
+}
+
+static
+enum XML_Error epilogProcessor(XML_Parser parser,
+                              const char *s,
+                              const char *end,
+                              const char **nextPtr)
+{
+  processor = epilogProcessor;
+  eventPtr = s;
+  for (;;) {
+    const char *next;
+    int tok = XmlPrologTok(encoding, s, end, &next);
+    eventEndPtr = next;
+    switch (tok) {
+    case -XML_TOK_PROLOG_S:
+      if (defaultHandler) {
+       eventEndPtr = end;
+       reportDefault(parser, encoding, s, end);
+      }
+      /* fall through */
+    case XML_TOK_NONE:
+      if (nextPtr)
+       *nextPtr = end;
+      return XML_ERROR_NONE;
+    case XML_TOK_PROLOG_S:
+      if (defaultHandler)
+       reportDefault(parser, encoding, s, next);
+      break;
+    case XML_TOK_PI:
+      if (!reportProcessingInstruction(parser, encoding, s, next))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_COMMENT:
+      if (!reportComment(parser, encoding, s, next))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_INVALID:
+      eventPtr = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    default:
+      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
+    }
+    eventPtr = s = next;
+  }
+}
+
+#ifdef XML_DTD
+
+static enum XML_Error
+processInternalParamEntity(XML_Parser parser, ENTITY *entity)
+{
+  const char *s, *end, *next;
+  int tok;
+  enum XML_Error result;
+  OPEN_INTERNAL_ENTITY openEntity;
+  entity->open = 1;
+  openEntity.next = openInternalEntities;
+  openInternalEntities = &openEntity;
+  openEntity.entity = entity;
+  openEntity.internalEventPtr = 0;
+  openEntity.internalEventEndPtr = 0;
+  s = (char *)entity->textPtr;
+  end = (char *)(entity->textPtr + entity->textLen);
+  tok = XmlPrologTok(internalEncoding, s, end, &next);
+  result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
+  entity->open = 0;
+  openInternalEntities = openEntity.next;
+  return result;
+}
+
+#endif /* XML_DTD */
+
+static
+enum XML_Error errorProcessor(XML_Parser parser,
+                             const char *s,
+                             const char *end,
+                             const char **nextPtr)
+{
+  return errorCode;
+}
+
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
+                   const char *ptr, const char *end,
+                   STRING_POOL *pool)
+{
+  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
+  if (result)
+    return result;
+  if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
+    poolChop(pool);
+  if (!poolAppendChar(pool, XML_T('\0')))
+    return XML_ERROR_NO_MEMORY;
+  return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
+                    const char *ptr, const char *end,
+                    STRING_POOL *pool)
+{
+  for (;;) {
+    const char *next;
+    int tok = XmlAttributeValueTok(enc, ptr, end, &next);
+    switch (tok) {
+    case XML_TOK_NONE:
+      return XML_ERROR_NONE;
+    case XML_TOK_INVALID:
+      if (enc == encoding)
+       eventPtr = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (enc == encoding)
+       eventPtr = ptr;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_CHAR_REF:
+      {
+       XML_Char buf[XML_ENCODE_MAX];
+       int i;
+       int n = XmlCharRefNumber(enc, ptr);
+       if (n < 0) {
+         if (enc == encoding)
+           eventPtr = ptr;
+         return XML_ERROR_BAD_CHAR_REF;
+       }
+       if (!isCdata
+           && n == 0x20 /* space */
+           && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+         break;
+       n = XmlEncode(n, (ICHAR *)buf);
+       if (!n) {
+         if (enc == encoding)
+           eventPtr = ptr;
+         return XML_ERROR_BAD_CHAR_REF;
+       }
+       for (i = 0; i < n; i++) {
+         if (!poolAppendChar(pool, buf[i]))
+           return XML_ERROR_NO_MEMORY;
+       }
+      }
+      break;
+    case XML_TOK_DATA_CHARS:
+      if (!poolAppend(pool, enc, ptr, next))
+       return XML_ERROR_NO_MEMORY;
+      break;
+      break;
+    case XML_TOK_TRAILING_CR:
+      next = ptr + enc->minBytesPerChar;
+      /* fall through */
+    case XML_TOK_ATTRIBUTE_VALUE_S:
+    case XML_TOK_DATA_NEWLINE:
+      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+       break;
+      if (!poolAppendChar(pool, 0x20))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_ENTITY_REF:
+      {
+       const XML_Char *name;
+       ENTITY *entity;
+       XML_Char ch = XmlPredefinedEntityName(enc,
+                                             ptr + enc->minBytesPerChar,
+                                             next - enc->minBytesPerChar);
+       if (ch) {
+         if (!poolAppendChar(pool, ch))
+           return XML_ERROR_NO_MEMORY;
+         break;
+       }
+       name = poolStoreString(&temp2Pool, enc,
+                              ptr + enc->minBytesPerChar,
+                              next - enc->minBytesPerChar);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
+       poolDiscard(&temp2Pool);
+       if (!entity) {
+         if (dtd.complete) {
+           if (enc == encoding)
+             eventPtr = ptr;
+           return XML_ERROR_UNDEFINED_ENTITY;
+         }
+       }
+       else if (entity->open) {
+         if (enc == encoding)
+           eventPtr = ptr;
+         return XML_ERROR_RECURSIVE_ENTITY_REF;
+       }
+       else if (entity->notation) {
+         if (enc == encoding)
+           eventPtr = ptr;
+         return XML_ERROR_BINARY_ENTITY_REF;
+       }
+       else if (!entity->textPtr) {
+         if (enc == encoding)
+           eventPtr = ptr;
+         return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
+       }
+       else {
+         enum XML_Error result;
+         const XML_Char *textEnd = entity->textPtr + entity->textLen;
+         entity->open = 1;
+         result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
+         entity->open = 0;
+         if (result)
+           return result;
+       }
+      }
+      break;
+    default:
+      abort();
+    }
+    ptr = next;
+  }
+  /* not reached */
+}
+
+static
+enum XML_Error storeEntityValue(XML_Parser parser,
+                               const ENCODING *enc,
+                               const char *entityTextPtr,
+                               const char *entityTextEnd)
+{
+  STRING_POOL *pool = &(dtd.pool);
+  for (;;) {
+    const char *next;
+    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
+    switch (tok) {
+    case XML_TOK_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+      if (parentParser || enc != encoding) {
+       enum XML_Error result;
+       const XML_Char *name;
+       ENTITY *entity;
+       name = poolStoreString(&tempPool, enc,
+                              entityTextPtr + enc->minBytesPerChar,
+                              next - enc->minBytesPerChar);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
+       poolDiscard(&tempPool);
+       if (!entity) {
+         if (enc == encoding)
+           eventPtr = entityTextPtr;
+         return XML_ERROR_UNDEFINED_ENTITY;
+       }
+       if (entity->open) {
+         if (enc == encoding)
+           eventPtr = entityTextPtr;
+         return XML_ERROR_RECURSIVE_ENTITY_REF;
+       }
+       if (entity->systemId) {
+         if (enc == encoding)
+           eventPtr = entityTextPtr;
+         return XML_ERROR_PARAM_ENTITY_REF;
+       }
+       entity->open = 1;
+       result = storeEntityValue(parser,
+                                 internalEncoding,
+                                 (char *)entity->textPtr,
+                                 (char *)(entity->textPtr + entity->textLen));
+       entity->open = 0;
+       if (result)
+         return result;
+       break;
+      }
+#endif /* XML_DTD */
+      eventPtr = entityTextPtr;
+      return XML_ERROR_SYNTAX;
+    case XML_TOK_NONE:
+      return XML_ERROR_NONE;
+    case XML_TOK_ENTITY_REF:
+    case XML_TOK_DATA_CHARS:
+      if (!poolAppend(pool, enc, entityTextPtr, next))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_TRAILING_CR:
+      next = entityTextPtr + enc->minBytesPerChar;
+      /* fall through */
+    case XML_TOK_DATA_NEWLINE:
+      if (pool->end == pool->ptr && !poolGrow(pool))
+       return XML_ERROR_NO_MEMORY;
+      *(pool->ptr)++ = 0xA;
+      break;
+    case XML_TOK_CHAR_REF:
+      {
+       XML_Char buf[XML_ENCODE_MAX];
+       int i;
+       int n = XmlCharRefNumber(enc, entityTextPtr);
+       if (n < 0) {
+         if (enc == encoding)
+           eventPtr = entityTextPtr;
+         return XML_ERROR_BAD_CHAR_REF;
+       }
+       n = XmlEncode(n, (ICHAR *)buf);
+       if (!n) {
+         if (enc == encoding)
+           eventPtr = entityTextPtr;
+         return XML_ERROR_BAD_CHAR_REF;
+       }
+       for (i = 0; i < n; i++) {
+         if (pool->end == pool->ptr && !poolGrow(pool))
+           return XML_ERROR_NO_MEMORY;
+         *(pool->ptr)++ = buf[i];
+       }
+      }
+      break;
+    case XML_TOK_PARTIAL:
+      if (enc == encoding)
+       eventPtr = entityTextPtr;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_INVALID:
+      if (enc == encoding)
+       eventPtr = next;
+      return XML_ERROR_INVALID_TOKEN;
+    default:
+      abort();
+    }
+    entityTextPtr = next;
+  }
+  /* not reached */
+}
+
+static void
+normalizeLines(XML_Char *s)
+{
+  XML_Char *p;
+  for (;; s++) {
+    if (*s == XML_T('\0'))
+      return;
+    if (*s == 0xD)
+      break;
+  }
+  p = s;
+  do {
+    if (*s == 0xD) {
+      *p++ = 0xA;
+      if (*++s == 0xA)
+        s++;
+    }
+    else
+      *p++ = *s++;
+  } while (*s);
+  *p = XML_T('\0');
+}
+
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+{
+  const XML_Char *target;
+  XML_Char *data;
+  const char *tem;
+  if (!processingInstructionHandler) {
+    if (defaultHandler)
+      reportDefault(parser, enc, start, end);
+    return 1;
+  }
+  start += enc->minBytesPerChar * 2;
+  tem = start + XmlNameLength(enc, start);
+  target = poolStoreString(&tempPool, enc, start, tem);
+  if (!target)
+    return 0;
+  poolFinish(&tempPool);
+  data = poolStoreString(&tempPool, enc,
+                       XmlSkipS(enc, tem),
+                       end - enc->minBytesPerChar*2);
+  if (!data)
+    return 0;
+  normalizeLines(data);
+  processingInstructionHandler(handlerArg, target, data);
+  poolClear(&tempPool);
+  return 1;
+}
+
+static int
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+{
+  XML_Char *data;
+  if (!commentHandler) {
+    if (defaultHandler)
+      reportDefault(parser, enc, start, end);
+    return 1;
+  }
+  data = poolStoreString(&tempPool,
+                         enc,
+                         start + enc->minBytesPerChar * 4, 
+                        end - enc->minBytesPerChar * 3);
+  if (!data)
+    return 0;
+  normalizeLines(data);
+  commentHandler(handlerArg, data);
+  poolClear(&tempPool);
+  return 1;
+}
+
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
+{
+  if (MUST_CONVERT(enc, s)) {
+    const char **eventPP;
+    const char **eventEndPP;
+    if (enc == encoding) {
+      eventPP = &eventPtr;
+      eventEndPP = &eventEndPtr;
+    }
+    else {
+      eventPP = &(openInternalEntities->internalEventPtr);
+      eventEndPP = &(openInternalEntities->internalEventEndPtr);
+    }
+    do {
+      ICHAR *dataPtr = (ICHAR *)dataBuf;
+      XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+      *eventEndPP = s;
+      defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+      *eventPP = s;
+    } while (s != end);
+  }
+  else
+    defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
+}
+
+
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, int isId, const XML_Char *value)
+{
+  DEFAULT_ATTRIBUTE *att;
+  if (value || isId) {
+    /* The handling of default attributes gets messed up if we have
+       a default which duplicates a non-default. */
+    int i;
+    for (i = 0; i < type->nDefaultAtts; i++)
+      if (attId == type->defaultAtts[i].id)
+       return 1;
+    if (isId && !type->idAtt && !attId->xmlns)
+      type->idAtt = attId;
+  }
+  if (type->nDefaultAtts == type->allocDefaultAtts) {
+    if (type->allocDefaultAtts == 0) {
+      type->allocDefaultAtts = 8;
+      type->defaultAtts = malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
+    }
+    else {
+      type->allocDefaultAtts *= 2;
+      type->defaultAtts = realloc(type->defaultAtts,
+                                 type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
+    }
+    if (!type->defaultAtts)
+      return 0;
+  }
+  att = type->defaultAtts + type->nDefaultAtts;
+  att->id = attId;
+  att->value = value;
+  att->isCdata = isCdata;
+  if (!isCdata)
+    attId->maybeTokenized = 1;
+  type->nDefaultAtts += 1;
+  return 1;
+}
+
+static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
+{
+  const XML_Char *name;
+  for (name = elementType->name; *name; name++) {
+    if (*name == XML_T(':')) {
+      PREFIX *prefix;
+      const XML_Char *s;
+      for (s = elementType->name; s != name; s++) {
+       if (!poolAppendChar(&dtd.pool, *s))
+         return 0;
+      }
+      if (!poolAppendChar(&dtd.pool, XML_T('\0')))
+       return 0;
+      prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
+      if (!prefix)
+       return 0;
+      if (prefix->name == poolStart(&dtd.pool))
+       poolFinish(&dtd.pool);
+      else
+       poolDiscard(&dtd.pool);
+      elementType->prefix = prefix;
+
+    }
+  }
+  return 1;
+}
+
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+{
+  ATTRIBUTE_ID *id;
+  const XML_Char *name;
+  if (!poolAppendChar(&dtd.pool, XML_T('\0')))
+    return 0;
+  name = poolStoreString(&dtd.pool, enc, start, end);
+  if (!name)
+    return 0;
+  ++name;
+  id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
+  if (!id)
+    return 0;
+  if (id->name != name)
+    poolDiscard(&dtd.pool);
+  else {
+    poolFinish(&dtd.pool);
+    if (!ns)
+      ;
+    else if (name[0] == 'x'
+       && name[1] == 'm'
+       && name[2] == 'l'
+       && name[3] == 'n'
+       && name[4] == 's'
+       && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
+      if (name[5] == '\0')
+       id->prefix = &dtd.defaultPrefix;
+      else
+       id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
+      id->xmlns = 1;
+    }
+    else {
+      int i;
+      for (i = 0; name[i]; i++) {
+       if (name[i] == XML_T(':')) {
+         int j;
+         for (j = 0; j < i; j++) {
+           if (!poolAppendChar(&dtd.pool, name[j]))
+             return 0;
+         }
+         if (!poolAppendChar(&dtd.pool, XML_T('\0')))
+           return 0;
+         id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
+         if (id->prefix->name == poolStart(&dtd.pool))
+           poolFinish(&dtd.pool);
+         else
+           poolDiscard(&dtd.pool);
+         break;
+       }
+      }
+    }
+  }
+  return id;
+}
+
+#define CONTEXT_SEP XML_T('\f')
+
+static
+const XML_Char *getContext(XML_Parser parser)
+{
+  HASH_TABLE_ITER iter;
+  int needSep = 0;
+
+  if (dtd.defaultPrefix.binding) {
+    int i;
+    int len;
+    if (!poolAppendChar(&tempPool, XML_T('=')))
+      return 0;
+    len = dtd.defaultPrefix.binding->uriLen;
+    if (namespaceSeparator != XML_T('\0'))
+      len--;
+    for (i = 0; i < len; i++)
+      if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
+       return 0;
+    needSep = 1;
+  }
+
+  hashTableIterInit(&iter, &(dtd.prefixes));
+  for (;;) {
+    int i;
+    int len;
+    const XML_Char *s;
+    PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
+    if (!prefix)
+      break;
+    if (!prefix->binding)
+      continue;
+    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+      return 0;
+    for (s = prefix->name; *s; s++)
+      if (!poolAppendChar(&tempPool, *s))
+        return 0;
+    if (!poolAppendChar(&tempPool, XML_T('=')))
+      return 0;
+    len = prefix->binding->uriLen;
+    if (namespaceSeparator != XML_T('\0'))
+      len--;
+    for (i = 0; i < len; i++)
+      if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
+        return 0;
+    needSep = 1;
+  }
+
+
+  hashTableIterInit(&iter, &(dtd.generalEntities));
+  for (;;) {
+    const XML_Char *s;
+    ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
+    if (!e)
+      break;
+    if (!e->open)
+      continue;
+    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+      return 0;
+    for (s = e->name; *s; s++)
+      if (!poolAppendChar(&tempPool, *s))
+        return 0;
+    needSep = 1;
+  }
+
+  if (!poolAppendChar(&tempPool, XML_T('\0')))
+    return 0;
+  return tempPool.start;
+}
+
+static
+int setContext(XML_Parser parser, const XML_Char *context)
+{
+  const XML_Char *s = context;
+
+  while (*context != XML_T('\0')) {
+    if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
+      ENTITY *e;
+      if (!poolAppendChar(&tempPool, XML_T('\0')))
+       return 0;
+      e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
+      if (e)
+       e->open = 1;
+      if (*s != XML_T('\0'))
+       s++;
+      context = s;
+      poolDiscard(&tempPool);
+    }
+    else if (*s == '=') {
+      PREFIX *prefix;
+      if (poolLength(&tempPool) == 0)
+       prefix = &dtd.defaultPrefix;
+      else {
+       if (!poolAppendChar(&tempPool, XML_T('\0')))
+         return 0;
+       prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
+       if (!prefix)
+         return 0;
+        if (prefix->name == poolStart(&tempPool)) {
+         prefix->name = poolCopyString(&dtd.pool, prefix->name);
+         if (!prefix->name)
+           return 0;
+       }
+       poolDiscard(&tempPool);
+      }
+      for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
+        if (!poolAppendChar(&tempPool, *context))
+          return 0;
+      if (!poolAppendChar(&tempPool, XML_T('\0')))
+       return 0;
+      if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
+       return 0;
+      poolDiscard(&tempPool);
+      if (*context != XML_T('\0'))
+       ++context;
+      s = context;
+    }
+    else {
+      if (!poolAppendChar(&tempPool, *s))
+       return 0;
+      s++;
+    }
+  }
+  return 1;
+}
+
+
+static
+void normalizePublicId(XML_Char *publicId)
+{
+  XML_Char *p = publicId;
+  XML_Char *s;
+  for (s = publicId; *s; s++) {
+    switch (*s) {
+    case 0x20:
+    case 0xD:
+    case 0xA:
+      if (p != publicId && p[-1] != 0x20)
+       *p++ = 0x20;
+      break;
+    default:
+      *p++ = *s;
+    }
+  }
+  if (p != publicId && p[-1] == 0x20)
+    --p;
+  *p = XML_T('\0');
+}
+
+static int dtdInit(DTD *p)
+{
+  poolInit(&(p->pool));
+  hashTableInit(&(p->generalEntities));
+  hashTableInit(&(p->elementTypes));
+  hashTableInit(&(p->attributeIds));
+  hashTableInit(&(p->prefixes));
+  p->complete = 1;
+  p->standalone = 0;
+#ifdef XML_DTD
+  hashTableInit(&(p->paramEntities));
+#endif /* XML_DTD */
+  p->defaultPrefix.name = 0;
+  p->defaultPrefix.binding = 0;
+  return 1;
+}
+
+#ifdef XML_DTD
+
+static void dtdSwap(DTD *p1, DTD *p2)
+{
+  DTD tem;
+  memcpy(&tem, p1, sizeof(DTD));
+  memcpy(p1, p2, sizeof(DTD));
+  memcpy(p2, &tem, sizeof(DTD));
+}
+
+#endif /* XML_DTD */
+
+static void dtdDestroy(DTD *p)
+{
+  HASH_TABLE_ITER iter;
+  hashTableIterInit(&iter, &(p->elementTypes));
+  for (;;) {
+    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+    if (!e)
+      break;
+    if (e->allocDefaultAtts != 0)
+      free(e->defaultAtts);
+  }
+  hashTableDestroy(&(p->generalEntities));
+#ifdef XML_DTD
+  hashTableDestroy(&(p->paramEntities));
+#endif /* XML_DTD */
+  hashTableDestroy(&(p->elementTypes));
+  hashTableDestroy(&(p->attributeIds));
+  hashTableDestroy(&(p->prefixes));
+  poolDestroy(&(p->pool));
+}
+
+/* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
+The new DTD has already been initialized. */
+
+static int dtdCopy(DTD *newDtd, const DTD *oldDtd)
+{
+  HASH_TABLE_ITER iter;
+
+  /* Copy the prefix table. */
+
+  hashTableIterInit(&iter, &(oldDtd->prefixes));
+  for (;;) {
+    const XML_Char *name;
+    const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
+    if (!oldP)
+      break;
+    name = poolCopyString(&(newDtd->pool), oldP->name);
+    if (!name)
+      return 0;
+    if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
+      return 0;
+  }
+
+  hashTableIterInit(&iter, &(oldDtd->attributeIds));
+
+  /* Copy the attribute id table. */
+
+  for (;;) {
+    ATTRIBUTE_ID *newA;
+    const XML_Char *name;
+    const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
+
+    if (!oldA)
+      break;
+    /* Remember to allocate the scratch byte before the name. */
+    if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
+      return 0;
+    name = poolCopyString(&(newDtd->pool), oldA->name);
+    if (!name)
+      return 0;
+    ++name;
+    newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
+    if (!newA)
+      return 0;
+    newA->maybeTokenized = oldA->maybeTokenized;
+    if (oldA->prefix) {
+      newA->xmlns = oldA->xmlns;
+      if (oldA->prefix == &oldDtd->defaultPrefix)
+       newA->prefix = &newDtd->defaultPrefix;
+      else
+       newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
+    }
+  }
+
+  /* Copy the element type table. */
+
+  hashTableIterInit(&iter, &(oldDtd->elementTypes));
+
+  for (;;) {
+    int i;
+    ELEMENT_TYPE *newE;
+    const XML_Char *name;
+    const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+    if (!oldE)
+      break;
+    name = poolCopyString(&(newDtd->pool), oldE->name);
+    if (!name)
+      return 0;
+    newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
+    if (!newE)
+      return 0;
+    if (oldE->nDefaultAtts) {
+      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+      if (!newE->defaultAtts)
+       return 0;
+    }
+    if (oldE->idAtt)
+      newE->idAtt = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
+    newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
+    if (oldE->prefix)
+      newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
+    for (i = 0; i < newE->nDefaultAtts; i++) {
+      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
+      newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
+      if (oldE->defaultAtts[i].value) {
+       newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
+       if (!newE->defaultAtts[i].value)
+         return 0;
+      }
+      else
+       newE->defaultAtts[i].value = 0;
+    }
+  }
+
+  /* Copy the entity tables. */
+  if (!copyEntityTable(&(newDtd->generalEntities),
+                      &(newDtd->pool),
+                      &(oldDtd->generalEntities)))
+      return 0;
+
+#ifdef XML_DTD
+  if (!copyEntityTable(&(newDtd->paramEntities),
+                      &(newDtd->pool),
+                      &(oldDtd->paramEntities)))
+      return 0;
+#endif /* XML_DTD */
+
+  newDtd->complete = oldDtd->complete;
+  newDtd->standalone = oldDtd->standalone;
+  return 1;
+}
+
+static int copyEntityTable(HASH_TABLE *newTable,
+                          STRING_POOL *newPool,
+                          const HASH_TABLE *oldTable)
+{
+  HASH_TABLE_ITER iter;
+  const XML_Char *cachedOldBase = 0;
+  const XML_Char *cachedNewBase = 0;
+
+  hashTableIterInit(&iter, oldTable);
+
+  for (;;) {
+    ENTITY *newE;
+    const XML_Char *name;
+    const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
+    if (!oldE)
+      break;
+    name = poolCopyString(newPool, oldE->name);
+    if (!name)
+      return 0;
+    newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
+    if (!newE)
+      return 0;
+    if (oldE->systemId) {
+      const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
+      if (!tem)
+       return 0;
+      newE->systemId = tem;
+      if (oldE->base) {
+       if (oldE->base == cachedOldBase)
+         newE->base = cachedNewBase;
+       else {
+         cachedOldBase = oldE->base;
+         tem = poolCopyString(newPool, cachedOldBase);
+         if (!tem)
+           return 0;
+         cachedNewBase = newE->base = tem;
+       }
+      }
+    }
+    else {
+      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
+      if (!tem)
+       return 0;
+      newE->textPtr = tem;
+      newE->textLen = oldE->textLen;
+    }
+    if (oldE->notation) {
+      const XML_Char *tem = poolCopyString(newPool, oldE->notation);
+      if (!tem)
+       return 0;
+      newE->notation = tem;
+    }
+  }
+  return 1;
+}
+
+#define INIT_SIZE 64
+
+static
+int keyeq(KEY s1, KEY s2)
+{
+  for (; *s1 == *s2; s1++, s2++)
+    if (*s1 == 0)
+      return 1;
+  return 0;
+}
+
+static
+unsigned long hash(KEY s)
+{
+  unsigned long h = 0;
+  while (*s)
+    h = (h << 5) + h + (unsigned char)*s++;
+  return h;
+}
+
+static
+NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
+{
+  size_t i;
+  if (table->size == 0) {
+    if (!createSize)
+      return 0;
+    table->v = calloc(INIT_SIZE, sizeof(NAMED *));
+    if (!table->v)
+      return 0;
+    table->size = INIT_SIZE;
+    table->usedLim = INIT_SIZE / 2;
+    i = hash(name) & (table->size - 1);
+  }
+  else {
+    unsigned long h = hash(name);
+    for (i = h & (table->size - 1);
+         table->v[i];
+         i == 0 ? i = table->size - 1 : --i) {
+      if (keyeq(name, table->v[i]->name))
+       return table->v[i];
+    }
+    if (!createSize)
+      return 0;
+    if (table->used == table->usedLim) {
+      /* check for overflow */
+      size_t newSize = table->size * 2;
+      NAMED **newV = calloc(newSize, sizeof(NAMED *));
+      if (!newV)
+       return 0;
+      for (i = 0; i < table->size; i++)
+       if (table->v[i]) {
+         size_t j;
+         for (j = hash(table->v[i]->name) & (newSize - 1);
+              newV[j];
+              j == 0 ? j = newSize - 1 : --j)
+           ;
+         newV[j] = table->v[i];
+       }
+      free(table->v);
+      table->v = newV;
+      table->size = newSize;
+      table->usedLim = newSize/2;
+      for (i = h & (table->size - 1);
+          table->v[i];
+          i == 0 ? i = table->size - 1 : --i)
+       ;
+    }
+  }
+  table->v[i] = calloc(1, createSize);
+  if (!table->v[i])
+    return 0;
+  table->v[i]->name = name;
+  (table->used)++;
+  return table->v[i];
+}
+
+static
+void hashTableDestroy(HASH_TABLE *table)
+{
+  size_t i;
+  for (i = 0; i < table->size; i++) {
+    NAMED *p = table->v[i];
+    if (p)
+      free(p);
+  }
+  if (table->v)
+    free(table->v);
+}
+
+static
+void hashTableInit(HASH_TABLE *p)
+{
+  p->size = 0;
+  p->usedLim = 0;
+  p->used = 0;
+  p->v = 0;
+}
+
+static
+void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
+{
+  iter->p = table->v;
+  iter->end = iter->p + table->size;
+}
+
+static
+NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
+{
+  while (iter->p != iter->end) {
+    NAMED *tem = *(iter->p)++;
+    if (tem)
+      return tem;
+  }
+  return 0;
+}
+
+
+static
+void poolInit(STRING_POOL *pool)
+{
+  pool->blocks = 0;
+  pool->freeBlocks = 0;
+  pool->start = 0;
+  pool->ptr = 0;
+  pool->end = 0;
+}
+
+static
+void poolClear(STRING_POOL *pool)
+{
+  if (!pool->freeBlocks)
+    pool->freeBlocks = pool->blocks;
+  else {
+    BLOCK *p = pool->blocks;
+    while (p) {
+      BLOCK *tem = p->next;
+      p->next = pool->freeBlocks;
+      pool->freeBlocks = p;
+      p = tem;
+    }
+  }
+  pool->blocks = 0;
+  pool->start = 0;
+  pool->ptr = 0;
+  pool->end = 0;
+}
+
+static
+void poolDestroy(STRING_POOL *pool)
+{
+  BLOCK *p = pool->blocks;
+  while (p) {
+    BLOCK *tem = p->next;
+    free(p);
+    p = tem;
+  }
+  pool->blocks = 0;
+  p = pool->freeBlocks;
+  while (p) {
+    BLOCK *tem = p->next;
+    free(p);
+    p = tem;
+  }
+  pool->freeBlocks = 0;
+  pool->ptr = 0;
+  pool->start = 0;
+  pool->end = 0;
+}
+
+static
+XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
+                    const char *ptr, const char *end)
+{
+  if (!pool->ptr && !poolGrow(pool))
+    return 0;
+  for (;;) {
+    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+    if (ptr == end)
+      break;
+    if (!poolGrow(pool))
+      return 0;
+  }
+  return pool->start;
+}
+
+static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
+{
+  do {
+    if (!poolAppendChar(pool, *s))
+      return 0;
+  } while (*s++);
+  s = pool->start;
+  poolFinish(pool);
+  return s;
+}
+
+static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
+{
+  if (!pool->ptr && !poolGrow(pool))
+    return 0;
+  for (; n > 0; --n, s++) {
+    if (!poolAppendChar(pool, *s))
+      return 0;
+
+  }
+  s = pool->start;
+  poolFinish(pool);
+  return s;
+}
+
+static
+XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+                         const char *ptr, const char *end)
+{
+  if (!poolAppend(pool, enc, ptr, end))
+    return 0;
+  if (pool->ptr == pool->end && !poolGrow(pool))
+    return 0;
+  *(pool->ptr)++ = 0;
+  return pool->start;
+}
+
+static
+int poolGrow(STRING_POOL *pool)
+{
+  if (pool->freeBlocks) {
+    if (pool->start == 0) {
+      pool->blocks = pool->freeBlocks;
+      pool->freeBlocks = pool->freeBlocks->next;
+      pool->blocks->next = 0;
+      pool->start = pool->blocks->s;
+      pool->end = pool->start + pool->blocks->size;
+      pool->ptr = pool->start;
+      return 1;
+    }
+    if (pool->end - pool->start < pool->freeBlocks->size) {
+      BLOCK *tem = pool->freeBlocks->next;
+      pool->freeBlocks->next = pool->blocks;
+      pool->blocks = pool->freeBlocks;
+      pool->freeBlocks = tem;
+      memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
+      pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+      pool->start = pool->blocks->s;
+      pool->end = pool->start + pool->blocks->size;
+      return 1;
+    }
+  }
+  if (pool->blocks && pool->start == pool->blocks->s) {
+    int blockSize = (pool->end - pool->start)*2;
+    pool->blocks = realloc(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
+    if (!pool->blocks)
+      return 0;
+    pool->blocks->size = blockSize;
+    pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+    pool->start = pool->blocks->s;
+    pool->end = pool->start + blockSize;
+  }
+  else {
+    BLOCK *tem;
+    int blockSize = pool->end - pool->start;
+    if (blockSize < INIT_BLOCK_SIZE)
+      blockSize = INIT_BLOCK_SIZE;
+    else
+      blockSize *= 2;
+    tem = malloc(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
+    if (!tem)
+      return 0;
+    tem->size = blockSize;
+    tem->next = pool->blocks;
+    pool->blocks = tem;
+    if (pool->ptr != pool->start)
+      memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
+    pool->ptr = tem->s + (pool->ptr - pool->start);
+    pool->start = tem->s;
+    pool->end = tem->s + blockSize;
+  }
+  return 1;
+}
diff --git a/contrib/src/xrc/expat/xmlparse/xmlparse.h b/contrib/src/xrc/expat/xmlparse/xmlparse.h
new file mode 100644 (file)
index 0000000..6dffe74
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#ifndef XmlParse_INCLUDED
+#define XmlParse_INCLUDED 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef XMLPARSEAPI
+#define XMLPARSEAPI /* as nothing */
+#endif
+
+typedef void *XML_Parser;
+
+#ifdef XML_UNICODE_WCHAR_T
+
+/* XML_UNICODE_WCHAR_T will work only if sizeof(wchar_t) == 2 and wchar_t
+uses Unicode. */
+/* Information is UTF-16 encoded as wchar_ts */
+
+#ifndef XML_UNICODE
+#define XML_UNICODE
+#endif
+
+#include <stddef.h>
+typedef wchar_t XML_Char;
+typedef wchar_t XML_LChar;
+
+#else /* not XML_UNICODE_WCHAR_T */
+
+#ifdef XML_UNICODE
+
+/* Information is UTF-16 encoded as unsigned shorts */
+typedef unsigned short XML_Char;
+typedef char XML_LChar;
+
+#else /* not XML_UNICODE */
+
+/* Information is UTF-8 encoded. */
+typedef char XML_Char;
+typedef char XML_LChar;
+
+#endif /* not XML_UNICODE */
+
+#endif /* not XML_UNICODE_WCHAR_T */
+
+
+/* Constructs a new parser; encoding is the encoding specified by the external
+protocol or null if there is none specified. */
+
+XML_Parser XMLPARSEAPI
+XML_ParserCreate(const XML_Char *encoding);
+
+/* Constructs a new parser and namespace processor.  Element type names
+and attribute names that belong to a namespace will be expanded;
+unprefixed attribute names are never expanded; unprefixed element type
+names are expanded only if there is a default namespace. The expanded
+name is the concatenation of the namespace URI, the namespace separator character,
+and the local part of the name.  If the namespace separator is '\0' then
+the namespace URI and the local part will be concatenated without any
+separator.  When a namespace is not declared, the name and prefix will be
+passed through without expansion. */
+
+XML_Parser XMLPARSEAPI
+XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
+
+
+/* atts is array of name/value pairs, terminated by 0;
+   names and values are 0 terminated. */
+
+typedef void (*XML_StartElementHandler)(void *userData,
+                                       const XML_Char *name,
+                                       const XML_Char **atts);
+
+typedef void (*XML_EndElementHandler)(void *userData,
+                                     const XML_Char *name);
+
+/* s is not 0 terminated. */
+typedef void (*XML_CharacterDataHandler)(void *userData,
+                                        const XML_Char *s,
+                                        int len);
+
+/* target and data are 0 terminated */
+typedef void (*XML_ProcessingInstructionHandler)(void *userData,
+                                                const XML_Char *target,
+                                                const XML_Char *data);
+
+/* data is 0 terminated */
+typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data);
+
+typedef void (*XML_StartCdataSectionHandler)(void *userData);
+typedef void (*XML_EndCdataSectionHandler)(void *userData);
+
+/* This is called for any characters in the XML document for
+which there is no applicable handler.  This includes both
+characters that are part of markup which is of a kind that is
+not reported (comments, markup declarations), or characters
+that are part of a construct which could be reported but
+for which no handler has been supplied. The characters are passed
+exactly as they were in the XML document except that
+they will be encoded in UTF-8.  Line boundaries are not normalized.
+Note that a byte order mark character is not passed to the default handler.
+There are no guarantees about how characters are divided between calls
+to the default handler: for example, a comment might be split between
+multiple calls. */
+
+typedef void (*XML_DefaultHandler)(void *userData,
+                                  const XML_Char *s,
+                                  int len);
+
+/* This is called for the start of the DOCTYPE declaration when the
+name of the DOCTYPE is encountered. */
+typedef void (*XML_StartDoctypeDeclHandler)(void *userData,
+                                           const XML_Char *doctypeName);
+
+/* This is called for the start of the DOCTYPE declaration when the
+closing > is encountered, but after processing any external subset. */
+typedef void (*XML_EndDoctypeDeclHandler)(void *userData);
+
+/* This is called for a declaration of an unparsed (NDATA)
+entity.  The base argument is whatever was set by XML_SetBase.
+The entityName, systemId and notationName arguments will never be null.
+The other arguments may be. */
+
+typedef void (*XML_UnparsedEntityDeclHandler)(void *userData,
+                                             const XML_Char *entityName,
+                                             const XML_Char *base,
+                                             const XML_Char *systemId,
+                                             const XML_Char *publicId,
+                                             const XML_Char *notationName);
+
+/* This is called for a declaration of notation.
+The base argument is whatever was set by XML_SetBase.
+The notationName will never be null.  The other arguments can be. */
+
+typedef void (*XML_NotationDeclHandler)(void *userData,
+                                       const XML_Char *notationName,
+                                       const XML_Char *base,
+                                       const XML_Char *systemId,
+                                       const XML_Char *publicId);
+
+typedef void (*XML_ExternalParsedEntityDeclHandler)(void *userData,
+                                                   const XML_Char *entityName,
+                                                   const XML_Char *base,
+                                                   const XML_Char *systemId,
+                                                   const XML_Char *publicId);
+
+typedef void (*XML_InternalParsedEntityDeclHandler)(void *userData,
+                                                   const XML_Char *entityName,
+                                                   const XML_Char *replacementText,
+                                                   int replacementTextLength);
+
+/* When namespace processing is enabled, these are called once for
+each namespace declaration. The call to the start and end element
+handlers occur between the calls to the start and end namespace
+declaration handlers. For an xmlns attribute, prefix will be null.
+For an xmlns="" attribute, uri will be null. */
+
+typedef void (*XML_StartNamespaceDeclHandler)(void *userData,
+                                             const XML_Char *prefix,
+                                             const XML_Char *uri);
+
+typedef void (*XML_EndNamespaceDeclHandler)(void *userData,
+                                           const XML_Char *prefix);
+
+/* This is called if the document is not standalone (it has an
+external subset or a reference to a parameter entity, but does not
+have standalone="yes"). If this handler returns 0, then processing
+will not continue, and the parser will return a
+XML_ERROR_NOT_STANDALONE error. */
+
+typedef int (*XML_NotStandaloneHandler)(void *userData);
+
+/* This is called for a reference to an external parsed general entity.
+The referenced entity is not automatically parsed.
+The application can parse it immediately or later using
+XML_ExternalEntityParserCreate.
+The parser argument is the parser parsing the entity containing the reference;
+it can be passed as the parser argument to XML_ExternalEntityParserCreate.
+The systemId argument is the system identifier as specified in the entity declaration;
+it will not be null.
+The base argument is the system identifier that should be used as the base for
+resolving systemId if systemId was relative; this is set by XML_SetBase;
+it may be null.
+The publicId argument is the public identifier as specified in the entity declaration,
+or null if none was specified; the whitespace in the public identifier
+will have been normalized as required by the XML spec.
+The context argument specifies the parsing context in the format
+expected by the context argument to
+XML_ExternalEntityParserCreate; context is valid only until the handler
+returns, so if the referenced entity is to be parsed later, it must be copied.
+The handler should return 0 if processing should not continue because of
+a fatal error in the handling of the external entity.
+In this case the calling parser will return an XML_ERROR_EXTERNAL_ENTITY_HANDLING
+error.
+Note that unlike other handlers the first argument is the parser, not userData. */
+
+typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser,
+                                           const XML_Char *context,
+                                           const XML_Char *base,
+                                           const XML_Char *systemId,
+                                           const XML_Char *publicId);
+
+/* This structure is filled in by the XML_UnknownEncodingHandler
+to provide information to the parser about encodings that are unknown
+to the parser.
+The map[b] member gives information about byte sequences
+whose first byte is b.
+If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c.
+If map[b] is -1, then the byte sequence is malformed.
+If map[b] is -n, where n >= 2, then b is the first byte of an n-byte
+sequence that encodes a single Unicode scalar value.
+The data member will be passed as the first argument to the convert function.
+The convert function is used to convert multibyte sequences;
+s will point to a n-byte sequence where map[(unsigned char)*s] == -n.
+The convert function must return the Unicode scalar value
+represented by this byte sequence or -1 if the byte sequence is malformed.
+The convert function may be null if the encoding is a single-byte encoding,
+that is if map[b] >= -1 for all bytes b.
+When the parser is finished with the encoding, then if release is not null,
+it will call release passing it the data member;
+once release has been called, the convert function will not be called again.
+
+Expat places certain restrictions on the encodings that are supported
+using this mechanism.
+
+1. Every ASCII character that can appear in a well-formed XML document,
+other than the characters
+
+  $@\^`{}~
+
+must be represented by a single byte, and that byte must be the
+same byte that represents that character in ASCII.
+
+2. No character may require more than 4 bytes to encode.
+
+3. All characters encoded must have Unicode scalar values <= 0xFFFF,
+(ie characters that would be encoded by surrogates in UTF-16
+are  not allowed).  Note that this restriction doesn't apply to
+the built-in support for UTF-8 and UTF-16.
+
+4. No Unicode character may be encoded by more than one distinct sequence
+of bytes. */
+
+typedef struct {
+  int map[256];
+  void *data;
+  int (*convert)(void *data, const char *s);
+  void (*release)(void *data);
+} XML_Encoding;
+
+/* This is called for an encoding that is unknown to the parser.
+The encodingHandlerData argument is that which was passed as the
+second argument to XML_SetUnknownEncodingHandler.
+The name argument gives the name of the encoding as specified in
+the encoding declaration.
+If the callback can provide information about the encoding,
+it must fill in the XML_Encoding structure, and return 1.
+Otherwise it must return 0.
+If info does not describe a suitable encoding,
+then the parser will return an XML_UNKNOWN_ENCODING error. */
+
+typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData,
+                                         const XML_Char *name,
+                                         XML_Encoding *info);
+
+void XMLPARSEAPI
+XML_SetElementHandler(XML_Parser parser,
+                     XML_StartElementHandler start,
+                     XML_EndElementHandler end);
+
+void XMLPARSEAPI
+XML_SetCharacterDataHandler(XML_Parser parser,
+                           XML_CharacterDataHandler handler);
+
+void XMLPARSEAPI
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+                                   XML_ProcessingInstructionHandler handler);
+void XMLPARSEAPI
+XML_SetCommentHandler(XML_Parser parser,
+                      XML_CommentHandler handler);
+
+void XMLPARSEAPI
+XML_SetCdataSectionHandler(XML_Parser parser,
+                          XML_StartCdataSectionHandler start,
+                          XML_EndCdataSectionHandler end);
+
+/* This sets the default handler and also inhibits expansion of internal entities.
+The entity reference will be passed to the default handler. */
+
+void XMLPARSEAPI
+XML_SetDefaultHandler(XML_Parser parser,
+                     XML_DefaultHandler handler);
+
+/* This sets the default handler but does not inhibit expansion of internal entities.
+The entity reference will not be passed to the default handler. */
+
+void XMLPARSEAPI
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+                           XML_DefaultHandler handler);
+
+void XMLPARSEAPI
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+                         XML_StartDoctypeDeclHandler start,
+                         XML_EndDoctypeDeclHandler end);
+
+void XMLPARSEAPI
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+                                XML_UnparsedEntityDeclHandler handler);
+
+void XMLPARSEAPI
+XML_SetNotationDeclHandler(XML_Parser parser,
+                          XML_NotationDeclHandler handler);
+
+void XMLPARSEAPI
+XML_SetExternalParsedEntityDeclHandler(XML_Parser parser,
+                                      XML_ExternalParsedEntityDeclHandler handler);
+
+void XMLPARSEAPI
+XML_SetInternalParsedEntityDeclHandler(XML_Parser parser,
+                                      XML_InternalParsedEntityDeclHandler handler);
+
+void XMLPARSEAPI
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+                           XML_StartNamespaceDeclHandler start,
+                           XML_EndNamespaceDeclHandler end);
+
+void XMLPARSEAPI
+XML_SetNotStandaloneHandler(XML_Parser parser,
+                           XML_NotStandaloneHandler handler);
+
+void XMLPARSEAPI
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+                               XML_ExternalEntityRefHandler handler);
+
+/* If a non-null value for arg is specified here, then it will be passed
+as the first argument to the external entity ref handler instead
+of the parser object. */
+void XMLPARSEAPI
+XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg);
+
+void XMLPARSEAPI
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+                             XML_UnknownEncodingHandler handler,
+                             void *encodingHandlerData);
+
+/* This can be called within a handler for a start element, end element,
+processing instruction or character data.  It causes the corresponding
+markup to be passed to the default handler. */
+void XMLPARSEAPI XML_DefaultCurrent(XML_Parser parser);
+
+/* This value is passed as the userData argument to callbacks. */
+void XMLPARSEAPI
+XML_SetUserData(XML_Parser parser, void *userData);
+
+/* Returns the last value set by XML_SetUserData or null. */
+#define XML_GetUserData(parser) (*(void **)(parser))
+
+/* This is equivalent to supplying an encoding argument
+to XML_ParserCreate. It must not be called after XML_Parse
+or XML_ParseBuffer. */
+
+int XMLPARSEAPI
+XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
+
+/* If this function is called, then the parser will be passed
+as the first argument to callbacks instead of userData.
+The userData will still be accessible using XML_GetUserData. */
+
+void XMLPARSEAPI
+XML_UseParserAsHandlerArg(XML_Parser parser);
+
+/* Sets the base to be used for resolving relative URIs in system identifiers in
+declarations.  Resolving relative identifiers is left to the application:
+this value will be passed through as the base argument to the
+XML_ExternalEntityRefHandler, XML_NotationDeclHandler
+and XML_UnparsedEntityDeclHandler. The base argument will be copied.
+Returns zero if out of memory, non-zero otherwise. */
+
+int XMLPARSEAPI
+XML_SetBase(XML_Parser parser, const XML_Char *base);
+
+const XML_Char XMLPARSEAPI *
+XML_GetBase(XML_Parser parser);
+
+/* Returns the number of the attribute/value pairs passed in last call
+to the XML_StartElementHandler that were specified in the start-tag
+rather than defaulted. Each attribute/value pair counts as 2; thus
+this correspondds to an index into the atts array passed to the
+XML_StartElementHandler. */
+
+int XMLPARSEAPI XML_GetSpecifiedAttributeCount(XML_Parser parser);
+
+/* Returns the index of the ID attribute passed in the last call to
+XML_StartElementHandler, or -1 if there is no ID attribute.  Each
+attribute/value pair counts as 2; thus this correspondds to an index
+into the atts array passed to the XML_StartElementHandler. */
+int XMLPARSEAPI XML_GetIdAttributeIndex(XML_Parser parser);
+
+/* Parses some input. Returns 0 if a fatal error is detected.
+The last call to XML_Parse must have isFinal true;
+len may be zero for this call (or any other). */
+int XMLPARSEAPI
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
+
+void XMLPARSEAPI *
+XML_GetBuffer(XML_Parser parser, int len);
+
+int XMLPARSEAPI
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
+
+/* Creates an XML_Parser object that can parse an external general entity;
+context is a '\0'-terminated string specifying the parse context;
+encoding is a '\0'-terminated string giving the name of the externally specified encoding,
+or null if there is no externally specified encoding.
+The context string consists of a sequence of tokens separated by formfeeds (\f);
+a token consisting of a name specifies that the general entity of the name
+is open; a token of the form prefix=uri specifies the namespace for a particular
+prefix; a token of the form =uri specifies the default namespace.
+This can be called at any point after the first call to an ExternalEntityRefHandler
+so longer as the parser has not yet been freed.
+The new parser is completely independent and may safely be used in a separate thread.
+The handlers and userData are initialized from the parser argument.
+Returns 0 if out of memory.  Otherwise returns a new XML_Parser object. */
+XML_Parser XMLPARSEAPI
+XML_ExternalEntityParserCreate(XML_Parser parser,
+                              const XML_Char *context,
+                              const XML_Char *encoding);
+
+enum XML_ParamEntityParsing {
+  XML_PARAM_ENTITY_PARSING_NEVER,
+  XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
+  XML_PARAM_ENTITY_PARSING_ALWAYS
+};
+
+/* Controls parsing of parameter entities (including the external DTD
+subset). If parsing of parameter entities is enabled, then references
+to external parameter entities (including the external DTD subset)
+will be passed to the handler set with
+XML_SetExternalEntityRefHandler.  The context passed will be 0.
+Unlike external general entities, external parameter entities can only
+be parsed synchronously.  If the external parameter entity is to be
+parsed, it must be parsed during the call to the external entity ref
+handler: the complete sequence of XML_ExternalEntityParserCreate,
+XML_Parse/XML_ParseBuffer and XML_ParserFree calls must be made during
+this call.  After XML_ExternalEntityParserCreate has been called to
+create the parser for the external parameter entity (context must be 0
+for this call), it is illegal to make any calls on the old parser
+until XML_ParserFree has been called on the newly created parser.  If
+the library has been compiled without support for parameter entity
+parsing (ie without XML_DTD being defined), then
+XML_SetParamEntityParsing will return 0 if parsing of parameter
+entities is requested; otherwise it will return non-zero. */
+
+int XMLPARSEAPI
+XML_SetParamEntityParsing(XML_Parser parser,
+                         enum XML_ParamEntityParsing parsing);
+
+enum XML_Error {
+  XML_ERROR_NONE,
+  XML_ERROR_NO_MEMORY,
+  XML_ERROR_SYNTAX,
+  XML_ERROR_NO_ELEMENTS,
+  XML_ERROR_INVALID_TOKEN,
+  XML_ERROR_UNCLOSED_TOKEN,
+  XML_ERROR_PARTIAL_CHAR,
+  XML_ERROR_TAG_MISMATCH,
+  XML_ERROR_DUPLICATE_ATTRIBUTE,
+  XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
+  XML_ERROR_PARAM_ENTITY_REF,
+  XML_ERROR_UNDEFINED_ENTITY,
+  XML_ERROR_RECURSIVE_ENTITY_REF,
+  XML_ERROR_ASYNC_ENTITY,
+  XML_ERROR_BAD_CHAR_REF,
+  XML_ERROR_BINARY_ENTITY_REF,
+  XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
+  XML_ERROR_MISPLACED_XML_PI,
+  XML_ERROR_UNKNOWN_ENCODING,
+  XML_ERROR_INCORRECT_ENCODING,
+  XML_ERROR_UNCLOSED_CDATA_SECTION,
+  XML_ERROR_EXTERNAL_ENTITY_HANDLING,
+  XML_ERROR_NOT_STANDALONE
+};
+
+/* If XML_Parse or XML_ParseBuffer have returned 0, then XML_GetErrorCode
+returns information about the error. */
+
+enum XML_Error XMLPARSEAPI XML_GetErrorCode(XML_Parser parser);
+
+/* These functions return information about the current parse location.
+They may be called when XML_Parse or XML_ParseBuffer return 0;
+in this case the location is the location of the character at which
+the error was detected.
+They may also be called from any other callback called to report
+some parse event; in this the location is the location of the first
+of the sequence of characters that generated the event. */
+
+int XMLPARSEAPI XML_GetCurrentLineNumber(XML_Parser parser);
+int XMLPARSEAPI XML_GetCurrentColumnNumber(XML_Parser parser);
+long XMLPARSEAPI XML_GetCurrentByteIndex(XML_Parser parser);
+
+/* Return the number of bytes in the current event.
+Returns 0 if the event is in an internal entity. */
+
+int XMLPARSEAPI XML_GetCurrentByteCount(XML_Parser parser);
+
+/* For backwards compatibility with previous versions. */
+#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
+#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
+#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
+
+/* Frees memory used by the parser. */
+void XMLPARSEAPI
+XML_ParserFree(XML_Parser parser);
+
+/* Returns a string describing the error. */
+const XML_LChar XMLPARSEAPI *XML_ErrorString(int code);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlParse_INCLUDED */
diff --git a/contrib/src/xrc/expat/xmltok/ascii.h b/contrib/src/xrc/expat/xmltok/ascii.h
new file mode 100644 (file)
index 0000000..a8a621c
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#define ASCII_A 0x41
+#define ASCII_B 0x42
+#define ASCII_C 0x43
+#define ASCII_D 0x44
+#define ASCII_E 0x45
+#define ASCII_F 0x46
+#define ASCII_G 0x47
+#define ASCII_H 0x48
+#define ASCII_I 0x49
+#define ASCII_J 0x4A
+#define ASCII_K 0x4B
+#define ASCII_L 0x4C
+#define ASCII_M 0x4D
+#define ASCII_N 0x4E
+#define ASCII_O 0x4F
+#define ASCII_P 0x50
+#define ASCII_Q 0x51
+#define ASCII_R 0x52
+#define ASCII_S 0x53
+#define ASCII_T 0x54
+#define ASCII_U 0x55
+#define ASCII_V 0x56
+#define ASCII_W 0x57
+#define ASCII_X 0x58
+#define ASCII_Y 0x59
+#define ASCII_Z 0x5A
+
+#define ASCII_a 0x61
+#define ASCII_b 0x62
+#define ASCII_c 0x63
+#define ASCII_d 0x64
+#define ASCII_e 0x65
+#define ASCII_f 0x66
+#define ASCII_g 0x67
+#define ASCII_h 0x68
+#define ASCII_i 0x69
+#define ASCII_j 0x6A
+#define ASCII_k 0x6B
+#define ASCII_l 0x6C
+#define ASCII_m 0x6D
+#define ASCII_n 0x6E
+#define ASCII_o 0x6F
+#define ASCII_p 0x70
+#define ASCII_q 0x71
+#define ASCII_r 0x72
+#define ASCII_s 0x73
+#define ASCII_t 0x74
+#define ASCII_u 0x75
+#define ASCII_v 0x76
+#define ASCII_w 0x77
+#define ASCII_x 0x78
+#define ASCII_y 0x79
+#define ASCII_z 0x7A
+
+#define ASCII_0 0x30
+#define ASCII_1 0x31
+#define ASCII_2 0x32
+#define ASCII_3 0x33
+#define ASCII_4 0x34
+#define ASCII_5 0x35
+#define ASCII_6 0x36
+#define ASCII_7 0x37
+#define ASCII_8 0x38
+#define ASCII_9 0x39
+
+#define ASCII_TAB 0x09
+#define ASCII_SPACE 0x20 
+#define ASCII_EXCL 0x21
+#define ASCII_QUOT 0x22
+#define ASCII_AMP 0x26
+#define ASCII_APOS 0x27
+#define ASCII_MINUS 0x2D
+#define ASCII_PERIOD 0x2E
+#define ASCII_COLON 0x3A
+#define ASCII_SEMI 0x3B
+#define ASCII_LT 0x3C
+#define ASCII_EQUALS 0x3D
+#define ASCII_GT 0x3E
+#define ASCII_LSQB 0x5B
+#define ASCII_RSQB 0x5D
+#define ASCII_UNDERSCORE 0x5F
diff --git a/contrib/src/xrc/expat/xmltok/asciitab.h b/contrib/src/xrc/expat/xmltok/asciitab.h
new file mode 100644 (file)
index 0000000..e994576
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/contrib/src/xrc/expat/xmltok/dllmain.c b/contrib/src/xrc/expat/xmltok/dllmain.c
new file mode 100644 (file)
index 0000000..d5aa4a3
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#define STRICT 1
+#define WIN32_LEAN_AND_MEAN 1
+
+#include <windows.h>
+
+BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
+{
+  return TRUE;
+}
+
diff --git a/contrib/src/xrc/expat/xmltok/iasciitab.h b/contrib/src/xrc/expat/xmltok/iasciitab.h
new file mode 100644 (file)
index 0000000..2694d9d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/contrib/src/xrc/expat/xmltok/latin1tab.h b/contrib/src/xrc/expat/xmltok/latin1tab.h
new file mode 100644 (file)
index 0000000..6e01d50
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
+/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
diff --git a/contrib/src/xrc/expat/xmltok/nametab.h b/contrib/src/xrc/expat/xmltok/nametab.h
new file mode 100644 (file)
index 0000000..b05e62c
--- /dev/null
@@ -0,0 +1,150 @@
+static const unsigned namingBitmap[] = {
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
+0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
+0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
+0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
+0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
+0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
+0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
+0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
+0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
+0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
+0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
+0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
+0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
+0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
+0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
+0x40000000, 0xF580C900, 0x00000007, 0x02010800,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
+0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
+0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
+0x00000000, 0x00004C40, 0x00000000, 0x00000000,
+0x00000007, 0x00000000, 0x00000000, 0x00000000,
+0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
+0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
+0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
+0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
+0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
+0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
+0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
+0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
+0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
+0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
+0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
+0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
+0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
+0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
+0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
+0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
+};
+static const unsigned char nmstrtPages[] = {
+0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
+0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static const unsigned char namePages[] = {
+0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
+0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/contrib/src/xrc/expat/xmltok/utf8tab.h b/contrib/src/xrc/expat/xmltok/utf8tab.h
new file mode 100644 (file)
index 0000000..28d9b59
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+
+/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
+/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
diff --git a/contrib/src/xrc/expat/xmltok/xmldef.h b/contrib/src/xrc/expat/xmltok/xmldef.h
new file mode 100644 (file)
index 0000000..57b8333
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#include <string.h>
+
+#ifdef XML_WINLIB
+
+#define WIN32_LEAN_AND_MEAN
+#define STRICT
+#include <windows.h>
+
+#define malloc(x) HeapAlloc(GetProcessHeap(), 0, (x))
+#define calloc(x, y) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (x)*(y))
+#define free(x) HeapFree(GetProcessHeap(), 0, (x))
+#define realloc(x, y) HeapReAlloc(GetProcessHeap(), 0, x, y)
+#define abort() /* as nothing */
+
+#else /* not XML_WINLIB */
+
+#include <stdlib.h>
+
+#endif /* not XML_WINLIB */
+
+/* This file can be used for any definitions needed in
+particular environments. */
+
+/* Mozilla specific defines */
+
+#ifdef MOZILLA_CLIENT
+
+#include "nspr.h"
+#define malloc(x) PR_Malloc((size_t)(x))
+#define realloc(x, y) PR_Realloc((x), (size_t)(y))
+#define calloc(x, y) PR_Calloc((x),(y))
+#define free(x) PR_Free(x)
+#if PR_BYTES_PER_INT != 4
+#define int int32
+#endif
+
+/* Enable Unicode string processing in expat. */
+#ifndef XML_UNICODE
+#define XML_UNICODE
+#endif
+
+/* Enable external parameter entity parsing in expat */
+#ifndef XML_DTD
+#define XML_DTD 1
+#endif
+
+#endif /* MOZILLA_CLIENT */
diff --git a/contrib/src/xrc/expat/xmltok/xmlrole.c b/contrib/src/xrc/expat/xmltok/xmlrole.c
new file mode 100644 (file)
index 0000000..50265f8
--- /dev/null
@@ -0,0 +1,1268 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#include "xmldef.h"
+#include "xmlrole.h"
+#include "ascii.h"
+
+/* Doesn't check:
+
+ that ,| are not mixed in a model group
+ content of literals
+
+*/
+
+static const char KW_ANY[] = { ASCII_A, ASCII_N, ASCII_Y, '\0' };
+static const char KW_ATTLIST[] = { ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
+static const char KW_CDATA[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_DOCTYPE[] = { ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
+static const char KW_ELEMENT[] = { ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
+static const char KW_EMPTY[] = { ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
+static const char KW_ENTITIES[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
+static const char KW_ENTITY[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
+static const char KW_FIXED[] = { ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
+static const char KW_ID[] = { ASCII_I, ASCII_D, '\0' };
+static const char KW_IDREF[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
+static const char KW_IDREFS[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
+/* Remove compiler warnings for not using when XML_DTD is not defined */
+#ifdef XML_DTD
+static const char KW_INCLUDE[] = { ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
+static const char KW_IGNORE[] = { ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
+#endif
+static const char KW_IMPLIED[] = { ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
+static const char KW_NDATA[] = { ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_NMTOKEN[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
+static const char KW_NMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
+static const char KW_NOTATION[] = { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, '\0' };
+static const char KW_PCDATA[] = { ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_PUBLIC[] = { ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
+static const char KW_REQUIRED[] = { ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, '\0' };
+static const char KW_SYSTEM[] = { ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
+
+#ifndef MIN_BYTES_PER_CHAR
+#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
+#endif
+
+#ifdef XML_DTD
+#define setTopLevel(state) \
+  ((state)->handler = ((state)->documentEntity \
+                       ? internalSubset \
+                       : externalSubset1))
+#else /* not XML_DTD */
+#define setTopLevel(state) ((state)->handler = internalSubset)
+#endif /* not XML_DTD */
+
+typedef int PROLOG_HANDLER(PROLOG_STATE *state,
+                          int tok,
+                          const char *ptr,
+                          const char *end,
+                          const ENCODING *enc);
+
+static PROLOG_HANDLER
+  prolog0, prolog1, prolog2,
+  doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
+  internalSubset,
+  entity0, entity1, entity2, entity3, entity4, entity5, entity6,
+  entity7, entity8, entity9,
+  notation0, notation1, notation2, notation3, notation4,
+  attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
+  attlist7, attlist8, attlist9,
+  element0, element1, element2, element3, element4, element5, element6,
+  element7,
+#ifdef XML_DTD
+  externalSubset0, externalSubset1,
+  condSect0, condSect1, condSect2,
+#endif /* XML_DTD */
+  declClose,
+  error;
+
+static
+int common(PROLOG_STATE *state, int tok);
+
+static
+int prolog0(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    state->handler = prolog1;
+    return XML_ROLE_NONE;
+  case XML_TOK_XML_DECL:
+    state->handler = prolog1;
+    return XML_ROLE_XML_DECL;
+  case XML_TOK_PI:
+    state->handler = prolog1;
+    return XML_ROLE_NONE;
+  case XML_TOK_COMMENT:
+    state->handler = prolog1;
+  case XML_TOK_BOM:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_OPEN:
+    if (!XmlNameMatchesAscii(enc,
+                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_DOCTYPE))
+      break;
+    state->handler = doctype0;
+    return XML_ROLE_NONE;
+  case XML_TOK_INSTANCE_START:
+    state->handler = error;
+    return XML_ROLE_INSTANCE_START;
+  }
+  return common(state, tok);
+}
+
+static
+int prolog1(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_PI:
+  case XML_TOK_COMMENT:
+  case XML_TOK_BOM:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_OPEN:
+    if (!XmlNameMatchesAscii(enc,
+                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_DOCTYPE))
+      break;
+    state->handler = doctype0;
+    return XML_ROLE_NONE;
+  case XML_TOK_INSTANCE_START:
+    state->handler = error;
+    return XML_ROLE_INSTANCE_START;
+  }
+  return common(state, tok);
+}
+
+static
+int prolog2(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_PI:
+  case XML_TOK_COMMENT:
+    return XML_ROLE_NONE;
+  case XML_TOK_INSTANCE_START:
+    state->handler = error;
+    return XML_ROLE_INSTANCE_START;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype0(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = doctype1;
+    return XML_ROLE_DOCTYPE_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype1(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = internalSubset;
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    state->handler = prolog2;
+    return XML_ROLE_DOCTYPE_CLOSE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = doctype3;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = doctype2;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype2(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = doctype3;
+    return XML_ROLE_DOCTYPE_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype3(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = doctype4;
+    return XML_ROLE_DOCTYPE_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype4(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = internalSubset;
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    state->handler = prolog2;
+    return XML_ROLE_DOCTYPE_CLOSE;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype5(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    state->handler = prolog2;
+    return XML_ROLE_DOCTYPE_CLOSE;
+  }
+  return common(state, tok);
+}
+
+static
+int internalSubset(PROLOG_STATE *state,
+                  int tok,
+                  const char *ptr,
+                  const char *end,
+                  const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_OPEN:
+    if (XmlNameMatchesAscii(enc,
+                           ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_ENTITY)) {
+      state->handler = entity0;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                           ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_ATTLIST)) {
+      state->handler = attlist0;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                           ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_ELEMENT)) {
+      state->handler = element0;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                           ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_NOTATION)) {
+      state->handler = notation0;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_PI:
+  case XML_TOK_COMMENT:
+    return XML_ROLE_NONE;
+  case XML_TOK_PARAM_ENTITY_REF:
+    return XML_ROLE_PARAM_ENTITY_REF;
+  case XML_TOK_CLOSE_BRACKET:
+    state->handler = doctype5;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static
+int externalSubset0(PROLOG_STATE *state,
+                   int tok,
+                   const char *ptr,
+                   const char *end,
+                   const ENCODING *enc)
+{
+  state->handler = externalSubset1;
+  if (tok == XML_TOK_XML_DECL)
+    return XML_ROLE_TEXT_DECL;
+  return externalSubset1(state, tok, ptr, end, enc);
+}
+
+static
+int externalSubset1(PROLOG_STATE *state,
+                   int tok,
+                   const char *ptr,
+                   const char *end,
+                   const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_COND_SECT_OPEN:
+    state->handler = condSect0;
+    return XML_ROLE_NONE;
+  case XML_TOK_COND_SECT_CLOSE:
+    if (state->includeLevel == 0)
+      break;
+    state->includeLevel -= 1;
+    return XML_ROLE_NONE;
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_BRACKET:
+    break;
+  case XML_TOK_NONE:
+    if (state->includeLevel)
+      break;
+    return XML_ROLE_NONE;
+  default:
+    return internalSubset(state, tok, ptr, end, enc);
+  }
+  return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static
+int entity0(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_PERCENT:
+    state->handler = entity1;
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = entity2;
+    return XML_ROLE_GENERAL_ENTITY_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int entity1(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = entity7;
+    return XML_ROLE_PARAM_ENTITY_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int entity2(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = entity4;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = entity3;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_ENTITY_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int entity3(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity4;
+    return XML_ROLE_ENTITY_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+
+static
+int entity4(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity5;
+    return XML_ROLE_ENTITY_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int entity5(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {
+      state->handler = entity6;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static
+int entity6(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = declClose;
+    return XML_ROLE_ENTITY_NOTATION_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int entity7(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = entity9;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = entity8;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_ENTITY_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int entity8(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity9;
+    return XML_ROLE_ENTITY_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int entity9(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_ENTITY_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int notation0(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = notation1;
+    return XML_ROLE_NOTATION_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int notation1(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = notation3;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = notation2;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static
+int notation2(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = notation4;
+    return XML_ROLE_NOTATION_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int notation3(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_NOTATION_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int notation4(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_NOTATION_SYSTEM_ID;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_NOTATION_NO_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist0(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = attlist1;
+    return XML_ROLE_ATTLIST_ELEMENT_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist1(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = attlist2;
+    return XML_ROLE_ATTRIBUTE_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist2(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    {
+      static const char *types[] = {
+       KW_CDATA,
+        KW_ID,
+        KW_IDREF,
+        KW_IDREFS,
+        KW_ENTITY,
+        KW_ENTITIES,
+        KW_NMTOKEN,
+        KW_NMTOKENS,
+      };
+      int i;
+      for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
+       if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
+         state->handler = attlist8;
+         return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
+       }
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
+      state->handler = attlist5;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_OPEN_PAREN:
+    state->handler = attlist3;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist3(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NMTOKEN:
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = attlist4;
+    return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist4(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->handler = attlist8;
+    return XML_ROLE_NONE;
+  case XML_TOK_OR:
+    state->handler = attlist3;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist5(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_PAREN:
+    state->handler = attlist6;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+
+static
+int attlist6(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = attlist7;
+    return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist7(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->handler = attlist8;
+    return XML_ROLE_NONE;
+  case XML_TOK_OR:
+    state->handler = attlist6;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+/* default value */
+static
+int attlist8(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_POUND_NAME:
+    if (XmlNameMatchesAscii(enc,
+                           ptr + MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_IMPLIED)) {
+      state->handler = attlist1;
+      return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                           ptr + MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_REQUIRED)) {
+      state->handler = attlist1;
+      return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                           ptr + MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_FIXED)) {
+      state->handler = attlist9;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_LITERAL:
+    state->handler = attlist1;
+    return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist9(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = attlist1;
+    return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int element0(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element1;
+    return XML_ROLE_ELEMENT_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int element1(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
+      state->handler = declClose;
+      return XML_ROLE_CONTENT_EMPTY;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
+      state->handler = declClose;
+      return XML_ROLE_CONTENT_ANY;
+    }
+    break;
+  case XML_TOK_OPEN_PAREN:
+    state->handler = element2;
+    state->level = 1;
+    return XML_ROLE_GROUP_OPEN;
+  }
+  return common(state, tok);
+}
+
+static
+int element2(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_POUND_NAME:
+    if (XmlNameMatchesAscii(enc,
+                           ptr + MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_PCDATA)) {
+      state->handler = element3;
+      return XML_ROLE_CONTENT_PCDATA;
+    }
+    break;
+  case XML_TOK_OPEN_PAREN:
+    state->level = 2;
+    state->handler = element6;
+    return XML_ROLE_GROUP_OPEN;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT;
+  case XML_TOK_NAME_QUESTION:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_OPT;
+  case XML_TOK_NAME_ASTERISK:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_REP;
+  case XML_TOK_NAME_PLUS:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_PLUS;
+  }
+  return common(state, tok);
+}
+
+static
+int element3(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN:
+  case XML_TOK_CLOSE_PAREN_ASTERISK:
+    state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_REP;
+  case XML_TOK_OR:
+    state->handler = element4;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int element4(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element5;
+    return XML_ROLE_CONTENT_ELEMENT;
+  }
+  return common(state, tok);
+}
+
+static
+int element5(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN_ASTERISK:
+    state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_REP;
+  case XML_TOK_OR:
+    state->handler = element4;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int element6(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_PAREN:
+    state->level += 1;
+    return XML_ROLE_GROUP_OPEN;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT;
+  case XML_TOK_NAME_QUESTION:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_OPT;
+  case XML_TOK_NAME_ASTERISK:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_REP;
+  case XML_TOK_NAME_PLUS:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_PLUS;
+  }
+  return common(state, tok);
+}
+
+static
+int element7(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->level -= 1;
+    if (state->level == 0)
+      state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE;
+  case XML_TOK_CLOSE_PAREN_ASTERISK:
+    state->level -= 1;
+    if (state->level == 0)
+      state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_REP;
+  case XML_TOK_CLOSE_PAREN_QUESTION:
+    state->level -= 1;
+    if (state->level == 0)
+      state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_OPT;
+  case XML_TOK_CLOSE_PAREN_PLUS:
+    state->level -= 1;
+    if (state->level == 0)
+      state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_PLUS;
+  case XML_TOK_COMMA:
+    state->handler = element6;
+    return XML_ROLE_GROUP_SEQUENCE;
+  case XML_TOK_OR:
+    state->handler = element6;
+    return XML_ROLE_GROUP_CHOICE;
+  }
+  return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static
+int condSect0(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) {
+      state->handler = condSect1;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) {
+      state->handler = condSect2;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static
+int condSect1(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = externalSubset1;
+    state->includeLevel += 1;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int condSect2(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = externalSubset1;
+    return XML_ROLE_IGNORE_SECT;
+  }
+  return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static
+int declClose(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+#if 0
+
+static
+int ignore(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_DECL_CLOSE:
+    state->handler = internalSubset;
+    return 0;
+  default:
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+#endif
+
+static
+int error(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  return XML_ROLE_NONE;
+}
+
+static
+int common(PROLOG_STATE *state, int tok)
+{
+#ifdef XML_DTD
+  if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
+    return XML_ROLE_INNER_PARAM_ENTITY_REF;
+#endif
+  state->handler = error;
+  return XML_ROLE_ERROR;
+}
+
+void XmlPrologStateInit(PROLOG_STATE *state)
+{
+  state->handler = prolog0;
+#ifdef XML_DTD
+  state->documentEntity = 1;
+  state->includeLevel = 0;
+#endif /* XML_DTD */
+}
+
+#ifdef XML_DTD
+
+void XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
+{
+  state->handler = externalSubset0;
+  state->documentEntity = 0;
+  state->includeLevel = 0;
+}
+
+#endif /* XML_DTD */
diff --git a/contrib/src/xrc/expat/xmltok/xmlrole.h b/contrib/src/xrc/expat/xmltok/xmlrole.h
new file mode 100644 (file)
index 0000000..22958df
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#ifndef XmlRole_INCLUDED
+#define XmlRole_INCLUDED 1
+
+#include "xmltok.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+  XML_ROLE_ERROR = -1,
+  XML_ROLE_NONE = 0,
+  XML_ROLE_XML_DECL,
+  XML_ROLE_INSTANCE_START,
+  XML_ROLE_DOCTYPE_NAME,
+  XML_ROLE_DOCTYPE_SYSTEM_ID,
+  XML_ROLE_DOCTYPE_PUBLIC_ID,
+  XML_ROLE_DOCTYPE_CLOSE,
+  XML_ROLE_GENERAL_ENTITY_NAME,
+  XML_ROLE_PARAM_ENTITY_NAME,
+  XML_ROLE_ENTITY_VALUE,
+  XML_ROLE_ENTITY_SYSTEM_ID,
+  XML_ROLE_ENTITY_PUBLIC_ID,
+  XML_ROLE_ENTITY_NOTATION_NAME,
+  XML_ROLE_NOTATION_NAME,
+  XML_ROLE_NOTATION_SYSTEM_ID,
+  XML_ROLE_NOTATION_NO_SYSTEM_ID,
+  XML_ROLE_NOTATION_PUBLIC_ID,
+  XML_ROLE_ATTRIBUTE_NAME,
+  XML_ROLE_ATTRIBUTE_TYPE_CDATA,
+  XML_ROLE_ATTRIBUTE_TYPE_ID,
+  XML_ROLE_ATTRIBUTE_TYPE_IDREF,
+  XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
+  XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
+  XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
+  XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
+  XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
+  XML_ROLE_ATTRIBUTE_ENUM_VALUE,
+  XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
+  XML_ROLE_ATTLIST_ELEMENT_NAME,
+  XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
+  XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
+  XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
+  XML_ROLE_FIXED_ATTRIBUTE_VALUE,
+  XML_ROLE_ELEMENT_NAME,
+  XML_ROLE_CONTENT_ANY,
+  XML_ROLE_CONTENT_EMPTY,
+  XML_ROLE_CONTENT_PCDATA,
+  XML_ROLE_GROUP_OPEN,
+  XML_ROLE_GROUP_CLOSE,
+  XML_ROLE_GROUP_CLOSE_REP,
+  XML_ROLE_GROUP_CLOSE_OPT,
+  XML_ROLE_GROUP_CLOSE_PLUS,
+  XML_ROLE_GROUP_CHOICE,
+  XML_ROLE_GROUP_SEQUENCE,
+  XML_ROLE_CONTENT_ELEMENT,
+  XML_ROLE_CONTENT_ELEMENT_REP,
+  XML_ROLE_CONTENT_ELEMENT_OPT,
+  XML_ROLE_CONTENT_ELEMENT_PLUS,
+#ifdef XML_DTD
+  XML_ROLE_TEXT_DECL,
+  XML_ROLE_IGNORE_SECT,
+  XML_ROLE_INNER_PARAM_ENTITY_REF,
+#endif /* XML_DTD */
+  XML_ROLE_PARAM_ENTITY_REF,
+  XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION
+};
+
+typedef struct prolog_state {
+  int (*handler)(struct prolog_state *state,
+                int tok,
+                const char *ptr,
+                const char *end,
+                const ENCODING *enc);
+  unsigned level;
+#ifdef XML_DTD
+  unsigned includeLevel;
+  int documentEntity;
+#endif /* XML_DTD */
+} PROLOG_STATE;
+
+void XMLTOKAPI XmlPrologStateInit(PROLOG_STATE *);
+#ifdef XML_DTD
+void XMLTOKAPI XmlPrologStateInitExternalEntity(PROLOG_STATE *);
+#endif /* XML_DTD */
+
+#define XmlTokenRole(state, tok, ptr, end, enc) \
+ (((state)->handler)(state, tok, ptr, end, enc))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlRole_INCLUDED */
diff --git a/contrib/src/xrc/expat/xmltok/xmltok.c b/contrib/src/xrc/expat/xmltok/xmltok.c
new file mode 100644 (file)
index 0000000..f7a5b2b
--- /dev/null
@@ -0,0 +1,1557 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#include "xmldef.h"
+#include "xmltok.h"
+#include "nametab.h"
+
+#ifdef XML_DTD
+#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
+#else
+#define IGNORE_SECTION_TOK_VTABLE /* as nothing */
+#endif
+
+#define VTABLE1 \
+  { PREFIX(prologTok), PREFIX(contentTok), \
+    PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
+  { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
+  PREFIX(sameName), \
+  PREFIX(nameMatchesAscii), \
+  PREFIX(nameLength), \
+  PREFIX(skipS), \
+  PREFIX(getAtts), \
+  PREFIX(charRefNumber), \
+  PREFIX(predefinedEntityName), \
+  PREFIX(updatePosition), \
+  PREFIX(isPublicId)
+
+#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
+
+#define UCS2_GET_NAMING(pages, hi, lo) \
+   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
+
+/* A 2 byte UTF-8 representation splits the characters 11 bits
+between the bottom 5 and 6 bits of the bytes.
+We need 8 bits to index into pages, 3 bits to add to that index and
+5 bits to generate the mask. */
+#define UTF8_GET_NAMING2(pages, byte) \
+    (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
+                      + ((((byte)[0]) & 3) << 1) \
+                      + ((((byte)[1]) >> 5) & 1)] \
+         & (1 << (((byte)[1]) & 0x1F)))
+
+/* A 3 byte UTF-8 representation splits the characters 16 bits
+between the bottom 4, 6 and 6 bits of the bytes.
+We need 8 bits to index into pages, 3 bits to add to that index and
+5 bits to generate the mask. */
+#define UTF8_GET_NAMING3(pages, byte) \
+  (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
+                             + ((((byte)[1]) >> 2) & 0xF)] \
+                      << 3) \
+                      + ((((byte)[1]) & 3) << 1) \
+                      + ((((byte)[2]) >> 5) & 1)] \
+         & (1 << (((byte)[2]) & 0x1F)))
+
+#define UTF8_GET_NAMING(pages, p, n) \
+  ((n) == 2 \
+  ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
+  : ((n) == 3 \
+     ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
+     : 0))
+
+#define UTF8_INVALID3(p) \
+  ((*p) == 0xED \
+  ? (((p)[1] & 0x20) != 0) \
+  : ((*p) == 0xEF \
+     ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \
+     : 0))
+
+#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0)
+
+static
+int isNever(const ENCODING *enc, const char *p)
+{
+  return 0;
+}
+
+static
+int utf8_isName2(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
+}
+
+static
+int utf8_isName3(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
+}
+
+#define utf8_isName4 isNever
+
+static
+int utf8_isNmstrt2(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
+}
+
+static
+int utf8_isNmstrt3(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
+}
+
+#define utf8_isNmstrt4 isNever
+
+#define utf8_isInvalid2 isNever
+
+static
+int utf8_isInvalid3(const ENCODING *enc, const char *p)
+{
+  return UTF8_INVALID3((const unsigned char *)p);
+}
+
+static
+int utf8_isInvalid4(const ENCODING *enc, const char *p)
+{
+  return UTF8_INVALID4((const unsigned char *)p);
+}
+
+struct normal_encoding {
+  ENCODING enc;
+  unsigned char type[256];
+#ifdef XML_MIN_SIZE
+  int (*byteType)(const ENCODING *, const char *);
+  int (*isNameMin)(const ENCODING *, const char *);
+  int (*isNmstrtMin)(const ENCODING *, const char *);
+  int (*byteToAscii)(const ENCODING *, const char *);
+  int (*charMatches)(const ENCODING *, const char *, int);
+#endif /* XML_MIN_SIZE */
+  int (*isName2)(const ENCODING *, const char *);
+  int (*isName3)(const ENCODING *, const char *);
+  int (*isName4)(const ENCODING *, const char *);
+  int (*isNmstrt2)(const ENCODING *, const char *);
+  int (*isNmstrt3)(const ENCODING *, const char *);
+  int (*isNmstrt4)(const ENCODING *, const char *);
+  int (*isInvalid2)(const ENCODING *, const char *);
+  int (*isInvalid3)(const ENCODING *, const char *);
+  int (*isInvalid4)(const ENCODING *, const char *);
+};
+
+#ifdef XML_MIN_SIZE
+
+#define STANDARD_VTABLE(E) \
+ E ## byteType, \
+ E ## isNameMin, \
+ E ## isNmstrtMin, \
+ E ## byteToAscii, \
+ E ## charMatches,
+
+#else
+
+#define STANDARD_VTABLE(E) /* as nothing */
+
+#endif
+
+#define NORMAL_VTABLE(E) \
+ E ## isName2, \
+ E ## isName3, \
+ E ## isName4, \
+ E ## isNmstrt2, \
+ E ## isNmstrt3, \
+ E ## isNmstrt4, \
+ E ## isInvalid2, \
+ E ## isInvalid3, \
+ E ## isInvalid4
+
+static int checkCharRefNumber(int);
+
+#include "xmltok_impl.h"
+#include "ascii.h"
+
+#ifdef XML_MIN_SIZE
+#define sb_isNameMin isNever
+#define sb_isNmstrtMin isNever
+#endif
+
+#ifdef XML_MIN_SIZE
+#define MINBPC(enc) ((enc)->minBytesPerChar)
+#else
+/* minimum bytes per character */
+#define MINBPC(enc) 1
+#endif
+
+#define SB_BYTE_TYPE(enc, p) \
+  (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
+
+#ifdef XML_MIN_SIZE
+static
+int sb_byteType(const ENCODING *enc, const char *p)
+{
+  return SB_BYTE_TYPE(enc, p);
+}
+#define BYTE_TYPE(enc, p) \
+ (((const struct normal_encoding *)(enc))->byteType(enc, p))
+#else
+#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define BYTE_TO_ASCII(enc, p) \
+ (((const struct normal_encoding *)(enc))->byteToAscii(enc, p))
+static
+int sb_byteToAscii(const ENCODING *enc, const char *p)
+{
+  return *p;
+}
+#else
+#define BYTE_TO_ASCII(enc, p) (*(p))
+#endif
+
+#define IS_NAME_CHAR(enc, p, n) \
+ (((const struct normal_encoding *)(enc))->isName ## n(enc, p))
+#define IS_NMSTRT_CHAR(enc, p, n) \
+ (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p))
+#define IS_INVALID_CHAR(enc, p, n) \
+ (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p))
+
+#ifdef XML_MIN_SIZE
+#define IS_NAME_CHAR_MINBPC(enc, p) \
+ (((const struct normal_encoding *)(enc))->isNameMin(enc, p))
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ (((const struct normal_encoding *)(enc))->isNmstrtMin(enc, p))
+#else
+#define IS_NAME_CHAR_MINBPC(enc, p) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define CHAR_MATCHES(enc, p, c) \
+ (((const struct normal_encoding *)(enc))->charMatches(enc, p, c))
+static
+int sb_charMatches(const ENCODING *enc, const char *p, int c)
+{
+  return *p == c;
+}
+#else
+/* c is an ASCII character */
+#define CHAR_MATCHES(enc, p, c) (*(p) == c)
+#endif
+
+#define PREFIX(ident) normal_ ## ident
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+enum {  /* UTF8_cvalN is value of masked first byte of N byte sequence */
+  UTF8_cval1 = 0x00,
+  UTF8_cval2 = 0xc0,
+  UTF8_cval3 = 0xe0,
+  UTF8_cval4 = 0xf0
+};
+
+static
+void utf8_toUtf8(const ENCODING *enc,
+                const char **fromP, const char *fromLim,
+                char **toP, const char *toLim)
+{
+  char *to;
+  const char *from;
+  if (fromLim - *fromP > toLim - *toP) {
+    /* Avoid copying partial characters. */
+    for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
+      if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
+       break;
+  }
+  for (to = *toP, from = *fromP; from != fromLim; from++, to++)
+    *to = *from;
+  *fromP = from;
+  *toP = to;
+}
+
+static
+void utf8_toUtf16(const ENCODING *enc,
+                 const char **fromP, const char *fromLim,
+                 unsigned short **toP, const unsigned short *toLim)
+{
+  unsigned short *to = *toP;
+  const char *from = *fromP;
+  while (from != fromLim && to != toLim) {
+    switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
+    case BT_LEAD2:
+      *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f);
+      from += 2;
+      break;
+    case BT_LEAD3:
+      *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f);
+      from += 3;
+      break;
+    case BT_LEAD4:
+      {
+       unsigned long n;
+       if (to + 1 == toLim)
+         break;
+       n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
+       n -= 0x10000;
+       to[0] = (unsigned short)((n >> 10) | 0xD800);
+       to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
+       to += 2;
+       from += 4;
+      }
+      break;
+    default:
+      *to++ = *from++;
+      break;
+    }
+  }
+  *fromP = from;
+  *toP = to;
+}
+
+#ifdef XML_NS
+static const struct normal_encoding utf8_encoding_ns = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#include "asciitab.h"
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+#endif
+
+static const struct normal_encoding utf8_encoding = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_utf8_encoding_ns = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#include "iasciitab.h"
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#endif
+
+static const struct normal_encoding internal_utf8_encoding = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+static
+void latin1_toUtf8(const ENCODING *enc,
+                  const char **fromP, const char *fromLim,
+                  char **toP, const char *toLim)
+{
+  for (;;) {
+    unsigned char c;
+    if (*fromP == fromLim)
+      break;
+    c = (unsigned char)**fromP;
+    if (c & 0x80) {
+      if (toLim - *toP < 2)
+       break;
+      *(*toP)++ = ((c >> 6) | UTF8_cval2);
+      *(*toP)++ = ((c & 0x3f) | 0x80);
+      (*fromP)++;
+    }
+    else {
+      if (*toP == toLim)
+       break;
+      *(*toP)++ = *(*fromP)++;
+    }
+  }
+}
+
+static
+void latin1_toUtf16(const ENCODING *enc,
+                   const char **fromP, const char *fromLim,
+                   unsigned short **toP, const unsigned short *toLim)
+{
+  while (*fromP != fromLim && *toP != toLim)
+    *(*toP)++ = (unsigned char)*(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding latin1_encoding_ns = {
+  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+  {
+#include "asciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding latin1_encoding = {
+  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+static
+void ascii_toUtf8(const ENCODING *enc,
+                 const char **fromP, const char *fromLim,
+                 char **toP, const char *toLim)
+{
+  while (*fromP != fromLim && *toP != toLim)
+    *(*toP)++ = *(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding ascii_encoding_ns = {
+  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+  {
+#include "asciitab.h"
+/* BT_NONXML == 0 */
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding ascii_encoding = {
+  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+/* BT_NONXML == 0 */
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+static int unicode_byte_type(char hi, char lo)
+{
+  switch ((unsigned char)hi) {
+  case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+    return BT_LEAD4;
+  case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+    return BT_TRAIL;
+  case 0xFF:
+    switch ((unsigned char)lo) {
+    case 0xFF:
+    case 0xFE:
+      return BT_NONXML;
+    }
+    break;
+  }
+  return BT_NONASCII;
+}
+
+#define DEFINE_UTF16_TO_UTF8(E) \
+static \
+void E ## toUtf8(const ENCODING *enc, \
+                const char **fromP, const char *fromLim, \
+                char **toP, const char *toLim) \
+{ \
+  const char *from; \
+  for (from = *fromP; from != fromLim; from += 2) { \
+    int plane; \
+    unsigned char lo2; \
+    unsigned char lo = GET_LO(from); \
+    unsigned char hi = GET_HI(from); \
+    switch (hi) { \
+    case 0: \
+      if (lo < 0x80) { \
+        if (*toP == toLim) { \
+          *fromP = from; \
+         return; \
+        } \
+        *(*toP)++ = lo; \
+        break; \
+      } \
+      /* fall through */ \
+    case 0x1: case 0x2: case 0x3: \
+    case 0x4: case 0x5: case 0x6: case 0x7: \
+      if (toLim -  *toP < 2) { \
+        *fromP = from; \
+       return; \
+      } \
+      *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \
+      *(*toP)++ = ((lo & 0x3f) | 0x80); \
+      break; \
+    default: \
+      if (toLim -  *toP < 3)  { \
+        *fromP = from; \
+       return; \
+      } \
+      /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
+      *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
+      *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
+      *(*toP)++ = ((lo & 0x3f) | 0x80); \
+      break; \
+    case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
+      if (toLim -  *toP < 4) { \
+       *fromP = from; \
+       return; \
+      } \
+      plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
+      *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
+      *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
+      from += 2; \
+      lo2 = GET_LO(from); \
+      *(*toP)++ = (((lo & 0x3) << 4) \
+                  | ((GET_HI(from) & 0x3) << 2) \
+                  | (lo2 >> 6) \
+                  | 0x80); \
+      *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
+      break; \
+    } \
+  } \
+  *fromP = from; \
+}
+
+#define DEFINE_UTF16_TO_UTF16(E) \
+static \
+void E ## toUtf16(const ENCODING *enc, \
+                 const char **fromP, const char *fromLim, \
+                 unsigned short **toP, const unsigned short *toLim) \
+{ \
+  /* Avoid copying first half only of surrogate */ \
+  if (fromLim - *fromP > ((toLim - *toP) << 1) \
+      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
+    fromLim -= 2; \
+  for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
+    *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
+}
+
+#define SET2(ptr, ch) \
+  (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[0])
+#define GET_HI(ptr) ((unsigned char)(ptr)[1])
+
+DEFINE_UTF16_TO_UTF8(little2_)
+DEFINE_UTF16_TO_UTF16(little2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define SET2(ptr, ch) \
+  (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[1])
+#define GET_HI(ptr) ((unsigned char)(ptr)[0])
+
+DEFINE_UTF16_TO_UTF8(big2_)
+DEFINE_UTF16_TO_UTF16(big2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define LITTLE2_BYTE_TYPE(enc, p) \
+ ((p)[1] == 0 \
+  ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
+  : unicode_byte_type((p)[1], (p)[0]))
+#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
+#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
+#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
+#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
+
+#ifdef XML_MIN_SIZE
+
+static
+int little2_byteType(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_BYTE_TYPE(enc, p);
+}
+
+static
+int little2_byteToAscii(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_BYTE_TO_ASCII(enc, p);
+}
+
+static
+int little2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+  return LITTLE2_CHAR_MATCHES(enc, p, c);
+}
+
+static
+int little2_isNameMin(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static
+int little2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) little2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) 
+#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding little2_encoding_ns = { 
+  { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 12
+    1
+#else
+    0
+#endif
+  },
+  {
+#include "asciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding little2_encoding = { 
+  { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 12
+    1
+#else
+    0
+#endif
+  },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#if XML_BYTE_ORDER != 21
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_little2_encoding_ns = { 
+  { VTABLE, 2, 0, 1 },
+  {
+#include "iasciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_little2_encoding = { 
+  { VTABLE, 2, 0, 1 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+
+#define BIG2_BYTE_TYPE(enc, p) \
+ ((p)[0] == 0 \
+  ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
+  : unicode_byte_type((p)[0], (p)[1]))
+#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
+#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
+#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
+#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
+
+#ifdef XML_MIN_SIZE
+
+static
+int big2_byteType(const ENCODING *enc, const char *p)
+{
+  return BIG2_BYTE_TYPE(enc, p);
+}
+
+static
+int big2_byteToAscii(const ENCODING *enc, const char *p)
+{
+  return BIG2_BYTE_TO_ASCII(enc, p);
+}
+
+static
+int big2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+  return BIG2_CHAR_MATCHES(enc, p, c);
+}
+
+static
+int big2_isNameMin(const ENCODING *enc, const char *p)
+{
+  return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static
+int big2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+  return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) big2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) 
+#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding big2_encoding_ns = {
+  { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 21
+  1
+#else
+  0
+#endif
+  },
+  {
+#include "asciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding big2_encoding = {
+  { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 21
+  1
+#else
+  0
+#endif
+  },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#if XML_BYTE_ORDER != 12
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_big2_encoding_ns = {
+  { VTABLE, 2, 0, 1 },
+  {
+#include "iasciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_big2_encoding = {
+  { VTABLE, 2, 0, 1 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+#undef PREFIX
+
+static
+int streqci(const char *s1, const char *s2)
+{
+  for (;;) {
+    char c1 = *s1++;
+    char c2 = *s2++;
+    if (ASCII_a <= c1 && c1 <= ASCII_z)
+      c1 += ASCII_A - ASCII_a;
+    if (ASCII_a <= c2 && c2 <= ASCII_z)
+      c2 += ASCII_A - ASCII_a;
+    if (c1 != c2)
+      return 0;
+    if (!c1)
+      break;
+  }
+  return 1;
+}
+
+static
+void initUpdatePosition(const ENCODING *enc, const char *ptr,
+                       const char *end, POSITION *pos)
+{
+  normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
+}
+
+static
+int toAscii(const ENCODING *enc, const char *ptr, const char *end)
+{
+  char buf[1];
+  char *p = buf;
+  XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
+  if (p == buf)
+    return -1;
+  else
+    return buf[0];
+}
+
+static
+int isSpace(int c)
+{
+  switch (c) {
+  case 0x20:
+  case 0xD:
+  case 0xA:
+  case 0x9:    
+    return 1;
+  }
+  return 0;
+}
+
+/* Return 1 if there's just optional white space
+or there's an S followed by name=val. */
+static
+int parsePseudoAttribute(const ENCODING *enc,
+                        const char *ptr,
+                        const char *end,
+                        const char **namePtr,
+                        const char **nameEndPtr,
+                        const char **valPtr,
+                        const char **nextTokPtr)
+{
+  int c;
+  char open;
+  if (ptr == end) {
+    *namePtr = 0;
+    return 1;
+  }
+  if (!isSpace(toAscii(enc, ptr, end))) {
+    *nextTokPtr = ptr;
+    return 0;
+  }
+  do {
+    ptr += enc->minBytesPerChar;
+  } while (isSpace(toAscii(enc, ptr, end)));
+  if (ptr == end) {
+    *namePtr = 0;
+    return 1;
+  }
+  *namePtr = ptr;
+  for (;;) {
+    c = toAscii(enc, ptr, end);
+    if (c == -1) {
+      *nextTokPtr = ptr;
+      return 0;
+    }
+    if (c == ASCII_EQUALS) {
+      *nameEndPtr = ptr;
+      break;
+    }
+    if (isSpace(c)) {
+      *nameEndPtr = ptr;
+      do {
+       ptr += enc->minBytesPerChar;
+      } while (isSpace(c = toAscii(enc, ptr, end)));
+      if (c != ASCII_EQUALS) {
+       *nextTokPtr = ptr;
+       return 0;
+      }
+      break;
+    }
+    ptr += enc->minBytesPerChar;
+  }
+  if (ptr == *namePtr) {
+    *nextTokPtr = ptr;
+    return 0;
+  }
+  ptr += enc->minBytesPerChar;
+  c = toAscii(enc, ptr, end);
+  while (isSpace(c)) {
+    ptr += enc->minBytesPerChar;
+    c = toAscii(enc, ptr, end);
+  }
+  if (c != ASCII_QUOT && c != ASCII_APOS) {
+    *nextTokPtr = ptr;
+    return 0;
+  }
+  open = c;
+  ptr += enc->minBytesPerChar;
+  *valPtr = ptr;
+  for (;; ptr += enc->minBytesPerChar) {
+    c = toAscii(enc, ptr, end);
+    if (c == open)
+      break;
+    if (!(ASCII_a <= c && c <= ASCII_z)
+       && !(ASCII_A <= c && c <= ASCII_Z)
+       && !(ASCII_0 <= c && c <= ASCII_9)
+       && c != ASCII_PERIOD
+       && c != ASCII_MINUS
+       && c != ASCII_UNDERSCORE) {
+      *nextTokPtr = ptr;
+      return 0;
+    }
+  }
+  *nextTokPtr = ptr + enc->minBytesPerChar;
+  return 1;
+}
+
+static const char KW_version[] = {
+  ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'
+};
+
+static const char KW_encoding[] = {
+  ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'
+};
+
+static const char KW_standalone[] = {
+  ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'
+};
+
+static const char KW_yes[] = {
+  ASCII_y, ASCII_e, ASCII_s,  '\0'
+};
+
+static const char KW_no[] = {
+  ASCII_n, ASCII_o,  '\0'
+};
+
+static
+int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
+                                                    const char *,
+                                                    const char *),
+                  int isGeneralTextEntity,
+                  const ENCODING *enc,
+                  const char *ptr,
+                  const char *end,
+                  const char **badPtr,
+                  const char **versionPtr,
+                  const char **encodingName,
+                  const ENCODING **encoding,
+                  int *standalone)
+{
+  const char *val = 0;
+  const char *name = 0;
+  const char *nameEnd = 0;
+  ptr += 5 * enc->minBytesPerChar;
+  end -= 2 * enc->minBytesPerChar;
+  if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) || !name) {
+    *badPtr = ptr;
+    return 0;
+  }
+  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
+    if (!isGeneralTextEntity) {
+      *badPtr = name;
+      return 0;
+    }
+  }
+  else {
+    if (versionPtr)
+      *versionPtr = val;
+    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+      *badPtr = ptr;
+      return 0;
+    }
+    if (!name) {
+      if (isGeneralTextEntity) {
+       /* a TextDecl must have an EncodingDecl */
+       *badPtr = ptr;
+       return 0;
+      }
+      return 1;
+    }
+  }
+  if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
+    int c = toAscii(enc, val, end);
+    if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {
+      *badPtr = val;
+      return 0;
+    }
+    if (encodingName)
+      *encodingName = val;
+    if (encoding)
+      *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
+    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+      *badPtr = ptr;
+      return 0;
+    }
+    if (!name)
+      return 1;
+  }
+  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) || isGeneralTextEntity) {
+    *badPtr = name;
+    return 0;
+  }
+  if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
+    if (standalone)
+      *standalone = 1;
+  }
+  else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
+    if (standalone)
+      *standalone = 0;
+  }
+  else {
+    *badPtr = val;
+    return 0;
+  }
+  while (isSpace(toAscii(enc, ptr, end)))
+    ptr += enc->minBytesPerChar;
+  if (ptr != end) {
+    *badPtr = ptr;
+    return 0;
+  }
+  return 1;
+}
+
+static
+int checkCharRefNumber(int result)
+{
+  switch (result >> 8) {
+  case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+  case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+    return -1;
+  case 0:
+    if (latin1_encoding.type[result] == BT_NONXML)
+      return -1;
+    break;
+  case 0xFF:
+    if (result == 0xFFFE || result == 0xFFFF)
+      return -1;
+    break;
+  }
+  return result;
+}
+
+int XmlUtf8Encode(int c, char *buf)
+{
+  enum {
+    /* minN is minimum legal resulting value for N byte sequence */
+    min2 = 0x80,
+    min3 = 0x800,
+    min4 = 0x10000
+  };
+
+  if (c < 0)
+    return 0;
+  if (c < min2) {
+    buf[0] = (c | UTF8_cval1);
+    return 1;
+  }
+  if (c < min3) {
+    buf[0] = ((c >> 6) | UTF8_cval2);
+    buf[1] = ((c & 0x3f) | 0x80);
+    return 2;
+  }
+  if (c < min4) {
+    buf[0] = ((c >> 12) | UTF8_cval3);
+    buf[1] = (((c >> 6) & 0x3f) | 0x80);
+    buf[2] = ((c & 0x3f) | 0x80);
+    return 3;
+  }
+  if (c < 0x110000) {
+    buf[0] = ((c >> 18) | UTF8_cval4);
+    buf[1] = (((c >> 12) & 0x3f) | 0x80);
+    buf[2] = (((c >> 6) & 0x3f) | 0x80);
+    buf[3] = ((c & 0x3f) | 0x80);
+    return 4;
+  }
+  return 0;
+}
+
+int XmlUtf16Encode(int charNum, unsigned short *buf)
+{
+  if (charNum < 0)
+    return 0;
+  if (charNum < 0x10000) {
+    buf[0] = charNum;
+    return 1;
+  }
+  if (charNum < 0x110000) {
+    charNum -= 0x10000;
+    buf[0] = (charNum >> 10) + 0xD800;
+    buf[1] = (charNum & 0x3FF) + 0xDC00;
+    return 2;
+  }
+  return 0;
+}
+
+struct unknown_encoding {
+  struct normal_encoding normal;
+  int (*convert)(void *userData, const char *p);
+  void *userData;
+  unsigned short utf16[256];
+  char utf8[256][4];
+};
+
+int XmlSizeOfUnknownEncoding(void)
+{
+  return sizeof(struct unknown_encoding);
+}
+
+static
+int unknown_isName(const ENCODING *enc, const char *p)
+{
+  int c = ((const struct unknown_encoding *)enc)
+         ->convert(((const struct unknown_encoding *)enc)->userData, p);
+  if (c & ~0xFFFF)
+    return 0;
+  return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
+}
+
+static
+int unknown_isNmstrt(const ENCODING *enc, const char *p)
+{
+  int c = ((const struct unknown_encoding *)enc)
+         ->convert(((const struct unknown_encoding *)enc)->userData, p);
+  if (c & ~0xFFFF)
+    return 0;
+  return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
+}
+
+static
+int unknown_isInvalid(const ENCODING *enc, const char *p)
+{
+  int c = ((const struct unknown_encoding *)enc)
+          ->convert(((const struct unknown_encoding *)enc)->userData, p);
+  return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
+}
+
+static
+void unknown_toUtf8(const ENCODING *enc,
+                   const char **fromP, const char *fromLim,
+                   char **toP, const char *toLim)
+{
+  char buf[XML_UTF8_ENCODE_MAX];
+  for (;;) {
+    const char *utf8;
+    int n;
+    if (*fromP == fromLim)
+      break;
+    utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP];
+    n = *utf8++;
+    if (n == 0) {
+      int c = ((const struct unknown_encoding *)enc)
+             ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
+      n = XmlUtf8Encode(c, buf);
+      if (n > toLim - *toP)
+       break;
+      utf8 = buf;
+      *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
+                - (BT_LEAD2 - 2);
+    }
+    else {
+      if (n > toLim - *toP)
+       break;
+      (*fromP)++;
+    }
+    do {
+      *(*toP)++ = *utf8++;
+    } while (--n != 0);
+  }
+}
+
+static
+void unknown_toUtf16(const ENCODING *enc,
+                    const char **fromP, const char *fromLim,
+                    unsigned short **toP, const unsigned short *toLim)
+{
+  while (*fromP != fromLim && *toP != toLim) {
+    unsigned short c
+      = ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP];
+    if (c == 0) {
+      c = (unsigned short)((const struct unknown_encoding *)enc)
+          ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
+      *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
+                - (BT_LEAD2 - 2);
+    }
+    else
+      (*fromP)++;
+    *(*toP)++ = c;
+  }
+}
+
+ENCODING *
+XmlInitUnknownEncoding(void *mem,
+                      int *table,
+                      int (*convert)(void *userData, const char *p),
+                      void *userData)
+{
+  int i;
+  struct unknown_encoding *e = mem;
+  for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
+    ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
+  for (i = 0; i < 128; i++)
+    if (latin1_encoding.type[i] != BT_OTHER
+        && latin1_encoding.type[i] != BT_NONXML
+       && table[i] != i)
+      return 0;
+  for (i = 0; i < 256; i++) {
+    int c = table[i];
+    if (c == -1) {
+      e->normal.type[i] = BT_MALFORM;
+      /* This shouldn't really get used. */
+      e->utf16[i] = 0xFFFF;
+      e->utf8[i][0] = 1;
+      e->utf8[i][1] = 0;
+    }
+    else if (c < 0) {
+      if (c < -4)
+       return 0;
+      e->normal.type[i] = BT_LEAD2 - (c + 2);
+      e->utf8[i][0] = 0;
+      e->utf16[i] = 0;
+    }
+    else if (c < 0x80) {
+      if (latin1_encoding.type[c] != BT_OTHER
+         && latin1_encoding.type[c] != BT_NONXML
+         && c != i)
+       return 0;
+      e->normal.type[i] = latin1_encoding.type[c];
+      e->utf8[i][0] = 1;
+      e->utf8[i][1] = (char)c;
+      e->utf16[i] = c == 0 ? 0xFFFF : c;
+    }
+    else if (checkCharRefNumber(c) < 0) {
+      e->normal.type[i] = BT_NONXML;
+      /* This shouldn't really get used. */
+      e->utf16[i] = 0xFFFF;
+      e->utf8[i][0] = 1;
+      e->utf8[i][1] = 0;
+    }
+    else {
+      if (c > 0xFFFF)
+       return 0;
+      if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
+       e->normal.type[i] = BT_NMSTRT;
+      else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
+       e->normal.type[i] = BT_NAME;
+      else
+       e->normal.type[i] = BT_OTHER;
+      e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
+      e->utf16[i] = c;
+    }
+  }
+  e->userData = userData;
+  e->convert = convert;
+  if (convert) {
+    e->normal.isName2 = unknown_isName;
+    e->normal.isName3 = unknown_isName;
+    e->normal.isName4 = unknown_isName;
+    e->normal.isNmstrt2 = unknown_isNmstrt;
+    e->normal.isNmstrt3 = unknown_isNmstrt;
+    e->normal.isNmstrt4 = unknown_isNmstrt;
+    e->normal.isInvalid2 = unknown_isInvalid;
+    e->normal.isInvalid3 = unknown_isInvalid;
+    e->normal.isInvalid4 = unknown_isInvalid;
+  }
+  e->normal.enc.utf8Convert = unknown_toUtf8;
+  e->normal.enc.utf16Convert = unknown_toUtf16;
+  return &(e->normal.enc);
+}
+
+/* If this enumeration is changed, getEncodingIndex and encodings
+must also be changed. */
+enum {
+  UNKNOWN_ENC = -1,
+  ISO_8859_1_ENC = 0,
+  US_ASCII_ENC,
+  UTF_8_ENC,
+  UTF_16_ENC,
+  UTF_16BE_ENC,
+  UTF_16LE_ENC,
+  /* must match encodingNames up to here */
+  NO_ENC
+};
+
+static const char KW_ISO_8859_1[] = {
+  ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'
+};
+static const char KW_US_ASCII[] = {
+  ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, '\0'
+};
+static const char KW_UTF_8[] = {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'
+};
+static const char KW_UTF_16[] =        {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'
+};
+static const char KW_UTF_16BE[] = {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, '\0'
+};
+static const char KW_UTF_16LE[] = {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, '\0'
+};
+
+static
+int getEncodingIndex(const char *name)
+{
+  static const char *encodingNames[] = {
+    KW_ISO_8859_1,
+    KW_US_ASCII,
+    KW_UTF_8,
+    KW_UTF_16,
+    KW_UTF_16BE,
+    KW_UTF_16LE,
+  };
+  int i;
+  if (name == 0)
+    return NO_ENC;
+  for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
+    if (streqci(name, encodingNames[i]))
+      return i;
+  return UNKNOWN_ENC;
+}
+
+/* For binary compatibility, we store the index of the encoding specified
+at initialization in the isUtf16 member. */
+
+#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
+#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
+
+/* This is what detects the encoding.
+encodingTable maps from encoding indices to encodings;
+INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding;
+state is XML_CONTENT_STATE if we're parsing an external text entity,
+and XML_PROLOG_STATE otherwise.
+*/
+
+
+static
+int initScan(const ENCODING **encodingTable,
+            const INIT_ENCODING *enc,
+            int state,
+            const char *ptr,
+            const char *end,
+            const char **nextTokPtr)
+{
+  const ENCODING **encPtr;
+
+  if (ptr == end)
+    return XML_TOK_NONE;
+  encPtr = enc->encPtr;
+  if (ptr + 1 == end) {
+    /* only a single byte available for auto-detection */
+#ifndef XML_DTD /* FIXME */
+    /* a well-formed document entity must have more than one byte */
+    if (state != XML_CONTENT_STATE)
+      return XML_TOK_PARTIAL;
+#endif
+    /* so we're parsing an external text entity... */
+    /* if UTF-16 was externally specified, then we need at least 2 bytes */
+    switch (INIT_ENC_INDEX(enc)) {
+    case UTF_16_ENC:
+    case UTF_16LE_ENC:
+    case UTF_16BE_ENC:
+      return XML_TOK_PARTIAL;
+    }
+    switch ((unsigned char)*ptr) {
+    case 0xFE:
+    case 0xFF:
+    case 0xEF: /* possibly first byte of UTF-8 BOM */
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+         && state == XML_CONTENT_STATE)
+       break;
+      /* fall through */
+    case 0x00:
+    case 0x3C:
+      return XML_TOK_PARTIAL;
+    }
+  }
+  else {
+    switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
+    case 0xFEFF:
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+         && state == XML_CONTENT_STATE)
+       break;
+      *nextTokPtr = ptr + 2;
+      *encPtr = encodingTable[UTF_16BE_ENC];
+      return XML_TOK_BOM;
+    /* 00 3C is handled in the default case */
+    case 0x3C00:
+      if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
+          || INIT_ENC_INDEX(enc) == UTF_16_ENC)
+         && state == XML_CONTENT_STATE)
+       break;
+      *encPtr = encodingTable[UTF_16LE_ENC];
+      return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+    case 0xFFFE:
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+         && state == XML_CONTENT_STATE)
+       break;
+      *nextTokPtr = ptr + 2;
+      *encPtr = encodingTable[UTF_16LE_ENC];
+      return XML_TOK_BOM;
+    case 0xEFBB:
+      /* Maybe a UTF-8 BOM (EF BB BF) */
+      /* If there's an explicitly specified (external) encoding
+         of ISO-8859-1 or some flavour of UTF-16
+         and this is an external text entity,
+        don't look for the BOM,
+         because it might be a legal data. */
+      if (state == XML_CONTENT_STATE) {
+       int e = INIT_ENC_INDEX(enc);
+       if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC)
+         break;
+      }
+      if (ptr + 2 == end)
+       return XML_TOK_PARTIAL;
+      if ((unsigned char)ptr[2] == 0xBF) {
+       *encPtr = encodingTable[UTF_8_ENC];
+       return XML_TOK_BOM;
+      }
+      break;
+    default:
+      if (ptr[0] == '\0') {
+       /* 0 isn't a legal data character. Furthermore a document entity can only
+          start with ASCII characters.  So the only way this can fail to be big-endian
+          UTF-16 if it it's an external parsed general entity that's labelled as
+          UTF-16LE. */
+       if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
+         break;
+       *encPtr = encodingTable[UTF_16BE_ENC];
+       return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+      }
+      else if (ptr[1] == '\0') {
+       /* We could recover here in the case:
+           - parsing an external entity
+           - second byte is 0
+           - no externally specified encoding
+           - no encoding declaration
+          by assuming UTF-16LE.  But we don't, because this would mean when
+          presented just with a single byte, we couldn't reliably determine
+          whether we needed further bytes. */
+       if (state == XML_CONTENT_STATE)
+         break;
+       *encPtr = encodingTable[UTF_16LE_ENC];
+       return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+      }
+      break;
+    }
+  }
+  *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
+  return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+}
+
+
+#define NS(x) x
+#define ns(x) x
+#include "xmltok_ns.c"
+#undef NS
+#undef ns
+
+#ifdef XML_NS
+
+#define NS(x) x ## NS
+#define ns(x) x ## _ns
+
+#include "xmltok_ns.c"
+
+#undef NS
+#undef ns
+
+ENCODING *
+XmlInitUnknownEncodingNS(void *mem,
+                        int *table,
+                        int (*convert)(void *userData, const char *p),
+                        void *userData)
+{
+  ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
+  if (enc)
+    ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
+  return enc;
+}
+
+#endif /* XML_NS */
diff --git a/contrib/src/xrc/expat/xmltok/xmltok.h b/contrib/src/xrc/expat/xmltok/xmltok.h
new file mode 100644 (file)
index 0000000..f7703ce
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#ifndef XmlTok_INCLUDED
+#define XmlTok_INCLUDED 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef XMLTOKAPI
+#define XMLTOKAPI /* as nothing */
+#endif
+
+/* The following token may be returned by XmlContentTok */
+#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of
+                                    illegal ]]> sequence */
+/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
+#define XML_TOK_NONE -4    /* The string to be scanned is empty */
+#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
+                                  might be part of CRLF sequence */ 
+#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
+#define XML_TOK_PARTIAL -1 /* only part of a token */
+#define XML_TOK_INVALID 0
+
+/* The following tokens are returned by XmlContentTok; some are also
+  returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */
+
+#define XML_TOK_START_TAG_WITH_ATTS 1
+#define XML_TOK_START_TAG_NO_ATTS 2
+#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
+#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
+#define XML_TOK_END_TAG 5
+#define XML_TOK_DATA_CHARS 6
+#define XML_TOK_DATA_NEWLINE 7
+#define XML_TOK_CDATA_SECT_OPEN 8
+#define XML_TOK_ENTITY_REF 9
+#define XML_TOK_CHAR_REF 10     /* numeric character reference */
+
+/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
+#define XML_TOK_PI 11      /* processing instruction */
+#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
+#define XML_TOK_COMMENT 13
+#define XML_TOK_BOM 14     /* Byte order mark */
+
+/* The following tokens are returned only by XmlPrologTok */
+#define XML_TOK_PROLOG_S 15
+#define XML_TOK_DECL_OPEN 16 /* <!foo */
+#define XML_TOK_DECL_CLOSE 17 /* > */
+#define XML_TOK_NAME 18
+#define XML_TOK_NMTOKEN 19
+#define XML_TOK_POUND_NAME 20 /* #name */
+#define XML_TOK_OR 21 /* | */
+#define XML_TOK_PERCENT 22
+#define XML_TOK_OPEN_PAREN 23
+#define XML_TOK_CLOSE_PAREN 24
+#define XML_TOK_OPEN_BRACKET 25
+#define XML_TOK_CLOSE_BRACKET 26
+#define XML_TOK_LITERAL 27
+#define XML_TOK_PARAM_ENTITY_REF 28
+#define XML_TOK_INSTANCE_START 29
+
+/* The following occur only in element type declarations */
+#define XML_TOK_NAME_QUESTION 30 /* name? */
+#define XML_TOK_NAME_ASTERISK 31 /* name* */
+#define XML_TOK_NAME_PLUS 32 /* name+ */
+#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
+#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
+#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
+#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
+#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
+#define XML_TOK_COMMA 38
+
+/* The following token is returned only by XmlAttributeValueTok */
+#define XML_TOK_ATTRIBUTE_VALUE_S 39
+
+/* The following token is returned only by XmlCdataSectionTok */
+#define XML_TOK_CDATA_SECT_CLOSE 40
+
+/* With namespace processing this is returned by XmlPrologTok
+   for a name with a colon. */
+#define XML_TOK_PREFIXED_NAME 41
+
+#ifdef XML_DTD
+#define XML_TOK_IGNORE_SECT 42
+#endif /* XML_DTD */
+
+#ifdef XML_DTD
+#define XML_N_STATES 4
+#else /* not XML_DTD */
+#define XML_N_STATES 3
+#endif /* not XML_DTD */
+
+#define XML_PROLOG_STATE 0
+#define XML_CONTENT_STATE 1
+#define XML_CDATA_SECTION_STATE 2
+#ifdef XML_DTD
+#define XML_IGNORE_SECTION_STATE 3
+#endif /* XML_DTD */
+
+#define XML_N_LITERAL_TYPES 2
+#define XML_ATTRIBUTE_VALUE_LITERAL 0
+#define XML_ENTITY_VALUE_LITERAL 1
+
+/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
+#define XML_UTF8_ENCODE_MAX 4
+/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
+#define XML_UTF16_ENCODE_MAX 2
+
+typedef struct position {
+  /* first line and first column are 0 not 1 */
+  unsigned long lineNumber;
+  unsigned long columnNumber;
+} POSITION;
+
+typedef struct {
+  const char *name;
+  const char *valuePtr;
+  const char *valueEnd;
+  char normalized;
+} ATTRIBUTE;
+
+struct encoding;
+typedef struct encoding ENCODING;
+
+struct encoding {
+  int (*scanners[XML_N_STATES])(const ENCODING *,
+                               const char *,
+                               const char *,
+                               const char **);
+  int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *,
+                                             const char *,
+                                             const char *,
+                                             const char **);
+  int (*sameName)(const ENCODING *,
+                 const char *, const char *);
+  int (*nameMatchesAscii)(const ENCODING *,
+                         const char *, const char *, const char *);
+  int (*nameLength)(const ENCODING *, const char *);
+  const char *(*skipS)(const ENCODING *, const char *);
+  int (*getAtts)(const ENCODING *enc, const char *ptr,
+                int attsMax, ATTRIBUTE *atts);
+  int (*charRefNumber)(const ENCODING *enc, const char *ptr);
+  int (*predefinedEntityName)(const ENCODING *, const char *, const char *);
+  void (*updatePosition)(const ENCODING *,
+                        const char *ptr,
+                        const char *end,
+                        POSITION *);
+  int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+                   const char **badPtr);
+  void (*utf8Convert)(const ENCODING *enc,
+                     const char **fromP,
+                     const char *fromLim,
+                     char **toP,
+                     const char *toLim);
+  void (*utf16Convert)(const ENCODING *enc,
+                      const char **fromP,
+                      const char *fromLim,
+                      unsigned short **toP,
+                      const unsigned short *toLim);
+  int minBytesPerChar;
+  char isUtf8;
+  char isUtf16;
+};
+
+/*
+Scan the string starting at ptr until the end of the next complete token,
+but do not scan past eptr.  Return an integer giving the type of token.
+
+Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
+
+Return XML_TOK_PARTIAL when the string does not contain a complete token;
+nextTokPtr will not be set.
+
+Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr
+will be set to point to the character which made the token invalid.
+
+Otherwise the string starts with a valid token; nextTokPtr will be set to point
+to the character following the end of that token.
+
+Each data character counts as a single token, but adjacent data characters
+may be returned together.  Similarly for characters in the prolog outside
+literals, comments and processing instructions.
+*/
+
+
+#define XmlTok(enc, state, ptr, end, nextTokPtr) \
+  (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
+
+#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
+
+#define XmlContentTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
+
+#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
+
+#ifdef XML_DTD
+
+#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
+
+#endif /* XML_DTD */
+
+/* This is used for performing a 2nd-level tokenization on
+the content of a literal that has already been returned by XmlTok. */ 
+
+#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
+  (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
+
+#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
+   XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
+   XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
+
+#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
+  (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
+
+#define XmlNameLength(enc, ptr) \
+  (((enc)->nameLength)(enc, ptr))
+
+#define XmlSkipS(enc, ptr) \
+  (((enc)->skipS)(enc, ptr))
+
+#define XmlGetAttributes(enc, ptr, attsMax, atts) \
+  (((enc)->getAtts)(enc, ptr, attsMax, atts))
+
+#define XmlCharRefNumber(enc, ptr) \
+  (((enc)->charRefNumber)(enc, ptr))
+
+#define XmlPredefinedEntityName(enc, ptr, end) \
+  (((enc)->predefinedEntityName)(enc, ptr, end))
+
+#define XmlUpdatePosition(enc, ptr, end, pos) \
+  (((enc)->updatePosition)(enc, ptr, end, pos))
+
+#define XmlIsPublicId(enc, ptr, end, badPtr) \
+  (((enc)->isPublicId)(enc, ptr, end, badPtr))
+
+#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
+  (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
+
+#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
+  (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
+
+typedef struct {
+  ENCODING initEnc;
+  const ENCODING **encPtr;
+} INIT_ENCODING;
+
+int XMLTOKAPI XmlParseXmlDecl(int isGeneralTextEntity,
+                             const ENCODING *enc,
+                             const char *ptr,
+                             const char *end,
+                             const char **badPtr,
+                             const char **versionPtr,
+                             const char **encodingNamePtr,
+                             const ENCODING **namedEncodingPtr,
+                             int *standalonePtr);
+
+int XMLTOKAPI XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncoding(void);
+const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncoding(void);
+int XMLTOKAPI XmlUtf8Encode(int charNumber, char *buf);
+int XMLTOKAPI XmlUtf16Encode(int charNumber, unsigned short *buf);
+
+int XMLTOKAPI XmlSizeOfUnknownEncoding(void);
+ENCODING XMLTOKAPI *
+XmlInitUnknownEncoding(void *mem,
+                      int *table,
+                      int (*conv)(void *userData, const char *p),
+                      void *userData);
+
+int XMLTOKAPI XmlParseXmlDeclNS(int isGeneralTextEntity,
+                               const ENCODING *enc,
+                               const char *ptr,
+                               const char *end,
+                               const char **badPtr,
+                               const char **versionPtr,
+                               const char **encodingNamePtr,
+                               const ENCODING **namedEncodingPtr,
+                               int *standalonePtr);
+int XMLTOKAPI XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncodingNS(void);
+const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncodingNS(void);
+ENCODING XMLTOKAPI *
+XmlInitUnknownEncodingNS(void *mem,
+                        int *table,
+                        int (*conv)(void *userData, const char *p),
+                        void *userData);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlTok_INCLUDED */
diff --git a/contrib/src/xrc/expat/xmltok/xmltok_impl.c b/contrib/src/xrc/expat/xmltok/xmltok_impl.c
new file mode 100644 (file)
index 0000000..8bb0c62
--- /dev/null
@@ -0,0 +1,1790 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#undef INVALID_LEAD_CASE
+
+#ifndef IS_INVALID_CHAR
+#define IS_INVALID_CHAR(enc, ptr, n) (0)
+#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
+      ptr += n; \
+      break;
+#else
+#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
+      if (IS_INVALID_CHAR(enc, ptr, n)) { \
+        *(nextTokPtr) = (ptr); \
+        return XML_TOK_INVALID; \
+      } \
+      ptr += n; \
+      break;
+#endif
+
+#define INVALID_CASES(ptr, nextTokPtr) \
+  INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
+  INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
+  INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
+  case BT_NONXML: \
+  case BT_MALFORM: \
+  case BT_TRAIL: \
+    *(nextTokPtr) = (ptr); \
+    return XML_TOK_INVALID;
+
+#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
+   case BT_LEAD ## n: \
+     if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
+     if (!IS_NAME_CHAR(enc, ptr, n)) { \
+       *nextTokPtr = ptr; \
+       return XML_TOK_INVALID; \
+     } \
+     ptr += n; \
+     break;
+
+#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
+  case BT_NONASCII: \
+    if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
+      *nextTokPtr = ptr; \
+      return XML_TOK_INVALID; \
+    } \
+  case BT_NMSTRT: \
+  case BT_HEX: \
+  case BT_DIGIT: \
+  case BT_NAME: \
+  case BT_MINUS: \
+    ptr += MINBPC(enc); \
+    break; \
+  CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
+  CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
+  CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
+
+#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
+   case BT_LEAD ## n: \
+     if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
+     if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
+       *nextTokPtr = ptr; \
+       return XML_TOK_INVALID; \
+     } \
+     ptr += n; \
+     break;
+
+#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
+  case BT_NONASCII: \
+    if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
+      *nextTokPtr = ptr; \
+      return XML_TOK_INVALID; \
+    } \
+  case BT_NMSTRT: \
+  case BT_HEX: \
+    ptr += MINBPC(enc); \
+    break; \
+  CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
+  CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
+  CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
+
+#ifndef PREFIX
+#define PREFIX(ident) ident
+#endif
+
+/* ptr points to character following "<!-" */
+
+static
+int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end,
+                       const char **nextTokPtr)
+{
+  if (ptr != end) {
+    if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+    ptr += MINBPC(enc);
+    while (ptr != end) {
+      switch (BYTE_TYPE(enc, ptr)) {
+      INVALID_CASES(ptr, nextTokPtr)
+      case BT_MINUS:
+       if ((ptr += MINBPC(enc)) == end)
+         return XML_TOK_PARTIAL;
+       if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+         if ((ptr += MINBPC(enc)) == end)
+           return XML_TOK_PARTIAL;
+         if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+           *nextTokPtr = ptr;
+           return XML_TOK_INVALID;
+         }
+         *nextTokPtr = ptr + MINBPC(enc);
+         return XML_TOK_COMMENT;
+       }
+       break;
+      default:
+       ptr += MINBPC(enc);
+       break;
+      }
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<!" */
+
+static
+int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end,
+                    const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_MINUS:
+    return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_LSQB:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_COND_SECT_OPEN;
+  case BT_NMSTRT:
+  case BT_HEX:
+    ptr += MINBPC(enc);
+    break;
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_PERCNT:
+      if (ptr + MINBPC(enc) == end)
+       return XML_TOK_PARTIAL;
+      /* don't allow <!ENTITY% foo "whatever"> */
+      switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
+      case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      /* fall through */
+    case BT_S: case BT_CR: case BT_LF:
+      *nextTokPtr = ptr;
+      return XML_TOK_DECL_OPEN;
+    case BT_NMSTRT:
+    case BT_HEX:
+      ptr += MINBPC(enc);
+      break;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, int *tokPtr)
+{
+  int upper = 0;
+  *tokPtr = XML_TOK_PI;
+  if (end - ptr != MINBPC(enc)*3)
+    return 1;
+  switch (BYTE_TO_ASCII(enc, ptr)) {
+  case ASCII_x:
+    break;
+  case ASCII_X:
+    upper = 1;
+    break;
+  default:
+    return 1;
+  }
+  ptr += MINBPC(enc);
+  switch (BYTE_TO_ASCII(enc, ptr)) {
+  case ASCII_m:
+    break;
+  case ASCII_M:
+    upper = 1;
+    break;
+  default:
+    return 1;
+  }
+  ptr += MINBPC(enc);
+  switch (BYTE_TO_ASCII(enc, ptr)) {
+  case ASCII_l:
+    break;
+  case ASCII_L:
+    upper = 1;
+    break;
+  default:
+    return 1;
+  }
+  if (upper)
+    return 0;
+  *tokPtr = XML_TOK_XML_DECL;
+  return 1;
+}
+
+/* ptr points to character following "<?" */
+
+static
+int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end,
+                  const char **nextTokPtr)
+{
+  int tok;
+  const char *target = ptr;
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_S: case BT_CR: case BT_LF:
+      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      ptr += MINBPC(enc);
+      while (ptr != end) {
+        switch (BYTE_TYPE(enc, ptr)) {
+        INVALID_CASES(ptr, nextTokPtr)
+       case BT_QUEST:
+         ptr += MINBPC(enc);
+         if (ptr == end)
+           return XML_TOK_PARTIAL;
+         if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+           *nextTokPtr = ptr + MINBPC(enc);
+           return tok;
+         }
+         break;
+       default:
+         ptr += MINBPC(enc);
+         break;
+       }
+      }
+      return XML_TOK_PARTIAL;
+    case BT_QUEST:
+      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      ptr += MINBPC(enc);
+      if (ptr == end)
+       return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+       *nextTokPtr = ptr + MINBPC(enc);
+       return tok;
+      }
+      /* fall through */
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+
+static
+int PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end,
+                            const char **nextTokPtr)
+{
+  static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, ASCII_LSQB };
+  int i;
+  /* CDATA[ */
+  if (end - ptr < 6 * MINBPC(enc))
+    return XML_TOK_PARTIAL;
+  for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
+    if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_CDATA_SECT_OPEN;
+}
+
+static
+int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
+                           const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_NONE;
+#if !(MINBPC(enc) == 1)
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      if (n == 0)
+       return XML_TOK_PARTIAL;
+      end = ptr + n;
+    }
+ }
+#endif
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_RSQB:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_PARTIAL;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+      break;
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_PARTIAL;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+      ptr -= MINBPC(enc);
+      break;
+    }
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_CDATA_SECT_CLOSE;
+  case BT_CR:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_PARTIAL;
+    if (BYTE_TYPE(enc, ptr) == BT_LF)
+      ptr += MINBPC(enc);
+    *nextTokPtr = ptr;
+    return XML_TOK_DATA_NEWLINE;
+  case BT_LF:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_DATA_NEWLINE;
+  INVALID_CASES(ptr, nextTokPtr)
+  default:
+    ptr += MINBPC(enc);
+    break;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+       *nextTokPtr = ptr; \
+       return XML_TOK_DATA_CHARS; \
+      } \
+      ptr += n; \
+      break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_NONXML:
+    case BT_MALFORM:
+    case BT_TRAIL:
+    case BT_CR:
+    case BT_LF:
+    case BT_RSQB:
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "</" */
+
+static
+int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end,
+                      const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_S: case BT_CR: case BT_LF:
+      for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+       switch (BYTE_TYPE(enc, ptr)) {
+       case BT_S: case BT_CR: case BT_LF:
+         break;
+       case BT_GT:
+         *nextTokPtr = ptr + MINBPC(enc);
+          return XML_TOK_END_TAG;
+       default:
+         *nextTokPtr = ptr;
+         return XML_TOK_INVALID;
+       }
+      }
+      return XML_TOK_PARTIAL;
+#ifdef XML_NS
+    case BT_COLON:
+      /* no need to check qname syntax here, since end-tag must match exactly */
+      ptr += MINBPC(enc);
+      break;
+#endif
+    case BT_GT:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_END_TAG;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#X" */
+
+static
+int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end,
+                          const char **nextTokPtr)
+{
+  if (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_DIGIT:
+    case BT_HEX:
+      break;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_DIGIT:
+      case BT_HEX:
+       break;
+      case BT_SEMI:
+       *nextTokPtr = ptr + MINBPC(enc);
+       return XML_TOK_CHAR_REF;
+      default:
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#" */
+
+static
+int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end,
+                       const char **nextTokPtr)
+{
+  if (ptr != end) {
+    if (CHAR_MATCHES(enc, ptr, ASCII_x))
+      return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_DIGIT:
+      break;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_DIGIT:
+       break;
+      case BT_SEMI:
+       *nextTokPtr = ptr + MINBPC(enc);
+       return XML_TOK_CHAR_REF;
+      default:
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&" */
+
+static
+int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
+                   const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_NUM:
+    return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_SEMI:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_ENTITY_REF;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following first character of attribute name */
+
+static
+int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
+                    const char **nextTokPtr)
+{
+#ifdef XML_NS
+  int hadColon = 0;
+#endif
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+    case BT_COLON:
+      if (hadColon) {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      hadColon = 1;
+      ptr += MINBPC(enc);
+      if (ptr == end)
+       return XML_TOK_PARTIAL;
+      switch (BYTE_TYPE(enc, ptr)) {
+      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+      default:
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      break;
+#endif
+    case BT_S: case BT_CR: case BT_LF:
+      for (;;) {
+       int t;
+
+       ptr += MINBPC(enc);
+       if (ptr == end)
+         return XML_TOK_PARTIAL;
+       t = BYTE_TYPE(enc, ptr);
+       if (t == BT_EQUALS)
+         break;
+       switch (t) {
+       case BT_S:
+       case BT_LF:
+       case BT_CR:
+         break;
+       default:
+         *nextTokPtr = ptr;
+         return XML_TOK_INVALID;
+       }
+      }
+    /* fall through */
+    case BT_EQUALS:
+      {
+       int open;
+#ifdef XML_NS
+       hadColon = 0;
+#endif
+       for (;;) {
+       
+         ptr += MINBPC(enc);
+         if (ptr == end)
+           return XML_TOK_PARTIAL;
+         open = BYTE_TYPE(enc, ptr);
+         if (open == BT_QUOT || open == BT_APOS)
+           break;
+         switch (open) {
+         case BT_S:
+         case BT_LF:
+         case BT_CR:
+           break;
+         default:
+           *nextTokPtr = ptr;
+           return XML_TOK_INVALID;
+         }
+       }
+       ptr += MINBPC(enc);
+       /* in attribute value */
+       for (;;) {
+         int t;
+         if (ptr == end)
+           return XML_TOK_PARTIAL;
+         t = BYTE_TYPE(enc, ptr);
+         if (t == open)
+           break;
+         switch (t) {
+         INVALID_CASES(ptr, nextTokPtr)
+         case BT_AMP:
+           {
+             int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
+             if (tok <= 0) {
+               if (tok == XML_TOK_INVALID)
+                 *nextTokPtr = ptr;
+               return tok;
+             }
+             break;
+           }
+         case BT_LT:
+           *nextTokPtr = ptr;
+           return XML_TOK_INVALID;
+         default:
+           ptr += MINBPC(enc);
+           break;
+         }
+       }
+       ptr += MINBPC(enc);
+       if (ptr == end)
+         return XML_TOK_PARTIAL;
+       switch (BYTE_TYPE(enc, ptr)) {
+       case BT_S:
+       case BT_CR:
+       case BT_LF:
+         break;
+       case BT_SOL:
+         goto sol;
+       case BT_GT:
+         goto gt;
+       default:
+         *nextTokPtr = ptr;
+         return XML_TOK_INVALID;
+       }
+       /* ptr points to closing quote */
+       for (;;) {
+         ptr += MINBPC(enc);
+         if (ptr == end)
+           return XML_TOK_PARTIAL;
+         switch (BYTE_TYPE(enc, ptr)) {
+         CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+         case BT_S: case BT_CR: case BT_LF:
+           continue;
+         case BT_GT:
+          gt:
+           *nextTokPtr = ptr + MINBPC(enc);
+           return XML_TOK_START_TAG_WITH_ATTS;
+         case BT_SOL:
+          sol:
+           ptr += MINBPC(enc);
+           if (ptr == end)
+             return XML_TOK_PARTIAL;
+           if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+             *nextTokPtr = ptr;
+             return XML_TOK_INVALID;
+           }
+           *nextTokPtr = ptr + MINBPC(enc);
+           return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
+         default:
+           *nextTokPtr = ptr;
+           return XML_TOK_INVALID;
+         }
+         break;
+       }
+       break;
+      }
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<" */
+
+static
+int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
+                  const char **nextTokPtr)
+{
+#ifdef XML_NS
+  int hadColon;
+#endif
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_EXCL:
+    if ((ptr += MINBPC(enc)) == end)
+      return XML_TOK_PARTIAL;
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_MINUS:
+      return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    case BT_LSQB:
+      return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  case BT_QUEST:
+    return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_SOL:
+    return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+#ifdef XML_NS
+  hadColon = 0;
+#endif
+  /* we have a start-tag */
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+    case BT_COLON:
+      if (hadColon) {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      hadColon = 1;
+      ptr += MINBPC(enc);
+      if (ptr == end)
+       return XML_TOK_PARTIAL;
+      switch (BYTE_TYPE(enc, ptr)) {
+      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+      default:
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      break;
+#endif
+    case BT_S: case BT_CR: case BT_LF:
+      {
+        ptr += MINBPC(enc);
+       while (ptr != end) {
+         switch (BYTE_TYPE(enc, ptr)) {
+         CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+         case BT_GT:
+           goto gt;
+         case BT_SOL:
+           goto sol;
+         case BT_S: case BT_CR: case BT_LF:
+           ptr += MINBPC(enc);
+           continue;
+         default:
+           *nextTokPtr = ptr;
+           return XML_TOK_INVALID;
+         }
+         return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
+       }
+       return XML_TOK_PARTIAL;
+      }
+    case BT_GT:
+    gt:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_START_TAG_NO_ATTS;
+    case BT_SOL:
+    sol:
+      ptr += MINBPC(enc);
+      if (ptr == end)
+       return XML_TOK_PARTIAL;
+      if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
+                      const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_NONE;
+#if !(MINBPC(enc) == 1)
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      if (n == 0)
+       return XML_TOK_PARTIAL;
+      end = ptr + n;
+    }
+  }
+#endif
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_LT:
+    return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_AMP:
+    return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_CR:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_TRAILING_CR;
+    if (BYTE_TYPE(enc, ptr) == BT_LF)
+      ptr += MINBPC(enc);
+    *nextTokPtr = ptr;
+    return XML_TOK_DATA_NEWLINE;
+  case BT_LF:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_DATA_NEWLINE;
+  case BT_RSQB:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_TRAILING_RSQB;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+      break;
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_TRAILING_RSQB;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+      ptr -= MINBPC(enc);
+      break;
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  INVALID_CASES(ptr, nextTokPtr)
+  default:
+    ptr += MINBPC(enc);
+    break;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+       *nextTokPtr = ptr; \
+       return XML_TOK_DATA_CHARS; \
+      } \
+      ptr += n; \
+      break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_RSQB:
+      if (ptr + MINBPC(enc) != end) {
+        if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
+          ptr += MINBPC(enc);
+          break;
+        }
+        if (ptr + 2*MINBPC(enc) != end) {
+          if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
+            ptr += MINBPC(enc);
+            break;
+          }
+          *nextTokPtr = ptr + 2*MINBPC(enc);
+          return XML_TOK_INVALID;
+        }
+      }
+      /* fall through */
+    case BT_AMP:
+    case BT_LT:
+    case BT_NONXML:
+    case BT_MALFORM:
+    case BT_TRAIL:
+    case BT_CR:
+    case BT_LF:
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "%" */
+
+static
+int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
+                       const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
+    *nextTokPtr = ptr;
+    return XML_TOK_PERCENT;
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_SEMI:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_PARAM_ENTITY_REF;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
+                         const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_CR: case BT_LF: case BT_S:
+    case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
+      *nextTokPtr = ptr;
+      return XML_TOK_POUND_NAME;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return -XML_TOK_POUND_NAME;
+}
+
+static
+int PREFIX(scanLit)(int open, const ENCODING *enc,
+                   const char *ptr, const char *end,
+                   const char **nextTokPtr)
+{
+  while (ptr != end) {
+    int t = BYTE_TYPE(enc, ptr);
+    switch (t) {
+    INVALID_CASES(ptr, nextTokPtr)
+    case BT_QUOT:
+    case BT_APOS:
+      ptr += MINBPC(enc);
+      if (t != open)
+       break;
+      if (ptr == end)
+       return -XML_TOK_LITERAL;
+      *nextTokPtr = ptr;
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_S: case BT_CR: case BT_LF:
+      case BT_GT: case BT_PERCNT: case BT_LSQB:
+       return XML_TOK_LITERAL;
+      default:
+       return XML_TOK_INVALID;
+      }
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
+                     const char **nextTokPtr)
+{
+  int tok;
+  if (ptr == end)
+    return XML_TOK_NONE;
+#if !(MINBPC(enc) == 1)
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      if (n == 0)
+       return XML_TOK_PARTIAL;
+      end = ptr + n;
+    }
+  }
+#endif
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_QUOT:
+    return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_APOS:
+    return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_LT:
+    {
+      ptr += MINBPC(enc);
+      if (ptr == end)
+       return XML_TOK_PARTIAL;
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_EXCL:
+       return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      case BT_QUEST:
+       return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      case BT_NMSTRT:
+      case BT_HEX:
+      case BT_NONASCII:
+      case BT_LEAD2:
+      case BT_LEAD3:
+      case BT_LEAD4:
+       *nextTokPtr = ptr - MINBPC(enc);
+       return XML_TOK_INSTANCE_START;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  case BT_CR:
+    if (ptr + MINBPC(enc) == end)
+      return -XML_TOK_PROLOG_S;
+    /* fall through */
+  case BT_S: case BT_LF:
+    for (;;) {
+      ptr += MINBPC(enc);
+      if (ptr == end)
+       break;
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_S: case BT_LF:
+       break;
+      case BT_CR:
+       /* don't split CR/LF pair */
+       if (ptr + MINBPC(enc) != end)
+         break;
+       /* fall through */
+      default:
+       *nextTokPtr = ptr;
+       return XML_TOK_PROLOG_S;
+      }
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_PROLOG_S;
+  case BT_PERCNT:
+    return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_COMMA:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_COMMA;
+  case BT_LSQB:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_OPEN_BRACKET;
+  case BT_RSQB:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return -XML_TOK_CLOSE_BRACKET;
+    if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+      if (ptr + MINBPC(enc) == end)
+       return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
+       *nextTokPtr = ptr + 2*MINBPC(enc);
+       return XML_TOK_COND_SECT_CLOSE;
+      }
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_CLOSE_BRACKET;
+  case BT_LPAR:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_OPEN_PAREN;
+  case BT_RPAR:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return -XML_TOK_CLOSE_PAREN;
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_AST:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_CLOSE_PAREN_ASTERISK;
+    case BT_QUEST:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_CLOSE_PAREN_QUESTION;
+    case BT_PLUS:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_CLOSE_PAREN_PLUS;
+    case BT_CR: case BT_LF: case BT_S:
+    case BT_GT: case BT_COMMA: case BT_VERBAR:
+    case BT_RPAR:
+      *nextTokPtr = ptr;
+      return XML_TOK_CLOSE_PAREN;
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  case BT_VERBAR:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_OR;
+  case BT_GT:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_DECL_CLOSE;
+  case BT_NUM:
+    return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+#ifdef XML_MIN_SIZE
+#define LEAD_CASE(n) \
+  case BT_LEAD ## n: \
+    if (end - ptr < n) \
+      return XML_TOK_PARTIAL_CHAR; \
+    if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
+      ptr += n; \
+      tok = XML_TOK_NAME; \
+      break; \
+    } \
+    if (IS_NAME_CHAR(enc, ptr, n)) { \
+      ptr += n; \
+      tok = XML_TOK_NMTOKEN; \
+      break; \
+    } \
+    *nextTokPtr = ptr; \
+    return XML_TOK_INVALID;
+#else
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+    if (end - ptr < n) \
+      return XML_TOK_PARTIAL_CHAR; \
+    *nextTokPtr = ptr; \
+    return XML_TOK_INVALID;
+#endif
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+  case BT_NMSTRT:
+  case BT_HEX:
+    tok = XML_TOK_NAME;
+    ptr += MINBPC(enc);
+    break;
+  case BT_DIGIT:
+  case BT_NAME:
+  case BT_MINUS:
+#ifdef XML_NS
+  case BT_COLON:
+#endif
+    tok = XML_TOK_NMTOKEN;
+    ptr += MINBPC(enc);
+    break;
+  case BT_NONASCII:
+#ifdef XML_MIN_SIZE
+    if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
+      ptr += MINBPC(enc);
+      tok = XML_TOK_NAME;
+      break;
+    }
+    if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
+      ptr += MINBPC(enc);
+      tok = XML_TOK_NMTOKEN;
+      break;
+    }
+#endif
+    /* fall through */
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_GT: case BT_RPAR: case BT_COMMA:
+    case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
+    case BT_S: case BT_CR: case BT_LF:
+      *nextTokPtr = ptr;
+      return tok;
+#ifdef XML_NS
+    case BT_COLON:
+      ptr += MINBPC(enc);
+      switch (tok) {
+      case XML_TOK_NAME:
+       if (ptr == end)
+         return XML_TOK_PARTIAL;
+       tok = XML_TOK_PREFIXED_NAME;
+       switch (BYTE_TYPE(enc, ptr)) {
+       CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+       default:
+         tok = XML_TOK_NMTOKEN;
+         break;
+       }
+       break;
+      case XML_TOK_PREFIXED_NAME:
+       tok = XML_TOK_NMTOKEN;
+       break;
+      }
+      break;
+#endif
+    case BT_PLUS:
+      if (tok == XML_TOK_NMTOKEN)  {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_NAME_PLUS;
+    case BT_AST:
+      if (tok == XML_TOK_NMTOKEN)  {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_NAME_ASTERISK;
+    case BT_QUEST:
+      if (tok == XML_TOK_NMTOKEN)  {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_NAME_QUESTION;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return -tok;
+}
+
+static
+int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end,
+                             const char **nextTokPtr)
+{
+  const char *start;
+  if (ptr == end)
+    return XML_TOK_NONE;
+  start = ptr;
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: ptr += n; break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_AMP:
+      if (ptr == start)
+       return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_LT:
+      /* this is for inside entity references */
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    case BT_LF:
+      if (ptr == start) {
+       *nextTokPtr = ptr + MINBPC(enc);
+       return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_CR:
+      if (ptr == start) {
+       ptr += MINBPC(enc);
+       if (ptr == end)
+         return XML_TOK_TRAILING_CR;
+       if (BYTE_TYPE(enc, ptr) == BT_LF)
+         ptr += MINBPC(enc);
+       *nextTokPtr = ptr;
+       return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_S:
+      if (ptr == start) {
+       *nextTokPtr = ptr + MINBPC(enc);
+       return XML_TOK_ATTRIBUTE_VALUE_S;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+static
+int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end,
+                          const char **nextTokPtr)
+{
+  const char *start;
+  if (ptr == end)
+    return XML_TOK_NONE;
+  start = ptr;
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: ptr += n; break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_AMP:
+      if (ptr == start)
+       return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_PERCNT:
+      if (ptr == start)
+       return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_LF:
+      if (ptr == start) {
+       *nextTokPtr = ptr + MINBPC(enc);
+       return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_CR:
+      if (ptr == start) {
+       ptr += MINBPC(enc);
+       if (ptr == end)
+         return XML_TOK_TRAILING_CR;
+       if (BYTE_TYPE(enc, ptr) == BT_LF)
+         ptr += MINBPC(enc);
+       *nextTokPtr = ptr;
+       return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+#ifdef XML_DTD
+
+static
+int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
+                            const char **nextTokPtr)
+{
+  int level = 0;
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      end = ptr + n;
+    }
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    INVALID_CASES(ptr, nextTokPtr)
+    case BT_LT:
+      if ((ptr += MINBPC(enc)) == end)
+       return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
+       if ((ptr += MINBPC(enc)) == end)
+         return XML_TOK_PARTIAL;
+       if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
+         ++level;
+         ptr += MINBPC(enc);
+       }
+      }
+      break;
+    case BT_RSQB:
+      if ((ptr += MINBPC(enc)) == end)
+       return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+       if ((ptr += MINBPC(enc)) == end)
+         return XML_TOK_PARTIAL;
+       if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+         ptr += MINBPC(enc);
+         if (level == 0) {
+           *nextTokPtr = ptr;
+           return XML_TOK_IGNORE_SECT;
+         }
+         --level;
+       }
+      }
+      break;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+#endif /* XML_DTD */
+
+static
+int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+                      const char **badPtr)
+{
+  ptr += MINBPC(enc);
+  end -= MINBPC(enc);
+  for (; ptr != end; ptr += MINBPC(enc)) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_DIGIT:
+    case BT_HEX:
+    case BT_MINUS:
+    case BT_APOS:
+    case BT_LPAR:
+    case BT_RPAR:
+    case BT_PLUS:
+    case BT_COMMA:
+    case BT_SOL:
+    case BT_EQUALS:
+    case BT_QUEST:
+    case BT_CR:
+    case BT_LF:
+    case BT_SEMI:
+    case BT_EXCL:
+    case BT_AST:
+    case BT_PERCNT:
+    case BT_NUM:
+#ifdef XML_NS
+    case BT_COLON:
+#endif
+      break;
+    case BT_S:
+      if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
+       *badPtr = ptr;
+       return 0;
+      }
+      break;
+    case BT_NAME:
+    case BT_NMSTRT:
+      if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
+       break;
+    default:
+      switch (BYTE_TO_ASCII(enc, ptr)) {
+      case 0x24: /* $ */
+      case 0x40: /* @ */
+       break;
+      default:
+       *badPtr = ptr;
+       return 0;
+      }
+      break;
+    }
+  }
+  return 1;
+}
+
+/* This must only be called for a well-formed start-tag or empty element tag.
+Returns the number of attributes.  Pointers to the first attsMax attributes
+are stored in atts. */
+
+static
+int PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
+                   int attsMax, ATTRIBUTE *atts)
+{
+  enum { other, inName, inValue } state = inName;
+  int nAtts = 0;
+  int open = 0; /* defined when state == inValue;
+                  initialization just to shut up compilers */
+
+  for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define START_NAME \
+      if (state == other) { \
+       if (nAtts < attsMax) { \
+         atts[nAtts].name = ptr; \
+         atts[nAtts].normalized = 1; \
+       } \
+       state = inName; \
+      }
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_NONASCII:
+    case BT_NMSTRT:
+    case BT_HEX:
+      START_NAME
+      break;
+#undef START_NAME
+    case BT_QUOT:
+      if (state != inValue) {
+       if (nAtts < attsMax)
+         atts[nAtts].valuePtr = ptr + MINBPC(enc);
+        state = inValue;
+        open = BT_QUOT;
+      }
+      else if (open == BT_QUOT) {
+        state = other;
+       if (nAtts < attsMax)
+         atts[nAtts].valueEnd = ptr;
+       nAtts++;
+      }
+      break;
+    case BT_APOS:
+      if (state != inValue) {
+       if (nAtts < attsMax)
+         atts[nAtts].valuePtr = ptr + MINBPC(enc);
+        state = inValue;
+        open = BT_APOS;
+      }
+      else if (open == BT_APOS) {
+        state = other;
+       if (nAtts < attsMax)
+         atts[nAtts].valueEnd = ptr;
+       nAtts++;
+      }
+      break;
+    case BT_AMP:
+      if (nAtts < attsMax)
+       atts[nAtts].normalized = 0;
+      break;
+    case BT_S:
+      if (state == inName)
+        state = other;
+      else if (state == inValue
+              && nAtts < attsMax
+              && atts[nAtts].normalized
+              && (ptr == atts[nAtts].valuePtr
+                  || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
+                  || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
+                  || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
+       atts[nAtts].normalized = 0;
+      break;
+    case BT_CR: case BT_LF:
+      /* This case ensures that the first attribute name is counted
+         Apart from that we could just change state on the quote. */
+      if (state == inName)
+        state = other;
+      else if (state == inValue && nAtts < attsMax)
+       atts[nAtts].normalized = 0;
+      break;
+    case BT_GT:
+    case BT_SOL:
+      if (state != inValue)
+       return nAtts;
+      break;
+    default:
+      break;
+    }
+  }
+  /* not reached */
+}
+
+static
+int PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
+{
+  int result = 0;
+  /* skip &# */
+  ptr += 2*MINBPC(enc);
+  if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
+    for (ptr += MINBPC(enc); !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+      int c = BYTE_TO_ASCII(enc, ptr);
+      switch (c) {
+      case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
+      case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
+       result <<= 4;
+       result |= (c - ASCII_0);
+       break;
+      case ASCII_A: case ASCII_B: case ASCII_C: case ASCII_D: case ASCII_E: case ASCII_F:
+       result <<= 4;
+       result += 10 + (c - ASCII_A);
+       break;
+      case ASCII_a: case ASCII_b: case ASCII_c: case ASCII_d: case ASCII_e: case ASCII_f:
+       result <<= 4;
+       result += 10 + (c - ASCII_a);
+       break;
+      }
+      if (result >= 0x110000)
+       return -1;
+    }
+  }
+  else {
+    for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+      int c = BYTE_TO_ASCII(enc, ptr);
+      result *= 10;
+      result += (c - ASCII_0);
+      if (result >= 0x110000)
+       return -1;
+    }
+  }
+  return checkCharRefNumber(result);
+}
+
+static
+int PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, const char *end)
+{
+  switch ((end - ptr)/MINBPC(enc)) {
+  case 2:
+    if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
+      switch (BYTE_TO_ASCII(enc, ptr)) {
+      case ASCII_l:
+       return ASCII_LT;
+      case ASCII_g:
+       return ASCII_GT;
+      }
+    }
+    break;
+  case 3:
+    if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
+      ptr += MINBPC(enc);
+      if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
+       ptr += MINBPC(enc);
+       if (CHAR_MATCHES(enc, ptr, ASCII_p))
+         return ASCII_AMP;
+      }
+    }
+    break;
+  case 4:
+    switch (BYTE_TO_ASCII(enc, ptr)) {
+    case ASCII_q:
+      ptr += MINBPC(enc);
+      if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
+       ptr += MINBPC(enc);
+       if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+         ptr += MINBPC(enc);
+         if (CHAR_MATCHES(enc, ptr, ASCII_t))
+           return ASCII_QUOT;
+       }
+      }
+      break;
+    case ASCII_a:
+      ptr += MINBPC(enc);
+      if (CHAR_MATCHES(enc, ptr, ASCII_p)) {
+       ptr += MINBPC(enc);
+       if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+         ptr += MINBPC(enc);
+         if (CHAR_MATCHES(enc, ptr, ASCII_s))
+           return ASCII_APOS;
+       }
+      }
+      break;
+    }
+  }
+  return 0;
+}
+
+static
+int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
+{
+  for (;;) {
+    switch (BYTE_TYPE(enc, ptr1)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      if (*ptr1++ != *ptr2++) \
+       return 0;
+    LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
+#undef LEAD_CASE
+      /* fall through */
+      if (*ptr1++ != *ptr2++)
+       return 0;
+      break;
+    case BT_NONASCII:
+    case BT_NMSTRT:
+#ifdef XML_NS
+    case BT_COLON:
+#endif
+    case BT_HEX:
+    case BT_DIGIT:
+    case BT_NAME:
+    case BT_MINUS:
+      if (*ptr2++ != *ptr1++)
+       return 0;
+      if (MINBPC(enc) > 1) {
+       if (*ptr2++ != *ptr1++)
+         return 0;
+       if (MINBPC(enc) > 2) {
+         if (*ptr2++ != *ptr1++)
+           return 0;
+          if (MINBPC(enc) > 3) {
+           if (*ptr2++ != *ptr1++)
+             return 0;
+         }
+       }
+      }
+      break;
+    default:
+      if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
+       return 1;
+      switch (BYTE_TYPE(enc, ptr2)) {
+      case BT_LEAD2:
+      case BT_LEAD3:
+      case BT_LEAD4:
+      case BT_NONASCII:
+      case BT_NMSTRT:
+#ifdef XML_NS
+      case BT_COLON:
+#endif
+      case BT_HEX:
+      case BT_DIGIT:
+      case BT_NAME:
+      case BT_MINUS:
+       return 0;
+      default:
+       return 1;
+      }
+    }
+  }
+  /* not reached */
+}
+
+static
+int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+                            const char *end1, const char *ptr2)
+{
+  for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
+    if (ptr1 == end1)
+      return 0;
+    if (!CHAR_MATCHES(enc, ptr1, *ptr2))
+      return 0;
+  }
+  return ptr1 == end1;
+}
+
+static
+int PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
+{
+  const char *start = ptr;
+  for (;;) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: ptr += n; break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_NONASCII:
+    case BT_NMSTRT:
+#ifdef XML_NS
+    case BT_COLON:
+#endif
+    case BT_HEX:
+    case BT_DIGIT:
+    case BT_NAME:
+    case BT_MINUS:
+      ptr += MINBPC(enc);
+      break;
+    default:
+      return ptr - start;
+    }
+  }
+}
+
+static
+const char *PREFIX(skipS)(const ENCODING *enc, const char *ptr)
+{
+  for (;;) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_LF:
+    case BT_CR:
+    case BT_S:
+      ptr += MINBPC(enc);
+      break;
+    default:
+      return ptr;
+    }
+  }
+}
+
+static
+void PREFIX(updatePosition)(const ENCODING *enc,
+                           const char *ptr,
+                           const char *end,
+                           POSITION *pos)
+{
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      ptr += n; \
+      break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_LF:
+      pos->columnNumber = (unsigned)-1;
+      pos->lineNumber++;
+      ptr += MINBPC(enc);
+      break;
+    case BT_CR:
+      pos->lineNumber++;
+      ptr += MINBPC(enc);
+      if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
+       ptr += MINBPC(enc);
+      pos->columnNumber = (unsigned)-1;
+      break;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+    pos->columnNumber++;
+  }
+}
+
+#undef DO_LEAD_CASE
+#undef MULTIBYTE_CASES
+#undef INVALID_CASES
+#undef CHECK_NAME_CASE
+#undef CHECK_NAME_CASES
+#undef CHECK_NMSTRT_CASE
+#undef CHECK_NMSTRT_CASES
diff --git a/contrib/src/xrc/expat/xmltok/xmltok_impl.h b/contrib/src/xrc/expat/xmltok/xmltok_impl.h
new file mode 100644 (file)
index 0000000..eb92802
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+enum {
+  BT_NONXML,
+  BT_MALFORM,
+  BT_LT,
+  BT_AMP,
+  BT_RSQB,
+  BT_LEAD2,
+  BT_LEAD3,
+  BT_LEAD4,
+  BT_TRAIL,
+  BT_CR,
+  BT_LF,
+  BT_GT,
+  BT_QUOT,
+  BT_APOS,
+  BT_EQUALS,
+  BT_QUEST,
+  BT_EXCL,
+  BT_SOL,
+  BT_SEMI,
+  BT_NUM,
+  BT_LSQB,
+  BT_S,
+  BT_NMSTRT,
+  BT_COLON,
+  BT_HEX,
+  BT_DIGIT,
+  BT_NAME,
+  BT_MINUS,
+  BT_OTHER, /* known not to be a name or name start character */
+  BT_NONASCII, /* might be a name or name start character */
+  BT_PERCNT,
+  BT_LPAR,
+  BT_RPAR,
+  BT_AST,
+  BT_PLUS,
+  BT_COMMA,
+  BT_VERBAR
+};
+
+#include <stddef.h>
diff --git a/contrib/src/xrc/expat/xmltok/xmltok_ns.c b/contrib/src/xrc/expat/xmltok/xmltok_ns.c
new file mode 100644 (file)
index 0000000..2427898
--- /dev/null
@@ -0,0 +1,96 @@
+const ENCODING *NS(XmlGetUtf8InternalEncoding)(void)
+{
+  return &ns(internal_utf8_encoding).enc;
+}
+
+const ENCODING *NS(XmlGetUtf16InternalEncoding)(void)
+{
+#if XML_BYTE_ORDER == 12
+  return &ns(internal_little2_encoding).enc;
+#elif XML_BYTE_ORDER == 21
+  return &ns(internal_big2_encoding).enc;
+#else
+  const short n = 1;
+  return *(const char *)&n ? &ns(internal_little2_encoding).enc : &ns(internal_big2_encoding).enc;
+#endif
+}
+
+static
+const ENCODING *NS(encodings)[] = {
+  &ns(latin1_encoding).enc,
+  &ns(ascii_encoding).enc,
+  &ns(utf8_encoding).enc,
+  &ns(big2_encoding).enc,
+  &ns(big2_encoding).enc,
+  &ns(little2_encoding).enc,
+  &ns(utf8_encoding).enc /* NO_ENC */
+};
+
+static
+int NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
+                      const char **nextTokPtr)
+{
+  return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr);
+}
+
+static
+int NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
+                      const char **nextTokPtr)
+{
+  return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr);
+}
+
+int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *name)
+{
+  int i = getEncodingIndex(name);
+  if (i == UNKNOWN_ENC)
+    return 0;
+  SET_INIT_ENC_INDEX(p, i);
+  p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
+  p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
+  p->initEnc.updatePosition = initUpdatePosition;
+  p->encPtr = encPtr;
+  *encPtr = &(p->initEnc);
+  return 1;
+}
+
+static
+const ENCODING *NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
+{
+#define ENCODING_MAX 128
+  char buf[ENCODING_MAX];
+  char *p = buf;
+  int i;
+  XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
+  if (ptr != end)
+    return 0;
+  *p = 0;
+  if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
+    return enc;
+  i = getEncodingIndex(buf);
+  if (i == UNKNOWN_ENC)
+    return 0;
+  return NS(encodings)[i];
+}
+
+int NS(XmlParseXmlDecl)(int isGeneralTextEntity,
+                       const ENCODING *enc,
+                       const char *ptr,
+                       const char *end,
+                       const char **badPtr,
+                       const char **versionPtr,
+                       const char **encodingName,
+                       const ENCODING **encoding,
+                       int *standalone)
+{
+  return doParseXmlDecl(NS(findEncoding),
+                       isGeneralTextEntity,
+                       enc,
+                       ptr,
+                       end,
+                       badPtr,
+                       versionPtr,
+                       encodingName,
+                       encoding,
+                       standalone);
+}
diff --git a/contrib/src/xrc/makefile.b32 b/contrib/src/xrc/makefile.b32
new file mode 100644 (file)
index 0000000..258e43c
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# File:                makefile.b32
+# Author:      Julian Smart
+# Created:     2000
+# Updated:     
+# Copyright:
+#
+# Makefile : Builds BC++ library for 32-bit BC++
+
+WXDIR = $(WXWIN)
+
+expat_dir = $(WXDIR)\contrib\src\xrc\expat
+XMLPARSEDIR = $(expat_dir)\xmlparse 
+XMLTOKDIR = $(expat_dir)\xmltok
+
+EXPAT_DEFS=-I$(expat_dir)\xmlparse -I$(expat_dir)\xmltok
+EXPAT_OBJECTS=xmltok.obj xmlrole.obj xmlparse.obj
+
+EXTRACPPFLAGS=$(wxLIBXMLDIR) $(EXPAT_DEFS)
+
+LIBTARGET=$(WXDIR)\lib\wxxrc.lib
+
+OBJECTS=$(EXPAT_OBJECTS) \
+        xml.obj xmlbin.obj xmlbinz.obj xmlexpat.obj xmlwrite.obj xmlres.obj xmlrsall.obj \
+        xh_bttn.obj xh_chckb.obj xh_chckl.obj xh_choic.obj xh_combo.obj xh_dlg.obj \
+        xh_gauge.obj xh_html.obj xh_menu.obj xh_notbk.obj xh_panel.obj xh_radbt.obj \
+        xh_radbx.obj xh_sizer.obj xh_slidr.obj xh_spin.obj xh_stbmp.obj xh_sttxt.obj \
+        xh_text.obj xh_listb.obj xh_toolb.obj xh_stlin.obj xh_bmp.obj \
+        xh_bmpbt.obj xh_cald.obj xh_listc.obj xh_scrol.obj xh_stbox.obj \
+        xh_tree.obj xh_unkwn.obj xh_frame.obj
+
+!include $(WXDIR)\src\makelib.b32
+
+{$(XMLPARSEDIR)}.c.obj:
+       bcc32 $(EXPAT_DEFS) -c -w-ccc -w-rch -w-par {$< }
+
+{$(XMLTOKDIR)}.c.obj:
+       bcc32 $(EXPAT_DEFS) -c -w-ccc -w-rch -w-par {$< }
+
+
diff --git a/contrib/src/xrc/makefile.g95 b/contrib/src/xrc/makefile.g95
new file mode 100644 (file)
index 0000000..3a11d89
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# File:         makefile.g95
+# Author:       Julian Smart
+# Created:      2000
+# Updated:
+# Copyright:    (c) Julian Smart, 2000
+#
+# Makefile for wxWindows wxXML library (Cygwin/Mingw32).
+
+WXDIR = ../../..
+
+expat_dir = $(WXDIR)/contrib/src/xrc/expat
+XMLPARSEDIR = $(expat_dir)/xmlparse
+XMLTOKDIR=$(expat_dir)/xmltok
+
+EXPAT_DEFS=-I$(expat_dir)/xmlparse -I$(expat_dir)/xmltok
+
+EXTRACPPFLAGS=$(EXPAT_DEFS)
+XMLPARSEDIR_OBJECTS=xmlparse.o
+XMLTOKDIR_OBJECTS=xmltok.o xmlrole.o
+
+LIBTARGET=$(WXDIR)/lib/libwxxrc.a
+
+OBJECTS= $(XMLPARSEDIR_OBJECTS) $(XMLTOKDIR_OBJECTS) \
+        xml.o xmlbin.o xmlbinz.o xmlexpat.o xmlwrite.o xmlres.o xmlrsall.o \
+        xh_bttn.o xh_chckb.o xh_chckl.o xh_choic.o xh_combo.o xh_dlg.o \
+        xh_gauge.o xh_html.o xh_menu.o xh_notbk.o xh_panel.o xh_radbt.o \
+        xh_radbx.o xh_sizer.o xh_slidr.o xh_spin.o xh_stbmp.o xh_sttxt.o \
+        xh_text.o xh_listb.o xh_toolb.o xh_stlin.o xh_bmp.o xh_unkwn.o \
+        xh_bmpbt.o xh_cald.o xh_listc.o xh_scrol.o xh_stbox.o xh_tree.o \
+        xh_frame.o
+
+include $(WXDIR)/src/makelib.g95
+
+$(XMLPARSEDIR_OBJECTS):
+       $(CC) -g $(EXPAT_DEFS) -c -o $@ $(XMLPARSEDIR)/$(patsubst %.o,%.c, $@)
+
+$(XMLTOKDIR_OBJECTS):
+       $(CC) -g $(EXPAT_DEFS) -c -o $@ $(XMLTOKDIR)/$(patsubst %.o,%.c, $@)
diff --git a/contrib/src/xrc/makefile.vc b/contrib/src/xrc/makefile.vc
new file mode 100644 (file)
index 0000000..f5c6515
--- /dev/null
@@ -0,0 +1,149 @@
+
+# File:                makefile.vc
+# Author:      Julian Smart
+# Created:     1993
+# Updated:
+# Copyright:   (c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds wxXML classes library (MS VC++).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+wxXMLDIR = $(WXDIR)\contrib\src\xrc
+wxXMLINC = $(WXDIR)\contrib\include\wx\xml
+THISDIR = $(WXDIR)\contrib\src\xrc
+DOCDIR=$(WXDIR)\contrib\docs
+LOCALDOCDIR=$(WXDIR)\contrib\docs\latex\xml
+
+NOPCH=1
+
+EXPAT_DIR=$(THISDIR)\expat
+E1=$(EXPAT_DIR)\xmlparse
+E2=$(EXPAT_DIR)\xmltok
+
+EXPAT_INCS=-I$(THISDIR)\expat\xmlparse -I$(THISDIR)\expat\xmltok
+EXPAT_OBJS=$(D)\xmlparse.obj $(D)\xmlrole.obj $(D)\xmltok.obj
+
+# Set this to where your libxml directory is
+EXTRAFLAGS=$(EXPAT_INCS)
+
+# Unfortunately we need this _before_ we include makelib.vc
+!if "$(FINAL)" == "1"
+D=Release
+!else
+D=Debug
+LIBEXT=d
+!endif
+
+LIBTARGET=$(WXDIR)\lib\wxxrc$(LIBEXT).lib
+EXTRATARGETS=$(D)
+
+OBJECTS=$(EXPAT_OBJS) \
+        $(D)\xml.obj $(D)\xmlbin.obj $(D)\xmlbinz.obj $(D)\xmlres.obj \
+        $(D)\xmlrsall.obj $(D)\xh_bttn.obj $(D)\xh_chckb.obj $(D)\xh_chckl.obj \
+               $(D)\xh_choic.obj $(D)\xh_combo.obj $(D)\xh_dlg.obj \
+        $(D)\xh_frame.obj $(D)\xh_gauge.obj $(D)\xh_html.obj $(D)\xh_menu.obj \
+               $(D)\xh_notbk.obj $(D)\xh_panel.obj $(D)\xh_radbt.obj \
+        $(D)\xh_radbx.obj $(D)\xh_sizer.obj $(D)\xh_slidr.obj $(D)\xh_spin.obj \
+               $(D)\xh_stbmp.obj $(D)\xh_sttxt.obj \
+        $(D)\xh_text.obj $(D)\xh_listb.obj $(D)\xh_toolb.obj \
+        $(D)\xh_bmpbt.obj $(D)\xh_cald.obj $(D)\xh_listc.obj $(D)\xh_scrol.obj \
+        $(D)\xh_stbox.obj $(D)\xh_tree.obj $(D)\xh_stlin.obj $(D)\xh_bmp.obj \
+        $(D)\xh_unkwn.obj $(D)\xmlwrite.obj $(D)\xmlexpat.obj
+
+!include $(WXDIR)\src\makelib.vc
+
+{$(E1)}.c{$(D)}.obj:
+       $(cc) @<<
+$(CPPFLAGS) /c /Fo$@ /Tc $<
+<<
+{$(E2)}.c{$(D)}.obj:
+       $(cc) @<<
+$(CPPFLAGS) /c /Fo$@ /Tc $<
+<<
+
+
+
+DOCSOURCES=$(LOCALDOCDIR)\xml.tex \
+ $(LOCALDOCDIR)\bugs.tex $(LOCALDOCDIR)\changes.tex\
+ $(LOCALDOCDIR)\classes.tex $(LOCALDOCDIR)\intro.tex\
+ $(LOCALDOCDIR)\topics.tex $(LOCALDOCDIR)\sample.tex
+
+html: $(DOCDIR)\html\xml\xml.htm
+htmlhelp: $(DOCDIR)\htmlhelp\xml.chm
+htb:   $(DOCDIR)\htb\xml.htb
+hlp: $(DOCDIR)\winhelp\xml.hlp
+pdfrtf: $(DOCDIR)\pdf\xml.rtf
+ps: $(DOCDIR)\ps\xml.ps
+
+touchmanual:
+       touch $(LOCALDOCDIR)\xml.tex
+
+
+$(DOCDIR)\winhelp\xml.hlp:         $(LOCALDOCDIR)\xml.rtf $(LOCALDOCDIR)\xml.hpj
+        cd $(LOCALDOCDIR)
+        -erase xml.ph
+        hc xml
+        move xml.hlp $(DOCDIR)\winhelp\xml.hlp
+        move xml.cnt $(DOCDIR)\winhelp\xml.cnt
+        cd $(THISDIR)
+
+$(LOCALDOCDIR)\xml.rtf: $(DOCSOURCES)
+        cd $(LOCALDOCDIR)
+        -start $(WAITFLAG) tex2rtf $(LOCALDOCDIR)\xml.tex $(LOCALDOCDIR)\xml.rtf -twice -winhelp
+        cd $(THISDIR)
+
+$(DOCDIR)\pdf\xml.rtf: $(DOCSOURCES)
+        cd $(LOCALDOCDIR)
+        -copy *.bmp $(DOCDIR)\pdf
+        -start $(WAITFLAG) tex2rtf $(LOCALDOCDIR)\xml.tex $(DOCDIR)\pdf\xml.rtf -twice -rtf
+        cd $(THISDIR)
+
+$(DOCDIR)\html\xml\xml.htm:         $(DOCSOURCES)
+        cd $(LOCALDOCDIR)
+        -mkdir $(DOCDIR)\html\xml
+        copy *.gif $(DOCDIR)\html\xml
+        -start $(WAITFLAG) tex2rtf $(LOCALDOCDIR)\xml.tex $(DOCDIR)\html\xml\xml.htm -twice -html
+        -erase $(DOCDIR)\html\xml\*.con
+        -erase *.con
+        -erase $(DOCDIR)\html\xml\*.ref
+        cd $(THISDIR)
+
+$(DOCDIR)\htmlhelp\xml.chm: $(DOCDIR)\html\xml\xml.htm $(DOCDIR)\html\xml\xml.hhp
+       cd $(DOCDIR)\html\xml
+       -hhc xml.hhp
+    move xml.chm $(DOCDIR)\htmlhelp\xml.chm
+       cd $(THISDIR)
+
+# An htb file is a zip file containing the .htm, .gif, .hhp, .hhc and .hhk
+# files, renamed to htb.
+# This can then be used with e.g. helpview.
+# Optionally, a cached version of the .hhp file can be generated with hhp2cached.
+$(DOCDIR)\htb\xml.htb: $(DOCDIR)\html\xml\xml.htm
+       cd $(DOCDIR)\html\xml
+    -erase xml.zip xml.htb
+    zip xml.zip *.htm *.gif *.hhp *.hhc *.hhk
+    -mkdir $(DOCDIR)\htb
+    move xml.zip $(DOCDIR)\htb\xml.htb
+    cd $(THISDIR)
+
+$(LOCALDOCDIR)\xml.dvi:        $(DOCSOURCES)
+       cd $(LOCALDOCDIR)
+        -latex xml
+        -latex xml
+        -makeindx xml
+        -bibtex xml
+        -latex xml
+        -latex xml
+        cd $(THISDIR)
+
+$(WXDIR)\docs\ps\xml.ps:       $(LOCALDOCDIR)\xml.dvi
+       cd $(LOCALDOCDIR)
+        -dvips32 -o xml.ps xml
+        move xml.ps $(WXDIR)\docs\ps\xml.ps
+        cd $(THISDIR)
+
diff --git a/contrib/src/xrc/makefile.wat b/contrib/src/xrc/makefile.wat
new file mode 100644 (file)
index 0000000..be5d104
--- /dev/null
@@ -0,0 +1,31 @@
+# wxXML makefile
+
+WXDIR = ..\..\..
+
+EXTRACPPFLAGS=/Id:\libxml\libxml2-2.1.1
+
+!include $(WXDIR)\src\makewat.env
+
+WXXMLLIB = $(WXDIR)\lib\wxxrc.lib
+THISDIR = $(WXDIR)\contrib\src\xrc
+
+NAME = wxxrc
+LNK = $(name).lnk
+
+OBJECTS=xml.obj xmlbin.obj xmlbinz.obj xmlpars.obj xmlres.obj xmlrsall.obj &
+        xh_bttn.obj xh_chckb.obj xh_chckl.obj xh_choic.obj xh_combo.obj xh_dlg.obj &
+        xh_gauge.obj xh_html.obj xh_menu.obj xh_notbk.obj xh_panel.obj xh_radbt.obj &
+        xh_radbx.obj xh_sizer.obj xh_slidr.obj xh_spin.obj xh_stbmp.obj xh_sttxt.obj &
+        xh_text.obj xh_listb.obj xh_toolb.obj xh_stlin.obj xh_bmp.obj &
+        xh_bmpbt.obj xh_cald.obj xh_listc.obj xh_scrol.obj xh_stbox.obj &
+        xh_tree.obj xh_unkwn.obj xh_frame.obj
+
+
+all: $(WXXMLLIB)
+
+$(WXXMLLIB): $(OBJECTS)
+       *wlib /b /c /n /P=256 $(WXXMLLIB) $(OBJECTS)
+
+clean:   .SYMBOLIC
+    -erase *.obj *.bak *.err *.pch $(WXXMLLIB) *.lbc
+
diff --git a/contrib/src/xrc/wxXMLVC.dsp b/contrib/src/xrc/wxXMLVC.dsp
new file mode 100644 (file)
index 0000000..5633c0c
--- /dev/null
@@ -0,0 +1,254 @@
+# Microsoft Developer Studio Project File - Name="wxXMLVC" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=wxXMLVC - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "wxXMLVC.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "wxXMLVC.mak" CFG="wxXMLVC - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "wxXMLVC - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "wxXMLVC - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "wxXMLVC - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../include" /I "../../include" /I "expat/xmlparse" /I "expat/xmltok" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x809
+# ADD RSC /l 0x809
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\lib\wxxrc.lib"
+
+!ELSEIF  "$(CFG)" == "wxXMLVC - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "../../../include" /I "../../include" /I "expat/xmlparse" /I "expat/xmltok" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D DEBUG=1 /D "__WXDEBUG__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x809
+# ADD RSC /l 0x809
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\lib\wxxrcd.lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "wxXMLVC - Win32 Release"
+# Name "wxXMLVC - Win32 Debug"
+# Begin Group "Expat"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\expat\xmlparse\xmlparse.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\expat\xmltok\xmlrole.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\expat\xmltok\xmltok.c
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\xh_bmp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_bmpbt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_bttn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_cald.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_chckb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_chckl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_choic.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_combo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_dlg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_frame.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_gauge.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_html.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_listb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_listc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_menu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_notbk.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_panel.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_radbt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_radbx.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_scrol.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_sizer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_slidr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_spin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_stbmp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_stbox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_stlin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_sttxt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_text.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_toolb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_tree.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_unkwn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xml.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xmlbin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xmlbinz.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xmlexpat.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xmlres.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xmlrsall.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xmlwrite.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/contrib/src/xrc/wxXMLVC.dsw b/contrib/src/xrc/wxXMLVC.dsw
new file mode 100644 (file)
index 0000000..6cabdb1
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "wxXMLVC"=.\wxXMLVC.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/contrib/src/xrc/xh_bmp.cpp b/contrib/src/xrc/xh_bmp.cpp
new file mode 100644 (file)
index 0000000..181af55
--- /dev/null
@@ -0,0 +1,60 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_bmp.cpp
+// Purpose:     XML resource for wxBitmap and wxIcon
+// Author:      Vaclav Slavik
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_bmp.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_bmp.h"
+#include "wx/bitmap.h"
+
+
+wxBitmapXmlHandler::wxBitmapXmlHandler() 
+: wxXmlResourceHandler() 
+{
+}
+
+wxObject *wxBitmapXmlHandler::DoCreateResource()
+{ 
+    return new wxBitmap(GetBitmap(wxT("")));
+}
+
+
+
+bool wxBitmapXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxBitmap"));
+}
+
+
+wxIconXmlHandler::wxIconXmlHandler() 
+: wxXmlResourceHandler() 
+{
+}
+
+wxObject *wxIconXmlHandler::DoCreateResource()
+{ 
+    return new wxIcon(GetIcon(wxT("")));
+}
+
+
+
+bool wxIconXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxIcon"));
+}
+
diff --git a/contrib/src/xrc/xh_bmpbt.cpp b/contrib/src/xrc/xh_bmpbt.cpp
new file mode 100644 (file)
index 0000000..476609d
--- /dev/null
@@ -0,0 +1,66 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_bmpbt.cpp
+// Purpose:     XML resource for bitmap buttons
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_bmpbt.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_bmpbt.h"
+#include <wx/bmpbuttn.h>
+
+wxBitmapButtonXmlHandler::wxBitmapButtonXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxBU_AUTODRAW);
+    ADD_STYLE(wxBU_LEFT);
+    ADD_STYLE(wxBU_RIGHT);
+    ADD_STYLE(wxBU_TOP);
+    ADD_STYLE(wxBU_BOTTOM);
+    AddWindowStyles();
+}
+
+
+wxObject *wxBitmapButtonXmlHandler::DoCreateResource()
+{ 
+    wxBitmapButton *button = new wxBitmapButton(m_parentAsWindow,
+                                    GetID(),
+                                    GetBitmap(wxT("bitmap")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(wxT("style"), wxBU_AUTODRAW),
+                                    wxDefaultValidator,
+                                    GetName());
+    if (GetBool(wxT("default"), 0) == 1) button->SetDefault();
+    SetupWindow(button);
+    
+    if (!GetParamValue(wxT("selected")).IsEmpty())
+        button->SetBitmapSelected(GetBitmap(wxT("selected")));
+    if (!GetParamValue(wxT("focus")).IsEmpty())
+        button->SetBitmapFocus(GetBitmap(wxT("focus")));
+    if (!GetParamValue(wxT("disabled")).IsEmpty())
+        button->SetBitmapDisabled(GetBitmap(wxT("disabled")));
+    
+    return button;
+}
+
+
+
+bool wxBitmapButtonXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxBitmapButton"));
+}
+
+
diff --git a/contrib/src/xrc/xh_bttn.cpp b/contrib/src/xrc/xh_bttn.cpp
new file mode 100644 (file)
index 0000000..ab6d6f7
--- /dev/null
@@ -0,0 +1,59 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_bttn.cpp
+// Purpose:     XML resource for buttons
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_bttn.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_bttn.h"
+#include "wx/button.h"
+
+
+wxButtonXmlHandler::wxButtonXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxBU_LEFT);
+    ADD_STYLE(wxBU_RIGHT);
+    ADD_STYLE(wxBU_TOP);
+    ADD_STYLE(wxBU_BOTTOM);
+    AddWindowStyles();
+}
+
+
+wxObject *wxButtonXmlHandler::DoCreateResource()
+{ 
+    wxButton *button = new wxButton(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("label")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName());
+    if (GetBool(wxT("default"), 0) == 1) button->SetDefault();
+    SetupWindow(button);
+    
+    return button;
+}
+
+
+
+bool wxButtonXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxButton"));
+}
+
+
diff --git a/contrib/src/xrc/xh_cald.cpp b/contrib/src/xrc/xh_cald.cpp
new file mode 100644 (file)
index 0000000..4e59b88
--- /dev/null
@@ -0,0 +1,61 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_cald.cpp
+// Purpose:     XML resource for wxCalendarCtrl
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_cald.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_cald.h"
+#include "wx/event.h"
+#include "wx/calctrl.h"
+
+
+wxCalendarCtrlXmlHandler::wxCalendarCtrlXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxCAL_SUNDAY_FIRST);
+    ADD_STYLE(wxCAL_MONDAY_FIRST);
+    ADD_STYLE(wxCAL_SHOW_HOLIDAYS);
+    ADD_STYLE(wxCAL_NO_YEAR_CHANGE);
+    ADD_STYLE(wxCAL_NO_MONTH_CHANGE);
+    AddWindowStyles();
+}
+
+
+wxObject *wxCalendarCtrlXmlHandler::DoCreateResource()
+{ 
+    wxCalendarCtrl *calendar = new wxCalendarCtrl(m_parentAsWindow,
+                                    GetID(),
+                                    wxDefaultDateTime,
+                                    /*TODO: take it from resource*/
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    GetName());
+    
+    SetupWindow(calendar);
+    
+    return calendar;
+}
+
+
+
+bool wxCalendarCtrlXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxCalendarCtrl"));
+}
+
+
diff --git a/contrib/src/xrc/xh_chckb.cpp b/contrib/src/xrc/xh_chckb.cpp
new file mode 100644 (file)
index 0000000..9974211
--- /dev/null
@@ -0,0 +1,57 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_chckb.cpp
+// Purpose:     XML resource for wxCheckBox
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_chckb.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_chckb.h"
+#include "wx/checkbox.h"
+
+#if wxUSE_CHECKBOX
+
+wxCheckBoxXmlHandler::wxCheckBoxXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    AddWindowStyles();
+}
+
+wxObject *wxCheckBoxXmlHandler::DoCreateResource()
+{ 
+    wxCheckBox *control = new wxCheckBox(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("label")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+    control->SetValue( GetBool( wxT("checked")));
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxCheckBoxXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxCheckBox"));
+}
+
+#endif
diff --git a/contrib/src/xrc/xh_chckl.cpp b/contrib/src/xrc/xh_chckl.cpp
new file mode 100644 (file)
index 0000000..b033b13
--- /dev/null
@@ -0,0 +1,109 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_chckl.cpp
+// Purpose:     XML resource for wxCheckList
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_chckl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_chckl.h"
+#include "wx/checklst.h"
+
+wxCheckListXmlHandler::wxCheckListXmlHandler() 
+: wxXmlResourceHandler(), m_insideBox(FALSE)
+{
+    // no styles
+    AddWindowStyles();
+}
+
+wxObject *wxCheckListXmlHandler::DoCreateResource()
+{ 
+    if (m_class == wxT("wxCheckList"))
+    {
+        // need to build the list of strings from children
+        m_insideBox = TRUE;
+        CreateChildrenPrivately(NULL, GetParamNode(wxT("content")));
+        wxString *strings = (wxString *) NULL;
+        if( strList.GetCount() > 0 )
+        {
+            strings = new wxString[strList.GetCount()];
+            int count = strList.GetCount();
+            for( int i = 0; i < count; i++ )
+                strings[i]=strList[i];
+        }
+
+
+        wxCheckListBox *control = new wxCheckListBox(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    strList.GetCount(),
+                                    strings,
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+        // step through children myself (again.)
+        wxXmlNode *n = GetParamNode(wxT("content"));
+        if (n) n = n->GetChildren();
+        int i = 0;
+        while (n)
+        {
+            if (n->GetType() != wxXML_ELEMENT_NODE ||
+                n->GetName() != wxT("item"))
+               { n = n->GetNext(); continue; }
+
+            // checking boolean is a bit ugly here (see GetBool() )
+            wxString v = n->GetPropVal(wxT("checked"), wxEmptyString);
+            v.MakeLower();
+            if (v && v == wxT("1"))
+                control->Check( i, TRUE );
+
+            i++;        
+            n = n->GetNext();
+        }
+        
+        SetupWindow(control);
+
+        if( strings != NULL )
+            delete [] strings;
+        strList.Clear();    // dump the strings   
+
+        return control;
+    }
+    else
+    {
+        // on the inside now.
+        // handle <item checked="boolean">Label</item>
+
+        // add to the list
+        strList.Add( GetNodeContent(m_node) );
+
+        return NULL;
+    }
+
+}
+
+
+
+bool wxCheckListXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return (IsOfClass(node, wxT("wxCheckList")) ||
+           (m_insideBox && node->GetName() == wxT("item"))
+           );
+}
+
+
diff --git a/contrib/src/xrc/xh_choic.cpp b/contrib/src/xrc/xh_choic.cpp
new file mode 100644 (file)
index 0000000..2d2dc7b
--- /dev/null
@@ -0,0 +1,95 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_choic.cpp
+// Purpose:     XML resource for wxChoice
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_choic.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_choic.h"
+#include "wx/choice.h"
+
+wxChoiceXmlHandler::wxChoiceXmlHandler() 
+: wxXmlResourceHandler() , m_insideBox(FALSE)
+{
+    ADD_STYLE(wxCB_SORT);
+    AddWindowStyles();
+}
+
+wxObject *wxChoiceXmlHandler::DoCreateResource()
+{ 
+    if( m_class == wxT("wxChoice"))
+    {
+        // find the selection
+        long selection = GetLong( wxT("selection"), -1 );
+
+        // need to build the list of strings from children
+        m_insideBox = TRUE;
+        CreateChildrenPrivately( NULL, GetParamNode(wxT("content")));
+        wxString *strings = (wxString *) NULL;
+        if( strList.GetCount() > 0 )
+        {
+            strings = new wxString[strList.GetCount()];
+            int count = strList.GetCount();
+            for( int i = 0; i < count; i++ )
+                strings[i]=strList[i];
+        }
+
+
+        wxChoice *control = new wxChoice(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    strList.GetCount(),
+                                    strings,
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+        if( selection != -1 )
+            control->SetSelection( selection );
+
+        SetupWindow(control);
+
+        if( strings != NULL )
+            delete [] strings;
+        strList.Clear();    // dump the strings   
+
+        return control;
+    }
+    else
+    {
+        // on the inside now.
+        // handle <item>Label</item>
+        
+        // add to the list
+        strList.Add( GetNodeContent(m_node) );
+
+        return NULL;
+    }
+
+}
+
+
+
+bool wxChoiceXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return (IsOfClass(node, wxT("wxChoice")) ||
+           (m_insideBox && node->GetName() == wxT("item"))
+           );
+}
+
+
diff --git a/contrib/src/xrc/xh_combo.cpp b/contrib/src/xrc/xh_combo.cpp
new file mode 100644 (file)
index 0000000..2353964
--- /dev/null
@@ -0,0 +1,101 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_combo.cpp
+// Purpose:     XML resource for wxRadioBox
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_combo.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_combo.h"
+#include "wx/combobox.h"
+
+#if wxUSE_COMBOBOX
+
+wxComboBoxXmlHandler::wxComboBoxXmlHandler() 
+: wxXmlResourceHandler() , m_insideBox(FALSE)
+{
+    ADD_STYLE(wxCB_SIMPLE);
+    ADD_STYLE(wxCB_SORT);
+    ADD_STYLE(wxCB_READONLY);
+    ADD_STYLE(wxCB_DROPDOWN);
+    AddWindowStyles();
+}
+
+wxObject *wxComboBoxXmlHandler::DoCreateResource()
+{ 
+    if( m_class == wxT("wxComboBox"))
+    {
+        // find the selection
+        long selection = GetLong( wxT("selection"), -1 );
+
+        // need to build the list of strings from children
+        m_insideBox = TRUE;
+        CreateChildrenPrivately( NULL, GetParamNode(wxT("content")));
+        wxString *strings = (wxString *) NULL;
+        if( strList.GetCount() > 0 )
+        {
+            strings = new wxString[strList.GetCount()];
+            int count = strList.GetCount();
+            for( int i = 0; i < count; i++ )
+                strings[i]=strList[i];
+        }
+
+
+        wxComboBox *control = new wxComboBox(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("value")),
+                                    GetPosition(), GetSize(),
+                                    strList.GetCount(),
+                                    strings,
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+        if( selection != -1 )
+            control->SetSelection( selection );
+
+        SetupWindow(control);
+
+        if( strings != NULL )
+            delete [] strings;
+        strList.Clear();    // dump the strings   
+
+        return control;
+    }
+    else
+    {
+        // on the inside now.
+        // handle <item>Label</item>
+
+        // add to the list
+        strList.Add( GetNodeContent(m_node) );
+
+        return NULL;
+    }
+
+}
+
+
+
+bool wxComboBoxXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return (IsOfClass(node, wxT("wxComboBox")) ||
+           (m_insideBox && node->GetName() == wxT("item"))
+           );
+}
+
+#endif
diff --git a/contrib/src/xrc/xh_dlg.cpp b/contrib/src/xrc/xh_dlg.cpp
new file mode 100644 (file)
index 0000000..9aec62e
--- /dev/null
@@ -0,0 +1,80 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_dlg.cpp
+// Purpose:     XML resource for dialogs
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_dlg.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_dlg.h"
+#include "wx/dialog.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+
+
+wxDialogXmlHandler::wxDialogXmlHandler() : wxXmlResourceHandler()
+{
+    ADD_STYLE(wxSTAY_ON_TOP);
+    ADD_STYLE(wxCAPTION);
+    ADD_STYLE(wxDEFAULT_DIALOG_STYLE);
+    ADD_STYLE(wxTHICK_FRAME);
+    ADD_STYLE(wxSYSTEM_MENU);
+    ADD_STYLE(wxRESIZE_BORDER);
+    ADD_STYLE(wxRESIZE_BOX);
+    ADD_STYLE(wxDIALOG_MODAL);
+    ADD_STYLE(wxDIALOG_MODELESS);
+
+    ADD_STYLE(wxNO_3D);
+    ADD_STYLE(wxTAB_TRAVERSAL);
+    ADD_STYLE(wxWS_EX_VALIDATE_RECURSIVELY);
+    ADD_STYLE(wxCLIP_CHILDREN);
+    AddWindowStyles();
+}
+
+
+
+wxObject *wxDialogXmlHandler::DoCreateResource()
+{ 
+    wxDialog *dlg = wxDynamicCast(m_instance, wxDialog);
+    
+    wxASSERT_MSG(dlg, _("XML resource: Cannot create dialog without instance."));
+    
+    dlg->Create(m_parentAsWindow,
+                GetID(),
+                GetText(wxT("title")),
+                wxDefaultPosition, wxDefaultSize,
+                GetStyle(wxT("style"), wxDEFAULT_DIALOG_STYLE),
+                GetName());
+    dlg->SetClientSize(GetSize());
+    dlg->Move(GetPosition());
+    SetupWindow(dlg);
+
+    CreateChildren(dlg);
+    
+    if (GetBool(_("centered"), FALSE))
+        dlg->Centre();
+    
+    return dlg;
+}
+
+
+
+bool wxDialogXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxDialog"));
+}
+
+
diff --git a/contrib/src/xrc/xh_frame.cpp b/contrib/src/xrc/xh_frame.cpp
new file mode 100644 (file)
index 0000000..7b5d003
--- /dev/null
@@ -0,0 +1,85 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_frame.cpp
+// Purpose:     XML resource for dialogs
+// Author:      Vaclav Slavik & Aleks.
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_frame.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_frame.h"
+#include "wx/frame.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+
+
+wxFrameXmlHandler::wxFrameXmlHandler() : wxXmlResourceHandler()
+{
+    ADD_STYLE(wxSTAY_ON_TOP);
+    ADD_STYLE(wxCAPTION);
+    ADD_STYLE(wxDEFAULT_DIALOG_STYLE);
+    ADD_STYLE(wxDEFAULT_FRAME_STYLE);
+    ADD_STYLE(wxTHICK_FRAME);
+    ADD_STYLE(wxSYSTEM_MENU);
+    ADD_STYLE(wxRESIZE_BORDER);
+    ADD_STYLE(wxRESIZE_BOX);
+
+    ADD_STYLE(wxFRAME_TOOL_WINDOW);
+    ADD_STYLE(wxFRAME_FLOAT_ON_PARENT);
+    ADD_STYLE(wxMAXIMIZE_BOX);
+    ADD_STYLE(wxMINIMIZE_BOX);
+    ADD_STYLE(wxSTAY_ON_TOP);
+
+    ADD_STYLE(wxNO_3D);
+    ADD_STYLE(wxTAB_TRAVERSAL);
+    ADD_STYLE(wxWS_EX_VALIDATE_RECURSIVELY);
+    ADD_STYLE(wxCLIP_CHILDREN);
+    AddWindowStyles();
+}
+
+
+
+wxObject *wxFrameXmlHandler::DoCreateResource()
+{ 
+    wxFrame *frame = wxDynamicCast(m_instance, wxFrame);
+    
+    wxASSERT_MSG(frame, _("XML resource: Cannot create dialog without instance."));
+    
+    frame->Create(m_parentAsWindow,
+                GetID(),
+                GetText(_T("title")),
+                wxDefaultPosition, wxDefaultSize,
+                GetStyle(_T("style"), wxDEFAULT_FRAME_STYLE),
+                GetName());
+    frame->SetClientSize(GetSize());
+    frame->Move(GetPosition());
+    SetupWindow(frame);
+
+    CreateChildren(frame);
+    
+    if (GetBool(_("centered"), FALSE))
+        frame->Centre();
+    
+    return frame;
+}
+
+
+
+bool wxFrameXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, _T("wxFrame"));
+}
+
+
diff --git a/contrib/src/xrc/xh_gauge.cpp b/contrib/src/xrc/xh_gauge.cpp
new file mode 100644 (file)
index 0000000..dec1db5
--- /dev/null
@@ -0,0 +1,74 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_gauge.cpp
+// Purpose:     XML resource for wxGauge
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_gauge.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_gauge.h"
+#include "wx/gauge.h"
+
+#if wxUSE_GAUGE
+
+wxGaugeXmlHandler::wxGaugeXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxGA_HORIZONTAL );
+    ADD_STYLE( wxGA_VERTICAL );
+    ADD_STYLE( wxGA_PROGRESSBAR );
+    ADD_STYLE( wxGA_SMOOTH );   // windows only
+    AddWindowStyles();
+}
+
+wxObject *wxGaugeXmlHandler::DoCreateResource()
+{ 
+    wxGauge *control = new wxGauge(m_parentAsWindow,
+                                    GetID(),
+                                    GetLong( wxT("range"), wxGAUGE_DEFAULT_RANGE), 
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+    if( HasParam( wxT("value") ))
+    {
+        control->SetValue( GetLong( wxT("value") ));
+    }
+    if( HasParam( wxT("shadow") ))
+    {
+        control->SetShadowWidth( GetDimension( wxT("shadow") ));
+    }
+    if( HasParam( wxT("bezel") ))
+    {
+        control->SetBezelFace( GetDimension( wxT("bezel") ));
+    }
+
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxGaugeXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxGauge"));
+}
+
+
+#endif // wxUSE_GAUGE
diff --git a/contrib/src/xrc/xh_html.cpp b/contrib/src/xrc/xh_html.cpp
new file mode 100644 (file)
index 0000000..affa03f
--- /dev/null
@@ -0,0 +1,72 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_html.cpp
+// Purpose:     XML resource for wxHtmlWindow
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_html.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_html.h"
+
+#if wxUSE_HTML
+
+#include "wx/html/htmlwin.h"
+
+
+wxHtmlWindowXmlHandler::wxHtmlWindowXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxHW_SCROLLBAR_NEVER );
+    ADD_STYLE( wxHW_SCROLLBAR_AUTO );
+    AddWindowStyles();
+}
+
+wxObject *wxHtmlWindowXmlHandler::DoCreateResource()
+{ 
+    wxHtmlWindow *control = new wxHtmlWindow(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    GetStyle( wxT("style" ), wxHW_SCROLLBAR_AUTO),
+                                    GetName()
+                                    );
+
+    if( HasParam( wxT("borders") ))
+    {
+        control->SetBorders( GetDimension( wxT("borders" )));
+    }
+
+    if( HasParam( wxT("url") ))
+    {
+        control->LoadPage( GetParamValue( wxT("url" )));
+    }
+    else if( HasParam( wxT("htmlcode") ))
+    {
+        control->SetPage( GetText(wxT("htmlcode")) );
+    }
+
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxHtmlWindowXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxHtmlWindow"));
+}
+
+#endif // wxUSE_HTML
diff --git a/contrib/src/xrc/xh_listb.cpp b/contrib/src/xrc/xh_listb.cpp
new file mode 100644 (file)
index 0000000..4cc771e
--- /dev/null
@@ -0,0 +1,101 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_listb.cpp
+// Purpose:     XML resource for wxListBox
+// Author:      Bob Mitchell & Vaclav Slavik
+// Created:     2000/07/29
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_listb.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_listb.h"
+#include "wx/listbox.h"
+
+wxListBoxXmlHandler::wxListBoxXmlHandler() 
+: wxXmlResourceHandler() , m_insideBox(FALSE)
+{
+    ADD_STYLE(wxLB_SINGLE);
+    ADD_STYLE(wxLB_MULTIPLE);
+    ADD_STYLE(wxLB_EXTENDED);
+    ADD_STYLE(wxLB_HSCROLL);
+    ADD_STYLE(wxLB_ALWAYS_SB);
+    ADD_STYLE(wxLB_NEEDED_SB);
+    ADD_STYLE(wxLB_SORT);
+    AddWindowStyles();
+}
+
+wxObject *wxListBoxXmlHandler::DoCreateResource()
+{ 
+    if( m_class == wxT("wxListBox"))
+    {
+        // find the selection
+        long selection = GetLong( wxT("selection"), -1 );
+
+        // need to build the list of strings from children
+        m_insideBox = TRUE;
+        CreateChildrenPrivately( NULL, GetParamNode(wxT("content")));
+        wxString *strings = (wxString *) NULL;
+        if( strList.GetCount() > 0 )
+        {
+            strings = new wxString[strList.GetCount()];
+            int count = strList.GetCount();
+            for( int i = 0; i < count; i++ )
+                strings[i]=strList[i];
+        }
+
+
+        wxListBox *control = new wxListBox(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    strList.GetCount(),
+                                    strings,
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+        if( selection != -1 )
+            control->SetSelection( selection );
+
+        SetupWindow(control);
+
+        if( strings != NULL )
+            delete [] strings;
+        strList.Clear();    // dump the strings   
+
+        return control;
+    }
+    else
+    {
+        // on the inside now.
+        // handle <item>Label</item>
+        
+        // add to the list
+        strList.Add( GetNodeContent(m_node) );
+
+        return NULL;
+    }
+
+}
+
+
+
+bool wxListBoxXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return (IsOfClass(node, wxT("wxListBox")) ||
+           (m_insideBox && node->GetName() == wxT("item"))
+           );
+}
+
+
diff --git a/contrib/src/xrc/xh_listc.cpp b/contrib/src/xrc/xh_listc.cpp
new file mode 100644 (file)
index 0000000..ee21109
--- /dev/null
@@ -0,0 +1,67 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_listc.cpp
+// Purpose:     XML resource for wxListCtrl
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_listc.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/textctrl.h"
+#include "wx/xrc/xh_listc.h"
+#include "wx/listctrl.h"
+
+
+wxListCtrlXmlHandler::wxListCtrlXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxLC_LIST);
+    ADD_STYLE(wxLC_REPORT);
+    ADD_STYLE(wxLC_ICON);
+    ADD_STYLE(wxLC_SMALL_ICON);
+    ADD_STYLE(wxLC_ALIGN_TOP);
+    ADD_STYLE(wxLC_ALIGN_LEFT);
+    ADD_STYLE(wxLC_AUTOARRANGE);
+    ADD_STYLE(wxLC_USER_TEXT);
+    ADD_STYLE(wxLC_EDIT_LABELS);
+    ADD_STYLE(wxLC_NO_HEADER);
+    ADD_STYLE(wxLC_SINGLE_SEL);
+    ADD_STYLE(wxLC_SORT_ASCENDING);
+    ADD_STYLE(wxLC_SORT_DESCENDING);
+    AddWindowStyles();
+}
+
+
+wxObject *wxListCtrlXmlHandler::DoCreateResource()
+{ 
+    wxListCtrl *list = new wxListCtrl(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName());
+    /* TODO: columns definition */
+    
+    SetupWindow(list);
+    
+    return list;
+}
+
+
+
+bool wxListCtrlXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxListCtrl"));
+}
diff --git a/contrib/src/xrc/xh_menu.cpp b/contrib/src/xrc/xh_menu.cpp
new file mode 100644 (file)
index 0000000..86a27e8
--- /dev/null
@@ -0,0 +1,135 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_menu.cpp
+// Purpose:     XML resource for menus and menubars
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_menu.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_menu.h"
+#include "wx/menu.h"
+
+
+wxMenuXmlHandler::wxMenuXmlHandler() : 
+        wxXmlResourceHandler(), m_insideMenu(FALSE)
+{
+    ADD_STYLE(wxMENU_TEAROFF);
+}
+
+
+
+wxObject *wxMenuXmlHandler::DoCreateResource()
+{
+    if (m_class == wxT("wxMenu"))
+    {
+        wxMenu *menu = new wxMenu(GetStyle());
+        wxString title = GetText(wxT("label"));
+        wxString help = GetText(wxT("help"));
+        
+        bool oldins = m_insideMenu;
+        m_insideMenu = TRUE;
+        CreateChildren(menu, TRUE/*only this handler*/);
+        m_insideMenu = oldins;
+
+        wxMenuBar *p_bar = wxDynamicCast(m_parent, wxMenuBar);
+        if (p_bar)
+            p_bar->Append(menu, title);
+        else
+        {
+            wxMenu *p_menu = wxDynamicCast(m_parent, wxMenu);
+            if (p_menu)
+                p_menu->Append(GetID(), title, menu, help);
+        }
+
+        return menu;
+    }
+
+    else
+    {
+        wxMenu *p_menu = wxDynamicCast(m_parent, wxMenu);
+        
+        if (m_class == wxT("separator"))
+            p_menu->AppendSeparator();
+        else if (m_class == wxT("break"))
+            p_menu->Break();
+        else /*wxMenuItem*/
+        {
+            int id = GetID();
+            bool checkable = GetBool(wxT("checkable"));
+            wxString label = GetText(wxT("label"));
+            wxString accel = GetText(wxT("accel"));
+            wxString fullLabel = label;
+            if (!accel.IsEmpty())
+                fullLabel << wxT("\t") << accel;
+
+            wxMenuItem *mitem = new wxMenuItem(p_menu, id, fullLabel,
+                                               GetText(wxT("help")), checkable);
+                                               
+#if wxCHECK_VERSION(2,3,0) || defined(__WXMSW__)
+                if (HasParam(wxT("bitmap")))
+                    mitem->SetBitmap(GetBitmap(wxT("bitmap")));
+#endif
+            p_menu->Append(mitem);
+            mitem->Enable(GetBool(wxT("enabled"), TRUE));
+            if (checkable) mitem->Check(GetBool(wxT("checked")));
+        }
+        return NULL;
+    }
+}
+
+
+
+bool wxMenuXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxMenu")) ||
+           (m_insideMenu && 
+               (IsOfClass(node, wxT("wxMenuItem")) ||
+                IsOfClass(node, wxT("break")) ||
+                IsOfClass(node, wxT("separator")))
+           );
+}
+
+
+
+
+
+
+
+
+
+
+
+wxMenuBarXmlHandler::wxMenuBarXmlHandler() : wxXmlResourceHandler()
+{
+    ADD_STYLE(wxMB_DOCKABLE);
+}
+
+
+
+wxObject *wxMenuBarXmlHandler::DoCreateResource()
+{
+    wxMenuBar *menubar = new wxMenuBar(GetStyle());
+    CreateChildren(menubar);
+    return menubar;
+}
+
+
+
+bool wxMenuBarXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxMenuBar"));
+}
+
diff --git a/contrib/src/xrc/xh_notbk.cpp b/contrib/src/xrc/xh_notbk.cpp
new file mode 100644 (file)
index 0000000..fe648dc
--- /dev/null
@@ -0,0 +1,100 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_notbk.cpp
+// Purpose:     XML resource for wxNotebook
+// Author:      Vaclav Slavik
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_notbk.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_notbk.h"
+
+#if wxUSE_NOTEBOOK
+
+#include "wx/log.h"
+#include "wx/notebook.h"
+#include "wx/sizer.h"
+
+wxNotebookXmlHandler::wxNotebookXmlHandler() 
+: wxXmlResourceHandler(), m_isInside(FALSE), m_notebook(NULL)
+{
+    ADD_STYLE(wxNB_FIXEDWIDTH);
+    ADD_STYLE(wxNB_LEFT);
+    ADD_STYLE(wxNB_RIGHT);
+    ADD_STYLE(wxNB_BOTTOM);
+    AddWindowStyles();
+}
+
+
+
+wxObject *wxNotebookXmlHandler::DoCreateResource()
+{ 
+    if (m_class == wxT("notebookpage"))
+    {
+        wxXmlNode *n = GetParamNode(wxT("object"));
+
+        if (n)
+        {
+            bool old_ins = m_isInside;
+            m_isInside = FALSE;
+            m_isInside = old_ins;
+            wxObject *item = CreateResFromNode(n, m_notebook, NULL);
+            wxWindow *wnd = wxDynamicCast(item, wxWindow);
+
+            if (wnd)
+                m_notebook->AddPage(wnd, GetText(wxT("label")),
+                                         GetBool(wxT("selected"), 0));
+            else 
+                wxLogError(wxT("Error in resource."));              
+            return wnd;
+        }
+        else
+        {
+            wxLogError(wxT("Error in resource: no control within notebook's <page> tag."));
+            return NULL;
+        }
+    }
+    
+    else {
+        wxNotebook *nb = new wxNotebook(m_parentAsWindow, 
+                                        GetID(),
+                                        GetPosition(), GetSize(),
+                                        GetStyle( wxT("style" )),
+                                        GetName());
+    
+        wxNotebook *old_par = m_notebook;
+        m_notebook = nb;
+        bool old_ins = m_isInside;
+        m_isInside = TRUE;
+        CreateChildren(m_notebook, TRUE/*only this handler*/);
+        m_isInside = old_ins;
+        m_notebook = old_par;
+
+        if (GetBool(wxT("usenotebooksizer"), FALSE))
+            return new wxNotebookSizer(nb);
+        else
+            return nb;
+    }
+}
+
+
+
+bool wxNotebookXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return ((!m_isInside && IsOfClass(node, wxT("wxNotebook"))) ||
+            (m_isInside && IsOfClass(node, wxT("notebookpage"))));
+}
+
+#endif
diff --git a/contrib/src/xrc/xh_panel.cpp b/contrib/src/xrc/xh_panel.cpp
new file mode 100644 (file)
index 0000000..d4d4095
--- /dev/null
@@ -0,0 +1,63 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_panel.cpp
+// Purpose:     XML resource for panels
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_panel.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_panel.h"
+#include "wx/panel.h"
+
+
+wxPanelXmlHandler::wxPanelXmlHandler() : wxXmlResourceHandler()
+{
+    ADD_STYLE(wxNO_3D);
+    ADD_STYLE(wxTAB_TRAVERSAL);
+    ADD_STYLE(wxWS_EX_VALIDATE_RECURSIVELY);
+    ADD_STYLE(wxCLIP_CHILDREN);
+    AddWindowStyles();
+}
+
+
+
+wxObject *wxPanelXmlHandler::DoCreateResource()
+{ 
+    wxPanel *panel = wxDynamicCast(m_instance, wxPanel);
+
+    if (panel == NULL)
+        panel = new wxPanel(m_parentAsWindow,
+                                 GetID(),
+                                 GetPosition(), GetSize(),
+                                 GetStyle(wxT("style"), wxTAB_TRAVERSAL),
+                                 GetName());
+    else
+        panel->Create(m_parentAsWindow,
+                                 GetID(),
+                                 GetPosition(), GetSize(),
+                                 GetStyle(wxT("style"), wxTAB_TRAVERSAL),
+                                 GetName());
+    SetupWindow(panel);
+    CreateChildren(panel);
+    
+    return panel;
+}
+
+
+bool wxPanelXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxPanel"));
+}
diff --git a/contrib/src/xrc/xh_radbt.cpp b/contrib/src/xrc/xh_radbt.cpp
new file mode 100644 (file)
index 0000000..9caa453
--- /dev/null
@@ -0,0 +1,66 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_radbt.cpp
+// Purpose:     XML resource for wxRadioButton
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_radbt.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_radbt.h"
+#include "wx/radiobut.h"
+
+#if wxUSE_RADIOBOX
+
+wxRadioButtonXmlHandler::wxRadioButtonXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxRB_GROUP );
+    AddWindowStyles();
+}
+
+wxObject *wxRadioButtonXmlHandler::DoCreateResource()
+{ 
+    /* BOBM - implementation note.
+     * once the wxBitmapRadioButton is implemented.
+     * look for a bitmap property. If not null, 
+     * make it a wxBitmapRadioButton instead of the 
+     * normal radio button.
+     */ 
+
+    wxRadioButton *control = new wxRadioButton(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("label")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+    control->SetValue( GetBool(wxT("value"), 0));
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxRadioButtonXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxRadioButton"));
+}
+
+
+#endif
diff --git a/contrib/src/xrc/xh_radbx.cpp b/contrib/src/xrc/xh_radbx.cpp
new file mode 100644 (file)
index 0000000..7d22430
--- /dev/null
@@ -0,0 +1,102 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_radbx.cpp
+// Purpose:     XML resource for wxRadioBox
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_radbx.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_radbx.h"
+#include "wx/radiobox.h"
+
+#if wxUSE_RADIOBOX
+
+wxRadioBoxXmlHandler::wxRadioBoxXmlHandler() 
+: wxXmlResourceHandler() , m_insideBox(FALSE)
+{
+    ADD_STYLE(wxRA_SPECIFY_COLS);
+    ADD_STYLE(wxRA_HORIZONTAL);
+    ADD_STYLE(wxRA_SPECIFY_ROWS);
+    ADD_STYLE(wxRA_VERTICAL);
+    AddWindowStyles();
+}
+
+wxObject *wxRadioBoxXmlHandler::DoCreateResource()
+{ 
+    if( m_class == wxT("wxRadioBox"))
+    {
+        // find the selection
+        long selection = GetLong( wxT("selection"), -1 );
+
+        // need to build the list of strings from children
+        m_insideBox = TRUE;
+        CreateChildrenPrivately( NULL, GetParamNode(wxT("content")));
+        wxString *strings = (wxString *) NULL;
+        if( strList.GetCount() > 0 )
+        {
+            strings = new wxString[strList.GetCount()];
+            int count = strList.GetCount();
+            for( int i = 0; i < count; i++ )
+                strings[i]=strList[i];
+        }
+
+
+        wxRadioBox *control = new wxRadioBox(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("label")),
+                                    GetPosition(), GetSize(),
+                                    strList.GetCount(),
+                                    strings,
+                                    GetLong( wxT("dimension"), 1 ),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+        if( selection != -1 )
+            control->SetSelection( selection );
+
+        SetupWindow(control);
+
+        if( strings != NULL )
+            delete [] strings;
+        strList.Clear();    // dump the strings   
+
+        return control;
+    }
+    else
+    {
+        // on the inside now.
+        // handle <item selected="boolean">Label</item>
+
+        // add to the list
+        strList.Add( GetNodeContent(m_node) );
+
+        return NULL;
+    }
+
+}
+
+
+
+bool wxRadioBoxXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return (IsOfClass(node, wxT("wxRadioBox")) ||
+           (m_insideBox && node->GetName() == wxT("item"))
+           );
+}
+
+#endif
diff --git a/contrib/src/xrc/xh_scrol.cpp b/contrib/src/xrc/xh_scrol.cpp
new file mode 100644 (file)
index 0000000..22af947
--- /dev/null
@@ -0,0 +1,63 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_scrol.cpp
+// Purpose:     XML resource for wxScrollBar
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_scrol.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_scrol.h"
+#include "wx/scrolbar.h"
+
+
+wxScrollBarXmlHandler::wxScrollBarXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxSB_HORIZONTAL );
+    ADD_STYLE( wxSB_VERTICAL );
+    AddWindowStyles();
+}
+
+wxObject *wxScrollBarXmlHandler::DoCreateResource()
+{ 
+    wxScrollBar *control = new wxScrollBar(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+    control->SetScrollbar(GetLong( wxT("value"), 0), 
+                          GetLong( wxT("thumbsize"),1),
+                          GetLong( wxT("range"), 10),
+                          GetLong( wxT("pagesize"),1)
+                          );
+                          
+    
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxScrollBarXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxScrollBar"));
+}
+
+
+
diff --git a/contrib/src/xrc/xh_sizer.cpp b/contrib/src/xrc/xh_sizer.cpp
new file mode 100644 (file)
index 0000000..0a64cbc
--- /dev/null
@@ -0,0 +1,219 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_sizer.cpp
+// Purpose:     XML resource for wxBoxSizer
+// Author:      Vaclav Slavik
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_sizer.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_sizer.h"
+#include "wx/sizer.h"
+#include "wx/log.h"
+#include "wx/statbox.h"
+#include "wx/notebook.h"
+#include "wx/tokenzr.h"
+
+bool wxSizerXmlHandler::IsSizerNode(wxXmlNode *node)
+{
+    return (IsOfClass(node, wxT("wxBoxSizer"))) ||
+           (IsOfClass(node, wxT("wxStaticBoxSizer"))) ||
+           (IsOfClass(node, wxT("wxGridSizer"))) ||
+           (IsOfClass(node, wxT("wxFlexGridSizer")));
+}
+
+
+
+wxSizerXmlHandler::wxSizerXmlHandler() 
+: wxXmlResourceHandler(), m_isInside(FALSE), m_parentSizer(NULL)
+{
+    ADD_STYLE(wxHORIZONTAL);
+    ADD_STYLE(wxVERTICAL);
+
+    // and flags
+    ADD_STYLE(wxLEFT);
+    ADD_STYLE(wxRIGHT);
+    ADD_STYLE(wxTOP);
+    ADD_STYLE(wxBOTTOM);
+    ADD_STYLE(wxNORTH);
+    ADD_STYLE(wxSOUTH);
+    ADD_STYLE(wxEAST);
+    ADD_STYLE(wxWEST);
+    ADD_STYLE(wxALL);
+
+    ADD_STYLE(wxGROW);
+    ADD_STYLE(wxEXPAND);
+    ADD_STYLE(wxSHAPED);
+    ADD_STYLE(wxSTRETCH_NOT);
+
+    ADD_STYLE(wxALIGN_CENTER);
+    ADD_STYLE(wxALIGN_CENTRE);
+    ADD_STYLE(wxALIGN_LEFT);
+    ADD_STYLE(wxALIGN_TOP);
+    ADD_STYLE(wxALIGN_RIGHT);
+    ADD_STYLE(wxALIGN_BOTTOM);
+    ADD_STYLE(wxALIGN_CENTER_HORIZONTAL);
+    ADD_STYLE(wxALIGN_CENTRE_HORIZONTAL);
+    ADD_STYLE(wxALIGN_CENTER_VERTICAL);
+    ADD_STYLE(wxALIGN_CENTRE_VERTICAL);
+}
+
+
+
+wxObject *wxSizerXmlHandler::DoCreateResource()
+{ 
+    if (m_class == wxT("sizeritem"))
+    {
+        wxXmlNode *n = GetParamNode(wxT("object"));
+
+        if (n)
+        {
+            bool old_ins = m_isInside;
+            wxSizer *old_par = m_parentSizer;
+            m_isInside = FALSE;
+            if (!IsSizerNode(n)) m_parentSizer = NULL;
+            wxObject *item = CreateResFromNode(n, m_parent, NULL);
+            m_isInside = old_ins;
+            m_parentSizer = old_par;
+            wxSizer *sizer = wxDynamicCast(item, wxSizer);
+            wxWindow *wnd = wxDynamicCast(item, wxWindow);
+            wxSize minsize = GetSize(wxT("minsize"));
+
+            if (sizer)
+            {
+                m_parentSizer->Add(sizer, GetLong(wxT("option")), 
+                                   GetStyle(wxT("flag")), GetDimension(wxT("border")));
+                if (!(minsize == wxDefaultSize))
+                    m_parentSizer->SetItemMinSize(sizer, minsize.x, minsize.y);
+            }
+            else if (wnd)
+            {
+                m_parentSizer->Add(wnd, GetLong(wxT("option")), 
+                                   GetStyle(wxT("flag")), GetDimension(wxT("border")));
+                if (!(minsize == wxDefaultSize))
+                    m_parentSizer->SetItemMinSize(wnd, minsize.x, minsize.y);
+            }
+            else 
+                wxLogError(wxT("Error in resource."));
+
+            return item;
+        }
+        else /*n == NULL*/
+        {
+            wxLogError(wxT("Error in resource: no control/sizer within sizer's <item> tag."));
+            return NULL;
+        }
+    }
+    
+    else if (m_class == wxT("spacer"))
+    {
+        wxCHECK_MSG(m_parentSizer, NULL, wxT("Incorrect syntax of XML resource: spacer not within sizer!"));
+        wxSize sz = GetSize();
+        m_parentSizer->Add(sz.x, sz.y,
+            GetLong(wxT("option")), GetStyle(wxT("flag")), GetDimension(wxT("border")));
+        return NULL;
+    }
+    
+
+    else {
+        wxSizer *sizer = NULL;
+        
+        wxXmlNode *parentNode = m_node->GetParent();
+
+        wxCHECK_MSG(m_parentSizer != NULL ||
+                ((IsOfClass(parentNode, wxT("wxPanel")) ||
+                  IsOfClass(parentNode, wxT("wxDialog"))) &&
+                 parentNode->GetType() == wxXML_ELEMENT_NODE), NULL,
+                wxT("Incorrect use of sizer: parent is not 'wxDialog' or 'wxPanel'."));
+
+        if (m_class == wxT("wxBoxSizer"))
+            sizer = new wxBoxSizer(GetStyle(wxT("orient"), wxHORIZONTAL));
+
+        else if (m_class == wxT("wxStaticBoxSizer"))
+        {
+            sizer = new wxStaticBoxSizer(
+                         new wxStaticBox(m_parentAsWindow, -1, GetText(wxT("label"))),
+                         GetStyle(wxT("orient"), wxHORIZONTAL));
+        }
+        
+        else if (m_class == wxT("wxGridSizer"))
+            sizer = new wxGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
+                                    GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
+                                    
+        else if (m_class == wxT("wxFlexGridSizer"))
+        {
+            wxFlexGridSizer *fsizer = 
+                  new wxFlexGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
+                      GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
+            sizer = fsizer;
+            wxStringTokenizer tkn;
+            unsigned long l;
+            tkn.SetString(GetParamValue(wxT("growablerows")), wxT(","));
+            while (tkn.HasMoreTokens())
+            {
+                if (!tkn.GetNextToken().ToULong(&l))
+                    wxLogError(wxT("growablerows must be comma-separated list of row numbers"));
+                else
+                    fsizer->AddGrowableRow(l);
+            }
+            tkn.SetString(GetParamValue(wxT("growablecols")), wxT(","));
+            while (tkn.HasMoreTokens())
+            {
+                if (!tkn.GetNextToken().ToULong(&l))
+                    wxLogError(wxT("growablecols must be comma-separated list of column numbers"));
+                else
+                    fsizer->AddGrowableCol(l);
+            }
+        }
+
+        wxSize minsize = GetSize(wxT("minsize"));
+        if (!(minsize == wxDefaultSize))
+            sizer->SetMinSize(minsize);
+
+        wxSizer *old_par = m_parentSizer;
+        m_parentSizer = sizer;
+        bool old_ins = m_isInside;
+        m_isInside = TRUE;
+        CreateChildren(m_parent, TRUE/*only this handler*/);
+        m_isInside = old_ins;
+        m_parentSizer = old_par;
+        
+        if (m_parentSizer == NULL) // setup window:
+        {
+            m_parentAsWindow->SetAutoLayout(TRUE);
+            m_parentAsWindow->SetSizer(sizer);
+
+            wxXmlNode *nd = m_node;
+            m_node = parentNode;
+            if (GetSize() == wxDefaultSize)
+                sizer->Fit(m_parentAsWindow);
+            m_node = nd;
+
+            if (m_parentAsWindow->GetWindowStyle() & (wxRESIZE_BOX | wxRESIZE_BORDER))
+                sizer->SetSizeHints(m_parentAsWindow);
+        }
+        
+        return sizer;
+    }
+}
+
+
+
+bool wxSizerXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return ((!m_isInside && IsSizerNode(node)) ||
+            (m_isInside && IsOfClass(node, wxT("sizeritem"))) ||
+            (m_isInside && IsOfClass(node, wxT("spacer"))));
+}
diff --git a/contrib/src/xrc/xh_slidr.cpp b/contrib/src/xrc/xh_slidr.cpp
new file mode 100644 (file)
index 0000000..52e0233
--- /dev/null
@@ -0,0 +1,94 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_slidr.cpp
+// Purpose:     XML resource for wxSlider
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_slidr.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_slidr.h"
+#include "wx/slider.h"
+
+#if wxUSE_SLIDER
+
+wxSliderXmlHandler::wxSliderXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxSL_HORIZONTAL );
+    ADD_STYLE( wxSL_VERTICAL );
+    ADD_STYLE( wxSL_AUTOTICKS );
+    ADD_STYLE( wxSL_LABELS );
+    ADD_STYLE( wxSL_LEFT );
+    ADD_STYLE( wxSL_TOP );
+    ADD_STYLE( wxSL_RIGHT );
+    ADD_STYLE( wxSL_BOTTOM );
+    ADD_STYLE( wxSL_BOTH );
+    ADD_STYLE( wxSL_SELRANGE );
+    AddWindowStyles();
+}
+
+wxObject *wxSliderXmlHandler::DoCreateResource()
+{ 
+    wxSlider *control = new wxSlider(m_parentAsWindow,
+                                    GetID(),
+                                    GetLong( wxT("value"), wxSL_DEFAULT_VALUE), 
+                                    GetLong( wxT("min"), wxSL_DEFAULT_MIN),
+                                    GetLong( wxT("max"), wxSL_DEFAULT_MAX),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+    if( HasParam( wxT("tickfreq") ))
+    {
+        control->SetTickFreq( GetLong( wxT("tickfreq") ), 0 );
+    }
+    if( HasParam( wxT("pagesize") ))
+    {
+        control->SetPageSize( GetLong( wxT("pagesize") ) );
+    }
+    if( HasParam( wxT("linesize") ))
+    {
+        control->SetLineSize( GetLong( wxT("linesize") ));
+    }
+    if( HasParam( wxT("thumb") ))
+    {
+        control->SetThumbLength( GetLong( wxT("thumb") ));
+    }
+    if( HasParam( wxT("tick") ))
+    {
+        control->SetTick( GetLong( wxT("tick") ));
+    }
+    if( HasParam( wxT("selmin") ) && HasParam( wxT("selmax")) )
+    {
+        control->SetSelection( GetLong( wxT("selmin") ), GetLong( wxT("selmax")) );
+    }
+
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxSliderXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxSlider"));
+}
+
+
+#endif
diff --git a/contrib/src/xrc/xh_spin.cpp b/contrib/src/xrc/xh_spin.cpp
new file mode 100644 (file)
index 0000000..bda1eeb
--- /dev/null
@@ -0,0 +1,99 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_spin.cpp
+// Purpose:     XML resource for wxSpinButton
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_spin.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_spin.h"
+#include "wx/spinctrl.h"
+
+#if wxUSE_SPINBTN
+
+wxSpinButtonXmlHandler::wxSpinButtonXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxSP_HORIZONTAL );
+    ADD_STYLE( wxSP_VERTICAL );
+    ADD_STYLE( wxSP_ARROW_KEYS );
+    ADD_STYLE( wxSP_WRAP );
+    AddWindowStyles();
+}
+
+wxObject *wxSpinButtonXmlHandler::DoCreateResource()
+{ 
+    wxSpinButton *control = new wxSpinButton(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    GetStyle( wxT("style"), wxSP_VERTICAL | wxSP_ARROW_KEYS ),
+                                    GetName()
+                                    );
+
+    control->SetValue( GetLong( wxT("value"), wxSP_DEFAULT_VALUE) );
+    control->SetRange( GetLong( wxT("min"), wxSP_DEFAULT_MIN),
+            GetLong( wxT("max"), wxSP_DEFAULT_MAX) );
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxSpinButtonXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxSpinButton"));
+}
+
+#endif // wxUSE_SPINBTN
+
+#if wxUSE_SPINCTRL
+
+wxSpinCtrlXmlHandler::wxSpinCtrlXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxSP_HORIZONTAL );
+    ADD_STYLE( wxSP_VERTICAL );
+    ADD_STYLE( wxSP_ARROW_KEYS );
+    ADD_STYLE( wxSP_WRAP );
+}
+
+wxObject *wxSpinCtrlXmlHandler::DoCreateResource()
+{ 
+    wxSpinCtrl *control = new wxSpinCtrl(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("value")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle( wxT("style"), wxSP_ARROW_KEYS ),
+                                    GetLong( wxT("min"), wxSP_DEFAULT_MIN),
+                                    GetLong( wxT("max"), wxSP_DEFAULT_MAX),
+                                    GetLong( wxT("value"), wxSP_DEFAULT_VALUE),
+                                    GetName()
+                                    );
+
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxSpinCtrlXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxSpinCtrl"));
+}
+
+#endif // wxUSE_SPINCTRL
diff --git a/contrib/src/xrc/xh_stbmp.cpp b/contrib/src/xrc/xh_stbmp.cpp
new file mode 100644 (file)
index 0000000..4937175
--- /dev/null
@@ -0,0 +1,52 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_stbmp.cpp
+// Purpose:     XML resource for wxStaticBitmap
+// Author:      Vaclav Slavik
+// Created:     2000/04/22
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_stbmp.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_stbmp.h"
+#include "wx/statbmp.h"
+
+wxStaticBitmapXmlHandler::wxStaticBitmapXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    AddWindowStyles();
+}
+
+wxObject *wxStaticBitmapXmlHandler::DoCreateResource()
+{ 
+    wxStaticBitmap *bmp = new wxStaticBitmap(m_parentAsWindow,
+                                    GetID(),
+                                    GetBitmap(wxT("bitmap"), GetSize()),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    GetName()
+                                    );
+    SetupWindow(bmp);
+    
+    return bmp;
+}
+
+
+
+bool wxStaticBitmapXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxStaticBitmap"));
+}
+
+
diff --git a/contrib/src/xrc/xh_stbox.cpp b/contrib/src/xrc/xh_stbox.cpp
new file mode 100644 (file)
index 0000000..42b5e97
--- /dev/null
@@ -0,0 +1,52 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_stbox.cpp
+// Purpose:     XML resource for wxStaticBox
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_stbox.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_stbox.h"
+#include "wx/statbox.h"
+
+wxStaticBoxXmlHandler::wxStaticBoxXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    AddWindowStyles();
+}
+
+wxObject *wxStaticBoxXmlHandler::DoCreateResource()
+{ 
+    wxStaticBox *box = new wxStaticBox(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("label")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    GetName()
+                                    );
+    SetupWindow(box);
+    
+    return box;
+}
+
+
+
+bool wxStaticBoxXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxStaticBox"));
+}
+
+
diff --git a/contrib/src/xrc/xh_stlin.cpp b/contrib/src/xrc/xh_stlin.cpp
new file mode 100644 (file)
index 0000000..9418de0
--- /dev/null
@@ -0,0 +1,55 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_stbox.cpp
+// Purpose:     XML resource for wxStaticLine
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_stlin.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_stlin.h"
+#include "wx/statline.h"
+
+#if wxUSE_STATLINE
+
+wxStaticLineXmlHandler::wxStaticLineXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxLI_HORIZONTAL);
+    ADD_STYLE(wxLI_VERTICAL);
+    AddWindowStyles();
+}
+
+wxObject *wxStaticLineXmlHandler::DoCreateResource()
+{ 
+    wxStaticLine *line = new wxStaticLine(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(wxT("style"), wxLI_HORIZONTAL),
+                                    GetName()
+                                    );
+    SetupWindow(line);
+    
+    return line;
+}
+
+
+
+bool wxStaticLineXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxStaticLine"));
+}
+
+#endif
diff --git a/contrib/src/xrc/xh_sttxt.cpp b/contrib/src/xrc/xh_sttxt.cpp
new file mode 100644 (file)
index 0000000..c188afb
--- /dev/null
@@ -0,0 +1,56 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_sttxt.cpp
+// Purpose:     XML resource for wxStaticText
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_sttxt.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_sttxt.h"
+#include "wx/stattext.h"
+
+wxStaticTextXmlHandler::wxStaticTextXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxST_NO_AUTORESIZE);
+    ADD_STYLE(wxALIGN_LEFT);
+    ADD_STYLE(wxALIGN_RIGHT);
+    ADD_STYLE(wxALIGN_CENTRE);
+    AddWindowStyles();
+}
+
+wxObject *wxStaticTextXmlHandler::DoCreateResource()
+{ 
+    wxStaticText *text = new wxStaticText(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("label")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    GetName()
+                                    );
+    SetupWindow(text);
+    
+    return text;
+}
+
+
+
+bool wxStaticTextXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxStaticText"));
+}
+
+
diff --git a/contrib/src/xrc/xh_text.cpp b/contrib/src/xrc/xh_text.cpp
new file mode 100644 (file)
index 0000000..26d8510
--- /dev/null
@@ -0,0 +1,58 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_text.cpp
+// Purpose:     XML resource for wxTextCtrl
+// Author:      Aleksandras Gluchovas
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Aleksandras Gluchovas
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_text.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_text.h"
+#include "wx/textctrl.h"
+
+wxTextCtrlXmlHandler::wxTextCtrlXmlHandler() : wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxTE_PROCESS_ENTER);
+    ADD_STYLE(wxTE_PROCESS_TAB);
+    ADD_STYLE(wxTE_MULTILINE);
+    ADD_STYLE(wxTE_PASSWORD);
+    ADD_STYLE(wxTE_READONLY);
+    ADD_STYLE(wxHSCROLL);
+    AddWindowStyles();
+}
+
+wxObject *wxTextCtrlXmlHandler::DoCreateResource()
+{ 
+    wxTextCtrl *text = new wxTextCtrl(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("value")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+    SetupWindow(text);
+    
+    return text;
+}
+
+
+
+bool wxTextCtrlXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxTextCtrl"));
+}
+
+
diff --git a/contrib/src/xrc/xh_toolb.cpp b/contrib/src/xrc/xh_toolb.cpp
new file mode 100644 (file)
index 0000000..e8c1253
--- /dev/null
@@ -0,0 +1,129 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_toolb.cpp
+// Purpose:     XML resource for wxBoxSizer
+// Author:      Vaclav Slavik
+// Created:     2000/08/11
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_toolb.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_toolb.h"
+#include "wx/toolbar.h"
+
+
+#if wxUSE_TOOLBAR
+
+wxToolBarXmlHandler::wxToolBarXmlHandler() 
+: wxXmlResourceHandler(), m_isInside(FALSE), m_toolbar(NULL)
+{
+    ADD_STYLE(wxTB_FLAT);
+    ADD_STYLE(wxTB_DOCKABLE);
+    ADD_STYLE(wxTB_VERTICAL);
+    ADD_STYLE(wxTB_HORIZONTAL);
+}
+
+
+
+wxObject *wxToolBarXmlHandler::DoCreateResource()
+{ 
+    if (m_class == wxT("tool"))
+    {
+        wxCHECK_MSG(m_toolbar, NULL, wxT("Incorrect syntax of XML resource: tool not within a toolbar!"));
+        m_toolbar->AddTool(GetID(),
+                           GetBitmap(wxT("bitmap")),
+                           GetBitmap(wxT("bitmap2")),
+                           GetBool(wxT("toggle")),
+                           GetPosition().x,
+                           GetPosition().y,
+                           NULL,
+                           GetText(wxT("tooltip")),
+                           GetText(wxT("longhelp")));
+        return m_toolbar; // must return non-NULL
+    }
+    
+    else if (m_class == wxT("separator"))
+    {
+        wxCHECK_MSG(m_toolbar, NULL, wxT("Incorrect syntax of XML resource: separator not within a toolbar!"));
+        m_toolbar->AddSeparator();
+        return m_toolbar; // must return non-NULL
+    }
+    
+    else /*<object class="wxToolBar">*/
+    {
+        int style = GetStyle(wxT("style"), wxNO_BORDER | wxTB_HORIZONTAL);
+#ifdef __WXMSW__
+        if (!(style & wxNO_BORDER)) style |= wxNO_BORDER;
+#endif
+        wxToolBar *toolbar = new wxToolBar(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(),
+                                    GetSize(),
+                                    style,
+                                    GetName());
+
+        wxSize bmpsize = GetSize(wxT("bitmapsize"));
+        if (!(bmpsize == wxDefaultSize))
+            toolbar->SetToolBitmapSize(bmpsize);
+        wxSize margins = GetSize(wxT("margins"));
+        if (!(margins == wxDefaultSize))
+            toolbar->SetMargins(margins.x, margins.y);
+        long packing = GetLong(wxT("packing"), -1);
+        if (packing != -1)
+            toolbar->SetToolPacking(packing);
+        long separation = GetLong(wxT("separation"), -1);
+        if (separation != -1)
+            toolbar->SetToolSeparation(separation);
+
+        wxXmlNode *children_node = GetParamNode(wxT("object"));
+        if (children_node == NULL) return toolbar;
+
+        m_isInside = TRUE;
+        m_toolbar = toolbar;
+
+        wxXmlNode *n = children_node;
+
+        while (n)
+        {
+            if (n->GetType() == wxXML_ELEMENT_NODE && 
+                n->GetName() == wxT("object"))
+            {
+                wxObject *created = CreateResFromNode(n, toolbar, NULL);
+                wxControl *control = wxDynamicCast(created, wxControl);
+                if (IsOfClass(n, wxT("tool")) &&
+                    IsOfClass(n, wxT("separator")) &&
+                    control != NULL)
+                    toolbar->AddControl(control);
+            }
+            n = n->GetNext();
+        }
+
+        m_isInside = FALSE;
+        m_toolbar = NULL;
+
+        toolbar->Realize();
+        return toolbar;
+    }
+}
+
+
+
+bool wxToolBarXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return ((!m_isInside && IsOfClass(node, wxT("wxToolBar"))) ||
+            (m_isInside && IsOfClass(node, wxT("tool"))) || 
+            (m_isInside && IsOfClass(node, wxT("separator"))));
+}
+
+#endif
diff --git a/contrib/src/xrc/xh_tree.cpp b/contrib/src/xrc/xh_tree.cpp
new file mode 100644 (file)
index 0000000..5bec60c
--- /dev/null
@@ -0,0 +1,57 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_tree.cpp
+// Purpose:     XML resource for wxTreeCtrl
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_tree.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_tree.h"
+#include "wx/treectrl.h"
+
+
+wxTreeCtrlXmlHandler::wxTreeCtrlXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxTR_HAS_BUTTONS);
+    ADD_STYLE(wxTR_EDIT_LABELS);
+    ADD_STYLE(wxTR_MULTIPLE);
+    AddWindowStyles();
+}
+
+
+wxObject *wxTreeCtrlXmlHandler::DoCreateResource()
+{ 
+    wxTreeCtrl *tree = new wxTreeCtrl(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName());
+    
+    SetupWindow(tree);
+    
+    return tree;
+}
+
+
+
+bool wxTreeCtrlXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxTreeCtrl"));
+}
+
+
diff --git a/contrib/src/xrc/xh_unkwn.cpp b/contrib/src/xrc/xh_unkwn.cpp
new file mode 100644 (file)
index 0000000..d08cba8
--- /dev/null
@@ -0,0 +1,91 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_unkwn.cpp
+// Purpose:     XML resource for unknown widget
+// Author:      Vaclav Slavik
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_unkwn.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_unkwn.h"
+#include "wx/window.h"
+#include "wx/log.h"
+#include "wx/sizer.h"
+
+
+class wxUnknownControlContainer : public wxPanel
+{
+public:
+    wxUnknownControlContainer(wxWindow *parent,
+                              const wxString& controlName,
+                              wxWindowID id = -1,
+                              const wxPoint& pos = wxDefaultPosition,
+                              const wxSize& size = wxDefaultSize)
+        : wxPanel(parent, id, pos, size, wxTAB_TRAVERSAL | wxNO_BORDER,
+                  controlName + wxT("_container")),
+          m_controlName(controlName), m_controlAdded(FALSE) 
+    {
+        m_bg = GetBackgroundColour();
+        SetBackgroundColour(wxColour(255, 0, 255));
+    }
+
+    virtual void AddChild(wxWindowBase *child);
+    
+protected:
+    wxString m_controlName;
+    bool m_controlAdded;
+    wxColour m_bg;
+};
+
+void wxUnknownControlContainer::AddChild(wxWindowBase *child)
+{
+    wxASSERT_MSG( !m_controlAdded, wxT("Couldn't add two unknown controls to the same container!") )
+
+    wxPanel::AddChild(child);
+    
+    SetBackgroundColour(m_bg);
+    child->SetName(m_controlName);
+    child->SetId(XMLID(m_controlName));
+    m_controlAdded = TRUE;
+    
+    wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
+    sizer->Add((wxWindow*)child, 1, wxEXPAND);
+    SetSizer(sizer);
+    SetAutoLayout(TRUE);
+    Layout();
+}
+
+
+
+wxUnknownWidgetXmlHandler::wxUnknownWidgetXmlHandler() 
+: wxXmlResourceHandler() 
+{
+}
+
+wxObject *wxUnknownWidgetXmlHandler::DoCreateResource()
+{ 
+    wxPanel *panel = 
+        new wxUnknownControlContainer(m_parentAsWindow,
+                                      GetName(), -1,
+                                      GetPosition(), GetSize());
+    SetupWindow(panel);
+    return panel;
+}
+
+bool wxUnknownWidgetXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("unknown"));
+}
+
diff --git a/contrib/src/xrc/xml.cpp b/contrib/src/xrc/xml.cpp
new file mode 100644 (file)
index 0000000..d6ba14d
--- /dev/null
@@ -0,0 +1,441 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xml.cpp
+// Purpose:     wxXmlDocument - XML parser & data holder class
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "xml.h"
+#pragma implementation "xmlio.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+
+#include "wx/wfstream.h"
+#include "wx/datstrm.h"
+#include "wx/zstream.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+
+#include "wx/xrc/xml.h"
+#include "wx/xrc/xmlio.h"
+
+
+
+wxXmlNode::wxXmlNode(wxXmlNode *parent,wxXmlNodeType type,
+                     const wxString& name, const wxString& content,
+                     wxXmlProperty *props, wxXmlNode *next)
+    : m_type(type), m_name(name), m_content(content),
+      m_properties(props), m_parent(parent),
+      m_children(NULL), m_next(next)
+{
+    if (m_parent)
+    {
+        if (m_parent->m_children)
+        {
+            m_next = m_parent->m_children;
+            m_parent->m_children = this;
+        }
+        else
+            m_parent->m_children = this;
+    }
+}
+
+
+
+wxXmlNode::wxXmlNode(wxXmlNodeType type, const wxString& name,
+                     const wxString& content)
+    : m_type(type), m_name(name), m_content(content),
+      m_properties(NULL), m_parent(NULL),
+      m_children(NULL), m_next(NULL)
+{}
+
+
+
+wxXmlNode::wxXmlNode(const wxXmlNode& node)
+{
+    m_next = NULL;
+    m_parent = NULL;
+    DoCopy(node);
+}
+
+
+
+wxXmlNode& wxXmlNode::operator=(const wxXmlNode& node)
+{
+    delete m_properties;
+    delete m_children;
+    DoCopy(node);
+    return *this;
+}
+
+
+
+void wxXmlNode::DoCopy(const wxXmlNode& node)
+{
+    m_type = node.m_type;
+    m_name = node.m_name;
+    m_content = node.m_content;
+    m_children = NULL;
+
+    wxXmlNode *n = node.m_children;
+    while (n)
+    {
+        AddChild(new wxXmlNode(*n));
+        n = n->GetNext();
+    }
+
+    m_properties = NULL;
+    wxXmlProperty *p = node.m_properties;
+    while (p)
+    {
+       AddProperty(p->GetName(), p->GetValue());
+       p = p->GetNext();
+    }
+}
+
+
+bool wxXmlNode::HasProp(const wxString& propName) const
+{
+    wxXmlProperty *prop = GetProperties();
+
+    while (prop)
+    {
+        if (prop->GetName() == propName) return TRUE;
+        prop = prop->GetNext();
+    }
+
+    return FALSE;
+}
+
+
+
+bool wxXmlNode::GetPropVal(const wxString& propName, wxString *value) const
+{
+    wxXmlProperty *prop = GetProperties();
+
+    while (prop)
+    {
+        if (prop->GetName() == propName)
+        {
+            *value = prop->GetValue();
+            return TRUE;
+        }
+        prop = prop->GetNext();
+    }
+
+    return FALSE;
+}
+
+
+
+wxString wxXmlNode::GetPropVal(const wxString& propName, const wxString& defaultVal) const
+{
+    wxString tmp;
+    if (GetPropVal(propName, &tmp))
+        return tmp;
+    else
+        return defaultVal;
+}
+
+
+
+void wxXmlNode::AddChild(wxXmlNode *child)
+{
+    if (m_children == NULL)
+        m_children = child;
+    else
+    {
+        wxXmlNode *ch = m_children;
+        while (ch->m_next) ch = ch->m_next;
+        ch->m_next = child;
+    }
+    child->m_next = NULL;
+    child->m_parent = this;
+}
+
+
+
+void wxXmlNode::InsertChild(wxXmlNode *child, wxXmlNode *before_node)
+{
+    wxASSERT_MSG(before_node->GetParent() == this, wxT("wxXmlNode::InsertChild - the node has incorrect parent"));
+
+    if (m_children == before_node)
+       m_children = child;
+    else
+    {
+        wxXmlNode *ch = m_children;
+        while (ch->m_next != before_node) ch = ch->m_next;
+        ch->m_next = child;
+    }
+
+    child->m_parent = this;
+    child->m_next = before_node;
+}
+
+
+
+bool wxXmlNode::RemoveChild(wxXmlNode *child)
+{
+    if (m_children == NULL)
+        return FALSE;
+    else if (m_children == child)
+    {
+        m_children = child->m_next;
+        child->m_parent = NULL;
+        child->m_next = NULL;
+        return TRUE;
+    }
+    else
+    {
+        wxXmlNode *ch = m_children;
+        while (ch->m_next)
+        {
+            if (ch->m_next == child)
+            {
+                ch->m_next = child->m_next;
+                child->m_parent = NULL;
+                child->m_next = NULL;
+                return TRUE;
+            }
+            ch = ch->m_next;
+        }
+        return FALSE;
+    }
+}
+
+
+
+void wxXmlNode::AddProperty(const wxString& name, const wxString& value)
+{
+    AddProperty(new wxXmlProperty(name, value, NULL));
+}
+
+void wxXmlNode::AddProperty(wxXmlProperty *prop)
+{
+    if (m_properties == NULL)
+        m_properties = prop;
+    else
+    {
+        wxXmlProperty *p = m_properties;
+        while (p->GetNext()) p = p->GetNext();
+        p->SetNext(prop);
+    }
+}
+
+
+
+bool wxXmlNode::DeleteProperty(const wxString& name)
+{
+    if (m_properties == NULL)
+        return FALSE;
+
+    else if (m_properties->GetName() == name)
+    {
+        wxXmlProperty *prop = m_properties;
+        m_properties = prop->GetNext();
+        prop->SetNext(NULL);
+        delete prop;
+        return TRUE;
+    }
+
+    else
+    {
+        wxXmlProperty *p = m_properties;
+        while (p->GetNext())
+        {
+            if (p->GetNext()->GetName() == name)
+            {
+                wxXmlProperty *prop = p->GetNext();
+                p->SetNext(prop->GetNext());
+                prop->SetNext(NULL);
+                delete prop;
+                return TRUE;
+            }
+            p = p->GetNext();
+        }
+        return FALSE;
+    }
+}
+
+
+
+
+
+
+
+
+wxList *wxXmlDocument::sm_handlers = NULL;
+
+
+
+wxXmlDocument::wxXmlDocument(const wxString& filename, wxXmlIOType io_type)
+                          : wxObject(), m_root(NULL)
+{
+    if (!Load(filename, io_type))
+    {
+        delete m_root;
+        m_root = NULL;
+    }
+}
+
+
+
+wxXmlDocument::wxXmlDocument(wxInputStream& stream, wxXmlIOType io_type)
+                          : wxObject(), m_root(NULL)
+{
+    if (!Load(stream, io_type))
+    {
+        delete m_root;
+        m_root = NULL;
+    }
+}
+
+
+
+wxXmlDocument::wxXmlDocument(const wxXmlDocument& doc)
+{
+    DoCopy(doc);
+}
+
+
+
+wxXmlDocument& wxXmlDocument::operator=(const wxXmlDocument& doc)
+{
+    delete m_root;
+    DoCopy(doc);
+    return *this;
+}
+
+
+
+void wxXmlDocument::DoCopy(const wxXmlDocument& doc)
+{
+    m_version = doc.m_version;
+    m_encoding = doc.m_encoding;
+    m_root = new wxXmlNode(*doc.m_root);
+}
+
+
+
+bool wxXmlDocument::Load(const wxString& filename, wxXmlIOType io_type)
+{
+    wxFileInputStream stream(filename);
+    return Load(stream, io_type);
+}
+
+
+
+bool wxXmlDocument::Load(wxInputStream& stream, wxXmlIOType io_type)
+{
+    wxNode *n = sm_handlers->GetFirst();
+    while (n)
+    {
+        wxXmlIOHandler *h = (wxXmlIOHandler*) n->GetData();
+
+        if ((io_type == wxXML_IO_AUTO || io_type == h->GetType()) &&
+            h->CanLoad(stream))
+        {
+            return h->Load(stream, *this);
+        }
+        n = n->GetNext();
+    }
+    wxLogError(_("Cannot find XML I/O handler capable of loading this format."));
+    return FALSE;
+}
+
+
+
+bool wxXmlDocument::Save(const wxString& filename, wxXmlIOType io_type) const
+{
+    wxFileOutputStream stream(filename);
+    return Save(stream, io_type);
+}
+
+
+
+bool wxXmlDocument::Save(wxOutputStream& stream, wxXmlIOType io_type) const
+{
+    wxNode *n = sm_handlers->GetFirst();
+    while (n)
+    {
+        wxXmlIOHandler *h = (wxXmlIOHandler*) n->GetData();
+        if (io_type == h->GetType() && h->CanSave())
+        {
+            return h->Save(stream, *this);
+        }
+        n = n->GetNext();
+    }
+    wxLogError(_("Cannot find XML I/O handler capable of saving in this format."));
+    return FALSE;
+}
+
+
+
+
+
+
+void wxXmlDocument::AddHandler(wxXmlIOHandler *handler)
+{
+    if (sm_handlers == NULL)
+    {
+        sm_handlers = new wxList;
+        sm_handlers->DeleteContents(TRUE);
+    }
+    sm_handlers->Append(handler);
+}
+
+
+void wxXmlDocument::CleanUpHandlers()
+{
+    delete sm_handlers;
+    sm_handlers = NULL;
+}
+
+
+void wxXmlDocument::InitStandardHandlers()
+{
+    AddHandler(new wxXmlIOHandlerBin);
+#if wxUSE_ZLIB
+    AddHandler(new wxXmlIOHandlerBinZ);
+#endif
+    AddHandler(new wxXmlIOHandlerExpat);
+    AddHandler(new wxXmlIOHandlerWriter);
+}
+
+
+#include "wx/module.h"
+
+class wxXmlModule: public wxModule
+{
+    DECLARE_DYNAMIC_CLASS(wxXmlModule)
+    public:
+        wxXmlModule() {}
+        bool OnInit() { wxXmlDocument::InitStandardHandlers(); return TRUE; };
+        void OnExit() { wxXmlDocument::CleanUpHandlers(); };
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxXmlModule, wxModule)
+
+
+
+
+// When wxXml is loaded dynamically after the application is already running
+// then the built-in module system won't pick this one up.  Add it manually.
+void wxXmlInitXmlModule()
+{
+    wxModule* module = new wxXmlModule;
+    module->Init();
+    wxModule::RegisterModule(module);
+}
+
diff --git a/contrib/src/xrc/xmlbin.cpp b/contrib/src/xrc/xmlbin.cpp
new file mode 100644 (file)
index 0000000..bbd98f7
--- /dev/null
@@ -0,0 +1,161 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xmlbin.cpp
+// Purpose:     wxXmlIOHandlerBin 
+// Author:      Vaclav Slavik
+// Created:     2000/07/24
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+// nothing, already in xml.cpp
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/datstrm.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+
+#include "wx/xrc/xmlio.h"
+
+
+
+
+bool wxXmlIOHandlerBin::CanLoad(wxInputStream& stream)
+{
+    bool canread;
+    canread = (ReadHeader(stream) == wxT("XMLBIN "));
+    stream.SeekI(-9, wxFromCurrent);
+    return canread;
+}
+
+
+
+wxString wxXmlIOHandlerBin::ReadHeader(wxInputStream& stream)
+{
+    wxUint8 version;
+    char cheader[8];
+
+    stream.Read(cheader, 8);
+    cheader[7] = 0;
+    stream.Read(&version, 1);
+    
+    if (version != 1) return wxEmptyString;
+    else return wxString(cheader);
+}
+
+
+
+void wxXmlIOHandlerBin::WriteHeader(wxOutputStream& stream, const wxString& header)
+{
+    char cheader[8];
+    size_t i;
+    wxUint8 version = 1;
+    
+    for (i = 0; i < header.Length(); i++) cheader[i] = header[i];
+    for (; i < 7; i++) cheader[i] = ' ';
+    cheader[7] = 0;
+    stream.Write(cheader, 8);
+    stream.Write(&version, 1);
+}
+
+
+
+static bool SaveBinNode(wxDataOutputStream& ds, wxXmlNode *node)
+{
+    if (node)
+    {
+        ds << (wxUint8)1 <<
+              (wxUint8)node->GetType() << 
+              node->GetName() << node->GetContent();
+        
+        wxXmlProperty *prop = node->GetProperties();
+        while (prop)
+        {
+            ds << (wxUint8)1;
+            ds << prop->GetName() << prop->GetValue();
+            prop = prop->GetNext();
+            
+        }
+        ds << (wxUint8)0;
+        
+        SaveBinNode(ds, node->GetNext());
+        SaveBinNode(ds, node->GetChildren());
+    }  
+    else
+        ds << (wxUint8)0;
+    
+    return TRUE;
+}
+
+
+
+bool wxXmlIOHandlerBin::Save(wxOutputStream& stream, const wxXmlDocument& doc)
+{
+    WriteHeader(stream, "XMLBIN ");
+    wxDataOutputStream ds(stream);
+    ds << doc.GetVersion() << doc.GetEncoding();
+    SaveBinNode(ds, doc.GetRoot());
+    return stream.LastError() == wxSTREAM_NOERROR;
+}
+
+
+
+static wxXmlProperty *LoadBinProp(wxDataInputStream& ds)
+{
+    wxUint8 dummy;
+    ds >> dummy;
+    if (dummy == 0) return NULL;
+
+    wxString name, value;
+    ds >> name >> value;
+    return new wxXmlProperty(name, value, LoadBinProp(ds));
+}
+
+
+
+
+static wxXmlNode *LoadBinNode(wxDataInputStream& ds, wxXmlNode *parent)
+{
+    wxUint8 type;
+    wxString name, content;
+    wxUint8 dummy;
+
+    ds >> dummy;
+    if (dummy == 0) return NULL;
+    ds >> type >> name >> content;
+    
+    wxXmlProperty *prop = LoadBinProp(ds);
+
+    wxXmlNode *nd = new wxXmlNode(parent, (wxXmlNodeType)type, name, content, 
+                                  prop, LoadBinNode(ds, parent));
+    LoadBinNode(ds, nd);
+    return nd;
+}
+
+
+
+bool wxXmlIOHandlerBin::Load(wxInputStream& stream, wxXmlDocument& doc)
+{
+    ReadHeader(stream);
+    wxDataInputStream ds(stream);
+    wxString tmp;
+
+    ds >> tmp;
+    doc.SetVersion(tmp);
+    ds >> tmp;
+    doc.SetEncoding(tmp);
+
+    doc.SetRoot(LoadBinNode(ds, NULL));
+        
+    return (doc.GetRoot() != NULL);
+}
+
+
diff --git a/contrib/src/xrc/xmlbinz.cpp b/contrib/src/xrc/xmlbinz.cpp
new file mode 100644 (file)
index 0000000..876ae33
--- /dev/null
@@ -0,0 +1,59 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xmlbinz.cpp
+// Purpose:     wxXmlIOHandlerBinZ
+// Author:      Vaclav Slavik
+// Created:     2000/07/24
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+// nothing, already in xml.cpp
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/datstrm.h"
+#include "wx/log.h"
+#include "wx/zstream.h"
+
+#include "wx/xrc/xmlio.h"
+
+#if wxUSE_ZLIB
+
+
+
+bool wxXmlIOHandlerBinZ::CanLoad(wxInputStream& stream)
+{
+    bool canread;
+    canread = (ReadHeader(stream) == wxT("XMLBINZ"));
+    stream.SeekI(-9, wxFromCurrent);
+    return canread;
+}
+
+
+
+bool wxXmlIOHandlerBinZ::Save(wxOutputStream& stream, const wxXmlDocument& doc)
+{
+    WriteHeader(stream, "XMLBINZ");
+    wxZlibOutputStream costr(stream, 9);
+    return wxXmlIOHandlerBin::Save(costr, doc);
+}
+
+
+
+bool wxXmlIOHandlerBinZ::Load(wxInputStream& stream, wxXmlDocument& doc)
+{
+    ReadHeader(stream);
+    wxZlibInputStream costr(stream);
+    return wxXmlIOHandlerBin::Load(costr, doc);
+}
+
+
+#endif
diff --git a/contrib/src/xrc/xmlexpat.cpp b/contrib/src/xrc/xmlexpat.cpp
new file mode 100644 (file)
index 0000000..c7894b4
--- /dev/null
@@ -0,0 +1,198 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xmlexpat.cpp
+// Purpose:     wxXmlDocument - XML reader via Expat
+// Author:      Vaclav Slavik
+// Created:     2001/04/30
+// RCS-ID:      $Id$
+// Copyright:   (c) 2001 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+// nothing - already in xml.cpp
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/wfstream.h"
+#include "wx/intl.h"
+#include "wx/log.h"
+#include "wx/strconv.h"
+#include "wx/xrc/xmlio.h"
+
+#include "xmlparse.h"
+
+/*
+
+    FIXME:
+
+     - handle unknown encodings
+     - process all elements, including CDATA
+     - XML resources should automatically select desired encoding besed on
+       runtime environment (?) (would need BIN and BINZ formats modification,
+       too)
+
+ */
+
+
+// converts Expat-produced string in UTF-8 into wxString.
+inline static wxString CharToString(const char *s, size_t len = wxSTRING_MAXLEN)
+{
+#if wxUSE_UNICODE
+    return wxString(s, wxMBConvUTF8, len);
+#else
+    return wxString(s, len);
+#endif
+}
+
+bool wxXmlIOHandlerExpat::CanLoad(wxInputStream& stream)
+{
+    char cheader[7];
+    cheader[6] = 0;
+    stream.Read(cheader, 6);
+    stream.SeekI(-6, wxFromCurrent);
+    return (strcmp(cheader, "<?xml ") == 0);
+}
+
+
+struct wxXmlParsingContext
+{
+    wxXmlNode *root;
+    wxXmlNode *node;
+    wxXmlNode *lastAsText;
+    wxString encoding;
+    wxString version;
+};
+
+static void StartElementHnd(void *userData, const char *name, const char **atts)
+{
+    wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
+    wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, CharToString(name));
+    const char **a = atts;
+    while (*a)
+    {
+        node->AddProperty(CharToString(a[0]), CharToString(a[1]));
+        a += 2;
+    }
+    if (ctx->root == NULL)
+        ctx->root = node;
+    else
+        ctx->node->AddChild(node);
+    ctx->node = node;
+    ctx->lastAsText = NULL;
+}
+
+static void EndElementHnd(void *userData, const char* WXUNUSED(name))
+{
+    wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
+
+    ctx->node = ctx->node->GetParent();
+    ctx->lastAsText = NULL;
+}
+
+static void TextHnd(void *userData, const char *s, int len)
+{
+    wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
+    char *buf = new char[len + 1];
+
+    buf[len] = '\0';
+    memcpy(buf, s, (size_t)len);
+
+    if (ctx->lastAsText)
+    {
+        ctx->lastAsText->SetContent(ctx->lastAsText->GetContent() +
+                                    CharToString(buf));
+    }
+    else
+    {
+        bool whiteOnly = TRUE;
+        for (char *c = buf; *c != '\0'; c++)
+            if (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\r')
+            {
+                whiteOnly = FALSE;
+                break;
+            }
+        if (!whiteOnly)
+        {
+            ctx->lastAsText = new wxXmlNode(wxXML_TEXT_NODE, wxT("text"),
+                                            CharToString(buf));
+            ctx->node->AddChild(ctx->lastAsText);
+        }
+    }
+
+    delete[] buf;
+}
+
+static void CommentHnd(void *userData, const char *data)
+{
+    wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
+
+    if (ctx->node)
+    {
+        // VS: ctx->node == NULL happens if there is a comment before
+        //     the root element (e.g. wxDesigner's output). We ignore such
+        //     comments, no big deal...
+        ctx->node->AddChild(new wxXmlNode(wxXML_COMMENT_NODE,
+                            wxT("comment"), CharToString(data)));
+    }
+    ctx->lastAsText = NULL;
+}
+
+static void DefaultHnd(void *userData, const char *s, int len)
+{
+    // XML header:
+    if (len > 6 && memcmp(s, "<?xml ", 6) == 0)
+    {
+        wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
+
+        wxString buf = CharToString(s, (size_t)len);
+        int pos;
+        pos = buf.Find(wxT("encoding="));
+        if (pos != wxNOT_FOUND)
+            ctx->encoding = buf.Mid(pos + 10).BeforeFirst(buf[(size_t)pos+9]);
+        pos = buf.Find(wxT("version="));
+        if (pos != wxNOT_FOUND)
+            ctx->version = buf.Mid(pos + 9).BeforeFirst(buf[(size_t)pos+8]);
+    }
+}
+
+bool wxXmlIOHandlerExpat::Load(wxInputStream& stream, wxXmlDocument& doc)
+{
+    const size_t BUFSIZE = 1024;
+    char buf[BUFSIZE];
+    wxXmlParsingContext ctx;
+    bool done;
+    XML_Parser parser = XML_ParserCreate(NULL);
+
+    ctx.root = ctx.node = NULL;
+    XML_SetUserData(parser, (void*)&ctx);
+    XML_SetElementHandler(parser, StartElementHnd, EndElementHnd);
+    XML_SetCharacterDataHandler(parser, TextHnd);
+    XML_SetCommentHandler(parser, CommentHnd);
+    XML_SetDefaultHandler(parser, DefaultHnd);
+
+    do
+    {
+        size_t len = stream.Read(buf, BUFSIZE).LastRead();
+        done = (len < BUFSIZE);
+        if (!XML_Parse(parser, buf, len, done))
+        {
+            wxLogError(_("XML parsing error: '%s' at line %d"),
+                       XML_ErrorString(XML_GetErrorCode(parser)),
+                       XML_GetCurrentLineNumber(parser));
+          return FALSE;
+        }
+    } while (!done);
+
+    doc.SetVersion(ctx.version);
+    doc.SetEncoding(ctx.encoding);
+    doc.SetRoot(ctx.root);
+
+    XML_ParserFree(parser);
+    return TRUE;
+}
diff --git a/contrib/src/xrc/xmlres.cpp b/contrib/src/xrc/xmlres.cpp
new file mode 100644 (file)
index 0000000..6e59b5a
--- /dev/null
@@ -0,0 +1,1001 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xmlres.cpp
+// Purpose:     XML resources
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "xmlres.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/dialog.h"
+#include "wx/panel.h"
+#include "wx/frame.h"
+#include "wx/wfstream.h"
+#include "wx/filesys.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+#include "wx/tokenzr.h"
+#include "wx/fontenum.h"
+#include "wx/module.h"
+#include "wx/bitmap.h"
+#include "wx/image.h"
+#include "wx/fontmap.h"
+
+#include "wx/xrc/xml.h"
+#include "wx/xrc/xmlres.h"
+
+#include "wx/arrimpl.cpp"
+WX_DEFINE_OBJARRAY(wxXmlResourceDataRecords);
+
+
+wxXmlResource::wxXmlResource(bool use_locale)
+{
+    m_handlers.DeleteContents(TRUE);
+    m_useLocale = use_locale;
+    m_version = -1;
+}
+
+wxXmlResource::wxXmlResource(const wxString& filemask, bool use_locale)
+{
+    m_useLocale = use_locale;
+    m_version = -1;
+    m_handlers.DeleteContents(TRUE);
+    Load(filemask);
+}
+
+wxXmlResource::~wxXmlResource()
+{
+    ClearHandlers();
+}
+
+
+bool wxXmlResource::Load(const wxString& filemask)
+{
+    wxString fnd;
+    wxXmlResourceDataRecord *drec;
+    bool iswild = wxIsWild(filemask);
+    bool rt = TRUE;
+
+#if wxUSE_FILESYSTEM
+    wxFileSystem fsys;
+#   define wxXmlFindFirst  fsys.FindFirst(filemask, wxFILE)
+#   define wxXmlFindNext   fsys.FindNext()
+#else
+#   define wxXmlFindFirst  wxFindFirstFile(filemask, wxFILE)
+#   define wxXmlFindNext   wxFindNextFile()
+#endif
+    if (iswild)
+        fnd = wxXmlFindFirst;
+    else
+        fnd = filemask;
+    while (!!fnd)
+    {
+#if wxUSE_FILESYSTEM
+        if (filemask.Lower().Matches("*.zip") ||
+            filemask.Lower().Matches("*.rsc"))
+        {
+            rt = rt && Load(fnd + wxT("#zip:*.xmb"));
+            rt = rt && Load(fnd + wxT("#zip:*.xrc"));
+        }
+        else
+#endif
+        {
+            drec = new wxXmlResourceDataRecord;
+            drec->File = fnd;
+            m_data.Add(drec);
+        }
+
+        if (iswild)
+            fnd = wxXmlFindNext;
+        else
+            fnd = wxEmptyString;
+    }
+#   undef wxXmlFindFirst
+#   undef wxXmlFindNext
+    return rt;
+}
+
+
+
+void wxXmlResource::AddHandler(wxXmlResourceHandler *handler)
+{
+    m_handlers.Append(handler);
+    handler->SetParentResource(this);
+}
+
+
+
+void wxXmlResource::ClearHandlers()
+{
+    m_handlers.Clear();
+}
+
+
+
+wxMenu *wxXmlResource::LoadMenu(const wxString& name)
+{
+    return (wxMenu*)CreateResFromNode(FindResource(name, wxT("wxMenu")), NULL, NULL);
+}
+
+
+
+wxMenuBar *wxXmlResource::LoadMenuBar(const wxString& name)
+{
+    return (wxMenuBar*)CreateResFromNode(FindResource(name, wxT("wxMenuBar")), NULL, NULL);
+}
+
+
+
+wxToolBar *wxXmlResource::LoadToolBar(wxWindow *parent, const wxString& name)
+{
+    return (wxToolBar*)CreateResFromNode(FindResource(name, wxT("wxToolBar")), parent, NULL);
+}
+
+
+
+wxDialog *wxXmlResource::LoadDialog(wxWindow *parent, const wxString& name)
+{
+    wxDialog *dialog = new wxDialog;
+    if (!LoadDialog(dialog, parent, name))
+        { delete dialog; return NULL; }
+    else return dialog;
+}
+
+bool wxXmlResource::LoadDialog(wxDialog *dlg, wxWindow *parent, const wxString& name)
+{
+    return CreateResFromNode(FindResource(name, wxT("wxDialog")), parent, dlg) != NULL;
+}
+
+
+
+wxPanel *wxXmlResource::LoadPanel(wxWindow *parent, const wxString& name)
+{
+    return (wxPanel*)CreateResFromNode(FindResource(name, wxT("wxPanel")), parent, NULL);
+}
+
+bool wxXmlResource::LoadPanel(wxPanel *panel, wxWindow *parent, const wxString& name)
+{
+    return CreateResFromNode(FindResource(name, wxT("wxPanel")), parent, panel) != NULL;
+}
+
+bool wxXmlResource::LoadFrame(wxFrame* frame, wxWindow *parent, const wxString& name)
+{
+    return CreateResFromNode(FindResource(name, wxT("wxFrame")), parent, frame) != NULL;
+}
+
+wxBitmap wxXmlResource::LoadBitmap(const wxString& name)
+{
+    wxBitmap *bmp = (wxBitmap*)CreateResFromNode(
+                               FindResource(name, wxT("wxBitmap")), NULL, NULL);
+    wxBitmap rt;
+
+    if (bmp) { rt = *bmp; delete bmp; }
+    return rt;
+}
+
+wxIcon wxXmlResource::LoadIcon(const wxString& name)
+{
+    wxIcon *icon = (wxIcon*)CreateResFromNode(
+                            FindResource(name, wxT("wxIcon")), NULL, NULL);
+    wxIcon rt;
+
+    if (icon) { rt = *icon; delete icon; }
+    return rt;
+}
+
+bool wxXmlResource::AttachUnknownControl(const wxString& name,
+                                         wxWindow *control, wxWindow *parent)
+{
+    if (parent == NULL)
+        parent = control->GetParent();
+    wxWindow *container = parent->FindWindow(name + wxT("_container"));
+    if (!container)
+    {
+        wxLogError(_("Cannot find container for unknown control '%s'."), name.c_str());
+        return FALSE;
+    }
+    return control->Reparent(container);
+}
+
+
+void wxXmlResource::ProcessPlatformProperty(wxXmlNode *node)
+{
+    wxString s;
+    bool isok;
+
+    wxXmlNode *c = node->GetChildren();
+    while (c)
+    {
+        isok = FALSE;
+        if (!c->GetPropVal(wxT("platform"), &s))
+            isok = TRUE;
+        else
+        {
+            wxStringTokenizer tkn(s, " |");
+
+            while (tkn.HasMoreTokens())
+            {
+                s = tkn.GetNextToken();
+                if (
+#ifdef __WXMSW__
+                    s == wxString(wxT("win"))
+#elif defined(__UNIX__)
+                    s == wxString(wxT("unix"))
+#elif defined(__MAC__)
+                    s == wxString(wxT("mac"))
+#elif defined(__OS2__)
+                    s == wxString(wxT("os2"))
+#else
+                    FALSE
+#endif
+              ) isok = TRUE;
+            }
+        }
+
+        if (isok)
+            ProcessPlatformProperty(c);
+        else
+        {
+            node->RemoveChild(c);
+            delete c;
+        }
+
+        c = c->GetNext();
+    }
+}
+
+
+
+void wxXmlResource::UpdateResources()
+{
+    bool modif;
+#   if wxUSE_FILESYSTEM
+    wxFSFile *file = NULL;
+    wxFileSystem fsys;
+#   endif
+
+    for (size_t i = 0; i < m_data.GetCount(); i++)
+    {
+        modif = (m_data[i].Doc == NULL);
+
+        if (!modif)
+        {
+#           if wxUSE_FILESYSTEM
+            file = fsys.OpenFile(m_data[i].File);
+            modif = file && file->GetModificationTime() > m_data[i].Time;
+            if (!file)
+                wxLogError(_("Cannot open file '%s'."), m_data[i].File.c_str());
+            wxDELETE(file);
+#           else
+            modif = wxDateTime(wxFileModificationTime(m_data[i].File)) > m_data[i].Time;
+#           endif
+        }
+
+        if (modif)
+        {
+                       wxInputStream *stream = NULL;
+
+#           if wxUSE_FILESYSTEM
+            file = fsys.OpenFile(m_data[i].File);
+                       if (file)
+                               stream = file->GetStream();
+#           else
+            stream = new wxFileInputStream(m_data[i].File);
+#           endif
+
+            if (stream)
+            {
+                delete m_data[i].Doc;
+                m_data[i].Doc = new wxXmlDocument;
+            }
+            if (!stream || !m_data[i].Doc->Load(*stream))
+            {
+                wxLogError(_("Cannot load resources from file '%s'."), m_data[i].File.c_str());
+                wxDELETE(m_data[i].Doc);
+            }
+            else if (m_data[i].Doc->GetRoot()->GetName() != wxT("resource"))
+            {
+                wxLogError(_("Invalid XML resource '%s': doesn't have root node 'resource'."), m_data[i].File.c_str());
+                wxDELETE(m_data[i].Doc);
+            }
+            else
+                       {
+                long version;
+                int v1, v2, v3, v4;
+                wxString verstr = m_data[i].Doc->GetRoot()->GetPropVal(
+                                      wxT("version"), wxT("0.0.0.0"));
+                if (wxSscanf(verstr.c_str(), wxT("%i.%i.%i.%i"),
+                    &v1, &v2, &v3, &v4) == 4)
+                    version = v1*256*256*256+v2*256*256+v3*256+v4;
+                else
+                    version = 0;
+                if (m_version == -1)
+                    m_version = version;
+                if (m_version != version)
+                    wxLogError(_("Resource files must have same version number!"));
+
+                ProcessPlatformProperty(m_data[i].Doc->GetRoot());
+                               m_data[i].Time = file->GetModificationTime();
+                       }
+
+#           if wxUSE_FILESYSTEM
+                               wxDELETE(file);
+#           else
+                               wxDELETE(stream);
+#           endif
+        }
+    }
+}
+
+
+
+wxXmlNode *wxXmlResource::FindResource(const wxString& name, const wxString& classname)
+{
+    UpdateResources(); //ensure everything is up-to-date
+
+    wxString dummy;
+    for (size_t f = 0; f < m_data.GetCount(); f++)
+    {
+        if (m_data[f].Doc == NULL || m_data[f].Doc->GetRoot() == NULL) continue;
+        for (wxXmlNode *node = m_data[f].Doc->GetRoot()->GetChildren();
+                                      node; node = node->GetNext())
+            if (node->GetType() == wxXML_ELEMENT_NODE &&
+                (!classname ||
+                  node->GetPropVal(wxT("class"), wxEmptyString) == classname) &&
+                node->GetName() == wxT("object") &&
+                node->GetPropVal(wxT("name"), &dummy) &&
+                dummy == name)
+            {
+#if wxUSE_FILESYSTEM
+                m_curFileSystem.ChangePathTo(m_data[f].File);
+#endif
+                return node;
+            }
+    }
+
+    wxLogError(_("XML resource '%s' (class '%s') not found!"),
+               name.c_str(), classname.c_str());
+    return NULL;
+}
+
+
+
+wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wxObject *instance)
+{
+    if (node == NULL) return NULL;
+
+    wxXmlResourceHandler *handler;
+    wxObject *ret;
+    wxNode * ND = m_handlers.GetFirst();
+    while (ND)
+    {
+        handler = (wxXmlResourceHandler*)ND->GetData();
+        if (node->GetName() == wxT("object") && handler->CanHandle(node))
+        {
+            ret = handler->CreateResource(node, parent, instance);
+            if (ret) return ret;
+        }
+        ND = ND->GetNext();
+    }
+
+    wxLogError(_("No handler found for XML node '%s', class '%s'!"),
+               node->GetName().c_str(),
+               node->GetPropVal(wxT("class"), wxEmptyString).c_str());
+    return NULL;
+}
+
+
+
+
+
+
+
+
+
+wxXmlResourceHandler::wxXmlResourceHandler()
+        : m_node(NULL), m_parent(NULL), m_instance(NULL),
+          m_parentAsWindow(NULL), m_instanceAsWindow(NULL)
+{}
+
+
+
+wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent, wxObject *instance)
+{
+    wxXmlNode *myNode = m_node;
+    wxString myClass = m_class;
+    wxObject *myParent = m_parent, *myInstance = m_instance;
+    wxWindow *myParentAW = m_parentAsWindow, *myInstanceAW = m_instanceAsWindow;
+
+    m_node = node;
+    m_class = node->GetPropVal(wxT("class"), wxEmptyString);
+    m_parent = parent;
+    m_instance = instance;
+    m_parentAsWindow = wxDynamicCast(m_parent, wxWindow);
+    m_instanceAsWindow = wxDynamicCast(m_instance, wxWindow);
+
+    wxObject *returned = DoCreateResource();
+
+    m_node = myNode;
+    m_class = myClass;
+    m_parent = myParent; m_parentAsWindow = myParentAW;
+    m_instance = myInstance; m_instanceAsWindow = myInstanceAW;
+
+    return returned;
+}
+
+
+void wxXmlResourceHandler::AddStyle(const wxString& name, int value)
+{
+    m_styleNames.Add(name);
+    m_styleValues.Add(value);
+}
+
+
+
+void wxXmlResourceHandler::AddWindowStyles()
+{
+    ADD_STYLE(wxSIMPLE_BORDER);
+    ADD_STYLE(wxSUNKEN_BORDER);
+    ADD_STYLE(wxDOUBLE_BORDER);
+    ADD_STYLE(wxRAISED_BORDER);
+    ADD_STYLE(wxSTATIC_BORDER);
+    ADD_STYLE(wxNO_BORDER);
+    ADD_STYLE(wxTRANSPARENT_WINDOW);
+    ADD_STYLE(wxWANTS_CHARS);
+    ADD_STYLE(wxNO_FULL_REPAINT_ON_RESIZE);
+}
+
+
+
+bool wxXmlResourceHandler::HasParam(const wxString& param)
+{
+    return (GetParamNode(param) != NULL);
+}
+
+
+int wxXmlResourceHandler::GetStyle(const wxString& param, int defaults)
+{
+    wxString s = GetParamValue(param);
+
+    if (!s) return defaults;
+
+    wxStringTokenizer tkn(s, wxT("| "), wxTOKEN_STRTOK);
+    int style = 0;
+    int index;
+    wxString fl;
+    while (tkn.HasMoreTokens())
+    {
+        fl = tkn.GetNextToken();
+        index = m_styleNames.Index(fl);
+        if (index != wxNOT_FOUND)
+            style |= m_styleValues[index];
+        else
+            wxLogError(_("Unknown style flag ") + fl);
+    }
+    return style;
+}
+
+
+
+wxString wxXmlResourceHandler::GetText(const wxString& param)
+{
+    wxString str1 = GetParamValue(param);
+    wxString str2;
+    const wxChar *dt;
+    wxChar amp_char;
+
+    // VS: First version of XML resources used $ instead of & (which is illegal in XML),
+    //     but later I realized that '_' fits this purpose much better (because
+    //     &File means "File with F underlined").
+    if (m_resource->CompareVersion(2,3,0,1) < 0)
+        amp_char = wxT('$');
+    else
+        amp_char = wxT('_');
+
+    for (dt = str1.c_str(); *dt; dt++)
+    {
+        // Remap amp_char to &, map double amp_char to amp_char (for things
+        // like "&File..." -- this is illegal in XML, so we use "_File..."):
+        if (*dt == amp_char)
+        {
+            if ( *(++dt) == amp_char )
+                str2 << amp_char;
+            else
+                str2 << wxT('&') << *dt;
+        }
+        // Remap \n to CR, \r to LF, \t to TAB:
+        else if (*dt == wxT('\\'))
+            switch (*(++dt))
+            {
+                case wxT('n') : str2 << wxT('\n'); break;
+                case wxT('t') : str2 << wxT('\t'); break;
+                case wxT('r') : str2 << wxT('\r'); break;
+                default       : str2 << wxT('\\') << *dt; break;
+            }
+        else str2 << *dt;
+    }
+
+    if (m_resource->GetUseLocale())
+        return wxGetTranslation(str2);
+    else
+        return str2;
+}
+
+
+
+long wxXmlResourceHandler::GetLong(const wxString& param, long defaultv)
+{
+    long value;
+    wxString str1 = GetParamValue(param);
+
+    if (!str1.ToLong(&value))
+        value = defaultv;
+
+    return value;
+}
+
+
+int wxXmlResourceHandler::GetID()
+{
+    wxString sid = GetName();
+    long num;
+
+    if (sid == wxT("-1")) return -1;
+    else if (sid.IsNumber() && sid.ToLong(&num)) return num;
+#define stdID(id) else if (sid == wxT(#id)) return id
+    stdID(wxID_OPEN); stdID(wxID_CLOSE); stdID(wxID_NEW);
+    stdID(wxID_SAVE); stdID(wxID_SAVEAS); stdID(wxID_REVERT);
+    stdID(wxID_EXIT); stdID(wxID_UNDO); stdID(wxID_REDO);
+    stdID(wxID_HELP); stdID(wxID_PRINT); stdID(wxID_PRINT_SETUP);
+    stdID(wxID_PREVIEW); stdID(wxID_ABOUT); stdID(wxID_HELP_CONTENTS);
+    stdID(wxID_HELP_COMMANDS); stdID(wxID_HELP_PROCEDURES);
+    stdID(wxID_CUT); stdID(wxID_COPY); stdID(wxID_PASTE);
+    stdID(wxID_CLEAR); stdID(wxID_FIND); stdID(wxID_DUPLICATE);
+    stdID(wxID_SELECTALL); stdID(wxID_OK); stdID(wxID_CANCEL);
+    stdID(wxID_APPLY); stdID(wxID_YES); stdID(wxID_NO);
+    stdID(wxID_STATIC); stdID(wxID_FORWARD); stdID(wxID_BACKWARD);
+    stdID(wxID_DEFAULT); stdID(wxID_MORE); stdID(wxID_SETUP);
+    stdID(wxID_RESET); stdID(wxID_HELP_CONTEXT);
+#undef stdID
+    else return XMLID(sid.c_str());
+}
+
+
+wxString wxXmlResourceHandler::GetName()
+{
+    return m_node->GetPropVal(wxT("name"), wxT("-1"));
+}
+
+
+
+bool wxXmlResourceHandler::GetBool(const wxString& param, bool defaultv)
+{
+    wxString v = GetParamValue(param);
+    v.MakeLower();
+    if (!v) return defaultv;
+    else return (v == wxT("1"));
+}
+
+
+
+wxColour wxXmlResourceHandler::GetColour(const wxString& param)
+{
+    wxString v = GetParamValue(param);
+    unsigned long tmp = 0;
+
+    if (v.Length() != 7 || v[0u] != wxT('#') ||
+        wxSscanf(v.c_str(), wxT("#%lX"), &tmp) != 1)
+    {
+        wxLogError(_("XML resource: Incorrect colour specification '%s' for property '%s'."),
+                   v.c_str(), param.c_str());
+        return wxNullColour;
+    }
+
+    return wxColour((unsigned char) ((tmp & 0xFF0000) >> 16) ,
+                    (unsigned char) ((tmp & 0x00FF00) >> 8),
+                    (unsigned char) ((tmp & 0x0000FF)));
+}
+
+
+
+wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, wxSize size)
+{
+    wxString name = GetParamValue(param);
+    if (name.IsEmpty()) return wxNullBitmap;
+#if wxUSE_FILESYSTEM
+    wxFSFile *fsfile = GetCurFileSystem().OpenFile(name);
+    if (fsfile == NULL)
+    {
+        wxLogError(_("XML resource: Cannot create bitmap from '%s'."), param.mb_str());
+        return wxNullBitmap;
+    }
+    wxImage img(*(fsfile->GetStream()));
+    delete fsfile;
+#else
+    wxImage img(GetParamValue(wxT("bitmap")));
+#endif
+    if (!img.Ok())
+    {
+        wxLogError(_("XML resource: Cannot create bitmap from '%s'."), param.mb_str());
+        return wxNullBitmap;
+    }
+    if (!(size == wxDefaultSize)) img.Rescale(size.x, size.y);
+    return img.ConvertToBitmap();
+}
+
+
+
+wxIcon wxXmlResourceHandler::GetIcon(const wxString& param, wxSize size)
+{
+#if wxCHECK_VERSION(2,3,0) || defined(__WXMSW__)
+    wxIcon icon;
+    icon.CopyFromBitmap(GetBitmap(param, size));
+#else
+    wxIcon *iconpt;
+    wxBitmap bmppt = GetBitmap(param, size);
+    iconpt = (wxIcon*)(&bmppt);
+    wxIcon icon(*iconpt);
+#endif
+    return icon;
+}
+
+
+
+wxXmlNode *wxXmlResourceHandler::GetParamNode(const wxString& param)
+{
+    wxXmlNode *n = m_node->GetChildren();
+
+    while (n)
+    {
+        if (n->GetType() == wxXML_ELEMENT_NODE && n->GetName() == param)
+            return n;
+        n = n->GetNext();
+    }
+    return NULL;
+}
+
+
+wxString wxXmlResourceHandler::GetNodeContent(wxXmlNode *node)
+{
+    wxXmlNode *n = node;
+    if (n == NULL) return wxEmptyString;
+    n = n->GetChildren();
+
+    while (n)
+    {
+        if (n->GetType() == wxXML_TEXT_NODE ||
+            n->GetType() == wxXML_CDATA_SECTION_NODE)
+            return n->GetContent();
+        n = n->GetNext();
+    }
+    return wxEmptyString;
+}
+
+
+
+wxString wxXmlResourceHandler::GetParamValue(const wxString& param)
+{
+    if (param.IsEmpty())
+        return GetNodeContent(m_node);
+    else
+        return GetNodeContent(GetParamNode(param));
+}
+
+
+
+wxSize wxXmlResourceHandler::GetSize(const wxString& param)
+{
+    wxString s = GetParamValue(param);
+    if (s.IsEmpty()) s = wxT("-1,-1");
+    bool is_dlg;
+    long sx, sy;
+
+    is_dlg = s[s.Length()-1] == wxT('d');
+    if (is_dlg) s.RemoveLast();
+
+    if (!s.BeforeFirst(wxT(',')).ToLong(&sx) ||
+        !s.AfterLast(wxT(',')).ToLong(&sy))
+    {
+        wxLogError(_("Cannot parse coordinates from '%s'."), s.mb_str());
+        return wxDefaultSize;
+    }
+
+    if (is_dlg)
+    {
+        if (m_instanceAsWindow)
+            return wxDLG_UNIT(m_instanceAsWindow, wxSize(sx, sy));
+        else if (m_parentAsWindow)
+            return wxDLG_UNIT(m_parentAsWindow, wxSize(sx, sy));
+        else
+        {
+            wxLogError(_("Cannot convert dialog units: dialog unknown."));
+            return wxDefaultSize;
+        }
+    }
+    else return wxSize(sx, sy);
+}
+
+
+
+wxPoint wxXmlResourceHandler::GetPosition(const wxString& param)
+{
+    wxSize sz = GetSize(param);
+    return wxPoint(sz.x, sz.y);
+}
+
+
+
+wxCoord wxXmlResourceHandler::GetDimension(const wxString& param, wxCoord defaultv)
+{
+    wxString s = GetParamValue(param);
+    if (s.IsEmpty()) return defaultv;
+    bool is_dlg;
+    long sx;
+
+    is_dlg = s[s.Length()-1] == wxT('d');
+    if (is_dlg) s.RemoveLast();
+
+    if (!s.ToLong(&sx))
+    {
+        wxLogError(_("Cannot parse dimension from '%s'."), s.mb_str());
+        return defaultv;
+    }
+
+    if (is_dlg)
+    {
+        if (m_instanceAsWindow)
+            return wxDLG_UNIT(m_instanceAsWindow, wxSize(sx, 0)).x;
+        else if (m_parentAsWindow)
+            return wxDLG_UNIT(m_parentAsWindow, wxSize(sx, 0)).x;
+        else
+        {
+            wxLogError(_("Cannot convert dialog units: dialog unknown."));
+            return defaultv;
+        }
+    }
+    else return sx;
+}
+
+
+
+wxFont wxXmlResourceHandler::GetFont(const wxString& param)
+{
+    wxXmlNode *font_node = GetParamNode(param);
+    if (font_node == NULL)
+    {
+        wxLogError(_("Cannot find font node '%s'."), param.mb_str());
+        return wxNullFont;
+    }
+
+    wxXmlNode *oldnode = m_node;
+    m_node = font_node;
+
+    long size = GetLong(wxT("size"), 12);
+
+    wxString style = GetParamValue(wxT("style"));
+    wxString weight = GetParamValue(wxT("weight"));
+    int istyle = wxNORMAL, iweight = wxNORMAL;
+    if (style == wxT("italic")) istyle = wxITALIC;
+    else if (style == wxT("slant")) istyle = wxSLANT;
+    if (weight == wxT("bold")) iweight = wxBOLD;
+    else if (weight == wxT("light")) iweight = wxLIGHT;
+
+    wxString family = GetParamValue(wxT("family"));
+    int ifamily = wxDEFAULT;
+         if (family == wxT("decorative")) ifamily = wxDECORATIVE;
+    else if (family == wxT("roman")) ifamily = wxROMAN;
+    else if (family == wxT("script")) ifamily = wxSCRIPT;
+    else if (family == wxT("swiss")) ifamily = wxSWISS;
+    else if (family == wxT("modern")) ifamily = wxMODERN;
+
+    bool underlined = GetBool(wxT("underlined"), FALSE);
+
+    wxString encoding = GetParamValue(wxT("encoding"));
+    wxFontMapper mapper;
+    wxFontEncoding enc = wxFONTENCODING_DEFAULT;
+    if (!encoding.IsEmpty()) enc = mapper.CharsetToEncoding(encoding);
+    if (enc == wxFONTENCODING_SYSTEM) enc = wxFONTENCODING_SYSTEM;
+
+    wxString faces = GetParamValue(wxT("face"));
+    wxString facename = wxEmptyString;
+    wxFontEnumerator enu;
+    enu.EnumerateFacenames();
+    wxStringTokenizer tk(faces, wxT(","));
+    while (tk.HasMoreTokens())
+    {
+        int index = enu.GetFacenames()->Index(tk.GetNextToken(), FALSE);
+        if (index != wxNOT_FOUND)
+        {
+            facename = (*enu.GetFacenames())[index];
+            break;
+        }
+    }
+
+    m_node = oldnode;
+
+    wxFont font(size, ifamily, istyle, iweight, underlined, facename, enc);
+    return font;
+}
+
+
+void wxXmlResourceHandler::SetupWindow(wxWindow *wnd)
+{
+    //FIXME : add cursor
+
+    if (HasParam(wxT("exstyle")))
+        wnd->SetExtraStyle(GetStyle(wxT("exstyle")));
+    if (HasParam(wxT("bg")))
+        wnd->SetBackgroundColour(GetColour(wxT("bg")));
+    if (HasParam(wxT("fg")))
+        wnd->SetForegroundColour(GetColour(wxT("fg")));
+    if (GetBool(wxT("enabled"), 1) == 0)
+        wnd->Enable(FALSE);
+    if (GetBool(wxT("focused"), 0) == 1)
+        wnd->SetFocus();
+    if (GetBool(wxT("hidden"), 0) == 1)
+        wnd->Show(FALSE);
+#if wxUSE_TOOLTIPS
+    if (HasParam(wxT("tooltip")))
+        wnd->SetToolTip(GetText(wxT("tooltip")));
+#endif
+    if (HasParam(wxT("font")))
+        wnd->SetFont(GetFont());
+}
+
+
+void wxXmlResourceHandler::CreateChildren(wxObject *parent, bool this_hnd_only)
+{
+    wxXmlNode *n = m_node->GetChildren();
+
+    while (n)
+    {
+        if (n->GetType() == wxXML_ELEMENT_NODE &&
+            n->GetName() == wxT("object"))
+        {
+            if (this_hnd_only && CanHandle(n))
+                CreateResource(n, parent, NULL);
+            else
+                m_resource->CreateResFromNode(n, parent, NULL);
+        }
+        n = n->GetNext();
+    }
+}
+
+
+void wxXmlResourceHandler::CreateChildrenPrivately(wxObject *parent, wxXmlNode *rootnode)
+{
+    wxXmlNode *root;
+    if (rootnode == NULL) root = m_node; else root = rootnode;
+    wxXmlNode *n = root->GetChildren();
+
+    while (n)
+    {
+        if (n->GetType() == wxXML_ELEMENT_NODE && CanHandle(n))
+        {
+            CreateResource(n, parent, NULL);
+        }
+        n = n->GetNext();
+    }
+}
+
+
+
+
+
+
+
+// --------------- XMLID implementation -----------------------------
+
+#define XMLID_TABLE_SIZE     1024
+
+
+struct XMLID_record
+{
+    int id;
+    char *key;
+    XMLID_record *next;
+};
+
+static XMLID_record *XMLID_Records[XMLID_TABLE_SIZE] = {NULL};
+
+/*static*/ int wxXmlResource::GetXMLID(const char *str_id)
+{
+    static int XMLID_LastID = wxID_HIGHEST;
+
+    int index = 0;
+
+    for (const char *c = str_id; *c != '\0'; c++) index += (int)*c;
+    index %= XMLID_TABLE_SIZE;
+
+    XMLID_record *oldrec = NULL;
+    int matchcnt = 0;
+    for (XMLID_record *rec = XMLID_Records[index]; rec; rec = rec->next)
+    {
+        if (strcmp(rec->key, str_id) == 0)
+        {
+            return rec->id;
+        }
+        matchcnt++;
+        oldrec = rec;
+    }
+
+    XMLID_record **rec_var = (oldrec == NULL) ?
+                              &XMLID_Records[index] : &oldrec->next;
+    *rec_var = new XMLID_record;
+    (*rec_var)->id = ++XMLID_LastID;
+    (*rec_var)->key = strdup(str_id);
+    (*rec_var)->next = NULL;
+
+    return (*rec_var)->id;
+}
+
+
+static void CleanXMLID_Record(XMLID_record *rec)
+{
+    if (rec)
+    {
+        CleanXMLID_Record(rec->next);
+        free (rec->key);
+        delete rec;
+    }
+}
+
+static void CleanXMLID_Records()
+{
+    for (int i = 0; i < XMLID_TABLE_SIZE; i++)
+        CleanXMLID_Record(XMLID_Records[i]);
+}
+
+
+
+
+
+
+
+
+// --------------- module and globals -----------------------------
+
+
+static wxXmlResource gs_XmlResource;
+
+wxXmlResource *wxTheXmlResource = &gs_XmlResource;
+
+
+class wxXmlResourceModule: public wxModule
+{
+DECLARE_DYNAMIC_CLASS(wxXmlResourceModule)
+public:
+    wxXmlResourceModule() {}
+    bool OnInit() {return TRUE;}
+    void OnExit()
+    {
+        wxTheXmlResource->ClearHandlers();
+        CleanXMLID_Records();
+    }
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxXmlResourceModule, wxModule)
+
+
+// When wxXml is loaded dynamically after the application is already running
+// then the built-in module system won't pick this one up.  Add it manually.
+void wxXmlInitResourceModule()
+{
+    wxModule* module = new wxXmlResourceModule;
+    module->Init();
+    wxModule::RegisterModule(module);
+}
+
+
diff --git a/contrib/src/xrc/xmlrsall.cpp b/contrib/src/xrc/xmlrsall.cpp
new file mode 100644 (file)
index 0000000..6f4a503
--- /dev/null
@@ -0,0 +1,97 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xmlrsall.cpp
+// Purpose:     wxXmlResource::InitAllHandlers
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+// -- Already done in xmlres.cpp
+//#ifdef __GNUG__
+//#pragma implementation "xmlres.h"
+//#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xmlres.h"
+#include "wx/xrc/xh_all.h"
+
+void wxXmlResource::InitAllHandlers()
+{
+    AddHandler(new wxBitmapXmlHandler);
+    AddHandler(new wxIconXmlHandler);
+    AddHandler(new wxMenuXmlHandler);
+    AddHandler(new wxMenuBarXmlHandler);
+
+    AddHandler(new wxDialogXmlHandler);
+    AddHandler(new wxPanelXmlHandler);
+
+    AddHandler(new wxSizerXmlHandler);
+//Controls
+    AddHandler(new wxButtonXmlHandler);
+    AddHandler(new wxBitmapButtonXmlHandler);
+    AddHandler(new wxStaticTextXmlHandler);
+    AddHandler(new wxStaticBoxXmlHandler);
+    AddHandler(new wxStaticBitmapXmlHandler);
+    AddHandler(new wxTreeCtrlXmlHandler);
+    AddHandler(new wxCalendarCtrlXmlHandler);
+    AddHandler(new wxListCtrlXmlHandler);
+#if CHECKLISTBOX
+    AddHandler(new wxCheckListXmlHandler);
+#endif
+#if wxUSE_CHOICE
+    AddHandler(new wxChoiceXmlHandler);
+#endif
+#if wxUSE_SLIDER
+    AddHandler(new wxSliderXmlHandler);
+#endif
+#if wxUSE_GAUGE
+    AddHandler(new wxGaugeXmlHandler);
+#endif
+#if wxUSE_CHECKBOX
+    AddHandler(new wxCheckBoxXmlHandler);
+#endif    
+#if wxUSE_HTML
+    AddHandler(new wxHtmlWindowXmlHandler);
+#endif    
+#if wxUSE_SPINBTN
+    AddHandler(new wxSpinButtonXmlHandler);
+#endif    
+#if wxUSE_SPINCTRL
+    AddHandler(new wxSpinCtrlXmlHandler);
+#endif    
+#if wxUSE_SCROLLBAR
+    AddHandler(new wxScrollBarXmlHandler);
+#endif
+    
+#if wxUSE_RADIOBOX
+    AddHandler(new wxRadioBoxXmlHandler);
+    AddHandler(new wxRadioButtonXmlHandler);
+#endif
+#if wxUSE_COMBOBOX
+    AddHandler(new wxComboBoxXmlHandler);
+#endif
+#if wxUSE_NOTEBOOK
+    AddHandler(new wxNotebookXmlHandler);
+#endif
+    AddHandler(new wxTextCtrlXmlHandler);
+#if wxUSE_LISTBOX
+    AddHandler(new wxListBoxXmlHandler);
+#endif
+#if wxUSE_TOOLBAR
+    AddHandler(new wxToolBarXmlHandler);
+#endif
+#if wxUSE_STATLINE
+    AddHandler(new wxStaticLineXmlHandler);
+#endif
+    AddHandler(new wxUnknownWidgetXmlHandler);
+
+    AddHandler(new wxFrameXmlHandler);
+}
diff --git a/contrib/src/xrc/xmlwrite.cpp b/contrib/src/xrc/xmlwrite.cpp
new file mode 100644 (file)
index 0000000..482f976
--- /dev/null
@@ -0,0 +1,152 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xmlwrite.cpp
+// Purpose:     wxXmlDocument - XML text writer
+// Author:      Vaclav Slavik
+// Created:     2001/04/30
+// RCS-ID:      $Id$
+// Copyright:   (c) 2001 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+// nothing - already in xml.cpp
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/wfstream.h"
+#include "wx/intl.h"
+#include "wx/log.h"
+#include "wx/strconv.h"
+#include "wx/xrc/xml.h"
+#include "wx/xrc/xmlio.h"
+
+// write string to output:
+inline static void OutputString(wxOutputStream& stream, const wxString& str)
+{
+    if (str.IsEmpty()) return;
+#if wxUSE_UNICODE
+    char *buf = str.mb_str(wxMBConvUTF8);
+    stream.Write(buf, strlen(buf));
+#else
+    stream.Write(str.mb_str(), str.Len());        
+#endif
+}
+
+// Same as above, but create entities first. 
+// Translates '<' to "&lt;", '>' to "&gt;" and '&' to "&amp;"
+static void OutputStringEnt(wxOutputStream& stream, const wxString& str)
+{
+    wxString buf;
+    size_t i, last, len;
+    char c;
+    
+    len = str.Len();
+    last = 0;
+    for (i = 0; i < len; i++)
+    {
+        c = str.GetChar(i);
+        if (c == '<' || c == '>' || 
+            (c == '&' && str.Mid(i+1, 4) != wxT("amp;")))
+        {
+            OutputString(stream, str.Mid(last, i - last));
+            switch (c)
+            {
+                case '<': OutputString(stream, wxT("&lt;")); break;
+                case '>': OutputString(stream, wxT("&gt;")); break;
+                case '&': OutputString(stream, wxT("&amp;")); break;
+                default: break;
+            }
+            last = i + 1;
+        }
+    }
+    OutputString(stream, str.Mid(last, i - last));
+}
+
+inline static void OutputIndentation(wxOutputStream& stream, int indent)
+{
+    wxString str = wxT("\n");
+    for (int i = 0; i < indent; i++)
+        str << wxT(' ') << wxT(' ');
+    OutputString(stream, str);
+}
+
+static void OutputNode(wxOutputStream& stream, wxXmlNode *node, int indent)
+{
+    wxXmlNode *n, *prev;
+    wxXmlProperty *prop;
+
+    switch (node->GetType())
+    {
+        case wxXML_TEXT_NODE:
+            OutputStringEnt(stream, node->GetContent());
+            break;
+            
+        case wxXML_ELEMENT_NODE:
+            OutputString(stream, wxT("<"));
+            OutputString(stream, node->GetName());
+            
+            prop = node->GetProperties();
+            while (prop)
+            {
+                OutputString(stream, wxT(" ") + prop->GetName() +
+                             wxT("=\"") + prop->GetValue() + wxT("\""));
+                // FIXME - what if prop contains '"'?
+                prop = prop->GetNext();
+            }
+            
+            if (node->GetChildren())
+            {
+                OutputString(stream, wxT(">"));
+                prev = NULL;
+                n = node->GetChildren();
+                while (n)
+                {
+                    if (n && n->GetType() != wxXML_TEXT_NODE)
+                        OutputIndentation(stream, indent + 1);
+                    OutputNode(stream, n, indent + 1);
+                    prev = n;
+                    n = n->GetNext();
+                }
+                if (prev && prev->GetType() != wxXML_TEXT_NODE)
+                    OutputIndentation(stream, indent);
+                OutputString(stream, wxT("</"));
+                OutputString(stream, node->GetName());
+                OutputString(stream, wxT(">"));
+            }
+            else
+                OutputString(stream, wxT("/>"));
+            break;
+             
+        case wxXML_COMMENT_NODE:
+            OutputString(stream, wxT("<!--"));
+            OutputString(stream, node->GetContent());
+            OutputString(stream, wxT("-->"));
+            break;
+            
+        default:
+            wxFAIL_MSG(wxT("unsupported node type"));
+    }
+}
+
+bool wxXmlIOHandlerWriter::Save(wxOutputStream& stream, const wxXmlDocument& doc)
+{
+    if (!doc.IsOk())
+        return FALSE;
+        
+    wxString s;
+    
+    s = wxT("<?xml version=\"") + doc.GetVersion() + 
+        wxT("\" encoding=\"utf-8\"?>\n");
+    OutputString(stream, s);  
+    
+    OutputNode(stream, doc.GetRoot(), 0);
+    OutputString(stream, wxT("\n"));
+        
+    return TRUE;
+}
diff --git a/src/xrc/FORMAT.txt b/src/xrc/FORMAT.txt
new file mode 100644 (file)
index 0000000..6d93b5d
--- /dev/null
@@ -0,0 +1,324 @@
+
+                         XML resources file format
+                      ===============================
+                      
+ 1. Basics
+-----------
+
+XML resource is well-formed XML document, i.e. all tags are paired
+and there is only one root node, which is always <resource>.
+
+In the following text, I will use standard XML terminology:
+
+<tag_one prop1="prop" prop2='yes'>
+   <tag_two/>
+</tag_one>
+
+Here, tag_one is a node (the word 'tag' refers to the type of the node),
+prop1 and prop2 are properties and tag_two is a child node of tag_one.
+Property's default value is the value that will be assigned to the property
+if you do not specify it explicitly.
+
+I will use the term "primary node" to refer to nodes than represent controls,
+dialogs etc. "Secondary nodes" are nodes used to store data: 
+
+<dialog name="my_dlg">                primary
+  <title>Demo Dialog...</title>       secondary
+  <size>100,200d</size>               secondary
+  <children>                          secondary
+    <button name="wxID_OK">           primary
+      <label>Ok</label>               secondary
+      <pos>10,10d</pos>               secondary
+    </button>
+  </children>
+</dialog>
+
+In the example above, <label>, <pos>, <size> and <title> are "variables",
+i.e. they contain a value and not a list of children (unlike <children> node).
+
+Any node (but the root one) may have property "platform" with possible 
+values "unix", "win", "mac" or "os2". All nodes with "platform" property
+specified and other than the platform the program is currently being executed
+on will be removed when reading XML resource file.
+
+Root node may have children of these and only these types: <menu>, <menubar>,
+<dialog>, <panel>
+
+
+
+ 2. IDs
+--------
+
+Any primary node may have property "name" used to identify it. Default value
+is "-1", any string is legal name. Names 
+    wxID_OPEN, wxID_CLOSE, wxID_NEW,
+    wxID_SAVE, wxID_SAVEAS, wxID_REVERT, 
+    wxID_EXIT, wxID_UNDO, wxID_REDO,
+    wxID_HELP, wxID_PRINT, wxID_PRINT_SETUP, 
+    wxID_PREVIEW, wxID_ABOUT, wxID_HELP_CONTENTS,
+    wxID_HELP_COMMANDS, wxID_HELP_PROCEDURES,
+    wxID_CUT, wxID_COPY, wxID_PASTE,
+    wxID_CLEAR, wxID_FIND, wxID_DUPLICATE,
+    wxID_SELECTALL, wxID_OK, wxID_CANCEL,
+    wxID_APPLY, wxID_YES, wxID_NO,
+    wxID_STATIC, wxID_FORWARD, wxID_BACKWARD,
+    wxID_DEFAULT, wxID_MORE, wxID_SETUP,
+    wxID_RESET, wxID_HELP_CONTEXT
+are translated into corresponding wxWindows ID constant, XMLID macro is used
+otherwise to generate unique ID. wxWindows control created from named node
+will have name=name and id=XMLID(name) or wxID_XXXX.
+
+
+ 3. Common variables types
+--------------------------- 
+
+Variables are always of a known type:
+
+bool       - boolean value. "1", "true", "t", "on" mean TRUE, anything
+             else (namely "0", "false", "f", "off") means FALSE.
+             FIXME: maybe use only 1/0 ??
+             
+integer    - integer value, i.e. digits 0-9 plus optional minus sign.
+             
+text       - anything. Within text node all occurences of $ are replaced 
+             by & (used for shortcuts, e.g. "E&xit"), $$ by $, \\, \n, \r,
+             \t as usual in C++.
+
+style      - (also called flags) list of flags delimined by any combination 
+             of spaces and | characters. Resources parser accepts only 
+             _registered_ flags -- i.e. flags that are valid for given 
+             node/control. Example:
+                  <flag>wxEXPAND | wxTOP|wxBOTTOM</flag>
+                  
+color      - color in HTML format: #rrggbb where rr,gg,bb are hexadecimal 
+             values (00-FF) for red, green and blue components in 
+             the RGB color model
+             
+coord      - size or position information. Consists of two integers
+             separated by comma ("x,y"). The values are in pixels 
+             unless "d" is attached to the right side of it -- 
+             in which case the values are interpreted as dialog units.
+             Value of -1 means "use default". Examples: 
+                  30,30
+                  -1,-1
+                  50,-1
+                  145,56d
+                  67,-1d
+
+
+
+ 4. Layout
+----------- 
+
+Most common nodes layout is as follows:
+
+<primary_node name="name" platform="platform">
+    <var_1>...</var_1>
+    .
+    .
+    .
+    <var_n>...</var_n>
+    <children>
+        (n primary nodes)
+    </children>
+</primary_node>
+
+where children node is supported only by panels, dialogs etc. -- see 
+nodes description for details.
+
+In the following text, 
+
+   TYPE var_name [ (= default_value) ]
+   
+means that given primary node may have child node with name var_name
+and content type TYPE. If default value is given, the node is optional
+and default_value will be used if not specified. Otherwise, the node
+is mandatory and must always be present. For example, "color fg" means
+than variable tag fg, e.g. <fg>#rr0000</fg> is expected.
+
+
+
+ 5. Common controls variables
+------------------------------
+
+_All_ nodes that represent wxWindows controls (gauge, panel, dialog, 
+textctrl etc.) accept the following properties:
+
+coord   pos       (= -1,-1) position of the control. Default value 
+                  equals to wxDefaultPosition
+coord   size      (= -1,-1) size of the control. Default value equals to 
+                  wxDefaultSize
+text    tooltip   window's tooltip
+color   bg        background color of the control
+color   fg        foreground/text color of the control
+style   style     control style flag. Default value is 
+                  control-dependent (but 0 is common value)
+style   exstyle   control extended style flag
+bool    enabled   (= 1) is the control enabled?
+bool    hidden    (= 0) is the control hidden?
+bool    focused   (= 0) has the control focus?
+
+
+_Usually_ (but not always, only when it makes sense) controls support text
+variable label which contains displayed text and/or value which contains
+editable text. These are always explicitly mentioned in tag description.
+
+
+
+
+ 6. Tags description
+---------------------
+
+If 'Control' is derived from wxControl, it supports all variables from '5.'
+'Styles' section lists all acceptable flags for style and exstyle variables.
+
+
+ <panel>
+--------- 
+      Control:
+         wxPanel
+
+      Variables:
+         only common controls variables
+
+      Styles:
+         wxNO_3D, wxTAB_TRAVERSAL, wxWS_EX_VALIDATE_RECURSIVELY
+
+
+
+ <dialog>
+----------
+      Control:
+         wxDialog
+
+      Variables:
+         style    style     (= wxDEFAULT_DIALOG_style)
+         text     title     dialog's title         
+
+      Styles:
+         wxSTAY_ON_TOP, wxCAPTION, wxDEFAULT_DIALOG_style, wxTHICK_FRAME,
+         wxSYSTEM_MENU, wxRESIZE_BORDER, wxRESIZE_BOX, wxDIALOG_MODAL,
+         wxDIALOG_MODELESS, wxNO_3D, wxTAB_TRAVERSAL, 
+         wxWS_EX_VALIDATE_RECURSIVELY
+
+
+
+ <boxsizer>
+--------------
+      Control:
+         wxBoxSizer (not a control)
+
+      Behaviour:
+         boxsizer's parent must be either <panel>, <dialog> or another
+         sizer, nothing else!
+         
+         If the sizer does not have parent sizer, the sizer will attach itself
+         to the parent panel/dialog using SetAutoLayout(TRUE) and SetSizer().
+         If the parent panel/dialog has default size (i.e. not specified in
+         the resource), the sizer will fit it using wxSizer::Fit(). If the
+         parent panel/dialog is resizable, size hints will be set 
+         automatically.
+
+      Variables:
+         style    orient    (= wxHORIZONTAL) orientation, either 
+                            wxHORIZONTAL or wxVERTICAL
+
+      Styles:
+         wxHORIZONTAL, wxVERTICAL (for orient variable)
+
+         wxLEFT, wxRIGHT, wxTOP, wxBOTTOM, wxNORTH, wxSOUTH, wxEAST, wxWEST,
+         wxALL, wxGROW, wxEXPAND, wxSHAPED, wxSTRETCH_NOT, wxALIGN_CENTER,
+         wxALIGN_CENTRE, wxALIGN_LEFT, wxALIGN_TOP, wxALIGN_RIGHT, 
+         wxALIGN_BOTTOM, wxALIGN_CENTER_HORIZONTAL, wxALIGN_CENTRE_HORIZONTAL,
+         wxALIGN_CENTER_HORIZONTAL, wxALIGN_CENTRE_HORIZONTAL (for flag
+         variable of <item> or <spacer> child nodes)
+
+      Child nodes:
+         Contains child node <children> which has arbitrary number of
+         <sizeritem> and <spacer> child nodes.
+         
+          <sizeritem>
+         -------------
+            Variables:
+               integer  option    (= 0) relative size of the widget
+               style    flag      (= 0) style flag
+               integer  border    (= 0) surrounding border
+               
+            Has exactly one child node <window> that contains the control
+            (or child sizer because sizers may be nested) 
+            to be inserted into the sizer.
+
+          <spacer>
+         ----------
+            Variables:
+               integer  option    (= 0) relative size of the widget
+               style    flag      (= 0) style flag
+               integer  border    (= 0) surrounding border
+
+            Inserts empty space into the sizer
+            
+
+
+ <staticboxsizer>
+------------------
+      Control:
+         wxStaticBoxSizer (not a control)
+
+      Same as <boxsizer> except that it has additional variable:
+      
+               text     label     (= "") label of surrounding static box
+
+      wxStaticBox required by wxStaticBoxSizer is created automatically!
+
+
+
+ <notebooksizer>
+-----------------
+      Control:
+         wxNotebookSizer (not a control)
+
+      Behaviour:
+         notebooksizer's parent must be a sizer (not notebooksizer,
+         see below)!
+
+      Variables:
+         none
+
+      Styles:
+         none
+
+      Child nodes:
+         Has exactly one child node <window> that contains the notebook
+         (nothing else is allowed!) to be inserted into the sizer.
+
+
+
+ <textctrl>
+------------ 
+      Control:
+         wxTextCtrl
+
+      Variables:
+         text     value     (= "")default text of the control
+
+      Styles:
+         wxTE_PROCESS_ENTER, wxTE_PROCESS_TAB, wxTE_MULTILINE, wxTE_PASSWORD,
+         wxTE_READONLY, wxHSCROLL
+
+
+
+ <htmlwindow>
+--------------
+      Control:
+         wxHtmlWindow
+
+      Variables:
+         integer  borders   (= 0) window's borders 
+                            (see wxHtmlWindow::SetBorders)
+         text     url       (= "") if present, given page will be loaded
+         text     htmlcode  (= "") if present, given _text_ will be displayed                            
+                            (you will have to use CDATA section
+                            to embed HTML code into XML document)
+
+      Styles:
+         wxHW_SCROLLBAR_NEVER, wxHW_SCROLLBAR_AUTO
diff --git a/src/xrc/Makefile.in b/src/xrc/Makefile.in
new file mode 100644 (file)
index 0000000..0748bc4
--- /dev/null
@@ -0,0 +1,41 @@
+# $Id$
+
+top_srcdir = @top_srcdir@/..
+top_builddir = ../../..
+
+expat_dir = $(top_srcdir)/contrib/src/xrc/expat
+libsrc_dir = contrib/src/xrc@PATH_IFS@$(expat_dir)/xmlparse@PATH_IFS@$(expat_dir)/xmltok
+
+
+TARGET_LIBNAME=libwxxrc
+
+LIBVERSION_CURRENT=0
+LIBVERSION_REVISION=1
+LIBVERSION_AGE=0
+
+HEADER_PATH=$(top_srcdir)/contrib/include/wx
+HEADER_SUBDIR=xrc
+
+EXPAT_DEFS=-I$(expat_dir)/xmlparse -I$(expat_dir)/xmltok
+EXPAT_OBJECTS=xmltok.o xmlrole.o xmlparse.o
+
+HEADERS=xh_all.h xh_bttn.h xh_chckb.h xh_chckl.h xh_choic.h xh_combo.h \
+        xh_dlg.h xh_gauge.h xh_html.h xh_menu.h xh_notbk.h xh_panel.h \
+        xh_radbt.h xh_radbx.h xh_sizer.h xh_slidr.h xh_spin.h xh_stbmp.h \
+        xh_sttxt.h xh_text.h xh_listb.h xml.h xmlio.h xmlres.h xh_toolb.h \
+        xh_bmpbt.h xh_cald.h xh_listc.h xh_scrol.h xh_stbox.h xh_tree.h \
+        xh_stlin.h xh_bmp.h xh_unkwn.h xh_frame.h
+
+OBJECTS=$(EXPAT_OBJECTS) \
+        xml.o xmlbin.o xmlbinz.o xmlexpat.o xmlwrite.o xmlres.o xmlrsall.o \
+        xh_bttn.o xh_chckb.o xh_chckl.o xh_choic.o xh_combo.o xh_dlg.o \
+        xh_gauge.o xh_html.o xh_menu.o xh_notbk.o xh_panel.o xh_radbt.o \
+        xh_radbx.o xh_sizer.o xh_slidr.o xh_spin.o xh_stbmp.o xh_sttxt.o \
+        xh_text.o xh_listb.o xh_toolb.o xh_stlin.o xh_bmp.o xh_unkwn.o \
+        xh_bmpbt.o xh_cald.o xh_listc.o xh_scrol.o xh_stbox.o xh_tree.o \
+        xh_frame.o
+
+APPEXTRADEFS=-I$(top_srcdir)/contrib/include $(EXPAT_DEFS)
+
+include $(top_builddir)/src/makelib.env
+
diff --git a/src/xrc/README.EXPAT b/src/xrc/README.EXPAT
new file mode 100644 (file)
index 0000000..a85c615
--- /dev/null
@@ -0,0 +1,39 @@
+
+./expat directory contains stripped-down version of Expat parser distribution
+by J. Clark. I removed stuff not neccessary for wxXML (docs, samples), if you
+are interested in it, please download full distribution from Clark's site
+(http://www.jclark.com).
+
+Version used is expat-1.2.
+
+The Expat parser is available is licensed under the MIT license as follows:
+
+
+
+      Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+
+      Permission is hereby granted, free of charge, to any person obtaining
+      a copy of this software and associated documentation files (the
+      "Software"), to deal in the Software without restriction, including
+      without limitation the rights to use, copy, modify, merge, publish,
+      distribute, sublicense, and/or sell copies of the Software, and to
+      permit persons to whom the Software is furnished to do so, subject to
+      the following conditions:
+
+      The above copyright notice and this permission notice shall be included
+      in all copies or substantial portions of the Software.
+
+      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+      EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+      IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+      CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+      TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+      SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+In other words, there shouldn't be any legal issues with using Expat in
+your application.
+
+                         Vaclav Slavik <v.slavik@volny.cz>
diff --git a/src/xrc/expat/copying.txt b/src/xrc/expat/copying.txt
new file mode 100644 (file)
index 0000000..bf0f567
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/src/xrc/expat/xmlparse/xmlparse.c b/src/xrc/expat/xmlparse/xmlparse.c
new file mode 100644 (file)
index 0000000..d11a146
--- /dev/null
@@ -0,0 +1,3925 @@
+/*
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#include "xmldef.h"
+#include "xmlparse.h"
+#include <stddef.h>
+
+#ifdef XML_UNICODE
+#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
+#define XmlConvert XmlUtf16Convert
+#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
+#define XmlEncode XmlUtf16Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
+typedef unsigned short ICHAR;
+#else
+#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
+#define XmlConvert XmlUtf8Convert
+#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
+#define XmlEncode XmlUtf8Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
+typedef char ICHAR;
+#endif
+
+
+#ifndef XML_NS
+
+#define XmlInitEncodingNS XmlInitEncoding
+#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
+#undef XmlGetInternalEncodingNS
+#define XmlGetInternalEncodingNS XmlGetInternalEncoding
+#define XmlParseXmlDeclNS XmlParseXmlDecl
+
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_T(x) L ## x
+#else
+#define XML_T(x) x
+#endif
+
+/* Round up n to be a multiple of sz, where sz is a power of 2. */
+#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
+
+#include "xmltok.h"
+#include "xmlrole.h"
+
+typedef const XML_Char *KEY;
+
+typedef struct {
+  KEY name;
+} NAMED;
+
+typedef struct {
+  NAMED **v;
+  size_t size;
+  size_t used;
+  size_t usedLim;
+} HASH_TABLE;
+
+typedef struct {
+  NAMED **p;
+  NAMED **end;
+} HASH_TABLE_ITER;
+
+#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
+#define INIT_DATA_BUF_SIZE 1024
+#define INIT_ATTS_SIZE 16
+#define INIT_BLOCK_SIZE 1024
+#define INIT_BUFFER_SIZE 1024
+
+#define EXPAND_SPARE 24
+
+typedef struct binding {
+  struct prefix *prefix;
+  struct binding *nextTagBinding;
+  struct binding *prevPrefixBinding;
+  const struct attribute_id *attId;
+  XML_Char *uri;
+  int uriLen;
+  int uriAlloc;
+} BINDING;
+
+typedef struct prefix {
+  const XML_Char *name;
+  BINDING *binding;
+} PREFIX;
+
+typedef struct {
+  const XML_Char *str;
+  const XML_Char *localPart;
+  int uriLen;
+} TAG_NAME;
+
+typedef struct tag {
+  struct tag *parent;
+  const char *rawName;
+  int rawNameLength;
+  TAG_NAME name;
+  char *buf;
+  char *bufEnd;
+  BINDING *bindings;
+} TAG;
+
+typedef struct {
+  const XML_Char *name;
+  const XML_Char *textPtr;
+  int textLen;
+  const XML_Char *systemId;
+  const XML_Char *base;
+  const XML_Char *publicId;
+  const XML_Char *notation;
+  char open;
+} ENTITY;
+
+typedef struct block {
+  struct block *next;
+  int size;
+  XML_Char s[1];
+} BLOCK;
+
+typedef struct {
+  BLOCK *blocks;
+  BLOCK *freeBlocks;
+  const XML_Char *end;
+  XML_Char *ptr;
+  XML_Char *start;
+} STRING_POOL;
+
+/* The XML_Char before the name is used to determine whether
+an attribute has been specified. */
+typedef struct attribute_id {
+  XML_Char *name;
+  PREFIX *prefix;
+  char maybeTokenized;
+  char xmlns;
+} ATTRIBUTE_ID;
+
+typedef struct {
+  const ATTRIBUTE_ID *id;
+  char isCdata;
+  const XML_Char *value;
+} DEFAULT_ATTRIBUTE;
+
+typedef struct {
+  const XML_Char *name;
+  PREFIX *prefix;
+  const ATTRIBUTE_ID *idAtt;
+  int nDefaultAtts;
+  int allocDefaultAtts;
+  DEFAULT_ATTRIBUTE *defaultAtts;
+} ELEMENT_TYPE;
+
+typedef struct {
+  HASH_TABLE generalEntities;
+  HASH_TABLE elementTypes;
+  HASH_TABLE attributeIds;
+  HASH_TABLE prefixes;
+  STRING_POOL pool;
+  int complete;
+  int standalone;
+#ifdef XML_DTD
+  HASH_TABLE paramEntities;
+#endif /* XML_DTD */
+  PREFIX defaultPrefix;
+} DTD;
+
+typedef struct open_internal_entity {
+  const char *internalEventPtr;
+  const char *internalEventEndPtr;
+  struct open_internal_entity *next;
+  ENTITY *entity;
+} OPEN_INTERNAL_ENTITY;
+
+typedef enum XML_Error Processor(XML_Parser parser,
+                                const char *start,
+                                const char *end,
+                                const char **endPtr);
+
+static Processor prologProcessor;
+static Processor prologInitProcessor;
+static Processor contentProcessor;
+static Processor cdataSectionProcessor;
+#ifdef XML_DTD
+static Processor ignoreSectionProcessor;
+#endif /* XML_DTD */
+static Processor epilogProcessor;
+static Processor errorProcessor;
+static Processor externalEntityInitProcessor;
+static Processor externalEntityInitProcessor2;
+static Processor externalEntityInitProcessor3;
+static Processor externalEntityContentProcessor;
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
+static enum XML_Error
+initializeEncoding(XML_Parser parser);
+static enum XML_Error
+doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
+        const char *end, int tok, const char *next, const char **nextPtr);
+static enum XML_Error
+processInternalParamEntity(XML_Parser parser, ENTITY *entity);
+static enum XML_Error
+doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
+         const char *start, const char *end, const char **endPtr);
+static enum XML_Error
+doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
+#ifdef XML_DTD
+static enum XML_Error
+doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
+#endif /* XML_DTD */
+static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
+                               TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
+static
+int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, int isId, const XML_Char *dfltValue);
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
+                   STRING_POOL *);
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
+                   STRING_POOL *);
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
+static enum XML_Error
+storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static int
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+
+static const XML_Char *getContext(XML_Parser parser);
+static int setContext(XML_Parser parser, const XML_Char *context);
+static void normalizePublicId(XML_Char *s);
+static int dtdInit(DTD *);
+static void dtdDestroy(DTD *);
+static int dtdCopy(DTD *newDtd, const DTD *oldDtd);
+static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);
+#ifdef XML_DTD
+static void dtdSwap(DTD *, DTD *);
+#endif /* XML_DTD */
+static NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
+static void hashTableInit(HASH_TABLE *);
+static void hashTableDestroy(HASH_TABLE *);
+static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
+static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
+static void poolInit(STRING_POOL *);
+static void poolClear(STRING_POOL *);
+static void poolDestroy(STRING_POOL *);
+static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
+                           const char *ptr, const char *end);
+static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+                                 const char *ptr, const char *end);
+static int poolGrow(STRING_POOL *pool);
+static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
+static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
+
+#define poolStart(pool) ((pool)->start)
+#define poolEnd(pool) ((pool)->ptr)
+#define poolLength(pool) ((pool)->ptr - (pool)->start)
+#define poolChop(pool) ((void)--(pool->ptr))
+#define poolLastChar(pool) (((pool)->ptr)[-1])
+#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
+#define poolFinish(pool) ((pool)->start = (pool)->ptr)
+#define poolAppendChar(pool, c) \
+  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
+   ? 0 \
+   : ((*((pool)->ptr)++ = c), 1))
+
+typedef struct {
+  /* The first member must be userData so that the XML_GetUserData macro works. */
+  void *m_userData;
+  void *m_handlerArg;
+  char *m_buffer;
+  /* first character to be parsed */
+  const char *m_bufferPtr;
+  /* past last character to be parsed */
+  char *m_bufferEnd;
+  /* allocated end of buffer */
+  const char *m_bufferLim;
+  long m_parseEndByteIndex;
+  const char *m_parseEndPtr;
+  XML_Char *m_dataBuf;
+  XML_Char *m_dataBufEnd;
+  XML_StartElementHandler m_startElementHandler;
+  XML_EndElementHandler m_endElementHandler;
+  XML_CharacterDataHandler m_characterDataHandler;
+  XML_ProcessingInstructionHandler m_processingInstructionHandler;
+  XML_CommentHandler m_commentHandler;
+  XML_StartCdataSectionHandler m_startCdataSectionHandler;
+  XML_EndCdataSectionHandler m_endCdataSectionHandler;
+  XML_DefaultHandler m_defaultHandler;
+  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
+  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
+  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
+  XML_NotationDeclHandler m_notationDeclHandler;
+  XML_ExternalParsedEntityDeclHandler m_externalParsedEntityDeclHandler;
+  XML_InternalParsedEntityDeclHandler m_internalParsedEntityDeclHandler;
+  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
+  XML_NotStandaloneHandler m_notStandaloneHandler;
+  XML_ExternalEntityRefHandler m_externalEntityRefHandler;
+  void *m_externalEntityRefHandlerArg;
+  XML_UnknownEncodingHandler m_unknownEncodingHandler;
+  const ENCODING *m_encoding;
+  INIT_ENCODING m_initEncoding;
+  const ENCODING *m_internalEncoding;
+  const XML_Char *m_protocolEncodingName;
+  int m_ns;
+  void *m_unknownEncodingMem;
+  void *m_unknownEncodingData;
+  void *m_unknownEncodingHandlerData;
+  void (*m_unknownEncodingRelease)(void *);
+  PROLOG_STATE m_prologState;
+  Processor *m_processor;
+  enum XML_Error m_errorCode;
+  const char *m_eventPtr;
+  const char *m_eventEndPtr;
+  const char *m_positionPtr;
+  OPEN_INTERNAL_ENTITY *m_openInternalEntities;
+  int m_defaultExpandInternalEntities;
+  int m_tagLevel;
+  ENTITY *m_declEntity;
+  const XML_Char *m_declNotationName;
+  const XML_Char *m_declNotationPublicId;
+  ELEMENT_TYPE *m_declElementType;
+  ATTRIBUTE_ID *m_declAttributeId;
+  char m_declAttributeIsCdata;
+  char m_declAttributeIsId;
+  DTD m_dtd;
+  const XML_Char *m_curBase;
+  TAG *m_tagStack;
+  TAG *m_freeTagList;
+  BINDING *m_inheritedBindings;
+  BINDING *m_freeBindingList;
+  int m_attsSize;
+  int m_nSpecifiedAtts;
+  int m_idAttIndex;
+  ATTRIBUTE *m_atts;
+  POSITION m_position;
+  STRING_POOL m_tempPool;
+  STRING_POOL m_temp2Pool;
+  char *m_groupConnector;
+  unsigned m_groupSize;
+  int m_hadExternalDoctype;
+  XML_Char m_namespaceSeparator;
+#ifdef XML_DTD
+  enum XML_ParamEntityParsing m_paramEntityParsing;
+  XML_Parser m_parentParser;
+#endif
+} Parser;
+
+#define userData (((Parser *)parser)->m_userData)
+#define handlerArg (((Parser *)parser)->m_handlerArg)
+#define startElementHandler (((Parser *)parser)->m_startElementHandler)
+#define endElementHandler (((Parser *)parser)->m_endElementHandler)
+#define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
+#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
+#define commentHandler (((Parser *)parser)->m_commentHandler)
+#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
+#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
+#define defaultHandler (((Parser *)parser)->m_defaultHandler)
+#define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
+#define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
+#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
+#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
+#define externalParsedEntityDeclHandler (((Parser *)parser)->m_externalParsedEntityDeclHandler)
+#define internalParsedEntityDeclHandler (((Parser *)parser)->m_internalParsedEntityDeclHandler)
+#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
+#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
+#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
+#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
+#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
+#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
+#define encoding (((Parser *)parser)->m_encoding)
+#define initEncoding (((Parser *)parser)->m_initEncoding)
+#define internalEncoding (((Parser *)parser)->m_internalEncoding)
+#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
+#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
+#define unknownEncodingHandlerData \
+  (((Parser *)parser)->m_unknownEncodingHandlerData)
+#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
+#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
+#define ns (((Parser *)parser)->m_ns)
+#define prologState (((Parser *)parser)->m_prologState)
+#define processor (((Parser *)parser)->m_processor)
+#define errorCode (((Parser *)parser)->m_errorCode)
+#define eventPtr (((Parser *)parser)->m_eventPtr)
+#define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
+#define positionPtr (((Parser *)parser)->m_positionPtr)
+#define position (((Parser *)parser)->m_position)
+#define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
+#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
+#define tagLevel (((Parser *)parser)->m_tagLevel)
+#define buffer (((Parser *)parser)->m_buffer)
+#define bufferPtr (((Parser *)parser)->m_bufferPtr)
+#define bufferEnd (((Parser *)parser)->m_bufferEnd)
+#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
+#define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
+#define bufferLim (((Parser *)parser)->m_bufferLim)
+#define dataBuf (((Parser *)parser)->m_dataBuf)
+#define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
+#define dtd (((Parser *)parser)->m_dtd)
+#define curBase (((Parser *)parser)->m_curBase)
+#define declEntity (((Parser *)parser)->m_declEntity)
+#define declNotationName (((Parser *)parser)->m_declNotationName)
+#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
+#define declElementType (((Parser *)parser)->m_declElementType)
+#define declAttributeId (((Parser *)parser)->m_declAttributeId)
+#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
+#define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
+#define freeTagList (((Parser *)parser)->m_freeTagList)
+#define freeBindingList (((Parser *)parser)->m_freeBindingList)
+#define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
+#define tagStack (((Parser *)parser)->m_tagStack)
+#define atts (((Parser *)parser)->m_atts)
+#define attsSize (((Parser *)parser)->m_attsSize)
+#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
+#define idAttIndex (((Parser *)parser)->m_idAttIndex)
+#define tempPool (((Parser *)parser)->m_tempPool)
+#define temp2Pool (((Parser *)parser)->m_temp2Pool)
+#define groupConnector (((Parser *)parser)->m_groupConnector)
+#define groupSize (((Parser *)parser)->m_groupSize)
+#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
+#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
+#ifdef XML_DTD
+#define parentParser (((Parser *)parser)->m_parentParser)
+#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
+#endif /* XML_DTD */
+
+#ifdef _MSC_VER
+#ifdef _DEBUG
+Parser *asParser(XML_Parser parser)
+{
+  return parser;
+}
+#endif
+#endif
+
+XML_Parser XML_ParserCreate(const XML_Char *encodingName)
+{
+  XML_Parser parser = malloc(sizeof(Parser));
+  if (!parser)
+    return parser;
+  processor = prologInitProcessor;
+  XmlPrologStateInit(&prologState);
+  userData = 0;
+  handlerArg = 0;
+  startElementHandler = 0;
+  endElementHandler = 0;
+  characterDataHandler = 0;
+  processingInstructionHandler = 0;
+  commentHandler = 0;
+  startCdataSectionHandler = 0;
+  endCdataSectionHandler = 0;
+  defaultHandler = 0;
+  startDoctypeDeclHandler = 0;
+  endDoctypeDeclHandler = 0;
+  unparsedEntityDeclHandler = 0;
+  notationDeclHandler = 0;
+  externalParsedEntityDeclHandler = 0;
+  internalParsedEntityDeclHandler = 0;
+  startNamespaceDeclHandler = 0;
+  endNamespaceDeclHandler = 0;
+  notStandaloneHandler = 0;
+  externalEntityRefHandler = 0;
+  externalEntityRefHandlerArg = parser;
+  unknownEncodingHandler = 0;
+  buffer = 0;
+  bufferPtr = 0;
+  bufferEnd = 0;
+  parseEndByteIndex = 0;
+  parseEndPtr = 0;
+  bufferLim = 0;
+  declElementType = 0;
+  declAttributeId = 0;
+  declEntity = 0;
+  declNotationName = 0;
+  declNotationPublicId = 0;
+  memset(&position, 0, sizeof(POSITION));
+  errorCode = XML_ERROR_NONE;
+  eventPtr = 0;
+  eventEndPtr = 0;
+  positionPtr = 0;
+  openInternalEntities = 0;
+  tagLevel = 0;
+  tagStack = 0;
+  freeTagList = 0;
+  freeBindingList = 0;
+  inheritedBindings = 0;
+  attsSize = INIT_ATTS_SIZE;
+  atts = malloc(attsSize * sizeof(ATTRIBUTE));
+  nSpecifiedAtts = 0;
+  dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+  groupSize = 0;
+  groupConnector = 0;
+  hadExternalDoctype = 0;
+  unknownEncodingMem = 0;
+  unknownEncodingRelease = 0;
+  unknownEncodingData = 0;
+  unknownEncodingHandlerData = 0;
+  namespaceSeparator = '!';
+#ifdef XML_DTD
+  parentParser = 0;
+  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+  ns = 0;
+  poolInit(&tempPool);
+  poolInit(&temp2Pool);
+  protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
+  curBase = 0;
+  if (!dtdInit(&dtd) || !atts || !dataBuf
+      || (encodingName && !protocolEncodingName)) {
+    XML_ParserFree(parser);
+    return 0;
+  }
+  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
+  XmlInitEncoding(&initEncoding, &encoding, 0);
+  internalEncoding = XmlGetInternalEncoding();
+  return parser;
+}
+
+XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
+{
+  static
+  const XML_Char implicitContext[] = {
+    XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
+    XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
+    XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
+    XML_T('.'), XML_T('w'), XML_T('3'),
+    XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
+    XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
+    XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
+    XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
+    XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
+    XML_T('\0')
+  };
+
+  XML_Parser parser = XML_ParserCreate(encodingName);
+  if (parser) {
+    XmlInitEncodingNS(&initEncoding, &encoding, 0);
+    ns = 1;
+    internalEncoding = XmlGetInternalEncodingNS();
+    namespaceSeparator = nsSep;
+  }
+  if (!setContext(parser, implicitContext)) {
+    XML_ParserFree(parser);
+    return 0;
+  }
+  return parser;
+}
+
+int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+  if (!encodingName)
+    protocolEncodingName = 0;
+  else {
+    protocolEncodingName = poolCopyString(&tempPool, encodingName);
+    if (!protocolEncodingName)
+      return 0;
+  }
+  return 1;
+}
+
+XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
+                                         const XML_Char *context,
+                                         const XML_Char *encodingName)
+{
+  XML_Parser parser = oldParser;
+  DTD *oldDtd = &dtd;
+  XML_StartElementHandler oldStartElementHandler = startElementHandler;
+  XML_EndElementHandler oldEndElementHandler = endElementHandler;
+  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
+  XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
+  XML_CommentHandler oldCommentHandler = commentHandler;
+  XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
+  XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
+  XML_DefaultHandler oldDefaultHandler = defaultHandler;
+  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
+  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
+  XML_ExternalParsedEntityDeclHandler oldExternalParsedEntityDeclHandler = externalParsedEntityDeclHandler;
+  XML_InternalParsedEntityDeclHandler oldInternalParsedEntityDeclHandler = internalParsedEntityDeclHandler;
+  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
+  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
+  XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
+  XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
+  void *oldUserData = userData;
+  void *oldHandlerArg = handlerArg;
+  int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+  void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+#ifdef XML_DTD
+  int oldParamEntityParsing = paramEntityParsing;
+#endif
+  parser = (ns
+            ? XML_ParserCreateNS(encodingName, namespaceSeparator)
+           : XML_ParserCreate(encodingName));
+  if (!parser)
+    return 0;
+  startElementHandler = oldStartElementHandler;
+  endElementHandler = oldEndElementHandler;
+  characterDataHandler = oldCharacterDataHandler;
+  processingInstructionHandler = oldProcessingInstructionHandler;
+  commentHandler = oldCommentHandler;
+  startCdataSectionHandler = oldStartCdataSectionHandler;
+  endCdataSectionHandler = oldEndCdataSectionHandler;
+  defaultHandler = oldDefaultHandler;
+  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
+  notationDeclHandler = oldNotationDeclHandler;
+  externalParsedEntityDeclHandler = oldExternalParsedEntityDeclHandler;
+  internalParsedEntityDeclHandler = oldInternalParsedEntityDeclHandler;
+  startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
+  endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
+  notStandaloneHandler = oldNotStandaloneHandler;
+  externalEntityRefHandler = oldExternalEntityRefHandler;
+  unknownEncodingHandler = oldUnknownEncodingHandler;
+  userData = oldUserData;
+  if (oldUserData == oldHandlerArg)
+    handlerArg = userData;
+  else
+    handlerArg = parser;
+  if (oldExternalEntityRefHandlerArg != oldParser)
+    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
+  defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
+#ifdef XML_DTD
+  paramEntityParsing = oldParamEntityParsing;
+  if (context) {
+#endif /* XML_DTD */
+    if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) {
+      XML_ParserFree(parser);
+      return 0;
+    }
+    processor = externalEntityInitProcessor;
+#ifdef XML_DTD
+  }
+  else {
+    dtdSwap(&dtd, oldDtd);
+    parentParser = oldParser;
+    XmlPrologStateInitExternalEntity(&prologState);
+    dtd.complete = 1;
+    hadExternalDoctype = 1;
+  }
+#endif /* XML_DTD */
+  return parser;
+}
+
+static
+void destroyBindings(BINDING *bindings)
+{
+  for (;;) {
+    BINDING *b = bindings;
+    if (!b)
+      break;
+    bindings = b->nextTagBinding;
+    free(b->uri);
+    free(b);
+  }
+}
+
+void XML_ParserFree(XML_Parser parser)
+{
+  for (;;) {
+    TAG *p;
+    if (tagStack == 0) {
+      if (freeTagList == 0)
+       break;
+      tagStack = freeTagList;
+      freeTagList = 0;
+    }
+    p = tagStack;
+    tagStack = tagStack->parent;
+    free(p->buf);
+    destroyBindings(p->bindings);
+    free(p);
+  }
+  destroyBindings(freeBindingList);
+  destroyBindings(inheritedBindings);
+  poolDestroy(&tempPool);
+  poolDestroy(&temp2Pool);
+#ifdef XML_DTD
+  if (parentParser) {
+    if (hadExternalDoctype)
+      dtd.complete = 0;
+    dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
+  }
+#endif /* XML_DTD */
+  dtdDestroy(&dtd);
+  free((void *)atts);
+  free(groupConnector);
+  free(buffer);
+  free(dataBuf);
+  free(unknownEncodingMem);
+  if (unknownEncodingRelease)
+    unknownEncodingRelease(unknownEncodingData);
+  free(parser);
+}
+
+void XML_UseParserAsHandlerArg(XML_Parser parser)
+{
+  handlerArg = parser;
+}
+
+void XML_SetUserData(XML_Parser parser, void *p)
+{
+  if (handlerArg == userData)
+    handlerArg = userData = p;
+  else
+    userData = p;
+}
+
+int XML_SetBase(XML_Parser parser, const XML_Char *p)
+{
+  if (p) {
+    p = poolCopyString(&dtd.pool, p);
+    if (!p)
+      return 0;
+    curBase = p;
+  }
+  else
+    curBase = 0;
+  return 1;
+}
+
+const XML_Char *XML_GetBase(XML_Parser parser)
+{
+  return curBase;
+}
+
+int XML_GetSpecifiedAttributeCount(XML_Parser parser)
+{
+  return nSpecifiedAtts;
+}
+
+int XML_GetIdAttributeIndex(XML_Parser parser)
+{
+  return idAttIndex;
+}
+
+void XML_SetElementHandler(XML_Parser parser,
+                          XML_StartElementHandler start,
+                          XML_EndElementHandler end)
+{
+  startElementHandler = start;
+  endElementHandler = end;
+}
+
+void XML_SetCharacterDataHandler(XML_Parser parser,
+                                XML_CharacterDataHandler handler)
+{
+  characterDataHandler = handler;
+}
+
+void XML_SetProcessingInstructionHandler(XML_Parser parser,
+                                        XML_ProcessingInstructionHandler handler)
+{
+  processingInstructionHandler = handler;
+}
+
+void XML_SetCommentHandler(XML_Parser parser,
+                          XML_CommentHandler handler)
+{
+  commentHandler = handler;
+}
+
+void XML_SetCdataSectionHandler(XML_Parser parser,
+                               XML_StartCdataSectionHandler start,
+                               XML_EndCdataSectionHandler end)
+{
+  startCdataSectionHandler = start;
+  endCdataSectionHandler = end;
+}
+
+void XML_SetDefaultHandler(XML_Parser parser,
+                          XML_DefaultHandler handler)
+{
+  defaultHandler = handler;
+  defaultExpandInternalEntities = 0;
+}
+
+void XML_SetDefaultHandlerExpand(XML_Parser parser,
+                                XML_DefaultHandler handler)
+{
+  defaultHandler = handler;
+  defaultExpandInternalEntities = 1;
+}
+
+void XML_SetDoctypeDeclHandler(XML_Parser parser,
+                              XML_StartDoctypeDeclHandler start,
+                              XML_EndDoctypeDeclHandler end)
+{
+  startDoctypeDeclHandler = start;
+  endDoctypeDeclHandler = end;
+}
+
+void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+                                     XML_UnparsedEntityDeclHandler handler)
+{
+  unparsedEntityDeclHandler = handler;
+}
+
+void XML_SetExternalParsedEntityDeclHandler(XML_Parser parser,
+                                           XML_ExternalParsedEntityDeclHandler handler)
+{
+  externalParsedEntityDeclHandler = handler;
+}
+
+void XML_SetInternalParsedEntityDeclHandler(XML_Parser parser,
+                                           XML_InternalParsedEntityDeclHandler handler)
+{
+  internalParsedEntityDeclHandler = handler;
+}
+
+void XML_SetNotationDeclHandler(XML_Parser parser,
+                               XML_NotationDeclHandler handler)
+{
+  notationDeclHandler = handler;
+}
+
+void XML_SetNamespaceDeclHandler(XML_Parser parser,
+                                XML_StartNamespaceDeclHandler start,
+                                XML_EndNamespaceDeclHandler end)
+{
+  startNamespaceDeclHandler = start;
+  endNamespaceDeclHandler = end;
+}
+
+void XML_SetNotStandaloneHandler(XML_Parser parser,
+                                XML_NotStandaloneHandler handler)
+{
+  notStandaloneHandler = handler;
+}
+
+void XML_SetExternalEntityRefHandler(XML_Parser parser,
+                                    XML_ExternalEntityRefHandler handler)
+{
+  externalEntityRefHandler = handler;
+}
+
+void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
+{
+  if (arg)
+    externalEntityRefHandlerArg = arg;
+  else
+    externalEntityRefHandlerArg = parser;
+}
+
+void XML_SetUnknownEncodingHandler(XML_Parser parser,
+                                  XML_UnknownEncodingHandler handler,
+                                  void *data)
+{
+  unknownEncodingHandler = handler;
+  unknownEncodingHandlerData = data;
+}
+
+int XML_SetParamEntityParsing(XML_Parser parser,
+                             enum XML_ParamEntityParsing parsing)
+{
+#ifdef XML_DTD
+  paramEntityParsing = parsing;
+  return 1;
+#else
+  return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
+
+int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
+{
+  if (len == 0) {
+    if (!isFinal)
+      return 1;
+    positionPtr = bufferPtr;
+    errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
+    if (errorCode == XML_ERROR_NONE)
+      return 1;
+    eventEndPtr = eventPtr;
+    processor = errorProcessor;
+    return 0;
+  }
+  else if (bufferPtr == bufferEnd) {
+    const char *end;
+    int nLeftOver;
+    parseEndByteIndex += len;
+    positionPtr = s;
+    if (isFinal) {
+      errorCode = processor(parser, s, parseEndPtr = s + len, 0);
+      if (errorCode == XML_ERROR_NONE)
+       return 1;
+      eventEndPtr = eventPtr;
+      processor = errorProcessor;
+      return 0;
+    }
+    errorCode = processor(parser, s, parseEndPtr = s + len, &end);
+    if (errorCode != XML_ERROR_NONE) {
+      eventEndPtr = eventPtr;
+      processor = errorProcessor;
+      return 0;
+    }
+    XmlUpdatePosition(encoding, positionPtr, end, &position);
+    nLeftOver = s + len - end;
+    if (nLeftOver) {
+      if (buffer == 0 || nLeftOver > bufferLim - buffer) {
+       /* FIXME avoid integer overflow */
+       buffer = buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2);
+       /* FIXME storage leak if realloc fails */
+       if (!buffer) {
+         errorCode = XML_ERROR_NO_MEMORY;
+         eventPtr = eventEndPtr = 0;
+         processor = errorProcessor;
+         return 0;
+       }
+       bufferLim = buffer + len * 2;
+      }
+      memcpy(buffer, end, nLeftOver);
+      bufferPtr = buffer;
+      bufferEnd = buffer + nLeftOver;
+    }
+    return 1;
+  }
+  else {
+    memcpy(XML_GetBuffer(parser, len), s, len);
+    return XML_ParseBuffer(parser, len, isFinal);
+  }
+}
+
+int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
+{
+  const char *start = bufferPtr;
+  positionPtr = start;
+  bufferEnd += len;
+  parseEndByteIndex += len;
+  errorCode = processor(parser, start, parseEndPtr = bufferEnd,
+                       isFinal ? (const char **)0 : &bufferPtr);
+  if (errorCode == XML_ERROR_NONE) {
+    if (!isFinal)
+      XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+    return 1;
+  }
+  else {
+    eventEndPtr = eventPtr;
+    processor = errorProcessor;
+    return 0;
+  }
+}
+
+void *XML_GetBuffer(XML_Parser parser, int len)
+{
+  if (len > bufferLim - bufferEnd) {
+    /* FIXME avoid integer overflow */
+    int neededSize = len + (bufferEnd - bufferPtr);
+    if (neededSize  <= bufferLim - buffer) {
+      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
+      bufferEnd = buffer + (bufferEnd - bufferPtr);
+      bufferPtr = buffer;
+    }
+    else {
+      char *newBuf;
+      int bufferSize = bufferLim - bufferPtr;
+      if (bufferSize == 0)
+       bufferSize = INIT_BUFFER_SIZE;
+      do {
+       bufferSize *= 2;
+      } while (bufferSize < neededSize);
+      newBuf = malloc(bufferSize);
+      if (newBuf == 0) {
+       errorCode = XML_ERROR_NO_MEMORY;
+       return 0;
+      }
+      bufferLim = newBuf + bufferSize;
+      if (bufferPtr) {
+       memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
+       free(buffer);
+      }
+      bufferEnd = newBuf + (bufferEnd - bufferPtr);
+      bufferPtr = buffer = newBuf;
+    }
+  }
+  return bufferEnd;
+}
+
+enum XML_Error XML_GetErrorCode(XML_Parser parser)
+{
+  return errorCode;
+}
+
+long XML_GetCurrentByteIndex(XML_Parser parser)
+{
+  if (eventPtr)
+    return parseEndByteIndex - (parseEndPtr - eventPtr);
+  return -1;
+}
+
+int XML_GetCurrentByteCount(XML_Parser parser)
+{
+  if (eventEndPtr && eventPtr)
+    return eventEndPtr - eventPtr;
+  return 0;
+}
+
+int XML_GetCurrentLineNumber(XML_Parser parser)
+{
+  if (eventPtr) {
+    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+    positionPtr = eventPtr;
+  }
+  return position.lineNumber + 1;
+}
+
+int XML_GetCurrentColumnNumber(XML_Parser parser)
+{
+  if (eventPtr) {
+    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+    positionPtr = eventPtr;
+  }
+  return position.columnNumber;
+}
+
+void XML_DefaultCurrent(XML_Parser parser)
+{
+  if (defaultHandler) {
+    if (openInternalEntities)
+      reportDefault(parser,
+                   internalEncoding,
+                   openInternalEntities->internalEventPtr,
+                   openInternalEntities->internalEventEndPtr);
+    else
+      reportDefault(parser, encoding, eventPtr, eventEndPtr);
+  }
+}
+
+const XML_LChar *XML_ErrorString(int code)
+{
+  static const XML_LChar *message[] = {
+    0,
+    XML_T("out of memory"),
+    XML_T("syntax error"),
+    XML_T("no element found"),
+    XML_T("not well-formed"),
+    XML_T("unclosed token"),
+    XML_T("unclosed token"),
+    XML_T("mismatched tag"),
+    XML_T("duplicate attribute"),
+    XML_T("junk after document element"),
+    XML_T("illegal parameter entity reference"),
+    XML_T("undefined entity"),
+    XML_T("recursive entity reference"),
+    XML_T("asynchronous entity"),
+    XML_T("reference to invalid character number"),
+    XML_T("reference to binary entity"),
+    XML_T("reference to external entity in attribute"),
+    XML_T("xml processing instruction not at start of external entity"),
+    XML_T("unknown encoding"),
+    XML_T("encoding specified in XML declaration is incorrect"),
+    XML_T("unclosed CDATA section"),
+    XML_T("error in processing external entity reference"),
+    XML_T("document is not standalone")
+  };
+  if (code > 0 && code < sizeof(message)/sizeof(message[0]))
+    return message[code];
+  return 0;
+}
+
+static
+enum XML_Error contentProcessor(XML_Parser parser,
+                               const char *start,
+                               const char *end,
+                               const char **endPtr)
+{
+  return doContent(parser, 0, encoding, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor(XML_Parser parser,
+                                          const char *start,
+                                          const char *end,
+                                          const char **endPtr)
+{
+  enum XML_Error result = initializeEncoding(parser);
+  if (result != XML_ERROR_NONE)
+    return result;
+  processor = externalEntityInitProcessor2;
+  return externalEntityInitProcessor2(parser, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
+                                           const char *start,
+                                           const char *end,
+                                           const char **endPtr)
+{
+  const char *next;
+  int tok = XmlContentTok(encoding, start, end, &next);
+  switch (tok) {
+  case XML_TOK_BOM:
+    start = next;
+    break;
+  case XML_TOK_PARTIAL:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_UNCLOSED_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_PARTIAL_CHAR;
+  }
+  processor = externalEntityInitProcessor3;
+  return externalEntityInitProcessor3(parser, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
+                                           const char *start,
+                                           const char *end,
+                                           const char **endPtr)
+{
+  const char *next;
+  int tok = XmlContentTok(encoding, start, end, &next);
+  switch (tok) {
+  case XML_TOK_XML_DECL:
+    {
+      enum XML_Error result = processXmlDecl(parser, 1, start, next);
+      if (result != XML_ERROR_NONE)
+       return result;
+      start = next;
+    }
+    break;
+  case XML_TOK_PARTIAL:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_UNCLOSED_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_PARTIAL_CHAR;
+  }
+  processor = externalEntityContentProcessor;
+  tagLevel = 1;
+  return doContent(parser, 1, encoding, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityContentProcessor(XML_Parser parser,
+                                             const char *start,
+                                             const char *end,
+                                             const char **endPtr)
+{
+  return doContent(parser, 1, encoding, start, end, endPtr);
+}
+
+static enum XML_Error
+doContent(XML_Parser parser,
+         int startTagLevel,
+         const ENCODING *enc,
+         const char *s,
+         const char *end,
+         const char **nextPtr)
+{
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  for (;;) {
+    const char *next = s; /* XmlContentTok doesn't always set the last arg */
+    int tok = XmlContentTok(enc, s, end, &next);
+    *eventEndPP = next;
+    switch (tok) {
+    case XML_TOK_TRAILING_CR:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      *eventEndPP = end;
+      if (characterDataHandler) {
+       XML_Char c = 0xA;
+       characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, end);
+      if (startTagLevel == 0)
+       return XML_ERROR_NO_ELEMENTS;
+      if (tagLevel != startTagLevel)
+       return XML_ERROR_ASYNC_ENTITY;
+      return XML_ERROR_NONE;
+    case XML_TOK_NONE:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      if (startTagLevel > 0) {
+       if (tagLevel != startTagLevel)
+         return XML_ERROR_ASYNC_ENTITY;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_NO_ELEMENTS;
+    case XML_TOK_INVALID:
+      *eventPP = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    case XML_TOK_ENTITY_REF:
+      {
+       const XML_Char *name;
+       ENTITY *entity;
+       XML_Char ch = XmlPredefinedEntityName(enc,
+                                             s + enc->minBytesPerChar,
+                                             next - enc->minBytesPerChar);
+       if (ch) {
+         if (characterDataHandler)
+           characterDataHandler(handlerArg, &ch, 1);
+         else if (defaultHandler)
+           reportDefault(parser, enc, s, next);
+         break;
+       }
+       name = poolStoreString(&dtd.pool, enc,
+                               s + enc->minBytesPerChar,
+                               next - enc->minBytesPerChar);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
+       poolDiscard(&dtd.pool);
+       if (!entity) {
+         if (dtd.complete || dtd.standalone)
+           return XML_ERROR_UNDEFINED_ENTITY;
+         if (defaultHandler)
+           reportDefault(parser, enc, s, next);
+         break;
+       }
+       if (entity->open)
+         return XML_ERROR_RECURSIVE_ENTITY_REF;
+       if (entity->notation)
+         return XML_ERROR_BINARY_ENTITY_REF;
+       if (entity) {
+         if (entity->textPtr) {
+           enum XML_Error result;
+           OPEN_INTERNAL_ENTITY openEntity;
+           if (defaultHandler && !defaultExpandInternalEntities) {
+             reportDefault(parser, enc, s, next);
+             break;
+           }
+           entity->open = 1;
+           openEntity.next = openInternalEntities;
+           openInternalEntities = &openEntity;
+           openEntity.entity = entity;
+           openEntity.internalEventPtr = 0;
+           openEntity.internalEventEndPtr = 0;
+           result = doContent(parser,
+                              tagLevel,
+                              internalEncoding,
+                              (char *)entity->textPtr,
+                              (char *)(entity->textPtr + entity->textLen),
+                              0);
+           entity->open = 0;
+           openInternalEntities = openEntity.next;
+           if (result)
+             return result;
+         }
+         else if (externalEntityRefHandler) {
+           const XML_Char *context;
+           entity->open = 1;
+           context = getContext(parser);
+           entity->open = 0;
+           if (!context)
+             return XML_ERROR_NO_MEMORY;
+           if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                         context,
+                                         entity->base,
+                                         entity->systemId,
+                                         entity->publicId))
+             return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+           poolDiscard(&tempPool);
+         }
+         else if (defaultHandler)
+           reportDefault(parser, enc, s, next);
+       }
+       break;
+      }
+    case XML_TOK_START_TAG_WITH_ATTS:
+      if (!startElementHandler) {
+       enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
+       if (result)
+         return result;
+      }
+      /* fall through */
+    case XML_TOK_START_TAG_NO_ATTS:
+      {
+       TAG *tag;
+       if (freeTagList) {
+         tag = freeTagList;
+         freeTagList = freeTagList->parent;
+       }
+       else {
+         tag = malloc(sizeof(TAG));
+         if (!tag)
+           return XML_ERROR_NO_MEMORY;
+         tag->buf = malloc(INIT_TAG_BUF_SIZE);
+         if (!tag->buf)
+           return XML_ERROR_NO_MEMORY;
+         tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
+       }
+       tag->bindings = 0;
+       tag->parent = tagStack;
+       tagStack = tag;
+       tag->name.localPart = 0;
+       tag->rawName = s + enc->minBytesPerChar;
+       tag->rawNameLength = XmlNameLength(enc, tag->rawName);
+       if (nextPtr) {
+         /* Need to guarantee that:
+            tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
+         if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
+           int bufSize = tag->rawNameLength * 4;
+           bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
+           tag->buf = realloc(tag->buf, bufSize);
+           if (!tag->buf)
+             return XML_ERROR_NO_MEMORY;
+           tag->bufEnd = tag->buf + bufSize;
+         }
+         memcpy(tag->buf, tag->rawName, tag->rawNameLength);
+         tag->rawName = tag->buf;
+       }
+       ++tagLevel;
+       if (startElementHandler) {
+         enum XML_Error result;
+         XML_Char *toPtr;
+         for (;;) {
+           const char *rawNameEnd = tag->rawName + tag->rawNameLength;
+           const char *fromPtr = tag->rawName;
+           int bufSize;
+           if (nextPtr)
+             toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
+           else
+             toPtr = (XML_Char *)tag->buf;
+           tag->name.str = toPtr;
+           XmlConvert(enc,
+                      &fromPtr, rawNameEnd,
+                      (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
+           if (fromPtr == rawNameEnd)
+             break;
+           bufSize = (tag->bufEnd - tag->buf) << 1;
+           tag->buf = realloc(tag->buf, bufSize);
+           if (!tag->buf)
+             return XML_ERROR_NO_MEMORY;
+           tag->bufEnd = tag->buf + bufSize;
+           if (nextPtr)
+             tag->rawName = tag->buf;
+         }
+         *toPtr = XML_T('\0');
+         result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
+         if (result)
+           return result;
+         startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
+         poolClear(&tempPool);
+       }
+       else {
+         tag->name.str = 0;
+         if (defaultHandler)
+           reportDefault(parser, enc, s, next);
+       }
+       break;
+      }
+    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
+      if (!startElementHandler) {
+       enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
+       if (result)
+         return result;
+      }
+      /* fall through */
+    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
+      if (startElementHandler || endElementHandler) {
+       const char *rawName = s + enc->minBytesPerChar;
+       enum XML_Error result;
+       BINDING *bindings = 0;
+       TAG_NAME name;
+       name.str = poolStoreString(&tempPool, enc, rawName,
+                                  rawName + XmlNameLength(enc, rawName));
+       if (!name.str)
+         return XML_ERROR_NO_MEMORY;
+       poolFinish(&tempPool);
+       result = storeAtts(parser, enc, s, &name, &bindings);
+       if (result)
+         return result;
+       poolFinish(&tempPool);
+       if (startElementHandler)
+         startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
+       if (endElementHandler) {
+         if (startElementHandler)
+           *eventPP = *eventEndPP;
+         endElementHandler(handlerArg, name.str);
+       }
+       poolClear(&tempPool);
+       while (bindings) {
+         BINDING *b = bindings;
+         if (endNamespaceDeclHandler)
+           endNamespaceDeclHandler(handlerArg, b->prefix->name);
+         bindings = bindings->nextTagBinding;
+         b->nextTagBinding = freeBindingList;
+         freeBindingList = b;
+         b->prefix->binding = b->prevPrefixBinding;
+       }
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      if (tagLevel == 0)
+       return epilogProcessor(parser, next, end, nextPtr);
+      break;
+    case XML_TOK_END_TAG:
+      if (tagLevel == startTagLevel)
+        return XML_ERROR_ASYNC_ENTITY;
+      else {
+       int len;
+       const char *rawName;
+       TAG *tag = tagStack;
+       tagStack = tag->parent;
+       tag->parent = freeTagList;
+       freeTagList = tag;
+       rawName = s + enc->minBytesPerChar*2;
+       len = XmlNameLength(enc, rawName);
+       if (len != tag->rawNameLength
+           || memcmp(tag->rawName, rawName, len) != 0) {
+         *eventPP = rawName;
+         return XML_ERROR_TAG_MISMATCH;
+       }
+       --tagLevel;
+       if (endElementHandler && tag->name.str) {
+         if (tag->name.localPart) {
+           XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
+           const XML_Char *from = tag->name.localPart;
+           while ((*to++ = *from++) != 0)
+             ;
+         }
+         endElementHandler(handlerArg, tag->name.str);
+       }
+       else if (defaultHandler)
+         reportDefault(parser, enc, s, next);
+       while (tag->bindings) {
+         BINDING *b = tag->bindings;
+         if (endNamespaceDeclHandler)
+           endNamespaceDeclHandler(handlerArg, b->prefix->name);
+         tag->bindings = tag->bindings->nextTagBinding;
+         b->nextTagBinding = freeBindingList;
+         freeBindingList = b;
+         b->prefix->binding = b->prevPrefixBinding;
+       }
+       if (tagLevel == 0)
+         return epilogProcessor(parser, next, end, nextPtr);
+      }
+      break;
+    case XML_TOK_CHAR_REF:
+      {
+       int n = XmlCharRefNumber(enc, s);
+       if (n < 0)
+         return XML_ERROR_BAD_CHAR_REF;
+       if (characterDataHandler) {
+         XML_Char buf[XML_ENCODE_MAX];
+         characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
+       }
+       else if (defaultHandler)
+         reportDefault(parser, enc, s, next);
+      }
+      break;
+    case XML_TOK_XML_DECL:
+      return XML_ERROR_MISPLACED_XML_PI;
+    case XML_TOK_DATA_NEWLINE:
+      if (characterDataHandler) {
+       XML_Char c = 0xA;
+       characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_CDATA_SECT_OPEN:
+      {
+       enum XML_Error result;
+       if (startCdataSectionHandler)
+         startCdataSectionHandler(handlerArg);
+#if 0
+       /* Suppose you doing a transformation on a document that involves
+          changing only the character data.  You set up a defaultHandler
+          and a characterDataHandler.  The defaultHandler simply copies
+          characters through.  The characterDataHandler does the transformation
+          and writes the characters out escaping them as necessary.  This case
+          will fail to work if we leave out the following two lines (because &
+          and < inside CDATA sections will be incorrectly escaped).
+
+          However, now we have a start/endCdataSectionHandler, so it seems
+          easier to let the user deal with this. */
+
+       else if (characterDataHandler)
+         characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+       else if (defaultHandler)
+         reportDefault(parser, enc, s, next);
+       result = doCdataSection(parser, enc, &next, end, nextPtr);
+       if (!next) {
+         processor = cdataSectionProcessor;
+         return result;
+       }
+      }
+      break;
+    case XML_TOK_TRAILING_RSQB:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      if (characterDataHandler) {
+       if (MUST_CONVERT(enc, s)) {
+         ICHAR *dataPtr = (ICHAR *)dataBuf;
+         XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+         characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+       }
+       else
+         characterDataHandler(handlerArg,
+                              (XML_Char *)s,
+                              (XML_Char *)end - (XML_Char *)s);
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, end);
+      if (startTagLevel == 0) {
+        *eventPP = end;
+       return XML_ERROR_NO_ELEMENTS;
+      }
+      if (tagLevel != startTagLevel) {
+       *eventPP = end;
+       return XML_ERROR_ASYNC_ENTITY;
+      }
+      return XML_ERROR_NONE;
+    case XML_TOK_DATA_CHARS:
+      if (characterDataHandler) {
+       if (MUST_CONVERT(enc, s)) {
+         for (;;) {
+           ICHAR *dataPtr = (ICHAR *)dataBuf;
+           XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+           *eventEndPP = s;
+           characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+           if (s == next)
+             break;
+           *eventPP = s;
+         }
+       }
+       else
+         characterDataHandler(handlerArg,
+                              (XML_Char *)s,
+                              (XML_Char *)next - (XML_Char *)s);
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_PI:
+      if (!reportProcessingInstruction(parser, enc, s, next))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_COMMENT:
+      if (!reportComment(parser, enc, s, next))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    default:
+      if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      break;
+    }
+    *eventPP = s = next;
+  }
+  /* not reached */
+}
+
+/* If tagNamePtr is non-null, build a real list of attributes,
+otherwise just check the attributes for well-formedness. */
+
+static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
+                               const char *attStr, TAG_NAME *tagNamePtr,
+                               BINDING **bindingsPtr)
+{
+  ELEMENT_TYPE *elementType = 0;
+  int nDefaultAtts = 0;
+  const XML_Char **appAtts;   /* the attribute list to pass to the application */
+  int attIndex = 0;
+  int i;
+  int n;
+  int nPrefixes = 0;
+  BINDING *binding;
+  const XML_Char *localPart;
+
+  /* lookup the element type name */
+  if (tagNamePtr) {
+    elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, 0);
+    if (!elementType) {
+      tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
+      if (!tagNamePtr->str)
+       return XML_ERROR_NO_MEMORY;
+      elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
+      if (!elementType)
+        return XML_ERROR_NO_MEMORY;
+      if (ns && !setElementTypePrefix(parser, elementType))
+        return XML_ERROR_NO_MEMORY;
+    }
+    nDefaultAtts = elementType->nDefaultAtts;
+  }
+  /* get the attributes from the tokenizer */
+  n = XmlGetAttributes(enc, attStr, attsSize, atts);
+  if (n + nDefaultAtts > attsSize) {
+    int oldAttsSize = attsSize;
+    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
+    atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
+    if (!atts)
+      return XML_ERROR_NO_MEMORY;
+    if (n > oldAttsSize)
+      XmlGetAttributes(enc, attStr, n, atts);
+  }
+  appAtts = (const XML_Char **)atts;
+  for (i = 0; i < n; i++) {
+    /* add the name and value to the attribute list */
+    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
+                                        atts[i].name
+                                        + XmlNameLength(enc, atts[i].name));
+    if (!attId)
+      return XML_ERROR_NO_MEMORY;
+    /* detect duplicate attributes */
+    if ((attId->name)[-1]) {
+      if (enc == encoding)
+       eventPtr = atts[i].name;
+      return XML_ERROR_DUPLICATE_ATTRIBUTE;
+    }
+    (attId->name)[-1] = 1;
+    appAtts[attIndex++] = attId->name;
+    if (!atts[i].normalized) {
+      enum XML_Error result;
+      int isCdata = 1;
+
+      /* figure out whether declared as other than CDATA */
+      if (attId->maybeTokenized) {
+       int j;
+       for (j = 0; j < nDefaultAtts; j++) {
+         if (attId == elementType->defaultAtts[j].id) {
+           isCdata = elementType->defaultAtts[j].isCdata;
+           break;
+         }
+       }
+      }
+
+      /* normalize the attribute value */
+      result = storeAttributeValue(parser, enc, isCdata,
+                                  atts[i].valuePtr, atts[i].valueEnd,
+                                  &tempPool);
+      if (result)
+       return result;
+      if (tagNamePtr) {
+       appAtts[attIndex] = poolStart(&tempPool);
+       poolFinish(&tempPool);
+      }
+      else
+       poolDiscard(&tempPool);
+    }
+    else if (tagNamePtr) {
+      /* the value did not need normalizing */
+      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
+      if (appAtts[attIndex] == 0)
+       return XML_ERROR_NO_MEMORY;
+      poolFinish(&tempPool);
+    }
+    /* handle prefixed attribute names */
+    if (attId->prefix && tagNamePtr) {
+      if (attId->xmlns) {
+       /* deal with namespace declarations here */
+        if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
+          return XML_ERROR_NO_MEMORY;
+        --attIndex;
+      }
+      else {
+       /* deal with other prefixed names later */
+        attIndex++;
+        nPrefixes++;
+        (attId->name)[-1] = 2;
+      }
+    }
+    else
+      attIndex++;
+  }
+  if (tagNamePtr) {
+    int j;
+    nSpecifiedAtts = attIndex;
+    if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
+      for (i = 0; i < attIndex; i += 2)
+       if (appAtts[i] == elementType->idAtt->name) {
+         idAttIndex = i;
+         break;
+       }
+    }
+    else
+      idAttIndex = -1;
+    /* do attribute defaulting */
+    for (j = 0; j < nDefaultAtts; j++) {
+      const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
+      if (!(da->id->name)[-1] && da->value) {
+        if (da->id->prefix) {
+          if (da->id->xmlns) {
+           if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
+             return XML_ERROR_NO_MEMORY;
+         }
+          else {
+           (da->id->name)[-1] = 2;
+           nPrefixes++;
+           appAtts[attIndex++] = da->id->name;
+           appAtts[attIndex++] = da->value;
+         }
+       }
+       else {
+         (da->id->name)[-1] = 1;
+         appAtts[attIndex++] = da->id->name;
+         appAtts[attIndex++] = da->value;
+       }
+      }
+    }
+    appAtts[attIndex] = 0;
+  }
+  i = 0;
+  if (nPrefixes) {
+    /* expand prefixed attribute names */
+    for (; i < attIndex; i += 2) {
+      if (appAtts[i][-1] == 2) {
+        ATTRIBUTE_ID *id;
+        ((XML_Char *)(appAtts[i]))[-1] = 0;
+       id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
+       if (id->prefix->binding) {
+         int j;
+         const BINDING *b = id->prefix->binding;
+         const XML_Char *s = appAtts[i];
+         for (j = 0; j < b->uriLen; j++) {
+           if (!poolAppendChar(&tempPool, b->uri[j]))
+             return XML_ERROR_NO_MEMORY;
+         }
+         while (*s++ != ':')
+           ;
+         do {
+           if (!poolAppendChar(&tempPool, *s))
+             return XML_ERROR_NO_MEMORY;
+         } while (*s++);
+         appAtts[i] = poolStart(&tempPool);
+         poolFinish(&tempPool);
+       }
+       if (!--nPrefixes)
+         break;
+      }
+      else
+       ((XML_Char *)(appAtts[i]))[-1] = 0;
+    }
+  }
+  /* clear the flags that say whether attributes were specified */
+  for (; i < attIndex; i += 2)
+    ((XML_Char *)(appAtts[i]))[-1] = 0;
+  if (!tagNamePtr)
+    return XML_ERROR_NONE;
+  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
+    binding->attId->name[-1] = 0;
+  /* expand the element type name */
+  if (elementType->prefix) {
+    binding = elementType->prefix->binding;
+    if (!binding)
+      return XML_ERROR_NONE;
+    localPart = tagNamePtr->str;
+    while (*localPart++ != XML_T(':'))
+      ;
+  }
+  else if (dtd.defaultPrefix.binding) {
+    binding = dtd.defaultPrefix.binding;
+    localPart = tagNamePtr->str;
+  }
+  else
+    return XML_ERROR_NONE;
+  tagNamePtr->localPart = localPart;
+  tagNamePtr->uriLen = binding->uriLen;
+  for (i = 0; localPart[i++];)
+    ;
+  n = i + binding->uriLen;
+  if (n > binding->uriAlloc) {
+    TAG *p;
+    XML_Char *uri = malloc((n + EXPAND_SPARE) * sizeof(XML_Char));
+    if (!uri)
+      return XML_ERROR_NO_MEMORY;
+    binding->uriAlloc = n + EXPAND_SPARE;
+    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
+    for (p = tagStack; p; p = p->parent)
+      if (p->name.str == binding->uri)
+       p->name.str = uri;
+    free(binding->uri);
+    binding->uri = uri;
+  }
+  memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
+  tagNamePtr->str = binding->uri;
+  return XML_ERROR_NONE;
+}
+
+static
+int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
+{
+  BINDING *b;
+  int len;
+  for (len = 0; uri[len]; len++)
+    ;
+  if (namespaceSeparator)
+    len++;
+  if (freeBindingList) {
+    b = freeBindingList;
+    if (len > b->uriAlloc) {
+      b->uri = realloc(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
+      if (!b->uri)
+       return 0;
+      b->uriAlloc = len + EXPAND_SPARE;
+    }
+    freeBindingList = b->nextTagBinding;
+  }
+  else {
+    b = malloc(sizeof(BINDING));
+    if (!b)
+      return 0;
+    b->uri = malloc(sizeof(XML_Char) * (len + EXPAND_SPARE));
+    if (!b->uri) {
+      free(b);
+      return 0;
+    }
+    b->uriAlloc = len + EXPAND_SPARE;
+  }
+  b->uriLen = len;
+  memcpy(b->uri, uri, len * sizeof(XML_Char));
+  if (namespaceSeparator)
+    b->uri[len - 1] = namespaceSeparator;
+  b->prefix = prefix;
+  b->attId = attId;
+  b->prevPrefixBinding = prefix->binding;
+  if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
+    prefix->binding = 0;
+  else
+    prefix->binding = b;
+  b->nextTagBinding = *bindingsPtr;
+  *bindingsPtr = b;
+  if (startNamespaceDeclHandler)
+    startNamespaceDeclHandler(handlerArg, prefix->name,
+                             prefix->binding ? uri : 0);
+  return 1;
+}
+
+/* The idea here is to avoid using stack for each CDATA section when
+the whole file is parsed with one call. */
+
+static
+enum XML_Error cdataSectionProcessor(XML_Parser parser,
+                                    const char *start,
+                                    const char *end,
+                                    const char **endPtr)
+{
+  enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
+  if (start) {
+    processor = contentProcessor;
+    return contentProcessor(parser, start, end, endPtr);
+  }
+  return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null if
+the section is not yet closed. */
+
+static
+enum XML_Error doCdataSection(XML_Parser parser,
+                             const ENCODING *enc,
+                             const char **startPtr,
+                             const char *end,
+                             const char **nextPtr)
+{
+  const char *s = *startPtr;
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    *eventPP = s;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  *startPtr = 0;
+  for (;;) {
+    const char *next;
+    int tok = XmlCdataSectionTok(enc, s, end, &next);
+    *eventEndPP = next;
+    switch (tok) {
+    case XML_TOK_CDATA_SECT_CLOSE:
+      if (endCdataSectionHandler)
+       endCdataSectionHandler(handlerArg);
+#if 0
+      /* see comment under XML_TOK_CDATA_SECT_OPEN */
+      else if (characterDataHandler)
+       characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      *startPtr = next;
+      return XML_ERROR_NONE;
+    case XML_TOK_DATA_NEWLINE:
+      if (characterDataHandler) {
+       XML_Char c = 0xA;
+       characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_DATA_CHARS:
+      if (characterDataHandler) {
+       if (MUST_CONVERT(enc, s)) {
+         for (;;) {
+           ICHAR *dataPtr = (ICHAR *)dataBuf;
+           XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+           *eventEndPP = next;
+           characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+           if (s == next)
+             break;
+           *eventPP = s;
+         }
+       }
+       else
+         characterDataHandler(handlerArg,
+                              (XML_Char *)s,
+                              (XML_Char *)next - (XML_Char *)s);
+      }
+      else if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_INVALID:
+      *eventPP = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    case XML_TOK_PARTIAL:
+    case XML_TOK_NONE:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_CDATA_SECTION;
+    default:
+      abort();
+    }
+    *eventPP = s = next;
+  }
+  /* not reached */
+}
+
+#ifdef XML_DTD
+
+/* The idea here is to avoid using stack for each IGNORE section when
+the whole file is parsed with one call. */
+
+static
+enum XML_Error ignoreSectionProcessor(XML_Parser parser,
+                                     const char *start,
+                                     const char *end,
+                                     const char **endPtr)
+{
+  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
+  if (start) {
+    processor = prologProcessor;
+    return prologProcessor(parser, start, end, endPtr);
+  }
+  return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null if
+the section is not yet closed. */
+
+static
+enum XML_Error doIgnoreSection(XML_Parser parser,
+                              const ENCODING *enc,
+                              const char **startPtr,
+                              const char *end,
+                              const char **nextPtr)
+{
+  const char *next;
+  int tok;
+  const char *s = *startPtr;
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    *eventPP = s;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  *startPtr = 0;
+  tok = XmlIgnoreSectionTok(enc, s, end, &next);
+  *eventEndPP = next;
+  switch (tok) {
+  case XML_TOK_IGNORE_SECT:
+    if (defaultHandler)
+      reportDefault(parser, enc, s, next);
+    *startPtr = next;
+    return XML_ERROR_NONE;
+  case XML_TOK_INVALID:
+    *eventPP = next;
+    return XML_ERROR_INVALID_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (nextPtr) {
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    }
+    return XML_ERROR_PARTIAL_CHAR;
+  case XML_TOK_PARTIAL:
+  case XML_TOK_NONE:
+    if (nextPtr) {
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    }
+    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
+  default:
+    abort();
+  }
+  /* not reached */
+}
+
+#endif /* XML_DTD */
+
+static enum XML_Error
+initializeEncoding(XML_Parser parser)
+{
+  const char *s;
+#ifdef XML_UNICODE
+  char encodingBuf[128];
+  if (!protocolEncodingName)
+    s = 0;
+  else {
+    int i;
+    for (i = 0; protocolEncodingName[i]; i++) {
+      if (i == sizeof(encodingBuf) - 1
+         || (protocolEncodingName[i] & ~0x7f) != 0) {
+       encodingBuf[0] = '\0';
+       break;
+      }
+      encodingBuf[i] = (char)protocolEncodingName[i];
+    }
+    encodingBuf[i] = '\0';
+    s = encodingBuf;
+  }
+#else
+  s = protocolEncodingName;
+#endif
+  if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
+    return XML_ERROR_NONE;
+  return handleUnknownEncoding(parser, protocolEncodingName);
+}
+
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+              const char *s, const char *next)
+{
+  const char *encodingName = 0;
+  const ENCODING *newEncoding = 0;
+  const char *version;
+  int standalone = -1;
+  if (!(ns
+        ? XmlParseXmlDeclNS
+       : XmlParseXmlDecl)(isGeneralTextEntity,
+                          encoding,
+                          s,
+                          next,
+                          &eventPtr,
+                          &version,
+                          &encodingName,
+                          &newEncoding,
+                          &standalone))
+    return XML_ERROR_SYNTAX;
+  if (!isGeneralTextEntity && standalone == 1) {
+    dtd.standalone = 1;
+#ifdef XML_DTD
+    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
+      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif /* XML_DTD */
+  }
+  if (defaultHandler)
+    reportDefault(parser, encoding, s, next);
+  if (!protocolEncodingName) {
+    if (newEncoding) {
+      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
+       eventPtr = encodingName;
+       return XML_ERROR_INCORRECT_ENCODING;
+      }
+      encoding = newEncoding;
+    }
+    else if (encodingName) {
+      enum XML_Error result;
+      const XML_Char *s = poolStoreString(&tempPool,
+                                         encoding,
+                                         encodingName,
+                                         encodingName
+                                         + XmlNameLength(encoding, encodingName));
+      if (!s)
+       return XML_ERROR_NO_MEMORY;
+      result = handleUnknownEncoding(parser, s);
+      poolDiscard(&tempPool);
+      if (result == XML_ERROR_UNKNOWN_ENCODING)
+       eventPtr = encodingName;
+      return result;
+    }
+  }
+  return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+  if (unknownEncodingHandler) {
+    XML_Encoding info;
+    int i;
+    for (i = 0; i < 256; i++)
+      info.map[i] = -1;
+    info.convert = 0;
+    info.data = 0;
+    info.release = 0;
+    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
+      ENCODING *enc;
+      unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding());
+      if (!unknownEncodingMem) {
+       if (info.release)
+         info.release(info.data);
+       return XML_ERROR_NO_MEMORY;
+      }
+      enc = (ns
+            ? XmlInitUnknownEncodingNS
+            : XmlInitUnknownEncoding)(unknownEncodingMem,
+                                      info.map,
+                                      info.convert,
+                                      info.data);
+      if (enc) {
+       unknownEncodingData = info.data;
+       unknownEncodingRelease = info.release;
+       encoding = enc;
+       return XML_ERROR_NONE;
+      }
+    }
+    if (info.release)
+      info.release(info.data);
+  }
+  return XML_ERROR_UNKNOWN_ENCODING;
+}
+
+static enum XML_Error
+prologInitProcessor(XML_Parser parser,
+                   const char *s,
+                   const char *end,
+                   const char **nextPtr)
+{
+  enum XML_Error result = initializeEncoding(parser);
+  if (result != XML_ERROR_NONE)
+    return result;
+  processor = prologProcessor;
+  return prologProcessor(parser, s, end, nextPtr);
+}
+
+static enum XML_Error
+prologProcessor(XML_Parser parser,
+               const char *s,
+               const char *end,
+               const char **nextPtr)
+{
+  const char *next;
+  int tok = XmlPrologTok(encoding, s, end, &next);
+  return doProlog(parser, encoding, s, end, tok, next, nextPtr);
+}
+
+static enum XML_Error
+doProlog(XML_Parser parser,
+        const ENCODING *enc,
+        const char *s,
+        const char *end,
+        int tok,
+        const char *next,
+        const char **nextPtr)
+{
+#ifdef XML_DTD
+  static const XML_Char externalSubsetName[] = { '#' , '\0' };
+#endif /* XML_DTD */
+
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  for (;;) {
+    int role;
+    *eventPP = s;
+    *eventEndPP = next;
+    if (tok <= 0) {
+      if (nextPtr != 0 && tok != XML_TOK_INVALID) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      switch (tok) {
+      case XML_TOK_INVALID:
+       *eventPP = next;
+       return XML_ERROR_INVALID_TOKEN;
+      case XML_TOK_PARTIAL:
+       return XML_ERROR_UNCLOSED_TOKEN;
+      case XML_TOK_PARTIAL_CHAR:
+       return XML_ERROR_PARTIAL_CHAR;
+      case XML_TOK_NONE:
+#ifdef XML_DTD
+       if (enc != encoding)
+         return XML_ERROR_NONE;
+       if (parentParser) {
+         if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
+             == XML_ROLE_ERROR)
+           return XML_ERROR_SYNTAX;
+         hadExternalDoctype = 0;
+         return XML_ERROR_NONE;
+       }
+#endif /* XML_DTD */
+       return XML_ERROR_NO_ELEMENTS;
+      default:
+       tok = -tok;
+       next = end;
+       break;
+      }
+    }
+    role = XmlTokenRole(&prologState, tok, s, next, enc);
+    switch (role) {
+    case XML_ROLE_XML_DECL:
+      {
+       enum XML_Error result = processXmlDecl(parser, 0, s, next);
+       if (result != XML_ERROR_NONE)
+         return result;
+       enc = encoding;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_NAME:
+      if (startDoctypeDeclHandler) {
+       const XML_Char *name = poolStoreString(&tempPool, enc, s, next);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       startDoctypeDeclHandler(handlerArg, name);
+       poolClear(&tempPool);
+      }
+      break;
+#ifdef XML_DTD
+    case XML_ROLE_TEXT_DECL:
+      {
+       enum XML_Error result = processXmlDecl(parser, 1, s, next);
+       if (result != XML_ERROR_NONE)
+         return result;
+       enc = encoding;
+      }
+      break;
+#endif /* XML_DTD */
+    case XML_ROLE_DOCTYPE_PUBLIC_ID:
+#ifdef XML_DTD
+      declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+                                   externalSubsetName,
+                                   sizeof(ENTITY));
+      if (!declEntity)
+       return XML_ERROR_NO_MEMORY;
+#endif /* XML_DTD */
+      /* fall through */
+    case XML_ROLE_ENTITY_PUBLIC_ID:
+      if (!XmlIsPublicId(enc, s, next, eventPP))
+       return XML_ERROR_SYNTAX;
+      if (declEntity) {
+       XML_Char *tem = poolStoreString(&dtd.pool,
+                                       enc,
+                                       s + enc->minBytesPerChar,
+                                       next - enc->minBytesPerChar);
+       if (!tem)
+         return XML_ERROR_NO_MEMORY;
+       normalizePublicId(tem);
+       declEntity->publicId = tem;
+       poolFinish(&dtd.pool);
+      }
+      break;
+    case XML_ROLE_DOCTYPE_CLOSE:
+      if (dtd.complete && hadExternalDoctype) {
+       dtd.complete = 0;
+#ifdef XML_DTD
+       if (paramEntityParsing && externalEntityRefHandler) {
+         ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
+                                           externalSubsetName,
+                                           0);
+         if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                       0,
+                                       entity->base,
+                                       entity->systemId,
+                                       entity->publicId))
+          return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+       }
+#endif /* XML_DTD */
+       if (!dtd.complete
+           && !dtd.standalone
+           && notStandaloneHandler
+           && !notStandaloneHandler(handlerArg))
+         return XML_ERROR_NOT_STANDALONE;
+      }
+      if (endDoctypeDeclHandler)
+       endDoctypeDeclHandler(handlerArg);
+      break;
+    case XML_ROLE_INSTANCE_START:
+      processor = contentProcessor;
+      return contentProcessor(parser, s, end, nextPtr);
+    case XML_ROLE_ATTLIST_ELEMENT_NAME:
+      {
+       const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
+       if (!declElementType)
+         return XML_ERROR_NO_MEMORY;
+       if (declElementType->name != name)
+         poolDiscard(&dtd.pool);
+       else {
+         poolFinish(&dtd.pool);
+         if (!setElementTypePrefix(parser, declElementType))
+            return XML_ERROR_NO_MEMORY;
+       }
+       break;
+      }
+    case XML_ROLE_ATTRIBUTE_NAME:
+      declAttributeId = getAttributeId(parser, enc, s, next);
+      if (!declAttributeId)
+       return XML_ERROR_NO_MEMORY;
+      declAttributeIsCdata = 0;
+      declAttributeIsId = 0;
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
+      declAttributeIsCdata = 1;
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_ID:
+      declAttributeIsId = 1;
+      break;
+    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
+    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
+      if (dtd.complete
+         && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata,
+                             declAttributeIsId, 0))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
+    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
+      {
+       const XML_Char *attVal;
+       enum XML_Error result
+         = storeAttributeValue(parser, enc, declAttributeIsCdata,
+                               s + enc->minBytesPerChar,
+                               next - enc->minBytesPerChar,
+                               &dtd.pool);
+       if (result)
+         return result;
+       attVal = poolStart(&dtd.pool);
+       poolFinish(&dtd.pool);
+       if (dtd.complete
+           // ID attributes aren't allowed to have a default
+           && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal))
+         return XML_ERROR_NO_MEMORY;
+       break;
+      }
+    case XML_ROLE_ENTITY_VALUE:
+      {
+       enum XML_Error result = storeEntityValue(parser, enc,
+                                                s + enc->minBytesPerChar,
+                                                next - enc->minBytesPerChar);
+       if (declEntity) {
+         declEntity->textPtr = poolStart(&dtd.pool);
+         declEntity->textLen = poolLength(&dtd.pool);
+         poolFinish(&dtd.pool);
+         if (internalParsedEntityDeclHandler
+             // Check it's not a parameter entity
+             && ((ENTITY *)lookup(&dtd.generalEntities, declEntity->name, 0)
+                 == declEntity)) {
+           *eventEndPP = s;
+           internalParsedEntityDeclHandler(handlerArg,
+                                           declEntity->name,
+                                           declEntity->textPtr,
+                                           declEntity->textLen);
+         }
+       }
+       else
+         poolDiscard(&dtd.pool);
+       if (result != XML_ERROR_NONE)
+         return result;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_SYSTEM_ID:
+      if (!dtd.standalone
+#ifdef XML_DTD
+         && !paramEntityParsing
+#endif /* XML_DTD */
+         && notStandaloneHandler
+         && !notStandaloneHandler(handlerArg))
+       return XML_ERROR_NOT_STANDALONE;
+      hadExternalDoctype = 1;
+#ifndef XML_DTD
+      break;
+#else /* XML_DTD */
+      if (!declEntity) {
+       declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+                                     externalSubsetName,
+                                     sizeof(ENTITY));
+       if (!declEntity)
+         return XML_ERROR_NO_MEMORY;
+      }
+      /* fall through */
+#endif /* XML_DTD */
+    case XML_ROLE_ENTITY_SYSTEM_ID:
+      if (declEntity) {
+       declEntity->systemId = poolStoreString(&dtd.pool, enc,
+                                              s + enc->minBytesPerChar,
+                                              next - enc->minBytesPerChar);
+       if (!declEntity->systemId)
+         return XML_ERROR_NO_MEMORY;
+       declEntity->base = curBase;
+       poolFinish(&dtd.pool);
+      }
+      break;
+    case XML_ROLE_ENTITY_NOTATION_NAME:
+      if (declEntity) {
+       declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
+       if (!declEntity->notation)
+         return XML_ERROR_NO_MEMORY;
+       poolFinish(&dtd.pool);
+       if (unparsedEntityDeclHandler) {
+         *eventEndPP = s;
+         unparsedEntityDeclHandler(handlerArg,
+                                   declEntity->name,
+                                   declEntity->base,
+                                   declEntity->systemId,
+                                   declEntity->publicId,
+                                   declEntity->notation);
+       }
+
+      }
+      break;
+    case XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION:
+      if (declEntity && externalParsedEntityDeclHandler) {
+       *eventEndPP = s;
+       externalParsedEntityDeclHandler(handlerArg,
+                                       declEntity->name,
+                                       declEntity->base,
+                                       declEntity->systemId,
+                                       declEntity->publicId);
+      }
+      break;
+    case XML_ROLE_GENERAL_ENTITY_NAME:
+      {
+       const XML_Char *name;
+       if (XmlPredefinedEntityName(enc, s, next)) {
+         declEntity = 0;
+         break;
+       }
+       name = poolStoreString(&dtd.pool, enc, s, next);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       if (dtd.complete) {
+         declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
+         if (!declEntity)
+           return XML_ERROR_NO_MEMORY;
+         if (declEntity->name != name) {
+           poolDiscard(&dtd.pool);
+           declEntity = 0;
+         }
+         else
+           poolFinish(&dtd.pool);
+       }
+       else {
+         poolDiscard(&dtd.pool);
+         declEntity = 0;
+       }
+      }
+      break;
+    case XML_ROLE_PARAM_ENTITY_NAME:
+#ifdef XML_DTD
+      if (dtd.complete) {
+       const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       declEntity = (ENTITY *)lookup(&dtd.paramEntities, name, sizeof(ENTITY));
+       if (!declEntity)
+         return XML_ERROR_NO_MEMORY;
+       if (declEntity->name != name) {
+         poolDiscard(&dtd.pool);
+         declEntity = 0;
+       }
+       else
+         poolFinish(&dtd.pool);
+      }
+#else /* not XML_DTD */
+      declEntity = 0;
+#endif /* not XML_DTD */
+      break;
+    case XML_ROLE_NOTATION_NAME:
+      declNotationPublicId = 0;
+      declNotationName = 0;
+      if (notationDeclHandler) {
+       declNotationName = poolStoreString(&tempPool, enc, s, next);
+       if (!declNotationName)
+         return XML_ERROR_NO_MEMORY;
+       poolFinish(&tempPool);
+      }
+      break;
+    case XML_ROLE_NOTATION_PUBLIC_ID:
+      if (!XmlIsPublicId(enc, s, next, eventPP))
+       return XML_ERROR_SYNTAX;
+      if (declNotationName) {
+       XML_Char *tem = poolStoreString(&tempPool,
+                                       enc,
+                                       s + enc->minBytesPerChar,
+                                       next - enc->minBytesPerChar);
+       if (!tem)
+         return XML_ERROR_NO_MEMORY;
+       normalizePublicId(tem);
+       declNotationPublicId = tem;
+       poolFinish(&tempPool);
+      }
+      break;
+    case XML_ROLE_NOTATION_SYSTEM_ID:
+      if (declNotationName && notationDeclHandler) {
+       const XML_Char *systemId
+         = poolStoreString(&tempPool, enc,
+                           s + enc->minBytesPerChar,
+                           next - enc->minBytesPerChar);
+       if (!systemId)
+         return XML_ERROR_NO_MEMORY;
+       *eventEndPP = s;
+       notationDeclHandler(handlerArg,
+                           declNotationName,
+                           curBase,
+                           systemId,
+                           declNotationPublicId);
+      }
+      poolClear(&tempPool);
+      break;
+    case XML_ROLE_NOTATION_NO_SYSTEM_ID:
+      if (declNotationPublicId && notationDeclHandler) {
+       *eventEndPP = s;
+       notationDeclHandler(handlerArg,
+                           declNotationName,
+                           curBase,
+                           0,
+                           declNotationPublicId);
+      }
+      poolClear(&tempPool);
+      break;
+    case XML_ROLE_ERROR:
+      switch (tok) {
+      case XML_TOK_PARAM_ENTITY_REF:
+       return XML_ERROR_PARAM_ENTITY_REF;
+      case XML_TOK_XML_DECL:
+       return XML_ERROR_MISPLACED_XML_PI;
+      default:
+       return XML_ERROR_SYNTAX;
+      }
+#ifdef XML_DTD
+    case XML_ROLE_IGNORE_SECT:
+      {
+       enum XML_Error result;
+       if (defaultHandler)
+         reportDefault(parser, enc, s, next);
+       result = doIgnoreSection(parser, enc, &next, end, nextPtr);
+       if (!next) {
+         processor = ignoreSectionProcessor;
+         return result;
+       }
+      }
+      break;
+#endif /* XML_DTD */
+    case XML_ROLE_GROUP_OPEN:
+      if (prologState.level >= groupSize) {
+       if (groupSize)
+         groupConnector = realloc(groupConnector, groupSize *= 2);
+       else
+         groupConnector = malloc(groupSize = 32);
+       if (!groupConnector)
+         return XML_ERROR_NO_MEMORY;
+      }
+      groupConnector[prologState.level] = 0;
+      break;
+    case XML_ROLE_GROUP_SEQUENCE:
+      if (groupConnector[prologState.level] == '|')
+       return XML_ERROR_SYNTAX;
+      groupConnector[prologState.level] = ',';
+      break;
+    case XML_ROLE_GROUP_CHOICE:
+      if (groupConnector[prologState.level] == ',')
+       return XML_ERROR_SYNTAX;
+      groupConnector[prologState.level] = '|';
+      break;
+    case XML_ROLE_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+    case XML_ROLE_INNER_PARAM_ENTITY_REF:
+      if (paramEntityParsing
+         && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
+       const XML_Char *name;
+       ENTITY *entity;
+       name = poolStoreString(&dtd.pool, enc,
+                               s + enc->minBytesPerChar,
+                               next - enc->minBytesPerChar);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
+       poolDiscard(&dtd.pool);
+       if (!entity) {
+         /* FIXME what to do if !dtd.complete? */
+         return XML_ERROR_UNDEFINED_ENTITY;
+       }
+       if (entity->open)
+         return XML_ERROR_RECURSIVE_ENTITY_REF;
+       if (entity->textPtr) {
+         enum XML_Error result;
+         result = processInternalParamEntity(parser, entity);
+         if (result != XML_ERROR_NONE)
+           return result;
+         break;
+       }
+       if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
+         return XML_ERROR_PARAM_ENTITY_REF;
+       if (externalEntityRefHandler) {
+         dtd.complete = 0;
+         entity->open = 1;
+         if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+                                       0,
+                                       entity->base,
+                                       entity->systemId,
+                                       entity->publicId)) {
+           entity->open = 0;
+           return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+         }
+         entity->open = 0;
+         if (dtd.complete)
+           break;
+       }
+      }
+#endif /* XML_DTD */
+      if (!dtd.standalone
+         && notStandaloneHandler
+         && !notStandaloneHandler(handlerArg))
+       return XML_ERROR_NOT_STANDALONE;
+      dtd.complete = 0;
+      if (defaultHandler)
+       reportDefault(parser, enc, s, next);
+      break;
+    case XML_ROLE_NONE:
+      switch (tok) {
+      case XML_TOK_PI:
+       if (!reportProcessingInstruction(parser, enc, s, next))
+         return XML_ERROR_NO_MEMORY;
+       break;
+      case XML_TOK_COMMENT:
+       if (!reportComment(parser, enc, s, next))
+         return XML_ERROR_NO_MEMORY;
+       break;
+      }
+      break;
+    }
+    if (defaultHandler) {
+      switch (tok) {
+      case XML_TOK_PI:
+      case XML_TOK_COMMENT:
+      case XML_TOK_BOM:
+      case XML_TOK_XML_DECL:
+#ifdef XML_DTD
+      case XML_TOK_IGNORE_SECT:
+#endif /* XML_DTD */
+      case XML_TOK_PARAM_ENTITY_REF:
+       break;
+      default:
+#ifdef XML_DTD
+       if (role != XML_ROLE_IGNORE_SECT)
+#endif /* XML_DTD */
+         reportDefault(parser, enc, s, next);
+      }
+    }
+    s = next;
+    tok = XmlPrologTok(enc, s, end, &next);
+  }
+  /* not reached */
+}
+
+static
+enum XML_Error epilogProcessor(XML_Parser parser,
+                              const char *s,
+                              const char *end,
+                              const char **nextPtr)
+{
+  processor = epilogProcessor;
+  eventPtr = s;
+  for (;;) {
+    const char *next;
+    int tok = XmlPrologTok(encoding, s, end, &next);
+    eventEndPtr = next;
+    switch (tok) {
+    case -XML_TOK_PROLOG_S:
+      if (defaultHandler) {
+       eventEndPtr = end;
+       reportDefault(parser, encoding, s, end);
+      }
+      /* fall through */
+    case XML_TOK_NONE:
+      if (nextPtr)
+       *nextPtr = end;
+      return XML_ERROR_NONE;
+    case XML_TOK_PROLOG_S:
+      if (defaultHandler)
+       reportDefault(parser, encoding, s, next);
+      break;
+    case XML_TOK_PI:
+      if (!reportProcessingInstruction(parser, encoding, s, next))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_COMMENT:
+      if (!reportComment(parser, encoding, s, next))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_INVALID:
+      eventPtr = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (nextPtr) {
+       *nextPtr = s;
+       return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    default:
+      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
+    }
+    eventPtr = s = next;
+  }
+}
+
+#ifdef XML_DTD
+
+static enum XML_Error
+processInternalParamEntity(XML_Parser parser, ENTITY *entity)
+{
+  const char *s, *end, *next;
+  int tok;
+  enum XML_Error result;
+  OPEN_INTERNAL_ENTITY openEntity;
+  entity->open = 1;
+  openEntity.next = openInternalEntities;
+  openInternalEntities = &openEntity;
+  openEntity.entity = entity;
+  openEntity.internalEventPtr = 0;
+  openEntity.internalEventEndPtr = 0;
+  s = (char *)entity->textPtr;
+  end = (char *)(entity->textPtr + entity->textLen);
+  tok = XmlPrologTok(internalEncoding, s, end, &next);
+  result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
+  entity->open = 0;
+  openInternalEntities = openEntity.next;
+  return result;
+}
+
+#endif /* XML_DTD */
+
+static
+enum XML_Error errorProcessor(XML_Parser parser,
+                             const char *s,
+                             const char *end,
+                             const char **nextPtr)
+{
+  return errorCode;
+}
+
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
+                   const char *ptr, const char *end,
+                   STRING_POOL *pool)
+{
+  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
+  if (result)
+    return result;
+  if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
+    poolChop(pool);
+  if (!poolAppendChar(pool, XML_T('\0')))
+    return XML_ERROR_NO_MEMORY;
+  return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
+                    const char *ptr, const char *end,
+                    STRING_POOL *pool)
+{
+  for (;;) {
+    const char *next;
+    int tok = XmlAttributeValueTok(enc, ptr, end, &next);
+    switch (tok) {
+    case XML_TOK_NONE:
+      return XML_ERROR_NONE;
+    case XML_TOK_INVALID:
+      if (enc == encoding)
+       eventPtr = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (enc == encoding)
+       eventPtr = ptr;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_CHAR_REF:
+      {
+       XML_Char buf[XML_ENCODE_MAX];
+       int i;
+       int n = XmlCharRefNumber(enc, ptr);
+       if (n < 0) {
+         if (enc == encoding)
+           eventPtr = ptr;
+         return XML_ERROR_BAD_CHAR_REF;
+       }
+       if (!isCdata
+           && n == 0x20 /* space */
+           && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+         break;
+       n = XmlEncode(n, (ICHAR *)buf);
+       if (!n) {
+         if (enc == encoding)
+           eventPtr = ptr;
+         return XML_ERROR_BAD_CHAR_REF;
+       }
+       for (i = 0; i < n; i++) {
+         if (!poolAppendChar(pool, buf[i]))
+           return XML_ERROR_NO_MEMORY;
+       }
+      }
+      break;
+    case XML_TOK_DATA_CHARS:
+      if (!poolAppend(pool, enc, ptr, next))
+       return XML_ERROR_NO_MEMORY;
+      break;
+      break;
+    case XML_TOK_TRAILING_CR:
+      next = ptr + enc->minBytesPerChar;
+      /* fall through */
+    case XML_TOK_ATTRIBUTE_VALUE_S:
+    case XML_TOK_DATA_NEWLINE:
+      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+       break;
+      if (!poolAppendChar(pool, 0x20))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_ENTITY_REF:
+      {
+       const XML_Char *name;
+       ENTITY *entity;
+       XML_Char ch = XmlPredefinedEntityName(enc,
+                                             ptr + enc->minBytesPerChar,
+                                             next - enc->minBytesPerChar);
+       if (ch) {
+         if (!poolAppendChar(pool, ch))
+           return XML_ERROR_NO_MEMORY;
+         break;
+       }
+       name = poolStoreString(&temp2Pool, enc,
+                              ptr + enc->minBytesPerChar,
+                              next - enc->minBytesPerChar);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
+       poolDiscard(&temp2Pool);
+       if (!entity) {
+         if (dtd.complete) {
+           if (enc == encoding)
+             eventPtr = ptr;
+           return XML_ERROR_UNDEFINED_ENTITY;
+         }
+       }
+       else if (entity->open) {
+         if (enc == encoding)
+           eventPtr = ptr;
+         return XML_ERROR_RECURSIVE_ENTITY_REF;
+       }
+       else if (entity->notation) {
+         if (enc == encoding)
+           eventPtr = ptr;
+         return XML_ERROR_BINARY_ENTITY_REF;
+       }
+       else if (!entity->textPtr) {
+         if (enc == encoding)
+           eventPtr = ptr;
+         return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
+       }
+       else {
+         enum XML_Error result;
+         const XML_Char *textEnd = entity->textPtr + entity->textLen;
+         entity->open = 1;
+         result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
+         entity->open = 0;
+         if (result)
+           return result;
+       }
+      }
+      break;
+    default:
+      abort();
+    }
+    ptr = next;
+  }
+  /* not reached */
+}
+
+static
+enum XML_Error storeEntityValue(XML_Parser parser,
+                               const ENCODING *enc,
+                               const char *entityTextPtr,
+                               const char *entityTextEnd)
+{
+  STRING_POOL *pool = &(dtd.pool);
+  for (;;) {
+    const char *next;
+    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
+    switch (tok) {
+    case XML_TOK_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+      if (parentParser || enc != encoding) {
+       enum XML_Error result;
+       const XML_Char *name;
+       ENTITY *entity;
+       name = poolStoreString(&tempPool, enc,
+                              entityTextPtr + enc->minBytesPerChar,
+                              next - enc->minBytesPerChar);
+       if (!name)
+         return XML_ERROR_NO_MEMORY;
+       entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
+       poolDiscard(&tempPool);
+       if (!entity) {
+         if (enc == encoding)
+           eventPtr = entityTextPtr;
+         return XML_ERROR_UNDEFINED_ENTITY;
+       }
+       if (entity->open) {
+         if (enc == encoding)
+           eventPtr = entityTextPtr;
+         return XML_ERROR_RECURSIVE_ENTITY_REF;
+       }
+       if (entity->systemId) {
+         if (enc == encoding)
+           eventPtr = entityTextPtr;
+         return XML_ERROR_PARAM_ENTITY_REF;
+       }
+       entity->open = 1;
+       result = storeEntityValue(parser,
+                                 internalEncoding,
+                                 (char *)entity->textPtr,
+                                 (char *)(entity->textPtr + entity->textLen));
+       entity->open = 0;
+       if (result)
+         return result;
+       break;
+      }
+#endif /* XML_DTD */
+      eventPtr = entityTextPtr;
+      return XML_ERROR_SYNTAX;
+    case XML_TOK_NONE:
+      return XML_ERROR_NONE;
+    case XML_TOK_ENTITY_REF:
+    case XML_TOK_DATA_CHARS:
+      if (!poolAppend(pool, enc, entityTextPtr, next))
+       return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_TRAILING_CR:
+      next = entityTextPtr + enc->minBytesPerChar;
+      /* fall through */
+    case XML_TOK_DATA_NEWLINE:
+      if (pool->end == pool->ptr && !poolGrow(pool))
+       return XML_ERROR_NO_MEMORY;
+      *(pool->ptr)++ = 0xA;
+      break;
+    case XML_TOK_CHAR_REF:
+      {
+       XML_Char buf[XML_ENCODE_MAX];
+       int i;
+       int n = XmlCharRefNumber(enc, entityTextPtr);
+       if (n < 0) {
+         if (enc == encoding)
+           eventPtr = entityTextPtr;
+         return XML_ERROR_BAD_CHAR_REF;
+       }
+       n = XmlEncode(n, (ICHAR *)buf);
+       if (!n) {
+         if (enc == encoding)
+           eventPtr = entityTextPtr;
+         return XML_ERROR_BAD_CHAR_REF;
+       }
+       for (i = 0; i < n; i++) {
+         if (pool->end == pool->ptr && !poolGrow(pool))
+           return XML_ERROR_NO_MEMORY;
+         *(pool->ptr)++ = buf[i];
+       }
+      }
+      break;
+    case XML_TOK_PARTIAL:
+      if (enc == encoding)
+       eventPtr = entityTextPtr;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_INVALID:
+      if (enc == encoding)
+       eventPtr = next;
+      return XML_ERROR_INVALID_TOKEN;
+    default:
+      abort();
+    }
+    entityTextPtr = next;
+  }
+  /* not reached */
+}
+
+static void
+normalizeLines(XML_Char *s)
+{
+  XML_Char *p;
+  for (;; s++) {
+    if (*s == XML_T('\0'))
+      return;
+    if (*s == 0xD)
+      break;
+  }
+  p = s;
+  do {
+    if (*s == 0xD) {
+      *p++ = 0xA;
+      if (*++s == 0xA)
+        s++;
+    }
+    else
+      *p++ = *s++;
+  } while (*s);
+  *p = XML_T('\0');
+}
+
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+{
+  const XML_Char *target;
+  XML_Char *data;
+  const char *tem;
+  if (!processingInstructionHandler) {
+    if (defaultHandler)
+      reportDefault(parser, enc, start, end);
+    return 1;
+  }
+  start += enc->minBytesPerChar * 2;
+  tem = start + XmlNameLength(enc, start);
+  target = poolStoreString(&tempPool, enc, start, tem);
+  if (!target)
+    return 0;
+  poolFinish(&tempPool);
+  data = poolStoreString(&tempPool, enc,
+                       XmlSkipS(enc, tem),
+                       end - enc->minBytesPerChar*2);
+  if (!data)
+    return 0;
+  normalizeLines(data);
+  processingInstructionHandler(handlerArg, target, data);
+  poolClear(&tempPool);
+  return 1;
+}
+
+static int
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+{
+  XML_Char *data;
+  if (!commentHandler) {
+    if (defaultHandler)
+      reportDefault(parser, enc, start, end);
+    return 1;
+  }
+  data = poolStoreString(&tempPool,
+                         enc,
+                         start + enc->minBytesPerChar * 4, 
+                        end - enc->minBytesPerChar * 3);
+  if (!data)
+    return 0;
+  normalizeLines(data);
+  commentHandler(handlerArg, data);
+  poolClear(&tempPool);
+  return 1;
+}
+
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
+{
+  if (MUST_CONVERT(enc, s)) {
+    const char **eventPP;
+    const char **eventEndPP;
+    if (enc == encoding) {
+      eventPP = &eventPtr;
+      eventEndPP = &eventEndPtr;
+    }
+    else {
+      eventPP = &(openInternalEntities->internalEventPtr);
+      eventEndPP = &(openInternalEntities->internalEventEndPtr);
+    }
+    do {
+      ICHAR *dataPtr = (ICHAR *)dataBuf;
+      XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+      *eventEndPP = s;
+      defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+      *eventPP = s;
+    } while (s != end);
+  }
+  else
+    defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
+}
+
+
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, int isId, const XML_Char *value)
+{
+  DEFAULT_ATTRIBUTE *att;
+  if (value || isId) {
+    /* The handling of default attributes gets messed up if we have
+       a default which duplicates a non-default. */
+    int i;
+    for (i = 0; i < type->nDefaultAtts; i++)
+      if (attId == type->defaultAtts[i].id)
+       return 1;
+    if (isId && !type->idAtt && !attId->xmlns)
+      type->idAtt = attId;
+  }
+  if (type->nDefaultAtts == type->allocDefaultAtts) {
+    if (type->allocDefaultAtts == 0) {
+      type->allocDefaultAtts = 8;
+      type->defaultAtts = malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
+    }
+    else {
+      type->allocDefaultAtts *= 2;
+      type->defaultAtts = realloc(type->defaultAtts,
+                                 type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
+    }
+    if (!type->defaultAtts)
+      return 0;
+  }
+  att = type->defaultAtts + type->nDefaultAtts;
+  att->id = attId;
+  att->value = value;
+  att->isCdata = isCdata;
+  if (!isCdata)
+    attId->maybeTokenized = 1;
+  type->nDefaultAtts += 1;
+  return 1;
+}
+
+static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
+{
+  const XML_Char *name;
+  for (name = elementType->name; *name; name++) {
+    if (*name == XML_T(':')) {
+      PREFIX *prefix;
+      const XML_Char *s;
+      for (s = elementType->name; s != name; s++) {
+       if (!poolAppendChar(&dtd.pool, *s))
+         return 0;
+      }
+      if (!poolAppendChar(&dtd.pool, XML_T('\0')))
+       return 0;
+      prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
+      if (!prefix)
+       return 0;
+      if (prefix->name == poolStart(&dtd.pool))
+       poolFinish(&dtd.pool);
+      else
+       poolDiscard(&dtd.pool);
+      elementType->prefix = prefix;
+
+    }
+  }
+  return 1;
+}
+
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+{
+  ATTRIBUTE_ID *id;
+  const XML_Char *name;
+  if (!poolAppendChar(&dtd.pool, XML_T('\0')))
+    return 0;
+  name = poolStoreString(&dtd.pool, enc, start, end);
+  if (!name)
+    return 0;
+  ++name;
+  id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
+  if (!id)
+    return 0;
+  if (id->name != name)
+    poolDiscard(&dtd.pool);
+  else {
+    poolFinish(&dtd.pool);
+    if (!ns)
+      ;
+    else if (name[0] == 'x'
+       && name[1] == 'm'
+       && name[2] == 'l'
+       && name[3] == 'n'
+       && name[4] == 's'
+       && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
+      if (name[5] == '\0')
+       id->prefix = &dtd.defaultPrefix;
+      else
+       id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
+      id->xmlns = 1;
+    }
+    else {
+      int i;
+      for (i = 0; name[i]; i++) {
+       if (name[i] == XML_T(':')) {
+         int j;
+         for (j = 0; j < i; j++) {
+           if (!poolAppendChar(&dtd.pool, name[j]))
+             return 0;
+         }
+         if (!poolAppendChar(&dtd.pool, XML_T('\0')))
+           return 0;
+         id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
+         if (id->prefix->name == poolStart(&dtd.pool))
+           poolFinish(&dtd.pool);
+         else
+           poolDiscard(&dtd.pool);
+         break;
+       }
+      }
+    }
+  }
+  return id;
+}
+
+#define CONTEXT_SEP XML_T('\f')
+
+static
+const XML_Char *getContext(XML_Parser parser)
+{
+  HASH_TABLE_ITER iter;
+  int needSep = 0;
+
+  if (dtd.defaultPrefix.binding) {
+    int i;
+    int len;
+    if (!poolAppendChar(&tempPool, XML_T('=')))
+      return 0;
+    len = dtd.defaultPrefix.binding->uriLen;
+    if (namespaceSeparator != XML_T('\0'))
+      len--;
+    for (i = 0; i < len; i++)
+      if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
+       return 0;
+    needSep = 1;
+  }
+
+  hashTableIterInit(&iter, &(dtd.prefixes));
+  for (;;) {
+    int i;
+    int len;
+    const XML_Char *s;
+    PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
+    if (!prefix)
+      break;
+    if (!prefix->binding)
+      continue;
+    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+      return 0;
+    for (s = prefix->name; *s; s++)
+      if (!poolAppendChar(&tempPool, *s))
+        return 0;
+    if (!poolAppendChar(&tempPool, XML_T('=')))
+      return 0;
+    len = prefix->binding->uriLen;
+    if (namespaceSeparator != XML_T('\0'))
+      len--;
+    for (i = 0; i < len; i++)
+      if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
+        return 0;
+    needSep = 1;
+  }
+
+
+  hashTableIterInit(&iter, &(dtd.generalEntities));
+  for (;;) {
+    const XML_Char *s;
+    ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
+    if (!e)
+      break;
+    if (!e->open)
+      continue;
+    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+      return 0;
+    for (s = e->name; *s; s++)
+      if (!poolAppendChar(&tempPool, *s))
+        return 0;
+    needSep = 1;
+  }
+
+  if (!poolAppendChar(&tempPool, XML_T('\0')))
+    return 0;
+  return tempPool.start;
+}
+
+static
+int setContext(XML_Parser parser, const XML_Char *context)
+{
+  const XML_Char *s = context;
+
+  while (*context != XML_T('\0')) {
+    if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
+      ENTITY *e;
+      if (!poolAppendChar(&tempPool, XML_T('\0')))
+       return 0;
+      e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
+      if (e)
+       e->open = 1;
+      if (*s != XML_T('\0'))
+       s++;
+      context = s;
+      poolDiscard(&tempPool);
+    }
+    else if (*s == '=') {
+      PREFIX *prefix;
+      if (poolLength(&tempPool) == 0)
+       prefix = &dtd.defaultPrefix;
+      else {
+       if (!poolAppendChar(&tempPool, XML_T('\0')))
+         return 0;
+       prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
+       if (!prefix)
+         return 0;
+        if (prefix->name == poolStart(&tempPool)) {
+         prefix->name = poolCopyString(&dtd.pool, prefix->name);
+         if (!prefix->name)
+           return 0;
+       }
+       poolDiscard(&tempPool);
+      }
+      for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
+        if (!poolAppendChar(&tempPool, *context))
+          return 0;
+      if (!poolAppendChar(&tempPool, XML_T('\0')))
+       return 0;
+      if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
+       return 0;
+      poolDiscard(&tempPool);
+      if (*context != XML_T('\0'))
+       ++context;
+      s = context;
+    }
+    else {
+      if (!poolAppendChar(&tempPool, *s))
+       return 0;
+      s++;
+    }
+  }
+  return 1;
+}
+
+
+static
+void normalizePublicId(XML_Char *publicId)
+{
+  XML_Char *p = publicId;
+  XML_Char *s;
+  for (s = publicId; *s; s++) {
+    switch (*s) {
+    case 0x20:
+    case 0xD:
+    case 0xA:
+      if (p != publicId && p[-1] != 0x20)
+       *p++ = 0x20;
+      break;
+    default:
+      *p++ = *s;
+    }
+  }
+  if (p != publicId && p[-1] == 0x20)
+    --p;
+  *p = XML_T('\0');
+}
+
+static int dtdInit(DTD *p)
+{
+  poolInit(&(p->pool));
+  hashTableInit(&(p->generalEntities));
+  hashTableInit(&(p->elementTypes));
+  hashTableInit(&(p->attributeIds));
+  hashTableInit(&(p->prefixes));
+  p->complete = 1;
+  p->standalone = 0;
+#ifdef XML_DTD
+  hashTableInit(&(p->paramEntities));
+#endif /* XML_DTD */
+  p->defaultPrefix.name = 0;
+  p->defaultPrefix.binding = 0;
+  return 1;
+}
+
+#ifdef XML_DTD
+
+static void dtdSwap(DTD *p1, DTD *p2)
+{
+  DTD tem;
+  memcpy(&tem, p1, sizeof(DTD));
+  memcpy(p1, p2, sizeof(DTD));
+  memcpy(p2, &tem, sizeof(DTD));
+}
+
+#endif /* XML_DTD */
+
+static void dtdDestroy(DTD *p)
+{
+  HASH_TABLE_ITER iter;
+  hashTableIterInit(&iter, &(p->elementTypes));
+  for (;;) {
+    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+    if (!e)
+      break;
+    if (e->allocDefaultAtts != 0)
+      free(e->defaultAtts);
+  }
+  hashTableDestroy(&(p->generalEntities));
+#ifdef XML_DTD
+  hashTableDestroy(&(p->paramEntities));
+#endif /* XML_DTD */
+  hashTableDestroy(&(p->elementTypes));
+  hashTableDestroy(&(p->attributeIds));
+  hashTableDestroy(&(p->prefixes));
+  poolDestroy(&(p->pool));
+}
+
+/* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
+The new DTD has already been initialized. */
+
+static int dtdCopy(DTD *newDtd, const DTD *oldDtd)
+{
+  HASH_TABLE_ITER iter;
+
+  /* Copy the prefix table. */
+
+  hashTableIterInit(&iter, &(oldDtd->prefixes));
+  for (;;) {
+    const XML_Char *name;
+    const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
+    if (!oldP)
+      break;
+    name = poolCopyString(&(newDtd->pool), oldP->name);
+    if (!name)
+      return 0;
+    if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
+      return 0;
+  }
+
+  hashTableIterInit(&iter, &(oldDtd->attributeIds));
+
+  /* Copy the attribute id table. */
+
+  for (;;) {
+    ATTRIBUTE_ID *newA;
+    const XML_Char *name;
+    const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
+
+    if (!oldA)
+      break;
+    /* Remember to allocate the scratch byte before the name. */
+    if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
+      return 0;
+    name = poolCopyString(&(newDtd->pool), oldA->name);
+    if (!name)
+      return 0;
+    ++name;
+    newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
+    if (!newA)
+      return 0;
+    newA->maybeTokenized = oldA->maybeTokenized;
+    if (oldA->prefix) {
+      newA->xmlns = oldA->xmlns;
+      if (oldA->prefix == &oldDtd->defaultPrefix)
+       newA->prefix = &newDtd->defaultPrefix;
+      else
+       newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
+    }
+  }
+
+  /* Copy the element type table. */
+
+  hashTableIterInit(&iter, &(oldDtd->elementTypes));
+
+  for (;;) {
+    int i;
+    ELEMENT_TYPE *newE;
+    const XML_Char *name;
+    const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+    if (!oldE)
+      break;
+    name = poolCopyString(&(newDtd->pool), oldE->name);
+    if (!name)
+      return 0;
+    newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
+    if (!newE)
+      return 0;
+    if (oldE->nDefaultAtts) {
+      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+      if (!newE->defaultAtts)
+       return 0;
+    }
+    if (oldE->idAtt)
+      newE->idAtt = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
+    newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
+    if (oldE->prefix)
+      newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
+    for (i = 0; i < newE->nDefaultAtts; i++) {
+      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
+      newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
+      if (oldE->defaultAtts[i].value) {
+       newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
+       if (!newE->defaultAtts[i].value)
+         return 0;
+      }
+      else
+       newE->defaultAtts[i].value = 0;
+    }
+  }
+
+  /* Copy the entity tables. */
+  if (!copyEntityTable(&(newDtd->generalEntities),
+                      &(newDtd->pool),
+                      &(oldDtd->generalEntities)))
+      return 0;
+
+#ifdef XML_DTD
+  if (!copyEntityTable(&(newDtd->paramEntities),
+                      &(newDtd->pool),
+                      &(oldDtd->paramEntities)))
+      return 0;
+#endif /* XML_DTD */
+
+  newDtd->complete = oldDtd->complete;
+  newDtd->standalone = oldDtd->standalone;
+  return 1;
+}
+
+static int copyEntityTable(HASH_TABLE *newTable,
+                          STRING_POOL *newPool,
+                          const HASH_TABLE *oldTable)
+{
+  HASH_TABLE_ITER iter;
+  const XML_Char *cachedOldBase = 0;
+  const XML_Char *cachedNewBase = 0;
+
+  hashTableIterInit(&iter, oldTable);
+
+  for (;;) {
+    ENTITY *newE;
+    const XML_Char *name;
+    const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
+    if (!oldE)
+      break;
+    name = poolCopyString(newPool, oldE->name);
+    if (!name)
+      return 0;
+    newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
+    if (!newE)
+      return 0;
+    if (oldE->systemId) {
+      const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
+      if (!tem)
+       return 0;
+      newE->systemId = tem;
+      if (oldE->base) {
+       if (oldE->base == cachedOldBase)
+         newE->base = cachedNewBase;
+       else {
+         cachedOldBase = oldE->base;
+         tem = poolCopyString(newPool, cachedOldBase);
+         if (!tem)
+           return 0;
+         cachedNewBase = newE->base = tem;
+       }
+      }
+    }
+    else {
+      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
+      if (!tem)
+       return 0;
+      newE->textPtr = tem;
+      newE->textLen = oldE->textLen;
+    }
+    if (oldE->notation) {
+      const XML_Char *tem = poolCopyString(newPool, oldE->notation);
+      if (!tem)
+       return 0;
+      newE->notation = tem;
+    }
+  }
+  return 1;
+}
+
+#define INIT_SIZE 64
+
+static
+int keyeq(KEY s1, KEY s2)
+{
+  for (; *s1 == *s2; s1++, s2++)
+    if (*s1 == 0)
+      return 1;
+  return 0;
+}
+
+static
+unsigned long hash(KEY s)
+{
+  unsigned long h = 0;
+  while (*s)
+    h = (h << 5) + h + (unsigned char)*s++;
+  return h;
+}
+
+static
+NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
+{
+  size_t i;
+  if (table->size == 0) {
+    if (!createSize)
+      return 0;
+    table->v = calloc(INIT_SIZE, sizeof(NAMED *));
+    if (!table->v)
+      return 0;
+    table->size = INIT_SIZE;
+    table->usedLim = INIT_SIZE / 2;
+    i = hash(name) & (table->size - 1);
+  }
+  else {
+    unsigned long h = hash(name);
+    for (i = h & (table->size - 1);
+         table->v[i];
+         i == 0 ? i = table->size - 1 : --i) {
+      if (keyeq(name, table->v[i]->name))
+       return table->v[i];
+    }
+    if (!createSize)
+      return 0;
+    if (table->used == table->usedLim) {
+      /* check for overflow */
+      size_t newSize = table->size * 2;
+      NAMED **newV = calloc(newSize, sizeof(NAMED *));
+      if (!newV)
+       return 0;
+      for (i = 0; i < table->size; i++)
+       if (table->v[i]) {
+         size_t j;
+         for (j = hash(table->v[i]->name) & (newSize - 1);
+              newV[j];
+              j == 0 ? j = newSize - 1 : --j)
+           ;
+         newV[j] = table->v[i];
+       }
+      free(table->v);
+      table->v = newV;
+      table->size = newSize;
+      table->usedLim = newSize/2;
+      for (i = h & (table->size - 1);
+          table->v[i];
+          i == 0 ? i = table->size - 1 : --i)
+       ;
+    }
+  }
+  table->v[i] = calloc(1, createSize);
+  if (!table->v[i])
+    return 0;
+  table->v[i]->name = name;
+  (table->used)++;
+  return table->v[i];
+}
+
+static
+void hashTableDestroy(HASH_TABLE *table)
+{
+  size_t i;
+  for (i = 0; i < table->size; i++) {
+    NAMED *p = table->v[i];
+    if (p)
+      free(p);
+  }
+  if (table->v)
+    free(table->v);
+}
+
+static
+void hashTableInit(HASH_TABLE *p)
+{
+  p->size = 0;
+  p->usedLim = 0;
+  p->used = 0;
+  p->v = 0;
+}
+
+static
+void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
+{
+  iter->p = table->v;
+  iter->end = iter->p + table->size;
+}
+
+static
+NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
+{
+  while (iter->p != iter->end) {
+    NAMED *tem = *(iter->p)++;
+    if (tem)
+      return tem;
+  }
+  return 0;
+}
+
+
+static
+void poolInit(STRING_POOL *pool)
+{
+  pool->blocks = 0;
+  pool->freeBlocks = 0;
+  pool->start = 0;
+  pool->ptr = 0;
+  pool->end = 0;
+}
+
+static
+void poolClear(STRING_POOL *pool)
+{
+  if (!pool->freeBlocks)
+    pool->freeBlocks = pool->blocks;
+  else {
+    BLOCK *p = pool->blocks;
+    while (p) {
+      BLOCK *tem = p->next;
+      p->next = pool->freeBlocks;
+      pool->freeBlocks = p;
+      p = tem;
+    }
+  }
+  pool->blocks = 0;
+  pool->start = 0;
+  pool->ptr = 0;
+  pool->end = 0;
+}
+
+static
+void poolDestroy(STRING_POOL *pool)
+{
+  BLOCK *p = pool->blocks;
+  while (p) {
+    BLOCK *tem = p->next;
+    free(p);
+    p = tem;
+  }
+  pool->blocks = 0;
+  p = pool->freeBlocks;
+  while (p) {
+    BLOCK *tem = p->next;
+    free(p);
+    p = tem;
+  }
+  pool->freeBlocks = 0;
+  pool->ptr = 0;
+  pool->start = 0;
+  pool->end = 0;
+}
+
+static
+XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
+                    const char *ptr, const char *end)
+{
+  if (!pool->ptr && !poolGrow(pool))
+    return 0;
+  for (;;) {
+    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+    if (ptr == end)
+      break;
+    if (!poolGrow(pool))
+      return 0;
+  }
+  return pool->start;
+}
+
+static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
+{
+  do {
+    if (!poolAppendChar(pool, *s))
+      return 0;
+  } while (*s++);
+  s = pool->start;
+  poolFinish(pool);
+  return s;
+}
+
+static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
+{
+  if (!pool->ptr && !poolGrow(pool))
+    return 0;
+  for (; n > 0; --n, s++) {
+    if (!poolAppendChar(pool, *s))
+      return 0;
+
+  }
+  s = pool->start;
+  poolFinish(pool);
+  return s;
+}
+
+static
+XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+                         const char *ptr, const char *end)
+{
+  if (!poolAppend(pool, enc, ptr, end))
+    return 0;
+  if (pool->ptr == pool->end && !poolGrow(pool))
+    return 0;
+  *(pool->ptr)++ = 0;
+  return pool->start;
+}
+
+static
+int poolGrow(STRING_POOL *pool)
+{
+  if (pool->freeBlocks) {
+    if (pool->start == 0) {
+      pool->blocks = pool->freeBlocks;
+      pool->freeBlocks = pool->freeBlocks->next;
+      pool->blocks->next = 0;
+      pool->start = pool->blocks->s;
+      pool->end = pool->start + pool->blocks->size;
+      pool->ptr = pool->start;
+      return 1;
+    }
+    if (pool->end - pool->start < pool->freeBlocks->size) {
+      BLOCK *tem = pool->freeBlocks->next;
+      pool->freeBlocks->next = pool->blocks;
+      pool->blocks = pool->freeBlocks;
+      pool->freeBlocks = tem;
+      memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
+      pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+      pool->start = pool->blocks->s;
+      pool->end = pool->start + pool->blocks->size;
+      return 1;
+    }
+  }
+  if (pool->blocks && pool->start == pool->blocks->s) {
+    int blockSize = (pool->end - pool->start)*2;
+    pool->blocks = realloc(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
+    if (!pool->blocks)
+      return 0;
+    pool->blocks->size = blockSize;
+    pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+    pool->start = pool->blocks->s;
+    pool->end = pool->start + blockSize;
+  }
+  else {
+    BLOCK *tem;
+    int blockSize = pool->end - pool->start;
+    if (blockSize < INIT_BLOCK_SIZE)
+      blockSize = INIT_BLOCK_SIZE;
+    else
+      blockSize *= 2;
+    tem = malloc(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
+    if (!tem)
+      return 0;
+    tem->size = blockSize;
+    tem->next = pool->blocks;
+    pool->blocks = tem;
+    if (pool->ptr != pool->start)
+      memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
+    pool->ptr = tem->s + (pool->ptr - pool->start);
+    pool->start = tem->s;
+    pool->end = tem->s + blockSize;
+  }
+  return 1;
+}
diff --git a/src/xrc/expat/xmlparse/xmlparse.h b/src/xrc/expat/xmlparse/xmlparse.h
new file mode 100644 (file)
index 0000000..6dffe74
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#ifndef XmlParse_INCLUDED
+#define XmlParse_INCLUDED 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef XMLPARSEAPI
+#define XMLPARSEAPI /* as nothing */
+#endif
+
+typedef void *XML_Parser;
+
+#ifdef XML_UNICODE_WCHAR_T
+
+/* XML_UNICODE_WCHAR_T will work only if sizeof(wchar_t) == 2 and wchar_t
+uses Unicode. */
+/* Information is UTF-16 encoded as wchar_ts */
+
+#ifndef XML_UNICODE
+#define XML_UNICODE
+#endif
+
+#include <stddef.h>
+typedef wchar_t XML_Char;
+typedef wchar_t XML_LChar;
+
+#else /* not XML_UNICODE_WCHAR_T */
+
+#ifdef XML_UNICODE
+
+/* Information is UTF-16 encoded as unsigned shorts */
+typedef unsigned short XML_Char;
+typedef char XML_LChar;
+
+#else /* not XML_UNICODE */
+
+/* Information is UTF-8 encoded. */
+typedef char XML_Char;
+typedef char XML_LChar;
+
+#endif /* not XML_UNICODE */
+
+#endif /* not XML_UNICODE_WCHAR_T */
+
+
+/* Constructs a new parser; encoding is the encoding specified by the external
+protocol or null if there is none specified. */
+
+XML_Parser XMLPARSEAPI
+XML_ParserCreate(const XML_Char *encoding);
+
+/* Constructs a new parser and namespace processor.  Element type names
+and attribute names that belong to a namespace will be expanded;
+unprefixed attribute names are never expanded; unprefixed element type
+names are expanded only if there is a default namespace. The expanded
+name is the concatenation of the namespace URI, the namespace separator character,
+and the local part of the name.  If the namespace separator is '\0' then
+the namespace URI and the local part will be concatenated without any
+separator.  When a namespace is not declared, the name and prefix will be
+passed through without expansion. */
+
+XML_Parser XMLPARSEAPI
+XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
+
+
+/* atts is array of name/value pairs, terminated by 0;
+   names and values are 0 terminated. */
+
+typedef void (*XML_StartElementHandler)(void *userData,
+                                       const XML_Char *name,
+                                       const XML_Char **atts);
+
+typedef void (*XML_EndElementHandler)(void *userData,
+                                     const XML_Char *name);
+
+/* s is not 0 terminated. */
+typedef void (*XML_CharacterDataHandler)(void *userData,
+                                        const XML_Char *s,
+                                        int len);
+
+/* target and data are 0 terminated */
+typedef void (*XML_ProcessingInstructionHandler)(void *userData,
+                                                const XML_Char *target,
+                                                const XML_Char *data);
+
+/* data is 0 terminated */
+typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data);
+
+typedef void (*XML_StartCdataSectionHandler)(void *userData);
+typedef void (*XML_EndCdataSectionHandler)(void *userData);
+
+/* This is called for any characters in the XML document for
+which there is no applicable handler.  This includes both
+characters that are part of markup which is of a kind that is
+not reported (comments, markup declarations), or characters
+that are part of a construct which could be reported but
+for which no handler has been supplied. The characters are passed
+exactly as they were in the XML document except that
+they will be encoded in UTF-8.  Line boundaries are not normalized.
+Note that a byte order mark character is not passed to the default handler.
+There are no guarantees about how characters are divided between calls
+to the default handler: for example, a comment might be split between
+multiple calls. */
+
+typedef void (*XML_DefaultHandler)(void *userData,
+                                  const XML_Char *s,
+                                  int len);
+
+/* This is called for the start of the DOCTYPE declaration when the
+name of the DOCTYPE is encountered. */
+typedef void (*XML_StartDoctypeDeclHandler)(void *userData,
+                                           const XML_Char *doctypeName);
+
+/* This is called for the start of the DOCTYPE declaration when the
+closing > is encountered, but after processing any external subset. */
+typedef void (*XML_EndDoctypeDeclHandler)(void *userData);
+
+/* This is called for a declaration of an unparsed (NDATA)
+entity.  The base argument is whatever was set by XML_SetBase.
+The entityName, systemId and notationName arguments will never be null.
+The other arguments may be. */
+
+typedef void (*XML_UnparsedEntityDeclHandler)(void *userData,
+                                             const XML_Char *entityName,
+                                             const XML_Char *base,
+                                             const XML_Char *systemId,
+                                             const XML_Char *publicId,
+                                             const XML_Char *notationName);
+
+/* This is called for a declaration of notation.
+The base argument is whatever was set by XML_SetBase.
+The notationName will never be null.  The other arguments can be. */
+
+typedef void (*XML_NotationDeclHandler)(void *userData,
+                                       const XML_Char *notationName,
+                                       const XML_Char *base,
+                                       const XML_Char *systemId,
+                                       const XML_Char *publicId);
+
+typedef void (*XML_ExternalParsedEntityDeclHandler)(void *userData,
+                                                   const XML_Char *entityName,
+                                                   const XML_Char *base,
+                                                   const XML_Char *systemId,
+                                                   const XML_Char *publicId);
+
+typedef void (*XML_InternalParsedEntityDeclHandler)(void *userData,
+                                                   const XML_Char *entityName,
+                                                   const XML_Char *replacementText,
+                                                   int replacementTextLength);
+
+/* When namespace processing is enabled, these are called once for
+each namespace declaration. The call to the start and end element
+handlers occur between the calls to the start and end namespace
+declaration handlers. For an xmlns attribute, prefix will be null.
+For an xmlns="" attribute, uri will be null. */
+
+typedef void (*XML_StartNamespaceDeclHandler)(void *userData,
+                                             const XML_Char *prefix,
+                                             const XML_Char *uri);
+
+typedef void (*XML_EndNamespaceDeclHandler)(void *userData,
+                                           const XML_Char *prefix);
+
+/* This is called if the document is not standalone (it has an
+external subset or a reference to a parameter entity, but does not
+have standalone="yes"). If this handler returns 0, then processing
+will not continue, and the parser will return a
+XML_ERROR_NOT_STANDALONE error. */
+
+typedef int (*XML_NotStandaloneHandler)(void *userData);
+
+/* This is called for a reference to an external parsed general entity.
+The referenced entity is not automatically parsed.
+The application can parse it immediately or later using
+XML_ExternalEntityParserCreate.
+The parser argument is the parser parsing the entity containing the reference;
+it can be passed as the parser argument to XML_ExternalEntityParserCreate.
+The systemId argument is the system identifier as specified in the entity declaration;
+it will not be null.
+The base argument is the system identifier that should be used as the base for
+resolving systemId if systemId was relative; this is set by XML_SetBase;
+it may be null.
+The publicId argument is the public identifier as specified in the entity declaration,
+or null if none was specified; the whitespace in the public identifier
+will have been normalized as required by the XML spec.
+The context argument specifies the parsing context in the format
+expected by the context argument to
+XML_ExternalEntityParserCreate; context is valid only until the handler
+returns, so if the referenced entity is to be parsed later, it must be copied.
+The handler should return 0 if processing should not continue because of
+a fatal error in the handling of the external entity.
+In this case the calling parser will return an XML_ERROR_EXTERNAL_ENTITY_HANDLING
+error.
+Note that unlike other handlers the first argument is the parser, not userData. */
+
+typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser,
+                                           const XML_Char *context,
+                                           const XML_Char *base,
+                                           const XML_Char *systemId,
+                                           const XML_Char *publicId);
+
+/* This structure is filled in by the XML_UnknownEncodingHandler
+to provide information to the parser about encodings that are unknown
+to the parser.
+The map[b] member gives information about byte sequences
+whose first byte is b.
+If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c.
+If map[b] is -1, then the byte sequence is malformed.
+If map[b] is -n, where n >= 2, then b is the first byte of an n-byte
+sequence that encodes a single Unicode scalar value.
+The data member will be passed as the first argument to the convert function.
+The convert function is used to convert multibyte sequences;
+s will point to a n-byte sequence where map[(unsigned char)*s] == -n.
+The convert function must return the Unicode scalar value
+represented by this byte sequence or -1 if the byte sequence is malformed.
+The convert function may be null if the encoding is a single-byte encoding,
+that is if map[b] >= -1 for all bytes b.
+When the parser is finished with the encoding, then if release is not null,
+it will call release passing it the data member;
+once release has been called, the convert function will not be called again.
+
+Expat places certain restrictions on the encodings that are supported
+using this mechanism.
+
+1. Every ASCII character that can appear in a well-formed XML document,
+other than the characters
+
+  $@\^`{}~
+
+must be represented by a single byte, and that byte must be the
+same byte that represents that character in ASCII.
+
+2. No character may require more than 4 bytes to encode.
+
+3. All characters encoded must have Unicode scalar values <= 0xFFFF,
+(ie characters that would be encoded by surrogates in UTF-16
+are  not allowed).  Note that this restriction doesn't apply to
+the built-in support for UTF-8 and UTF-16.
+
+4. No Unicode character may be encoded by more than one distinct sequence
+of bytes. */
+
+typedef struct {
+  int map[256];
+  void *data;
+  int (*convert)(void *data, const char *s);
+  void (*release)(void *data);
+} XML_Encoding;
+
+/* This is called for an encoding that is unknown to the parser.
+The encodingHandlerData argument is that which was passed as the
+second argument to XML_SetUnknownEncodingHandler.
+The name argument gives the name of the encoding as specified in
+the encoding declaration.
+If the callback can provide information about the encoding,
+it must fill in the XML_Encoding structure, and return 1.
+Otherwise it must return 0.
+If info does not describe a suitable encoding,
+then the parser will return an XML_UNKNOWN_ENCODING error. */
+
+typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData,
+                                         const XML_Char *name,
+                                         XML_Encoding *info);
+
+void XMLPARSEAPI
+XML_SetElementHandler(XML_Parser parser,
+                     XML_StartElementHandler start,
+                     XML_EndElementHandler end);
+
+void XMLPARSEAPI
+XML_SetCharacterDataHandler(XML_Parser parser,
+                           XML_CharacterDataHandler handler);
+
+void XMLPARSEAPI
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+                                   XML_ProcessingInstructionHandler handler);
+void XMLPARSEAPI
+XML_SetCommentHandler(XML_Parser parser,
+                      XML_CommentHandler handler);
+
+void XMLPARSEAPI
+XML_SetCdataSectionHandler(XML_Parser parser,
+                          XML_StartCdataSectionHandler start,
+                          XML_EndCdataSectionHandler end);
+
+/* This sets the default handler and also inhibits expansion of internal entities.
+The entity reference will be passed to the default handler. */
+
+void XMLPARSEAPI
+XML_SetDefaultHandler(XML_Parser parser,
+                     XML_DefaultHandler handler);
+
+/* This sets the default handler but does not inhibit expansion of internal entities.
+The entity reference will not be passed to the default handler. */
+
+void XMLPARSEAPI
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+                           XML_DefaultHandler handler);
+
+void XMLPARSEAPI
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+                         XML_StartDoctypeDeclHandler start,
+                         XML_EndDoctypeDeclHandler end);
+
+void XMLPARSEAPI
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+                                XML_UnparsedEntityDeclHandler handler);
+
+void XMLPARSEAPI
+XML_SetNotationDeclHandler(XML_Parser parser,
+                          XML_NotationDeclHandler handler);
+
+void XMLPARSEAPI
+XML_SetExternalParsedEntityDeclHandler(XML_Parser parser,
+                                      XML_ExternalParsedEntityDeclHandler handler);
+
+void XMLPARSEAPI
+XML_SetInternalParsedEntityDeclHandler(XML_Parser parser,
+                                      XML_InternalParsedEntityDeclHandler handler);
+
+void XMLPARSEAPI
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+                           XML_StartNamespaceDeclHandler start,
+                           XML_EndNamespaceDeclHandler end);
+
+void XMLPARSEAPI
+XML_SetNotStandaloneHandler(XML_Parser parser,
+                           XML_NotStandaloneHandler handler);
+
+void XMLPARSEAPI
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+                               XML_ExternalEntityRefHandler handler);
+
+/* If a non-null value for arg is specified here, then it will be passed
+as the first argument to the external entity ref handler instead
+of the parser object. */
+void XMLPARSEAPI
+XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg);
+
+void XMLPARSEAPI
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+                             XML_UnknownEncodingHandler handler,
+                             void *encodingHandlerData);
+
+/* This can be called within a handler for a start element, end element,
+processing instruction or character data.  It causes the corresponding
+markup to be passed to the default handler. */
+void XMLPARSEAPI XML_DefaultCurrent(XML_Parser parser);
+
+/* This value is passed as the userData argument to callbacks. */
+void XMLPARSEAPI
+XML_SetUserData(XML_Parser parser, void *userData);
+
+/* Returns the last value set by XML_SetUserData or null. */
+#define XML_GetUserData(parser) (*(void **)(parser))
+
+/* This is equivalent to supplying an encoding argument
+to XML_ParserCreate. It must not be called after XML_Parse
+or XML_ParseBuffer. */
+
+int XMLPARSEAPI
+XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
+
+/* If this function is called, then the parser will be passed
+as the first argument to callbacks instead of userData.
+The userData will still be accessible using XML_GetUserData. */
+
+void XMLPARSEAPI
+XML_UseParserAsHandlerArg(XML_Parser parser);
+
+/* Sets the base to be used for resolving relative URIs in system identifiers in
+declarations.  Resolving relative identifiers is left to the application:
+this value will be passed through as the base argument to the
+XML_ExternalEntityRefHandler, XML_NotationDeclHandler
+and XML_UnparsedEntityDeclHandler. The base argument will be copied.
+Returns zero if out of memory, non-zero otherwise. */
+
+int XMLPARSEAPI
+XML_SetBase(XML_Parser parser, const XML_Char *base);
+
+const XML_Char XMLPARSEAPI *
+XML_GetBase(XML_Parser parser);
+
+/* Returns the number of the attribute/value pairs passed in last call
+to the XML_StartElementHandler that were specified in the start-tag
+rather than defaulted. Each attribute/value pair counts as 2; thus
+this correspondds to an index into the atts array passed to the
+XML_StartElementHandler. */
+
+int XMLPARSEAPI XML_GetSpecifiedAttributeCount(XML_Parser parser);
+
+/* Returns the index of the ID attribute passed in the last call to
+XML_StartElementHandler, or -1 if there is no ID attribute.  Each
+attribute/value pair counts as 2; thus this correspondds to an index
+into the atts array passed to the XML_StartElementHandler. */
+int XMLPARSEAPI XML_GetIdAttributeIndex(XML_Parser parser);
+
+/* Parses some input. Returns 0 if a fatal error is detected.
+The last call to XML_Parse must have isFinal true;
+len may be zero for this call (or any other). */
+int XMLPARSEAPI
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
+
+void XMLPARSEAPI *
+XML_GetBuffer(XML_Parser parser, int len);
+
+int XMLPARSEAPI
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
+
+/* Creates an XML_Parser object that can parse an external general entity;
+context is a '\0'-terminated string specifying the parse context;
+encoding is a '\0'-terminated string giving the name of the externally specified encoding,
+or null if there is no externally specified encoding.
+The context string consists of a sequence of tokens separated by formfeeds (\f);
+a token consisting of a name specifies that the general entity of the name
+is open; a token of the form prefix=uri specifies the namespace for a particular
+prefix; a token of the form =uri specifies the default namespace.
+This can be called at any point after the first call to an ExternalEntityRefHandler
+so longer as the parser has not yet been freed.
+The new parser is completely independent and may safely be used in a separate thread.
+The handlers and userData are initialized from the parser argument.
+Returns 0 if out of memory.  Otherwise returns a new XML_Parser object. */
+XML_Parser XMLPARSEAPI
+XML_ExternalEntityParserCreate(XML_Parser parser,
+                              const XML_Char *context,
+                              const XML_Char *encoding);
+
+enum XML_ParamEntityParsing {
+  XML_PARAM_ENTITY_PARSING_NEVER,
+  XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
+  XML_PARAM_ENTITY_PARSING_ALWAYS
+};
+
+/* Controls parsing of parameter entities (including the external DTD
+subset). If parsing of parameter entities is enabled, then references
+to external parameter entities (including the external DTD subset)
+will be passed to the handler set with
+XML_SetExternalEntityRefHandler.  The context passed will be 0.
+Unlike external general entities, external parameter entities can only
+be parsed synchronously.  If the external parameter entity is to be
+parsed, it must be parsed during the call to the external entity ref
+handler: the complete sequence of XML_ExternalEntityParserCreate,
+XML_Parse/XML_ParseBuffer and XML_ParserFree calls must be made during
+this call.  After XML_ExternalEntityParserCreate has been called to
+create the parser for the external parameter entity (context must be 0
+for this call), it is illegal to make any calls on the old parser
+until XML_ParserFree has been called on the newly created parser.  If
+the library has been compiled without support for parameter entity
+parsing (ie without XML_DTD being defined), then
+XML_SetParamEntityParsing will return 0 if parsing of parameter
+entities is requested; otherwise it will return non-zero. */
+
+int XMLPARSEAPI
+XML_SetParamEntityParsing(XML_Parser parser,
+                         enum XML_ParamEntityParsing parsing);
+
+enum XML_Error {
+  XML_ERROR_NONE,
+  XML_ERROR_NO_MEMORY,
+  XML_ERROR_SYNTAX,
+  XML_ERROR_NO_ELEMENTS,
+  XML_ERROR_INVALID_TOKEN,
+  XML_ERROR_UNCLOSED_TOKEN,
+  XML_ERROR_PARTIAL_CHAR,
+  XML_ERROR_TAG_MISMATCH,
+  XML_ERROR_DUPLICATE_ATTRIBUTE,
+  XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
+  XML_ERROR_PARAM_ENTITY_REF,
+  XML_ERROR_UNDEFINED_ENTITY,
+  XML_ERROR_RECURSIVE_ENTITY_REF,
+  XML_ERROR_ASYNC_ENTITY,
+  XML_ERROR_BAD_CHAR_REF,
+  XML_ERROR_BINARY_ENTITY_REF,
+  XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
+  XML_ERROR_MISPLACED_XML_PI,
+  XML_ERROR_UNKNOWN_ENCODING,
+  XML_ERROR_INCORRECT_ENCODING,
+  XML_ERROR_UNCLOSED_CDATA_SECTION,
+  XML_ERROR_EXTERNAL_ENTITY_HANDLING,
+  XML_ERROR_NOT_STANDALONE
+};
+
+/* If XML_Parse or XML_ParseBuffer have returned 0, then XML_GetErrorCode
+returns information about the error. */
+
+enum XML_Error XMLPARSEAPI XML_GetErrorCode(XML_Parser parser);
+
+/* These functions return information about the current parse location.
+They may be called when XML_Parse or XML_ParseBuffer return 0;
+in this case the location is the location of the character at which
+the error was detected.
+They may also be called from any other callback called to report
+some parse event; in this the location is the location of the first
+of the sequence of characters that generated the event. */
+
+int XMLPARSEAPI XML_GetCurrentLineNumber(XML_Parser parser);
+int XMLPARSEAPI XML_GetCurrentColumnNumber(XML_Parser parser);
+long XMLPARSEAPI XML_GetCurrentByteIndex(XML_Parser parser);
+
+/* Return the number of bytes in the current event.
+Returns 0 if the event is in an internal entity. */
+
+int XMLPARSEAPI XML_GetCurrentByteCount(XML_Parser parser);
+
+/* For backwards compatibility with previous versions. */
+#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
+#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
+#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
+
+/* Frees memory used by the parser. */
+void XMLPARSEAPI
+XML_ParserFree(XML_Parser parser);
+
+/* Returns a string describing the error. */
+const XML_LChar XMLPARSEAPI *XML_ErrorString(int code);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlParse_INCLUDED */
diff --git a/src/xrc/expat/xmltok/ascii.h b/src/xrc/expat/xmltok/ascii.h
new file mode 100644 (file)
index 0000000..a8a621c
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#define ASCII_A 0x41
+#define ASCII_B 0x42
+#define ASCII_C 0x43
+#define ASCII_D 0x44
+#define ASCII_E 0x45
+#define ASCII_F 0x46
+#define ASCII_G 0x47
+#define ASCII_H 0x48
+#define ASCII_I 0x49
+#define ASCII_J 0x4A
+#define ASCII_K 0x4B
+#define ASCII_L 0x4C
+#define ASCII_M 0x4D
+#define ASCII_N 0x4E
+#define ASCII_O 0x4F
+#define ASCII_P 0x50
+#define ASCII_Q 0x51
+#define ASCII_R 0x52
+#define ASCII_S 0x53
+#define ASCII_T 0x54
+#define ASCII_U 0x55
+#define ASCII_V 0x56
+#define ASCII_W 0x57
+#define ASCII_X 0x58
+#define ASCII_Y 0x59
+#define ASCII_Z 0x5A
+
+#define ASCII_a 0x61
+#define ASCII_b 0x62
+#define ASCII_c 0x63
+#define ASCII_d 0x64
+#define ASCII_e 0x65
+#define ASCII_f 0x66
+#define ASCII_g 0x67
+#define ASCII_h 0x68
+#define ASCII_i 0x69
+#define ASCII_j 0x6A
+#define ASCII_k 0x6B
+#define ASCII_l 0x6C
+#define ASCII_m 0x6D
+#define ASCII_n 0x6E
+#define ASCII_o 0x6F
+#define ASCII_p 0x70
+#define ASCII_q 0x71
+#define ASCII_r 0x72
+#define ASCII_s 0x73
+#define ASCII_t 0x74
+#define ASCII_u 0x75
+#define ASCII_v 0x76
+#define ASCII_w 0x77
+#define ASCII_x 0x78
+#define ASCII_y 0x79
+#define ASCII_z 0x7A
+
+#define ASCII_0 0x30
+#define ASCII_1 0x31
+#define ASCII_2 0x32
+#define ASCII_3 0x33
+#define ASCII_4 0x34
+#define ASCII_5 0x35
+#define ASCII_6 0x36
+#define ASCII_7 0x37
+#define ASCII_8 0x38
+#define ASCII_9 0x39
+
+#define ASCII_TAB 0x09
+#define ASCII_SPACE 0x20 
+#define ASCII_EXCL 0x21
+#define ASCII_QUOT 0x22
+#define ASCII_AMP 0x26
+#define ASCII_APOS 0x27
+#define ASCII_MINUS 0x2D
+#define ASCII_PERIOD 0x2E
+#define ASCII_COLON 0x3A
+#define ASCII_SEMI 0x3B
+#define ASCII_LT 0x3C
+#define ASCII_EQUALS 0x3D
+#define ASCII_GT 0x3E
+#define ASCII_LSQB 0x5B
+#define ASCII_RSQB 0x5D
+#define ASCII_UNDERSCORE 0x5F
diff --git a/src/xrc/expat/xmltok/asciitab.h b/src/xrc/expat/xmltok/asciitab.h
new file mode 100644 (file)
index 0000000..e994576
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/src/xrc/expat/xmltok/dllmain.c b/src/xrc/expat/xmltok/dllmain.c
new file mode 100644 (file)
index 0000000..d5aa4a3
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#define STRICT 1
+#define WIN32_LEAN_AND_MEAN 1
+
+#include <windows.h>
+
+BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
+{
+  return TRUE;
+}
+
diff --git a/src/xrc/expat/xmltok/iasciitab.h b/src/xrc/expat/xmltok/iasciitab.h
new file mode 100644 (file)
index 0000000..2694d9d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/src/xrc/expat/xmltok/latin1tab.h b/src/xrc/expat/xmltok/latin1tab.h
new file mode 100644 (file)
index 0000000..6e01d50
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
+/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
diff --git a/src/xrc/expat/xmltok/nametab.h b/src/xrc/expat/xmltok/nametab.h
new file mode 100644 (file)
index 0000000..b05e62c
--- /dev/null
@@ -0,0 +1,150 @@
+static const unsigned namingBitmap[] = {
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
+0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
+0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
+0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
+0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
+0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
+0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
+0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
+0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
+0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
+0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
+0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
+0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
+0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
+0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
+0x40000000, 0xF580C900, 0x00000007, 0x02010800,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
+0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
+0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
+0x00000000, 0x00004C40, 0x00000000, 0x00000000,
+0x00000007, 0x00000000, 0x00000000, 0x00000000,
+0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
+0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
+0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
+0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
+0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
+0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
+0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
+0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
+0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
+0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
+0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
+0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
+0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
+0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
+0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
+0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
+};
+static const unsigned char nmstrtPages[] = {
+0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
+0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static const unsigned char namePages[] = {
+0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
+0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/src/xrc/expat/xmltok/utf8tab.h b/src/xrc/expat/xmltok/utf8tab.h
new file mode 100644 (file)
index 0000000..28d9b59
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+
+/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
+/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
diff --git a/src/xrc/expat/xmltok/xmldef.h b/src/xrc/expat/xmltok/xmldef.h
new file mode 100644 (file)
index 0000000..57b8333
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#include <string.h>
+
+#ifdef XML_WINLIB
+
+#define WIN32_LEAN_AND_MEAN
+#define STRICT
+#include <windows.h>
+
+#define malloc(x) HeapAlloc(GetProcessHeap(), 0, (x))
+#define calloc(x, y) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (x)*(y))
+#define free(x) HeapFree(GetProcessHeap(), 0, (x))
+#define realloc(x, y) HeapReAlloc(GetProcessHeap(), 0, x, y)
+#define abort() /* as nothing */
+
+#else /* not XML_WINLIB */
+
+#include <stdlib.h>
+
+#endif /* not XML_WINLIB */
+
+/* This file can be used for any definitions needed in
+particular environments. */
+
+/* Mozilla specific defines */
+
+#ifdef MOZILLA_CLIENT
+
+#include "nspr.h"
+#define malloc(x) PR_Malloc((size_t)(x))
+#define realloc(x, y) PR_Realloc((x), (size_t)(y))
+#define calloc(x, y) PR_Calloc((x),(y))
+#define free(x) PR_Free(x)
+#if PR_BYTES_PER_INT != 4
+#define int int32
+#endif
+
+/* Enable Unicode string processing in expat. */
+#ifndef XML_UNICODE
+#define XML_UNICODE
+#endif
+
+/* Enable external parameter entity parsing in expat */
+#ifndef XML_DTD
+#define XML_DTD 1
+#endif
+
+#endif /* MOZILLA_CLIENT */
diff --git a/src/xrc/expat/xmltok/xmlrole.c b/src/xrc/expat/xmltok/xmlrole.c
new file mode 100644 (file)
index 0000000..50265f8
--- /dev/null
@@ -0,0 +1,1268 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#include "xmldef.h"
+#include "xmlrole.h"
+#include "ascii.h"
+
+/* Doesn't check:
+
+ that ,| are not mixed in a model group
+ content of literals
+
+*/
+
+static const char KW_ANY[] = { ASCII_A, ASCII_N, ASCII_Y, '\0' };
+static const char KW_ATTLIST[] = { ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
+static const char KW_CDATA[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_DOCTYPE[] = { ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
+static const char KW_ELEMENT[] = { ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
+static const char KW_EMPTY[] = { ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
+static const char KW_ENTITIES[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
+static const char KW_ENTITY[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
+static const char KW_FIXED[] = { ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
+static const char KW_ID[] = { ASCII_I, ASCII_D, '\0' };
+static const char KW_IDREF[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
+static const char KW_IDREFS[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
+/* Remove compiler warnings for not using when XML_DTD is not defined */
+#ifdef XML_DTD
+static const char KW_INCLUDE[] = { ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
+static const char KW_IGNORE[] = { ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
+#endif
+static const char KW_IMPLIED[] = { ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
+static const char KW_NDATA[] = { ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_NMTOKEN[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
+static const char KW_NMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
+static const char KW_NOTATION[] = { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, '\0' };
+static const char KW_PCDATA[] = { ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_PUBLIC[] = { ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
+static const char KW_REQUIRED[] = { ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, '\0' };
+static const char KW_SYSTEM[] = { ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
+
+#ifndef MIN_BYTES_PER_CHAR
+#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
+#endif
+
+#ifdef XML_DTD
+#define setTopLevel(state) \
+  ((state)->handler = ((state)->documentEntity \
+                       ? internalSubset \
+                       : externalSubset1))
+#else /* not XML_DTD */
+#define setTopLevel(state) ((state)->handler = internalSubset)
+#endif /* not XML_DTD */
+
+typedef int PROLOG_HANDLER(PROLOG_STATE *state,
+                          int tok,
+                          const char *ptr,
+                          const char *end,
+                          const ENCODING *enc);
+
+static PROLOG_HANDLER
+  prolog0, prolog1, prolog2,
+  doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
+  internalSubset,
+  entity0, entity1, entity2, entity3, entity4, entity5, entity6,
+  entity7, entity8, entity9,
+  notation0, notation1, notation2, notation3, notation4,
+  attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
+  attlist7, attlist8, attlist9,
+  element0, element1, element2, element3, element4, element5, element6,
+  element7,
+#ifdef XML_DTD
+  externalSubset0, externalSubset1,
+  condSect0, condSect1, condSect2,
+#endif /* XML_DTD */
+  declClose,
+  error;
+
+static
+int common(PROLOG_STATE *state, int tok);
+
+static
+int prolog0(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    state->handler = prolog1;
+    return XML_ROLE_NONE;
+  case XML_TOK_XML_DECL:
+    state->handler = prolog1;
+    return XML_ROLE_XML_DECL;
+  case XML_TOK_PI:
+    state->handler = prolog1;
+    return XML_ROLE_NONE;
+  case XML_TOK_COMMENT:
+    state->handler = prolog1;
+  case XML_TOK_BOM:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_OPEN:
+    if (!XmlNameMatchesAscii(enc,
+                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_DOCTYPE))
+      break;
+    state->handler = doctype0;
+    return XML_ROLE_NONE;
+  case XML_TOK_INSTANCE_START:
+    state->handler = error;
+    return XML_ROLE_INSTANCE_START;
+  }
+  return common(state, tok);
+}
+
+static
+int prolog1(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_PI:
+  case XML_TOK_COMMENT:
+  case XML_TOK_BOM:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_OPEN:
+    if (!XmlNameMatchesAscii(enc,
+                            ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                            end,
+                            KW_DOCTYPE))
+      break;
+    state->handler = doctype0;
+    return XML_ROLE_NONE;
+  case XML_TOK_INSTANCE_START:
+    state->handler = error;
+    return XML_ROLE_INSTANCE_START;
+  }
+  return common(state, tok);
+}
+
+static
+int prolog2(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_PI:
+  case XML_TOK_COMMENT:
+    return XML_ROLE_NONE;
+  case XML_TOK_INSTANCE_START:
+    state->handler = error;
+    return XML_ROLE_INSTANCE_START;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype0(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = doctype1;
+    return XML_ROLE_DOCTYPE_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype1(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = internalSubset;
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    state->handler = prolog2;
+    return XML_ROLE_DOCTYPE_CLOSE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = doctype3;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = doctype2;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype2(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = doctype3;
+    return XML_ROLE_DOCTYPE_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype3(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = doctype4;
+    return XML_ROLE_DOCTYPE_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype4(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = internalSubset;
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    state->handler = prolog2;
+    return XML_ROLE_DOCTYPE_CLOSE;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype5(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    state->handler = prolog2;
+    return XML_ROLE_DOCTYPE_CLOSE;
+  }
+  return common(state, tok);
+}
+
+static
+int internalSubset(PROLOG_STATE *state,
+                  int tok,
+                  const char *ptr,
+                  const char *end,
+                  const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_OPEN:
+    if (XmlNameMatchesAscii(enc,
+                           ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_ENTITY)) {
+      state->handler = entity0;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                           ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_ATTLIST)) {
+      state->handler = attlist0;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                           ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_ELEMENT)) {
+      state->handler = element0;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                           ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_NOTATION)) {
+      state->handler = notation0;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_PI:
+  case XML_TOK_COMMENT:
+    return XML_ROLE_NONE;
+  case XML_TOK_PARAM_ENTITY_REF:
+    return XML_ROLE_PARAM_ENTITY_REF;
+  case XML_TOK_CLOSE_BRACKET:
+    state->handler = doctype5;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static
+int externalSubset0(PROLOG_STATE *state,
+                   int tok,
+                   const char *ptr,
+                   const char *end,
+                   const ENCODING *enc)
+{
+  state->handler = externalSubset1;
+  if (tok == XML_TOK_XML_DECL)
+    return XML_ROLE_TEXT_DECL;
+  return externalSubset1(state, tok, ptr, end, enc);
+}
+
+static
+int externalSubset1(PROLOG_STATE *state,
+                   int tok,
+                   const char *ptr,
+                   const char *end,
+                   const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_COND_SECT_OPEN:
+    state->handler = condSect0;
+    return XML_ROLE_NONE;
+  case XML_TOK_COND_SECT_CLOSE:
+    if (state->includeLevel == 0)
+      break;
+    state->includeLevel -= 1;
+    return XML_ROLE_NONE;
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_BRACKET:
+    break;
+  case XML_TOK_NONE:
+    if (state->includeLevel)
+      break;
+    return XML_ROLE_NONE;
+  default:
+    return internalSubset(state, tok, ptr, end, enc);
+  }
+  return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static
+int entity0(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_PERCENT:
+    state->handler = entity1;
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = entity2;
+    return XML_ROLE_GENERAL_ENTITY_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int entity1(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = entity7;
+    return XML_ROLE_PARAM_ENTITY_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int entity2(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = entity4;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = entity3;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_ENTITY_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int entity3(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity4;
+    return XML_ROLE_ENTITY_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+
+static
+int entity4(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity5;
+    return XML_ROLE_ENTITY_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int entity5(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {
+      state->handler = entity6;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static
+int entity6(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = declClose;
+    return XML_ROLE_ENTITY_NOTATION_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int entity7(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = entity9;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = entity8;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_ENTITY_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int entity8(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity9;
+    return XML_ROLE_ENTITY_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int entity9(PROLOG_STATE *state,
+           int tok,
+           const char *ptr,
+           const char *end,
+           const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_ENTITY_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int notation0(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = notation1;
+    return XML_ROLE_NOTATION_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int notation1(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = notation3;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = notation2;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static
+int notation2(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = notation4;
+    return XML_ROLE_NOTATION_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int notation3(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_NOTATION_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int notation4(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_NOTATION_SYSTEM_ID;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_NOTATION_NO_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist0(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = attlist1;
+    return XML_ROLE_ATTLIST_ELEMENT_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist1(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = attlist2;
+    return XML_ROLE_ATTRIBUTE_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist2(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    {
+      static const char *types[] = {
+       KW_CDATA,
+        KW_ID,
+        KW_IDREF,
+        KW_IDREFS,
+        KW_ENTITY,
+        KW_ENTITIES,
+        KW_NMTOKEN,
+        KW_NMTOKENS,
+      };
+      int i;
+      for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
+       if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
+         state->handler = attlist8;
+         return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
+       }
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
+      state->handler = attlist5;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_OPEN_PAREN:
+    state->handler = attlist3;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist3(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NMTOKEN:
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = attlist4;
+    return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist4(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->handler = attlist8;
+    return XML_ROLE_NONE;
+  case XML_TOK_OR:
+    state->handler = attlist3;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist5(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_PAREN:
+    state->handler = attlist6;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+
+static
+int attlist6(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = attlist7;
+    return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist7(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->handler = attlist8;
+    return XML_ROLE_NONE;
+  case XML_TOK_OR:
+    state->handler = attlist6;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+/* default value */
+static
+int attlist8(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_POUND_NAME:
+    if (XmlNameMatchesAscii(enc,
+                           ptr + MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_IMPLIED)) {
+      state->handler = attlist1;
+      return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                           ptr + MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_REQUIRED)) {
+      state->handler = attlist1;
+      return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
+    }
+    if (XmlNameMatchesAscii(enc,
+                           ptr + MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_FIXED)) {
+      state->handler = attlist9;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_LITERAL:
+    state->handler = attlist1;
+    return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist9(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = attlist1;
+    return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int element0(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element1;
+    return XML_ROLE_ELEMENT_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int element1(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
+      state->handler = declClose;
+      return XML_ROLE_CONTENT_EMPTY;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
+      state->handler = declClose;
+      return XML_ROLE_CONTENT_ANY;
+    }
+    break;
+  case XML_TOK_OPEN_PAREN:
+    state->handler = element2;
+    state->level = 1;
+    return XML_ROLE_GROUP_OPEN;
+  }
+  return common(state, tok);
+}
+
+static
+int element2(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_POUND_NAME:
+    if (XmlNameMatchesAscii(enc,
+                           ptr + MIN_BYTES_PER_CHAR(enc),
+                           end,
+                           KW_PCDATA)) {
+      state->handler = element3;
+      return XML_ROLE_CONTENT_PCDATA;
+    }
+    break;
+  case XML_TOK_OPEN_PAREN:
+    state->level = 2;
+    state->handler = element6;
+    return XML_ROLE_GROUP_OPEN;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT;
+  case XML_TOK_NAME_QUESTION:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_OPT;
+  case XML_TOK_NAME_ASTERISK:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_REP;
+  case XML_TOK_NAME_PLUS:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_PLUS;
+  }
+  return common(state, tok);
+}
+
+static
+int element3(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN:
+  case XML_TOK_CLOSE_PAREN_ASTERISK:
+    state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_REP;
+  case XML_TOK_OR:
+    state->handler = element4;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int element4(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element5;
+    return XML_ROLE_CONTENT_ELEMENT;
+  }
+  return common(state, tok);
+}
+
+static
+int element5(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN_ASTERISK:
+    state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_REP;
+  case XML_TOK_OR:
+    state->handler = element4;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int element6(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_PAREN:
+    state->level += 1;
+    return XML_ROLE_GROUP_OPEN;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT;
+  case XML_TOK_NAME_QUESTION:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_OPT;
+  case XML_TOK_NAME_ASTERISK:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_REP;
+  case XML_TOK_NAME_PLUS:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_PLUS;
+  }
+  return common(state, tok);
+}
+
+static
+int element7(PROLOG_STATE *state,
+            int tok,
+            const char *ptr,
+            const char *end,
+            const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->level -= 1;
+    if (state->level == 0)
+      state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE;
+  case XML_TOK_CLOSE_PAREN_ASTERISK:
+    state->level -= 1;
+    if (state->level == 0)
+      state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_REP;
+  case XML_TOK_CLOSE_PAREN_QUESTION:
+    state->level -= 1;
+    if (state->level == 0)
+      state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_OPT;
+  case XML_TOK_CLOSE_PAREN_PLUS:
+    state->level -= 1;
+    if (state->level == 0)
+      state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_PLUS;
+  case XML_TOK_COMMA:
+    state->handler = element6;
+    return XML_ROLE_GROUP_SEQUENCE;
+  case XML_TOK_OR:
+    state->handler = element6;
+    return XML_ROLE_GROUP_CHOICE;
+  }
+  return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static
+int condSect0(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) {
+      state->handler = condSect1;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) {
+      state->handler = condSect2;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static
+int condSect1(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = externalSubset1;
+    state->includeLevel += 1;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int condSect2(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = externalSubset1;
+    return XML_ROLE_IGNORE_SECT;
+  }
+  return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static
+int declClose(PROLOG_STATE *state,
+             int tok,
+             const char *ptr,
+             const char *end,
+             const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+#if 0
+
+static
+int ignore(PROLOG_STATE *state,
+          int tok,
+          const char *ptr,
+          const char *end,
+          const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_DECL_CLOSE:
+    state->handler = internalSubset;
+    return 0;
+  default:
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+#endif
+
+static
+int error(PROLOG_STATE *state,
+         int tok,
+         const char *ptr,
+         const char *end,
+         const ENCODING *enc)
+{
+  return XML_ROLE_NONE;
+}
+
+static
+int common(PROLOG_STATE *state, int tok)
+{
+#ifdef XML_DTD
+  if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
+    return XML_ROLE_INNER_PARAM_ENTITY_REF;
+#endif
+  state->handler = error;
+  return XML_ROLE_ERROR;
+}
+
+void XmlPrologStateInit(PROLOG_STATE *state)
+{
+  state->handler = prolog0;
+#ifdef XML_DTD
+  state->documentEntity = 1;
+  state->includeLevel = 0;
+#endif /* XML_DTD */
+}
+
+#ifdef XML_DTD
+
+void XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
+{
+  state->handler = externalSubset0;
+  state->documentEntity = 0;
+  state->includeLevel = 0;
+}
+
+#endif /* XML_DTD */
diff --git a/src/xrc/expat/xmltok/xmlrole.h b/src/xrc/expat/xmltok/xmlrole.h
new file mode 100644 (file)
index 0000000..22958df
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#ifndef XmlRole_INCLUDED
+#define XmlRole_INCLUDED 1
+
+#include "xmltok.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+  XML_ROLE_ERROR = -1,
+  XML_ROLE_NONE = 0,
+  XML_ROLE_XML_DECL,
+  XML_ROLE_INSTANCE_START,
+  XML_ROLE_DOCTYPE_NAME,
+  XML_ROLE_DOCTYPE_SYSTEM_ID,
+  XML_ROLE_DOCTYPE_PUBLIC_ID,
+  XML_ROLE_DOCTYPE_CLOSE,
+  XML_ROLE_GENERAL_ENTITY_NAME,
+  XML_ROLE_PARAM_ENTITY_NAME,
+  XML_ROLE_ENTITY_VALUE,
+  XML_ROLE_ENTITY_SYSTEM_ID,
+  XML_ROLE_ENTITY_PUBLIC_ID,
+  XML_ROLE_ENTITY_NOTATION_NAME,
+  XML_ROLE_NOTATION_NAME,
+  XML_ROLE_NOTATION_SYSTEM_ID,
+  XML_ROLE_NOTATION_NO_SYSTEM_ID,
+  XML_ROLE_NOTATION_PUBLIC_ID,
+  XML_ROLE_ATTRIBUTE_NAME,
+  XML_ROLE_ATTRIBUTE_TYPE_CDATA,
+  XML_ROLE_ATTRIBUTE_TYPE_ID,
+  XML_ROLE_ATTRIBUTE_TYPE_IDREF,
+  XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
+  XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
+  XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
+  XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
+  XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
+  XML_ROLE_ATTRIBUTE_ENUM_VALUE,
+  XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
+  XML_ROLE_ATTLIST_ELEMENT_NAME,
+  XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
+  XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
+  XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
+  XML_ROLE_FIXED_ATTRIBUTE_VALUE,
+  XML_ROLE_ELEMENT_NAME,
+  XML_ROLE_CONTENT_ANY,
+  XML_ROLE_CONTENT_EMPTY,
+  XML_ROLE_CONTENT_PCDATA,
+  XML_ROLE_GROUP_OPEN,
+  XML_ROLE_GROUP_CLOSE,
+  XML_ROLE_GROUP_CLOSE_REP,
+  XML_ROLE_GROUP_CLOSE_OPT,
+  XML_ROLE_GROUP_CLOSE_PLUS,
+  XML_ROLE_GROUP_CHOICE,
+  XML_ROLE_GROUP_SEQUENCE,
+  XML_ROLE_CONTENT_ELEMENT,
+  XML_ROLE_CONTENT_ELEMENT_REP,
+  XML_ROLE_CONTENT_ELEMENT_OPT,
+  XML_ROLE_CONTENT_ELEMENT_PLUS,
+#ifdef XML_DTD
+  XML_ROLE_TEXT_DECL,
+  XML_ROLE_IGNORE_SECT,
+  XML_ROLE_INNER_PARAM_ENTITY_REF,
+#endif /* XML_DTD */
+  XML_ROLE_PARAM_ENTITY_REF,
+  XML_ROLE_EXTERNAL_GENERAL_ENTITY_NO_NOTATION
+};
+
+typedef struct prolog_state {
+  int (*handler)(struct prolog_state *state,
+                int tok,
+                const char *ptr,
+                const char *end,
+                const ENCODING *enc);
+  unsigned level;
+#ifdef XML_DTD
+  unsigned includeLevel;
+  int documentEntity;
+#endif /* XML_DTD */
+} PROLOG_STATE;
+
+void XMLTOKAPI XmlPrologStateInit(PROLOG_STATE *);
+#ifdef XML_DTD
+void XMLTOKAPI XmlPrologStateInitExternalEntity(PROLOG_STATE *);
+#endif /* XML_DTD */
+
+#define XmlTokenRole(state, tok, ptr, end, enc) \
+ (((state)->handler)(state, tok, ptr, end, enc))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlRole_INCLUDED */
diff --git a/src/xrc/expat/xmltok/xmltok.c b/src/xrc/expat/xmltok/xmltok.c
new file mode 100644 (file)
index 0000000..f7a5b2b
--- /dev/null
@@ -0,0 +1,1557 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#include "xmldef.h"
+#include "xmltok.h"
+#include "nametab.h"
+
+#ifdef XML_DTD
+#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
+#else
+#define IGNORE_SECTION_TOK_VTABLE /* as nothing */
+#endif
+
+#define VTABLE1 \
+  { PREFIX(prologTok), PREFIX(contentTok), \
+    PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
+  { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
+  PREFIX(sameName), \
+  PREFIX(nameMatchesAscii), \
+  PREFIX(nameLength), \
+  PREFIX(skipS), \
+  PREFIX(getAtts), \
+  PREFIX(charRefNumber), \
+  PREFIX(predefinedEntityName), \
+  PREFIX(updatePosition), \
+  PREFIX(isPublicId)
+
+#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
+
+#define UCS2_GET_NAMING(pages, hi, lo) \
+   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
+
+/* A 2 byte UTF-8 representation splits the characters 11 bits
+between the bottom 5 and 6 bits of the bytes.
+We need 8 bits to index into pages, 3 bits to add to that index and
+5 bits to generate the mask. */
+#define UTF8_GET_NAMING2(pages, byte) \
+    (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
+                      + ((((byte)[0]) & 3) << 1) \
+                      + ((((byte)[1]) >> 5) & 1)] \
+         & (1 << (((byte)[1]) & 0x1F)))
+
+/* A 3 byte UTF-8 representation splits the characters 16 bits
+between the bottom 4, 6 and 6 bits of the bytes.
+We need 8 bits to index into pages, 3 bits to add to that index and
+5 bits to generate the mask. */
+#define UTF8_GET_NAMING3(pages, byte) \
+  (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
+                             + ((((byte)[1]) >> 2) & 0xF)] \
+                      << 3) \
+                      + ((((byte)[1]) & 3) << 1) \
+                      + ((((byte)[2]) >> 5) & 1)] \
+         & (1 << (((byte)[2]) & 0x1F)))
+
+#define UTF8_GET_NAMING(pages, p, n) \
+  ((n) == 2 \
+  ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
+  : ((n) == 3 \
+     ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
+     : 0))
+
+#define UTF8_INVALID3(p) \
+  ((*p) == 0xED \
+  ? (((p)[1] & 0x20) != 0) \
+  : ((*p) == 0xEF \
+     ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \
+     : 0))
+
+#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0)
+
+static
+int isNever(const ENCODING *enc, const char *p)
+{
+  return 0;
+}
+
+static
+int utf8_isName2(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
+}
+
+static
+int utf8_isName3(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
+}
+
+#define utf8_isName4 isNever
+
+static
+int utf8_isNmstrt2(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
+}
+
+static
+int utf8_isNmstrt3(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
+}
+
+#define utf8_isNmstrt4 isNever
+
+#define utf8_isInvalid2 isNever
+
+static
+int utf8_isInvalid3(const ENCODING *enc, const char *p)
+{
+  return UTF8_INVALID3((const unsigned char *)p);
+}
+
+static
+int utf8_isInvalid4(const ENCODING *enc, const char *p)
+{
+  return UTF8_INVALID4((const unsigned char *)p);
+}
+
+struct normal_encoding {
+  ENCODING enc;
+  unsigned char type[256];
+#ifdef XML_MIN_SIZE
+  int (*byteType)(const ENCODING *, const char *);
+  int (*isNameMin)(const ENCODING *, const char *);
+  int (*isNmstrtMin)(const ENCODING *, const char *);
+  int (*byteToAscii)(const ENCODING *, const char *);
+  int (*charMatches)(const ENCODING *, const char *, int);
+#endif /* XML_MIN_SIZE */
+  int (*isName2)(const ENCODING *, const char *);
+  int (*isName3)(const ENCODING *, const char *);
+  int (*isName4)(const ENCODING *, const char *);
+  int (*isNmstrt2)(const ENCODING *, const char *);
+  int (*isNmstrt3)(const ENCODING *, const char *);
+  int (*isNmstrt4)(const ENCODING *, const char *);
+  int (*isInvalid2)(const ENCODING *, const char *);
+  int (*isInvalid3)(const ENCODING *, const char *);
+  int (*isInvalid4)(const ENCODING *, const char *);
+};
+
+#ifdef XML_MIN_SIZE
+
+#define STANDARD_VTABLE(E) \
+ E ## byteType, \
+ E ## isNameMin, \
+ E ## isNmstrtMin, \
+ E ## byteToAscii, \
+ E ## charMatches,
+
+#else
+
+#define STANDARD_VTABLE(E) /* as nothing */
+
+#endif
+
+#define NORMAL_VTABLE(E) \
+ E ## isName2, \
+ E ## isName3, \
+ E ## isName4, \
+ E ## isNmstrt2, \
+ E ## isNmstrt3, \
+ E ## isNmstrt4, \
+ E ## isInvalid2, \
+ E ## isInvalid3, \
+ E ## isInvalid4
+
+static int checkCharRefNumber(int);
+
+#include "xmltok_impl.h"
+#include "ascii.h"
+
+#ifdef XML_MIN_SIZE
+#define sb_isNameMin isNever
+#define sb_isNmstrtMin isNever
+#endif
+
+#ifdef XML_MIN_SIZE
+#define MINBPC(enc) ((enc)->minBytesPerChar)
+#else
+/* minimum bytes per character */
+#define MINBPC(enc) 1
+#endif
+
+#define SB_BYTE_TYPE(enc, p) \
+  (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
+
+#ifdef XML_MIN_SIZE
+static
+int sb_byteType(const ENCODING *enc, const char *p)
+{
+  return SB_BYTE_TYPE(enc, p);
+}
+#define BYTE_TYPE(enc, p) \
+ (((const struct normal_encoding *)(enc))->byteType(enc, p))
+#else
+#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define BYTE_TO_ASCII(enc, p) \
+ (((const struct normal_encoding *)(enc))->byteToAscii(enc, p))
+static
+int sb_byteToAscii(const ENCODING *enc, const char *p)
+{
+  return *p;
+}
+#else
+#define BYTE_TO_ASCII(enc, p) (*(p))
+#endif
+
+#define IS_NAME_CHAR(enc, p, n) \
+ (((const struct normal_encoding *)(enc))->isName ## n(enc, p))
+#define IS_NMSTRT_CHAR(enc, p, n) \
+ (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p))
+#define IS_INVALID_CHAR(enc, p, n) \
+ (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p))
+
+#ifdef XML_MIN_SIZE
+#define IS_NAME_CHAR_MINBPC(enc, p) \
+ (((const struct normal_encoding *)(enc))->isNameMin(enc, p))
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ (((const struct normal_encoding *)(enc))->isNmstrtMin(enc, p))
+#else
+#define IS_NAME_CHAR_MINBPC(enc, p) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define CHAR_MATCHES(enc, p, c) \
+ (((const struct normal_encoding *)(enc))->charMatches(enc, p, c))
+static
+int sb_charMatches(const ENCODING *enc, const char *p, int c)
+{
+  return *p == c;
+}
+#else
+/* c is an ASCII character */
+#define CHAR_MATCHES(enc, p, c) (*(p) == c)
+#endif
+
+#define PREFIX(ident) normal_ ## ident
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+enum {  /* UTF8_cvalN is value of masked first byte of N byte sequence */
+  UTF8_cval1 = 0x00,
+  UTF8_cval2 = 0xc0,
+  UTF8_cval3 = 0xe0,
+  UTF8_cval4 = 0xf0
+};
+
+static
+void utf8_toUtf8(const ENCODING *enc,
+                const char **fromP, const char *fromLim,
+                char **toP, const char *toLim)
+{
+  char *to;
+  const char *from;
+  if (fromLim - *fromP > toLim - *toP) {
+    /* Avoid copying partial characters. */
+    for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
+      if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
+       break;
+  }
+  for (to = *toP, from = *fromP; from != fromLim; from++, to++)
+    *to = *from;
+  *fromP = from;
+  *toP = to;
+}
+
+static
+void utf8_toUtf16(const ENCODING *enc,
+                 const char **fromP, const char *fromLim,
+                 unsigned short **toP, const unsigned short *toLim)
+{
+  unsigned short *to = *toP;
+  const char *from = *fromP;
+  while (from != fromLim && to != toLim) {
+    switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
+    case BT_LEAD2:
+      *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f);
+      from += 2;
+      break;
+    case BT_LEAD3:
+      *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f);
+      from += 3;
+      break;
+    case BT_LEAD4:
+      {
+       unsigned long n;
+       if (to + 1 == toLim)
+         break;
+       n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
+       n -= 0x10000;
+       to[0] = (unsigned short)((n >> 10) | 0xD800);
+       to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
+       to += 2;
+       from += 4;
+      }
+      break;
+    default:
+      *to++ = *from++;
+      break;
+    }
+  }
+  *fromP = from;
+  *toP = to;
+}
+
+#ifdef XML_NS
+static const struct normal_encoding utf8_encoding_ns = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#include "asciitab.h"
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+#endif
+
+static const struct normal_encoding utf8_encoding = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_utf8_encoding_ns = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#include "iasciitab.h"
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#endif
+
+static const struct normal_encoding internal_utf8_encoding = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+static
+void latin1_toUtf8(const ENCODING *enc,
+                  const char **fromP, const char *fromLim,
+                  char **toP, const char *toLim)
+{
+  for (;;) {
+    unsigned char c;
+    if (*fromP == fromLim)
+      break;
+    c = (unsigned char)**fromP;
+    if (c & 0x80) {
+      if (toLim - *toP < 2)
+       break;
+      *(*toP)++ = ((c >> 6) | UTF8_cval2);
+      *(*toP)++ = ((c & 0x3f) | 0x80);
+      (*fromP)++;
+    }
+    else {
+      if (*toP == toLim)
+       break;
+      *(*toP)++ = *(*fromP)++;
+    }
+  }
+}
+
+static
+void latin1_toUtf16(const ENCODING *enc,
+                   const char **fromP, const char *fromLim,
+                   unsigned short **toP, const unsigned short *toLim)
+{
+  while (*fromP != fromLim && *toP != toLim)
+    *(*toP)++ = (unsigned char)*(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding latin1_encoding_ns = {
+  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+  {
+#include "asciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding latin1_encoding = {
+  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+static
+void ascii_toUtf8(const ENCODING *enc,
+                 const char **fromP, const char *fromLim,
+                 char **toP, const char *toLim)
+{
+  while (*fromP != fromLim && *toP != toLim)
+    *(*toP)++ = *(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding ascii_encoding_ns = {
+  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+  {
+#include "asciitab.h"
+/* BT_NONXML == 0 */
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding ascii_encoding = {
+  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+/* BT_NONXML == 0 */
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+static int unicode_byte_type(char hi, char lo)
+{
+  switch ((unsigned char)hi) {
+  case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+    return BT_LEAD4;
+  case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+    return BT_TRAIL;
+  case 0xFF:
+    switch ((unsigned char)lo) {
+    case 0xFF:
+    case 0xFE:
+      return BT_NONXML;
+    }
+    break;
+  }
+  return BT_NONASCII;
+}
+
+#define DEFINE_UTF16_TO_UTF8(E) \
+static \
+void E ## toUtf8(const ENCODING *enc, \
+                const char **fromP, const char *fromLim, \
+                char **toP, const char *toLim) \
+{ \
+  const char *from; \
+  for (from = *fromP; from != fromLim; from += 2) { \
+    int plane; \
+    unsigned char lo2; \
+    unsigned char lo = GET_LO(from); \
+    unsigned char hi = GET_HI(from); \
+    switch (hi) { \
+    case 0: \
+      if (lo < 0x80) { \
+        if (*toP == toLim) { \
+          *fromP = from; \
+         return; \
+        } \
+        *(*toP)++ = lo; \
+        break; \
+      } \
+      /* fall through */ \
+    case 0x1: case 0x2: case 0x3: \
+    case 0x4: case 0x5: case 0x6: case 0x7: \
+      if (toLim -  *toP < 2) { \
+        *fromP = from; \
+       return; \
+      } \
+      *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \
+      *(*toP)++ = ((lo & 0x3f) | 0x80); \
+      break; \
+    default: \
+      if (toLim -  *toP < 3)  { \
+        *fromP = from; \
+       return; \
+      } \
+      /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
+      *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
+      *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
+      *(*toP)++ = ((lo & 0x3f) | 0x80); \
+      break; \
+    case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
+      if (toLim -  *toP < 4) { \
+       *fromP = from; \
+       return; \
+      } \
+      plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
+      *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
+      *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
+      from += 2; \
+      lo2 = GET_LO(from); \
+      *(*toP)++ = (((lo & 0x3) << 4) \
+                  | ((GET_HI(from) & 0x3) << 2) \
+                  | (lo2 >> 6) \
+                  | 0x80); \
+      *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
+      break; \
+    } \
+  } \
+  *fromP = from; \
+}
+
+#define DEFINE_UTF16_TO_UTF16(E) \
+static \
+void E ## toUtf16(const ENCODING *enc, \
+                 const char **fromP, const char *fromLim, \
+                 unsigned short **toP, const unsigned short *toLim) \
+{ \
+  /* Avoid copying first half only of surrogate */ \
+  if (fromLim - *fromP > ((toLim - *toP) << 1) \
+      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
+    fromLim -= 2; \
+  for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
+    *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
+}
+
+#define SET2(ptr, ch) \
+  (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[0])
+#define GET_HI(ptr) ((unsigned char)(ptr)[1])
+
+DEFINE_UTF16_TO_UTF8(little2_)
+DEFINE_UTF16_TO_UTF16(little2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define SET2(ptr, ch) \
+  (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[1])
+#define GET_HI(ptr) ((unsigned char)(ptr)[0])
+
+DEFINE_UTF16_TO_UTF8(big2_)
+DEFINE_UTF16_TO_UTF16(big2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define LITTLE2_BYTE_TYPE(enc, p) \
+ ((p)[1] == 0 \
+  ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
+  : unicode_byte_type((p)[1], (p)[0]))
+#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
+#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
+#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
+#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
+
+#ifdef XML_MIN_SIZE
+
+static
+int little2_byteType(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_BYTE_TYPE(enc, p);
+}
+
+static
+int little2_byteToAscii(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_BYTE_TO_ASCII(enc, p);
+}
+
+static
+int little2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+  return LITTLE2_CHAR_MATCHES(enc, p, c);
+}
+
+static
+int little2_isNameMin(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static
+int little2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) little2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) 
+#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding little2_encoding_ns = { 
+  { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 12
+    1
+#else
+    0
+#endif
+  },
+  {
+#include "asciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding little2_encoding = { 
+  { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 12
+    1
+#else
+    0
+#endif
+  },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#if XML_BYTE_ORDER != 21
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_little2_encoding_ns = { 
+  { VTABLE, 2, 0, 1 },
+  {
+#include "iasciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_little2_encoding = { 
+  { VTABLE, 2, 0, 1 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+
+#define BIG2_BYTE_TYPE(enc, p) \
+ ((p)[0] == 0 \
+  ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
+  : unicode_byte_type((p)[0], (p)[1]))
+#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
+#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
+#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
+#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
+
+#ifdef XML_MIN_SIZE
+
+static
+int big2_byteType(const ENCODING *enc, const char *p)
+{
+  return BIG2_BYTE_TYPE(enc, p);
+}
+
+static
+int big2_byteToAscii(const ENCODING *enc, const char *p)
+{
+  return BIG2_BYTE_TO_ASCII(enc, p);
+}
+
+static
+int big2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+  return BIG2_CHAR_MATCHES(enc, p, c);
+}
+
+static
+int big2_isNameMin(const ENCODING *enc, const char *p)
+{
+  return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static
+int big2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+  return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) big2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) 
+#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding big2_encoding_ns = {
+  { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 21
+  1
+#else
+  0
+#endif
+  },
+  {
+#include "asciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding big2_encoding = {
+  { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 21
+  1
+#else
+  0
+#endif
+  },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#if XML_BYTE_ORDER != 12
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_big2_encoding_ns = {
+  { VTABLE, 2, 0, 1 },
+  {
+#include "iasciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_big2_encoding = {
+  { VTABLE, 2, 0, 1 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+#undef PREFIX
+
+static
+int streqci(const char *s1, const char *s2)
+{
+  for (;;) {
+    char c1 = *s1++;
+    char c2 = *s2++;
+    if (ASCII_a <= c1 && c1 <= ASCII_z)
+      c1 += ASCII_A - ASCII_a;
+    if (ASCII_a <= c2 && c2 <= ASCII_z)
+      c2 += ASCII_A - ASCII_a;
+    if (c1 != c2)
+      return 0;
+    if (!c1)
+      break;
+  }
+  return 1;
+}
+
+static
+void initUpdatePosition(const ENCODING *enc, const char *ptr,
+                       const char *end, POSITION *pos)
+{
+  normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
+}
+
+static
+int toAscii(const ENCODING *enc, const char *ptr, const char *end)
+{
+  char buf[1];
+  char *p = buf;
+  XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
+  if (p == buf)
+    return -1;
+  else
+    return buf[0];
+}
+
+static
+int isSpace(int c)
+{
+  switch (c) {
+  case 0x20:
+  case 0xD:
+  case 0xA:
+  case 0x9:    
+    return 1;
+  }
+  return 0;
+}
+
+/* Return 1 if there's just optional white space
+or there's an S followed by name=val. */
+static
+int parsePseudoAttribute(const ENCODING *enc,
+                        const char *ptr,
+                        const char *end,
+                        const char **namePtr,
+                        const char **nameEndPtr,
+                        const char **valPtr,
+                        const char **nextTokPtr)
+{
+  int c;
+  char open;
+  if (ptr == end) {
+    *namePtr = 0;
+    return 1;
+  }
+  if (!isSpace(toAscii(enc, ptr, end))) {
+    *nextTokPtr = ptr;
+    return 0;
+  }
+  do {
+    ptr += enc->minBytesPerChar;
+  } while (isSpace(toAscii(enc, ptr, end)));
+  if (ptr == end) {
+    *namePtr = 0;
+    return 1;
+  }
+  *namePtr = ptr;
+  for (;;) {
+    c = toAscii(enc, ptr, end);
+    if (c == -1) {
+      *nextTokPtr = ptr;
+      return 0;
+    }
+    if (c == ASCII_EQUALS) {
+      *nameEndPtr = ptr;
+      break;
+    }
+    if (isSpace(c)) {
+      *nameEndPtr = ptr;
+      do {
+       ptr += enc->minBytesPerChar;
+      } while (isSpace(c = toAscii(enc, ptr, end)));
+      if (c != ASCII_EQUALS) {
+       *nextTokPtr = ptr;
+       return 0;
+      }
+      break;
+    }
+    ptr += enc->minBytesPerChar;
+  }
+  if (ptr == *namePtr) {
+    *nextTokPtr = ptr;
+    return 0;
+  }
+  ptr += enc->minBytesPerChar;
+  c = toAscii(enc, ptr, end);
+  while (isSpace(c)) {
+    ptr += enc->minBytesPerChar;
+    c = toAscii(enc, ptr, end);
+  }
+  if (c != ASCII_QUOT && c != ASCII_APOS) {
+    *nextTokPtr = ptr;
+    return 0;
+  }
+  open = c;
+  ptr += enc->minBytesPerChar;
+  *valPtr = ptr;
+  for (;; ptr += enc->minBytesPerChar) {
+    c = toAscii(enc, ptr, end);
+    if (c == open)
+      break;
+    if (!(ASCII_a <= c && c <= ASCII_z)
+       && !(ASCII_A <= c && c <= ASCII_Z)
+       && !(ASCII_0 <= c && c <= ASCII_9)
+       && c != ASCII_PERIOD
+       && c != ASCII_MINUS
+       && c != ASCII_UNDERSCORE) {
+      *nextTokPtr = ptr;
+      return 0;
+    }
+  }
+  *nextTokPtr = ptr + enc->minBytesPerChar;
+  return 1;
+}
+
+static const char KW_version[] = {
+  ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'
+};
+
+static const char KW_encoding[] = {
+  ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'
+};
+
+static const char KW_standalone[] = {
+  ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'
+};
+
+static const char KW_yes[] = {
+  ASCII_y, ASCII_e, ASCII_s,  '\0'
+};
+
+static const char KW_no[] = {
+  ASCII_n, ASCII_o,  '\0'
+};
+
+static
+int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
+                                                    const char *,
+                                                    const char *),
+                  int isGeneralTextEntity,
+                  const ENCODING *enc,
+                  const char *ptr,
+                  const char *end,
+                  const char **badPtr,
+                  const char **versionPtr,
+                  const char **encodingName,
+                  const ENCODING **encoding,
+                  int *standalone)
+{
+  const char *val = 0;
+  const char *name = 0;
+  const char *nameEnd = 0;
+  ptr += 5 * enc->minBytesPerChar;
+  end -= 2 * enc->minBytesPerChar;
+  if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) || !name) {
+    *badPtr = ptr;
+    return 0;
+  }
+  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
+    if (!isGeneralTextEntity) {
+      *badPtr = name;
+      return 0;
+    }
+  }
+  else {
+    if (versionPtr)
+      *versionPtr = val;
+    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+      *badPtr = ptr;
+      return 0;
+    }
+    if (!name) {
+      if (isGeneralTextEntity) {
+       /* a TextDecl must have an EncodingDecl */
+       *badPtr = ptr;
+       return 0;
+      }
+      return 1;
+    }
+  }
+  if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
+    int c = toAscii(enc, val, end);
+    if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {
+      *badPtr = val;
+      return 0;
+    }
+    if (encodingName)
+      *encodingName = val;
+    if (encoding)
+      *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
+    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+      *badPtr = ptr;
+      return 0;
+    }
+    if (!name)
+      return 1;
+  }
+  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) || isGeneralTextEntity) {
+    *badPtr = name;
+    return 0;
+  }
+  if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
+    if (standalone)
+      *standalone = 1;
+  }
+  else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
+    if (standalone)
+      *standalone = 0;
+  }
+  else {
+    *badPtr = val;
+    return 0;
+  }
+  while (isSpace(toAscii(enc, ptr, end)))
+    ptr += enc->minBytesPerChar;
+  if (ptr != end) {
+    *badPtr = ptr;
+    return 0;
+  }
+  return 1;
+}
+
+static
+int checkCharRefNumber(int result)
+{
+  switch (result >> 8) {
+  case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+  case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+    return -1;
+  case 0:
+    if (latin1_encoding.type[result] == BT_NONXML)
+      return -1;
+    break;
+  case 0xFF:
+    if (result == 0xFFFE || result == 0xFFFF)
+      return -1;
+    break;
+  }
+  return result;
+}
+
+int XmlUtf8Encode(int c, char *buf)
+{
+  enum {
+    /* minN is minimum legal resulting value for N byte sequence */
+    min2 = 0x80,
+    min3 = 0x800,
+    min4 = 0x10000
+  };
+
+  if (c < 0)
+    return 0;
+  if (c < min2) {
+    buf[0] = (c | UTF8_cval1);
+    return 1;
+  }
+  if (c < min3) {
+    buf[0] = ((c >> 6) | UTF8_cval2);
+    buf[1] = ((c & 0x3f) | 0x80);
+    return 2;
+  }
+  if (c < min4) {
+    buf[0] = ((c >> 12) | UTF8_cval3);
+    buf[1] = (((c >> 6) & 0x3f) | 0x80);
+    buf[2] = ((c & 0x3f) | 0x80);
+    return 3;
+  }
+  if (c < 0x110000) {
+    buf[0] = ((c >> 18) | UTF8_cval4);
+    buf[1] = (((c >> 12) & 0x3f) | 0x80);
+    buf[2] = (((c >> 6) & 0x3f) | 0x80);
+    buf[3] = ((c & 0x3f) | 0x80);
+    return 4;
+  }
+  return 0;
+}
+
+int XmlUtf16Encode(int charNum, unsigned short *buf)
+{
+  if (charNum < 0)
+    return 0;
+  if (charNum < 0x10000) {
+    buf[0] = charNum;
+    return 1;
+  }
+  if (charNum < 0x110000) {
+    charNum -= 0x10000;
+    buf[0] = (charNum >> 10) + 0xD800;
+    buf[1] = (charNum & 0x3FF) + 0xDC00;
+    return 2;
+  }
+  return 0;
+}
+
+struct unknown_encoding {
+  struct normal_encoding normal;
+  int (*convert)(void *userData, const char *p);
+  void *userData;
+  unsigned short utf16[256];
+  char utf8[256][4];
+};
+
+int XmlSizeOfUnknownEncoding(void)
+{
+  return sizeof(struct unknown_encoding);
+}
+
+static
+int unknown_isName(const ENCODING *enc, const char *p)
+{
+  int c = ((const struct unknown_encoding *)enc)
+         ->convert(((const struct unknown_encoding *)enc)->userData, p);
+  if (c & ~0xFFFF)
+    return 0;
+  return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
+}
+
+static
+int unknown_isNmstrt(const ENCODING *enc, const char *p)
+{
+  int c = ((const struct unknown_encoding *)enc)
+         ->convert(((const struct unknown_encoding *)enc)->userData, p);
+  if (c & ~0xFFFF)
+    return 0;
+  return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
+}
+
+static
+int unknown_isInvalid(const ENCODING *enc, const char *p)
+{
+  int c = ((const struct unknown_encoding *)enc)
+          ->convert(((const struct unknown_encoding *)enc)->userData, p);
+  return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
+}
+
+static
+void unknown_toUtf8(const ENCODING *enc,
+                   const char **fromP, const char *fromLim,
+                   char **toP, const char *toLim)
+{
+  char buf[XML_UTF8_ENCODE_MAX];
+  for (;;) {
+    const char *utf8;
+    int n;
+    if (*fromP == fromLim)
+      break;
+    utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP];
+    n = *utf8++;
+    if (n == 0) {
+      int c = ((const struct unknown_encoding *)enc)
+             ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
+      n = XmlUtf8Encode(c, buf);
+      if (n > toLim - *toP)
+       break;
+      utf8 = buf;
+      *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
+                - (BT_LEAD2 - 2);
+    }
+    else {
+      if (n > toLim - *toP)
+       break;
+      (*fromP)++;
+    }
+    do {
+      *(*toP)++ = *utf8++;
+    } while (--n != 0);
+  }
+}
+
+static
+void unknown_toUtf16(const ENCODING *enc,
+                    const char **fromP, const char *fromLim,
+                    unsigned short **toP, const unsigned short *toLim)
+{
+  while (*fromP != fromLim && *toP != toLim) {
+    unsigned short c
+      = ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP];
+    if (c == 0) {
+      c = (unsigned short)((const struct unknown_encoding *)enc)
+          ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
+      *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
+                - (BT_LEAD2 - 2);
+    }
+    else
+      (*fromP)++;
+    *(*toP)++ = c;
+  }
+}
+
+ENCODING *
+XmlInitUnknownEncoding(void *mem,
+                      int *table,
+                      int (*convert)(void *userData, const char *p),
+                      void *userData)
+{
+  int i;
+  struct unknown_encoding *e = mem;
+  for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
+    ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
+  for (i = 0; i < 128; i++)
+    if (latin1_encoding.type[i] != BT_OTHER
+        && latin1_encoding.type[i] != BT_NONXML
+       && table[i] != i)
+      return 0;
+  for (i = 0; i < 256; i++) {
+    int c = table[i];
+    if (c == -1) {
+      e->normal.type[i] = BT_MALFORM;
+      /* This shouldn't really get used. */
+      e->utf16[i] = 0xFFFF;
+      e->utf8[i][0] = 1;
+      e->utf8[i][1] = 0;
+    }
+    else if (c < 0) {
+      if (c < -4)
+       return 0;
+      e->normal.type[i] = BT_LEAD2 - (c + 2);
+      e->utf8[i][0] = 0;
+      e->utf16[i] = 0;
+    }
+    else if (c < 0x80) {
+      if (latin1_encoding.type[c] != BT_OTHER
+         && latin1_encoding.type[c] != BT_NONXML
+         && c != i)
+       return 0;
+      e->normal.type[i] = latin1_encoding.type[c];
+      e->utf8[i][0] = 1;
+      e->utf8[i][1] = (char)c;
+      e->utf16[i] = c == 0 ? 0xFFFF : c;
+    }
+    else if (checkCharRefNumber(c) < 0) {
+      e->normal.type[i] = BT_NONXML;
+      /* This shouldn't really get used. */
+      e->utf16[i] = 0xFFFF;
+      e->utf8[i][0] = 1;
+      e->utf8[i][1] = 0;
+    }
+    else {
+      if (c > 0xFFFF)
+       return 0;
+      if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
+       e->normal.type[i] = BT_NMSTRT;
+      else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
+       e->normal.type[i] = BT_NAME;
+      else
+       e->normal.type[i] = BT_OTHER;
+      e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
+      e->utf16[i] = c;
+    }
+  }
+  e->userData = userData;
+  e->convert = convert;
+  if (convert) {
+    e->normal.isName2 = unknown_isName;
+    e->normal.isName3 = unknown_isName;
+    e->normal.isName4 = unknown_isName;
+    e->normal.isNmstrt2 = unknown_isNmstrt;
+    e->normal.isNmstrt3 = unknown_isNmstrt;
+    e->normal.isNmstrt4 = unknown_isNmstrt;
+    e->normal.isInvalid2 = unknown_isInvalid;
+    e->normal.isInvalid3 = unknown_isInvalid;
+    e->normal.isInvalid4 = unknown_isInvalid;
+  }
+  e->normal.enc.utf8Convert = unknown_toUtf8;
+  e->normal.enc.utf16Convert = unknown_toUtf16;
+  return &(e->normal.enc);
+}
+
+/* If this enumeration is changed, getEncodingIndex and encodings
+must also be changed. */
+enum {
+  UNKNOWN_ENC = -1,
+  ISO_8859_1_ENC = 0,
+  US_ASCII_ENC,
+  UTF_8_ENC,
+  UTF_16_ENC,
+  UTF_16BE_ENC,
+  UTF_16LE_ENC,
+  /* must match encodingNames up to here */
+  NO_ENC
+};
+
+static const char KW_ISO_8859_1[] = {
+  ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'
+};
+static const char KW_US_ASCII[] = {
+  ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, '\0'
+};
+static const char KW_UTF_8[] = {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'
+};
+static const char KW_UTF_16[] =        {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'
+};
+static const char KW_UTF_16BE[] = {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, '\0'
+};
+static const char KW_UTF_16LE[] = {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, '\0'
+};
+
+static
+int getEncodingIndex(const char *name)
+{
+  static const char *encodingNames[] = {
+    KW_ISO_8859_1,
+    KW_US_ASCII,
+    KW_UTF_8,
+    KW_UTF_16,
+    KW_UTF_16BE,
+    KW_UTF_16LE,
+  };
+  int i;
+  if (name == 0)
+    return NO_ENC;
+  for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
+    if (streqci(name, encodingNames[i]))
+      return i;
+  return UNKNOWN_ENC;
+}
+
+/* For binary compatibility, we store the index of the encoding specified
+at initialization in the isUtf16 member. */
+
+#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
+#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
+
+/* This is what detects the encoding.
+encodingTable maps from encoding indices to encodings;
+INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding;
+state is XML_CONTENT_STATE if we're parsing an external text entity,
+and XML_PROLOG_STATE otherwise.
+*/
+
+
+static
+int initScan(const ENCODING **encodingTable,
+            const INIT_ENCODING *enc,
+            int state,
+            const char *ptr,
+            const char *end,
+            const char **nextTokPtr)
+{
+  const ENCODING **encPtr;
+
+  if (ptr == end)
+    return XML_TOK_NONE;
+  encPtr = enc->encPtr;
+  if (ptr + 1 == end) {
+    /* only a single byte available for auto-detection */
+#ifndef XML_DTD /* FIXME */
+    /* a well-formed document entity must have more than one byte */
+    if (state != XML_CONTENT_STATE)
+      return XML_TOK_PARTIAL;
+#endif
+    /* so we're parsing an external text entity... */
+    /* if UTF-16 was externally specified, then we need at least 2 bytes */
+    switch (INIT_ENC_INDEX(enc)) {
+    case UTF_16_ENC:
+    case UTF_16LE_ENC:
+    case UTF_16BE_ENC:
+      return XML_TOK_PARTIAL;
+    }
+    switch ((unsigned char)*ptr) {
+    case 0xFE:
+    case 0xFF:
+    case 0xEF: /* possibly first byte of UTF-8 BOM */
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+         && state == XML_CONTENT_STATE)
+       break;
+      /* fall through */
+    case 0x00:
+    case 0x3C:
+      return XML_TOK_PARTIAL;
+    }
+  }
+  else {
+    switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
+    case 0xFEFF:
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+         && state == XML_CONTENT_STATE)
+       break;
+      *nextTokPtr = ptr + 2;
+      *encPtr = encodingTable[UTF_16BE_ENC];
+      return XML_TOK_BOM;
+    /* 00 3C is handled in the default case */
+    case 0x3C00:
+      if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
+          || INIT_ENC_INDEX(enc) == UTF_16_ENC)
+         && state == XML_CONTENT_STATE)
+       break;
+      *encPtr = encodingTable[UTF_16LE_ENC];
+      return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+    case 0xFFFE:
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+         && state == XML_CONTENT_STATE)
+       break;
+      *nextTokPtr = ptr + 2;
+      *encPtr = encodingTable[UTF_16LE_ENC];
+      return XML_TOK_BOM;
+    case 0xEFBB:
+      /* Maybe a UTF-8 BOM (EF BB BF) */
+      /* If there's an explicitly specified (external) encoding
+         of ISO-8859-1 or some flavour of UTF-16
+         and this is an external text entity,
+        don't look for the BOM,
+         because it might be a legal data. */
+      if (state == XML_CONTENT_STATE) {
+       int e = INIT_ENC_INDEX(enc);
+       if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC)
+         break;
+      }
+      if (ptr + 2 == end)
+       return XML_TOK_PARTIAL;
+      if ((unsigned char)ptr[2] == 0xBF) {
+       *encPtr = encodingTable[UTF_8_ENC];
+       return XML_TOK_BOM;
+      }
+      break;
+    default:
+      if (ptr[0] == '\0') {
+       /* 0 isn't a legal data character. Furthermore a document entity can only
+          start with ASCII characters.  So the only way this can fail to be big-endian
+          UTF-16 if it it's an external parsed general entity that's labelled as
+          UTF-16LE. */
+       if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
+         break;
+       *encPtr = encodingTable[UTF_16BE_ENC];
+       return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+      }
+      else if (ptr[1] == '\0') {
+       /* We could recover here in the case:
+           - parsing an external entity
+           - second byte is 0
+           - no externally specified encoding
+           - no encoding declaration
+          by assuming UTF-16LE.  But we don't, because this would mean when
+          presented just with a single byte, we couldn't reliably determine
+          whether we needed further bytes. */
+       if (state == XML_CONTENT_STATE)
+         break;
+       *encPtr = encodingTable[UTF_16LE_ENC];
+       return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+      }
+      break;
+    }
+  }
+  *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
+  return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+}
+
+
+#define NS(x) x
+#define ns(x) x
+#include "xmltok_ns.c"
+#undef NS
+#undef ns
+
+#ifdef XML_NS
+
+#define NS(x) x ## NS
+#define ns(x) x ## _ns
+
+#include "xmltok_ns.c"
+
+#undef NS
+#undef ns
+
+ENCODING *
+XmlInitUnknownEncodingNS(void *mem,
+                        int *table,
+                        int (*convert)(void *userData, const char *p),
+                        void *userData)
+{
+  ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
+  if (enc)
+    ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
+  return enc;
+}
+
+#endif /* XML_NS */
diff --git a/src/xrc/expat/xmltok/xmltok.h b/src/xrc/expat/xmltok/xmltok.h
new file mode 100644 (file)
index 0000000..f7703ce
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#ifndef XmlTok_INCLUDED
+#define XmlTok_INCLUDED 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef XMLTOKAPI
+#define XMLTOKAPI /* as nothing */
+#endif
+
+/* The following token may be returned by XmlContentTok */
+#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of
+                                    illegal ]]> sequence */
+/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
+#define XML_TOK_NONE -4    /* The string to be scanned is empty */
+#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
+                                  might be part of CRLF sequence */ 
+#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
+#define XML_TOK_PARTIAL -1 /* only part of a token */
+#define XML_TOK_INVALID 0
+
+/* The following tokens are returned by XmlContentTok; some are also
+  returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */
+
+#define XML_TOK_START_TAG_WITH_ATTS 1
+#define XML_TOK_START_TAG_NO_ATTS 2
+#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
+#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
+#define XML_TOK_END_TAG 5
+#define XML_TOK_DATA_CHARS 6
+#define XML_TOK_DATA_NEWLINE 7
+#define XML_TOK_CDATA_SECT_OPEN 8
+#define XML_TOK_ENTITY_REF 9
+#define XML_TOK_CHAR_REF 10     /* numeric character reference */
+
+/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
+#define XML_TOK_PI 11      /* processing instruction */
+#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
+#define XML_TOK_COMMENT 13
+#define XML_TOK_BOM 14     /* Byte order mark */
+
+/* The following tokens are returned only by XmlPrologTok */
+#define XML_TOK_PROLOG_S 15
+#define XML_TOK_DECL_OPEN 16 /* <!foo */
+#define XML_TOK_DECL_CLOSE 17 /* > */
+#define XML_TOK_NAME 18
+#define XML_TOK_NMTOKEN 19
+#define XML_TOK_POUND_NAME 20 /* #name */
+#define XML_TOK_OR 21 /* | */
+#define XML_TOK_PERCENT 22
+#define XML_TOK_OPEN_PAREN 23
+#define XML_TOK_CLOSE_PAREN 24
+#define XML_TOK_OPEN_BRACKET 25
+#define XML_TOK_CLOSE_BRACKET 26
+#define XML_TOK_LITERAL 27
+#define XML_TOK_PARAM_ENTITY_REF 28
+#define XML_TOK_INSTANCE_START 29
+
+/* The following occur only in element type declarations */
+#define XML_TOK_NAME_QUESTION 30 /* name? */
+#define XML_TOK_NAME_ASTERISK 31 /* name* */
+#define XML_TOK_NAME_PLUS 32 /* name+ */
+#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
+#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
+#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
+#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
+#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
+#define XML_TOK_COMMA 38
+
+/* The following token is returned only by XmlAttributeValueTok */
+#define XML_TOK_ATTRIBUTE_VALUE_S 39
+
+/* The following token is returned only by XmlCdataSectionTok */
+#define XML_TOK_CDATA_SECT_CLOSE 40
+
+/* With namespace processing this is returned by XmlPrologTok
+   for a name with a colon. */
+#define XML_TOK_PREFIXED_NAME 41
+
+#ifdef XML_DTD
+#define XML_TOK_IGNORE_SECT 42
+#endif /* XML_DTD */
+
+#ifdef XML_DTD
+#define XML_N_STATES 4
+#else /* not XML_DTD */
+#define XML_N_STATES 3
+#endif /* not XML_DTD */
+
+#define XML_PROLOG_STATE 0
+#define XML_CONTENT_STATE 1
+#define XML_CDATA_SECTION_STATE 2
+#ifdef XML_DTD
+#define XML_IGNORE_SECTION_STATE 3
+#endif /* XML_DTD */
+
+#define XML_N_LITERAL_TYPES 2
+#define XML_ATTRIBUTE_VALUE_LITERAL 0
+#define XML_ENTITY_VALUE_LITERAL 1
+
+/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
+#define XML_UTF8_ENCODE_MAX 4
+/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
+#define XML_UTF16_ENCODE_MAX 2
+
+typedef struct position {
+  /* first line and first column are 0 not 1 */
+  unsigned long lineNumber;
+  unsigned long columnNumber;
+} POSITION;
+
+typedef struct {
+  const char *name;
+  const char *valuePtr;
+  const char *valueEnd;
+  char normalized;
+} ATTRIBUTE;
+
+struct encoding;
+typedef struct encoding ENCODING;
+
+struct encoding {
+  int (*scanners[XML_N_STATES])(const ENCODING *,
+                               const char *,
+                               const char *,
+                               const char **);
+  int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *,
+                                             const char *,
+                                             const char *,
+                                             const char **);
+  int (*sameName)(const ENCODING *,
+                 const char *, const char *);
+  int (*nameMatchesAscii)(const ENCODING *,
+                         const char *, const char *, const char *);
+  int (*nameLength)(const ENCODING *, const char *);
+  const char *(*skipS)(const ENCODING *, const char *);
+  int (*getAtts)(const ENCODING *enc, const char *ptr,
+                int attsMax, ATTRIBUTE *atts);
+  int (*charRefNumber)(const ENCODING *enc, const char *ptr);
+  int (*predefinedEntityName)(const ENCODING *, const char *, const char *);
+  void (*updatePosition)(const ENCODING *,
+                        const char *ptr,
+                        const char *end,
+                        POSITION *);
+  int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+                   const char **badPtr);
+  void (*utf8Convert)(const ENCODING *enc,
+                     const char **fromP,
+                     const char *fromLim,
+                     char **toP,
+                     const char *toLim);
+  void (*utf16Convert)(const ENCODING *enc,
+                      const char **fromP,
+                      const char *fromLim,
+                      unsigned short **toP,
+                      const unsigned short *toLim);
+  int minBytesPerChar;
+  char isUtf8;
+  char isUtf16;
+};
+
+/*
+Scan the string starting at ptr until the end of the next complete token,
+but do not scan past eptr.  Return an integer giving the type of token.
+
+Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
+
+Return XML_TOK_PARTIAL when the string does not contain a complete token;
+nextTokPtr will not be set.
+
+Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr
+will be set to point to the character which made the token invalid.
+
+Otherwise the string starts with a valid token; nextTokPtr will be set to point
+to the character following the end of that token.
+
+Each data character counts as a single token, but adjacent data characters
+may be returned together.  Similarly for characters in the prolog outside
+literals, comments and processing instructions.
+*/
+
+
+#define XmlTok(enc, state, ptr, end, nextTokPtr) \
+  (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
+
+#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
+
+#define XmlContentTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
+
+#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
+
+#ifdef XML_DTD
+
+#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
+
+#endif /* XML_DTD */
+
+/* This is used for performing a 2nd-level tokenization on
+the content of a literal that has already been returned by XmlTok. */ 
+
+#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
+  (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
+
+#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
+   XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
+   XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
+
+#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
+  (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
+
+#define XmlNameLength(enc, ptr) \
+  (((enc)->nameLength)(enc, ptr))
+
+#define XmlSkipS(enc, ptr) \
+  (((enc)->skipS)(enc, ptr))
+
+#define XmlGetAttributes(enc, ptr, attsMax, atts) \
+  (((enc)->getAtts)(enc, ptr, attsMax, atts))
+
+#define XmlCharRefNumber(enc, ptr) \
+  (((enc)->charRefNumber)(enc, ptr))
+
+#define XmlPredefinedEntityName(enc, ptr, end) \
+  (((enc)->predefinedEntityName)(enc, ptr, end))
+
+#define XmlUpdatePosition(enc, ptr, end, pos) \
+  (((enc)->updatePosition)(enc, ptr, end, pos))
+
+#define XmlIsPublicId(enc, ptr, end, badPtr) \
+  (((enc)->isPublicId)(enc, ptr, end, badPtr))
+
+#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
+  (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
+
+#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
+  (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
+
+typedef struct {
+  ENCODING initEnc;
+  const ENCODING **encPtr;
+} INIT_ENCODING;
+
+int XMLTOKAPI XmlParseXmlDecl(int isGeneralTextEntity,
+                             const ENCODING *enc,
+                             const char *ptr,
+                             const char *end,
+                             const char **badPtr,
+                             const char **versionPtr,
+                             const char **encodingNamePtr,
+                             const ENCODING **namedEncodingPtr,
+                             int *standalonePtr);
+
+int XMLTOKAPI XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncoding(void);
+const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncoding(void);
+int XMLTOKAPI XmlUtf8Encode(int charNumber, char *buf);
+int XMLTOKAPI XmlUtf16Encode(int charNumber, unsigned short *buf);
+
+int XMLTOKAPI XmlSizeOfUnknownEncoding(void);
+ENCODING XMLTOKAPI *
+XmlInitUnknownEncoding(void *mem,
+                      int *table,
+                      int (*conv)(void *userData, const char *p),
+                      void *userData);
+
+int XMLTOKAPI XmlParseXmlDeclNS(int isGeneralTextEntity,
+                               const ENCODING *enc,
+                               const char *ptr,
+                               const char *end,
+                               const char **badPtr,
+                               const char **versionPtr,
+                               const char **encodingNamePtr,
+                               const ENCODING **namedEncodingPtr,
+                               int *standalonePtr);
+int XMLTOKAPI XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncodingNS(void);
+const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncodingNS(void);
+ENCODING XMLTOKAPI *
+XmlInitUnknownEncodingNS(void *mem,
+                        int *table,
+                        int (*conv)(void *userData, const char *p),
+                        void *userData);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlTok_INCLUDED */
diff --git a/src/xrc/expat/xmltok/xmltok_impl.c b/src/xrc/expat/xmltok/xmltok_impl.c
new file mode 100644 (file)
index 0000000..8bb0c62
--- /dev/null
@@ -0,0 +1,1790 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+#undef INVALID_LEAD_CASE
+
+#ifndef IS_INVALID_CHAR
+#define IS_INVALID_CHAR(enc, ptr, n) (0)
+#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
+      ptr += n; \
+      break;
+#else
+#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
+      if (IS_INVALID_CHAR(enc, ptr, n)) { \
+        *(nextTokPtr) = (ptr); \
+        return XML_TOK_INVALID; \
+      } \
+      ptr += n; \
+      break;
+#endif
+
+#define INVALID_CASES(ptr, nextTokPtr) \
+  INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
+  INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
+  INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
+  case BT_NONXML: \
+  case BT_MALFORM: \
+  case BT_TRAIL: \
+    *(nextTokPtr) = (ptr); \
+    return XML_TOK_INVALID;
+
+#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
+   case BT_LEAD ## n: \
+     if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
+     if (!IS_NAME_CHAR(enc, ptr, n)) { \
+       *nextTokPtr = ptr; \
+       return XML_TOK_INVALID; \
+     } \
+     ptr += n; \
+     break;
+
+#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
+  case BT_NONASCII: \
+    if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
+      *nextTokPtr = ptr; \
+      return XML_TOK_INVALID; \
+    } \
+  case BT_NMSTRT: \
+  case BT_HEX: \
+  case BT_DIGIT: \
+  case BT_NAME: \
+  case BT_MINUS: \
+    ptr += MINBPC(enc); \
+    break; \
+  CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
+  CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
+  CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
+
+#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
+   case BT_LEAD ## n: \
+     if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
+     if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
+       *nextTokPtr = ptr; \
+       return XML_TOK_INVALID; \
+     } \
+     ptr += n; \
+     break;
+
+#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
+  case BT_NONASCII: \
+    if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
+      *nextTokPtr = ptr; \
+      return XML_TOK_INVALID; \
+    } \
+  case BT_NMSTRT: \
+  case BT_HEX: \
+    ptr += MINBPC(enc); \
+    break; \
+  CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
+  CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
+  CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
+
+#ifndef PREFIX
+#define PREFIX(ident) ident
+#endif
+
+/* ptr points to character following "<!-" */
+
+static
+int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end,
+                       const char **nextTokPtr)
+{
+  if (ptr != end) {
+    if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+    ptr += MINBPC(enc);
+    while (ptr != end) {
+      switch (BYTE_TYPE(enc, ptr)) {
+      INVALID_CASES(ptr, nextTokPtr)
+      case BT_MINUS:
+       if ((ptr += MINBPC(enc)) == end)
+         return XML_TOK_PARTIAL;
+       if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+         if ((ptr += MINBPC(enc)) == end)
+           return XML_TOK_PARTIAL;
+         if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+           *nextTokPtr = ptr;
+           return XML_TOK_INVALID;
+         }
+         *nextTokPtr = ptr + MINBPC(enc);
+         return XML_TOK_COMMENT;
+       }
+       break;
+      default:
+       ptr += MINBPC(enc);
+       break;
+      }
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<!" */
+
+static
+int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end,
+                    const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_MINUS:
+    return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_LSQB:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_COND_SECT_OPEN;
+  case BT_NMSTRT:
+  case BT_HEX:
+    ptr += MINBPC(enc);
+    break;
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_PERCNT:
+      if (ptr + MINBPC(enc) == end)
+       return XML_TOK_PARTIAL;
+      /* don't allow <!ENTITY% foo "whatever"> */
+      switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
+      case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      /* fall through */
+    case BT_S: case BT_CR: case BT_LF:
+      *nextTokPtr = ptr;
+      return XML_TOK_DECL_OPEN;
+    case BT_NMSTRT:
+    case BT_HEX:
+      ptr += MINBPC(enc);
+      break;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, int *tokPtr)
+{
+  int upper = 0;
+  *tokPtr = XML_TOK_PI;
+  if (end - ptr != MINBPC(enc)*3)
+    return 1;
+  switch (BYTE_TO_ASCII(enc, ptr)) {
+  case ASCII_x:
+    break;
+  case ASCII_X:
+    upper = 1;
+    break;
+  default:
+    return 1;
+  }
+  ptr += MINBPC(enc);
+  switch (BYTE_TO_ASCII(enc, ptr)) {
+  case ASCII_m:
+    break;
+  case ASCII_M:
+    upper = 1;
+    break;
+  default:
+    return 1;
+  }
+  ptr += MINBPC(enc);
+  switch (BYTE_TO_ASCII(enc, ptr)) {
+  case ASCII_l:
+    break;
+  case ASCII_L:
+    upper = 1;
+    break;
+  default:
+    return 1;
+  }
+  if (upper)
+    return 0;
+  *tokPtr = XML_TOK_XML_DECL;
+  return 1;
+}
+
+/* ptr points to character following "<?" */
+
+static
+int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end,
+                  const char **nextTokPtr)
+{
+  int tok;
+  const char *target = ptr;
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_S: case BT_CR: case BT_LF:
+      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      ptr += MINBPC(enc);
+      while (ptr != end) {
+        switch (BYTE_TYPE(enc, ptr)) {
+        INVALID_CASES(ptr, nextTokPtr)
+       case BT_QUEST:
+         ptr += MINBPC(enc);
+         if (ptr == end)
+           return XML_TOK_PARTIAL;
+         if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+           *nextTokPtr = ptr + MINBPC(enc);
+           return tok;
+         }
+         break;
+       default:
+         ptr += MINBPC(enc);
+         break;
+       }
+      }
+      return XML_TOK_PARTIAL;
+    case BT_QUEST:
+      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      ptr += MINBPC(enc);
+      if (ptr == end)
+       return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+       *nextTokPtr = ptr + MINBPC(enc);
+       return tok;
+      }
+      /* fall through */
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+
+static
+int PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end,
+                            const char **nextTokPtr)
+{
+  static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, ASCII_LSQB };
+  int i;
+  /* CDATA[ */
+  if (end - ptr < 6 * MINBPC(enc))
+    return XML_TOK_PARTIAL;
+  for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
+    if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_CDATA_SECT_OPEN;
+}
+
+static
+int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
+                           const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_NONE;
+#if !(MINBPC(enc) == 1)
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      if (n == 0)
+       return XML_TOK_PARTIAL;
+      end = ptr + n;
+    }
+ }
+#endif
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_RSQB:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_PARTIAL;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+      break;
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_PARTIAL;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+      ptr -= MINBPC(enc);
+      break;
+    }
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_CDATA_SECT_CLOSE;
+  case BT_CR:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_PARTIAL;
+    if (BYTE_TYPE(enc, ptr) == BT_LF)
+      ptr += MINBPC(enc);
+    *nextTokPtr = ptr;
+    return XML_TOK_DATA_NEWLINE;
+  case BT_LF:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_DATA_NEWLINE;
+  INVALID_CASES(ptr, nextTokPtr)
+  default:
+    ptr += MINBPC(enc);
+    break;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+       *nextTokPtr = ptr; \
+       return XML_TOK_DATA_CHARS; \
+      } \
+      ptr += n; \
+      break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_NONXML:
+    case BT_MALFORM:
+    case BT_TRAIL:
+    case BT_CR:
+    case BT_LF:
+    case BT_RSQB:
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "</" */
+
+static
+int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end,
+                      const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_S: case BT_CR: case BT_LF:
+      for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+       switch (BYTE_TYPE(enc, ptr)) {
+       case BT_S: case BT_CR: case BT_LF:
+         break;
+       case BT_GT:
+         *nextTokPtr = ptr + MINBPC(enc);
+          return XML_TOK_END_TAG;
+       default:
+         *nextTokPtr = ptr;
+         return XML_TOK_INVALID;
+       }
+      }
+      return XML_TOK_PARTIAL;
+#ifdef XML_NS
+    case BT_COLON:
+      /* no need to check qname syntax here, since end-tag must match exactly */
+      ptr += MINBPC(enc);
+      break;
+#endif
+    case BT_GT:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_END_TAG;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#X" */
+
+static
+int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end,
+                          const char **nextTokPtr)
+{
+  if (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_DIGIT:
+    case BT_HEX:
+      break;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_DIGIT:
+      case BT_HEX:
+       break;
+      case BT_SEMI:
+       *nextTokPtr = ptr + MINBPC(enc);
+       return XML_TOK_CHAR_REF;
+      default:
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#" */
+
+static
+int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end,
+                       const char **nextTokPtr)
+{
+  if (ptr != end) {
+    if (CHAR_MATCHES(enc, ptr, ASCII_x))
+      return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_DIGIT:
+      break;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_DIGIT:
+       break;
+      case BT_SEMI:
+       *nextTokPtr = ptr + MINBPC(enc);
+       return XML_TOK_CHAR_REF;
+      default:
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&" */
+
+static
+int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
+                   const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_NUM:
+    return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_SEMI:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_ENTITY_REF;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following first character of attribute name */
+
+static
+int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
+                    const char **nextTokPtr)
+{
+#ifdef XML_NS
+  int hadColon = 0;
+#endif
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+    case BT_COLON:
+      if (hadColon) {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      hadColon = 1;
+      ptr += MINBPC(enc);
+      if (ptr == end)
+       return XML_TOK_PARTIAL;
+      switch (BYTE_TYPE(enc, ptr)) {
+      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+      default:
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      break;
+#endif
+    case BT_S: case BT_CR: case BT_LF:
+      for (;;) {
+       int t;
+
+       ptr += MINBPC(enc);
+       if (ptr == end)
+         return XML_TOK_PARTIAL;
+       t = BYTE_TYPE(enc, ptr);
+       if (t == BT_EQUALS)
+         break;
+       switch (t) {
+       case BT_S:
+       case BT_LF:
+       case BT_CR:
+         break;
+       default:
+         *nextTokPtr = ptr;
+         return XML_TOK_INVALID;
+       }
+      }
+    /* fall through */
+    case BT_EQUALS:
+      {
+       int open;
+#ifdef XML_NS
+       hadColon = 0;
+#endif
+       for (;;) {
+       
+         ptr += MINBPC(enc);
+         if (ptr == end)
+           return XML_TOK_PARTIAL;
+         open = BYTE_TYPE(enc, ptr);
+         if (open == BT_QUOT || open == BT_APOS)
+           break;
+         switch (open) {
+         case BT_S:
+         case BT_LF:
+         case BT_CR:
+           break;
+         default:
+           *nextTokPtr = ptr;
+           return XML_TOK_INVALID;
+         }
+       }
+       ptr += MINBPC(enc);
+       /* in attribute value */
+       for (;;) {
+         int t;
+         if (ptr == end)
+           return XML_TOK_PARTIAL;
+         t = BYTE_TYPE(enc, ptr);
+         if (t == open)
+           break;
+         switch (t) {
+         INVALID_CASES(ptr, nextTokPtr)
+         case BT_AMP:
+           {
+             int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
+             if (tok <= 0) {
+               if (tok == XML_TOK_INVALID)
+                 *nextTokPtr = ptr;
+               return tok;
+             }
+             break;
+           }
+         case BT_LT:
+           *nextTokPtr = ptr;
+           return XML_TOK_INVALID;
+         default:
+           ptr += MINBPC(enc);
+           break;
+         }
+       }
+       ptr += MINBPC(enc);
+       if (ptr == end)
+         return XML_TOK_PARTIAL;
+       switch (BYTE_TYPE(enc, ptr)) {
+       case BT_S:
+       case BT_CR:
+       case BT_LF:
+         break;
+       case BT_SOL:
+         goto sol;
+       case BT_GT:
+         goto gt;
+       default:
+         *nextTokPtr = ptr;
+         return XML_TOK_INVALID;
+       }
+       /* ptr points to closing quote */
+       for (;;) {
+         ptr += MINBPC(enc);
+         if (ptr == end)
+           return XML_TOK_PARTIAL;
+         switch (BYTE_TYPE(enc, ptr)) {
+         CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+         case BT_S: case BT_CR: case BT_LF:
+           continue;
+         case BT_GT:
+          gt:
+           *nextTokPtr = ptr + MINBPC(enc);
+           return XML_TOK_START_TAG_WITH_ATTS;
+         case BT_SOL:
+          sol:
+           ptr += MINBPC(enc);
+           if (ptr == end)
+             return XML_TOK_PARTIAL;
+           if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+             *nextTokPtr = ptr;
+             return XML_TOK_INVALID;
+           }
+           *nextTokPtr = ptr + MINBPC(enc);
+           return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
+         default:
+           *nextTokPtr = ptr;
+           return XML_TOK_INVALID;
+         }
+         break;
+       }
+       break;
+      }
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<" */
+
+static
+int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
+                  const char **nextTokPtr)
+{
+#ifdef XML_NS
+  int hadColon;
+#endif
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_EXCL:
+    if ((ptr += MINBPC(enc)) == end)
+      return XML_TOK_PARTIAL;
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_MINUS:
+      return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    case BT_LSQB:
+      return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  case BT_QUEST:
+    return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_SOL:
+    return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+#ifdef XML_NS
+  hadColon = 0;
+#endif
+  /* we have a start-tag */
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+    case BT_COLON:
+      if (hadColon) {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      hadColon = 1;
+      ptr += MINBPC(enc);
+      if (ptr == end)
+       return XML_TOK_PARTIAL;
+      switch (BYTE_TYPE(enc, ptr)) {
+      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+      default:
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      break;
+#endif
+    case BT_S: case BT_CR: case BT_LF:
+      {
+        ptr += MINBPC(enc);
+       while (ptr != end) {
+         switch (BYTE_TYPE(enc, ptr)) {
+         CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+         case BT_GT:
+           goto gt;
+         case BT_SOL:
+           goto sol;
+         case BT_S: case BT_CR: case BT_LF:
+           ptr += MINBPC(enc);
+           continue;
+         default:
+           *nextTokPtr = ptr;
+           return XML_TOK_INVALID;
+         }
+         return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
+       }
+       return XML_TOK_PARTIAL;
+      }
+    case BT_GT:
+    gt:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_START_TAG_NO_ATTS;
+    case BT_SOL:
+    sol:
+      ptr += MINBPC(enc);
+      if (ptr == end)
+       return XML_TOK_PARTIAL;
+      if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
+                      const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_NONE;
+#if !(MINBPC(enc) == 1)
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      if (n == 0)
+       return XML_TOK_PARTIAL;
+      end = ptr + n;
+    }
+  }
+#endif
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_LT:
+    return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_AMP:
+    return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_CR:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_TRAILING_CR;
+    if (BYTE_TYPE(enc, ptr) == BT_LF)
+      ptr += MINBPC(enc);
+    *nextTokPtr = ptr;
+    return XML_TOK_DATA_NEWLINE;
+  case BT_LF:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_DATA_NEWLINE;
+  case BT_RSQB:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_TRAILING_RSQB;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+      break;
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_TRAILING_RSQB;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+      ptr -= MINBPC(enc);
+      break;
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  INVALID_CASES(ptr, nextTokPtr)
+  default:
+    ptr += MINBPC(enc);
+    break;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+       *nextTokPtr = ptr; \
+       return XML_TOK_DATA_CHARS; \
+      } \
+      ptr += n; \
+      break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_RSQB:
+      if (ptr + MINBPC(enc) != end) {
+        if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
+          ptr += MINBPC(enc);
+          break;
+        }
+        if (ptr + 2*MINBPC(enc) != end) {
+          if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
+            ptr += MINBPC(enc);
+            break;
+          }
+          *nextTokPtr = ptr + 2*MINBPC(enc);
+          return XML_TOK_INVALID;
+        }
+      }
+      /* fall through */
+    case BT_AMP:
+    case BT_LT:
+    case BT_NONXML:
+    case BT_MALFORM:
+    case BT_TRAIL:
+    case BT_CR:
+    case BT_LF:
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "%" */
+
+static
+int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
+                       const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
+    *nextTokPtr = ptr;
+    return XML_TOK_PERCENT;
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_SEMI:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_PARAM_ENTITY_REF;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
+                         const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_CR: case BT_LF: case BT_S:
+    case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
+      *nextTokPtr = ptr;
+      return XML_TOK_POUND_NAME;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return -XML_TOK_POUND_NAME;
+}
+
+static
+int PREFIX(scanLit)(int open, const ENCODING *enc,
+                   const char *ptr, const char *end,
+                   const char **nextTokPtr)
+{
+  while (ptr != end) {
+    int t = BYTE_TYPE(enc, ptr);
+    switch (t) {
+    INVALID_CASES(ptr, nextTokPtr)
+    case BT_QUOT:
+    case BT_APOS:
+      ptr += MINBPC(enc);
+      if (t != open)
+       break;
+      if (ptr == end)
+       return -XML_TOK_LITERAL;
+      *nextTokPtr = ptr;
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_S: case BT_CR: case BT_LF:
+      case BT_GT: case BT_PERCNT: case BT_LSQB:
+       return XML_TOK_LITERAL;
+      default:
+       return XML_TOK_INVALID;
+      }
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
+                     const char **nextTokPtr)
+{
+  int tok;
+  if (ptr == end)
+    return XML_TOK_NONE;
+#if !(MINBPC(enc) == 1)
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      if (n == 0)
+       return XML_TOK_PARTIAL;
+      end = ptr + n;
+    }
+  }
+#endif
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_QUOT:
+    return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_APOS:
+    return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_LT:
+    {
+      ptr += MINBPC(enc);
+      if (ptr == end)
+       return XML_TOK_PARTIAL;
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_EXCL:
+       return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      case BT_QUEST:
+       return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      case BT_NMSTRT:
+      case BT_HEX:
+      case BT_NONASCII:
+      case BT_LEAD2:
+      case BT_LEAD3:
+      case BT_LEAD4:
+       *nextTokPtr = ptr - MINBPC(enc);
+       return XML_TOK_INSTANCE_START;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  case BT_CR:
+    if (ptr + MINBPC(enc) == end)
+      return -XML_TOK_PROLOG_S;
+    /* fall through */
+  case BT_S: case BT_LF:
+    for (;;) {
+      ptr += MINBPC(enc);
+      if (ptr == end)
+       break;
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_S: case BT_LF:
+       break;
+      case BT_CR:
+       /* don't split CR/LF pair */
+       if (ptr + MINBPC(enc) != end)
+         break;
+       /* fall through */
+      default:
+       *nextTokPtr = ptr;
+       return XML_TOK_PROLOG_S;
+      }
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_PROLOG_S;
+  case BT_PERCNT:
+    return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_COMMA:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_COMMA;
+  case BT_LSQB:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_OPEN_BRACKET;
+  case BT_RSQB:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return -XML_TOK_CLOSE_BRACKET;
+    if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+      if (ptr + MINBPC(enc) == end)
+       return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
+       *nextTokPtr = ptr + 2*MINBPC(enc);
+       return XML_TOK_COND_SECT_CLOSE;
+      }
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_CLOSE_BRACKET;
+  case BT_LPAR:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_OPEN_PAREN;
+  case BT_RPAR:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return -XML_TOK_CLOSE_PAREN;
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_AST:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_CLOSE_PAREN_ASTERISK;
+    case BT_QUEST:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_CLOSE_PAREN_QUESTION;
+    case BT_PLUS:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_CLOSE_PAREN_PLUS;
+    case BT_CR: case BT_LF: case BT_S:
+    case BT_GT: case BT_COMMA: case BT_VERBAR:
+    case BT_RPAR:
+      *nextTokPtr = ptr;
+      return XML_TOK_CLOSE_PAREN;
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  case BT_VERBAR:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_OR;
+  case BT_GT:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_DECL_CLOSE;
+  case BT_NUM:
+    return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+#ifdef XML_MIN_SIZE
+#define LEAD_CASE(n) \
+  case BT_LEAD ## n: \
+    if (end - ptr < n) \
+      return XML_TOK_PARTIAL_CHAR; \
+    if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
+      ptr += n; \
+      tok = XML_TOK_NAME; \
+      break; \
+    } \
+    if (IS_NAME_CHAR(enc, ptr, n)) { \
+      ptr += n; \
+      tok = XML_TOK_NMTOKEN; \
+      break; \
+    } \
+    *nextTokPtr = ptr; \
+    return XML_TOK_INVALID;
+#else
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+    if (end - ptr < n) \
+      return XML_TOK_PARTIAL_CHAR; \
+    *nextTokPtr = ptr; \
+    return XML_TOK_INVALID;
+#endif
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+  case BT_NMSTRT:
+  case BT_HEX:
+    tok = XML_TOK_NAME;
+    ptr += MINBPC(enc);
+    break;
+  case BT_DIGIT:
+  case BT_NAME:
+  case BT_MINUS:
+#ifdef XML_NS
+  case BT_COLON:
+#endif
+    tok = XML_TOK_NMTOKEN;
+    ptr += MINBPC(enc);
+    break;
+  case BT_NONASCII:
+#ifdef XML_MIN_SIZE
+    if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
+      ptr += MINBPC(enc);
+      tok = XML_TOK_NAME;
+      break;
+    }
+    if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
+      ptr += MINBPC(enc);
+      tok = XML_TOK_NMTOKEN;
+      break;
+    }
+#endif
+    /* fall through */
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_GT: case BT_RPAR: case BT_COMMA:
+    case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
+    case BT_S: case BT_CR: case BT_LF:
+      *nextTokPtr = ptr;
+      return tok;
+#ifdef XML_NS
+    case BT_COLON:
+      ptr += MINBPC(enc);
+      switch (tok) {
+      case XML_TOK_NAME:
+       if (ptr == end)
+         return XML_TOK_PARTIAL;
+       tok = XML_TOK_PREFIXED_NAME;
+       switch (BYTE_TYPE(enc, ptr)) {
+       CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+       default:
+         tok = XML_TOK_NMTOKEN;
+         break;
+       }
+       break;
+      case XML_TOK_PREFIXED_NAME:
+       tok = XML_TOK_NMTOKEN;
+       break;
+      }
+      break;
+#endif
+    case BT_PLUS:
+      if (tok == XML_TOK_NMTOKEN)  {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_NAME_PLUS;
+    case BT_AST:
+      if (tok == XML_TOK_NMTOKEN)  {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_NAME_ASTERISK;
+    case BT_QUEST:
+      if (tok == XML_TOK_NMTOKEN)  {
+       *nextTokPtr = ptr;
+       return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_NAME_QUESTION;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return -tok;
+}
+
+static
+int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end,
+                             const char **nextTokPtr)
+{
+  const char *start;
+  if (ptr == end)
+    return XML_TOK_NONE;
+  start = ptr;
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: ptr += n; break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_AMP:
+      if (ptr == start)
+       return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_LT:
+      /* this is for inside entity references */
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    case BT_LF:
+      if (ptr == start) {
+       *nextTokPtr = ptr + MINBPC(enc);
+       return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_CR:
+      if (ptr == start) {
+       ptr += MINBPC(enc);
+       if (ptr == end)
+         return XML_TOK_TRAILING_CR;
+       if (BYTE_TYPE(enc, ptr) == BT_LF)
+         ptr += MINBPC(enc);
+       *nextTokPtr = ptr;
+       return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_S:
+      if (ptr == start) {
+       *nextTokPtr = ptr + MINBPC(enc);
+       return XML_TOK_ATTRIBUTE_VALUE_S;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+static
+int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end,
+                          const char **nextTokPtr)
+{
+  const char *start;
+  if (ptr == end)
+    return XML_TOK_NONE;
+  start = ptr;
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: ptr += n; break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_AMP:
+      if (ptr == start)
+       return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_PERCNT:
+      if (ptr == start)
+       return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_LF:
+      if (ptr == start) {
+       *nextTokPtr = ptr + MINBPC(enc);
+       return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_CR:
+      if (ptr == start) {
+       ptr += MINBPC(enc);
+       if (ptr == end)
+         return XML_TOK_TRAILING_CR;
+       if (BYTE_TYPE(enc, ptr) == BT_LF)
+         ptr += MINBPC(enc);
+       *nextTokPtr = ptr;
+       return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+#ifdef XML_DTD
+
+static
+int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
+                            const char **nextTokPtr)
+{
+  int level = 0;
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      end = ptr + n;
+    }
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    INVALID_CASES(ptr, nextTokPtr)
+    case BT_LT:
+      if ((ptr += MINBPC(enc)) == end)
+       return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
+       if ((ptr += MINBPC(enc)) == end)
+         return XML_TOK_PARTIAL;
+       if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
+         ++level;
+         ptr += MINBPC(enc);
+       }
+      }
+      break;
+    case BT_RSQB:
+      if ((ptr += MINBPC(enc)) == end)
+       return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+       if ((ptr += MINBPC(enc)) == end)
+         return XML_TOK_PARTIAL;
+       if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+         ptr += MINBPC(enc);
+         if (level == 0) {
+           *nextTokPtr = ptr;
+           return XML_TOK_IGNORE_SECT;
+         }
+         --level;
+       }
+      }
+      break;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+#endif /* XML_DTD */
+
+static
+int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+                      const char **badPtr)
+{
+  ptr += MINBPC(enc);
+  end -= MINBPC(enc);
+  for (; ptr != end; ptr += MINBPC(enc)) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_DIGIT:
+    case BT_HEX:
+    case BT_MINUS:
+    case BT_APOS:
+    case BT_LPAR:
+    case BT_RPAR:
+    case BT_PLUS:
+    case BT_COMMA:
+    case BT_SOL:
+    case BT_EQUALS:
+    case BT_QUEST:
+    case BT_CR:
+    case BT_LF:
+    case BT_SEMI:
+    case BT_EXCL:
+    case BT_AST:
+    case BT_PERCNT:
+    case BT_NUM:
+#ifdef XML_NS
+    case BT_COLON:
+#endif
+      break;
+    case BT_S:
+      if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
+       *badPtr = ptr;
+       return 0;
+      }
+      break;
+    case BT_NAME:
+    case BT_NMSTRT:
+      if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
+       break;
+    default:
+      switch (BYTE_TO_ASCII(enc, ptr)) {
+      case 0x24: /* $ */
+      case 0x40: /* @ */
+       break;
+      default:
+       *badPtr = ptr;
+       return 0;
+      }
+      break;
+    }
+  }
+  return 1;
+}
+
+/* This must only be called for a well-formed start-tag or empty element tag.
+Returns the number of attributes.  Pointers to the first attsMax attributes
+are stored in atts. */
+
+static
+int PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
+                   int attsMax, ATTRIBUTE *atts)
+{
+  enum { other, inName, inValue } state = inName;
+  int nAtts = 0;
+  int open = 0; /* defined when state == inValue;
+                  initialization just to shut up compilers */
+
+  for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define START_NAME \
+      if (state == other) { \
+       if (nAtts < attsMax) { \
+         atts[nAtts].name = ptr; \
+         atts[nAtts].normalized = 1; \
+       } \
+       state = inName; \
+      }
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_NONASCII:
+    case BT_NMSTRT:
+    case BT_HEX:
+      START_NAME
+      break;
+#undef START_NAME
+    case BT_QUOT:
+      if (state != inValue) {
+       if (nAtts < attsMax)
+         atts[nAtts].valuePtr = ptr + MINBPC(enc);
+        state = inValue;
+        open = BT_QUOT;
+      }
+      else if (open == BT_QUOT) {
+        state = other;
+       if (nAtts < attsMax)
+         atts[nAtts].valueEnd = ptr;
+       nAtts++;
+      }
+      break;
+    case BT_APOS:
+      if (state != inValue) {
+       if (nAtts < attsMax)
+         atts[nAtts].valuePtr = ptr + MINBPC(enc);
+        state = inValue;
+        open = BT_APOS;
+      }
+      else if (open == BT_APOS) {
+        state = other;
+       if (nAtts < attsMax)
+         atts[nAtts].valueEnd = ptr;
+       nAtts++;
+      }
+      break;
+    case BT_AMP:
+      if (nAtts < attsMax)
+       atts[nAtts].normalized = 0;
+      break;
+    case BT_S:
+      if (state == inName)
+        state = other;
+      else if (state == inValue
+              && nAtts < attsMax
+              && atts[nAtts].normalized
+              && (ptr == atts[nAtts].valuePtr
+                  || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
+                  || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
+                  || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
+       atts[nAtts].normalized = 0;
+      break;
+    case BT_CR: case BT_LF:
+      /* This case ensures that the first attribute name is counted
+         Apart from that we could just change state on the quote. */
+      if (state == inName)
+        state = other;
+      else if (state == inValue && nAtts < attsMax)
+       atts[nAtts].normalized = 0;
+      break;
+    case BT_GT:
+    case BT_SOL:
+      if (state != inValue)
+       return nAtts;
+      break;
+    default:
+      break;
+    }
+  }
+  /* not reached */
+}
+
+static
+int PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
+{
+  int result = 0;
+  /* skip &# */
+  ptr += 2*MINBPC(enc);
+  if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
+    for (ptr += MINBPC(enc); !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+      int c = BYTE_TO_ASCII(enc, ptr);
+      switch (c) {
+      case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
+      case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
+       result <<= 4;
+       result |= (c - ASCII_0);
+       break;
+      case ASCII_A: case ASCII_B: case ASCII_C: case ASCII_D: case ASCII_E: case ASCII_F:
+       result <<= 4;
+       result += 10 + (c - ASCII_A);
+       break;
+      case ASCII_a: case ASCII_b: case ASCII_c: case ASCII_d: case ASCII_e: case ASCII_f:
+       result <<= 4;
+       result += 10 + (c - ASCII_a);
+       break;
+      }
+      if (result >= 0x110000)
+       return -1;
+    }
+  }
+  else {
+    for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+      int c = BYTE_TO_ASCII(enc, ptr);
+      result *= 10;
+      result += (c - ASCII_0);
+      if (result >= 0x110000)
+       return -1;
+    }
+  }
+  return checkCharRefNumber(result);
+}
+
+static
+int PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, const char *end)
+{
+  switch ((end - ptr)/MINBPC(enc)) {
+  case 2:
+    if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
+      switch (BYTE_TO_ASCII(enc, ptr)) {
+      case ASCII_l:
+       return ASCII_LT;
+      case ASCII_g:
+       return ASCII_GT;
+      }
+    }
+    break;
+  case 3:
+    if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
+      ptr += MINBPC(enc);
+      if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
+       ptr += MINBPC(enc);
+       if (CHAR_MATCHES(enc, ptr, ASCII_p))
+         return ASCII_AMP;
+      }
+    }
+    break;
+  case 4:
+    switch (BYTE_TO_ASCII(enc, ptr)) {
+    case ASCII_q:
+      ptr += MINBPC(enc);
+      if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
+       ptr += MINBPC(enc);
+       if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+         ptr += MINBPC(enc);
+         if (CHAR_MATCHES(enc, ptr, ASCII_t))
+           return ASCII_QUOT;
+       }
+      }
+      break;
+    case ASCII_a:
+      ptr += MINBPC(enc);
+      if (CHAR_MATCHES(enc, ptr, ASCII_p)) {
+       ptr += MINBPC(enc);
+       if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+         ptr += MINBPC(enc);
+         if (CHAR_MATCHES(enc, ptr, ASCII_s))
+           return ASCII_APOS;
+       }
+      }
+      break;
+    }
+  }
+  return 0;
+}
+
+static
+int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
+{
+  for (;;) {
+    switch (BYTE_TYPE(enc, ptr1)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      if (*ptr1++ != *ptr2++) \
+       return 0;
+    LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
+#undef LEAD_CASE
+      /* fall through */
+      if (*ptr1++ != *ptr2++)
+       return 0;
+      break;
+    case BT_NONASCII:
+    case BT_NMSTRT:
+#ifdef XML_NS
+    case BT_COLON:
+#endif
+    case BT_HEX:
+    case BT_DIGIT:
+    case BT_NAME:
+    case BT_MINUS:
+      if (*ptr2++ != *ptr1++)
+       return 0;
+      if (MINBPC(enc) > 1) {
+       if (*ptr2++ != *ptr1++)
+         return 0;
+       if (MINBPC(enc) > 2) {
+         if (*ptr2++ != *ptr1++)
+           return 0;
+          if (MINBPC(enc) > 3) {
+           if (*ptr2++ != *ptr1++)
+             return 0;
+         }
+       }
+      }
+      break;
+    default:
+      if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
+       return 1;
+      switch (BYTE_TYPE(enc, ptr2)) {
+      case BT_LEAD2:
+      case BT_LEAD3:
+      case BT_LEAD4:
+      case BT_NONASCII:
+      case BT_NMSTRT:
+#ifdef XML_NS
+      case BT_COLON:
+#endif
+      case BT_HEX:
+      case BT_DIGIT:
+      case BT_NAME:
+      case BT_MINUS:
+       return 0;
+      default:
+       return 1;
+      }
+    }
+  }
+  /* not reached */
+}
+
+static
+int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+                            const char *end1, const char *ptr2)
+{
+  for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
+    if (ptr1 == end1)
+      return 0;
+    if (!CHAR_MATCHES(enc, ptr1, *ptr2))
+      return 0;
+  }
+  return ptr1 == end1;
+}
+
+static
+int PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
+{
+  const char *start = ptr;
+  for (;;) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: ptr += n; break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_NONASCII:
+    case BT_NMSTRT:
+#ifdef XML_NS
+    case BT_COLON:
+#endif
+    case BT_HEX:
+    case BT_DIGIT:
+    case BT_NAME:
+    case BT_MINUS:
+      ptr += MINBPC(enc);
+      break;
+    default:
+      return ptr - start;
+    }
+  }
+}
+
+static
+const char *PREFIX(skipS)(const ENCODING *enc, const char *ptr)
+{
+  for (;;) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_LF:
+    case BT_CR:
+    case BT_S:
+      ptr += MINBPC(enc);
+      break;
+    default:
+      return ptr;
+    }
+  }
+}
+
+static
+void PREFIX(updatePosition)(const ENCODING *enc,
+                           const char *ptr,
+                           const char *end,
+                           POSITION *pos)
+{
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      ptr += n; \
+      break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_LF:
+      pos->columnNumber = (unsigned)-1;
+      pos->lineNumber++;
+      ptr += MINBPC(enc);
+      break;
+    case BT_CR:
+      pos->lineNumber++;
+      ptr += MINBPC(enc);
+      if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
+       ptr += MINBPC(enc);
+      pos->columnNumber = (unsigned)-1;
+      break;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+    pos->columnNumber++;
+  }
+}
+
+#undef DO_LEAD_CASE
+#undef MULTIBYTE_CASES
+#undef INVALID_CASES
+#undef CHECK_NAME_CASE
+#undef CHECK_NAME_CASES
+#undef CHECK_NMSTRT_CASE
+#undef CHECK_NMSTRT_CASES
diff --git a/src/xrc/expat/xmltok/xmltok_impl.h b/src/xrc/expat/xmltok/xmltok_impl.h
new file mode 100644 (file)
index 0000000..eb92802
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file copying.txt for copying permission.
+*/
+
+enum {
+  BT_NONXML,
+  BT_MALFORM,
+  BT_LT,
+  BT_AMP,
+  BT_RSQB,
+  BT_LEAD2,
+  BT_LEAD3,
+  BT_LEAD4,
+  BT_TRAIL,
+  BT_CR,
+  BT_LF,
+  BT_GT,
+  BT_QUOT,
+  BT_APOS,
+  BT_EQUALS,
+  BT_QUEST,
+  BT_EXCL,
+  BT_SOL,
+  BT_SEMI,
+  BT_NUM,
+  BT_LSQB,
+  BT_S,
+  BT_NMSTRT,
+  BT_COLON,
+  BT_HEX,
+  BT_DIGIT,
+  BT_NAME,
+  BT_MINUS,
+  BT_OTHER, /* known not to be a name or name start character */
+  BT_NONASCII, /* might be a name or name start character */
+  BT_PERCNT,
+  BT_LPAR,
+  BT_RPAR,
+  BT_AST,
+  BT_PLUS,
+  BT_COMMA,
+  BT_VERBAR
+};
+
+#include <stddef.h>
diff --git a/src/xrc/expat/xmltok/xmltok_ns.c b/src/xrc/expat/xmltok/xmltok_ns.c
new file mode 100644 (file)
index 0000000..2427898
--- /dev/null
@@ -0,0 +1,96 @@
+const ENCODING *NS(XmlGetUtf8InternalEncoding)(void)
+{
+  return &ns(internal_utf8_encoding).enc;
+}
+
+const ENCODING *NS(XmlGetUtf16InternalEncoding)(void)
+{
+#if XML_BYTE_ORDER == 12
+  return &ns(internal_little2_encoding).enc;
+#elif XML_BYTE_ORDER == 21
+  return &ns(internal_big2_encoding).enc;
+#else
+  const short n = 1;
+  return *(const char *)&n ? &ns(internal_little2_encoding).enc : &ns(internal_big2_encoding).enc;
+#endif
+}
+
+static
+const ENCODING *NS(encodings)[] = {
+  &ns(latin1_encoding).enc,
+  &ns(ascii_encoding).enc,
+  &ns(utf8_encoding).enc,
+  &ns(big2_encoding).enc,
+  &ns(big2_encoding).enc,
+  &ns(little2_encoding).enc,
+  &ns(utf8_encoding).enc /* NO_ENC */
+};
+
+static
+int NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
+                      const char **nextTokPtr)
+{
+  return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr);
+}
+
+static
+int NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
+                      const char **nextTokPtr)
+{
+  return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr);
+}
+
+int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *name)
+{
+  int i = getEncodingIndex(name);
+  if (i == UNKNOWN_ENC)
+    return 0;
+  SET_INIT_ENC_INDEX(p, i);
+  p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
+  p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
+  p->initEnc.updatePosition = initUpdatePosition;
+  p->encPtr = encPtr;
+  *encPtr = &(p->initEnc);
+  return 1;
+}
+
+static
+const ENCODING *NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
+{
+#define ENCODING_MAX 128
+  char buf[ENCODING_MAX];
+  char *p = buf;
+  int i;
+  XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
+  if (ptr != end)
+    return 0;
+  *p = 0;
+  if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
+    return enc;
+  i = getEncodingIndex(buf);
+  if (i == UNKNOWN_ENC)
+    return 0;
+  return NS(encodings)[i];
+}
+
+int NS(XmlParseXmlDecl)(int isGeneralTextEntity,
+                       const ENCODING *enc,
+                       const char *ptr,
+                       const char *end,
+                       const char **badPtr,
+                       const char **versionPtr,
+                       const char **encodingName,
+                       const ENCODING **encoding,
+                       int *standalone)
+{
+  return doParseXmlDecl(NS(findEncoding),
+                       isGeneralTextEntity,
+                       enc,
+                       ptr,
+                       end,
+                       badPtr,
+                       versionPtr,
+                       encodingName,
+                       encoding,
+                       standalone);
+}
diff --git a/src/xrc/makefile.b32 b/src/xrc/makefile.b32
new file mode 100644 (file)
index 0000000..258e43c
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# File:                makefile.b32
+# Author:      Julian Smart
+# Created:     2000
+# Updated:     
+# Copyright:
+#
+# Makefile : Builds BC++ library for 32-bit BC++
+
+WXDIR = $(WXWIN)
+
+expat_dir = $(WXDIR)\contrib\src\xrc\expat
+XMLPARSEDIR = $(expat_dir)\xmlparse 
+XMLTOKDIR = $(expat_dir)\xmltok
+
+EXPAT_DEFS=-I$(expat_dir)\xmlparse -I$(expat_dir)\xmltok
+EXPAT_OBJECTS=xmltok.obj xmlrole.obj xmlparse.obj
+
+EXTRACPPFLAGS=$(wxLIBXMLDIR) $(EXPAT_DEFS)
+
+LIBTARGET=$(WXDIR)\lib\wxxrc.lib
+
+OBJECTS=$(EXPAT_OBJECTS) \
+        xml.obj xmlbin.obj xmlbinz.obj xmlexpat.obj xmlwrite.obj xmlres.obj xmlrsall.obj \
+        xh_bttn.obj xh_chckb.obj xh_chckl.obj xh_choic.obj xh_combo.obj xh_dlg.obj \
+        xh_gauge.obj xh_html.obj xh_menu.obj xh_notbk.obj xh_panel.obj xh_radbt.obj \
+        xh_radbx.obj xh_sizer.obj xh_slidr.obj xh_spin.obj xh_stbmp.obj xh_sttxt.obj \
+        xh_text.obj xh_listb.obj xh_toolb.obj xh_stlin.obj xh_bmp.obj \
+        xh_bmpbt.obj xh_cald.obj xh_listc.obj xh_scrol.obj xh_stbox.obj \
+        xh_tree.obj xh_unkwn.obj xh_frame.obj
+
+!include $(WXDIR)\src\makelib.b32
+
+{$(XMLPARSEDIR)}.c.obj:
+       bcc32 $(EXPAT_DEFS) -c -w-ccc -w-rch -w-par {$< }
+
+{$(XMLTOKDIR)}.c.obj:
+       bcc32 $(EXPAT_DEFS) -c -w-ccc -w-rch -w-par {$< }
+
+
diff --git a/src/xrc/makefile.g95 b/src/xrc/makefile.g95
new file mode 100644 (file)
index 0000000..3a11d89
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# File:         makefile.g95
+# Author:       Julian Smart
+# Created:      2000
+# Updated:
+# Copyright:    (c) Julian Smart, 2000
+#
+# Makefile for wxWindows wxXML library (Cygwin/Mingw32).
+
+WXDIR = ../../..
+
+expat_dir = $(WXDIR)/contrib/src/xrc/expat
+XMLPARSEDIR = $(expat_dir)/xmlparse
+XMLTOKDIR=$(expat_dir)/xmltok
+
+EXPAT_DEFS=-I$(expat_dir)/xmlparse -I$(expat_dir)/xmltok
+
+EXTRACPPFLAGS=$(EXPAT_DEFS)
+XMLPARSEDIR_OBJECTS=xmlparse.o
+XMLTOKDIR_OBJECTS=xmltok.o xmlrole.o
+
+LIBTARGET=$(WXDIR)/lib/libwxxrc.a
+
+OBJECTS= $(XMLPARSEDIR_OBJECTS) $(XMLTOKDIR_OBJECTS) \
+        xml.o xmlbin.o xmlbinz.o xmlexpat.o xmlwrite.o xmlres.o xmlrsall.o \
+        xh_bttn.o xh_chckb.o xh_chckl.o xh_choic.o xh_combo.o xh_dlg.o \
+        xh_gauge.o xh_html.o xh_menu.o xh_notbk.o xh_panel.o xh_radbt.o \
+        xh_radbx.o xh_sizer.o xh_slidr.o xh_spin.o xh_stbmp.o xh_sttxt.o \
+        xh_text.o xh_listb.o xh_toolb.o xh_stlin.o xh_bmp.o xh_unkwn.o \
+        xh_bmpbt.o xh_cald.o xh_listc.o xh_scrol.o xh_stbox.o xh_tree.o \
+        xh_frame.o
+
+include $(WXDIR)/src/makelib.g95
+
+$(XMLPARSEDIR_OBJECTS):
+       $(CC) -g $(EXPAT_DEFS) -c -o $@ $(XMLPARSEDIR)/$(patsubst %.o,%.c, $@)
+
+$(XMLTOKDIR_OBJECTS):
+       $(CC) -g $(EXPAT_DEFS) -c -o $@ $(XMLTOKDIR)/$(patsubst %.o,%.c, $@)
diff --git a/src/xrc/makefile.vc b/src/xrc/makefile.vc
new file mode 100644 (file)
index 0000000..f5c6515
--- /dev/null
@@ -0,0 +1,149 @@
+
+# File:                makefile.vc
+# Author:      Julian Smart
+# Created:     1993
+# Updated:
+# Copyright:   (c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds wxXML classes library (MS VC++).
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+# Set WXDIR for your system
+WXDIR = $(WXWIN)
+wxXMLDIR = $(WXDIR)\contrib\src\xrc
+wxXMLINC = $(WXDIR)\contrib\include\wx\xml
+THISDIR = $(WXDIR)\contrib\src\xrc
+DOCDIR=$(WXDIR)\contrib\docs
+LOCALDOCDIR=$(WXDIR)\contrib\docs\latex\xml
+
+NOPCH=1
+
+EXPAT_DIR=$(THISDIR)\expat
+E1=$(EXPAT_DIR)\xmlparse
+E2=$(EXPAT_DIR)\xmltok
+
+EXPAT_INCS=-I$(THISDIR)\expat\xmlparse -I$(THISDIR)\expat\xmltok
+EXPAT_OBJS=$(D)\xmlparse.obj $(D)\xmlrole.obj $(D)\xmltok.obj
+
+# Set this to where your libxml directory is
+EXTRAFLAGS=$(EXPAT_INCS)
+
+# Unfortunately we need this _before_ we include makelib.vc
+!if "$(FINAL)" == "1"
+D=Release
+!else
+D=Debug
+LIBEXT=d
+!endif
+
+LIBTARGET=$(WXDIR)\lib\wxxrc$(LIBEXT).lib
+EXTRATARGETS=$(D)
+
+OBJECTS=$(EXPAT_OBJS) \
+        $(D)\xml.obj $(D)\xmlbin.obj $(D)\xmlbinz.obj $(D)\xmlres.obj \
+        $(D)\xmlrsall.obj $(D)\xh_bttn.obj $(D)\xh_chckb.obj $(D)\xh_chckl.obj \
+               $(D)\xh_choic.obj $(D)\xh_combo.obj $(D)\xh_dlg.obj \
+        $(D)\xh_frame.obj $(D)\xh_gauge.obj $(D)\xh_html.obj $(D)\xh_menu.obj \
+               $(D)\xh_notbk.obj $(D)\xh_panel.obj $(D)\xh_radbt.obj \
+        $(D)\xh_radbx.obj $(D)\xh_sizer.obj $(D)\xh_slidr.obj $(D)\xh_spin.obj \
+               $(D)\xh_stbmp.obj $(D)\xh_sttxt.obj \
+        $(D)\xh_text.obj $(D)\xh_listb.obj $(D)\xh_toolb.obj \
+        $(D)\xh_bmpbt.obj $(D)\xh_cald.obj $(D)\xh_listc.obj $(D)\xh_scrol.obj \
+        $(D)\xh_stbox.obj $(D)\xh_tree.obj $(D)\xh_stlin.obj $(D)\xh_bmp.obj \
+        $(D)\xh_unkwn.obj $(D)\xmlwrite.obj $(D)\xmlexpat.obj
+
+!include $(WXDIR)\src\makelib.vc
+
+{$(E1)}.c{$(D)}.obj:
+       $(cc) @<<
+$(CPPFLAGS) /c /Fo$@ /Tc $<
+<<
+{$(E2)}.c{$(D)}.obj:
+       $(cc) @<<
+$(CPPFLAGS) /c /Fo$@ /Tc $<
+<<
+
+
+
+DOCSOURCES=$(LOCALDOCDIR)\xml.tex \
+ $(LOCALDOCDIR)\bugs.tex $(LOCALDOCDIR)\changes.tex\
+ $(LOCALDOCDIR)\classes.tex $(LOCALDOCDIR)\intro.tex\
+ $(LOCALDOCDIR)\topics.tex $(LOCALDOCDIR)\sample.tex
+
+html: $(DOCDIR)\html\xml\xml.htm
+htmlhelp: $(DOCDIR)\htmlhelp\xml.chm
+htb:   $(DOCDIR)\htb\xml.htb
+hlp: $(DOCDIR)\winhelp\xml.hlp
+pdfrtf: $(DOCDIR)\pdf\xml.rtf
+ps: $(DOCDIR)\ps\xml.ps
+
+touchmanual:
+       touch $(LOCALDOCDIR)\xml.tex
+
+
+$(DOCDIR)\winhelp\xml.hlp:         $(LOCALDOCDIR)\xml.rtf $(LOCALDOCDIR)\xml.hpj
+        cd $(LOCALDOCDIR)
+        -erase xml.ph
+        hc xml
+        move xml.hlp $(DOCDIR)\winhelp\xml.hlp
+        move xml.cnt $(DOCDIR)\winhelp\xml.cnt
+        cd $(THISDIR)
+
+$(LOCALDOCDIR)\xml.rtf: $(DOCSOURCES)
+        cd $(LOCALDOCDIR)
+        -start $(WAITFLAG) tex2rtf $(LOCALDOCDIR)\xml.tex $(LOCALDOCDIR)\xml.rtf -twice -winhelp
+        cd $(THISDIR)
+
+$(DOCDIR)\pdf\xml.rtf: $(DOCSOURCES)
+        cd $(LOCALDOCDIR)
+        -copy *.bmp $(DOCDIR)\pdf
+        -start $(WAITFLAG) tex2rtf $(LOCALDOCDIR)\xml.tex $(DOCDIR)\pdf\xml.rtf -twice -rtf
+        cd $(THISDIR)
+
+$(DOCDIR)\html\xml\xml.htm:         $(DOCSOURCES)
+        cd $(LOCALDOCDIR)
+        -mkdir $(DOCDIR)\html\xml
+        copy *.gif $(DOCDIR)\html\xml
+        -start $(WAITFLAG) tex2rtf $(LOCALDOCDIR)\xml.tex $(DOCDIR)\html\xml\xml.htm -twice -html
+        -erase $(DOCDIR)\html\xml\*.con
+        -erase *.con
+        -erase $(DOCDIR)\html\xml\*.ref
+        cd $(THISDIR)
+
+$(DOCDIR)\htmlhelp\xml.chm: $(DOCDIR)\html\xml\xml.htm $(DOCDIR)\html\xml\xml.hhp
+       cd $(DOCDIR)\html\xml
+       -hhc xml.hhp
+    move xml.chm $(DOCDIR)\htmlhelp\xml.chm
+       cd $(THISDIR)
+
+# An htb file is a zip file containing the .htm, .gif, .hhp, .hhc and .hhk
+# files, renamed to htb.
+# This can then be used with e.g. helpview.
+# Optionally, a cached version of the .hhp file can be generated with hhp2cached.
+$(DOCDIR)\htb\xml.htb: $(DOCDIR)\html\xml\xml.htm
+       cd $(DOCDIR)\html\xml
+    -erase xml.zip xml.htb
+    zip xml.zip *.htm *.gif *.hhp *.hhc *.hhk
+    -mkdir $(DOCDIR)\htb
+    move xml.zip $(DOCDIR)\htb\xml.htb
+    cd $(THISDIR)
+
+$(LOCALDOCDIR)\xml.dvi:        $(DOCSOURCES)
+       cd $(LOCALDOCDIR)
+        -latex xml
+        -latex xml
+        -makeindx xml
+        -bibtex xml
+        -latex xml
+        -latex xml
+        cd $(THISDIR)
+
+$(WXDIR)\docs\ps\xml.ps:       $(LOCALDOCDIR)\xml.dvi
+       cd $(LOCALDOCDIR)
+        -dvips32 -o xml.ps xml
+        move xml.ps $(WXDIR)\docs\ps\xml.ps
+        cd $(THISDIR)
+
diff --git a/src/xrc/makefile.wat b/src/xrc/makefile.wat
new file mode 100644 (file)
index 0000000..be5d104
--- /dev/null
@@ -0,0 +1,31 @@
+# wxXML makefile
+
+WXDIR = ..\..\..
+
+EXTRACPPFLAGS=/Id:\libxml\libxml2-2.1.1
+
+!include $(WXDIR)\src\makewat.env
+
+WXXMLLIB = $(WXDIR)\lib\wxxrc.lib
+THISDIR = $(WXDIR)\contrib\src\xrc
+
+NAME = wxxrc
+LNK = $(name).lnk
+
+OBJECTS=xml.obj xmlbin.obj xmlbinz.obj xmlpars.obj xmlres.obj xmlrsall.obj &
+        xh_bttn.obj xh_chckb.obj xh_chckl.obj xh_choic.obj xh_combo.obj xh_dlg.obj &
+        xh_gauge.obj xh_html.obj xh_menu.obj xh_notbk.obj xh_panel.obj xh_radbt.obj &
+        xh_radbx.obj xh_sizer.obj xh_slidr.obj xh_spin.obj xh_stbmp.obj xh_sttxt.obj &
+        xh_text.obj xh_listb.obj xh_toolb.obj xh_stlin.obj xh_bmp.obj &
+        xh_bmpbt.obj xh_cald.obj xh_listc.obj xh_scrol.obj xh_stbox.obj &
+        xh_tree.obj xh_unkwn.obj xh_frame.obj
+
+
+all: $(WXXMLLIB)
+
+$(WXXMLLIB): $(OBJECTS)
+       *wlib /b /c /n /P=256 $(WXXMLLIB) $(OBJECTS)
+
+clean:   .SYMBOLIC
+    -erase *.obj *.bak *.err *.pch $(WXXMLLIB) *.lbc
+
diff --git a/src/xrc/wxXMLVC.dsp b/src/xrc/wxXMLVC.dsp
new file mode 100644 (file)
index 0000000..5633c0c
--- /dev/null
@@ -0,0 +1,254 @@
+# Microsoft Developer Studio Project File - Name="wxXMLVC" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=wxXMLVC - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "wxXMLVC.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "wxXMLVC.mak" CFG="wxXMLVC - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "wxXMLVC - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "wxXMLVC - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "wxXMLVC - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../include" /I "../../include" /I "expat/xmlparse" /I "expat/xmltok" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x809
+# ADD RSC /l 0x809
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\lib\wxxrc.lib"
+
+!ELSEIF  "$(CFG)" == "wxXMLVC - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "../../../include" /I "../../include" /I "expat/xmlparse" /I "expat/xmltok" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D DEBUG=1 /D "__WXDEBUG__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x809
+# ADD RSC /l 0x809
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\lib\wxxrcd.lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "wxXMLVC - Win32 Release"
+# Name "wxXMLVC - Win32 Debug"
+# Begin Group "Expat"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\expat\xmlparse\xmlparse.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\expat\xmltok\xmlrole.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\expat\xmltok\xmltok.c
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\xh_bmp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_bmpbt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_bttn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_cald.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_chckb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_chckl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_choic.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_combo.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_dlg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_frame.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_gauge.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_html.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_listb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_listc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_menu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_notbk.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_panel.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_radbt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_radbx.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_scrol.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_sizer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_slidr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_spin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_stbmp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_stbox.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_stlin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_sttxt.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_text.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_toolb.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_tree.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xh_unkwn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xml.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xmlbin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xmlbinz.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xmlexpat.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xmlres.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xmlrsall.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\xmlwrite.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/src/xrc/wxXMLVC.dsw b/src/xrc/wxXMLVC.dsw
new file mode 100644 (file)
index 0000000..6cabdb1
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "wxXMLVC"=.\wxXMLVC.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/xrc/xh_bmp.cpp b/src/xrc/xh_bmp.cpp
new file mode 100644 (file)
index 0000000..181af55
--- /dev/null
@@ -0,0 +1,60 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_bmp.cpp
+// Purpose:     XML resource for wxBitmap and wxIcon
+// Author:      Vaclav Slavik
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_bmp.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_bmp.h"
+#include "wx/bitmap.h"
+
+
+wxBitmapXmlHandler::wxBitmapXmlHandler() 
+: wxXmlResourceHandler() 
+{
+}
+
+wxObject *wxBitmapXmlHandler::DoCreateResource()
+{ 
+    return new wxBitmap(GetBitmap(wxT("")));
+}
+
+
+
+bool wxBitmapXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxBitmap"));
+}
+
+
+wxIconXmlHandler::wxIconXmlHandler() 
+: wxXmlResourceHandler() 
+{
+}
+
+wxObject *wxIconXmlHandler::DoCreateResource()
+{ 
+    return new wxIcon(GetIcon(wxT("")));
+}
+
+
+
+bool wxIconXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxIcon"));
+}
+
diff --git a/src/xrc/xh_bmpbt.cpp b/src/xrc/xh_bmpbt.cpp
new file mode 100644 (file)
index 0000000..476609d
--- /dev/null
@@ -0,0 +1,66 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_bmpbt.cpp
+// Purpose:     XML resource for bitmap buttons
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_bmpbt.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_bmpbt.h"
+#include <wx/bmpbuttn.h>
+
+wxBitmapButtonXmlHandler::wxBitmapButtonXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxBU_AUTODRAW);
+    ADD_STYLE(wxBU_LEFT);
+    ADD_STYLE(wxBU_RIGHT);
+    ADD_STYLE(wxBU_TOP);
+    ADD_STYLE(wxBU_BOTTOM);
+    AddWindowStyles();
+}
+
+
+wxObject *wxBitmapButtonXmlHandler::DoCreateResource()
+{ 
+    wxBitmapButton *button = new wxBitmapButton(m_parentAsWindow,
+                                    GetID(),
+                                    GetBitmap(wxT("bitmap")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(wxT("style"), wxBU_AUTODRAW),
+                                    wxDefaultValidator,
+                                    GetName());
+    if (GetBool(wxT("default"), 0) == 1) button->SetDefault();
+    SetupWindow(button);
+    
+    if (!GetParamValue(wxT("selected")).IsEmpty())
+        button->SetBitmapSelected(GetBitmap(wxT("selected")));
+    if (!GetParamValue(wxT("focus")).IsEmpty())
+        button->SetBitmapFocus(GetBitmap(wxT("focus")));
+    if (!GetParamValue(wxT("disabled")).IsEmpty())
+        button->SetBitmapDisabled(GetBitmap(wxT("disabled")));
+    
+    return button;
+}
+
+
+
+bool wxBitmapButtonXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxBitmapButton"));
+}
+
+
diff --git a/src/xrc/xh_bttn.cpp b/src/xrc/xh_bttn.cpp
new file mode 100644 (file)
index 0000000..ab6d6f7
--- /dev/null
@@ -0,0 +1,59 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_bttn.cpp
+// Purpose:     XML resource for buttons
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_bttn.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_bttn.h"
+#include "wx/button.h"
+
+
+wxButtonXmlHandler::wxButtonXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxBU_LEFT);
+    ADD_STYLE(wxBU_RIGHT);
+    ADD_STYLE(wxBU_TOP);
+    ADD_STYLE(wxBU_BOTTOM);
+    AddWindowStyles();
+}
+
+
+wxObject *wxButtonXmlHandler::DoCreateResource()
+{ 
+    wxButton *button = new wxButton(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("label")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName());
+    if (GetBool(wxT("default"), 0) == 1) button->SetDefault();
+    SetupWindow(button);
+    
+    return button;
+}
+
+
+
+bool wxButtonXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxButton"));
+}
+
+
diff --git a/src/xrc/xh_cald.cpp b/src/xrc/xh_cald.cpp
new file mode 100644 (file)
index 0000000..4e59b88
--- /dev/null
@@ -0,0 +1,61 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_cald.cpp
+// Purpose:     XML resource for wxCalendarCtrl
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_cald.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_cald.h"
+#include "wx/event.h"
+#include "wx/calctrl.h"
+
+
+wxCalendarCtrlXmlHandler::wxCalendarCtrlXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxCAL_SUNDAY_FIRST);
+    ADD_STYLE(wxCAL_MONDAY_FIRST);
+    ADD_STYLE(wxCAL_SHOW_HOLIDAYS);
+    ADD_STYLE(wxCAL_NO_YEAR_CHANGE);
+    ADD_STYLE(wxCAL_NO_MONTH_CHANGE);
+    AddWindowStyles();
+}
+
+
+wxObject *wxCalendarCtrlXmlHandler::DoCreateResource()
+{ 
+    wxCalendarCtrl *calendar = new wxCalendarCtrl(m_parentAsWindow,
+                                    GetID(),
+                                    wxDefaultDateTime,
+                                    /*TODO: take it from resource*/
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    GetName());
+    
+    SetupWindow(calendar);
+    
+    return calendar;
+}
+
+
+
+bool wxCalendarCtrlXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxCalendarCtrl"));
+}
+
+
diff --git a/src/xrc/xh_chckb.cpp b/src/xrc/xh_chckb.cpp
new file mode 100644 (file)
index 0000000..9974211
--- /dev/null
@@ -0,0 +1,57 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_chckb.cpp
+// Purpose:     XML resource for wxCheckBox
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_chckb.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_chckb.h"
+#include "wx/checkbox.h"
+
+#if wxUSE_CHECKBOX
+
+wxCheckBoxXmlHandler::wxCheckBoxXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    AddWindowStyles();
+}
+
+wxObject *wxCheckBoxXmlHandler::DoCreateResource()
+{ 
+    wxCheckBox *control = new wxCheckBox(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("label")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+    control->SetValue( GetBool( wxT("checked")));
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxCheckBoxXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxCheckBox"));
+}
+
+#endif
diff --git a/src/xrc/xh_chckl.cpp b/src/xrc/xh_chckl.cpp
new file mode 100644 (file)
index 0000000..b033b13
--- /dev/null
@@ -0,0 +1,109 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_chckl.cpp
+// Purpose:     XML resource for wxCheckList
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_chckl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_chckl.h"
+#include "wx/checklst.h"
+
+wxCheckListXmlHandler::wxCheckListXmlHandler() 
+: wxXmlResourceHandler(), m_insideBox(FALSE)
+{
+    // no styles
+    AddWindowStyles();
+}
+
+wxObject *wxCheckListXmlHandler::DoCreateResource()
+{ 
+    if (m_class == wxT("wxCheckList"))
+    {
+        // need to build the list of strings from children
+        m_insideBox = TRUE;
+        CreateChildrenPrivately(NULL, GetParamNode(wxT("content")));
+        wxString *strings = (wxString *) NULL;
+        if( strList.GetCount() > 0 )
+        {
+            strings = new wxString[strList.GetCount()];
+            int count = strList.GetCount();
+            for( int i = 0; i < count; i++ )
+                strings[i]=strList[i];
+        }
+
+
+        wxCheckListBox *control = new wxCheckListBox(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    strList.GetCount(),
+                                    strings,
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+        // step through children myself (again.)
+        wxXmlNode *n = GetParamNode(wxT("content"));
+        if (n) n = n->GetChildren();
+        int i = 0;
+        while (n)
+        {
+            if (n->GetType() != wxXML_ELEMENT_NODE ||
+                n->GetName() != wxT("item"))
+               { n = n->GetNext(); continue; }
+
+            // checking boolean is a bit ugly here (see GetBool() )
+            wxString v = n->GetPropVal(wxT("checked"), wxEmptyString);
+            v.MakeLower();
+            if (v && v == wxT("1"))
+                control->Check( i, TRUE );
+
+            i++;        
+            n = n->GetNext();
+        }
+        
+        SetupWindow(control);
+
+        if( strings != NULL )
+            delete [] strings;
+        strList.Clear();    // dump the strings   
+
+        return control;
+    }
+    else
+    {
+        // on the inside now.
+        // handle <item checked="boolean">Label</item>
+
+        // add to the list
+        strList.Add( GetNodeContent(m_node) );
+
+        return NULL;
+    }
+
+}
+
+
+
+bool wxCheckListXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return (IsOfClass(node, wxT("wxCheckList")) ||
+           (m_insideBox && node->GetName() == wxT("item"))
+           );
+}
+
+
diff --git a/src/xrc/xh_choic.cpp b/src/xrc/xh_choic.cpp
new file mode 100644 (file)
index 0000000..2d2dc7b
--- /dev/null
@@ -0,0 +1,95 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_choic.cpp
+// Purpose:     XML resource for wxChoice
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_choic.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_choic.h"
+#include "wx/choice.h"
+
+wxChoiceXmlHandler::wxChoiceXmlHandler() 
+: wxXmlResourceHandler() , m_insideBox(FALSE)
+{
+    ADD_STYLE(wxCB_SORT);
+    AddWindowStyles();
+}
+
+wxObject *wxChoiceXmlHandler::DoCreateResource()
+{ 
+    if( m_class == wxT("wxChoice"))
+    {
+        // find the selection
+        long selection = GetLong( wxT("selection"), -1 );
+
+        // need to build the list of strings from children
+        m_insideBox = TRUE;
+        CreateChildrenPrivately( NULL, GetParamNode(wxT("content")));
+        wxString *strings = (wxString *) NULL;
+        if( strList.GetCount() > 0 )
+        {
+            strings = new wxString[strList.GetCount()];
+            int count = strList.GetCount();
+            for( int i = 0; i < count; i++ )
+                strings[i]=strList[i];
+        }
+
+
+        wxChoice *control = new wxChoice(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    strList.GetCount(),
+                                    strings,
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+        if( selection != -1 )
+            control->SetSelection( selection );
+
+        SetupWindow(control);
+
+        if( strings != NULL )
+            delete [] strings;
+        strList.Clear();    // dump the strings   
+
+        return control;
+    }
+    else
+    {
+        // on the inside now.
+        // handle <item>Label</item>
+        
+        // add to the list
+        strList.Add( GetNodeContent(m_node) );
+
+        return NULL;
+    }
+
+}
+
+
+
+bool wxChoiceXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return (IsOfClass(node, wxT("wxChoice")) ||
+           (m_insideBox && node->GetName() == wxT("item"))
+           );
+}
+
+
diff --git a/src/xrc/xh_combo.cpp b/src/xrc/xh_combo.cpp
new file mode 100644 (file)
index 0000000..2353964
--- /dev/null
@@ -0,0 +1,101 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_combo.cpp
+// Purpose:     XML resource for wxRadioBox
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_combo.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_combo.h"
+#include "wx/combobox.h"
+
+#if wxUSE_COMBOBOX
+
+wxComboBoxXmlHandler::wxComboBoxXmlHandler() 
+: wxXmlResourceHandler() , m_insideBox(FALSE)
+{
+    ADD_STYLE(wxCB_SIMPLE);
+    ADD_STYLE(wxCB_SORT);
+    ADD_STYLE(wxCB_READONLY);
+    ADD_STYLE(wxCB_DROPDOWN);
+    AddWindowStyles();
+}
+
+wxObject *wxComboBoxXmlHandler::DoCreateResource()
+{ 
+    if( m_class == wxT("wxComboBox"))
+    {
+        // find the selection
+        long selection = GetLong( wxT("selection"), -1 );
+
+        // need to build the list of strings from children
+        m_insideBox = TRUE;
+        CreateChildrenPrivately( NULL, GetParamNode(wxT("content")));
+        wxString *strings = (wxString *) NULL;
+        if( strList.GetCount() > 0 )
+        {
+            strings = new wxString[strList.GetCount()];
+            int count = strList.GetCount();
+            for( int i = 0; i < count; i++ )
+                strings[i]=strList[i];
+        }
+
+
+        wxComboBox *control = new wxComboBox(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("value")),
+                                    GetPosition(), GetSize(),
+                                    strList.GetCount(),
+                                    strings,
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+        if( selection != -1 )
+            control->SetSelection( selection );
+
+        SetupWindow(control);
+
+        if( strings != NULL )
+            delete [] strings;
+        strList.Clear();    // dump the strings   
+
+        return control;
+    }
+    else
+    {
+        // on the inside now.
+        // handle <item>Label</item>
+
+        // add to the list
+        strList.Add( GetNodeContent(m_node) );
+
+        return NULL;
+    }
+
+}
+
+
+
+bool wxComboBoxXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return (IsOfClass(node, wxT("wxComboBox")) ||
+           (m_insideBox && node->GetName() == wxT("item"))
+           );
+}
+
+#endif
diff --git a/src/xrc/xh_dlg.cpp b/src/xrc/xh_dlg.cpp
new file mode 100644 (file)
index 0000000..9aec62e
--- /dev/null
@@ -0,0 +1,80 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_dlg.cpp
+// Purpose:     XML resource for dialogs
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_dlg.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_dlg.h"
+#include "wx/dialog.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+
+
+wxDialogXmlHandler::wxDialogXmlHandler() : wxXmlResourceHandler()
+{
+    ADD_STYLE(wxSTAY_ON_TOP);
+    ADD_STYLE(wxCAPTION);
+    ADD_STYLE(wxDEFAULT_DIALOG_STYLE);
+    ADD_STYLE(wxTHICK_FRAME);
+    ADD_STYLE(wxSYSTEM_MENU);
+    ADD_STYLE(wxRESIZE_BORDER);
+    ADD_STYLE(wxRESIZE_BOX);
+    ADD_STYLE(wxDIALOG_MODAL);
+    ADD_STYLE(wxDIALOG_MODELESS);
+
+    ADD_STYLE(wxNO_3D);
+    ADD_STYLE(wxTAB_TRAVERSAL);
+    ADD_STYLE(wxWS_EX_VALIDATE_RECURSIVELY);
+    ADD_STYLE(wxCLIP_CHILDREN);
+    AddWindowStyles();
+}
+
+
+
+wxObject *wxDialogXmlHandler::DoCreateResource()
+{ 
+    wxDialog *dlg = wxDynamicCast(m_instance, wxDialog);
+    
+    wxASSERT_MSG(dlg, _("XML resource: Cannot create dialog without instance."));
+    
+    dlg->Create(m_parentAsWindow,
+                GetID(),
+                GetText(wxT("title")),
+                wxDefaultPosition, wxDefaultSize,
+                GetStyle(wxT("style"), wxDEFAULT_DIALOG_STYLE),
+                GetName());
+    dlg->SetClientSize(GetSize());
+    dlg->Move(GetPosition());
+    SetupWindow(dlg);
+
+    CreateChildren(dlg);
+    
+    if (GetBool(_("centered"), FALSE))
+        dlg->Centre();
+    
+    return dlg;
+}
+
+
+
+bool wxDialogXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxDialog"));
+}
+
+
diff --git a/src/xrc/xh_frame.cpp b/src/xrc/xh_frame.cpp
new file mode 100644 (file)
index 0000000..7b5d003
--- /dev/null
@@ -0,0 +1,85 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_frame.cpp
+// Purpose:     XML resource for dialogs
+// Author:      Vaclav Slavik & Aleks.
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_frame.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_frame.h"
+#include "wx/frame.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+
+
+wxFrameXmlHandler::wxFrameXmlHandler() : wxXmlResourceHandler()
+{
+    ADD_STYLE(wxSTAY_ON_TOP);
+    ADD_STYLE(wxCAPTION);
+    ADD_STYLE(wxDEFAULT_DIALOG_STYLE);
+    ADD_STYLE(wxDEFAULT_FRAME_STYLE);
+    ADD_STYLE(wxTHICK_FRAME);
+    ADD_STYLE(wxSYSTEM_MENU);
+    ADD_STYLE(wxRESIZE_BORDER);
+    ADD_STYLE(wxRESIZE_BOX);
+
+    ADD_STYLE(wxFRAME_TOOL_WINDOW);
+    ADD_STYLE(wxFRAME_FLOAT_ON_PARENT);
+    ADD_STYLE(wxMAXIMIZE_BOX);
+    ADD_STYLE(wxMINIMIZE_BOX);
+    ADD_STYLE(wxSTAY_ON_TOP);
+
+    ADD_STYLE(wxNO_3D);
+    ADD_STYLE(wxTAB_TRAVERSAL);
+    ADD_STYLE(wxWS_EX_VALIDATE_RECURSIVELY);
+    ADD_STYLE(wxCLIP_CHILDREN);
+    AddWindowStyles();
+}
+
+
+
+wxObject *wxFrameXmlHandler::DoCreateResource()
+{ 
+    wxFrame *frame = wxDynamicCast(m_instance, wxFrame);
+    
+    wxASSERT_MSG(frame, _("XML resource: Cannot create dialog without instance."));
+    
+    frame->Create(m_parentAsWindow,
+                GetID(),
+                GetText(_T("title")),
+                wxDefaultPosition, wxDefaultSize,
+                GetStyle(_T("style"), wxDEFAULT_FRAME_STYLE),
+                GetName());
+    frame->SetClientSize(GetSize());
+    frame->Move(GetPosition());
+    SetupWindow(frame);
+
+    CreateChildren(frame);
+    
+    if (GetBool(_("centered"), FALSE))
+        frame->Centre();
+    
+    return frame;
+}
+
+
+
+bool wxFrameXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, _T("wxFrame"));
+}
+
+
diff --git a/src/xrc/xh_gauge.cpp b/src/xrc/xh_gauge.cpp
new file mode 100644 (file)
index 0000000..dec1db5
--- /dev/null
@@ -0,0 +1,74 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_gauge.cpp
+// Purpose:     XML resource for wxGauge
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_gauge.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_gauge.h"
+#include "wx/gauge.h"
+
+#if wxUSE_GAUGE
+
+wxGaugeXmlHandler::wxGaugeXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxGA_HORIZONTAL );
+    ADD_STYLE( wxGA_VERTICAL );
+    ADD_STYLE( wxGA_PROGRESSBAR );
+    ADD_STYLE( wxGA_SMOOTH );   // windows only
+    AddWindowStyles();
+}
+
+wxObject *wxGaugeXmlHandler::DoCreateResource()
+{ 
+    wxGauge *control = new wxGauge(m_parentAsWindow,
+                                    GetID(),
+                                    GetLong( wxT("range"), wxGAUGE_DEFAULT_RANGE), 
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+    if( HasParam( wxT("value") ))
+    {
+        control->SetValue( GetLong( wxT("value") ));
+    }
+    if( HasParam( wxT("shadow") ))
+    {
+        control->SetShadowWidth( GetDimension( wxT("shadow") ));
+    }
+    if( HasParam( wxT("bezel") ))
+    {
+        control->SetBezelFace( GetDimension( wxT("bezel") ));
+    }
+
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxGaugeXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxGauge"));
+}
+
+
+#endif // wxUSE_GAUGE
diff --git a/src/xrc/xh_html.cpp b/src/xrc/xh_html.cpp
new file mode 100644 (file)
index 0000000..affa03f
--- /dev/null
@@ -0,0 +1,72 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_html.cpp
+// Purpose:     XML resource for wxHtmlWindow
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_html.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_html.h"
+
+#if wxUSE_HTML
+
+#include "wx/html/htmlwin.h"
+
+
+wxHtmlWindowXmlHandler::wxHtmlWindowXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxHW_SCROLLBAR_NEVER );
+    ADD_STYLE( wxHW_SCROLLBAR_AUTO );
+    AddWindowStyles();
+}
+
+wxObject *wxHtmlWindowXmlHandler::DoCreateResource()
+{ 
+    wxHtmlWindow *control = new wxHtmlWindow(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    GetStyle( wxT("style" ), wxHW_SCROLLBAR_AUTO),
+                                    GetName()
+                                    );
+
+    if( HasParam( wxT("borders") ))
+    {
+        control->SetBorders( GetDimension( wxT("borders" )));
+    }
+
+    if( HasParam( wxT("url") ))
+    {
+        control->LoadPage( GetParamValue( wxT("url" )));
+    }
+    else if( HasParam( wxT("htmlcode") ))
+    {
+        control->SetPage( GetText(wxT("htmlcode")) );
+    }
+
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxHtmlWindowXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxHtmlWindow"));
+}
+
+#endif // wxUSE_HTML
diff --git a/src/xrc/xh_listb.cpp b/src/xrc/xh_listb.cpp
new file mode 100644 (file)
index 0000000..4cc771e
--- /dev/null
@@ -0,0 +1,101 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_listb.cpp
+// Purpose:     XML resource for wxListBox
+// Author:      Bob Mitchell & Vaclav Slavik
+// Created:     2000/07/29
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_listb.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_listb.h"
+#include "wx/listbox.h"
+
+wxListBoxXmlHandler::wxListBoxXmlHandler() 
+: wxXmlResourceHandler() , m_insideBox(FALSE)
+{
+    ADD_STYLE(wxLB_SINGLE);
+    ADD_STYLE(wxLB_MULTIPLE);
+    ADD_STYLE(wxLB_EXTENDED);
+    ADD_STYLE(wxLB_HSCROLL);
+    ADD_STYLE(wxLB_ALWAYS_SB);
+    ADD_STYLE(wxLB_NEEDED_SB);
+    ADD_STYLE(wxLB_SORT);
+    AddWindowStyles();
+}
+
+wxObject *wxListBoxXmlHandler::DoCreateResource()
+{ 
+    if( m_class == wxT("wxListBox"))
+    {
+        // find the selection
+        long selection = GetLong( wxT("selection"), -1 );
+
+        // need to build the list of strings from children
+        m_insideBox = TRUE;
+        CreateChildrenPrivately( NULL, GetParamNode(wxT("content")));
+        wxString *strings = (wxString *) NULL;
+        if( strList.GetCount() > 0 )
+        {
+            strings = new wxString[strList.GetCount()];
+            int count = strList.GetCount();
+            for( int i = 0; i < count; i++ )
+                strings[i]=strList[i];
+        }
+
+
+        wxListBox *control = new wxListBox(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    strList.GetCount(),
+                                    strings,
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+        if( selection != -1 )
+            control->SetSelection( selection );
+
+        SetupWindow(control);
+
+        if( strings != NULL )
+            delete [] strings;
+        strList.Clear();    // dump the strings   
+
+        return control;
+    }
+    else
+    {
+        // on the inside now.
+        // handle <item>Label</item>
+        
+        // add to the list
+        strList.Add( GetNodeContent(m_node) );
+
+        return NULL;
+    }
+
+}
+
+
+
+bool wxListBoxXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return (IsOfClass(node, wxT("wxListBox")) ||
+           (m_insideBox && node->GetName() == wxT("item"))
+           );
+}
+
+
diff --git a/src/xrc/xh_listc.cpp b/src/xrc/xh_listc.cpp
new file mode 100644 (file)
index 0000000..ee21109
--- /dev/null
@@ -0,0 +1,67 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_listc.cpp
+// Purpose:     XML resource for wxListCtrl
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_listc.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/textctrl.h"
+#include "wx/xrc/xh_listc.h"
+#include "wx/listctrl.h"
+
+
+wxListCtrlXmlHandler::wxListCtrlXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxLC_LIST);
+    ADD_STYLE(wxLC_REPORT);
+    ADD_STYLE(wxLC_ICON);
+    ADD_STYLE(wxLC_SMALL_ICON);
+    ADD_STYLE(wxLC_ALIGN_TOP);
+    ADD_STYLE(wxLC_ALIGN_LEFT);
+    ADD_STYLE(wxLC_AUTOARRANGE);
+    ADD_STYLE(wxLC_USER_TEXT);
+    ADD_STYLE(wxLC_EDIT_LABELS);
+    ADD_STYLE(wxLC_NO_HEADER);
+    ADD_STYLE(wxLC_SINGLE_SEL);
+    ADD_STYLE(wxLC_SORT_ASCENDING);
+    ADD_STYLE(wxLC_SORT_DESCENDING);
+    AddWindowStyles();
+}
+
+
+wxObject *wxListCtrlXmlHandler::DoCreateResource()
+{ 
+    wxListCtrl *list = new wxListCtrl(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName());
+    /* TODO: columns definition */
+    
+    SetupWindow(list);
+    
+    return list;
+}
+
+
+
+bool wxListCtrlXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxListCtrl"));
+}
diff --git a/src/xrc/xh_menu.cpp b/src/xrc/xh_menu.cpp
new file mode 100644 (file)
index 0000000..86a27e8
--- /dev/null
@@ -0,0 +1,135 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_menu.cpp
+// Purpose:     XML resource for menus and menubars
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_menu.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_menu.h"
+#include "wx/menu.h"
+
+
+wxMenuXmlHandler::wxMenuXmlHandler() : 
+        wxXmlResourceHandler(), m_insideMenu(FALSE)
+{
+    ADD_STYLE(wxMENU_TEAROFF);
+}
+
+
+
+wxObject *wxMenuXmlHandler::DoCreateResource()
+{
+    if (m_class == wxT("wxMenu"))
+    {
+        wxMenu *menu = new wxMenu(GetStyle());
+        wxString title = GetText(wxT("label"));
+        wxString help = GetText(wxT("help"));
+        
+        bool oldins = m_insideMenu;
+        m_insideMenu = TRUE;
+        CreateChildren(menu, TRUE/*only this handler*/);
+        m_insideMenu = oldins;
+
+        wxMenuBar *p_bar = wxDynamicCast(m_parent, wxMenuBar);
+        if (p_bar)
+            p_bar->Append(menu, title);
+        else
+        {
+            wxMenu *p_menu = wxDynamicCast(m_parent, wxMenu);
+            if (p_menu)
+                p_menu->Append(GetID(), title, menu, help);
+        }
+
+        return menu;
+    }
+
+    else
+    {
+        wxMenu *p_menu = wxDynamicCast(m_parent, wxMenu);
+        
+        if (m_class == wxT("separator"))
+            p_menu->AppendSeparator();
+        else if (m_class == wxT("break"))
+            p_menu->Break();
+        else /*wxMenuItem*/
+        {
+            int id = GetID();
+            bool checkable = GetBool(wxT("checkable"));
+            wxString label = GetText(wxT("label"));
+            wxString accel = GetText(wxT("accel"));
+            wxString fullLabel = label;
+            if (!accel.IsEmpty())
+                fullLabel << wxT("\t") << accel;
+
+            wxMenuItem *mitem = new wxMenuItem(p_menu, id, fullLabel,
+                                               GetText(wxT("help")), checkable);
+                                               
+#if wxCHECK_VERSION(2,3,0) || defined(__WXMSW__)
+                if (HasParam(wxT("bitmap")))
+                    mitem->SetBitmap(GetBitmap(wxT("bitmap")));
+#endif
+            p_menu->Append(mitem);
+            mitem->Enable(GetBool(wxT("enabled"), TRUE));
+            if (checkable) mitem->Check(GetBool(wxT("checked")));
+        }
+        return NULL;
+    }
+}
+
+
+
+bool wxMenuXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxMenu")) ||
+           (m_insideMenu && 
+               (IsOfClass(node, wxT("wxMenuItem")) ||
+                IsOfClass(node, wxT("break")) ||
+                IsOfClass(node, wxT("separator")))
+           );
+}
+
+
+
+
+
+
+
+
+
+
+
+wxMenuBarXmlHandler::wxMenuBarXmlHandler() : wxXmlResourceHandler()
+{
+    ADD_STYLE(wxMB_DOCKABLE);
+}
+
+
+
+wxObject *wxMenuBarXmlHandler::DoCreateResource()
+{
+    wxMenuBar *menubar = new wxMenuBar(GetStyle());
+    CreateChildren(menubar);
+    return menubar;
+}
+
+
+
+bool wxMenuBarXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxMenuBar"));
+}
+
diff --git a/src/xrc/xh_notbk.cpp b/src/xrc/xh_notbk.cpp
new file mode 100644 (file)
index 0000000..fe648dc
--- /dev/null
@@ -0,0 +1,100 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_notbk.cpp
+// Purpose:     XML resource for wxNotebook
+// Author:      Vaclav Slavik
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_notbk.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_notbk.h"
+
+#if wxUSE_NOTEBOOK
+
+#include "wx/log.h"
+#include "wx/notebook.h"
+#include "wx/sizer.h"
+
+wxNotebookXmlHandler::wxNotebookXmlHandler() 
+: wxXmlResourceHandler(), m_isInside(FALSE), m_notebook(NULL)
+{
+    ADD_STYLE(wxNB_FIXEDWIDTH);
+    ADD_STYLE(wxNB_LEFT);
+    ADD_STYLE(wxNB_RIGHT);
+    ADD_STYLE(wxNB_BOTTOM);
+    AddWindowStyles();
+}
+
+
+
+wxObject *wxNotebookXmlHandler::DoCreateResource()
+{ 
+    if (m_class == wxT("notebookpage"))
+    {
+        wxXmlNode *n = GetParamNode(wxT("object"));
+
+        if (n)
+        {
+            bool old_ins = m_isInside;
+            m_isInside = FALSE;
+            m_isInside = old_ins;
+            wxObject *item = CreateResFromNode(n, m_notebook, NULL);
+            wxWindow *wnd = wxDynamicCast(item, wxWindow);
+
+            if (wnd)
+                m_notebook->AddPage(wnd, GetText(wxT("label")),
+                                         GetBool(wxT("selected"), 0));
+            else 
+                wxLogError(wxT("Error in resource."));              
+            return wnd;
+        }
+        else
+        {
+            wxLogError(wxT("Error in resource: no control within notebook's <page> tag."));
+            return NULL;
+        }
+    }
+    
+    else {
+        wxNotebook *nb = new wxNotebook(m_parentAsWindow, 
+                                        GetID(),
+                                        GetPosition(), GetSize(),
+                                        GetStyle( wxT("style" )),
+                                        GetName());
+    
+        wxNotebook *old_par = m_notebook;
+        m_notebook = nb;
+        bool old_ins = m_isInside;
+        m_isInside = TRUE;
+        CreateChildren(m_notebook, TRUE/*only this handler*/);
+        m_isInside = old_ins;
+        m_notebook = old_par;
+
+        if (GetBool(wxT("usenotebooksizer"), FALSE))
+            return new wxNotebookSizer(nb);
+        else
+            return nb;
+    }
+}
+
+
+
+bool wxNotebookXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return ((!m_isInside && IsOfClass(node, wxT("wxNotebook"))) ||
+            (m_isInside && IsOfClass(node, wxT("notebookpage"))));
+}
+
+#endif
diff --git a/src/xrc/xh_panel.cpp b/src/xrc/xh_panel.cpp
new file mode 100644 (file)
index 0000000..d4d4095
--- /dev/null
@@ -0,0 +1,63 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_panel.cpp
+// Purpose:     XML resource for panels
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_panel.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_panel.h"
+#include "wx/panel.h"
+
+
+wxPanelXmlHandler::wxPanelXmlHandler() : wxXmlResourceHandler()
+{
+    ADD_STYLE(wxNO_3D);
+    ADD_STYLE(wxTAB_TRAVERSAL);
+    ADD_STYLE(wxWS_EX_VALIDATE_RECURSIVELY);
+    ADD_STYLE(wxCLIP_CHILDREN);
+    AddWindowStyles();
+}
+
+
+
+wxObject *wxPanelXmlHandler::DoCreateResource()
+{ 
+    wxPanel *panel = wxDynamicCast(m_instance, wxPanel);
+
+    if (panel == NULL)
+        panel = new wxPanel(m_parentAsWindow,
+                                 GetID(),
+                                 GetPosition(), GetSize(),
+                                 GetStyle(wxT("style"), wxTAB_TRAVERSAL),
+                                 GetName());
+    else
+        panel->Create(m_parentAsWindow,
+                                 GetID(),
+                                 GetPosition(), GetSize(),
+                                 GetStyle(wxT("style"), wxTAB_TRAVERSAL),
+                                 GetName());
+    SetupWindow(panel);
+    CreateChildren(panel);
+    
+    return panel;
+}
+
+
+bool wxPanelXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxPanel"));
+}
diff --git a/src/xrc/xh_radbt.cpp b/src/xrc/xh_radbt.cpp
new file mode 100644 (file)
index 0000000..9caa453
--- /dev/null
@@ -0,0 +1,66 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_radbt.cpp
+// Purpose:     XML resource for wxRadioButton
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_radbt.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_radbt.h"
+#include "wx/radiobut.h"
+
+#if wxUSE_RADIOBOX
+
+wxRadioButtonXmlHandler::wxRadioButtonXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxRB_GROUP );
+    AddWindowStyles();
+}
+
+wxObject *wxRadioButtonXmlHandler::DoCreateResource()
+{ 
+    /* BOBM - implementation note.
+     * once the wxBitmapRadioButton is implemented.
+     * look for a bitmap property. If not null, 
+     * make it a wxBitmapRadioButton instead of the 
+     * normal radio button.
+     */ 
+
+    wxRadioButton *control = new wxRadioButton(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("label")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+    control->SetValue( GetBool(wxT("value"), 0));
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxRadioButtonXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxRadioButton"));
+}
+
+
+#endif
diff --git a/src/xrc/xh_radbx.cpp b/src/xrc/xh_radbx.cpp
new file mode 100644 (file)
index 0000000..7d22430
--- /dev/null
@@ -0,0 +1,102 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_radbx.cpp
+// Purpose:     XML resource for wxRadioBox
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_radbx.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_radbx.h"
+#include "wx/radiobox.h"
+
+#if wxUSE_RADIOBOX
+
+wxRadioBoxXmlHandler::wxRadioBoxXmlHandler() 
+: wxXmlResourceHandler() , m_insideBox(FALSE)
+{
+    ADD_STYLE(wxRA_SPECIFY_COLS);
+    ADD_STYLE(wxRA_HORIZONTAL);
+    ADD_STYLE(wxRA_SPECIFY_ROWS);
+    ADD_STYLE(wxRA_VERTICAL);
+    AddWindowStyles();
+}
+
+wxObject *wxRadioBoxXmlHandler::DoCreateResource()
+{ 
+    if( m_class == wxT("wxRadioBox"))
+    {
+        // find the selection
+        long selection = GetLong( wxT("selection"), -1 );
+
+        // need to build the list of strings from children
+        m_insideBox = TRUE;
+        CreateChildrenPrivately( NULL, GetParamNode(wxT("content")));
+        wxString *strings = (wxString *) NULL;
+        if( strList.GetCount() > 0 )
+        {
+            strings = new wxString[strList.GetCount()];
+            int count = strList.GetCount();
+            for( int i = 0; i < count; i++ )
+                strings[i]=strList[i];
+        }
+
+
+        wxRadioBox *control = new wxRadioBox(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("label")),
+                                    GetPosition(), GetSize(),
+                                    strList.GetCount(),
+                                    strings,
+                                    GetLong( wxT("dimension"), 1 ),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+        if( selection != -1 )
+            control->SetSelection( selection );
+
+        SetupWindow(control);
+
+        if( strings != NULL )
+            delete [] strings;
+        strList.Clear();    // dump the strings   
+
+        return control;
+    }
+    else
+    {
+        // on the inside now.
+        // handle <item selected="boolean">Label</item>
+
+        // add to the list
+        strList.Add( GetNodeContent(m_node) );
+
+        return NULL;
+    }
+
+}
+
+
+
+bool wxRadioBoxXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return (IsOfClass(node, wxT("wxRadioBox")) ||
+           (m_insideBox && node->GetName() == wxT("item"))
+           );
+}
+
+#endif
diff --git a/src/xrc/xh_scrol.cpp b/src/xrc/xh_scrol.cpp
new file mode 100644 (file)
index 0000000..22af947
--- /dev/null
@@ -0,0 +1,63 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_scrol.cpp
+// Purpose:     XML resource for wxScrollBar
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_scrol.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_scrol.h"
+#include "wx/scrolbar.h"
+
+
+wxScrollBarXmlHandler::wxScrollBarXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxSB_HORIZONTAL );
+    ADD_STYLE( wxSB_VERTICAL );
+    AddWindowStyles();
+}
+
+wxObject *wxScrollBarXmlHandler::DoCreateResource()
+{ 
+    wxScrollBar *control = new wxScrollBar(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+    control->SetScrollbar(GetLong( wxT("value"), 0), 
+                          GetLong( wxT("thumbsize"),1),
+                          GetLong( wxT("range"), 10),
+                          GetLong( wxT("pagesize"),1)
+                          );
+                          
+    
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxScrollBarXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxScrollBar"));
+}
+
+
+
diff --git a/src/xrc/xh_sizer.cpp b/src/xrc/xh_sizer.cpp
new file mode 100644 (file)
index 0000000..0a64cbc
--- /dev/null
@@ -0,0 +1,219 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_sizer.cpp
+// Purpose:     XML resource for wxBoxSizer
+// Author:      Vaclav Slavik
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_sizer.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_sizer.h"
+#include "wx/sizer.h"
+#include "wx/log.h"
+#include "wx/statbox.h"
+#include "wx/notebook.h"
+#include "wx/tokenzr.h"
+
+bool wxSizerXmlHandler::IsSizerNode(wxXmlNode *node)
+{
+    return (IsOfClass(node, wxT("wxBoxSizer"))) ||
+           (IsOfClass(node, wxT("wxStaticBoxSizer"))) ||
+           (IsOfClass(node, wxT("wxGridSizer"))) ||
+           (IsOfClass(node, wxT("wxFlexGridSizer")));
+}
+
+
+
+wxSizerXmlHandler::wxSizerXmlHandler() 
+: wxXmlResourceHandler(), m_isInside(FALSE), m_parentSizer(NULL)
+{
+    ADD_STYLE(wxHORIZONTAL);
+    ADD_STYLE(wxVERTICAL);
+
+    // and flags
+    ADD_STYLE(wxLEFT);
+    ADD_STYLE(wxRIGHT);
+    ADD_STYLE(wxTOP);
+    ADD_STYLE(wxBOTTOM);
+    ADD_STYLE(wxNORTH);
+    ADD_STYLE(wxSOUTH);
+    ADD_STYLE(wxEAST);
+    ADD_STYLE(wxWEST);
+    ADD_STYLE(wxALL);
+
+    ADD_STYLE(wxGROW);
+    ADD_STYLE(wxEXPAND);
+    ADD_STYLE(wxSHAPED);
+    ADD_STYLE(wxSTRETCH_NOT);
+
+    ADD_STYLE(wxALIGN_CENTER);
+    ADD_STYLE(wxALIGN_CENTRE);
+    ADD_STYLE(wxALIGN_LEFT);
+    ADD_STYLE(wxALIGN_TOP);
+    ADD_STYLE(wxALIGN_RIGHT);
+    ADD_STYLE(wxALIGN_BOTTOM);
+    ADD_STYLE(wxALIGN_CENTER_HORIZONTAL);
+    ADD_STYLE(wxALIGN_CENTRE_HORIZONTAL);
+    ADD_STYLE(wxALIGN_CENTER_VERTICAL);
+    ADD_STYLE(wxALIGN_CENTRE_VERTICAL);
+}
+
+
+
+wxObject *wxSizerXmlHandler::DoCreateResource()
+{ 
+    if (m_class == wxT("sizeritem"))
+    {
+        wxXmlNode *n = GetParamNode(wxT("object"));
+
+        if (n)
+        {
+            bool old_ins = m_isInside;
+            wxSizer *old_par = m_parentSizer;
+            m_isInside = FALSE;
+            if (!IsSizerNode(n)) m_parentSizer = NULL;
+            wxObject *item = CreateResFromNode(n, m_parent, NULL);
+            m_isInside = old_ins;
+            m_parentSizer = old_par;
+            wxSizer *sizer = wxDynamicCast(item, wxSizer);
+            wxWindow *wnd = wxDynamicCast(item, wxWindow);
+            wxSize minsize = GetSize(wxT("minsize"));
+
+            if (sizer)
+            {
+                m_parentSizer->Add(sizer, GetLong(wxT("option")), 
+                                   GetStyle(wxT("flag")), GetDimension(wxT("border")));
+                if (!(minsize == wxDefaultSize))
+                    m_parentSizer->SetItemMinSize(sizer, minsize.x, minsize.y);
+            }
+            else if (wnd)
+            {
+                m_parentSizer->Add(wnd, GetLong(wxT("option")), 
+                                   GetStyle(wxT("flag")), GetDimension(wxT("border")));
+                if (!(minsize == wxDefaultSize))
+                    m_parentSizer->SetItemMinSize(wnd, minsize.x, minsize.y);
+            }
+            else 
+                wxLogError(wxT("Error in resource."));
+
+            return item;
+        }
+        else /*n == NULL*/
+        {
+            wxLogError(wxT("Error in resource: no control/sizer within sizer's <item> tag."));
+            return NULL;
+        }
+    }
+    
+    else if (m_class == wxT("spacer"))
+    {
+        wxCHECK_MSG(m_parentSizer, NULL, wxT("Incorrect syntax of XML resource: spacer not within sizer!"));
+        wxSize sz = GetSize();
+        m_parentSizer->Add(sz.x, sz.y,
+            GetLong(wxT("option")), GetStyle(wxT("flag")), GetDimension(wxT("border")));
+        return NULL;
+    }
+    
+
+    else {
+        wxSizer *sizer = NULL;
+        
+        wxXmlNode *parentNode = m_node->GetParent();
+
+        wxCHECK_MSG(m_parentSizer != NULL ||
+                ((IsOfClass(parentNode, wxT("wxPanel")) ||
+                  IsOfClass(parentNode, wxT("wxDialog"))) &&
+                 parentNode->GetType() == wxXML_ELEMENT_NODE), NULL,
+                wxT("Incorrect use of sizer: parent is not 'wxDialog' or 'wxPanel'."));
+
+        if (m_class == wxT("wxBoxSizer"))
+            sizer = new wxBoxSizer(GetStyle(wxT("orient"), wxHORIZONTAL));
+
+        else if (m_class == wxT("wxStaticBoxSizer"))
+        {
+            sizer = new wxStaticBoxSizer(
+                         new wxStaticBox(m_parentAsWindow, -1, GetText(wxT("label"))),
+                         GetStyle(wxT("orient"), wxHORIZONTAL));
+        }
+        
+        else if (m_class == wxT("wxGridSizer"))
+            sizer = new wxGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
+                                    GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
+                                    
+        else if (m_class == wxT("wxFlexGridSizer"))
+        {
+            wxFlexGridSizer *fsizer = 
+                  new wxFlexGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
+                      GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
+            sizer = fsizer;
+            wxStringTokenizer tkn;
+            unsigned long l;
+            tkn.SetString(GetParamValue(wxT("growablerows")), wxT(","));
+            while (tkn.HasMoreTokens())
+            {
+                if (!tkn.GetNextToken().ToULong(&l))
+                    wxLogError(wxT("growablerows must be comma-separated list of row numbers"));
+                else
+                    fsizer->AddGrowableRow(l);
+            }
+            tkn.SetString(GetParamValue(wxT("growablecols")), wxT(","));
+            while (tkn.HasMoreTokens())
+            {
+                if (!tkn.GetNextToken().ToULong(&l))
+                    wxLogError(wxT("growablecols must be comma-separated list of column numbers"));
+                else
+                    fsizer->AddGrowableCol(l);
+            }
+        }
+
+        wxSize minsize = GetSize(wxT("minsize"));
+        if (!(minsize == wxDefaultSize))
+            sizer->SetMinSize(minsize);
+
+        wxSizer *old_par = m_parentSizer;
+        m_parentSizer = sizer;
+        bool old_ins = m_isInside;
+        m_isInside = TRUE;
+        CreateChildren(m_parent, TRUE/*only this handler*/);
+        m_isInside = old_ins;
+        m_parentSizer = old_par;
+        
+        if (m_parentSizer == NULL) // setup window:
+        {
+            m_parentAsWindow->SetAutoLayout(TRUE);
+            m_parentAsWindow->SetSizer(sizer);
+
+            wxXmlNode *nd = m_node;
+            m_node = parentNode;
+            if (GetSize() == wxDefaultSize)
+                sizer->Fit(m_parentAsWindow);
+            m_node = nd;
+
+            if (m_parentAsWindow->GetWindowStyle() & (wxRESIZE_BOX | wxRESIZE_BORDER))
+                sizer->SetSizeHints(m_parentAsWindow);
+        }
+        
+        return sizer;
+    }
+}
+
+
+
+bool wxSizerXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return ((!m_isInside && IsSizerNode(node)) ||
+            (m_isInside && IsOfClass(node, wxT("sizeritem"))) ||
+            (m_isInside && IsOfClass(node, wxT("spacer"))));
+}
diff --git a/src/xrc/xh_slidr.cpp b/src/xrc/xh_slidr.cpp
new file mode 100644 (file)
index 0000000..52e0233
--- /dev/null
@@ -0,0 +1,94 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_slidr.cpp
+// Purpose:     XML resource for wxSlider
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_slidr.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_slidr.h"
+#include "wx/slider.h"
+
+#if wxUSE_SLIDER
+
+wxSliderXmlHandler::wxSliderXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxSL_HORIZONTAL );
+    ADD_STYLE( wxSL_VERTICAL );
+    ADD_STYLE( wxSL_AUTOTICKS );
+    ADD_STYLE( wxSL_LABELS );
+    ADD_STYLE( wxSL_LEFT );
+    ADD_STYLE( wxSL_TOP );
+    ADD_STYLE( wxSL_RIGHT );
+    ADD_STYLE( wxSL_BOTTOM );
+    ADD_STYLE( wxSL_BOTH );
+    ADD_STYLE( wxSL_SELRANGE );
+    AddWindowStyles();
+}
+
+wxObject *wxSliderXmlHandler::DoCreateResource()
+{ 
+    wxSlider *control = new wxSlider(m_parentAsWindow,
+                                    GetID(),
+                                    GetLong( wxT("value"), wxSL_DEFAULT_VALUE), 
+                                    GetLong( wxT("min"), wxSL_DEFAULT_MIN),
+                                    GetLong( wxT("max"), wxSL_DEFAULT_MAX),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+
+    if( HasParam( wxT("tickfreq") ))
+    {
+        control->SetTickFreq( GetLong( wxT("tickfreq") ), 0 );
+    }
+    if( HasParam( wxT("pagesize") ))
+    {
+        control->SetPageSize( GetLong( wxT("pagesize") ) );
+    }
+    if( HasParam( wxT("linesize") ))
+    {
+        control->SetLineSize( GetLong( wxT("linesize") ));
+    }
+    if( HasParam( wxT("thumb") ))
+    {
+        control->SetThumbLength( GetLong( wxT("thumb") ));
+    }
+    if( HasParam( wxT("tick") ))
+    {
+        control->SetTick( GetLong( wxT("tick") ));
+    }
+    if( HasParam( wxT("selmin") ) && HasParam( wxT("selmax")) )
+    {
+        control->SetSelection( GetLong( wxT("selmin") ), GetLong( wxT("selmax")) );
+    }
+
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxSliderXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxSlider"));
+}
+
+
+#endif
diff --git a/src/xrc/xh_spin.cpp b/src/xrc/xh_spin.cpp
new file mode 100644 (file)
index 0000000..bda1eeb
--- /dev/null
@@ -0,0 +1,99 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_spin.cpp
+// Purpose:     XML resource for wxSpinButton
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_spin.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_spin.h"
+#include "wx/spinctrl.h"
+
+#if wxUSE_SPINBTN
+
+wxSpinButtonXmlHandler::wxSpinButtonXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxSP_HORIZONTAL );
+    ADD_STYLE( wxSP_VERTICAL );
+    ADD_STYLE( wxSP_ARROW_KEYS );
+    ADD_STYLE( wxSP_WRAP );
+    AddWindowStyles();
+}
+
+wxObject *wxSpinButtonXmlHandler::DoCreateResource()
+{ 
+    wxSpinButton *control = new wxSpinButton(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    GetStyle( wxT("style"), wxSP_VERTICAL | wxSP_ARROW_KEYS ),
+                                    GetName()
+                                    );
+
+    control->SetValue( GetLong( wxT("value"), wxSP_DEFAULT_VALUE) );
+    control->SetRange( GetLong( wxT("min"), wxSP_DEFAULT_MIN),
+            GetLong( wxT("max"), wxSP_DEFAULT_MAX) );
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxSpinButtonXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxSpinButton"));
+}
+
+#endif // wxUSE_SPINBTN
+
+#if wxUSE_SPINCTRL
+
+wxSpinCtrlXmlHandler::wxSpinCtrlXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE( wxSP_HORIZONTAL );
+    ADD_STYLE( wxSP_VERTICAL );
+    ADD_STYLE( wxSP_ARROW_KEYS );
+    ADD_STYLE( wxSP_WRAP );
+}
+
+wxObject *wxSpinCtrlXmlHandler::DoCreateResource()
+{ 
+    wxSpinCtrl *control = new wxSpinCtrl(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("value")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle( wxT("style"), wxSP_ARROW_KEYS ),
+                                    GetLong( wxT("min"), wxSP_DEFAULT_MIN),
+                                    GetLong( wxT("max"), wxSP_DEFAULT_MAX),
+                                    GetLong( wxT("value"), wxSP_DEFAULT_VALUE),
+                                    GetName()
+                                    );
+
+    SetupWindow(control);
+    
+    return control;
+}
+
+
+
+bool wxSpinCtrlXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxSpinCtrl"));
+}
+
+#endif // wxUSE_SPINCTRL
diff --git a/src/xrc/xh_stbmp.cpp b/src/xrc/xh_stbmp.cpp
new file mode 100644 (file)
index 0000000..4937175
--- /dev/null
@@ -0,0 +1,52 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_stbmp.cpp
+// Purpose:     XML resource for wxStaticBitmap
+// Author:      Vaclav Slavik
+// Created:     2000/04/22
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_stbmp.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_stbmp.h"
+#include "wx/statbmp.h"
+
+wxStaticBitmapXmlHandler::wxStaticBitmapXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    AddWindowStyles();
+}
+
+wxObject *wxStaticBitmapXmlHandler::DoCreateResource()
+{ 
+    wxStaticBitmap *bmp = new wxStaticBitmap(m_parentAsWindow,
+                                    GetID(),
+                                    GetBitmap(wxT("bitmap"), GetSize()),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    GetName()
+                                    );
+    SetupWindow(bmp);
+    
+    return bmp;
+}
+
+
+
+bool wxStaticBitmapXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxStaticBitmap"));
+}
+
+
diff --git a/src/xrc/xh_stbox.cpp b/src/xrc/xh_stbox.cpp
new file mode 100644 (file)
index 0000000..42b5e97
--- /dev/null
@@ -0,0 +1,52 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_stbox.cpp
+// Purpose:     XML resource for wxStaticBox
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_stbox.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_stbox.h"
+#include "wx/statbox.h"
+
+wxStaticBoxXmlHandler::wxStaticBoxXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    AddWindowStyles();
+}
+
+wxObject *wxStaticBoxXmlHandler::DoCreateResource()
+{ 
+    wxStaticBox *box = new wxStaticBox(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("label")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    GetName()
+                                    );
+    SetupWindow(box);
+    
+    return box;
+}
+
+
+
+bool wxStaticBoxXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxStaticBox"));
+}
+
+
diff --git a/src/xrc/xh_stlin.cpp b/src/xrc/xh_stlin.cpp
new file mode 100644 (file)
index 0000000..9418de0
--- /dev/null
@@ -0,0 +1,55 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_stbox.cpp
+// Purpose:     XML resource for wxStaticLine
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_stlin.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_stlin.h"
+#include "wx/statline.h"
+
+#if wxUSE_STATLINE
+
+wxStaticLineXmlHandler::wxStaticLineXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxLI_HORIZONTAL);
+    ADD_STYLE(wxLI_VERTICAL);
+    AddWindowStyles();
+}
+
+wxObject *wxStaticLineXmlHandler::DoCreateResource()
+{ 
+    wxStaticLine *line = new wxStaticLine(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(wxT("style"), wxLI_HORIZONTAL),
+                                    GetName()
+                                    );
+    SetupWindow(line);
+    
+    return line;
+}
+
+
+
+bool wxStaticLineXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxStaticLine"));
+}
+
+#endif
diff --git a/src/xrc/xh_sttxt.cpp b/src/xrc/xh_sttxt.cpp
new file mode 100644 (file)
index 0000000..c188afb
--- /dev/null
@@ -0,0 +1,56 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_sttxt.cpp
+// Purpose:     XML resource for wxStaticText
+// Author:      Bob Mitchell
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Bob Mitchell and Verant Interactive
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_sttxt.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_sttxt.h"
+#include "wx/stattext.h"
+
+wxStaticTextXmlHandler::wxStaticTextXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxST_NO_AUTORESIZE);
+    ADD_STYLE(wxALIGN_LEFT);
+    ADD_STYLE(wxALIGN_RIGHT);
+    ADD_STYLE(wxALIGN_CENTRE);
+    AddWindowStyles();
+}
+
+wxObject *wxStaticTextXmlHandler::DoCreateResource()
+{ 
+    wxStaticText *text = new wxStaticText(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("label")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    GetName()
+                                    );
+    SetupWindow(text);
+    
+    return text;
+}
+
+
+
+bool wxStaticTextXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxStaticText"));
+}
+
+
diff --git a/src/xrc/xh_text.cpp b/src/xrc/xh_text.cpp
new file mode 100644 (file)
index 0000000..26d8510
--- /dev/null
@@ -0,0 +1,58 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_text.cpp
+// Purpose:     XML resource for wxTextCtrl
+// Author:      Aleksandras Gluchovas
+// Created:     2000/03/21
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Aleksandras Gluchovas
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_text.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_text.h"
+#include "wx/textctrl.h"
+
+wxTextCtrlXmlHandler::wxTextCtrlXmlHandler() : wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxTE_PROCESS_ENTER);
+    ADD_STYLE(wxTE_PROCESS_TAB);
+    ADD_STYLE(wxTE_MULTILINE);
+    ADD_STYLE(wxTE_PASSWORD);
+    ADD_STYLE(wxTE_READONLY);
+    ADD_STYLE(wxHSCROLL);
+    AddWindowStyles();
+}
+
+wxObject *wxTextCtrlXmlHandler::DoCreateResource()
+{ 
+    wxTextCtrl *text = new wxTextCtrl(m_parentAsWindow,
+                                    GetID(),
+                                    GetText(wxT("value")),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName()
+                                    );
+    SetupWindow(text);
+    
+    return text;
+}
+
+
+
+bool wxTextCtrlXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxTextCtrl"));
+}
+
+
diff --git a/src/xrc/xh_toolb.cpp b/src/xrc/xh_toolb.cpp
new file mode 100644 (file)
index 0000000..e8c1253
--- /dev/null
@@ -0,0 +1,129 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_toolb.cpp
+// Purpose:     XML resource for wxBoxSizer
+// Author:      Vaclav Slavik
+// Created:     2000/08/11
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_toolb.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_toolb.h"
+#include "wx/toolbar.h"
+
+
+#if wxUSE_TOOLBAR
+
+wxToolBarXmlHandler::wxToolBarXmlHandler() 
+: wxXmlResourceHandler(), m_isInside(FALSE), m_toolbar(NULL)
+{
+    ADD_STYLE(wxTB_FLAT);
+    ADD_STYLE(wxTB_DOCKABLE);
+    ADD_STYLE(wxTB_VERTICAL);
+    ADD_STYLE(wxTB_HORIZONTAL);
+}
+
+
+
+wxObject *wxToolBarXmlHandler::DoCreateResource()
+{ 
+    if (m_class == wxT("tool"))
+    {
+        wxCHECK_MSG(m_toolbar, NULL, wxT("Incorrect syntax of XML resource: tool not within a toolbar!"));
+        m_toolbar->AddTool(GetID(),
+                           GetBitmap(wxT("bitmap")),
+                           GetBitmap(wxT("bitmap2")),
+                           GetBool(wxT("toggle")),
+                           GetPosition().x,
+                           GetPosition().y,
+                           NULL,
+                           GetText(wxT("tooltip")),
+                           GetText(wxT("longhelp")));
+        return m_toolbar; // must return non-NULL
+    }
+    
+    else if (m_class == wxT("separator"))
+    {
+        wxCHECK_MSG(m_toolbar, NULL, wxT("Incorrect syntax of XML resource: separator not within a toolbar!"));
+        m_toolbar->AddSeparator();
+        return m_toolbar; // must return non-NULL
+    }
+    
+    else /*<object class="wxToolBar">*/
+    {
+        int style = GetStyle(wxT("style"), wxNO_BORDER | wxTB_HORIZONTAL);
+#ifdef __WXMSW__
+        if (!(style & wxNO_BORDER)) style |= wxNO_BORDER;
+#endif
+        wxToolBar *toolbar = new wxToolBar(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(),
+                                    GetSize(),
+                                    style,
+                                    GetName());
+
+        wxSize bmpsize = GetSize(wxT("bitmapsize"));
+        if (!(bmpsize == wxDefaultSize))
+            toolbar->SetToolBitmapSize(bmpsize);
+        wxSize margins = GetSize(wxT("margins"));
+        if (!(margins == wxDefaultSize))
+            toolbar->SetMargins(margins.x, margins.y);
+        long packing = GetLong(wxT("packing"), -1);
+        if (packing != -1)
+            toolbar->SetToolPacking(packing);
+        long separation = GetLong(wxT("separation"), -1);
+        if (separation != -1)
+            toolbar->SetToolSeparation(separation);
+
+        wxXmlNode *children_node = GetParamNode(wxT("object"));
+        if (children_node == NULL) return toolbar;
+
+        m_isInside = TRUE;
+        m_toolbar = toolbar;
+
+        wxXmlNode *n = children_node;
+
+        while (n)
+        {
+            if (n->GetType() == wxXML_ELEMENT_NODE && 
+                n->GetName() == wxT("object"))
+            {
+                wxObject *created = CreateResFromNode(n, toolbar, NULL);
+                wxControl *control = wxDynamicCast(created, wxControl);
+                if (IsOfClass(n, wxT("tool")) &&
+                    IsOfClass(n, wxT("separator")) &&
+                    control != NULL)
+                    toolbar->AddControl(control);
+            }
+            n = n->GetNext();
+        }
+
+        m_isInside = FALSE;
+        m_toolbar = NULL;
+
+        toolbar->Realize();
+        return toolbar;
+    }
+}
+
+
+
+bool wxToolBarXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return ((!m_isInside && IsOfClass(node, wxT("wxToolBar"))) ||
+            (m_isInside && IsOfClass(node, wxT("tool"))) || 
+            (m_isInside && IsOfClass(node, wxT("separator"))));
+}
+
+#endif
diff --git a/src/xrc/xh_tree.cpp b/src/xrc/xh_tree.cpp
new file mode 100644 (file)
index 0000000..5bec60c
--- /dev/null
@@ -0,0 +1,57 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_tree.cpp
+// Purpose:     XML resource for wxTreeCtrl
+// Author:      Brian Gavin
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Brian Gavin
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_tree.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_tree.h"
+#include "wx/treectrl.h"
+
+
+wxTreeCtrlXmlHandler::wxTreeCtrlXmlHandler() 
+: wxXmlResourceHandler() 
+{
+    ADD_STYLE(wxTR_HAS_BUTTONS);
+    ADD_STYLE(wxTR_EDIT_LABELS);
+    ADD_STYLE(wxTR_MULTIPLE);
+    AddWindowStyles();
+}
+
+
+wxObject *wxTreeCtrlXmlHandler::DoCreateResource()
+{ 
+    wxTreeCtrl *tree = new wxTreeCtrl(m_parentAsWindow,
+                                    GetID(),
+                                    GetPosition(), GetSize(),
+                                    GetStyle(),
+                                    wxDefaultValidator,
+                                    GetName());
+    
+    SetupWindow(tree);
+    
+    return tree;
+}
+
+
+
+bool wxTreeCtrlXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("wxTreeCtrl"));
+}
+
+
diff --git a/src/xrc/xh_unkwn.cpp b/src/xrc/xh_unkwn.cpp
new file mode 100644 (file)
index 0000000..d08cba8
--- /dev/null
@@ -0,0 +1,91 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_unkwn.cpp
+// Purpose:     XML resource for unknown widget
+// Author:      Vaclav Slavik
+// Created:     2000/09/09
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "xh_unkwn.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xh_unkwn.h"
+#include "wx/window.h"
+#include "wx/log.h"
+#include "wx/sizer.h"
+
+
+class wxUnknownControlContainer : public wxPanel
+{
+public:
+    wxUnknownControlContainer(wxWindow *parent,
+                              const wxString& controlName,
+                              wxWindowID id = -1,
+                              const wxPoint& pos = wxDefaultPosition,
+                              const wxSize& size = wxDefaultSize)
+        : wxPanel(parent, id, pos, size, wxTAB_TRAVERSAL | wxNO_BORDER,
+                  controlName + wxT("_container")),
+          m_controlName(controlName), m_controlAdded(FALSE) 
+    {
+        m_bg = GetBackgroundColour();
+        SetBackgroundColour(wxColour(255, 0, 255));
+    }
+
+    virtual void AddChild(wxWindowBase *child);
+    
+protected:
+    wxString m_controlName;
+    bool m_controlAdded;
+    wxColour m_bg;
+};
+
+void wxUnknownControlContainer::AddChild(wxWindowBase *child)
+{
+    wxASSERT_MSG( !m_controlAdded, wxT("Couldn't add two unknown controls to the same container!") )
+
+    wxPanel::AddChild(child);
+    
+    SetBackgroundColour(m_bg);
+    child->SetName(m_controlName);
+    child->SetId(XMLID(m_controlName));
+    m_controlAdded = TRUE;
+    
+    wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
+    sizer->Add((wxWindow*)child, 1, wxEXPAND);
+    SetSizer(sizer);
+    SetAutoLayout(TRUE);
+    Layout();
+}
+
+
+
+wxUnknownWidgetXmlHandler::wxUnknownWidgetXmlHandler() 
+: wxXmlResourceHandler() 
+{
+}
+
+wxObject *wxUnknownWidgetXmlHandler::DoCreateResource()
+{ 
+    wxPanel *panel = 
+        new wxUnknownControlContainer(m_parentAsWindow,
+                                      GetName(), -1,
+                                      GetPosition(), GetSize());
+    SetupWindow(panel);
+    return panel;
+}
+
+bool wxUnknownWidgetXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return IsOfClass(node, wxT("unknown"));
+}
+
diff --git a/src/xrc/xml.cpp b/src/xrc/xml.cpp
new file mode 100644 (file)
index 0000000..d6ba14d
--- /dev/null
@@ -0,0 +1,441 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xml.cpp
+// Purpose:     wxXmlDocument - XML parser & data holder class
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "xml.h"
+#pragma implementation "xmlio.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+
+#include "wx/wfstream.h"
+#include "wx/datstrm.h"
+#include "wx/zstream.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+
+#include "wx/xrc/xml.h"
+#include "wx/xrc/xmlio.h"
+
+
+
+wxXmlNode::wxXmlNode(wxXmlNode *parent,wxXmlNodeType type,
+                     const wxString& name, const wxString& content,
+                     wxXmlProperty *props, wxXmlNode *next)
+    : m_type(type), m_name(name), m_content(content),
+      m_properties(props), m_parent(parent),
+      m_children(NULL), m_next(next)
+{
+    if (m_parent)
+    {
+        if (m_parent->m_children)
+        {
+            m_next = m_parent->m_children;
+            m_parent->m_children = this;
+        }
+        else
+            m_parent->m_children = this;
+    }
+}
+
+
+
+wxXmlNode::wxXmlNode(wxXmlNodeType type, const wxString& name,
+                     const wxString& content)
+    : m_type(type), m_name(name), m_content(content),
+      m_properties(NULL), m_parent(NULL),
+      m_children(NULL), m_next(NULL)
+{}
+
+
+
+wxXmlNode::wxXmlNode(const wxXmlNode& node)
+{
+    m_next = NULL;
+    m_parent = NULL;
+    DoCopy(node);
+}
+
+
+
+wxXmlNode& wxXmlNode::operator=(const wxXmlNode& node)
+{
+    delete m_properties;
+    delete m_children;
+    DoCopy(node);
+    return *this;
+}
+
+
+
+void wxXmlNode::DoCopy(const wxXmlNode& node)
+{
+    m_type = node.m_type;
+    m_name = node.m_name;
+    m_content = node.m_content;
+    m_children = NULL;
+
+    wxXmlNode *n = node.m_children;
+    while (n)
+    {
+        AddChild(new wxXmlNode(*n));
+        n = n->GetNext();
+    }
+
+    m_properties = NULL;
+    wxXmlProperty *p = node.m_properties;
+    while (p)
+    {
+       AddProperty(p->GetName(), p->GetValue());
+       p = p->GetNext();
+    }
+}
+
+
+bool wxXmlNode::HasProp(const wxString& propName) const
+{
+    wxXmlProperty *prop = GetProperties();
+
+    while (prop)
+    {
+        if (prop->GetName() == propName) return TRUE;
+        prop = prop->GetNext();
+    }
+
+    return FALSE;
+}
+
+
+
+bool wxXmlNode::GetPropVal(const wxString& propName, wxString *value) const
+{
+    wxXmlProperty *prop = GetProperties();
+
+    while (prop)
+    {
+        if (prop->GetName() == propName)
+        {
+            *value = prop->GetValue();
+            return TRUE;
+        }
+        prop = prop->GetNext();
+    }
+
+    return FALSE;
+}
+
+
+
+wxString wxXmlNode::GetPropVal(const wxString& propName, const wxString& defaultVal) const
+{
+    wxString tmp;
+    if (GetPropVal(propName, &tmp))
+        return tmp;
+    else
+        return defaultVal;
+}
+
+
+
+void wxXmlNode::AddChild(wxXmlNode *child)
+{
+    if (m_children == NULL)
+        m_children = child;
+    else
+    {
+        wxXmlNode *ch = m_children;
+        while (ch->m_next) ch = ch->m_next;
+        ch->m_next = child;
+    }
+    child->m_next = NULL;
+    child->m_parent = this;
+}
+
+
+
+void wxXmlNode::InsertChild(wxXmlNode *child, wxXmlNode *before_node)
+{
+    wxASSERT_MSG(before_node->GetParent() == this, wxT("wxXmlNode::InsertChild - the node has incorrect parent"));
+
+    if (m_children == before_node)
+       m_children = child;
+    else
+    {
+        wxXmlNode *ch = m_children;
+        while (ch->m_next != before_node) ch = ch->m_next;
+        ch->m_next = child;
+    }
+
+    child->m_parent = this;
+    child->m_next = before_node;
+}
+
+
+
+bool wxXmlNode::RemoveChild(wxXmlNode *child)
+{
+    if (m_children == NULL)
+        return FALSE;
+    else if (m_children == child)
+    {
+        m_children = child->m_next;
+        child->m_parent = NULL;
+        child->m_next = NULL;
+        return TRUE;
+    }
+    else
+    {
+        wxXmlNode *ch = m_children;
+        while (ch->m_next)
+        {
+            if (ch->m_next == child)
+            {
+                ch->m_next = child->m_next;
+                child->m_parent = NULL;
+                child->m_next = NULL;
+                return TRUE;
+            }
+            ch = ch->m_next;
+        }
+        return FALSE;
+    }
+}
+
+
+
+void wxXmlNode::AddProperty(const wxString& name, const wxString& value)
+{
+    AddProperty(new wxXmlProperty(name, value, NULL));
+}
+
+void wxXmlNode::AddProperty(wxXmlProperty *prop)
+{
+    if (m_properties == NULL)
+        m_properties = prop;
+    else
+    {
+        wxXmlProperty *p = m_properties;
+        while (p->GetNext()) p = p->GetNext();
+        p->SetNext(prop);
+    }
+}
+
+
+
+bool wxXmlNode::DeleteProperty(const wxString& name)
+{
+    if (m_properties == NULL)
+        return FALSE;
+
+    else if (m_properties->GetName() == name)
+    {
+        wxXmlProperty *prop = m_properties;
+        m_properties = prop->GetNext();
+        prop->SetNext(NULL);
+        delete prop;
+        return TRUE;
+    }
+
+    else
+    {
+        wxXmlProperty *p = m_properties;
+        while (p->GetNext())
+        {
+            if (p->GetNext()->GetName() == name)
+            {
+                wxXmlProperty *prop = p->GetNext();
+                p->SetNext(prop->GetNext());
+                prop->SetNext(NULL);
+                delete prop;
+                return TRUE;
+            }
+            p = p->GetNext();
+        }
+        return FALSE;
+    }
+}
+
+
+
+
+
+
+
+
+wxList *wxXmlDocument::sm_handlers = NULL;
+
+
+
+wxXmlDocument::wxXmlDocument(const wxString& filename, wxXmlIOType io_type)
+                          : wxObject(), m_root(NULL)
+{
+    if (!Load(filename, io_type))
+    {
+        delete m_root;
+        m_root = NULL;
+    }
+}
+
+
+
+wxXmlDocument::wxXmlDocument(wxInputStream& stream, wxXmlIOType io_type)
+                          : wxObject(), m_root(NULL)
+{
+    if (!Load(stream, io_type))
+    {
+        delete m_root;
+        m_root = NULL;
+    }
+}
+
+
+
+wxXmlDocument::wxXmlDocument(const wxXmlDocument& doc)
+{
+    DoCopy(doc);
+}
+
+
+
+wxXmlDocument& wxXmlDocument::operator=(const wxXmlDocument& doc)
+{
+    delete m_root;
+    DoCopy(doc);
+    return *this;
+}
+
+
+
+void wxXmlDocument::DoCopy(const wxXmlDocument& doc)
+{
+    m_version = doc.m_version;
+    m_encoding = doc.m_encoding;
+    m_root = new wxXmlNode(*doc.m_root);
+}
+
+
+
+bool wxXmlDocument::Load(const wxString& filename, wxXmlIOType io_type)
+{
+    wxFileInputStream stream(filename);
+    return Load(stream, io_type);
+}
+
+
+
+bool wxXmlDocument::Load(wxInputStream& stream, wxXmlIOType io_type)
+{
+    wxNode *n = sm_handlers->GetFirst();
+    while (n)
+    {
+        wxXmlIOHandler *h = (wxXmlIOHandler*) n->GetData();
+
+        if ((io_type == wxXML_IO_AUTO || io_type == h->GetType()) &&
+            h->CanLoad(stream))
+        {
+            return h->Load(stream, *this);
+        }
+        n = n->GetNext();
+    }
+    wxLogError(_("Cannot find XML I/O handler capable of loading this format."));
+    return FALSE;
+}
+
+
+
+bool wxXmlDocument::Save(const wxString& filename, wxXmlIOType io_type) const
+{
+    wxFileOutputStream stream(filename);
+    return Save(stream, io_type);
+}
+
+
+
+bool wxXmlDocument::Save(wxOutputStream& stream, wxXmlIOType io_type) const
+{
+    wxNode *n = sm_handlers->GetFirst();
+    while (n)
+    {
+        wxXmlIOHandler *h = (wxXmlIOHandler*) n->GetData();
+        if (io_type == h->GetType() && h->CanSave())
+        {
+            return h->Save(stream, *this);
+        }
+        n = n->GetNext();
+    }
+    wxLogError(_("Cannot find XML I/O handler capable of saving in this format."));
+    return FALSE;
+}
+
+
+
+
+
+
+void wxXmlDocument::AddHandler(wxXmlIOHandler *handler)
+{
+    if (sm_handlers == NULL)
+    {
+        sm_handlers = new wxList;
+        sm_handlers->DeleteContents(TRUE);
+    }
+    sm_handlers->Append(handler);
+}
+
+
+void wxXmlDocument::CleanUpHandlers()
+{
+    delete sm_handlers;
+    sm_handlers = NULL;
+}
+
+
+void wxXmlDocument::InitStandardHandlers()
+{
+    AddHandler(new wxXmlIOHandlerBin);
+#if wxUSE_ZLIB
+    AddHandler(new wxXmlIOHandlerBinZ);
+#endif
+    AddHandler(new wxXmlIOHandlerExpat);
+    AddHandler(new wxXmlIOHandlerWriter);
+}
+
+
+#include "wx/module.h"
+
+class wxXmlModule: public wxModule
+{
+    DECLARE_DYNAMIC_CLASS(wxXmlModule)
+    public:
+        wxXmlModule() {}
+        bool OnInit() { wxXmlDocument::InitStandardHandlers(); return TRUE; };
+        void OnExit() { wxXmlDocument::CleanUpHandlers(); };
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxXmlModule, wxModule)
+
+
+
+
+// When wxXml is loaded dynamically after the application is already running
+// then the built-in module system won't pick this one up.  Add it manually.
+void wxXmlInitXmlModule()
+{
+    wxModule* module = new wxXmlModule;
+    module->Init();
+    wxModule::RegisterModule(module);
+}
+
diff --git a/src/xrc/xmlbin.cpp b/src/xrc/xmlbin.cpp
new file mode 100644 (file)
index 0000000..bbd98f7
--- /dev/null
@@ -0,0 +1,161 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xmlbin.cpp
+// Purpose:     wxXmlIOHandlerBin 
+// Author:      Vaclav Slavik
+// Created:     2000/07/24
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+// nothing, already in xml.cpp
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/datstrm.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+
+#include "wx/xrc/xmlio.h"
+
+
+
+
+bool wxXmlIOHandlerBin::CanLoad(wxInputStream& stream)
+{
+    bool canread;
+    canread = (ReadHeader(stream) == wxT("XMLBIN "));
+    stream.SeekI(-9, wxFromCurrent);
+    return canread;
+}
+
+
+
+wxString wxXmlIOHandlerBin::ReadHeader(wxInputStream& stream)
+{
+    wxUint8 version;
+    char cheader[8];
+
+    stream.Read(cheader, 8);
+    cheader[7] = 0;
+    stream.Read(&version, 1);
+    
+    if (version != 1) return wxEmptyString;
+    else return wxString(cheader);
+}
+
+
+
+void wxXmlIOHandlerBin::WriteHeader(wxOutputStream& stream, const wxString& header)
+{
+    char cheader[8];
+    size_t i;
+    wxUint8 version = 1;
+    
+    for (i = 0; i < header.Length(); i++) cheader[i] = header[i];
+    for (; i < 7; i++) cheader[i] = ' ';
+    cheader[7] = 0;
+    stream.Write(cheader, 8);
+    stream.Write(&version, 1);
+}
+
+
+
+static bool SaveBinNode(wxDataOutputStream& ds, wxXmlNode *node)
+{
+    if (node)
+    {
+        ds << (wxUint8)1 <<
+              (wxUint8)node->GetType() << 
+              node->GetName() << node->GetContent();
+        
+        wxXmlProperty *prop = node->GetProperties();
+        while (prop)
+        {
+            ds << (wxUint8)1;
+            ds << prop->GetName() << prop->GetValue();
+            prop = prop->GetNext();
+            
+        }
+        ds << (wxUint8)0;
+        
+        SaveBinNode(ds, node->GetNext());
+        SaveBinNode(ds, node->GetChildren());
+    }  
+    else
+        ds << (wxUint8)0;
+    
+    return TRUE;
+}
+
+
+
+bool wxXmlIOHandlerBin::Save(wxOutputStream& stream, const wxXmlDocument& doc)
+{
+    WriteHeader(stream, "XMLBIN ");
+    wxDataOutputStream ds(stream);
+    ds << doc.GetVersion() << doc.GetEncoding();
+    SaveBinNode(ds, doc.GetRoot());
+    return stream.LastError() == wxSTREAM_NOERROR;
+}
+
+
+
+static wxXmlProperty *LoadBinProp(wxDataInputStream& ds)
+{
+    wxUint8 dummy;
+    ds >> dummy;
+    if (dummy == 0) return NULL;
+
+    wxString name, value;
+    ds >> name >> value;
+    return new wxXmlProperty(name, value, LoadBinProp(ds));
+}
+
+
+
+
+static wxXmlNode *LoadBinNode(wxDataInputStream& ds, wxXmlNode *parent)
+{
+    wxUint8 type;
+    wxString name, content;
+    wxUint8 dummy;
+
+    ds >> dummy;
+    if (dummy == 0) return NULL;
+    ds >> type >> name >> content;
+    
+    wxXmlProperty *prop = LoadBinProp(ds);
+
+    wxXmlNode *nd = new wxXmlNode(parent, (wxXmlNodeType)type, name, content, 
+                                  prop, LoadBinNode(ds, parent));
+    LoadBinNode(ds, nd);
+    return nd;
+}
+
+
+
+bool wxXmlIOHandlerBin::Load(wxInputStream& stream, wxXmlDocument& doc)
+{
+    ReadHeader(stream);
+    wxDataInputStream ds(stream);
+    wxString tmp;
+
+    ds >> tmp;
+    doc.SetVersion(tmp);
+    ds >> tmp;
+    doc.SetEncoding(tmp);
+
+    doc.SetRoot(LoadBinNode(ds, NULL));
+        
+    return (doc.GetRoot() != NULL);
+}
+
+
diff --git a/src/xrc/xmlbinz.cpp b/src/xrc/xmlbinz.cpp
new file mode 100644 (file)
index 0000000..876ae33
--- /dev/null
@@ -0,0 +1,59 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xmlbinz.cpp
+// Purpose:     wxXmlIOHandlerBinZ
+// Author:      Vaclav Slavik
+// Created:     2000/07/24
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+// nothing, already in xml.cpp
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/datstrm.h"
+#include "wx/log.h"
+#include "wx/zstream.h"
+
+#include "wx/xrc/xmlio.h"
+
+#if wxUSE_ZLIB
+
+
+
+bool wxXmlIOHandlerBinZ::CanLoad(wxInputStream& stream)
+{
+    bool canread;
+    canread = (ReadHeader(stream) == wxT("XMLBINZ"));
+    stream.SeekI(-9, wxFromCurrent);
+    return canread;
+}
+
+
+
+bool wxXmlIOHandlerBinZ::Save(wxOutputStream& stream, const wxXmlDocument& doc)
+{
+    WriteHeader(stream, "XMLBINZ");
+    wxZlibOutputStream costr(stream, 9);
+    return wxXmlIOHandlerBin::Save(costr, doc);
+}
+
+
+
+bool wxXmlIOHandlerBinZ::Load(wxInputStream& stream, wxXmlDocument& doc)
+{
+    ReadHeader(stream);
+    wxZlibInputStream costr(stream);
+    return wxXmlIOHandlerBin::Load(costr, doc);
+}
+
+
+#endif
diff --git a/src/xrc/xmlexpat.cpp b/src/xrc/xmlexpat.cpp
new file mode 100644 (file)
index 0000000..c7894b4
--- /dev/null
@@ -0,0 +1,198 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xmlexpat.cpp
+// Purpose:     wxXmlDocument - XML reader via Expat
+// Author:      Vaclav Slavik
+// Created:     2001/04/30
+// RCS-ID:      $Id$
+// Copyright:   (c) 2001 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+// nothing - already in xml.cpp
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/wfstream.h"
+#include "wx/intl.h"
+#include "wx/log.h"
+#include "wx/strconv.h"
+#include "wx/xrc/xmlio.h"
+
+#include "xmlparse.h"
+
+/*
+
+    FIXME:
+
+     - handle unknown encodings
+     - process all elements, including CDATA
+     - XML resources should automatically select desired encoding besed on
+       runtime environment (?) (would need BIN and BINZ formats modification,
+       too)
+
+ */
+
+
+// converts Expat-produced string in UTF-8 into wxString.
+inline static wxString CharToString(const char *s, size_t len = wxSTRING_MAXLEN)
+{
+#if wxUSE_UNICODE
+    return wxString(s, wxMBConvUTF8, len);
+#else
+    return wxString(s, len);
+#endif
+}
+
+bool wxXmlIOHandlerExpat::CanLoad(wxInputStream& stream)
+{
+    char cheader[7];
+    cheader[6] = 0;
+    stream.Read(cheader, 6);
+    stream.SeekI(-6, wxFromCurrent);
+    return (strcmp(cheader, "<?xml ") == 0);
+}
+
+
+struct wxXmlParsingContext
+{
+    wxXmlNode *root;
+    wxXmlNode *node;
+    wxXmlNode *lastAsText;
+    wxString encoding;
+    wxString version;
+};
+
+static void StartElementHnd(void *userData, const char *name, const char **atts)
+{
+    wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
+    wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, CharToString(name));
+    const char **a = atts;
+    while (*a)
+    {
+        node->AddProperty(CharToString(a[0]), CharToString(a[1]));
+        a += 2;
+    }
+    if (ctx->root == NULL)
+        ctx->root = node;
+    else
+        ctx->node->AddChild(node);
+    ctx->node = node;
+    ctx->lastAsText = NULL;
+}
+
+static void EndElementHnd(void *userData, const char* WXUNUSED(name))
+{
+    wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
+
+    ctx->node = ctx->node->GetParent();
+    ctx->lastAsText = NULL;
+}
+
+static void TextHnd(void *userData, const char *s, int len)
+{
+    wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
+    char *buf = new char[len + 1];
+
+    buf[len] = '\0';
+    memcpy(buf, s, (size_t)len);
+
+    if (ctx->lastAsText)
+    {
+        ctx->lastAsText->SetContent(ctx->lastAsText->GetContent() +
+                                    CharToString(buf));
+    }
+    else
+    {
+        bool whiteOnly = TRUE;
+        for (char *c = buf; *c != '\0'; c++)
+            if (*c != ' ' && *c != '\t' && *c != '\n' && *c != '\r')
+            {
+                whiteOnly = FALSE;
+                break;
+            }
+        if (!whiteOnly)
+        {
+            ctx->lastAsText = new wxXmlNode(wxXML_TEXT_NODE, wxT("text"),
+                                            CharToString(buf));
+            ctx->node->AddChild(ctx->lastAsText);
+        }
+    }
+
+    delete[] buf;
+}
+
+static void CommentHnd(void *userData, const char *data)
+{
+    wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
+
+    if (ctx->node)
+    {
+        // VS: ctx->node == NULL happens if there is a comment before
+        //     the root element (e.g. wxDesigner's output). We ignore such
+        //     comments, no big deal...
+        ctx->node->AddChild(new wxXmlNode(wxXML_COMMENT_NODE,
+                            wxT("comment"), CharToString(data)));
+    }
+    ctx->lastAsText = NULL;
+}
+
+static void DefaultHnd(void *userData, const char *s, int len)
+{
+    // XML header:
+    if (len > 6 && memcmp(s, "<?xml ", 6) == 0)
+    {
+        wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData;
+
+        wxString buf = CharToString(s, (size_t)len);
+        int pos;
+        pos = buf.Find(wxT("encoding="));
+        if (pos != wxNOT_FOUND)
+            ctx->encoding = buf.Mid(pos + 10).BeforeFirst(buf[(size_t)pos+9]);
+        pos = buf.Find(wxT("version="));
+        if (pos != wxNOT_FOUND)
+            ctx->version = buf.Mid(pos + 9).BeforeFirst(buf[(size_t)pos+8]);
+    }
+}
+
+bool wxXmlIOHandlerExpat::Load(wxInputStream& stream, wxXmlDocument& doc)
+{
+    const size_t BUFSIZE = 1024;
+    char buf[BUFSIZE];
+    wxXmlParsingContext ctx;
+    bool done;
+    XML_Parser parser = XML_ParserCreate(NULL);
+
+    ctx.root = ctx.node = NULL;
+    XML_SetUserData(parser, (void*)&ctx);
+    XML_SetElementHandler(parser, StartElementHnd, EndElementHnd);
+    XML_SetCharacterDataHandler(parser, TextHnd);
+    XML_SetCommentHandler(parser, CommentHnd);
+    XML_SetDefaultHandler(parser, DefaultHnd);
+
+    do
+    {
+        size_t len = stream.Read(buf, BUFSIZE).LastRead();
+        done = (len < BUFSIZE);
+        if (!XML_Parse(parser, buf, len, done))
+        {
+            wxLogError(_("XML parsing error: '%s' at line %d"),
+                       XML_ErrorString(XML_GetErrorCode(parser)),
+                       XML_GetCurrentLineNumber(parser));
+          return FALSE;
+        }
+    } while (!done);
+
+    doc.SetVersion(ctx.version);
+    doc.SetEncoding(ctx.encoding);
+    doc.SetRoot(ctx.root);
+
+    XML_ParserFree(parser);
+    return TRUE;
+}
diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp
new file mode 100644 (file)
index 0000000..6e59b5a
--- /dev/null
@@ -0,0 +1,1001 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xmlres.cpp
+// Purpose:     XML resources
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "xmlres.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/dialog.h"
+#include "wx/panel.h"
+#include "wx/frame.h"
+#include "wx/wfstream.h"
+#include "wx/filesys.h"
+#include "wx/log.h"
+#include "wx/intl.h"
+#include "wx/tokenzr.h"
+#include "wx/fontenum.h"
+#include "wx/module.h"
+#include "wx/bitmap.h"
+#include "wx/image.h"
+#include "wx/fontmap.h"
+
+#include "wx/xrc/xml.h"
+#include "wx/xrc/xmlres.h"
+
+#include "wx/arrimpl.cpp"
+WX_DEFINE_OBJARRAY(wxXmlResourceDataRecords);
+
+
+wxXmlResource::wxXmlResource(bool use_locale)
+{
+    m_handlers.DeleteContents(TRUE);
+    m_useLocale = use_locale;
+    m_version = -1;
+}
+
+wxXmlResource::wxXmlResource(const wxString& filemask, bool use_locale)
+{
+    m_useLocale = use_locale;
+    m_version = -1;
+    m_handlers.DeleteContents(TRUE);
+    Load(filemask);
+}
+
+wxXmlResource::~wxXmlResource()
+{
+    ClearHandlers();
+}
+
+
+bool wxXmlResource::Load(const wxString& filemask)
+{
+    wxString fnd;
+    wxXmlResourceDataRecord *drec;
+    bool iswild = wxIsWild(filemask);
+    bool rt = TRUE;
+
+#if wxUSE_FILESYSTEM
+    wxFileSystem fsys;
+#   define wxXmlFindFirst  fsys.FindFirst(filemask, wxFILE)
+#   define wxXmlFindNext   fsys.FindNext()
+#else
+#   define wxXmlFindFirst  wxFindFirstFile(filemask, wxFILE)
+#   define wxXmlFindNext   wxFindNextFile()
+#endif
+    if (iswild)
+        fnd = wxXmlFindFirst;
+    else
+        fnd = filemask;
+    while (!!fnd)
+    {
+#if wxUSE_FILESYSTEM
+        if (filemask.Lower().Matches("*.zip") ||
+            filemask.Lower().Matches("*.rsc"))
+        {
+            rt = rt && Load(fnd + wxT("#zip:*.xmb"));
+            rt = rt && Load(fnd + wxT("#zip:*.xrc"));
+        }
+        else
+#endif
+        {
+            drec = new wxXmlResourceDataRecord;
+            drec->File = fnd;
+            m_data.Add(drec);
+        }
+
+        if (iswild)
+            fnd = wxXmlFindNext;
+        else
+            fnd = wxEmptyString;
+    }
+#   undef wxXmlFindFirst
+#   undef wxXmlFindNext
+    return rt;
+}
+
+
+
+void wxXmlResource::AddHandler(wxXmlResourceHandler *handler)
+{
+    m_handlers.Append(handler);
+    handler->SetParentResource(this);
+}
+
+
+
+void wxXmlResource::ClearHandlers()
+{
+    m_handlers.Clear();
+}
+
+
+
+wxMenu *wxXmlResource::LoadMenu(const wxString& name)
+{
+    return (wxMenu*)CreateResFromNode(FindResource(name, wxT("wxMenu")), NULL, NULL);
+}
+
+
+
+wxMenuBar *wxXmlResource::LoadMenuBar(const wxString& name)
+{
+    return (wxMenuBar*)CreateResFromNode(FindResource(name, wxT("wxMenuBar")), NULL, NULL);
+}
+
+
+
+wxToolBar *wxXmlResource::LoadToolBar(wxWindow *parent, const wxString& name)
+{
+    return (wxToolBar*)CreateResFromNode(FindResource(name, wxT("wxToolBar")), parent, NULL);
+}
+
+
+
+wxDialog *wxXmlResource::LoadDialog(wxWindow *parent, const wxString& name)
+{
+    wxDialog *dialog = new wxDialog;
+    if (!LoadDialog(dialog, parent, name))
+        { delete dialog; return NULL; }
+    else return dialog;
+}
+
+bool wxXmlResource::LoadDialog(wxDialog *dlg, wxWindow *parent, const wxString& name)
+{
+    return CreateResFromNode(FindResource(name, wxT("wxDialog")), parent, dlg) != NULL;
+}
+
+
+
+wxPanel *wxXmlResource::LoadPanel(wxWindow *parent, const wxString& name)
+{
+    return (wxPanel*)CreateResFromNode(FindResource(name, wxT("wxPanel")), parent, NULL);
+}
+
+bool wxXmlResource::LoadPanel(wxPanel *panel, wxWindow *parent, const wxString& name)
+{
+    return CreateResFromNode(FindResource(name, wxT("wxPanel")), parent, panel) != NULL;
+}
+
+bool wxXmlResource::LoadFrame(wxFrame* frame, wxWindow *parent, const wxString& name)
+{
+    return CreateResFromNode(FindResource(name, wxT("wxFrame")), parent, frame) != NULL;
+}
+
+wxBitmap wxXmlResource::LoadBitmap(const wxString& name)
+{
+    wxBitmap *bmp = (wxBitmap*)CreateResFromNode(
+                               FindResource(name, wxT("wxBitmap")), NULL, NULL);
+    wxBitmap rt;
+
+    if (bmp) { rt = *bmp; delete bmp; }
+    return rt;
+}
+
+wxIcon wxXmlResource::LoadIcon(const wxString& name)
+{
+    wxIcon *icon = (wxIcon*)CreateResFromNode(
+                            FindResource(name, wxT("wxIcon")), NULL, NULL);
+    wxIcon rt;
+
+    if (icon) { rt = *icon; delete icon; }
+    return rt;
+}
+
+bool wxXmlResource::AttachUnknownControl(const wxString& name,
+                                         wxWindow *control, wxWindow *parent)
+{
+    if (parent == NULL)
+        parent = control->GetParent();
+    wxWindow *container = parent->FindWindow(name + wxT("_container"));
+    if (!container)
+    {
+        wxLogError(_("Cannot find container for unknown control '%s'."), name.c_str());
+        return FALSE;
+    }
+    return control->Reparent(container);
+}
+
+
+void wxXmlResource::ProcessPlatformProperty(wxXmlNode *node)
+{
+    wxString s;
+    bool isok;
+
+    wxXmlNode *c = node->GetChildren();
+    while (c)
+    {
+        isok = FALSE;
+        if (!c->GetPropVal(wxT("platform"), &s))
+            isok = TRUE;
+        else
+        {
+            wxStringTokenizer tkn(s, " |");
+
+            while (tkn.HasMoreTokens())
+            {
+                s = tkn.GetNextToken();
+                if (
+#ifdef __WXMSW__
+                    s == wxString(wxT("win"))
+#elif defined(__UNIX__)
+                    s == wxString(wxT("unix"))
+#elif defined(__MAC__)
+                    s == wxString(wxT("mac"))
+#elif defined(__OS2__)
+                    s == wxString(wxT("os2"))
+#else
+                    FALSE
+#endif
+              ) isok = TRUE;
+            }
+        }
+
+        if (isok)
+            ProcessPlatformProperty(c);
+        else
+        {
+            node->RemoveChild(c);
+            delete c;
+        }
+
+        c = c->GetNext();
+    }
+}
+
+
+
+void wxXmlResource::UpdateResources()
+{
+    bool modif;
+#   if wxUSE_FILESYSTEM
+    wxFSFile *file = NULL;
+    wxFileSystem fsys;
+#   endif
+
+    for (size_t i = 0; i < m_data.GetCount(); i++)
+    {
+        modif = (m_data[i].Doc == NULL);
+
+        if (!modif)
+        {
+#           if wxUSE_FILESYSTEM
+            file = fsys.OpenFile(m_data[i].File);
+            modif = file && file->GetModificationTime() > m_data[i].Time;
+            if (!file)
+                wxLogError(_("Cannot open file '%s'."), m_data[i].File.c_str());
+            wxDELETE(file);
+#           else
+            modif = wxDateTime(wxFileModificationTime(m_data[i].File)) > m_data[i].Time;
+#           endif
+        }
+
+        if (modif)
+        {
+                       wxInputStream *stream = NULL;
+
+#           if wxUSE_FILESYSTEM
+            file = fsys.OpenFile(m_data[i].File);
+                       if (file)
+                               stream = file->GetStream();
+#           else
+            stream = new wxFileInputStream(m_data[i].File);
+#           endif
+
+            if (stream)
+            {
+                delete m_data[i].Doc;
+                m_data[i].Doc = new wxXmlDocument;
+            }
+            if (!stream || !m_data[i].Doc->Load(*stream))
+            {
+                wxLogError(_("Cannot load resources from file '%s'."), m_data[i].File.c_str());
+                wxDELETE(m_data[i].Doc);
+            }
+            else if (m_data[i].Doc->GetRoot()->GetName() != wxT("resource"))
+            {
+                wxLogError(_("Invalid XML resource '%s': doesn't have root node 'resource'."), m_data[i].File.c_str());
+                wxDELETE(m_data[i].Doc);
+            }
+            else
+                       {
+                long version;
+                int v1, v2, v3, v4;
+                wxString verstr = m_data[i].Doc->GetRoot()->GetPropVal(
+                                      wxT("version"), wxT("0.0.0.0"));
+                if (wxSscanf(verstr.c_str(), wxT("%i.%i.%i.%i"),
+                    &v1, &v2, &v3, &v4) == 4)
+                    version = v1*256*256*256+v2*256*256+v3*256+v4;
+                else
+                    version = 0;
+                if (m_version == -1)
+                    m_version = version;
+                if (m_version != version)
+                    wxLogError(_("Resource files must have same version number!"));
+
+                ProcessPlatformProperty(m_data[i].Doc->GetRoot());
+                               m_data[i].Time = file->GetModificationTime();
+                       }
+
+#           if wxUSE_FILESYSTEM
+                               wxDELETE(file);
+#           else
+                               wxDELETE(stream);
+#           endif
+        }
+    }
+}
+
+
+
+wxXmlNode *wxXmlResource::FindResource(const wxString& name, const wxString& classname)
+{
+    UpdateResources(); //ensure everything is up-to-date
+
+    wxString dummy;
+    for (size_t f = 0; f < m_data.GetCount(); f++)
+    {
+        if (m_data[f].Doc == NULL || m_data[f].Doc->GetRoot() == NULL) continue;
+        for (wxXmlNode *node = m_data[f].Doc->GetRoot()->GetChildren();
+                                      node; node = node->GetNext())
+            if (node->GetType() == wxXML_ELEMENT_NODE &&
+                (!classname ||
+                  node->GetPropVal(wxT("class"), wxEmptyString) == classname) &&
+                node->GetName() == wxT("object") &&
+                node->GetPropVal(wxT("name"), &dummy) &&
+                dummy == name)
+            {
+#if wxUSE_FILESYSTEM
+                m_curFileSystem.ChangePathTo(m_data[f].File);
+#endif
+                return node;
+            }
+    }
+
+    wxLogError(_("XML resource '%s' (class '%s') not found!"),
+               name.c_str(), classname.c_str());
+    return NULL;
+}
+
+
+
+wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wxObject *instance)
+{
+    if (node == NULL) return NULL;
+
+    wxXmlResourceHandler *handler;
+    wxObject *ret;
+    wxNode * ND = m_handlers.GetFirst();
+    while (ND)
+    {
+        handler = (wxXmlResourceHandler*)ND->GetData();
+        if (node->GetName() == wxT("object") && handler->CanHandle(node))
+        {
+            ret = handler->CreateResource(node, parent, instance);
+            if (ret) return ret;
+        }
+        ND = ND->GetNext();
+    }
+
+    wxLogError(_("No handler found for XML node '%s', class '%s'!"),
+               node->GetName().c_str(),
+               node->GetPropVal(wxT("class"), wxEmptyString).c_str());
+    return NULL;
+}
+
+
+
+
+
+
+
+
+
+wxXmlResourceHandler::wxXmlResourceHandler()
+        : m_node(NULL), m_parent(NULL), m_instance(NULL),
+          m_parentAsWindow(NULL), m_instanceAsWindow(NULL)
+{}
+
+
+
+wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent, wxObject *instance)
+{
+    wxXmlNode *myNode = m_node;
+    wxString myClass = m_class;
+    wxObject *myParent = m_parent, *myInstance = m_instance;
+    wxWindow *myParentAW = m_parentAsWindow, *myInstanceAW = m_instanceAsWindow;
+
+    m_node = node;
+    m_class = node->GetPropVal(wxT("class"), wxEmptyString);
+    m_parent = parent;
+    m_instance = instance;
+    m_parentAsWindow = wxDynamicCast(m_parent, wxWindow);
+    m_instanceAsWindow = wxDynamicCast(m_instance, wxWindow);
+
+    wxObject *returned = DoCreateResource();
+
+    m_node = myNode;
+    m_class = myClass;
+    m_parent = myParent; m_parentAsWindow = myParentAW;
+    m_instance = myInstance; m_instanceAsWindow = myInstanceAW;
+
+    return returned;
+}
+
+
+void wxXmlResourceHandler::AddStyle(const wxString& name, int value)
+{
+    m_styleNames.Add(name);
+    m_styleValues.Add(value);
+}
+
+
+
+void wxXmlResourceHandler::AddWindowStyles()
+{
+    ADD_STYLE(wxSIMPLE_BORDER);
+    ADD_STYLE(wxSUNKEN_BORDER);
+    ADD_STYLE(wxDOUBLE_BORDER);
+    ADD_STYLE(wxRAISED_BORDER);
+    ADD_STYLE(wxSTATIC_BORDER);
+    ADD_STYLE(wxNO_BORDER);
+    ADD_STYLE(wxTRANSPARENT_WINDOW);
+    ADD_STYLE(wxWANTS_CHARS);
+    ADD_STYLE(wxNO_FULL_REPAINT_ON_RESIZE);
+}
+
+
+
+bool wxXmlResourceHandler::HasParam(const wxString& param)
+{
+    return (GetParamNode(param) != NULL);
+}
+
+
+int wxXmlResourceHandler::GetStyle(const wxString& param, int defaults)
+{
+    wxString s = GetParamValue(param);
+
+    if (!s) return defaults;
+
+    wxStringTokenizer tkn(s, wxT("| "), wxTOKEN_STRTOK);
+    int style = 0;
+    int index;
+    wxString fl;
+    while (tkn.HasMoreTokens())
+    {
+        fl = tkn.GetNextToken();
+        index = m_styleNames.Index(fl);
+        if (index != wxNOT_FOUND)
+            style |= m_styleValues[index];
+        else
+            wxLogError(_("Unknown style flag ") + fl);
+    }
+    return style;
+}
+
+
+
+wxString wxXmlResourceHandler::GetText(const wxString& param)
+{
+    wxString str1 = GetParamValue(param);
+    wxString str2;
+    const wxChar *dt;
+    wxChar amp_char;
+
+    // VS: First version of XML resources used $ instead of & (which is illegal in XML),
+    //     but later I realized that '_' fits this purpose much better (because
+    //     &File means "File with F underlined").
+    if (m_resource->CompareVersion(2,3,0,1) < 0)
+        amp_char = wxT('$');
+    else
+        amp_char = wxT('_');
+
+    for (dt = str1.c_str(); *dt; dt++)
+    {
+        // Remap amp_char to &, map double amp_char to amp_char (for things
+        // like "&File..." -- this is illegal in XML, so we use "_File..."):
+        if (*dt == amp_char)
+        {
+            if ( *(++dt) == amp_char )
+                str2 << amp_char;
+            else
+                str2 << wxT('&') << *dt;
+        }
+        // Remap \n to CR, \r to LF, \t to TAB:
+        else if (*dt == wxT('\\'))
+            switch (*(++dt))
+            {
+                case wxT('n') : str2 << wxT('\n'); break;
+                case wxT('t') : str2 << wxT('\t'); break;
+                case wxT('r') : str2 << wxT('\r'); break;
+                default       : str2 << wxT('\\') << *dt; break;
+            }
+        else str2 << *dt;
+    }
+
+    if (m_resource->GetUseLocale())
+        return wxGetTranslation(str2);
+    else
+        return str2;
+}
+
+
+
+long wxXmlResourceHandler::GetLong(const wxString& param, long defaultv)
+{
+    long value;
+    wxString str1 = GetParamValue(param);
+
+    if (!str1.ToLong(&value))
+        value = defaultv;
+
+    return value;
+}
+
+
+int wxXmlResourceHandler::GetID()
+{
+    wxString sid = GetName();
+    long num;
+
+    if (sid == wxT("-1")) return -1;
+    else if (sid.IsNumber() && sid.ToLong(&num)) return num;
+#define stdID(id) else if (sid == wxT(#id)) return id
+    stdID(wxID_OPEN); stdID(wxID_CLOSE); stdID(wxID_NEW);
+    stdID(wxID_SAVE); stdID(wxID_SAVEAS); stdID(wxID_REVERT);
+    stdID(wxID_EXIT); stdID(wxID_UNDO); stdID(wxID_REDO);
+    stdID(wxID_HELP); stdID(wxID_PRINT); stdID(wxID_PRINT_SETUP);
+    stdID(wxID_PREVIEW); stdID(wxID_ABOUT); stdID(wxID_HELP_CONTENTS);
+    stdID(wxID_HELP_COMMANDS); stdID(wxID_HELP_PROCEDURES);
+    stdID(wxID_CUT); stdID(wxID_COPY); stdID(wxID_PASTE);
+    stdID(wxID_CLEAR); stdID(wxID_FIND); stdID(wxID_DUPLICATE);
+    stdID(wxID_SELECTALL); stdID(wxID_OK); stdID(wxID_CANCEL);
+    stdID(wxID_APPLY); stdID(wxID_YES); stdID(wxID_NO);
+    stdID(wxID_STATIC); stdID(wxID_FORWARD); stdID(wxID_BACKWARD);
+    stdID(wxID_DEFAULT); stdID(wxID_MORE); stdID(wxID_SETUP);
+    stdID(wxID_RESET); stdID(wxID_HELP_CONTEXT);
+#undef stdID
+    else return XMLID(sid.c_str());
+}
+
+
+wxString wxXmlResourceHandler::GetName()
+{
+    return m_node->GetPropVal(wxT("name"), wxT("-1"));
+}
+
+
+
+bool wxXmlResourceHandler::GetBool(const wxString& param, bool defaultv)
+{
+    wxString v = GetParamValue(param);
+    v.MakeLower();
+    if (!v) return defaultv;
+    else return (v == wxT("1"));
+}
+
+
+
+wxColour wxXmlResourceHandler::GetColour(const wxString& param)
+{
+    wxString v = GetParamValue(param);
+    unsigned long tmp = 0;
+
+    if (v.Length() != 7 || v[0u] != wxT('#') ||
+        wxSscanf(v.c_str(), wxT("#%lX"), &tmp) != 1)
+    {
+        wxLogError(_("XML resource: Incorrect colour specification '%s' for property '%s'."),
+                   v.c_str(), param.c_str());
+        return wxNullColour;
+    }
+
+    return wxColour((unsigned char) ((tmp & 0xFF0000) >> 16) ,
+                    (unsigned char) ((tmp & 0x00FF00) >> 8),
+                    (unsigned char) ((tmp & 0x0000FF)));
+}
+
+
+
+wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, wxSize size)
+{
+    wxString name = GetParamValue(param);
+    if (name.IsEmpty()) return wxNullBitmap;
+#if wxUSE_FILESYSTEM
+    wxFSFile *fsfile = GetCurFileSystem().OpenFile(name);
+    if (fsfile == NULL)
+    {
+        wxLogError(_("XML resource: Cannot create bitmap from '%s'."), param.mb_str());
+        return wxNullBitmap;
+    }
+    wxImage img(*(fsfile->GetStream()));
+    delete fsfile;
+#else
+    wxImage img(GetParamValue(wxT("bitmap")));
+#endif
+    if (!img.Ok())
+    {
+        wxLogError(_("XML resource: Cannot create bitmap from '%s'."), param.mb_str());
+        return wxNullBitmap;
+    }
+    if (!(size == wxDefaultSize)) img.Rescale(size.x, size.y);
+    return img.ConvertToBitmap();
+}
+
+
+
+wxIcon wxXmlResourceHandler::GetIcon(const wxString& param, wxSize size)
+{
+#if wxCHECK_VERSION(2,3,0) || defined(__WXMSW__)
+    wxIcon icon;
+    icon.CopyFromBitmap(GetBitmap(param, size));
+#else
+    wxIcon *iconpt;
+    wxBitmap bmppt = GetBitmap(param, size);
+    iconpt = (wxIcon*)(&bmppt);
+    wxIcon icon(*iconpt);
+#endif
+    return icon;
+}
+
+
+
+wxXmlNode *wxXmlResourceHandler::GetParamNode(const wxString& param)
+{
+    wxXmlNode *n = m_node->GetChildren();
+
+    while (n)
+    {
+        if (n->GetType() == wxXML_ELEMENT_NODE && n->GetName() == param)
+            return n;
+        n = n->GetNext();
+    }
+    return NULL;
+}
+
+
+wxString wxXmlResourceHandler::GetNodeContent(wxXmlNode *node)
+{
+    wxXmlNode *n = node;
+    if (n == NULL) return wxEmptyString;
+    n = n->GetChildren();
+
+    while (n)
+    {
+        if (n->GetType() == wxXML_TEXT_NODE ||
+            n->GetType() == wxXML_CDATA_SECTION_NODE)
+            return n->GetContent();
+        n = n->GetNext();
+    }
+    return wxEmptyString;
+}
+
+
+
+wxString wxXmlResourceHandler::GetParamValue(const wxString& param)
+{
+    if (param.IsEmpty())
+        return GetNodeContent(m_node);
+    else
+        return GetNodeContent(GetParamNode(param));
+}
+
+
+
+wxSize wxXmlResourceHandler::GetSize(const wxString& param)
+{
+    wxString s = GetParamValue(param);
+    if (s.IsEmpty()) s = wxT("-1,-1");
+    bool is_dlg;
+    long sx, sy;
+
+    is_dlg = s[s.Length()-1] == wxT('d');
+    if (is_dlg) s.RemoveLast();
+
+    if (!s.BeforeFirst(wxT(',')).ToLong(&sx) ||
+        !s.AfterLast(wxT(',')).ToLong(&sy))
+    {
+        wxLogError(_("Cannot parse coordinates from '%s'."), s.mb_str());
+        return wxDefaultSize;
+    }
+
+    if (is_dlg)
+    {
+        if (m_instanceAsWindow)
+            return wxDLG_UNIT(m_instanceAsWindow, wxSize(sx, sy));
+        else if (m_parentAsWindow)
+            return wxDLG_UNIT(m_parentAsWindow, wxSize(sx, sy));
+        else
+        {
+            wxLogError(_("Cannot convert dialog units: dialog unknown."));
+            return wxDefaultSize;
+        }
+    }
+    else return wxSize(sx, sy);
+}
+
+
+
+wxPoint wxXmlResourceHandler::GetPosition(const wxString& param)
+{
+    wxSize sz = GetSize(param);
+    return wxPoint(sz.x, sz.y);
+}
+
+
+
+wxCoord wxXmlResourceHandler::GetDimension(const wxString& param, wxCoord defaultv)
+{
+    wxString s = GetParamValue(param);
+    if (s.IsEmpty()) return defaultv;
+    bool is_dlg;
+    long sx;
+
+    is_dlg = s[s.Length()-1] == wxT('d');
+    if (is_dlg) s.RemoveLast();
+
+    if (!s.ToLong(&sx))
+    {
+        wxLogError(_("Cannot parse dimension from '%s'."), s.mb_str());
+        return defaultv;
+    }
+
+    if (is_dlg)
+    {
+        if (m_instanceAsWindow)
+            return wxDLG_UNIT(m_instanceAsWindow, wxSize(sx, 0)).x;
+        else if (m_parentAsWindow)
+            return wxDLG_UNIT(m_parentAsWindow, wxSize(sx, 0)).x;
+        else
+        {
+            wxLogError(_("Cannot convert dialog units: dialog unknown."));
+            return defaultv;
+        }
+    }
+    else return sx;
+}
+
+
+
+wxFont wxXmlResourceHandler::GetFont(const wxString& param)
+{
+    wxXmlNode *font_node = GetParamNode(param);
+    if (font_node == NULL)
+    {
+        wxLogError(_("Cannot find font node '%s'."), param.mb_str());
+        return wxNullFont;
+    }
+
+    wxXmlNode *oldnode = m_node;
+    m_node = font_node;
+
+    long size = GetLong(wxT("size"), 12);
+
+    wxString style = GetParamValue(wxT("style"));
+    wxString weight = GetParamValue(wxT("weight"));
+    int istyle = wxNORMAL, iweight = wxNORMAL;
+    if (style == wxT("italic")) istyle = wxITALIC;
+    else if (style == wxT("slant")) istyle = wxSLANT;
+    if (weight == wxT("bold")) iweight = wxBOLD;
+    else if (weight == wxT("light")) iweight = wxLIGHT;
+
+    wxString family = GetParamValue(wxT("family"));
+    int ifamily = wxDEFAULT;
+         if (family == wxT("decorative")) ifamily = wxDECORATIVE;
+    else if (family == wxT("roman")) ifamily = wxROMAN;
+    else if (family == wxT("script")) ifamily = wxSCRIPT;
+    else if (family == wxT("swiss")) ifamily = wxSWISS;
+    else if (family == wxT("modern")) ifamily = wxMODERN;
+
+    bool underlined = GetBool(wxT("underlined"), FALSE);
+
+    wxString encoding = GetParamValue(wxT("encoding"));
+    wxFontMapper mapper;
+    wxFontEncoding enc = wxFONTENCODING_DEFAULT;
+    if (!encoding.IsEmpty()) enc = mapper.CharsetToEncoding(encoding);
+    if (enc == wxFONTENCODING_SYSTEM) enc = wxFONTENCODING_SYSTEM;
+
+    wxString faces = GetParamValue(wxT("face"));
+    wxString facename = wxEmptyString;
+    wxFontEnumerator enu;
+    enu.EnumerateFacenames();
+    wxStringTokenizer tk(faces, wxT(","));
+    while (tk.HasMoreTokens())
+    {
+        int index = enu.GetFacenames()->Index(tk.GetNextToken(), FALSE);
+        if (index != wxNOT_FOUND)
+        {
+            facename = (*enu.GetFacenames())[index];
+            break;
+        }
+    }
+
+    m_node = oldnode;
+
+    wxFont font(size, ifamily, istyle, iweight, underlined, facename, enc);
+    return font;
+}
+
+
+void wxXmlResourceHandler::SetupWindow(wxWindow *wnd)
+{
+    //FIXME : add cursor
+
+    if (HasParam(wxT("exstyle")))
+        wnd->SetExtraStyle(GetStyle(wxT("exstyle")));
+    if (HasParam(wxT("bg")))
+        wnd->SetBackgroundColour(GetColour(wxT("bg")));
+    if (HasParam(wxT("fg")))
+        wnd->SetForegroundColour(GetColour(wxT("fg")));
+    if (GetBool(wxT("enabled"), 1) == 0)
+        wnd->Enable(FALSE);
+    if (GetBool(wxT("focused"), 0) == 1)
+        wnd->SetFocus();
+    if (GetBool(wxT("hidden"), 0) == 1)
+        wnd->Show(FALSE);
+#if wxUSE_TOOLTIPS
+    if (HasParam(wxT("tooltip")))
+        wnd->SetToolTip(GetText(wxT("tooltip")));
+#endif
+    if (HasParam(wxT("font")))
+        wnd->SetFont(GetFont());
+}
+
+
+void wxXmlResourceHandler::CreateChildren(wxObject *parent, bool this_hnd_only)
+{
+    wxXmlNode *n = m_node->GetChildren();
+
+    while (n)
+    {
+        if (n->GetType() == wxXML_ELEMENT_NODE &&
+            n->GetName() == wxT("object"))
+        {
+            if (this_hnd_only && CanHandle(n))
+                CreateResource(n, parent, NULL);
+            else
+                m_resource->CreateResFromNode(n, parent, NULL);
+        }
+        n = n->GetNext();
+    }
+}
+
+
+void wxXmlResourceHandler::CreateChildrenPrivately(wxObject *parent, wxXmlNode *rootnode)
+{
+    wxXmlNode *root;
+    if (rootnode == NULL) root = m_node; else root = rootnode;
+    wxXmlNode *n = root->GetChildren();
+
+    while (n)
+    {
+        if (n->GetType() == wxXML_ELEMENT_NODE && CanHandle(n))
+        {
+            CreateResource(n, parent, NULL);
+        }
+        n = n->GetNext();
+    }
+}
+
+
+
+
+
+
+
+// --------------- XMLID implementation -----------------------------
+
+#define XMLID_TABLE_SIZE     1024
+
+
+struct XMLID_record
+{
+    int id;
+    char *key;
+    XMLID_record *next;
+};
+
+static XMLID_record *XMLID_Records[XMLID_TABLE_SIZE] = {NULL};
+
+/*static*/ int wxXmlResource::GetXMLID(const char *str_id)
+{
+    static int XMLID_LastID = wxID_HIGHEST;
+
+    int index = 0;
+
+    for (const char *c = str_id; *c != '\0'; c++) index += (int)*c;
+    index %= XMLID_TABLE_SIZE;
+
+    XMLID_record *oldrec = NULL;
+    int matchcnt = 0;
+    for (XMLID_record *rec = XMLID_Records[index]; rec; rec = rec->next)
+    {
+        if (strcmp(rec->key, str_id) == 0)
+        {
+            return rec->id;
+        }
+        matchcnt++;
+        oldrec = rec;
+    }
+
+    XMLID_record **rec_var = (oldrec == NULL) ?
+                              &XMLID_Records[index] : &oldrec->next;
+    *rec_var = new XMLID_record;
+    (*rec_var)->id = ++XMLID_LastID;
+    (*rec_var)->key = strdup(str_id);
+    (*rec_var)->next = NULL;
+
+    return (*rec_var)->id;
+}
+
+
+static void CleanXMLID_Record(XMLID_record *rec)
+{
+    if (rec)
+    {
+        CleanXMLID_Record(rec->next);
+        free (rec->key);
+        delete rec;
+    }
+}
+
+static void CleanXMLID_Records()
+{
+    for (int i = 0; i < XMLID_TABLE_SIZE; i++)
+        CleanXMLID_Record(XMLID_Records[i]);
+}
+
+
+
+
+
+
+
+
+// --------------- module and globals -----------------------------
+
+
+static wxXmlResource gs_XmlResource;
+
+wxXmlResource *wxTheXmlResource = &gs_XmlResource;
+
+
+class wxXmlResourceModule: public wxModule
+{
+DECLARE_DYNAMIC_CLASS(wxXmlResourceModule)
+public:
+    wxXmlResourceModule() {}
+    bool OnInit() {return TRUE;}
+    void OnExit()
+    {
+        wxTheXmlResource->ClearHandlers();
+        CleanXMLID_Records();
+    }
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxXmlResourceModule, wxModule)
+
+
+// When wxXml is loaded dynamically after the application is already running
+// then the built-in module system won't pick this one up.  Add it manually.
+void wxXmlInitResourceModule()
+{
+    wxModule* module = new wxXmlResourceModule;
+    module->Init();
+    wxModule::RegisterModule(module);
+}
+
+
diff --git a/src/xrc/xmlrsall.cpp b/src/xrc/xmlrsall.cpp
new file mode 100644 (file)
index 0000000..6f4a503
--- /dev/null
@@ -0,0 +1,97 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xmlrsall.cpp
+// Purpose:     wxXmlResource::InitAllHandlers
+// Author:      Vaclav Slavik
+// Created:     2000/03/05
+// RCS-ID:      $Id$
+// Copyright:   (c) 2000 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+// -- Already done in xmlres.cpp
+//#ifdef __GNUG__
+//#pragma implementation "xmlres.h"
+//#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/xrc/xmlres.h"
+#include "wx/xrc/xh_all.h"
+
+void wxXmlResource::InitAllHandlers()
+{
+    AddHandler(new wxBitmapXmlHandler);
+    AddHandler(new wxIconXmlHandler);
+    AddHandler(new wxMenuXmlHandler);
+    AddHandler(new wxMenuBarXmlHandler);
+
+    AddHandler(new wxDialogXmlHandler);
+    AddHandler(new wxPanelXmlHandler);
+
+    AddHandler(new wxSizerXmlHandler);
+//Controls
+    AddHandler(new wxButtonXmlHandler);
+    AddHandler(new wxBitmapButtonXmlHandler);
+    AddHandler(new wxStaticTextXmlHandler);
+    AddHandler(new wxStaticBoxXmlHandler);
+    AddHandler(new wxStaticBitmapXmlHandler);
+    AddHandler(new wxTreeCtrlXmlHandler);
+    AddHandler(new wxCalendarCtrlXmlHandler);
+    AddHandler(new wxListCtrlXmlHandler);
+#if CHECKLISTBOX
+    AddHandler(new wxCheckListXmlHandler);
+#endif
+#if wxUSE_CHOICE
+    AddHandler(new wxChoiceXmlHandler);
+#endif
+#if wxUSE_SLIDER
+    AddHandler(new wxSliderXmlHandler);
+#endif
+#if wxUSE_GAUGE
+    AddHandler(new wxGaugeXmlHandler);
+#endif
+#if wxUSE_CHECKBOX
+    AddHandler(new wxCheckBoxXmlHandler);
+#endif    
+#if wxUSE_HTML
+    AddHandler(new wxHtmlWindowXmlHandler);
+#endif    
+#if wxUSE_SPINBTN
+    AddHandler(new wxSpinButtonXmlHandler);
+#endif    
+#if wxUSE_SPINCTRL
+    AddHandler(new wxSpinCtrlXmlHandler);
+#endif    
+#if wxUSE_SCROLLBAR
+    AddHandler(new wxScrollBarXmlHandler);
+#endif
+    
+#if wxUSE_RADIOBOX
+    AddHandler(new wxRadioBoxXmlHandler);
+    AddHandler(new wxRadioButtonXmlHandler);
+#endif
+#if wxUSE_COMBOBOX
+    AddHandler(new wxComboBoxXmlHandler);
+#endif
+#if wxUSE_NOTEBOOK
+    AddHandler(new wxNotebookXmlHandler);
+#endif
+    AddHandler(new wxTextCtrlXmlHandler);
+#if wxUSE_LISTBOX
+    AddHandler(new wxListBoxXmlHandler);
+#endif
+#if wxUSE_TOOLBAR
+    AddHandler(new wxToolBarXmlHandler);
+#endif
+#if wxUSE_STATLINE
+    AddHandler(new wxStaticLineXmlHandler);
+#endif
+    AddHandler(new wxUnknownWidgetXmlHandler);
+
+    AddHandler(new wxFrameXmlHandler);
+}
diff --git a/src/xrc/xmlwrite.cpp b/src/xrc/xmlwrite.cpp
new file mode 100644 (file)
index 0000000..482f976
--- /dev/null
@@ -0,0 +1,152 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xmlwrite.cpp
+// Purpose:     wxXmlDocument - XML text writer
+// Author:      Vaclav Slavik
+// Created:     2001/04/30
+// RCS-ID:      $Id$
+// Copyright:   (c) 2001 Vaclav Slavik
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+// nothing - already in xml.cpp
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/wfstream.h"
+#include "wx/intl.h"
+#include "wx/log.h"
+#include "wx/strconv.h"
+#include "wx/xrc/xml.h"
+#include "wx/xrc/xmlio.h"
+
+// write string to output:
+inline static void OutputString(wxOutputStream& stream, const wxString& str)
+{
+    if (str.IsEmpty()) return;
+#if wxUSE_UNICODE
+    char *buf = str.mb_str(wxMBConvUTF8);
+    stream.Write(buf, strlen(buf));
+#else
+    stream.Write(str.mb_str(), str.Len());        
+#endif
+}
+
+// Same as above, but create entities first. 
+// Translates '<' to "&lt;", '>' to "&gt;" and '&' to "&amp;"
+static void OutputStringEnt(wxOutputStream& stream, const wxString& str)
+{
+    wxString buf;
+    size_t i, last, len;
+    char c;
+    
+    len = str.Len();
+    last = 0;
+    for (i = 0; i < len; i++)
+    {
+        c = str.GetChar(i);
+        if (c == '<' || c == '>' || 
+            (c == '&' && str.Mid(i+1, 4) != wxT("amp;")))
+        {
+            OutputString(stream, str.Mid(last, i - last));
+            switch (c)
+            {
+                case '<': OutputString(stream, wxT("&lt;")); break;
+                case '>': OutputString(stream, wxT("&gt;")); break;
+                case '&': OutputString(stream, wxT("&amp;")); break;
+                default: break;
+            }
+            last = i + 1;
+        }
+    }
+    OutputString(stream, str.Mid(last, i - last));
+}
+
+inline static void OutputIndentation(wxOutputStream& stream, int indent)
+{
+    wxString str = wxT("\n");
+    for (int i = 0; i < indent; i++)
+        str << wxT(' ') << wxT(' ');
+    OutputString(stream, str);
+}
+
+static void OutputNode(wxOutputStream& stream, wxXmlNode *node, int indent)
+{
+    wxXmlNode *n, *prev;
+    wxXmlProperty *prop;
+
+    switch (node->GetType())
+    {
+        case wxXML_TEXT_NODE:
+            OutputStringEnt(stream, node->GetContent());
+            break;
+            
+        case wxXML_ELEMENT_NODE:
+            OutputString(stream, wxT("<"));
+            OutputString(stream, node->GetName());
+            
+            prop = node->GetProperties();
+            while (prop)
+            {
+                OutputString(stream, wxT(" ") + prop->GetName() +
+                             wxT("=\"") + prop->GetValue() + wxT("\""));
+                // FIXME - what if prop contains '"'?
+                prop = prop->GetNext();
+            }
+            
+            if (node->GetChildren())
+            {
+                OutputString(stream, wxT(">"));
+                prev = NULL;
+                n = node->GetChildren();
+                while (n)
+                {
+                    if (n && n->GetType() != wxXML_TEXT_NODE)
+                        OutputIndentation(stream, indent + 1);
+                    OutputNode(stream, n, indent + 1);
+                    prev = n;
+                    n = n->GetNext();
+                }
+                if (prev && prev->GetType() != wxXML_TEXT_NODE)
+                    OutputIndentation(stream, indent);
+                OutputString(stream, wxT("</"));
+                OutputString(stream, node->GetName());
+                OutputString(stream, wxT(">"));
+            }
+            else
+                OutputString(stream, wxT("/>"));
+            break;
+             
+        case wxXML_COMMENT_NODE:
+            OutputString(stream, wxT("<!--"));
+            OutputString(stream, node->GetContent());
+            OutputString(stream, wxT("-->"));
+            break;
+            
+        default:
+            wxFAIL_MSG(wxT("unsupported node type"));
+    }
+}
+
+bool wxXmlIOHandlerWriter::Save(wxOutputStream& stream, const wxXmlDocument& doc)
+{
+    if (!doc.IsOk())
+        return FALSE;
+        
+    wxString s;
+    
+    s = wxT("<?xml version=\"") + doc.GetVersion() + 
+        wxT("\" encoding=\"utf-8\"?>\n");
+    OutputString(stream, s);  
+    
+    OutputNode(stream, doc.GetRoot(), 0);
+    OutputString(stream, wxT("\n"));
+        
+    return TRUE;
+}