Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch trunk Through [86c70df47c] Excluding Merge-Ins

This is equivalent to a diff from 3e8527de8c to 86c70df47c

2018-07-25
23:06
Made the build system closer to recent TEA. Most of the valuable work was done by Stuart Cassoff. check-in: 59c3d27071 user: rolf tags: trunk
23:03
Merged from trunk. Closed-Leaf check-in: 5d4b4c3d25 user: rolf tags: nearerTEAtoThee
2018-07-24
21:30
Release 0.9.1 check-in: 86c70df47c user: rolf tags: trunk, release, tdom-0-9-1-rc, tdom-0-9-1
2018-07-23
21:53
Updated README. Closed-Leaf check-in: b82decbc00 user: rolf tags: tdom-0-9-1-rc
10:42
Applied a last round of spell fixes provided by the debian tDOM maintainers. check-in: 02bf3a9823 user: rolf tags: trunk
2011-03-30
16:17
as per email exchange with Richard Hipp on March 29th, 2011, we can move the license of his very old XML parsing code (from TMML) into public domain: " Call it public domain. Do whatever you like with it. (Just please remove my name from the comment.) " drh@sqlite.org check-in: 1968382659 user: jolo@osslab-jl.emea.hpqcorp.net tags: trunk
2009-11-10
20:49
See file. Leaf check-in: 3e8527de8c user: rolf tags: trunk, origin
20:47
Fix for possible DoS attack (see CVE-2009-3720) check-in: 156458f135 user: rolf tags: trunk, origin

Added .fossil-settings/crlf-glob.





>
>
1
2
*.vc

Added .fossil-settings/ignore-glob.

















>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
*/win/Debug*
*/win/Release*
*/win/version*.vc
*/win/nmakehlp.exe
*/win/nmakehlp.obj
*/win/nmakehlp.out
*/win/_junk.pch

Added .fossil-settings/manifest.



>
1
on

Changes to CHANGES.
































































































































































































1
2
3
4
5
6
7
































































































































































































--- Release 0.8.2, 15. Aug. 2007 --- See ChangeLog for details ---

2007-08-11  Rolf Ade  <rolf@pointsman.de>

        Now tcldomsh will source ~/.tcldomshrc at start up.

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
2018-07-16  Rolf Ade  <rolf@pointsman.de>

        The package name is tDOM, but it always has been requested by
        [package require tdom] and now the scripted helper commands in
        tdom.tcl are also in the namespace tdom (not anymore in tDOM).
        The new pullparser command is now also in this namespace.
        There are aliases from the old command names to the new one,
        so there must be nothing done; old scripts will run as they
        did. It's just, that you in new code don't have to write
        serveral upcase letters in a row because of tDOM.

2018-07-14  Rolf Ade  <rolf@pointsman.de>

        Updated to expat 2.2.5. Expat now want to use a "good" entropy
        source to salt internal hash table (to reduce the possibility
        of DoS attacts with malicious XML input). Configure tries to
        figure out automatically the most appropriate entropy source
        on your platform. The new configure switch --with-entropy
        gives control over that. The configure switch
        --without-entropy disables all this; expat (and in turn tDOM)
        will use what was used in earlier expat versions.

2018-07-12  Rolf Ade  <rolf@pointsman.de>

        Updated TEA.

2018-05-17  Rolf Ade  <rolf@pointsman.de>

        Added new method attributeNames to domNode (cmds).

2018-05-10  Rolf Ade  <rolf@pointsman.de>

        Added new methods line and column to most pull parser states.

2018-05-04  Rolf Ade  <rolf@pointsman.de>

        More fine grain control about serialization details: new asXML
        options -nogtescape and -noEmptyElementTag.

2018-04-24  Rolf Ade  <rolf@pointsman.de>

        Fixed a potentially dramatic speed problem in case of certain
        classes of XPath expressions if a threads enabled tDOM is
        used, the result set is large and the DOM tree to query was
        altered somewhere before the query by an operation, which
        appended, inserted or replaced a node.

2018-03-09  Rolf Ade  <rolf@pointsman.de>

        Added command tDOM::pullparser, with creates simple XML "pull"
        parser commands. This commands parse XML input and stop at
        certain points ("events"). You continue parsing at your will.

2018-03-06  Rolf Ade  <rolf@pointsman.de>

        Fixed a potentially dramatic speed problem, if the expat
        parser is used w/ "Welch dispatch" with any 8.6 version. The
        core changed behaviour, we had to adapt.

        Added method "delete" to the [expat] push parser (as an alias
        to the still there "free").

2018-02-14  Rolf Ade  <rolf@pointsman.de>

        Added [dom featureinfo versionhash], which returns the fossil
        repository version hash of the sources build from.
        
2018-02-03  Rolf Ade  <rolf@pointsman.de>

        In a bunch of spell fixes a few changes (partly even marginal,
        e.g. during configuration) in error messages for uniformly
        usage of names.

2017-11-07  Rolf Ade  <rolf@pointsman.de>

        New flag -keepCDATA for [dom parse ...].

--- Release 0.9.0, 24. Aug. 2017 --- 

2017-08-21 Ashok Nadkarni

        Windows build system (VC and mingw) modernised.

2017-08-17 Rolf Ade  <rolf@pointsman.de>

        New feature "creating real FQ nodes with *fromScript methods",
        by adding option -namespace to [dom createNodeCmd].

2017-08-14 Rolf Ade  <rolf@pointsman.de>

        Updated TEA.

2017-07-29 Rolf Ade  <rolf@pointsman.de>

        Removed hacky check on [load] time if the tclsh and tDOM are
        build with incompatible TCL_UTF_MAX (because it did not work
        anymore with recent tcl because of changes in core).

2017-07-28 Rolf Ade  <rolf@pointsman.de>

        Added JSON support. New -json option to [dom parse]. New doc
        method asJSON. New node method jsonType. New option -jsonType
        of [dom createNodeCmd]. New option -tagName of [dom
        createNodeCmd]. New option -jsonType to dom method
        createDocumentNode.

2017-04-06 Rolf Ade  <rolf@pointsman.de>

        Added HTM5 parser (new -html5 option to [dom parse]). Requires
        gumbo lib and must be enabled at configure time.
        
2016-10-01 Rolf Ade  <rolf@pointsman.de>

        Updated to expat 2.2.0.

2015-09-11 Rolf Ade  <rolf@pointsman.de>

        Added options -xmlDeclaration and -encString to the asXML
        method of the domDoc and domNode commands.

2015-04-11 Rolf Ade  <rolf@pointsman.de>

        Changed behavior wrt to result code of a called
        -xsltmessagecmd script. Up to now, the result code of that
        script evaluation was ignored. Now, any other return code of
        that script then TCL_OK terminates the xslt transformation and
        returns error. Purposeful termination may be signaled with
        return -code break, for which the error message will be empty.

2015-04-01 Rolf Ade  <rolf@pointsman.de>

        Added new expat parser cmd method currentmarkup. 

2015-03-26 Rolf Ade  <rolf@pointsman.de>

        Added option -indentAttrs to the domDoc/domNode method
        asXML. Thanks goes to evilotto.

2014-10-16 Rolf Ade  <rolf@pointsman.de>
	
        Added configure option --with-expat, to build and link against
        the system or a custom expat lib. Default is, to use the
        included sources.

2014-01-01 Rolf Ade  <rolf@pointsman.de>

        Rework so some basic internals, for (even) more efficiency of
        token mode.

2013-12-24 Rolf Ade  <rolf@pointsman.de>

        Improved handling of characters beyond BMP. 
        
2013-12-20 Rolf Ade  <rolf@pointsman.de>

        Added option -feedbackcmd to the dom parse method. This option
        allows to specify a script, which will be called as feedback
        command. For backward compatibility, if no -feedbackcmd is
        given, but there is a tcl proc named ::dom::domParseFeedback
        then this proc is used as -feedbackcmd. If there isn't such a
        proc and -feedbackAfter is used, it is an error to not also
        use -feedbackcmd. A return -code break from the -feedbackcmd
        causes the parser to almost immediately abort parsing and let
        the [dom parse] call return the empty string (instead of a
        document) without raising error. 

        For expat parser objects: If a handler script returns -code
        return, then parsing is aborted, but no error is raised.

2013-12-04 Rolf Ade <rolf@pointsman.de>

        tDOM now cross-compiles on linux for windows (w32/w64) with
        mingw-w64.
        
2013-09-26 Rolf Ade  <rolf@pointsman.de>

        Added dom method featureinfo.

2013-08-31 Rolf Ade  <rolf@pointsman.de>

        Raised the limit of maximum number of different XML
        namespaceses within one DOM tree to 2^31. New configure switch
        --enable-lessns restores old code.

2013-07-21 Rolf Ade  <rolf@pointsman.de>

        Updated TEA build system of tdom itself and the extensions.

2013-05-16  Rolf Ade  <rolf@pointsman.de>

        Update to expat 2.1.0.

--- Release 0.8.2, 15. Aug. 2007 --- See ChangeLog for details ---

2007-08-11  Rolf Ade  <rolf@pointsman.de>

        Now tcldomsh will source ~/.tcldomshrc at start up.

Changes to ChangeLog.




















1
2
3
4
5
6
7
...
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
...
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
....
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
....
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
....
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
....
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
....
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
....
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290



















2009-11-10  Rolf Ade  <rolf@pointsman.de>

        * expat/xmltok_impl.c: Fix for possible DoS attack (see
          CVE-2009-3720)


2008-08-27  Rolf Ade  <rolf@pointsman.de>
................................................................................
2005-01-11  Rolf Ade  <rolf@pointsman.de>

        * doc/domDoc.*
        * doc/domNode.*: Added documentation for the -cache option of
          the selectNodes method.

        * lib/tdom.tcl: Scripted xpath function element-available:
          moved xsl:output to the avaliable elements, since it's in
          fact avaliable in the meantime (with exception of the
          'version' and 'cdata-section-elements' attributes) - the
          output options can be queried from the result doc, but it's
          the responsibility of the application, to serialize the tree
          according to that settings.

2005-01-10  Rolf Ade  <rolf@pointsman.de>

................................................................................
        * doc/domNode.*
        * generic/tcldom.c: Improved speed of the getAttribute
          shortcut '@attname' (and, not so notable, of tcl coded
          methods of the dom, domDoc and domNode cmds). Corrected typo
          in domNode usage msg for getElementByID. Improved error msg
          for getAttribute, if attribute is not found. Changed
          behavior of getElementByID: if no element with the given id
          is found, returns now the emtpy string, not a TCL_ERROR
          (closer to DOM rec, getElementByID never raise an
          exception). Bug fix: nodeName now returns the per DOM rec
          correct values for comment and cdata section nodes (were as
          yet reported as if they where text nodes).

        * tests/entity.test  
        * generic/tclexpat.c: Better error msg in case of 'filename'
................................................................................

2003-10-16  Zoran Vasiljevic  <zv@archiware.com>

	* generic/tcldom.c: added "dom detachDocument" command
	  to match the already present "dom attachDocument".
	  This is used only for threaded tdom builds.

	* generic/domlock.c: changed lock caching to accomodate for
	  situation with huge number of created documnents
	
	  Also, added new "domDoc" command as a first-class tdom citizen,
	  analogous to the already existing "domNode". It operates on the
	  document token.

	  Attempt has been made to start to follow Tcl-style-guide
................................................................................
          overwriting named templates without match attribute with an
          other named template). Improved error reports: for more
          detected errors there is now a line/column number
          given. Plenty of improvements in detecting erroneous
          stylesheets: more checks for format-number formatting
          patters (although especically format-number patterns are
          still a can of worms), added parameter number check for
          additional XPath function current(), template, paramter,
          variable, sort, choose, copy, and message elements.

2003-03-26  Rolf Ade  <rolf@pointsman.de>
        
        * generic/domxslt.c: Fixed some memory problems, mostly in
          case of erroneous stylesheets.

................................................................................

        * lib/tdom.tcl
          generic/dom.c: Improved ::tDOM::xml(Read|Open)File. Now
          handles also utf-16 files with BOM right.

        * generic/domxslt.c: Made some functions static. Removed a
          TODO note, which already was done. Improved some error msgs
          (now with line/column info, if avaliable). Bug fix:
          xsltXPathFuncs must return -1 to signal error, because if
          the source of the function call was inside of domxslt.c the
          result code (rc) check rule is rc < 0. Fixed text in a
          xsl:attribute error msg. Fixed memory leak in error case in
          ExecAction, case forEach. Added a missing result code check
          in ExecAction, case procinstr. Bug fix: Even literal result
          element subtrees are relevant for xslt variable scope
................................................................................
        * generic/dom.c
        * generic/tcldom.c
        * tests/dom.test: Fix for the problem with ownerDocument
          reported by Oleg Oleinick (see test dom-29.1).

        * generic/tcldom.c
        * tests/dom.test: Fixed bug with COMMENT_NODEs while using the
          asList method (problem reported by Ramon Rib). While at it,
          also added code for handling processing instructions, which
          was also missing, up to now.

2003-01-11  Rolf Ade  <rolf@pointsman.de>

        * generic/dom.c
        * generic/dom.h
................................................................................
2002-12-20  Zoran Vasiljevic  (zoran@archiware.com)

	* generic/tcldom.c
	* generic/dom.c
	* generic/domxpath.c
	* generic/domalloc.c
	* generic/domhtml.c
	* generic/docxpath.c: added DBG macro arround some fprintf's

2002-11-28  Rolf Ade  <rolf@pointsman.de>

        * generic/domxslt.c: Reuse already parsed trees only if it is
          requested again for the same matter (as stylesheet or as
          source dir), otherwise create a new tree, because of the
          different white space stripping rules for stylesheets and
................................................................................
        * lib/tdom.tcl: tDOM::xmlOpenFile fix for files < 4 Byte size.    
        
        * generic/domxpath.c
        * generic/domxpath.h: Fixed ridiculously long runtime of
          certain // expr on certain documents. During analysis and
          testing, it turned out, that it would have been an even
          simpler approach, to simply expand the abbreviation // in
          the according productions. Though, the choosen implentation
          seems often to be (slightly) faster and is a start to
          collect experiences with early predicate evaluation.

2002-11-02  Zoran Vasiljevic  <zoran@archiware.com>

	* lib/tdomhtml.tcl: removed in favour of new tdom extension

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
...
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
....
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
....
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
....
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
....
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
....
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
....
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309

NOTICE: This file isn't kept up to date anymore. Look at the timeline
of the leading fossil repository (http://tdom.org) or at the backup
repository at https://core.tcl.tk/tdom/timeline for detailed lists of
code changes.

User interface changes/enhancements and other important changes will
still be documented in the CHANGES file.

2012-05-17  Rolf Ade  <rolf@pointsman.de>

        * generic/dom.h
        * generic/tcldom.c: Compatibility with Tcl 8.6 - Beginning
          with 8.6, interp->errorLine isn't public visible anymore
          (TIP 330).

        * generic/domxslt.c: Fixed wrong size on memcpy on 64 bit
          (when sizeof(int)!=sizeof(int*))

2009-11-10  Rolf Ade  <rolf@pointsman.de>

        * expat/xmltok_impl.c: Fix for possible DoS attack (see
          CVE-2009-3720)


2008-08-27  Rolf Ade  <rolf@pointsman.de>
................................................................................
2005-01-11  Rolf Ade  <rolf@pointsman.de>

        * doc/domDoc.*
        * doc/domNode.*: Added documentation for the -cache option of
          the selectNodes method.

        * lib/tdom.tcl: Scripted xpath function element-available:
          moved xsl:output to the available elements, since it's in
          fact available in the meantime (with exception of the
          'version' and 'cdata-section-elements' attributes) - the
          output options can be queried from the result doc, but it's
          the responsibility of the application, to serialize the tree
          according to that settings.

2005-01-10  Rolf Ade  <rolf@pointsman.de>

................................................................................
        * doc/domNode.*
        * generic/tcldom.c: Improved speed of the getAttribute
          shortcut '@attname' (and, not so notable, of tcl coded
          methods of the dom, domDoc and domNode cmds). Corrected typo
          in domNode usage msg for getElementByID. Improved error msg
          for getAttribute, if attribute is not found. Changed
          behavior of getElementByID: if no element with the given id
          is found, returns now the empty string, not a TCL_ERROR
          (closer to DOM rec, getElementByID never raise an
          exception). Bug fix: nodeName now returns the per DOM rec
          correct values for comment and cdata section nodes (were as
          yet reported as if they where text nodes).

        * tests/entity.test  
        * generic/tclexpat.c: Better error msg in case of 'filename'
................................................................................

2003-10-16  Zoran Vasiljevic  <zv@archiware.com>

	* generic/tcldom.c: added "dom detachDocument" command
	  to match the already present "dom attachDocument".
	  This is used only for threaded tdom builds.

	* generic/domlock.c: changed lock caching to accommodate for
	  situation with huge number of created documnents
	
	  Also, added new "domDoc" command as a first-class tdom citizen,
	  analogous to the already existing "domNode". It operates on the
	  document token.

	  Attempt has been made to start to follow Tcl-style-guide
................................................................................
          overwriting named templates without match attribute with an
          other named template). Improved error reports: for more
          detected errors there is now a line/column number
          given. Plenty of improvements in detecting erroneous
          stylesheets: more checks for format-number formatting
          patters (although especically format-number patterns are
          still a can of worms), added parameter number check for
          additional XPath function current(), template, parameter,
          variable, sort, choose, copy, and message elements.

2003-03-26  Rolf Ade  <rolf@pointsman.de>
        
        * generic/domxslt.c: Fixed some memory problems, mostly in
          case of erroneous stylesheets.

................................................................................

        * lib/tdom.tcl
          generic/dom.c: Improved ::tDOM::xml(Read|Open)File. Now
          handles also utf-16 files with BOM right.

        * generic/domxslt.c: Made some functions static. Removed a
          TODO note, which already was done. Improved some error msgs
          (now with line/column info, if available). Bug fix:
          xsltXPathFuncs must return -1 to signal error, because if
          the source of the function call was inside of domxslt.c the
          result code (rc) check rule is rc < 0. Fixed text in a
          xsl:attribute error msg. Fixed memory leak in error case in
          ExecAction, case forEach. Added a missing result code check
          in ExecAction, case procinstr. Bug fix: Even literal result
          element subtrees are relevant for xslt variable scope
................................................................................
        * generic/dom.c
        * generic/tcldom.c
        * tests/dom.test: Fix for the problem with ownerDocument
          reported by Oleg Oleinick (see test dom-29.1).

        * generic/tcldom.c
        * tests/dom.test: Fixed bug with COMMENT_NODEs while using the
          asList method (problem reported by Ramon Ribรณ). While at it,
          also added code for handling processing instructions, which
          was also missing, up to now.

2003-01-11  Rolf Ade  <rolf@pointsman.de>

        * generic/dom.c
        * generic/dom.h
................................................................................
2002-12-20  Zoran Vasiljevic  (zoran@archiware.com)

	* generic/tcldom.c
	* generic/dom.c
	* generic/domxpath.c
	* generic/domalloc.c
	* generic/domhtml.c
	* generic/docxpath.c: added DBG macro around some fprintf's

2002-11-28  Rolf Ade  <rolf@pointsman.de>

        * generic/domxslt.c: Reuse already parsed trees only if it is
          requested again for the same matter (as stylesheet or as
          source dir), otherwise create a new tree, because of the
          different white space stripping rules for stylesheets and
................................................................................
        * lib/tdom.tcl: tDOM::xmlOpenFile fix for files < 4 Byte size.    
        
        * generic/domxpath.c
        * generic/domxpath.h: Fixed ridiculously long runtime of
          certain // expr on certain documents. During analysis and
          testing, it turned out, that it would have been an even
          simpler approach, to simply expand the abbreviation // in
          the according productions. Though, the chosen implementation
          seems often to be (slightly) faster and is a start to
          collect experiences with early predicate evaluation.

2002-11-02  Zoran Vasiljevic  <zoran@archiware.com>

	* lib/tdomhtml.tcl: removed in favour of new tdom extension

Changes to Makefile.in.

1
2
3
4
5
6
7
8



9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
79
80
81
82
83
84
85


86
87
88
89
90
91
92
93
94
95
96
97
98
99


100
101
102

103
104
105
106
107
108
109
110
111
112
113
114
115
116
...
121
122
123
124
125
126
127


128
129
130


131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169

170

171
172
173
174
175
176


177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260










261
262
263
264
265
266
267
...
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312


















313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
...
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
...
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400



401
402
403
404
405
406
407
408
409
410


411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
# Makefile.in --
#
#	This file is a Makefile for Sample TEA Extension.  If it has the name
#	"Makefile.in" then it is a template for a Makefile;  to generate the
#	actual Makefile, run "./configure", which is a configuration script
#	generated by the "autoconf" program (constructs like "@foo@" will get
#	replaced in the actual Makefile.
#



# Copyright (c) 1999 Scriptics Corporation.
# Copyright (c) 2002-2005 ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id$

#========================================================================
# Add additional lines to handle any additional AC_SUBST cases that
# have been added in a customized configure script.
#========================================================================

AOL_DIR		= @AOL_DIR@
................................................................................

srcdir		= @srcdir@
prefix		= @prefix@
exec_prefix	= @exec_prefix@

bindir		= @bindir@
libdir		= @libdir@


datadir		= @datadir@
mandir		= @mandir@
includedir	= @includedir@

DESTDIR		=

PKG_DIR		= $(PACKAGE_NAME)$(PACKAGE_VERSION)
pkgdatadir	= $(datadir)/$(PKG_DIR)
pkglibdir	= $(libdir)/$(PKG_DIR)
pkgincludedir	= $(includedir)/$(PKG_DIR)

top_builddir	= .

INSTALL		= @INSTALL@


INSTALL_PROGRAM	= @INSTALL_PROGRAM@
INSTALL_DATA	= @INSTALL_DATA@
INSTALL_SCRIPT	= @INSTALL_SCRIPT@


PACKAGE_NAME	= @PACKAGE_NAME@
PACKAGE_VERSION	= @PACKAGE_VERSION@
CC		= @CC@
CFLAGS_DEFAULT	= @CFLAGS_DEFAULT@
CFLAGS_WARNING	= @CFLAGS_WARNING@
CLEANFILES	= @CLEANFILES@
EXEEXT		= @EXEEXT@
LDFLAGS_DEFAULT	= @LDFLAGS_DEFAULT@
MAKE_LIB	= @MAKE_LIB@
MAKE_SHARED_LIB	= @MAKE_SHARED_LIB@
MAKE_STATIC_LIB	= @MAKE_STATIC_LIB@
MAKE_STUB_LIB	= @MAKE_STUB_LIB@
OBJEXT		= @OBJEXT@
................................................................................
SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
STLIB_LD	= @STLIB_LD@
#TCL_DEFS	= @TCL_DEFS@
TCL_BIN_DIR	= @TCL_BIN_DIR@
TCL_SRC_DIR	= @TCL_SRC_DIR@
#TK_BIN_DIR	= @TK_BIN_DIR@
#TK_SRC_DIR	= @TK_SRC_DIR@



# Not used, but retained for reference of what libs Tcl required
#TCL_LIBS	= @TCL_LIBS@



#========================================================================
# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
# package without installing.  The other environment variables allow us
# to test against an uninstalled Tcl.  Add special env vars that you
# require for testing here (like TCLX_LIBRARY).
#========================================================================

EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR)
#EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
TCLLIBPATH	= $(top_builddir)
TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
		  @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
		  PATH="$(EXTRA_PATH):$(PATH)" \
		  TCLLIBPATH="$(TCLLIBPATH)"
#		  TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`

TCLSH_PROG	= @TCLSH_PROG@
TCLSH   	= $(TCLSH_ENV) $(TCLSH_PROG)


#WISH_PROG	= @WISH_PROG@
#WISH   	= $(TCLSH_ENV) $(WISH_PROG)


SHARED_BUILD	= @SHARED_BUILD@

INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@
#INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@

PKG_CFLAGS	= @PKG_CFLAGS@

# TCL_DEFS is not strictly need here, but if you remove it, then you
# must make sure that configure.in checks for the necessary components
# that your library may use.  TCL_DEFS can actually be a problem if
# you do not compile with a similar machine setup as the Tcl core was
# compiled with.
#DEFS		= $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
DEFS		= @DEFS@ $(PKG_CFLAGS)


CONFIG_CLEAN_FILES = Makefile tdomConfig.sh tdom.tcl


CPPFLAGS	= @CPPFLAGS@
LIBS		= @PKG_LIBS@ @LIBS@
AR		= @AR@
CFLAGS		= @CFLAGS@
COMPILE		= $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)



#========================================================================
# Start of user-definable TARGETS section
#========================================================================

#========================================================================
# TEA TARGETS.  Please note that the "libraries:" target refers to platform
# independent files, and the "binaries:" target inclues executable programs and
# platform-dependent libraries.  Modify these targets so that they install
# the various pieces of your package.  The make and install rules
# for the BINARIES that you specified above have already been done.
#========================================================================

all: binaries libraries doc

#========================================================================
# TDOM enabled shell is build as an extra directive, since non TEA. 
#========================================================================

$(TDOMSHELL): $(PKG_OBJECTS)
	$(COMPILE) -c `@CYGPATH@ $(srcdir)/unix/tclAppInit.c`
	$(CC) @LDFLAGS@ -o $@ tclAppInit.$(OBJEXT) $(PKG_OBJECTS) \
	  $(TCL_LIBS) $(TCL_LIB_SPEC) $(LIBS) $(TDOM_LD_SEARCH_FLAGS)

#========================================================================
# The binaries target builds executable programs, Windows .dll's, unix
# shared/static libraries, and any other platform-dependent files.
# The list of targets to build for "binaries:" is specified at the top
# of the Makefile, in the "BINARIES" variable.
#========================================================================

binaries: $(BINARIES) pkgIndex.tcl-hand

libraries:


#========================================================================
# Your doc target should differentiate from doc builds (by the developer)
# and doc installs (see install-doc), which just install the docs on the
# end user machine when building from source.
#========================================================================

................................................................................

#========================================================================
# This rule installs platform-independent files, such as header files.
# The list=...; for p in $$list handles the empty list case x-platform.
#========================================================================

install-libraries: libraries
	@mkdir -p $(DESTDIR)$(includedir)
	@echo "Installing header files in $(DESTDIR)$(includedir)"
	@list='$(PKG_HEADERS)'; for i in $$list; do \
	    echo "Installing $(srcdir)/$$i" ; \
	    $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
	done;

#========================================================================
# Install documentation.  Unix manpages should go in the $(mandir)
# directory.
#========================================================================

install-doc: doc
	@mkdir -p $(DESTDIR)$(mandir)/mann
	@echo "Installing documentation in $(DESTDIR)$(mandir)"
	@list='$(srcdir)/doc/*.n'; for i in $$list; do \
	    echo "Installing $$i"; \
	    rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
	    $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
	done

test: binaries libraries
	@cp $(srcdir)/lib/tdom.tcl .
	$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)

shell: binaries libraries
	@$(TCLSH) $(SCRIPT)

gdb:
	$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)











depend:

#========================================================================
# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
# mentioned above.  That will ensure that this target is built when you
# run "make binaries".
................................................................................
# 	$(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
#
# Setting the VPATH variable to a list of paths will cause the makefile
# to look into these paths when resolving .c to .obj dependencies.
# As necessary, add $(srcdir):$(srcdir)/compat:....
#========================================================================

VPATH = $(srcdir):$(srcdir)/expat:$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win

.c.@OBJEXT@:
	$(COMPILE) -c `@CYGPATH@ $<` -o $@

#========================================================================
# Create the pkgIndex.tcl file.
#========================================================================

pkgIndex.tcl-hand:
	@(echo 'package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
	"load [list [file join $$dir $(PKG_LIB_FILE)]];\
         source [list [file join $$dir tdom.tcl]]"'\
	) > pkgIndex.tcl



















#========================================================================
# Distribution creation
# You may need to tweak this target to make it work correctly.
#========================================================================

#COMPRESS	= tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
COMPRESS	= gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT	= /tmp/dist
DIST_DIR	= $(DIST_ROOT)/$(PKG_DIR)

dist-clean:
	rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*

dist: dist-clean
................................................................................
#========================================================================

#========================================================================
# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
# variable in configure.in
#========================================================================

clean:  
	-test -z "$(BINARIES)" || rm -f $(BINARIES)
	-rm -f *.$(OBJEXT) core *.core
	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)

distclean: clean
	-rm -f *.tab.c
	-rm -f $(CONFIG_CLEAN_FILES)
................................................................................
# In addition, this will generate the pkgIndex.tcl
# file in the install location (assuming it can find a usable tclsh shell)
#
# You should not have to modify this target.
#========================================================================

install-lib-binaries: binaries
	@mkdir -p $(DESTDIR)$(pkglibdir)
	@list='$(lib_BINARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
	    stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
	    if test "x$$stub" = "xstub"; then \
		echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
		$(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
	    else \
		echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
		$(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
	    fi; \



	    ext=`echo $$p|sed -e "s/.*\.//"`; \
	    if test "x$$ext" = "xdll"; then \
		lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
		if test -f $$lib; then \
		    echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
	            $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
		fi; \
	    fi; \
	  fi; \
	done


	@list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
	  if test -f $(srcdir)/$$p; then \
	    destp=`basename $$p`; \
	    echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
	    $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
	  fi; \
	done
	@if test "x$(SHARED_BUILD)" = "x1"; then \
	    echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
	    $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
	fi
	$(INSTALL_DATA) tdomConfig.sh $(DESTDIR)$(libdir)

#========================================================================
# Install binary executables (e.g. .exe files and dependent .dll files)
# This is for files that must go in the bin directory (located next to
# wish and tclsh), like dependent .dll files on Windows.
#
# You should not have to modify this target, except to define bin_BINARIES
# above if necessary.
#========================================================================

install-bin-binaries: binaries
	@mkdir -p $(DESTDIR)$(bindir)
	@list='$(bin_BINARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
	  fi; \
	done

.SUFFIXES: .c .$(OBJEXT)

Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
	cd $(top_builddir) \
	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status

uninstall-binaries:
	list='$(lib_BINARIES)'; for p in $$list; do \
	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \
|

|





>
>
>





<
<







 







>
>


<










|
>
>
|
|
|
>






<







 







>
>



>
>











|
|


<


|

>

|
<



|












>
|
>






>
>







|











|


|








|


<







 







|












|



<












>
>
>
>
>
>
>
>
>
>







 







|













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|







 







|







 







|


<
<
<

|
|

|
|

>
>
>










>
>











<











|







<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


17
18
19
20
21
22
23
..
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
...
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160

161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
...
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
...
418
419
420
421
422
423
424
425
426
427



428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479


480
481
482
483
484
485
486
#  Makefile.in --
#
#	This file is a Makefile for the tdom TEA Extension. If it has the name
#	"Makefile.in" then it is a template for a Makefile;  to generate the
#	actual Makefile, run "./configure", which is a configuration script
#	generated by the "autoconf" program (constructs like "@foo@" will get
#	replaced in the actual Makefile.
#
# Copyright (c) 2013 Rolf Ade
#
# Derived from work
# Copyright (c) 1999 Scriptics Corporation.
# Copyright (c) 2002-2005 ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.



#========================================================================
# Add additional lines to handle any additional AC_SUBST cases that
# have been added in a customized configure script.
#========================================================================

AOL_DIR		= @AOL_DIR@
................................................................................

srcdir		= @srcdir@
prefix		= @prefix@
exec_prefix	= @exec_prefix@

bindir		= @bindir@
libdir		= @libdir@
includedir	= @includedir@
datarootdir	= @datarootdir@
datadir		= @datadir@
mandir		= @mandir@


DESTDIR		=

PKG_DIR		= $(PACKAGE_NAME)$(PACKAGE_VERSION)
pkgdatadir	= $(datadir)/$(PKG_DIR)
pkglibdir	= $(libdir)/$(PKG_DIR)
pkgincludedir	= $(includedir)/$(PKG_DIR)

top_builddir	= .

INSTALL_OPTIONS =
INSTALL		= $(SHELL) $(srcdir)/tclconfig/install-sh -c ${INSTALL_OPTIONS}
INSTALL_DATA_DIR = ${INSTALL} -d -m 755
INSTALL_PROGRAM	= ${INSTALL} -m 555
INSTALL_DATA	= ${INSTALL} -m 444
INSTALL_SCRIPT	= ${INSTALL_PROGRAM}
INSTALL_LIBRARY	= ${INSTALL_DATA}

PACKAGE_NAME	= @PACKAGE_NAME@
PACKAGE_VERSION	= @PACKAGE_VERSION@
CC		= @CC@
CFLAGS_DEFAULT	= @CFLAGS_DEFAULT@
CFLAGS_WARNING	= @CFLAGS_WARNING@

EXEEXT		= @EXEEXT@
LDFLAGS_DEFAULT	= @LDFLAGS_DEFAULT@
MAKE_LIB	= @MAKE_LIB@
MAKE_SHARED_LIB	= @MAKE_SHARED_LIB@
MAKE_STATIC_LIB	= @MAKE_STATIC_LIB@
MAKE_STUB_LIB	= @MAKE_STUB_LIB@
OBJEXT		= @OBJEXT@
................................................................................
SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
STLIB_LD	= @STLIB_LD@
#TCL_DEFS	= @TCL_DEFS@
TCL_BIN_DIR	= @TCL_BIN_DIR@
TCL_SRC_DIR	= @TCL_SRC_DIR@
#TK_BIN_DIR	= @TK_BIN_DIR@
#TK_SRC_DIR	= @TK_SRC_DIR@

MATH_LIBS	= @MATH_LIBS@

# Not used, but retained for reference of what libs Tcl required
#TCL_LIBS	= @TCL_LIBS@

TDOMSHELL_LIBS = @TCL_LIBS@ @SHLIB_LD_LIBS@

#========================================================================
# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
# package without installing.  The other environment variables allow us
# to test against an uninstalled Tcl.  Add special env vars that you
# require for testing here (like TCLX_LIBRARY).
#========================================================================

EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR)
#EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
TCLLIBPATH	= $(top_builddir)
TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
PKG_ENV		= @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
		  PATH="$(EXTRA_PATH):$(PATH)" \
		  TCLLIBPATH="$(TCLLIBPATH)"


TCLSH_PROG	= @TCLSH_PROG@
TCLSH		= $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)

#WISH_ENV	= TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
#WISH_PROG	= @WISH_PROG@
#WISH		= $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)


SHARED_BUILD	= @SHARED_BUILD@

INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ -I$(top_builddir)
#INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@

PKG_CFLAGS	= @PKG_CFLAGS@

# TCL_DEFS is not strictly need here, but if you remove it, then you
# must make sure that configure.in checks for the necessary components
# that your library may use.  TCL_DEFS can actually be a problem if
# you do not compile with a similar machine setup as the Tcl core was
# compiled with.
#DEFS		= $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
DEFS		= @DEFS@ $(PKG_CFLAGS)

# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl tdomConfig.sh versionhash.h
CLEANFILES	= @CLEANFILES@

CPPFLAGS	= @CPPFLAGS@
LIBS		= @PKG_LIBS@ @LIBS@
AR		= @AR@
CFLAGS		= @CFLAGS@
COMPILE		= $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)

.SUFFIXES: .c .$(OBJEXT)

#========================================================================
# Start of user-definable TARGETS section
#========================================================================

#========================================================================
# TEA TARGETS.  Please note that the "libraries:" target refers to platform
# independent files, and the "binaries:" target includes executable programs and
# platform-dependent libraries.  Modify these targets so that they install
# the various pieces of your package.  The make and install rules
# for the BINARIES that you specified above have already been done.
#========================================================================

all: binaries libraries doc

#========================================================================
# TDOM enabled shell is build as an extra directive, since non TEA. 
#========================================================================

$(TDOMSHELL): $(PKG_OBJECTS) $(srcdir)/unix/tclAppInit.c
	$(COMPILE) -c `@CYGPATH@ $(srcdir)/unix/tclAppInit.c`
	$(CC) @LDFLAGS@ -o $@ tclAppInit.$(OBJEXT) $(PKG_OBJECTS) \
	  $(TCL_LIB_SPEC) $(TDOMSHELL_LIBS) $(TDOM_LD_SEARCH_FLAGS)

#========================================================================
# The binaries target builds executable programs, Windows .dll's, unix
# shared/static libraries, and any other platform-dependent files.
# The list of targets to build for "binaries:" is specified at the top
# of the Makefile, in the "BINARIES" variable.
#========================================================================

binaries: versionhash.h $(BINARIES) pkgIndex.tcl-hand

libraries:


#========================================================================
# Your doc target should differentiate from doc builds (by the developer)
# and doc installs (see install-doc), which just install the docs on the
# end user machine when building from source.
#========================================================================

................................................................................

#========================================================================
# This rule installs platform-independent files, such as header files.
# The list=...; for p in $$list handles the empty list case x-platform.
#========================================================================

install-libraries: libraries
	@$(INSTALL_DATA_DIR) $(DESTDIR)$(includedir)
	@echo "Installing header files in $(DESTDIR)$(includedir)"
	@list='$(PKG_HEADERS)'; for i in $$list; do \
	    echo "Installing $(srcdir)/$$i" ; \
	    $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
	done;

#========================================================================
# Install documentation.  Unix manpages should go in the $(mandir)
# directory.
#========================================================================

install-doc: doc
	@$(INSTALL_DATA_DIR) $(DESTDIR)$(mandir)/mann
	@echo "Installing documentation in $(DESTDIR)$(mandir)"
	@list='$(srcdir)/doc/*.n'; for i in $$list; do \
	    echo "Installing $$i"; \

	    $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
	done

test: binaries libraries
	@cp $(srcdir)/lib/tdom.tcl .
	$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)

shell: binaries libraries
	@$(TCLSH) $(SCRIPT)

gdb:
	$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)

VALGRINDARGS =	--tool=memcheck --num-callers=20 --leak-resolution=high \
		--leak-check=yes --show-reachable=yes -v

valgrind: binaries libraries
	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) \
		`@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)

valgrindshell: binaries libraries
	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)

depend:

#========================================================================
# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
# mentioned above.  That will ensure that this target is built when you
# run "make binaries".
................................................................................
# 	$(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
#
# Setting the VPATH variable to a list of paths will cause the makefile
# to look into these paths when resolving .c to .obj dependencies.
# As necessary, add $(srcdir):$(srcdir)/compat:....
#========================================================================

VPATH = $(srcdir):$(srcdir)/expat:$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macosx

.c.@OBJEXT@:
	$(COMPILE) -c `@CYGPATH@ $<` -o $@

#========================================================================
# Create the pkgIndex.tcl file.
#========================================================================

pkgIndex.tcl-hand:
	@(echo 'package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
	"load [list [file join $$dir $(PKG_LIB_FILE)]];\
         source [list [file join $$dir tdom.tcl]]"'\
	) > pkgIndex.tcl

#========================================================================
# Create tdomDecls.h and tdomStubInit.c from tdom.decls
#========================================================================

genstubs: $(srcdir)/generic/tdom.decls
	$(TCLSH_PROG) $(TCL_SRC_DIR)/tools/genStubs.tcl $(srcdir)/generic \
               $(srcdir)/generic/tdom.decls

#========================================================================
# Create a include file that #define the current fossil hash
#========================================================================
versionhash.h: $(srcdir)/manifest.uuid
	@echo "#define FOSSIL_HASH \"" | tr -d '\n\r' > $(top_builddir)/versionhash.h
	@cat $(srcdir)/manifest.uuid | tr -d '\n\r' >> $(top_builddir)/versionhash.h
	@echo "\"" >> $(top_builddir)/versionhash.h

tcldom.o: $(srcdir)/generic/tcldom.c $(top_builddir)/versionhash.h

#========================================================================
# Distribution creation
# You may need to tweak this target to make it work correctly.
#========================================================================

#COMPRESS	= tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
COMPRESS	= tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT	= /tmp/dist
DIST_DIR	= $(DIST_ROOT)/$(PKG_DIR)

dist-clean:
	rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*

dist: dist-clean
................................................................................
#========================================================================

#========================================================================
# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
# variable in configure.in
#========================================================================

clean:
	-test -z "$(BINARIES)" || rm -f $(BINARIES)
	-rm -f *.$(OBJEXT) core *.core
	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)

distclean: clean
	-rm -f *.tab.c
	-rm -f $(CONFIG_CLEAN_FILES)
................................................................................
# In addition, this will generate the pkgIndex.tcl
# file in the install location (assuming it can find a usable tclsh shell)
#
# You should not have to modify this target.
#========================================================================

install-lib-binaries: binaries
	@$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir)
	@list='$(lib_BINARIES)'; for p in $$list; do \
	  if test -f $$p; then \



	    if test "x$$stub" = "xstub"; then \
		echo " $(RANLIB_STUB) $$p"; \
		$(RANLIB_STUB) $$p; \
	    else \
		echo " $(RANLIB) $$p"; \
		$(RANLIB) $$p; \
	    fi; \
	    echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
	    $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
	    stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
	    ext=`echo $$p|sed -e "s/.*\.//"`; \
	    if test "x$$ext" = "xdll"; then \
		lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
		if test -f $$lib; then \
		    echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
	            $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
		fi; \
	    fi; \
	  fi; \
	done
	@echo "Installing tdomConfig.sh to $(DESTDIR)$(libdir)/"
	@$(INSTALL_DATA) tdomConfig.sh "$(DESTDIR)$(libdir)/tdomConfig.sh"
	@list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
	  if test -f $(srcdir)/$$p; then \
	    destp=`basename $$p`; \
	    echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
	    $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
	  fi; \
	done
	@if test "x$(SHARED_BUILD)" = "x1"; then \
	    echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
	    $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
	fi


#========================================================================
# Install binary executables (e.g. .exe files and dependent .dll files)
# This is for files that must go in the bin directory (located next to
# wish and tclsh), like dependent .dll files on Windows.
#
# You should not have to modify this target, except to define bin_BINARIES
# above if necessary.
#========================================================================

install-bin-binaries: binaries
	@$(INSTALL_DATA_DIR) $(DESTDIR)$(bindir)
	@list='$(bin_BINARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
	  fi; \
	done



Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
	cd $(top_builddir) \
	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status

uninstall-binaries:
	list='$(lib_BINARIES)'; for p in $$list; do \
	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \

Changes to README.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

22
23
24
25
26

27
28
29
30
31
32
33

34
35
36
37
38
39
40

41
42
43

44
45







46
47
48

49
50




























51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75


76
77
78
79
80
81
82
83
84
85

86



87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113






              tDOM - a XML/DOM/XPath/XSLT implementation for Tcl
                          (Version 0.8.3)

		    Jochen Loewer (loewerj@hotmail.com)
                       Rolf Ade (rolf@pointsman.de)

                       with some contributions by:

                 Zoran Vasiljevic (zv@archiware.com)
                

This directory contains a freely distributable (under the Mozilla Public 
License) thread-safe extension to Tcl/Tk called tDOM.


tDOM contains:

    *  the newest version of Expat, the XML parser from James Clark,
       including namespace and DTD support.


    *  a modified version of Steve Ball's Tclexpat, the Tcl interface to 
       expat, for event-like (SAX-like) XML parsing. The modifications
       are for performance improvements, to make the newest Expat
       features (XML namespace) available and for some additional features.


    *  a (partial) DOM I and II implementation in C for maximum
       performance and minimum memory need following the W3C DOM Core
       Level 1 recommendation using a OO-like syntax.

    *  a very complete, compliant and fast XPath implementation in C
       following the November 99 W3C recommendation.


    *  a fast XSLT implementation in C following the W3C Recommendation
       16 November 1999.
    
    *  a (partial) implementation in C of the XPointer (97) navigational 
       functions.


    *  UTF-8 to 8 bit encoding back conversion functionality to support
       Tcl version < 8.1x


    *  optional DTD validation   








    *  additional convenience methods
 
    *  documentation in TMML, HTML and nroff format































COMPILING/USING tDOM

    Depending on your platform, (unix or win) go to the corresponding
    directory and invoke the configure script:

        ../configure
        make 
        make test
        make install

    Alternatively, you can build the tDOM package in just about any
    directory elsewhere on the fileystem (since TEA-compatible).
    
    NOTE: Be sure to have the CC=gcc defined if you're using GCC.

    You might also want to do "../configure --help" to get list of all
    supported options of the configure script. In the "unix" directory
    there is a "CONFIG" file containing some examples on how to invoke
    the "configure" script for some common cases. You can peek
    there. This file also includes a short description of the tDOM
    specific configure options.

    Since tDOM is TEA-compatible you should be able to build it using
    the MinGW build environment for Windows. There is also the MSVC
    nmake file so you can compile the package with Microsoft tools.



    The compile process will build the tDOM shared library suitable for
    loading into the Tcl shell using standard "package require" mechanism.
    Optionally the make process can also generate the "tcldomsh" 
    executable shell with tDOM functionality built-in. You can use this
    shell as any other Tcl shell. To do this, you have to:

        make tcldomsh

    Note, however, that this step is optional.






    Note for Tcl 8.0.5 users:
    -------------------------

    Per default, this release of tDOM links against Tcl stubs
    library. To build it against Tcl8.0.5, use the configure-tcl8.0.5
    script to generate the Makefile.


    If you want to recreate the configure script for building against
    Tcl8.0.5 please edit the "configure.in" file in this directory,
    comment-out the AC_DEFINE(USE_TCL_STUBS) directive and run
    autoconf. Please be sure to use autoconf with version 2.59.


PLATFORMS
    HP-UX-10.20                  (both ansi cc and gcc)
    HP-UX-9.x
    Linux 2.2.5                  (egcs 2.91.66, SuSE 6.1)
    Solaris 2.5.1+               (both gcc and SunWorks compilers)
    W2K                          (VC++ 6.0)
    Mac OS X 10.2.6              (Apple's gcc)

    Other machines and OS's are not tested but should work too. 

Have fun! 

- EOF -






|
|

<
<

<
<
<
<
<
|
|
<



|
|
>

<
|
|
|
>

<
|
<

|
|
>




|
<

>
|
<

>
|

>
>
>
>
>
>
>
|

<
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

|
|









<
<
|
|
|
|
|
|




>
>



<
<
<

<

<
>

>
>
>

<
<

<
<
<
>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>
>
>
1
2
3
4
5


6





7
8

9
10
11
12
13
14
15

16
17
18
19
20

21

22
23
24
25
26
27
28
29
30

31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105



106

107

108
109
110
111
112
113


114



115
116



















117
118
119
120


    tDOM - a XML/DOM/XPath/XSLT/HTML/JSON implementation for Tcl
                          (Version 0.9.1)









This directory contains a freely distributable thread-safe extension
to Tcl/Tk called tDOM.


tDOM contains:

    *  for convenience expat 2.2.5, the XML parser originated from
       James Clark, although you're able to link tDOM with other
       expat versions or the library provided by the system.


    *  building a DOM tree from XML in one go implemented in C for
       maximum performance and minimum memory usage, and DOM I and II
       methods to work on such a tree using either a OO-like or a
       handle syntax.


    *  a Tcl interface to expat for event-like (SAX-like) XML parsing.


    *  a complete, compliant and fast XPath implementation in C
       following the November 99 W3C recommendation for navigating and
       data extraction.

    *  a fast XSLT implementation in C following the W3C Recommendation
       16 November 1999.
    
    *  optional DTD validation.


    *  a JSON parser which parses any possible JSON input into a DOM
       tree without losing information.


    *  an efficient and Tcl'ish way to create XML and HTML documents
       and JSON string.

    *  as build option an interface to the gumbo HTML5 parser, which
       also digests almost any other HTML.

    *  an even faster simple XML parser for trusted XML input.

    *  A slim Tcl interface to use expat as pull-parser.

    *  additional convenience methods.
 

    *  and more.


DOCUMENTATION

    The documentation is included into the source distribution in HTML
    and man format. Alternatively, read it online starting at
    http://tdom.org/index.html/doc/trunk/doc/index.html


GETTING THE CODE

    The development repository is hosted at http://tdom.org and is
    mirrored at http://core.tcl.tk/tdom. You are encouraged to use
    trunk.

    If you insist on using an older tDOM with lesser features and
    probably more bugs, you should use the latest release 0.9.1. Get
    the source code release from
    http://tdom.org/downloads/tdom-0.9.1-src.tgz or
    http://tdom.org/downloads/tdom-0.9.1-src.zip

    Windows binaries (32 bit as well as 64 bit) of the 0.9.1 release
    are also available. Get it from
    http://tdom.org/downloads/tdom-0.9.1-windows-x64.zip and 
    http://tdom.org/downloads/tdom-0.9.1-windows-x86.zip
    
    The provided windows binaries include (statically linked) the
    HTML5 parser.


COMPILING tDOM

    Depending on your platform (unix/mac or win), go to the
    corresponding directory and invoke the configure script:

        ../configure
        make 
        make test
        make install

    Alternatively, you can build the tDOM package in just about any
    directory elsewhere on the fileystem (since TEA-compatible).
    


    You might also want to do "../configure --help" to get a list of
    all supported options of the configure script. In the "unix"
    directory there is a "CONFIG" file containing some examples on how
    to invoke the "configure" script for some common cases. You can
    peek there. This file also includes a short description of the
    tDOM specific configure options.

    Since tDOM is TEA-compatible you should be able to build it using
    the MinGW build environment for Windows. There is also the MSVC
    nmake file so you can compile the package with Microsoft tools.
    Refer to the README in the win directory for more details about
    building on Windows.

    The compile process will build the tDOM shared library suitable for
    loading into the Tcl shell using standard "package require" mechanism.







REPORTING BUGS

    Please head to http://tdom.org/index.html/ticket and click on "New
    Ticket". Log in as anonymous and report your findings. If you
    prefer to have an individual login write Rolf a mail.







HISTORY




















    tDOM was started by Jochen Loewer (loewerj@hotmail.com) and
    developed by Jochen and Rolf Ade (rolf@pointsman.de) with
    contributions by Zoran Vasiljevic (zv@archiware.com). Since more
    than a dozen years it is maintained and developed by Rolf Ade.

Changes to README.AOL.

1
2
3
4
5
6
7
8
9
10
11


              tDOM - a XML/DOM/XPath/XSLT implementation for Tcl
                          (Version 0.8.3)

		    Jochen Loewer (loewerj@hotmail.com)
                       Rolf Ade (rolf@pointsman.de)

                       with some contributions by:

                 Zoran Vasiljevic (zv@archiware.com)



|







1
2
3
4
5
6
7
8
9
10
11


              tDOM - a XML/DOM/XPath/XSLT implementation for Tcl
                          (Version 0.9.1)

		    Jochen Loewer (loewerj@hotmail.com)
                       Rolf Ade (rolf@pointsman.de)

                       with some contributions by:

                 Zoran Vasiljevic (zv@archiware.com)

Changes to apps/xslt.tcl.

113
114
115
116
117
118
119


        puts [$resultDoc asText]
    }
    default {
        puts stderr "Unknown output method '$outputOpt'!"
        exit 1
    }
}









>
>
113
114
115
116
117
118
119
120
121
        puts [$resultDoc asText]
    }
    default {
        puts stderr "Unknown output method '$outputOpt'!"
        exit 1
    }
}

proc exit args {}

Changes to configure.

more than 10,000 changes

Deleted configure-tcl8.0.5.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
#! /bin/sh

# Guess values for system-dependent variables and create Makefiles.
# Generated automatically using autoconf version 2.13 
# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.

# Defaults:
ac_help=
ac_default_prefix=/usr/local
# Any additions from configure.in:
ac_help="$ac_help
  --with-tcl              directory containing tcl configuration (tclConfig.sh)"
ac_help="$ac_help
  --with-tclinclude      directory containing the public Tcl header files"
ac_help="$ac_help
  --enable-threads        build with threads"
ac_help="$ac_help
  --enable-shared         build and link with shared libraries [--enable-shared]"
ac_help="$ac_help
  --enable-64bit          enable 64bit support (where applicable)"
ac_help="$ac_help
  --enable-64bit-vis      enable 64bit Sparc VIS support"
ac_help="$ac_help
  --disable-load          disallow dynamic loading and "load" command"
ac_help="$ac_help
  --enable-symbols        build with debugging symbols [--disable-symbols]"
ac_help="$ac_help
  --with-aolserver        directory with AOLserver distribution"
ac_help="$ac_help
  --enable-dtd            build with the dtd support [--enable-dtd]"
ac_help="$ac_help
  --enable-ns             build with the namespace support [--enable-ns]"
ac_help="$ac_help
  --enable-unknown        enable built-in unknown command [--disable-unknown]"
ac_help="$ac_help
  --enable-tdomalloc      build with the tDOM allocator [--enable-tdomalloc]"

# Initialize some variables set by options.
# The variables have the same names as the options, with
# dashes changed to underlines.
build=NONE
cache_file=./config.cache
exec_prefix=NONE
host=NONE
no_create=
nonopt=NONE
no_recursion=
prefix=NONE
program_prefix=NONE
program_suffix=NONE
program_transform_name=s,x,x,
silent=
site=
srcdir=
target=NONE
verbose=
x_includes=NONE
x_libraries=NONE
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datadir='${prefix}/share'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'
infodir='${prefix}/info'
mandir='${prefix}/man'

# Initialize some other variables.
subdirs=
MFLAGS= MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}
# Maximum number of lines to put in a shell here document.
ac_max_here_lines=12

ac_prev=
for ac_option
do

  # If the previous option needs an argument, assign it.
  if test -n "$ac_prev"; then
    eval "$ac_prev=\$ac_option"
    ac_prev=
    continue
  fi

  case "$ac_option" in
  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
  *) ac_optarg= ;;
  esac

  # Accept the important Cygnus configure options, so we can diagnose typos.

  case "$ac_option" in

  -bindir | --bindir | --bindi | --bind | --bin | --bi)
    ac_prev=bindir ;;
  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
    bindir="$ac_optarg" ;;

  -build | --build | --buil | --bui | --bu)
    ac_prev=build ;;
  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
    build="$ac_optarg" ;;

  -cache-file | --cache-file | --cache-fil | --cache-fi \
  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
    ac_prev=cache_file ;;
  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
    cache_file="$ac_optarg" ;;

  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
    ac_prev=datadir ;;
  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
  | --da=*)
    datadir="$ac_optarg" ;;

  -disable-* | --disable-*)
    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
    # Reject names that are not valid shell variable names.
    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
    fi
    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
    eval "enable_${ac_feature}=no" ;;

  -enable-* | --enable-*)
    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
    # Reject names that are not valid shell variable names.
    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
    fi
    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
    case "$ac_option" in
      *=*) ;;
      *) ac_optarg=yes ;;
    esac
    eval "enable_${ac_feature}='$ac_optarg'" ;;

  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
  | --exec | --exe | --ex)
    ac_prev=exec_prefix ;;
  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
  | --exec=* | --exe=* | --ex=*)
    exec_prefix="$ac_optarg" ;;

  -gas | --gas | --ga | --g)
    # Obsolete; use --with-gas.
    with_gas=yes ;;

  -help | --help | --hel | --he)
    # Omit some internal or obsolete options to make the list less imposing.
    # This message is too long to be a string in the A/UX 3.1 sh.
    cat << EOF
Usage: configure [options] [host]
Options: [defaults in brackets after descriptions]
Configuration:
  --cache-file=FILE       cache test results in FILE
  --help                  print this message
  --no-create             do not create output files
  --quiet, --silent       do not print \`checking...' messages
  --version               print the version of autoconf that created configure
Directory and file names:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [$ac_default_prefix]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [same as prefix]
  --bindir=DIR            user executables in DIR [EPREFIX/bin]
  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
  --datadir=DIR           read-only architecture-independent data in DIR
                          [PREFIX/share]
  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
                          [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
  --includedir=DIR        C header files in DIR [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
  --infodir=DIR           info documentation in DIR [PREFIX/info]
  --mandir=DIR            man documentation in DIR [PREFIX/man]
  --srcdir=DIR            find the sources in DIR [configure dir or ..]
  --program-prefix=PREFIX prepend PREFIX to installed program names
  --program-suffix=SUFFIX append SUFFIX to installed program names
  --program-transform-name=PROGRAM
                          run sed PROGRAM on installed program names
EOF
    cat << EOF
Host type:
  --build=BUILD           configure for building on BUILD [BUILD=HOST]
  --host=HOST             configure for HOST [guessed]
  --target=TARGET         configure for TARGET [TARGET=HOST]
Features and packages:
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --x-includes=DIR        X include files are in DIR
  --x-libraries=DIR       X library files are in DIR
EOF
    if test -n "$ac_help"; then
      echo "--enable and --with options recognized:$ac_help"
    fi
    exit 0 ;;

  -host | --host | --hos | --ho)
    ac_prev=host ;;
  -host=* | --host=* | --hos=* | --ho=*)
    host="$ac_optarg" ;;

  -includedir | --includedir | --includedi | --included | --include \
  | --includ | --inclu | --incl | --inc)
    ac_prev=includedir ;;
  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
  | --includ=* | --inclu=* | --incl=* | --inc=*)
    includedir="$ac_optarg" ;;

  -infodir | --infodir | --infodi | --infod | --info | --inf)
    ac_prev=infodir ;;
  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
    infodir="$ac_optarg" ;;

  -libdir | --libdir | --libdi | --libd)
    ac_prev=libdir ;;
  -libdir=* | --libdir=* | --libdi=* | --libd=*)
    libdir="$ac_optarg" ;;

  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
  | --libexe | --libex | --libe)
    ac_prev=libexecdir ;;
  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
  | --libexe=* | --libex=* | --libe=*)
    libexecdir="$ac_optarg" ;;

  -localstatedir | --localstatedir | --localstatedi | --localstated \
  | --localstate | --localstat | --localsta | --localst \
  | --locals | --local | --loca | --loc | --lo)
    ac_prev=localstatedir ;;
  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
    localstatedir="$ac_optarg" ;;

  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
    ac_prev=mandir ;;
  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
    mandir="$ac_optarg" ;;

  -nfp | --nfp | --nf)
    # Obsolete; use --without-fp.
    with_fp=no ;;

  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
  | --no-cr | --no-c)
    no_create=yes ;;

  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
    no_recursion=yes ;;

  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
  | --oldin | --oldi | --old | --ol | --o)
    ac_prev=oldincludedir ;;
  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
    oldincludedir="$ac_optarg" ;;

  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
    ac_prev=prefix ;;
  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
    prefix="$ac_optarg" ;;

  -program-prefix | --program-prefix | --program-prefi | --program-pref \
  | --program-pre | --program-pr | --program-p)
    ac_prev=program_prefix ;;
  -program-prefix=* | --program-prefix=* | --program-prefi=* \
  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
    program_prefix="$ac_optarg" ;;

  -program-suffix | --program-suffix | --program-suffi | --program-suff \
  | --program-suf | --program-su | --program-s)
    ac_prev=program_suffix ;;
  -program-suffix=* | --program-suffix=* | --program-suffi=* \
  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
    program_suffix="$ac_optarg" ;;

  -program-transform-name | --program-transform-name \
  | --program-transform-nam | --program-transform-na \
  | --program-transform-n | --program-transform- \
  | --program-transform | --program-transfor \
  | --program-transfo | --program-transf \
  | --program-trans | --program-tran \
  | --progr-tra | --program-tr | --program-t)
    ac_prev=program_transform_name ;;
  -program-transform-name=* | --program-transform-name=* \
  | --program-transform-nam=* | --program-transform-na=* \
  | --program-transform-n=* | --program-transform-=* \
  | --program-transform=* | --program-transfor=* \
  | --program-transfo=* | --program-transf=* \
  | --program-trans=* | --program-tran=* \
  | --progr-tra=* | --program-tr=* | --program-t=*)
    program_transform_name="$ac_optarg" ;;

  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil)
    silent=yes ;;

  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
    ac_prev=sbindir ;;
  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
  | --sbi=* | --sb=*)
    sbindir="$ac_optarg" ;;

  -sharedstatedir | --sharedstatedir | --sharedstatedi \
  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
  | --sharedst | --shareds | --shared | --share | --shar \
  | --sha | --sh)
    ac_prev=sharedstatedir ;;
  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
  | --sha=* | --sh=*)
    sharedstatedir="$ac_optarg" ;;

  -site | --site | --sit)
    ac_prev=site ;;
  -site=* | --site=* | --sit=*)
    site="$ac_optarg" ;;

  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
    ac_prev=srcdir ;;
  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
    srcdir="$ac_optarg" ;;

  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
  | --syscon | --sysco | --sysc | --sys | --sy)
    ac_prev=sysconfdir ;;
  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
    sysconfdir="$ac_optarg" ;;

  -target | --target | --targe | --targ | --tar | --ta | --t)
    ac_prev=target ;;
  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
    target="$ac_optarg" ;;

  -v | -verbose | --verbose | --verbos | --verbo | --verb)
    verbose=yes ;;

  -version | --version | --versio | --versi | --vers)
    echo "configure generated by autoconf version 2.13"
    exit 0 ;;

  -with-* | --with-*)
    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
    # Reject names that are not valid shell variable names.
    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
    fi
    ac_package=`echo $ac_package| sed 's/-/_/g'`
    case "$ac_option" in
      *=*) ;;
      *) ac_optarg=yes ;;
    esac
    eval "with_${ac_package}='$ac_optarg'" ;;

  -without-* | --without-*)
    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
    # Reject names that are not valid shell variable names.
    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
    fi
    ac_package=`echo $ac_package| sed 's/-/_/g'`
    eval "with_${ac_package}=no" ;;

  --x)
    # Obsolete; use --with-x.
    with_x=yes ;;

  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
  | --x-incl | --x-inc | --x-in | --x-i)
    ac_prev=x_includes ;;
  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
    x_includes="$ac_optarg" ;;

  -x-libraries | --x-libraries | --x-librarie | --x-librari \
  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
    ac_prev=x_libraries ;;
  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
    x_libraries="$ac_optarg" ;;

  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
    ;;

  *)
    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
      echo "configure: warning: $ac_option: invalid host type" 1>&2
    fi
    if test "x$nonopt" != xNONE; then
      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
    fi
    nonopt="$ac_option"
    ;;

  esac
done

if test -n "$ac_prev"; then
  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
fi

trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15

# File descriptor usage:
# 0 standard input
# 1 file creation
# 2 errors and warnings
# 3 some systems may open it to /dev/tty
# 4 used on the Kubota Titan
# 6 checking for... messages and results
# 5 compiler messages saved in config.log
if test "$silent" = yes; then
  exec 6>/dev/null
else
  exec 6>&1
fi
exec 5>./config.log

echo "\
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
" 1>&5

# Strip out --no-create and --no-recursion so they do not pile up.
# Also quote any args containing shell metacharacters.
ac_configure_args=
for ac_arg
do
  case "$ac_arg" in
  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
  | --no-cr | --no-c) ;;
  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
  esac
done

# NLS nuisances.
# Only set these to C if already set.  These must not be set unconditionally
# because not all systems understand e.g. LANG=C (notably SCO).
# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
# Non-C LC_CTYPE values break the ctype check.
if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi

# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
# AIX cpp loses on an empty file, so make sure it contains at least a newline.
echo > confdefs.h

# A filename unique to this package, relative to the directory that
# configure is in, which we can look for to find out if srcdir is correct.
ac_unique_file=generic/tcldom.c

# Find the source files, if location was not specified.
if test -z "$srcdir"; then
  ac_srcdir_defaulted=yes
  # Try the directory containing this script, then its parent.
  ac_prog=$0
  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
  srcdir=$ac_confdir
  if test ! -r $srcdir/$ac_unique_file; then
    srcdir=..
  fi
else
  ac_srcdir_defaulted=no
fi
if test ! -r $srcdir/$ac_unique_file; then
  if test "$ac_srcdir_defaulted" = yes; then
    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
  else
    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
  fi
fi
srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`

# Prefer explicitly selected file to automatically selected ones.
if test -z "$CONFIG_SITE"; then
  if test "x$prefix" != xNONE; then
    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
  else
    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
  fi
fi
for ac_site_file in $CONFIG_SITE; do
  if test -r "$ac_site_file"; then
    echo "loading site script $ac_site_file"
    . "$ac_site_file"
  fi
done

if test -r "$cache_file"; then
  echo "loading cache $cache_file"
  . $cache_file
else
  echo "creating cache $cache_file"
  > $cache_file
fi

ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross

ac_exeext=
ac_objext=o
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
    ac_n= ac_c='
' ac_t='	'
  else
    ac_n=-n ac_c= ac_t=
  fi
else
  ac_n= ac_c='\c' ac_t=
fi



#-----------------------------------------------------------------------
# Be sure we're invoked from the platform directory.
#-----------------------------------------------------------------------

if test ${srcdir} = "." ; then
    echo ""
    echo "Please cd to the platform-specific dir (unix or win) and invoke:"
    echo "  ../configure"
    echo ""
    exit 1
fi

#-----------------------------------------------------------------------
# These are needed for the expat compilation. Do this early so we
# do not step over some CFLAGS which will confuse the compiler.
#-----------------------------------------------------------------------

for ac_func in memmove bcopy
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:572: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  cat > conftest.$ac_ext <<EOF
#line 577 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
    which can conflict with char $ac_func(); below.  */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error.  */
/* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
char $ac_func();

int main() {

/* The GNU C library defines this for functions which it implements
    to always fail with ENOSYS.  Some functions are actually named
    something starting with __ and the normal name is an alias.  */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
$ac_func();
#endif

; return 0; }
EOF
if { (eval echo configure:600: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  rm -rf conftest*
  eval "ac_cv_func_$ac_func=yes"
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
fi

if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
  echo "$ac_t""yes" 1>&6
    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
  cat >> confdefs.h <<EOF
#define $ac_tr_func 1
EOF
 
else
  echo "$ac_t""no" 1>&6
fi
done


#-----------------------------------------------------------------------
# Where is the tcl.m4 and brothers?
#-----------------------------------------------------------------------

ac_aux_dir=
for ac_dir in tclconfig $srcdir/tclconfig; do
  if test -f $ac_dir/install-sh; then
    ac_aux_dir=$ac_dir
    ac_install_sh="$ac_aux_dir/install-sh -c"
    break
  elif test -f $ac_dir/install.sh; then
    ac_aux_dir=$ac_dir
    ac_install_sh="$ac_aux_dir/install.sh -c"
    break
  fi
done
if test -z "$ac_aux_dir"; then
  { echo "configure: error: can not find install-sh or install.sh in tclconfig $srcdir/tclconfig" 1>&2; exit 1; }
fi
ac_config_guess=$ac_aux_dir/config.guess
ac_config_sub=$ac_aux_dir/config.sub
ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.

CONFIGDIR=${srcdir}/tclconfig


#----------------------------------------------------------------------
# __CHANGE__
# Set your package name and version numbers here. The NODOT_VERSION is
# required for constructing the library name on systems that don't like
# dots in library names (Windows). The VERSION variable is used on the
# other systems. Note that we substitute the VERSIN later down, after
# we have initialized TEA so we know which platform we're dealing with.
#----------------------------------------------------------------------

PACKAGE=tdom


TDOMSHELL=tcldomsh


MAJOR_VERSION=0


MINOR_VERSION=8


PATCHLEVEL=3

# This package name must be replaced statically for AC_SUBST to work


# Substitute stub_LIB_FILE if your package creates a stub library too.


#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows".
#--------------------------------------------------------------------


    echo $ac_n "checking for correct TEA configuration""... $ac_c" 1>&6
echo "configure:688: checking for correct TEA configuration" >&5
    if test x"${PACKAGE}" = x ; then
	{ echo "configure: error: 
The PACKAGE variable must be defined by your TEA configure.in" 1>&2; exit 1; }
    fi
    echo "$ac_t""ok" 1>&6
    TEA_INITED=ok
    case "`uname -s`" in
	*win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_98*|*CYGWIN_95*|*CYGWIN_ME*|*MINGW32_*)
	    # Extract the first word of "cygpath", so it can be a program name with args.
set dummy cygpath; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:700: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CYGPATH'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$CYGPATH"; then
  ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
  ac_dummy="$PATH"
  for ac_dir in $ac_dummy; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_CYGPATH="cygpath -w"
      break
    fi
  done
  IFS="$ac_save_ifs"
  test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo"
fi
fi
CYGPATH="$ac_cv_prog_CYGPATH"
if test -n "$CYGPATH"; then
  echo "$ac_t""$CYGPATH" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

	    EXEEXT=".exe"
	    TEA_PLATFORM="windows"
	    ;;
	*)
	    CYGPATH=echo
	    EXEEXT=""
	    TEA_PLATFORM="unix"
	    ;;
    esac

    
    


#--------------------------------------------------------------------
# Load the tclConfig.sh file
#--------------------------------------------------------------------


    if test x"${TEA_INITED}" = x ; then
	# Can't refer to exact macro name or it will be substituted
	{ echo "configure: error: Must call TEA INIT before PATH_TCLCONFIG" 1>&2; exit 1; }
    fi
    #
    # Ok, lets find the tcl configuration
    # First, look for one uninstalled.
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true
	# Check whether --with-tcl or --without-tcl was given.
if test "${with_tcl+set}" = set; then
  withval="$with_tcl"
  with_tclconfig=${withval}
fi

	echo $ac_n "checking for Tcl configuration""... $ac_c" 1>&6
echo "configure:766: checking for Tcl configuration" >&5
	if eval "test \"`echo '$''{'ac_cv_c_tclconfig'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  

	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		if test -f "${with_tclconfig}/tclConfig.sh" ; then
		    ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
		else
		    { echo "configure: error: ${with_tclconfig} directory doesn't contain tclConfig.sh" 1>&2; exit 1; }
		fi
	    fi

	    # then check for a private Tcl installation
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in \
			../tcl \
			`ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \
			../../tcl \
			`ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \
			../../../tcl \
			`ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do
		    if test -f "$i/unix/tclConfig.sh" ; then
			ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
			break
		    fi
		done
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig=`(cd $i; pwd)`
			break
		    fi
		done
	    fi

	    # check in a few other private locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in \
			${srcdir}/../tcl \
			`ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do
		    if test -f "$i/unix/tclConfig.sh" ; then
		    ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
		    break
		fi
		done
	    fi
	
fi


	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    echo "configure: warning: "Cannot find Tcl configuration definitions"" 1>&2
	    exit 0
	else
	    no_tcl=
	    TCL_BIN_DIR=${ac_cv_c_tclconfig}
	    echo "$ac_t""found $TCL_BIN_DIR/tclConfig.sh" 1>&6
	fi
    fi


    echo $ac_n "checking for existence of $TCL_BIN_DIR/tclConfig.sh""... $ac_c" 1>&6
echo "configure:839: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5

    if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then
        echo "$ac_t""loading" 1>&6
	. $TCL_BIN_DIR/tclConfig.sh
    else
        echo "$ac_t""file not found" 1>&6
    fi

    #
    # If the TCL_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TCL_LIB_SPEC will be set to the value
    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.
    #

    if test -f $TCL_BIN_DIR/Makefile ; then
        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
    fi

    #
    # eval is required to do the TCL_DBGX substitution
    #

    eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""

    eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\""
    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""

    
    
    

    
    
    

    
    
    

    #AC_SUBST(TCL_DBGX)
    
    
    
    
    
    #AC_SUBST(TCL_BUILD_LIB_SPEC)
    #AC_SUBST(TCL_BUILD_STUB_LIB_SPEC)


#--------------------------------------------------------------------
# Load the tkConfig.sh file if necessary (Tk extension)
#--------------------------------------------------------------------

#TEA_PATH_TKCONFIG
#TEA_LOAD_TKCONFIG

#-----------------------------------------------------------------------
# Handle the --prefix=... option by defaulting to what Tcl gave.
# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
#-----------------------------------------------------------------------


    # Should be AC_MSG_NOTICE, but that requires autoconf 2.50
    if test "${prefix}" = "NONE"; then
	prefix_default=yes
	if test x"${TCL_PREFIX}" != x; then
	    echo "configure: warning: --prefix defaulting to TCL_PREFIX ${TCL_PREFIX}" 1>&2
	    prefix=${TCL_PREFIX}
	else
	    prefix=/usr/local
	fi
    fi
    if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" ; then
	if test x"${TCL_EXEC_PREFIX}" != x; then
	    echo "configure: warning: --exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}" 1>&2
	    exec_prefix=${TCL_EXEC_PREFIX}
	else
	    exec_prefix=$prefix
	fi
    fi


#-----------------------------------------------------------------------
# Standard compiler checks.
# This sets up CC by using the CC env var, or looks for gcc otherwise.
# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
# the basic setup necessary to compile executables.
#-----------------------------------------------------------------------

echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
echo "configure:938: checking for Cygwin environment" >&5
if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  cat > conftest.$ac_ext <<EOF
#line 943 "configure"
#include "confdefs.h"

int main() {

#ifndef __CYGWIN__
#define __CYGWIN__ __CYGWIN32__
#endif
return __CYGWIN__;
; return 0; }
EOF
if { (eval echo configure:954: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  rm -rf conftest*
  ac_cv_cygwin=yes
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  ac_cv_cygwin=no
fi
rm -f conftest*
rm -f conftest*
fi

echo "$ac_t""$ac_cv_cygwin" 1>&6
CYGWIN=
test "$ac_cv_cygwin" = yes && CYGWIN=yes
echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
echo "configure:971: checking for mingw32 environment" >&5
if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  cat > conftest.$ac_ext <<EOF
#line 976 "configure"
#include "confdefs.h"

int main() {
return __MINGW32__;
; return 0; }
EOF
if { (eval echo configure:983: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  rm -rf conftest*
  ac_cv_mingw32=yes
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  ac_cv_mingw32=no
fi
rm -f conftest*
rm -f conftest*
fi

echo "$ac_t""$ac_cv_mingw32" 1>&6
MINGW32=
test "$ac_cv_mingw32" = yes && MINGW32=yes

    # If the user did not set CFLAGS, set it now to keep
    # the AC_PROG_CC macro from adding "-g -O2".
    if test "${CFLAGS+set}" != "set" ; then
	CFLAGS=""
    fi

    # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1009: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
  ac_dummy="$PATH"
  for ac_dir in $ac_dummy; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_CC="gcc"
      break
    fi
  done
  IFS="$ac_save_ifs"
fi
fi
CC="$ac_cv_prog_CC"
if test -n "$CC"; then
  echo "$ac_t""$CC" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

if test -z "$CC"; then
  # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1039: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
  ac_prog_rejected=no
  ac_dummy="$PATH"
  for ac_dir in $ac_dummy; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
        ac_prog_rejected=yes
	continue
      fi
      ac_cv_prog_CC="cc"
      break
    fi
  done
  IFS="$ac_save_ifs"
if test $ac_prog_rejected = yes; then
  # We found a bogon in the path, so make sure we never use it.
  set dummy $ac_cv_prog_CC
  shift
  if test $# -gt 0; then
    # We chose a different compiler from the bogus one.
    # However, it has the same basename, so the bogon will be chosen
    # first if we set CC to just the basename; use the full file name.
    shift
    set dummy "$ac_dir/$ac_word" "$@"
    shift
    ac_cv_prog_CC="$@"
  fi
fi
fi
fi
CC="$ac_cv_prog_CC"
if test -n "$CC"; then
  echo "$ac_t""$CC" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

  if test -z "$CC"; then
    case "`uname -s`" in
    *win32* | *WIN32*)
      # Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1090: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$CC"; then
  ac_cv_prog_CC="$CC" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
  ac_dummy="$PATH"
  for ac_dir in $ac_dummy; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_CC="cl"
      break
    fi
  done
  IFS="$ac_save_ifs"
fi
fi
CC="$ac_cv_prog_CC"
if test -n "$CC"; then
  echo "$ac_t""$CC" 1>&6
else
  echo "$ac_t""no" 1>&6
fi
 ;;
    esac
  fi
  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
fi

echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
echo "configure:1122: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5

ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross

cat > conftest.$ac_ext << EOF

#line 1133 "configure"
#include "confdefs.h"

main(){return(0);}
EOF
if { (eval echo configure:1138: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  ac_cv_prog_cc_works=yes
  # If we can't run a trivial program, we are probably using a cross compiler.
  if (./conftest; exit) 2>/dev/null; then
    ac_cv_prog_cc_cross=no
  else
    ac_cv_prog_cc_cross=yes
  fi
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  ac_cv_prog_cc_works=no
fi
rm -fr conftest*
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross

echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
if test $ac_cv_prog_cc_works = no; then
  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
echo "configure:1164: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross

echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
echo "configure:1169: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  cat > conftest.c <<EOF
#ifdef __GNUC__
  yes;
#endif
EOF
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1178: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
  ac_cv_prog_gcc=yes
else
  ac_cv_prog_gcc=no
fi
fi

echo "$ac_t""$ac_cv_prog_gcc" 1>&6

if test $ac_cv_prog_gcc = yes; then
  GCC=yes
else
  GCC=
fi

ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
echo "configure:1197: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  echo 'void f(){}' > conftest.c
if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
  ac_cv_prog_cc_g=yes
else
  ac_cv_prog_cc_g=no
fi
rm -f conftest*

fi

echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
if test "$ac_test_CFLAGS" = set; then
  CFLAGS="$ac_save_CFLAGS"
elif test $ac_cv_prog_cc_g = yes; then
  if test "$GCC" = yes; then
    CFLAGS="-g -O2"
  else
    CFLAGS="-g"
  fi
else
  if test "$GCC" = yes; then
    CFLAGS="-O2"
  else
    CFLAGS=
  fi
fi


    #------------------------------------------------------------------------
    # If we're using GCC, see if the compiler understands -pipe. If so, use it.
    # It makes compiling go faster.  (This is only a performance feature.)
    #------------------------------------------------------------------------

    if test -z "$no_pipe" -a -n "$GCC"; then
	echo $ac_n "checking if the compiler understands -pipe""... $ac_c" 1>&6
echo "configure:1236: checking if the compiler understands -pipe" >&5
	OLDCC="$CC"
	CC="$CC -pipe"
	cat > conftest.$ac_ext <<EOF
#line 1240 "configure"
#include "confdefs.h"

int main() {

; return 0; }
EOF
if { (eval echo configure:1247: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  rm -rf conftest*
  echo "$ac_t""yes" 1>&6
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  CC="$OLDCC"
	    echo "$ac_t""no" 1>&6
fi
rm -f conftest*
    fi

    # Find a good install program.  We prefer a C program (faster),
# so one script is as good as another.  But avoid the broken or
# incompatible versions:
# SysV /etc/install, /usr/sbin/install
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install
# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:1272: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS=":"
  for ac_dir in $PATH; do
    # Account for people who put trailing slashes in PATH elements.
    case "$ac_dir/" in
    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
    *)
      # OSF1 and SCO ODT 3.0 have their own names for install.
      # Don't use installbsd from OSF since it installs stuff as root
      # by default.
      for ac_prog in ginstall scoinst install; do
        if test -f $ac_dir/$ac_prog; then
	  if test $ac_prog = install &&
            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
	    # AIX install.  It has an incompatible calling convention.
	    :
	  else
	    ac_cv_path_install="$ac_dir/$ac_prog -c"
	    break 2
	  fi
	fi
      done
      ;;
    esac
  done
  IFS="$ac_save_IFS"

fi
  if test "${ac_cv_path_install+set}" = set; then
    INSTALL="$ac_cv_path_install"
  else
    # As a last resort, use the slow shell script.  We don't cache a
    # path for INSTALL within a source directory, because that will
    # break other packages using the cache if that directory is
    # removed, or if the path is relative.
    INSTALL="$ac_install_sh"
  fi
fi
echo "$ac_t""$INSTALL" 1>&6

# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'

test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'

test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'


    #--------------------------------------------------------------------
    # Checks to see if the make program sets the $MAKE variable.
    #--------------------------------------------------------------------

    echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
echo "configure:1330: checking whether ${MAKE-make} sets \${MAKE}" >&5
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  cat > conftestmake <<\EOF
all:
	@echo 'ac_maketemp="${MAKE}"'
EOF
# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
if test -n "$ac_maketemp"; then
  eval ac_cv_prog_make_${ac_make}_set=yes
else
  eval ac_cv_prog_make_${ac_make}_set=no
fi
rm -f conftestmake
fi
if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  SET_MAKE=
else
  echo "$ac_t""no" 1>&6
  SET_MAKE="MAKE=${MAKE-make}"
fi


    #--------------------------------------------------------------------
    # Find ranlib
    #--------------------------------------------------------------------

    # Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1364: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$RANLIB"; then
  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
  ac_dummy="$PATH"
  for ac_dir in $ac_dummy; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_RANLIB="ranlib"
      break
    fi
  done
  IFS="$ac_save_ifs"
  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
fi
fi
RANLIB="$ac_cv_prog_RANLIB"
if test -n "$RANLIB"; then
  echo "$ac_t""$RANLIB" 1>&6
else
  echo "$ac_t""no" 1>&6
fi


    #--------------------------------------------------------------------
    # Determines the correct binary file extension (.o, .obj, .exe etc.)
    #--------------------------------------------------------------------

    echo $ac_n "checking for object suffix""... $ac_c" 1>&6
echo "configure:1397: checking for object suffix" >&5
if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  rm -f conftest*
echo 'int i = 1;' > conftest.$ac_ext
if { (eval echo configure:1403: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  for ac_file in conftest.*; do
    case $ac_file in
    *.c) ;;
    *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;;
    esac
  done
else
  { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; }
fi
rm -f conftest*
fi

echo "$ac_t""$ac_cv_objext" 1>&6
OBJEXT=$ac_cv_objext
ac_objext=$ac_cv_objext

    

echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
echo "configure:1423: checking for executable suffix" >&5
if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
  ac_cv_exeext=.exe
else
  rm -f conftest*
  echo 'int main () { return 0; }' > conftest.$ac_ext
  ac_cv_exeext=
  if { (eval echo configure:1433: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
    for file in conftest.*; do
      case $file in
      *.c | *.o | *.obj) ;;
      *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
      esac
    done
  else
    { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
  fi
  rm -f conftest*
  test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
fi
fi

EXEEXT=""
test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
echo "$ac_t""${ac_cv_exeext}" 1>&6
ac_exeext=$EXEEXT



#--------------------------------------------------------------------
# __CHANGE__
# Choose which headers you need.  Extension authors should try very
# hard to only rely on the Tcl public header files.  Internal headers
# contain private data structures and are subject to change without
# notice.
# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
#--------------------------------------------------------------------


    echo $ac_n "checking for Tcl public headers""... $ac_c" 1>&6
echo "configure:1466: checking for Tcl public headers" >&5

    # Check whether --with-tclinclude or --without-tclinclude was given.
if test "${with_tclinclude+set}" = set; then
  withval="$with_tclinclude"
  with_tclinclude=${withval}
fi


    if eval "test \"`echo '$''{'ac_cv_c_tclh'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  
	# Use the value from --with-tclinclude, if it was given

	if test x"${with_tclinclude}" != x ; then
	    if test -f "${with_tclinclude}/tcl.h" ; then
		ac_cv_c_tclh=${with_tclinclude}
	    else
		{ echo "configure: error: ${with_tclinclude} directory does not contain tcl.h" 1>&2; exit 1; }
	    fi
	else
	    # Check order: pkg --prefix location, Tcl's --prefix location,
	    # directory of tclConfig.sh, and Tcl source directory.
	    # Looking in the source dir is not ideal, but OK.

	    eval "temp_includedir=${includedir}"
	    list="`ls -d ${temp_includedir}      2>/dev/null` \
		`ls -d ${TCL_PREFIX}/include     2>/dev/null` \
		`ls -d ${TCL_BIN_DIR}/../include 2>/dev/null` \
		`ls -d ${TCL_SRC_DIR}/generic    2>/dev/null`"
	    if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
		list="$list /usr/local/include /usr/include"
	    fi
	    for i in $list ; do
		if test -f "$i/tcl.h" ; then
		    ac_cv_c_tclh=$i
		    break
		fi
	    done
	fi
    
fi


    # Print a message based on how we determined the include path

    if test x"${ac_cv_c_tclh}" = x ; then
	{ echo "configure: error: tcl.h not found.  Please specify its location with --with-tclinclude" 1>&2; exit 1; }
    else
	echo "$ac_t""${ac_cv_c_tclh}" 1>&6
    fi

    # Convert to a native path and substitute into the output files.

    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}`

    TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"

    

#TEA_PRIVATE_TCL_HEADERS

#TEA_PUBLIC_TK_HEADERS
#TEA_PRIVATE_TK_HEADERS

#--------------------------------------------------------------------
# __CHANGE__
# A few miscellaneous platform-specific items:
#
# Define a special symbol for Windows (BUILD_sample in this case) so
# that we create the export library with the dll.  See sha1.h on how
# to use this.
#
# Windows creates a few extra files that need to be cleaned up.
# You can add more files to clean if your extension creates any extra
# files.
#
# Define any extra compiler flags in the PACKAGE_CFLAGS variable.
# These will be appended to the current set of compiler flags for
# your system.
#--------------------------------------------------------------------

if test "${TEA_PLATFORM}" = "windows" ; then
    cat >> confdefs.h <<\EOF
#define BUILD_tdom 1
EOF

    CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
    EXTRA_SOURCES='$(WIN_SOURCES)'
    VERSION=${MAJOR_VERSION}${MINOR_VERSION}${PATCHLEVEL}
else
    CLEANFILES="pkgIndex.tcl"
    EXTRA_SOURCES='$(UNIX_SOURCES)'
    VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${PATCHLEVEL}
fi





#--------------------------------------------------------------------
# We put this here so that you can compile with -DVERSION="1.2" to
# encode the package version directly into the source files.
#--------------------------------------------------------------------

eval cat >> confdefs.h <<EOF
#define VERSION "${VERSION}"
EOF


#--------------------------------------------------------------------
# Setup the current source directory so extensions building against
# tDOM stub library will know where to find binary directories.
# Setup paths and linker specification of the stub library.
# Note: some of those below are replicated in Makefile.in as well.
#--------------------------------------------------------------------

tdom_SRC_DIR=`cd ${srcdir}; pwd`

pkglibdir="${exec_prefix}/lib/${PACKAGE}${VERSION}"
tdomstub_LIB_FLAG="-ltdomstub${VERSION}${TCL_DBGX}"

tdomstub_BUILD_SPEC="-L`pwd` ${tdomstub_LIB_FLAG}"
tdomstub_FILE_SPEC="-L${pkglibdir} ${tdomstub_LIB_FLAG}"





#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
#--------------------------------------------------------------------


    # Check whether --enable-threads or --disable-threads was given.
if test "${enable_threads+set}" = set; then
  enableval="$enable_threads"
  tcl_ok=$enableval
else
  tcl_ok=
fi


    if test "$tcl_ok" = "yes"; then
	TCL_THREADS=1

	if test "${TEA_PLATFORM}" != "windows" ; then
	    # We are always OK on Windows, so check what this platform wants.
	    cat >> confdefs.h <<\EOF
#define USE_THREAD_ALLOC 1
EOF

	    cat >> confdefs.h <<\EOF
#define _REENTRANT 1
EOF

	    cat >> confdefs.h <<\EOF
#define _THREAD_SAFE 1
EOF

	    echo $ac_n "checking for pthread_mutex_init in -lpthread""... $ac_c" 1>&6
echo "configure:1628: checking for pthread_mutex_init in -lpthread" >&5
ac_lib_var=`echo pthread'_'pthread_mutex_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  ac_save_LIBS="$LIBS"
LIBS="-lpthread  $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1636 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error.  */
/* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
char pthread_mutex_init();

int main() {
pthread_mutex_init()
; return 0; }
EOF
if { (eval echo configure:1647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=yes"
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"

fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  tcl_ok=yes
else
  echo "$ac_t""no" 1>&6
tcl_ok=no
fi

	    if test "$tcl_ok" = "no"; then
		# Check a little harder for __pthread_mutex_init in the
		# same library, as some systems hide it there until
		# pthread.h is defined.	 We could alternatively do an
		# AC_TRY_COMPILE with pthread.h, but that will work with
		# libpthread really doesn't exist, like AIX 4.2.
		# [Bug: 4359]
		echo $ac_n "checking for __pthread_mutex_init in -lpthread""... $ac_c" 1>&6
echo "configure:1676: checking for __pthread_mutex_init in -lpthread" >&5
ac_lib_var=`echo pthread'_'__pthread_mutex_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  ac_save_LIBS="$LIBS"
LIBS="-lpthread  $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1684 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error.  */
/* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
char __pthread_mutex_init();

int main() {
__pthread_mutex_init()
; return 0; }
EOF
if { (eval echo configure:1695: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=yes"
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"

fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  tcl_ok=yes
else
  echo "$ac_t""no" 1>&6
tcl_ok=no
fi

	    fi
	    
	    if test "$tcl_ok" = "yes"; then
		# The space is needed
		THREADS_LIBS=" -lpthread"
	    else
		echo $ac_n "checking for pthread_mutex_init in -lpthreads""... $ac_c" 1>&6
echo "configure:1723: checking for pthread_mutex_init in -lpthreads" >&5
ac_lib_var=`echo pthreads'_'pthread_mutex_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  ac_save_LIBS="$LIBS"
LIBS="-lpthreads  $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1731 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error.  */
/* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
char pthread_mutex_init();

int main() {
pthread_mutex_init()
; return 0; }
EOF
if { (eval echo configure:1742: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=yes"
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"

fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  tcl_ok=yes
else
  echo "$ac_t""no" 1>&6
tcl_ok=no
fi

		if test "$tcl_ok" = "yes"; then
		    # The space is needed
		    THREADS_LIBS=" -lpthreads"
		else
		    echo $ac_n "checking for pthread_mutex_init in -lc""... $ac_c" 1>&6
echo "configure:1768: checking for pthread_mutex_init in -lc" >&5
ac_lib_var=`echo c'_'pthread_mutex_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  ac_save_LIBS="$LIBS"
LIBS="-lc  $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1776 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error.  */
/* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
char pthread_mutex_init();

int main() {
pthread_mutex_init()
; return 0; }
EOF
if { (eval echo configure:1787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=yes"
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"

fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  tcl_ok=yes
else
  echo "$ac_t""no" 1>&6
tcl_ok=no
fi

		    if test "$tcl_ok" = "no"; then
			echo $ac_n "checking for pthread_mutex_init in -lc_r""... $ac_c" 1>&6
echo "configure:1810: checking for pthread_mutex_init in -lc_r" >&5
ac_lib_var=`echo c_r'_'pthread_mutex_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  ac_save_LIBS="$LIBS"
LIBS="-lc_r  $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1818 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error.  */
/* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
char pthread_mutex_init();

int main() {
pthread_mutex_init()
; return 0; }
EOF
if { (eval echo configure:1829: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=yes"
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"

fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  tcl_ok=yes
else
  echo "$ac_t""no" 1>&6
tcl_ok=no
fi

			if test "$tcl_ok" = "yes"; then
			    # The space is needed
			    THREADS_LIBS=" -pthread"
			else
			    TCL_THREADS=0
			    echo "configure: warning: "Don t know how to find pthread lib on your system - thread support disabled"" 1>&2
			fi
		    fi
		fi
	    fi
	    
	    # Does the pthread-implementation provide
	    # 'pthread_attr_setstacksize' ?
	    for ac_func in pthread_attr_setstacksize
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:1866: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  cat > conftest.$ac_ext <<EOF
#line 1871 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
    which can conflict with char $ac_func(); below.  */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error.  */
/* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
char $ac_func();

int main() {

/* The GNU C library defines this for functions which it implements
    to always fail with ENOSYS.  Some functions are actually named
    something starting with __ and the normal name is an alias.  */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
$ac_func();
#endif

; return 0; }
EOF
if { (eval echo configure:1894: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  rm -rf conftest*
  eval "ac_cv_func_$ac_func=yes"
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
fi

if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
  echo "$ac_t""yes" 1>&6
    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
  cat >> confdefs.h <<EOF
#define $ac_tr_func 1
EOF
 
else
  echo "$ac_t""no" 1>&6
fi
done

	fi
    else
	TCL_THREADS=0
    fi
    # Do checking message here to not mess up interleaved configure output
    echo $ac_n "checking for building with threads""... $ac_c" 1>&6
echo "configure:1924: checking for building with threads" >&5
    if test "${TCL_THREADS}" = "1"; then
	cat >> confdefs.h <<\EOF
#define TCL_THREADS 1
EOF

	echo "$ac_t""yes" 1>&6
    else
	echo "$ac_t""no (default)" 1>&6
    fi
    # TCL_THREADS sanity checking.  See if our request for building with
    # threads is the same as the way Tcl was built.  If not, warn the user.
    case ${TCL_DEFS} in
	*THREADS=1*)
	    if test "${TCL_THREADS}" = "0"; then
		echo "configure: warning: 
    Building ${PACKAGE} without threads enabled, but building against a Tcl
    that IS thread-enabled." 1>&2
	    fi
	    ;;
	*)
	    if test "${TCL_THREADS}" = "1"; then
		echo "configure: warning: 
    --enable-threads requested, but attempting building against a Tcl
    that is NOT thread-enabled." 1>&2
	    fi
	    ;;
    esac
    


#--------------------------------------------------------------------
# The statement below defines a collection of symbols related to
# building as a shared library instead of a static library.
#--------------------------------------------------------------------


    echo $ac_n "checking how to build libraries""... $ac_c" 1>&6
echo "configure:1962: checking how to build libraries" >&5
    # Check whether --enable-shared or --disable-shared was given.
if test "${enable_shared+set}" = set; then
  enableval="$enable_shared"
  tcl_ok=$enableval
else
  tcl_ok=yes
fi


    if test "${enable_shared+set}" = set; then
	enableval="$enable_shared"
	tcl_ok=$enableval
    else
	tcl_ok=yes
    fi

    if test "$tcl_ok" = "yes" ; then
	echo "$ac_t""shared" 1>&6
	SHARED_BUILD=1
    else
	echo "$ac_t""static" 1>&6
	SHARED_BUILD=0
	cat >> confdefs.h <<\EOF
#define STATIC_BUILD 1
EOF

    fi


#--------------------------------------------------------------------
# This macro figures out what flags to use with the compiler/linker
# when building shared/static debug/optimized objects.  This information
# can be taken from the tclConfig.sh file, but this figures it all out.
#--------------------------------------------------------------------

echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:1999: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
  CPP=
fi
if test -z "$CPP"; then
if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
    # This must be in double quotes, not single quotes, because CPP may get
  # substituted into the Makefile and "${CC-cc}" will confuse make.
  CPP="${CC-cc} -E"
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp.
  cat > conftest.$ac_ext <<EOF
#line 2014 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2020: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
  :
else
  echo "$ac_err" >&5
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  CPP="${CC-cc} -E -traditional-cpp"
  cat > conftest.$ac_ext <<EOF
#line 2031 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2037: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
  :
else
  echo "$ac_err" >&5
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  CPP="${CC-cc} -nologo -E"
  cat > conftest.$ac_ext <<EOF
#line 2048 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2054: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
  :
else
  echo "$ac_err" >&5
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  CPP=/lib/cpp
fi
rm -f conftest*
fi
rm -f conftest*
fi
rm -f conftest*
  ac_cv_prog_CPP="$CPP"
fi
  CPP="$ac_cv_prog_CPP"
else
  ac_cv_prog_CPP="$CPP"
fi
echo "$ac_t""$CPP" 1>&6


    if test x"${TEA_INITED}" = x ; then
	# Can't refer to exact macro name or it will be substituted
	{ echo "configure: error: Must call TEA INIT before CONFIG_CFLAGS" 1>&2; exit 1; }
    fi

    # Step 0: Enable 64 bit support?

    echo $ac_n "checking if 64bit support is enabled""... $ac_c" 1>&6
echo "configure:2087: checking if 64bit support is enabled" >&5
    # Check whether --enable-64bit or --disable-64bit was given.
if test "${enable_64bit+set}" = set; then
  enableval="$enable_64bit"
  do64bit=$enableval
else
  do64bit=no
fi

    echo "$ac_t""$do64bit" 1>&6
 
    # Step 0.b: Enable Solaris 64 bit VIS support?

    echo $ac_n "checking if 64bit Sparc VIS support is requested""... $ac_c" 1>&6
echo "configure:2101: checking if 64bit Sparc VIS support is requested" >&5
    # Check whether --enable-64bit-vis or --disable-64bit-vis was given.
if test "${enable_64bit_vis+set}" = set; then
  enableval="$enable_64bit_vis"
  do64bitVIS=$enableval
else
  do64bitVIS=no
fi

    echo "$ac_t""$do64bitVIS" 1>&6

    if test "$do64bitVIS" = "yes"; then
	# Force 64bit on with VIS
	do64bit=yes
    fi

    # Step 1: set the variable "system" to hold the name and version number
    # for the system.  This can usually be done via the "uname" command, but
    # there are a few systems, like Next, where this doesn't work.

    echo $ac_n "checking system version (for dynamic loading)""... $ac_c" 1>&6
echo "configure:2122: checking system version (for dynamic loading)" >&5
    if test -f /usr/lib/NextStep/software_version; then
	system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
    else
	system=`uname -s`-`uname -r`
	if test "$?" -ne 0 ; then
	    echo "$ac_t""unknown (can't find uname command)" 1>&6
	    system=unknown
	else
	    # Special check for weird MP-RAS system (uname returns weird
	    # results, and the version is kept in special file).
	
	    if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
		system=MP-RAS-`awk '{print }' /etc/.relid'`
	    fi
	    if test "`uname -s`" = "AIX" ; then
		system=AIX-`uname -v`.`uname -r`
	    fi
	    if test "${TEA_PLATFORM}" = "windows" ; then
		system=windows
	    fi
	    echo "$ac_t""$system" 1>&6
	fi
    fi

    # Step 2: check for existence of -ldl library.  This is needed because
    # Linux can use either -ldl or -ldld for dynamic loading.

    echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
echo "configure:2151: checking for dlopen in -ldl" >&5
ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  ac_save_LIBS="$LIBS"
LIBS="-ldl  $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2159 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error.  */
/* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
char dlopen();

int main() {
dlopen()
; return 0; }
EOF
if { (eval echo configure:2170: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=yes"
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"

fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  have_dl=yes
else
  echo "$ac_t""no" 1>&6
have_dl=no
fi


    # Step 3: set configuration options based on system name and version.

    do64bit_ok=no
    EXTRA_CFLAGS=""
    TCL_EXPORT_FILE_SUFFIX=""
    UNSHARED_LIB_SUFFIX=""
    TCL_TRIM_DOTS='`echo ${VERSION} | tr -d .`'
    ECHO_VERSION='`echo ${VERSION}`'
    TCL_LIB_VERSIONS_OK=ok
    CFLAGS_DEBUG=-g
    CFLAGS_OPTIMIZE=-O
    if test "$GCC" = "yes" ; then
	CFLAGS_WARNING="-Wall -Wconversion -Wno-implicit-int"
    else
	CFLAGS_WARNING=""
    fi
    TCL_NEEDS_EXP_FILE=0
    TCL_BUILD_EXP_FILE=""
    TCL_EXP_FILE=""
    # Extract the first word of "ar", so it can be a program name with args.
set dummy ar; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:2214: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$AR"; then
  ac_cv_prog_AR="$AR" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
  ac_dummy="$PATH"
  for ac_dir in $ac_dummy; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_AR="ar"
      break
    fi
  done
  IFS="$ac_save_ifs"
fi
fi
AR="$ac_cv_prog_AR"
if test -n "$AR"; then
  echo "$ac_t""$AR" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

    STLIB_LD='${AR} cr'
    case $system in
	windows)
	    # This is a 2-stage check to make sure we have the 64-bit SDK
	    # We have to know where the SDK is installed.
	    if test "$do64bit" = "yes" ; then
		if test "x${MSSDK}x" = "xx" ; then
		    MSSDK="C:/Progra~1/Microsoft SDK"
		fi
		# In order to work in the tortured autoconf environment,
		# we need to ensure that this path has no spaces
		MSSDK=`cygpath -w -s "$MSSDK" | sed -e 's!\\\!/!g'`
		if test ! -d "${MSSDK}/bin/win64" ; then
		    echo "configure: warning: "could not find 64-bit SDK to enable 64bit mode"" 1>&2
		    do64bit="no"
		else
		    do64bit_ok="yes"
		fi
	    fi

	    if test "${SHARED_BUILD}" = "0" ; then
		runtime=-MT
	    else
		runtime=-MD
	    fi

	    if test "$do64bit" = "yes" ; then
		# All this magic is necessary for the Win64 SDK RC1 - hobbs
		export CC="${MSSDK}/Bin/Win64/cl.exe \
	    -I${MSSDK}/Include/prerelease -I${MSSDK}/Include/Win64/crt \
	    -I${MSSDK}/Include"
		export RC="${MSSDK}/bin/rc.exe"
		export lflags="-MACHINE:IA64 -LIBPATH:${MSSDK}/Lib/IA64 \
	    -LIBPATH:${MSSDK}/Lib/Prerelease/IA64"
		export STLIB_LD="${MSSDK}/bin/win64/lib.exe -nologo ${lflags}"
		export LINKBIN="${MSSDK}/bin/win64/link.exe ${lflags}"
		CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
		CFLAGS_OPTIMIZE="-nologo -O2 -Gs -W2 ${runtime}"
	    else
		RC="rc"
		STLIB_LD="lib -nologo"
    		LINKBIN="link -link50compat"
		CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
		CFLAGS_OPTIMIZE="-nologo -O2 -Gs -GD -W2 ${runtime}"
	    fi

	    if test "$MINGW32" = "yes"; then
		# mingw gcc mode
		CFLAGS_DEBUG="-g"
		CFLAGS_OPTIMIZE="-O2"
		SHLIB_LD="gcc -shared"
		STLIB_LD='${AR} cr'
		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
		LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
		LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"
	    else
		SHLIB_LD="${LINKBIN} -dll -nologo"
		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.lib'
		EXTRA_CFLAGS="-YX"
		# For information on what debugtype is most useful, see:
		# http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
		# This essentially turns it all on.
		LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2"
		LDFLAGS_OPTIMIZE="-release"
		LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
		LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
		PATHTYPE=-w
	    fi

	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".dll"
	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.dll'

	    TCL_LIB_VERSIONS_OK=nodots
	    # Bogus to avoid getting this turned off
	    DL_OBJS="tclLoadNone.obj"
    	    ;;
	AIX-*)
	    if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then
		# AIX requires the _r compiler when gcc isn't being used
		if test "${CC}" != "cc_r" ; then
		    CC=${CC}_r
		fi
		echo "$ac_t""Using $CC for compiling with threads" 1>&6
	    fi
	    LIBS="$LIBS -lc"
	    SHLIB_CFLAGS=""
	    SHLIB_SUFFIX=".so"
	    SHLIB_LD_LIBS='${LIBS}'
	    if test "`uname -m`" = "ia64" ; then
		# AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
		# AIX-5 has dl* in libc.so
		DL_LIBS=""
		if test "$GCC" = "yes" ; then
		    LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		else
		    LD_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
		fi
	    else
		SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
		DL_LIBS="-ldl"
		LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
		TCL_NEEDS_EXP_FILE=1
		TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.exp'
	    fi
	    DL_OBJS="tclLoadDl.o"
	    LDFLAGS=""

	    # AIX v<=4.1 has some different flags than 4.2+
	    if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then
		LIBOBJS="$LIBOBJS tclLoadAix.o"
		DL_LIBS="-lld"
	    fi

	    # On AIX <=v4 systems, libbsd.a has to be linked in to support
	    # non-blocking file IO.  This library has to be linked in after
	    # the MATH_LIBS or it breaks the pow() function.  The way to
	    # insure proper sequencing, is to add it to the tail of MATH_LIBS.
	    # This library also supplies gettimeofday.
	    #
	    # AIX does not have a timezone field in struct tm. When the AIX
	    # bsd library is used, the timezone global and the gettimeofday
	    # methods are to be avoided for timezone deduction instead, we
	    # deduce the timezone by comparing the localtime result on a
	    # known GMT value.

	    echo $ac_n "checking for gettimeofday in -lbsd""... $ac_c" 1>&6
echo "configure:2368: checking for gettimeofday in -lbsd" >&5
ac_lib_var=`echo bsd'_'gettimeofday | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  ac_save_LIBS="$LIBS"
LIBS="-lbsd  $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2376 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error.  */
/* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
char gettimeofday();

int main() {
gettimeofday()
; return 0; }
EOF
if { (eval echo configure:2387: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=yes"
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"

fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  libbsd=yes
else
  echo "$ac_t""no" 1>&6
libbsd=no
fi

	    if test $libbsd = yes; then
	    	MATH_LIBS="$MATH_LIBS -lbsd"
	    	cat >> confdefs.h <<\EOF
#define USE_DELTA_FOR_TZ 1
EOF

	    fi

	    # Check to enable 64-bit flags for compiler/linker on AIX 5+
	    if test "$do64bit" = "yes" -a "`uname -v`" -gt "4" ; then
		if test "$GCC" = "yes" ; then
		    echo "configure: warning: "64bit mode not supported with GCC on $system"" 1>&2
		else 
		    do64bit_ok=yes
		    EXTRA_CFLAGS="-q64"
		    LDFLAGS="-q64"
		fi
	    fi
	    ;;
	BSD/OS-2.1*|BSD/OS-3*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="shlicc -r"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	BSD/OS-4.*)
	    SHLIB_CFLAGS="-export-dynamic -fPIC"
	    SHLIB_LD="cc -shared"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="-export-dynamic"
	    LD_SEARCH_FLAGS=""
	    ;;
	dgux*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD="cc -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	HP-UX-*.11.*)
	    # Use updated header definitions where possible
	    cat >> confdefs.h <<\EOF
#define _XOPEN_SOURCE_EXTENDED 1
EOF


	    SHLIB_SUFFIX=".sl"
	    echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
echo "configure:2466: checking for shl_load in -ldld" >&5
ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  ac_save_LIBS="$LIBS"
LIBS="-ldld  $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2474 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error.  */
/* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
char shl_load();

int main() {
shl_load()
; return 0; }
EOF
if { (eval echo configure:2485: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=yes"
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"

fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  tcl_ok=yes
else
  echo "$ac_t""no" 1>&6
tcl_ok=no
fi

	    if test "$tcl_ok" = yes; then
		SHLIB_CFLAGS="+z"
		SHLIB_LD="ld -b"
		SHLIB_LD_LIBS=""
		DL_OBJS="tclLoadShl.o"
		DL_LIBS="-ldld"
		LDFLAGS="-Wl,-E"
		LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
	    fi

	    # Check to enable 64-bit flags for compiler/linker
	    if test "$do64bit" = "yes" ; then
		if test "$GCC" = "yes" ; then
		    echo "configure: warning: "64bit mode not supported with GCC on $system"" 1>&2
		else
		    do64bit_ok=yes
		    EXTRA_CFLAGS="+DA2.0W"
		    LDFLAGS="+DA2.0W $LDFLAGS"
		fi
	    fi
	    ;;
	HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
	    SHLIB_SUFFIX=".sl"
	    echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
echo "configure:2530: checking for shl_load in -ldld" >&5
ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  ac_save_LIBS="$LIBS"
LIBS="-ldld  $LIBS"
cat > conftest.$ac_ext <<EOF
#line 2538 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error.  */
/* We use char because int might match the return type of a gcc2
    builtin and then its argument prototype would still apply.  */
char shl_load();

int main() {
shl_load()
; return 0; }
EOF
if { (eval echo configure:2549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=yes"
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"

fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  tcl_ok=yes
else
  echo "$ac_t""no" 1>&6
tcl_ok=no
fi

	    if test "$tcl_ok" = yes; then
		SHLIB_CFLAGS="+z"
		SHLIB_LD="ld -b"
		SHLIB_LD_LIBS=""
		DL_OBJS="tclLoadShl.o"
		DL_LIBS="-ldld"
		LDFLAGS="-Wl,-E"
		LD_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
	    fi
	    ;;
	IRIX-4.*)
	    SHLIB_CFLAGS="-G 0"
	    SHLIB_SUFFIX=".a"
	    SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
	    SHLIB_LD_LIBS='${LIBS}'
	    DL_OBJS="tclLoadAout.o"
	    DL_LIBS=""
	    LDFLAGS="-Wl,-D,08000000"
	    LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	    SHARED_LIB_SUFFIX='${VERSION}\$\{DBGX\}.a'
	    ;;
	IRIX-5.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -shared -rdata_shared"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    EXTRA_CFLAGS=""
	    LDFLAGS=""
	    ;;
	IRIX-6.*|IRIX64-6.5*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    if test "$GCC" = "yes" ; then
		EXTRA_CFLAGS="-mabi=n32"
		LDFLAGS="-mabi=n32"
	    else
		case $system in
		    IRIX-6.3)
			# Use to build 6.2 compatible binaries on 6.3.
			EXTRA_CFLAGS="-n32 -D_OLD_TERMIOS"
			;;
		    *)
			EXTRA_CFLAGS="-n32"
			;;
		esac
		LDFLAGS="-n32"
	    fi
	    ;;
	IRIX64-6.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS=""
	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    ;;
	Linux*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"

	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings 
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.

	    CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    if test "$have_dl" = yes; then
		SHLIB_LD="${CC} -shared"
		DL_OBJS="tclLoadDl.o"
		DL_LIBS="-ldl"
		LDFLAGS="-rdynamic"
		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    else
		ac_safe=`echo "dld.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for dld.h""... $ac_c" 1>&6
echo "configure:2656: checking for dld.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  cat > conftest.$ac_ext <<EOF
#line 2661 "configure"
#include "confdefs.h"
#include <dld.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2666: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
  rm -rf conftest*
  eval "ac_cv_header_$ac_safe=yes"
else
  echo "$ac_err" >&5
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_header_$ac_safe=no"
fi
rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  
		    SHLIB_LD="ld -shared"
		    DL_OBJS="tclLoadDld.o"
		    DL_LIBS="-ldld"
		    LDFLAGS=""
		    LD_SEARCH_FLAGS=""
else
  echo "$ac_t""no" 1>&6
fi

	    fi
	    if test "`uname -m`" = "alpha" ; then
		EXTRA_CFLAGS="-mieee"
	    fi

	    # The combo of gcc + glibc has a bug related
	    # to inlining of functions like strtod(). The
	    # -fno-builtin flag should address this problem
	    # but it does not work. The -fno-inline flag
	    # is kind of overkill but it works.
	    # Disable inlining only when one of the
	    # files in compat/*.c is being linked in.
	    if test x"${LIBOBJS}" != x ; then
	        EXTRA_CFLAGS="${EXTRA_CFLAGS} -fno-inline"
	    fi

	    ;;
	GNU*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"

	    if test "$have_dl" = yes; then
		SHLIB_LD="${CC} -shared"
		DL_OBJS=""
		DL_LIBS="-ldl"
		LDFLAGS="-rdynamic"
		LD_SEARCH_FLAGS=""
	    else
		ac_safe=`echo "dld.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for dld.h""... $ac_c" 1>&6
echo "configure:2723: checking for dld.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  cat > conftest.$ac_ext <<EOF
#line 2728 "configure"
#include "confdefs.h"
#include <dld.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2733: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
  rm -rf conftest*
  eval "ac_cv_header_$ac_safe=yes"
else
  echo "$ac_err" >&5
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_header_$ac_safe=no"
fi
rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  
		    SHLIB_LD="ld -shared"
		    DL_OBJS=""
		    DL_LIBS="-ldld"
		    LDFLAGS=""
		    LD_SEARCH_FLAGS=""
else
  echo "$ac_t""no" 1>&6
fi

	    fi
	    if test "`uname -m`" = "alpha" ; then
		EXTRA_CFLAGS="-mieee"
	    fi
	    ;;
	MP-RAS-02*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD="cc -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	MP-RAS-*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD="cc -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="-Wl,-Bexport"
	    LD_SEARCH_FLAGS=""
	    ;;
	NetBSD-*|FreeBSD-[1-2].*|OpenBSD-*)
	    # Not available on all versions:  check for include file.
	    ac_safe=`echo "dlfcn.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for dlfcn.h""... $ac_c" 1>&6
echo "configure:2788: checking for dlfcn.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  cat > conftest.$ac_ext <<EOF
#line 2793 "configure"
#include "confdefs.h"
#include <dlfcn.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:2798: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
  rm -rf conftest*
  eval "ac_cv_header_$ac_safe=yes"
else
  echo "$ac_err" >&5
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_header_$ac_safe=no"
fi
rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  
		# NetBSD/SPARC needs -fPIC, -fpic will not do.
		SHLIB_CFLAGS="-fPIC"
		SHLIB_LD="ld -Bshareable -x"
		SHLIB_LD_LIBS=""
		SHLIB_SUFFIX=".so"
		DL_OBJS="tclLoadDl.o"
		DL_LIBS=""
		LDFLAGS=""
		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		echo $ac_n "checking for ELF""... $ac_c" 1>&6
echo "configure:2825: checking for ELF" >&5
		cat > conftest.$ac_ext <<EOF
#line 2827 "configure"
#include "confdefs.h"

#ifdef __ELF__
	yes
#endif
		
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  egrep "yes" >/dev/null 2>&1; then
  rm -rf conftest*
  echo "$ac_t""yes" 1>&6
		    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so'
else
  rm -rf conftest*
  echo "$ac_t""no" 1>&6
		    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1.0'
		
fi
rm -f conftest*

	    
else
  echo "$ac_t""no" 1>&6

		SHLIB_CFLAGS=""
		SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r"
		SHLIB_LD_LIBS='${LIBS}'
		SHLIB_SUFFIX=".a"
		DL_OBJS="tclLoadAout.o"
		DL_LIBS=""
		LDFLAGS=""
		LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
	    
fi


	    # FreeBSD doesn't handle version numbers with dots.

	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	FreeBSD-*)
	    # FreeBSD 3.* and greater have ELF.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS="-export-dynamic"
	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    if test "${TCL_THREADS}" = "1" ; then
		EXTRA_CFLAGS="-pthread"
	    	LDFLAGS="$LDFLAGS -pthread"
	    fi
	    case $system in
	    FreeBSD-3.*)
	    	# FreeBSD-3 doesn't handle version numbers with dots.
	    	UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
	    	SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so'
	    	TCL_LIB_VERSIONS_OK=nodots
		;;
	    esac
	    ;;
	Rhapsody-*|Darwin-*)
	    SHLIB_CFLAGS="-fno-common"
	    SHLIB_LD="cc -dynamiclib \${LDFLAGS}"
	    TCL_SHLIB_LD_EXTRAS="-compatibility_version ${TCL_MAJOR_VERSION} -current_version \${VERSION} -install_name \${LIB_RUNTIME_DIR}/\${TCL_LIB_FILE} -prebind -seg1addr a000000"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".dylib"
	    DL_OBJS="tclLoadDyld.o"
	    DL_LIBS=""
	    LDFLAGS="-prebind"
	    LD_SEARCH_FLAGS=""
	    CFLAGS_OPTIMIZE="-O3"
	    EXTRA_CFLAGS="-arch ppc -pipe"
	    ;;
	NEXTSTEP-*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="cc -nostdlib -r"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadNext.o"
	    DL_LIBS=""
	    LDFLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OS/390-*)
	    CFLAGS_OPTIMIZE=""      # Optimizer is buggy
	    cat >> confdefs.h <<\EOF
#define _OE_SOCKETS 1
EOF
  # needed in sys/socket.h
	    ;;      
	OSF1-1.0|OSF1-1.1|OSF1-1.2)
	    # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
	    SHLIB_CFLAGS=""
	    # Hack: make package name same as library name
	    SHLIB_LD='ld -R -export :'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadOSF.o"
	    DL_LIBS=""
	    LDFLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OSF1-1.*)
	    # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="ld -shared"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OSF1-V*)
	    # Digital OSF/1
	    SHLIB_CFLAGS=""
	    SHLIB_LD='ld -shared -expect_unresolved "*"'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS=""
	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    if test "$GCC" != "yes" ; then
		EXTRA_CFLAGS="-DHAVE_TZSET -std1"
	    fi
	    # see pthread_intro(3) for pthread support on osf1, k.furukawa
	    if test "${TCL_THREADS}" = "1" ; then
		EXTRA_CFLAGS="${EXTRA_CFLAGS} -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
		EXTRA_CFLAGS="${EXTRA_CFLAGS} -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
		LIBS=`echo $LIBS | sed s/-lpthreads//`
		if test "$GCC" = "yes" ; then
		    LIBS="$LIBS -lpthread -lmach -lexc"
		else
		    EXTRA_CFLAGS="${EXTRA_CFLAGS} -pthread"
		    LDFLAGS="-pthread"
		fi
	    fi

	    ;;
	QNX-6*)
	    # QNX RTP
	    # This may work for all QNX, but it was only reported for v6.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    # dlopen is in -lc on QNX
	    DL_LIBS=""
	    LDFLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	RISCos-*)
	    SHLIB_CFLAGS="-G 0"
	    SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".a"
	    DL_OBJS="tclLoadAout.o"
	    DL_LIBS=""
	    LDFLAGS="-Wl,-D,08000000"
	    LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	    ;;
	SCO_SV-3.2*)
	    # Note, dlopen is available only on SCO 3.2.5 and greater. However,
	    # this test works, since "uname -s" was non-standard in 3.2.4 and
	    # below.
	    if test "$GCC" = "yes" ; then
	    	SHLIB_CFLAGS="-fPIC -melf"
	    	LDFLAGS="-melf -Wl,-Bexport"
	    else
	    	SHLIB_CFLAGS="-Kpic -belf"
	    	LDFLAGS="-belf -Wl,-Bexport"
	    fi
	    SHLIB_LD="ld -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SINIX*5.4*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD="cc -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SunOS-4*)
	    SHLIB_CFLAGS="-PIC"
	    SHLIB_LD="ld"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS=""
	    LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'

	    # SunOS can't handle version numbers with dots in them in library
	    # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
	    # requires an extra version number at the end of .so file names.
	    # So, the library has to have a name like libtcl75.so.1.0

	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1.0'
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	SunOS-5.[0-6]*)

	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.

	    cat >> confdefs.h <<\EOF
#define _REENTRANT 1
EOF

	    cat >> confdefs.h <<\EOF
#define _POSIX_PTHREAD_SEMANTICS 1
EOF


	    SHLIB_CFLAGS="-KPIC"
	    SHLIB_LD="/usr/ccs/bin/ld -G -z text"

	    # Note: need the LIBS below, otherwise Tk won't find Tcl's
	    # symbols when dynamically loaded into tclsh.

	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS=""
	    if test "$GCC" = "yes" ; then
		LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
	    else
		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
	    fi
	    ;;
	SunOS-5*)

	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.

	    cat >> confdefs.h <<\EOF
#define _REENTRANT 1
EOF

	    cat >> confdefs.h <<\EOF
#define _POSIX_PTHREAD_SEMANTICS 1
EOF


	    SHLIB_CFLAGS="-KPIC"
	    SHLIB_LD="/usr/ccs/bin/ld -G -z text"
	    LDFLAGS=""
    
	    # Check to enable 64-bit flags for compiler/linker
	    if test "$do64bit" = "yes" ; then
		arch=`isainfo`
		if test "$arch" = "sparcv9 sparc" ; then
			if test "$GCC" = "yes" ; then
			    echo "configure: warning: "64bit mode not supported with GCC on $system"" 1>&2
			else
			    do64bit_ok=yes
			    if test "$do64bitVIS" = "yes" ; then
				EXTRA_CFLAGS="-xarch=v9a"
			    	LDFLAGS="-xarch=v9a"
			    else
				EXTRA_CFLAGS="-xarch=v9"
			    	LDFLAGS="-xarch=v9"
			    fi
			fi
		else
		    echo "configure: warning: "64bit mode only supported sparcv9 system"" 1>&2
		fi
	    fi
	    
	    # Note: need the LIBS below, otherwise Tk won't find Tcl's
	    # symbols when dynamically loaded into tclsh.

	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    if test "$GCC" = "yes" ; then
		LD_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
	    else
		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
	    fi
	    ;;
	ULTRIX-4.*)
	    SHLIB_CFLAGS="-G 0"
	    SHLIB_SUFFIX=".a"
	    SHLIB_LD="echo tclLdAout $CC \{$SHLIB_CFLAGS\} | `pwd`/tclsh -r -G 0"
	    SHLIB_LD_LIBS='${LIBS}'
	    DL_OBJS="tclLoadAout.o"
	    DL_LIBS=""
	    LDFLAGS="-Wl,-D,08000000"
	    LD_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	    if test "$GCC" != "yes" ; then
		EXTRA_CFLAGS="-DHAVE_TZSET -std1"
	    fi
	    ;;
	UNIX_SV* | UnixWare-5*)
	    SHLIB_CFLAGS="-KPIC"
	    SHLIB_LD="cc -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
	    # that don't grok the -Bexport option.  Test that it does.
	    hold_ldflags=$LDFLAGS
	    echo $ac_n "checking for ld accepts -Bexport flag""... $ac_c" 1>&6
echo "configure:3150: checking for ld accepts -Bexport flag" >&5
	    LDFLAGS="${LDFLAGS} -Wl,-Bexport"
	    cat > conftest.$ac_ext <<EOF
#line 3153 "configure"
#include "confdefs.h"

int main() {
int i;
; return 0; }
EOF
if { (eval echo configure:3160: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
  rm -rf conftest*
  found=yes
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  found=no
fi
rm -f conftest*
	    LDFLAGS=$hold_ldflags
	    echo "$ac_t""$found" 1>&6
	    if test $found = yes; then
	    LDFLAGS="-Wl,-Bexport"
	    else
	    LDFLAGS=""
	    fi
	    LD_SEARCH_FLAGS=""
	    ;;
    esac

    if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
    echo "configure: warning: "64bit support being disabled -- don\'t know magic for this platform"" 1>&2
    fi

    # Step 4: If pseudo-static linking is in use (see K. B. Kenny, "Dynamic
    # Loading for Tcl -- What Became of It?".  Proc. 2nd Tcl/Tk Workshop,
    # New Orleans, LA, Computerized Processes Unlimited, 1994), then we need
    # to determine which of several header files defines the a.out file
    # format (a.out.h, sys/exec.h, or sys/exec_aout.h).  At present, we
    # support only a file format that is more or less version-7-compatible. 
    # In particular,
    #	- a.out files must begin with `struct exec'.
    #	- the N_TXTOFF on the `struct exec' must compute the seek address
    #	  of the text segment
    #	- The `struct exec' must contain a_magic, a_text, a_data, a_bss
    #	  and a_entry fields.
    # The following compilation should succeed if and only if either sys/exec.h
    # or a.out.h is usable for the purpose.
    #
    # Note that the modified COFF format used on MIPS Ultrix 4.x is usable; the
    # `struct exec' includes a second header that contains information that
    # duplicates the v7 fields that are needed.

    if test "x$DL_OBJS" = "xtclLoadAout.o" ; then
	echo $ac_n "checking sys/exec.h""... $ac_c" 1>&6
echo "configure:3206: checking sys/exec.h" >&5
	cat > conftest.$ac_ext <<EOF
#line 3208 "configure"
#include "confdefs.h"
#include <sys/exec.h>
int main() {

	    struct exec foo;
	    unsigned long seek;
	    int flag;
#if defined(__mips) || defined(mips)
	    seek = N_TXTOFF (foo.ex_f, foo.ex_o);
#else
	    seek = N_TXTOFF (foo);
#endif
	    flag = (foo.a_magic == OMAGIC);
	    return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry;
    
; return 0; }
EOF
if { (eval echo configure:3226: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  rm -rf conftest*
  tcl_ok=usable
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  tcl_ok=unusable
fi
rm -f conftest*
	echo "$ac_t""$tcl_ok" 1>&6
	if test $tcl_ok = usable; then
	    cat >> confdefs.h <<\EOF
#define USE_SYS_EXEC_H 1
EOF

	else
	    echo $ac_n "checking a.out.h""... $ac_c" 1>&6
echo "configure:3244: checking a.out.h" >&5
	    cat > conftest.$ac_ext <<EOF
#line 3246 "configure"
#include "confdefs.h"
#include <a.out.h>
int main() {

		struct exec foo;
		unsigned long seek;
		int flag;
#if defined(__mips) || defined(mips)
		seek = N_TXTOFF (foo.ex_f, foo.ex_o);
#else
		seek = N_TXTOFF (foo);
#endif
		flag = (foo.a_magic == OMAGIC);
		return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry;
	    
; return 0; }
EOF
if { (eval echo configure:3264: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  rm -rf conftest*
  tcl_ok=usable
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  tcl_ok=unusable
fi
rm -f conftest*
	    echo "$ac_t""$tcl_ok" 1>&6
	    if test $tcl_ok = usable; then
		cat >> confdefs.h <<\EOF
#define USE_A_OUT_H 1
EOF

	    else
		echo $ac_n "checking sys/exec_aout.h""... $ac_c" 1>&6
echo "configure:3282: checking sys/exec_aout.h" >&5
		cat > conftest.$ac_ext <<EOF
#line 3284 "configure"
#include "confdefs.h"
#include <sys/exec_aout.h>
int main() {

		    struct exec foo;
		    unsigned long seek;
		    int flag;
#if defined(__mips) || defined(mips)
		    seek = N_TXTOFF (foo.ex_f, foo.ex_o);
#else
		    seek = N_TXTOFF (foo);
#endif
		    flag = (foo.a_midmag == OMAGIC);
		    return foo.a_text + foo.a_data + foo.a_bss + foo.a_entry;
		
; return 0; }
EOF
if { (eval echo configure:3302: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  rm -rf conftest*
  tcl_ok=usable
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  tcl_ok=unusable
fi
rm -f conftest*
		echo "$ac_t""$tcl_ok" 1>&6
		if test $tcl_ok = usable; then
		    cat >> confdefs.h <<\EOF
#define USE_SYS_EXEC_AOUT_H 1
EOF

		else
		    DL_OBJS=""
		fi
	    fi
	fi
    fi

    # Step 5: disable dynamic loading if requested via a command-line switch.

    # Check whether --enable-load or --disable-load was given.
if test "${enable_load+set}" = set; then
  enableval="$enable_load"
  tcl_ok=$enableval
else
  tcl_ok=yes
fi

    if test "$tcl_ok" = "no"; then
	DL_OBJS=""
    fi

    if test "x$DL_OBJS" != "x" ; then
	BUILD_DLTEST="\$(DLTEST_TARGETS)"
    else
	echo "Can't figure out how to do dynamic loading or shared libraries"
	echo "on this system."
	SHLIB_CFLAGS=""
	SHLIB_LD=""
	SHLIB_SUFFIX=""
	DL_OBJS="tclLoadNone.o"
	DL_LIBS=""
	LDFLAGS=""
	LD_SEARCH_FLAGS=""
	BUILD_DLTEST=""
    fi

    # If we're running gcc, then change the C flags for compiling shared
    # libraries to the right flags for gcc, instead of those for the
    # standard manufacturer compiler.

    if test "$DL_OBJS" != "tclLoadNone.o" ; then
	if test "$GCC" = "yes" ; then
	    case $system in
		AIX-*)
		    ;;
		BSD/OS*)
		    ;;
		IRIX*)
		    ;;
		NetBSD-*|FreeBSD-*|OpenBSD-*)
		    ;;
		Rhapsody-*|Darwin-*)
		    ;;
		RISCos-*)
		    ;;
		SCO_SV-3.2*)
		    ;;
		ULTRIX-4.*)
		    ;;
		windows)
		    if test "$MINGW32" != "yes"; then 
		        SHLIB_CFLAGS="-fPIC"
		    fi
		    ;;
		*)
		    SHLIB_CFLAGS="-fPIC"
		    ;;
	    esac
	fi
    fi

    if test "$SHARED_LIB_SUFFIX" = "" ; then
	SHARED_LIB_SUFFIX='${VERSION}\$\{DBGX\}${SHLIB_SUFFIX}'
    fi
    if test "$UNSHARED_LIB_SUFFIX" = "" ; then
	UNSHARED_LIB_SUFFIX='${VERSION}\$\{DBGX\}.a'
    fi

    
    
    
    
    

    SHLIB_LDFLAGS='$(LDFLAGS_DEFAULT)'
    
    
    
    
    
    
    

TDOM_LD_SEARCH_FLAGS=${LD_SEARCH_FLAGS}


#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols option.
#--------------------------------------------------------------------


    if test x"${TEA_INITED}" = x ; then
	# Can't refer to exact macro name or it will be substituted
	{ echo "configure: error: Must call TEA INIT before ENABLE_SYMBOLS" 1>&2; exit 1; }
    fi

    if test "${TEA_PLATFORM}" = "windows" ; then
	tcl_dbgx=d
    else
	tcl_dbgx=g
    fi

    echo $ac_n "checking for build with symbols""... $ac_c" 1>&6
echo "configure:3431: checking for build with symbols" >&5
    # Check whether --enable-symbols or --disable-symbols was given.
if test "${enable_symbols+set}" = set; then
  enableval="$enable_symbols"
  tcl_ok=$enableval
else
  tcl_ok=no
fi

    if test "$tcl_ok" = "yes"; then
	CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
	LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
	DBGX=${tcl_dbgx}
	TCL_DBGX=${tcl_dbgx}
	echo "$ac_t""yes" 1>&6
    else
	CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
	LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
	DBGX=""
	TCL_DBGX=""
	echo "$ac_t""no" 1>&6
    fi

    
    
    


if test "${SHARED_BUILD}" = "1" ; then
    CFLAGS='${CFLAGS_DEFAULT} ${CFLAGS_WARNING} ${SHLIB_CFLAGS}'
else
    CFLAGS='${CFLAGS_DEFAULT} ${CFLAGS_WARNING}'
fi


#--------------------------------------------------------------------
# Everyone should be linking against the Tcl stub library.  If you
# can't for some reason, remove this definition.  If you aren't using
# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
# link against the non-stubbed Tcl library.  Add Tk too if necessary.
#--------------------------------------------------------------------

#AC_DEFINE(USE_TCL_STUBS)
#AC_DEFINE(USE_TK_STUBS)

#--------------------------------------------------------------------
# This macro generates a line to use when building a library.  It
# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
# and TEA_LOAD_TCLCONFIG macros above.
# For tDOM we always build both, static and shared libraries
#--------------------------------------------------------------------


    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
	MAKE_STATIC_LIB="\${STLIB_LD} -out:\$@ \$(\$(PACKAGE)_OBJECTS)"
	MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LDFLAGS} \${SHLIB_LD_LIBS} \$(LDFLAGS) -out:\$@ \$(\$(PACKAGE)_OBJECTS)"
	MAKE_STUB_LIB="\${STLIB_LD} -out:\$@ \$(\$(PACKAGE)stub_OBJECTS)"
    else
	MAKE_STATIC_LIB="\${STLIB_LD} \$@ \$(\$(PACKAGE)_OBJECTS)"
	MAKE_SHARED_LIB="\${SHLIB_LD} -o \$@ \$(\$(PACKAGE)_OBJECTS) \${SHLIB_LDFLAGS} \${SHLIB_LD_LIBS}"
	MAKE_STUB_LIB="\${STLIB_LD} \$@ \$(\$(PACKAGE)stub_OBJECTS)"
    fi

    if test "${SHARED_BUILD}" = "1" ; then
	MAKE_LIB="${MAKE_SHARED_LIB} "
    else
	MAKE_LIB="${MAKE_STATIC_LIB} "
    fi

    #--------------------------------------------------------------------
    # Shared libraries and static libraries have different names.
    # Use the double eval to make sure the ${DBGX} in the suffix is
    # substituted.
    #--------------------------------------------------------------------

    if test "${TEA_PLATFORM}" = "windows" ; then
	if test "${SHARED_BUILD}" = "1" ; then
	    # We force the unresolved linking of symbols that are really in
	    # the private libraries of Tcl and Tk.
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
	    if test x"${TK_BIN_DIR}" != x ; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
	    fi
	    eval eval "${PACKAGE}_LIB_FILE=${PACKAGE}${SHARED_LIB_SUFFIX}"
	    RANLIB=:
	else
	    eval eval "${PACKAGE}_LIB_FILE=${PACKAGE}${UNSHARED_LIB_SUFFIX}"
	fi
	# Some packages build there own stubs libraries
	eval eval "${PACKAGE}stub_LIB_FILE=${PACKAGE}stub${UNSHARED_LIB_SUFFIX}"
    else
	if test "${SHARED_BUILD}" = "1" ; then
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
	    if test x"${TK_BIN_DIR}" != x ; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
	    fi
	    eval eval "${PACKAGE}_LIB_FILE=lib${PACKAGE}${SHARED_LIB_SUFFIX}"
	    RANLIB=:
	else
	    eval eval "${PACKAGE}_LIB_FILE=lib${PACKAGE}${UNSHARED_LIB_SUFFIX}"
	fi
	# Some packages build there own stubs libraries
	eval eval "${PACKAGE}stub_LIB_FILE=lib${PACKAGE}stub${UNSHARED_LIB_SUFFIX}"
    fi

    
    
    
    


#--------------------------------------------------------------------
# __CHANGE__
# Add platform libs to LIBS or SHLIB_LD_LIBS as necessary.
#--------------------------------------------------------------------

#LIBS="${LIBS} -lsuperfly"

#--------------------------------------------------------------------
# Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl
# file during the install process.  Don't run the TCLSH_PROG through
# ${CYGPATH} because it's being used directly by make.
# Require that we use a tclsh shell version 8.2 or later since earlier
# versions have bugs in the pkg_mkIndex routine.
# Add WISH as well if this is a Tk extension.
#--------------------------------------------------------------------


    echo $ac_n "checking for tclsh""... $ac_c" 1>&6
echo "configure:3560: checking for tclsh" >&5

    if eval "test \"`echo '$''{'ac_cv_path_tclsh'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  
	search_path=`echo ${TCL_BIN_DIR}:${TCL_BIN_DIR}/../bin:${exec_prefix}/bin:${prefix}/bin:${PATH} | sed -e 's/:/ /g'`
	for dir in $search_path ; do
	    for j in `ls -r $dir/tclsh[8-9]*${EXEEXT} 2> /dev/null` \
		    `ls -r $dir/tclsh*${EXEEXT} 2> /dev/null` ; do
		if test x"$ac_cv_path_tclsh" = x ; then
		    if test -f "$j" ; then
			ac_cv_path_tclsh=$j
			break
		    fi
		fi
	    done
	done
    
fi


    if test -f "$ac_cv_path_tclsh" ; then
	TCLSH_PROG=$ac_cv_path_tclsh
	echo "$ac_t""$TCLSH_PROG" 1>&6
    else
	{ echo "configure: error: No tclsh found in PATH:  $search_path" 1>&2; exit 1; }
    fi
    

#TEA_PROG_WISH

#--------------------------------------------------------------------
# Add some private include directories
#--------------------------------------------------------------------

TDOM_INCLUDES="-I${srcdir}/generic -I${srcdir}/expat"


#--------------------------------------------------------------------
# Add optional AOLserver includes
#--------------------------------------------------------------------


    echo $ac_n "checking for AOLserver configuration""... $ac_c" 1>&6
echo "configure:3605: checking for AOLserver configuration" >&5
    # Check whether --with-aol or --without-aol was given.
if test "${with_aol+set}" = set; then
  withval="$with_aol"
  \
    with_aolserver=${withval}
fi


    if eval "test \"`echo '$''{'ac_cv_c_aolserver'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  
    if test x"${with_aolserver}" != x ; then
        if test -f "${with_aolserver}/include/ns.h" ; then
            ac_cv_c_aolserver=`(cd ${with_aolserver}; pwd)`
        else
            { echo "configure: error: ${with_aolserver} directory doesn't contain ns.h" 1>&2; exit 1; }
        fi
    fi
    
fi

    if test x"${ac_cv_c_aolserver}" = x ; then
        echo "$ac_t""none found" 1>&6
    else
        AOL_DIR=${ac_cv_c_aolserver}
        echo "$ac_t""found AOLserver in $AOL_DIR" 1>&6
        cat >> confdefs.h <<\EOF
#define NS_AOLSERVER 1
EOF

        cat >> confdefs.h <<\EOF
#define USE_NORMAL_ALLOCATOR 1
EOF

    fi

if test x"${AOL_DIR}" != "x" ; then
    AOL_INCLUDES="-I${AOL_DIR}/include"
else
    AOL_INCLUDES=
fi



#--------------------------------------------------------------------
# Add some private preprocessor options
#--------------------------------------------------------------------


    echo $ac_n "checking wether to enable dtd support""... $ac_c" 1>&6
echo "configure:3657: checking wether to enable dtd support" >&5
    # Check whether --enable-dtd or --disable-dtd was given.
if test "${enable_dtd+set}" = set; then
  enableval="$enable_dtd"
  tcl_ok=$enableval
else
  tcl_ok=yes
fi


    if test "${enable_dt+set}" = set; then
        enableval="$enable_dtd"
        tcl_ok=$enableval
    else
        tcl_ok=yes
    fi

    if test "$tcl_ok" = "yes" ; then
        echo "$ac_t""yes" 1>&6
        cat >> confdefs.h <<\EOF
#define XML_DTD 1
EOF

    else
        echo "$ac_t""no" 1>&6
    fi


    echo $ac_n "checking wether to enable namespace support""... $ac_c" 1>&6
echo "configure:3686: checking wether to enable namespace support" >&5
    # Check whether --enable-ns or --disable-ns was given.
if test "${enable_ns+set}" = set; then
  enableval="$enable_ns"
  tcl_ok=$enableval
else
  tcl_ok=yes
fi


    if test "${enable_ns+set}" = set; then
        enableval="$enable_ns"
        tcl_ok=$enableval
    else
        tcl_ok=yes
    fi

    if test "$tcl_ok" = "yes" ; then
        echo "$ac_t""yes" 1>&6
        cat >> confdefs.h <<\EOF
#define XML_NS 1
EOF

    else
        echo "$ac_t""no" 1>&6
    fi


    echo $ac_n "checking wether to enable built-in unknown command""... $ac_c" 1>&6
echo "configure:3715: checking wether to enable built-in unknown command" >&5
    # Check whether --enable-ucmd or --disable-ucmd was given.
if test "${enable_ucmd+set}" = set; then
  enableval="$enable_ucmd"
  tcl_ok=$enableval
else
  tcl_ok=no
fi


    if test "${enable_unknown+set}" = set; then
        enableval="$enable_unknown"
        tcl_ok=$enableval
    else
        tcl_ok=no
    fi

    if test "$tcl_ok" = "no" ; then
        echo "$ac_t""no" 1>&6
        cat >> confdefs.h <<\EOF
#define TDOM_NO_UNKNOWN_CMD 1
EOF

    else
        echo "$ac_t""yes" 1>&6
    fi


    echo $ac_n "checking wether to enable tDOMs block allocator""... $ac_c" 1>&6
echo "configure:3744: checking wether to enable tDOMs block allocator" >&5
    # Check whether --enable-tdomalloc or --disable-tdomalloc was given.
if test "${enable_tdomalloc+set}" = set; then
  enableval="$enable_tdomalloc"
  tcl_ok=$enableval
else
  tcl_ok=yes
fi


    if test "${enable_tdomalloc+set}" = set; then
        enableval="$enable_tdomalloc"
        tcl_ok=$enableval
    else
        tcl_ok=yes
    fi

    if test "$tcl_ok" = "yes" ; then
        echo "$ac_t""yes" 1>&6
    else
        echo "$ac_t""no" 1>&6
        cat >> confdefs.h <<\EOF
#define USE_NORMAL_ALLOCATOR 1
EOF

    fi

echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
echo "configure:3772: checking whether byte ordering is bigendian" >&5
if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  ac_cv_c_bigendian=unknown
# See if sys/param.h defines the BYTE_ORDER macro.
cat > conftest.$ac_ext <<EOF
#line 3779 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
int main() {

#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
 bogus endian macros
#endif
; return 0; }
EOF
if { (eval echo configure:3790: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  rm -rf conftest*
  # It does; now see whether it defined to BIG_ENDIAN or not.
cat > conftest.$ac_ext <<EOF
#line 3794 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
int main() {

#if BYTE_ORDER != BIG_ENDIAN
 not big endian
#endif
; return 0; }
EOF
if { (eval echo configure:3805: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  rm -rf conftest*
  ac_cv_c_bigendian=yes
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  ac_cv_c_bigendian=no
fi
rm -f conftest*
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
fi
rm -f conftest*
if test $ac_cv_c_bigendian = unknown; then
if test "$cross_compiling" = yes; then
   echo $ac_n "cross-compiling... " 2>&6 
else
  cat > conftest.$ac_ext <<EOF
#line 3825 "configure"
#include "confdefs.h"
main () {
  /* Are we little or big endian?  From Harbison&Steele.  */
  union
  {
    long l;
    char c[sizeof (long)];
  } u;
  u.l = 1;
  exit (u.c[sizeof (long) - 1] == 1);
}
EOF
if { (eval echo configure:3838: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
  ac_cv_c_bigendian=no
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -fr conftest*
  ac_cv_c_bigendian=yes
fi
rm -fr conftest*
fi

fi
fi

echo "$ac_t""$ac_cv_c_bigendian" 1>&6
if test $ac_cv_c_bigendian = unknown; then
echo $ac_n "checking to probe for byte ordering""... $ac_c" 1>&6
echo "configure:3856: checking to probe for byte ordering" >&5

cat >conftest.c <<EOF
short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
void _ascii() { char* s = (char*) ascii_mm; s = (char*) ascii_ii; }
short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
void _ebcdic() { char* s = (char*) ebcdic_mm; s = (char*) ebcdic_ii; }
int main() { _ascii (); _ebcdic (); return 0; }
EOF
 if test -f conftest.c ; then
     if ${CC-cc} -c conftest.c -o conftest.o && test -f conftest.o ; then
        if test `grep -l BIGenDianSyS conftest.o` ; then
           echo $ac_n ' big endian probe OK, ' 1>&6
           ac_cv_c_bigendian=yes
        fi
        if test `grep -l LiTTleEnDian conftest.o` ; then
           echo $ac_n ' little endian probe OK, ' 1>&6
           if test $ac_cv_c_bigendian = yes ; then
            ac_cv_c_bigendian=unknown;
           else
            ac_cv_c_bigendian=no
           fi
        fi
        echo $ac_n 'guessing bigendian ...  ' >&6
     fi
  fi
echo "$ac_t""$ac_cv_c_bigendian" 1>&6
fi
if test $ac_cv_c_bigendian = yes; then
  cat >> confdefs.h <<\EOF
#define WORDS_BIGENDIAN 1
EOF

  BYTEORDER=4321
else
  BYTEORDER=1234
fi
if test $ac_cv_c_bigendian = unknown; then
  { echo "configure: error: unknown endianess - sorry" 1>&2; exit 1; }
fi



#--------------------------------------------------------------------
# Finally, substitute all of the various values into the Makefile.
# You may alternatively have a special pkgIndex.tcl.in or other files
# which require substituting th AC variables in.  Include these here.
#--------------------------------------------------------------------

trap '' 1 2 15
cat > confcache <<\EOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs.  It is not useful on other systems.
# If it contains results you don't want to keep, you may remove or edit it.
#
# By default, configure uses ./config.cache as the cache file,
# creating it if it does not exist already.  You can give configure
# the --cache-file=FILE option to use a different cache file; that is
# what configure does when it calls configure scripts in
# subdirectories, so they share the cache.
# Giving --cache-file=/dev/null disables caching, for debugging configure.
# config.status only pays attention to the cache file if you give it the
# --recheck option to rerun configure.
#
EOF
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 |
  case `(ac_space=' '; set | grep ac_space) 2>&1` in
  *ac_space=\ *)
    # `set' does not quote correctly, so add quotes (double-quote substitution
    # turns \\\\ into \\, and sed turns \\ into \).
    sed -n \
      -e "s/'/'\\\\''/g" \
      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
    ;;
  *)
    # `set' quotes correctly as required by POSIX, so do not add quotes.
    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
    ;;
  esac >> confcache
if cmp -s $cache_file confcache; then
  :
else
  if test -w $cache_file; then
    echo "updating cache $cache_file"
    cat confcache > $cache_file
  else
    echo "not updating unwritable cache $cache_file"
  fi
fi
rm -f confcache

trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15

test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'

# Any assignment to VPATH causes Sun make to only execute
# the first set of double-colon rules, so remove it if not needed.
# If there is a colon in the path, we need to keep it.
if test "x$srcdir" = x.; then
  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
fi

trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15

# Transform confdefs.h into DEFS.
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
cat > conftest.defs <<\EOF
s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
s%[ 	`~#$^&*(){}\\|;'"<>?]%\\&%g
s%\[%\\&%g
s%\]%\\&%g
s%\$%$$%g
EOF
DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
rm -f conftest.defs


# Without the "./", some shells look in PATH for config.status.
: ${CONFIG_STATUS=./config.status}

echo creating $CONFIG_STATUS
rm -f $CONFIG_STATUS
cat > $CONFIG_STATUS <<EOF
#! /bin/sh
# Generated automatically by configure.
# Run this file to recreate the current configuration.
# This directory was configured as follows,
# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
#
# $0 $ac_configure_args
#
# Compiler output produced by configure, useful for debugging
# configure, is in ./config.log if it exists.

ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
for ac_option
do
  case "\$ac_option" in
  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
    echo "$CONFIG_STATUS generated by autoconf version 2.13"
    exit 0 ;;
  -help | --help | --hel | --he | --h)
    echo "\$ac_cs_usage"; exit 0 ;;
  *) echo "\$ac_cs_usage"; exit 1 ;;
  esac
done

ac_given_srcdir=$srcdir
ac_given_INSTALL="$INSTALL"

trap 'rm -fr `echo "Makefile tdomConfig.sh" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS <<EOF

# Protect against being on the right side of a sed subst in config.status.
sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
 s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
$ac_vpsub
$extrasub
s%@SHELL@%$SHELL%g
s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g
s%@FFLAGS@%$FFLAGS%g
s%@DEFS@%$DEFS%g
s%@LDFLAGS@%$LDFLAGS%g
s%@LIBS@%$LIBS%g
s%@exec_prefix@%$exec_prefix%g
s%@prefix@%$prefix%g
s%@program_transform_name@%$program_transform_name%g
s%@bindir@%$bindir%g
s%@sbindir@%$sbindir%g
s%@libexecdir@%$libexecdir%g
s%@datadir@%$datadir%g
s%@sysconfdir@%$sysconfdir%g
s%@sharedstatedir@%$sharedstatedir%g
s%@localstatedir@%$localstatedir%g
s%@libdir@%$libdir%g
s%@includedir@%$includedir%g
s%@oldincludedir@%$oldincludedir%g
s%@infodir@%$infodir%g
s%@mandir@%$mandir%g
s%@CONFIGDIR@%$CONFIGDIR%g
s%@PACKAGE@%$PACKAGE%g
s%@TDOMSHELL@%$TDOMSHELL%g
s%@MAJOR_VERSION@%$MAJOR_VERSION%g
s%@MINOR_VERSION@%$MINOR_VERSION%g
s%@PATCHLEVEL@%$PATCHLEVEL%g
s%@tdom_LIB_FILE@%$tdom_LIB_FILE%g
s%@tdomstub_LIB_FILE@%$tdomstub_LIB_FILE%g
s%@CYGPATH@%$CYGPATH%g
s%@EXEEXT@%$EXEEXT%g
s%@TCL_VERSION@%$TCL_VERSION%g
s%@TCL_BIN_DIR@%$TCL_BIN_DIR%g
s%@TCL_SRC_DIR@%$TCL_SRC_DIR%g
s%@TCL_LIB_FILE@%$TCL_LIB_FILE%g
s%@TCL_LIB_FLAG@%$TCL_LIB_FLAG%g
s%@TCL_LIB_SPEC@%$TCL_LIB_SPEC%g
s%@TCL_STUB_LIB_FILE@%$TCL_STUB_LIB_FILE%g
s%@TCL_STUB_LIB_FLAG@%$TCL_STUB_LIB_FLAG%g
s%@TCL_STUB_LIB_SPEC@%$TCL_STUB_LIB_SPEC%g
s%@TCL_LIBS@%$TCL_LIBS%g
s%@TCL_DEFS@%$TCL_DEFS%g
s%@TCL_EXTRA_CFLAGS@%$TCL_EXTRA_CFLAGS%g
s%@TCL_LD_FLAGS@%$TCL_LD_FLAGS%g
s%@TCL_SHLIB_LD_LIBS@%$TCL_SHLIB_LD_LIBS%g
s%@CC@%$CC%g
s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
s%@INSTALL_DATA@%$INSTALL_DATA%g
s%@SET_MAKE@%$SET_MAKE%g
s%@RANLIB@%$RANLIB%g
s%@OBJEXT@%$OBJEXT%g
s%@TCL_INCLUDES@%$TCL_INCLUDES%g
s%@CLEANFILES@%$CLEANFILES%g
s%@EXTRA_SOURCES@%$EXTRA_SOURCES%g
s%@VERSION@%$VERSION%g
s%@tdomstub_BUILD_SPEC@%$tdomstub_BUILD_SPEC%g
s%@tdomstub_FILE_SPEC@%$tdomstub_FILE_SPEC%g
s%@tdom_SRC_DIR@%$tdom_SRC_DIR%g
s%@TCL_THREADS@%$TCL_THREADS%g
s%@AR@%$AR%g
s%@CPP@%$CPP%g
s%@DL_LIBS@%$DL_LIBS%g
s%@CFLAGS_DEBUG@%$CFLAGS_DEBUG%g
s%@CFLAGS_OPTIMIZE@%$CFLAGS_OPTIMIZE%g
s%@CFLAGS_WARNING@%$CFLAGS_WARNING%g
s%@EXTRA_CFLAGS@%$EXTRA_CFLAGS%g
s%@STLIB_LD@%$STLIB_LD%g
s%@SHLIB_LD@%$SHLIB_LD%g
s%@SHLIB_CFLAGS@%$SHLIB_CFLAGS%g
s%@SHLIB_LDFLAGS@%$SHLIB_LDFLAGS%g
s%@SHLIB_LD_LIBS@%$SHLIB_LD_LIBS%g
s%@LDFLAGS_DEBUG@%$LDFLAGS_DEBUG%g
s%@LDFLAGS_OPTIMIZE@%$LDFLAGS_OPTIMIZE%g
s%@TDOM_LD_SEARCH_FLAGS@%$TDOM_LD_SEARCH_FLAGS%g
s%@TCL_DBGX@%$TCL_DBGX%g
s%@CFLAGS_DEFAULT@%$CFLAGS_DEFAULT%g
s%@LDFLAGS_DEFAULT@%$LDFLAGS_DEFAULT%g
s%@SHARED_BUILD@%$SHARED_BUILD%g
s%@MAKE_LIB@%$MAKE_LIB%g
s%@MAKE_SHARED_LIB@%$MAKE_SHARED_LIB%g
s%@MAKE_STATIC_LIB@%$MAKE_STATIC_LIB%g
s%@MAKE_STUB_LIB@%$MAKE_STUB_LIB%g
s%@TCLSH_PROG@%$TCLSH_PROG%g
s%@TDOM_INCLUDES@%$TDOM_INCLUDES%g
s%@AOL_DIR@%$AOL_DIR%g
s%@AOL_INCLUDES@%$AOL_INCLUDES%g
s%@BYTEORDER@%$BYTEORDER%g

CEOF
EOF

cat >> $CONFIG_STATUS <<\EOF

# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
ac_file=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_cmds # Line after last line for current file.
ac_more_lines=:
ac_sed_cmds=""
while $ac_more_lines; do
  if test $ac_beg -gt 1; then
    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
  else
    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
  fi
  if test ! -s conftest.s$ac_file; then
    ac_more_lines=false
    rm -f conftest.s$ac_file
  else
    if test -z "$ac_sed_cmds"; then
      ac_sed_cmds="sed -f conftest.s$ac_file"
    else
      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
    fi
    ac_file=`expr $ac_file + 1`
    ac_beg=$ac_end
    ac_end=`expr $ac_end + $ac_max_sed_cmds`
  fi
done
if test -z "$ac_sed_cmds"; then
  ac_sed_cmds=cat
fi
EOF

cat >> $CONFIG_STATUS <<EOF

CONFIG_FILES=\${CONFIG_FILES-"Makefile tdomConfig.sh"}
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
  case "$ac_file" in
  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
  *) ac_file_in="${ac_file}.in" ;;
  esac

  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.

  # Remove last slash and all that follows it.  Not all systems have dirname.
  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
    # The file is in a subdirectory.
    test ! -d "$ac_dir" && mkdir "$ac_dir"
    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
    # A "../" for each directory in $ac_dir_suffix.
    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
  else
    ac_dir_suffix= ac_dots=
  fi

  case "$ac_given_srcdir" in
  .)  srcdir=.
      if test -z "$ac_dots"; then top_srcdir=.
      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
  *) # Relative path.
    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
    top_srcdir="$ac_dots$ac_given_srcdir" ;;
  esac

  case "$ac_given_INSTALL" in
  [/$]*) INSTALL="$ac_given_INSTALL" ;;
  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
  esac

  echo creating "$ac_file"
  rm -f "$ac_file"
  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
  case "$ac_file" in
  *Makefile*) ac_comsub="1i\\
# $configure_input" ;;
  *) ac_comsub= ;;
  esac

  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
  sed -e "$ac_comsub
s%@configure_input@%$configure_input%g
s%@srcdir@%$srcdir%g
s%@top_srcdir@%$top_srcdir%g
s%@INSTALL@%$INSTALL%g
" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
fi; done
rm -f conftest.s*

EOF
cat >> $CONFIG_STATUS <<EOF

EOF
cat >> $CONFIG_STATUS <<\EOF

exit 0
EOF
chmod +x $CONFIG_STATUS
rm -fr confdefs* $ac_clean_files
test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to configure.in.

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
19


20
21
22


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
..
68
69
70
71
72
73
74












75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92


93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117



118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
...
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227
228
229
230
231
#!/bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tcl installation
dnl	to configure the system for the local environment.
#
# RCS: @(#) $Id$

#-----------------------------------------------------------------------
# Sample configure.in for Tcl Extensions.  The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------


#-----------------------------------------------------------------------
# __CHANGE__
# Set your package name and version numbers here.
#
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided.  These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.


#-----------------------------------------------------------------------

AC_INIT([tdom], [0.8.3])



#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------

TEA_INIT([3.6])

AC_CONFIG_AUX_DIR(tclconfig)

#--------------------------------------------------------------------
# Load the tclConfig.sh file
#--------------------------------------------------------------------

................................................................................
#-----------------------------------------------------------------------

TEA_PREFIX

#-----------------------------------------------------------------------
# Standard compiler checks.
# This sets up CC by using the CC env var, or looks for gcc otherwise.
# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
# the basic setup necessary to compile executables.
#-----------------------------------------------------------------------

TEA_SETUP_COMPILER

#-----------------------------------------------------------------------
# Those two are needed for compiling expat.
#-----------------------------------------------------------------------
................................................................................
AC_CHECK_FUNCS(memmove bcopy)

#--------------------------------------------------------------------
# Add optional AOLserver includes
#--------------------------------------------------------------------

TDOM_PATH_AOLSERVER













#-----------------------------------------------------------------------
# __CHANGE__
# Specify the C source files to compile in TEA_ADD_SOURCES,
# public headers that need to be installed in TEA_ADD_HEADERS,
# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
# and PKG_TCL_SOURCES.
#-----------------------------------------------------------------------

TEA_ADD_SOURCES([expat/xmlrole.c     \
                 expat/xmltok.c      \
                 expat/xmlparse.c    \
                 generic/xmlsimple.c \
                 generic/utf8conv.c  \
                 generic/dom.c       \
                 generic/domhtml.c   \


                 generic/domxpath.c  \
                 generic/domxslt.c   \
                 generic/domlock.c   \
                 generic/tcldom.c    \
                 generic/nodecmd.c   \
                 generic/tdominit.c  \
                 generic/tclexpat.c  \

                 generic/tdomStubInit.c])
TEA_ADD_HEADERS([generic/tdom.h])
TEA_ADD_INCLUDES([-I${srcdir}/generic -I${srcdir}/expat ${AOL_INCLUDES}])
TEA_ADD_LIBS([${AOL_LIBS}])
TEA_ADD_CFLAGS([])
TEA_ADD_STUB_SOURCES([generic/tdomStubLib.c])
TEA_ADD_TCL_SOURCES([lib/tdom.tcl])

#--------------------------------------------------------------------
# __CHANGE__
# A few miscellaneous platform-specific items:
#
# Define a special symbol for Windows (BUILD_sample in this case) so
# that we create the export library with the dll.
#
# Windows creates a few extra files that need to be cleaned up.
# You can add more files to clean if your extension creates any extra
# files.



#

# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------

if test "${TEA_PLATFORM}" = "windows" ; then
    AC_DEFINE(BUILD_tdom)
    CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
    #TEA_ADD_SOURCES([win/winFile.c])
    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
else
    CLEANFILES="pkgIndex.tcl tcldomsh"
    #TEA_ADD_SOURCES([unix/unixFile.c])
    #TEA_ADD_LIBS([-lsuperfly])
fi
AC_SUBST(CLEANFILES)

#--------------------------------------------------------------------
# __CHANGE__
................................................................................
#--------------------------------------------------------------------
# Everyone should be linking against the Tcl stub library.  If you
# can't for some reason, remove this definition.  If you aren't using
# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
# link against the non-stubbed Tcl library.  Add Tk too if necessary.
#--------------------------------------------------------------------

AC_DEFINE(USE_TCL_STUBS)
#AC_DEFINE(USE_TK_STUBS)

#--------------------------------------------------------------------
# This macro generates a line to use when building a library.  It
# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
# and TEA_LOAD_TCLCONFIG macros above.
#--------------------------------------------------------------------

TEA_MAKE_LIB

#--------------------------------------------------------------------
# Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl
# file during the install process.  Don't run the TCLSH_PROG through
# ${CYGPATH} because it's being used directly by make.
# Require that we use a tclsh shell version 8.2 or later since earlier
# versions have bugs in the pkg_mkIndex routine.
# Add WISH as well if this is a Tk extension.
#--------------------------------------------------------------------

TEA_PROG_TCLSH
#TEA_PROG_WISH

#--------------------------------------------------------------------
# Add some private preprocessor options
#--------------------------------------------------------------------

TDOM_ENABLE_DTD
TDOM_ENABLE_NS
TDOM_ENABLE_UNKNOWN
TDOM_ENABLE_TDOMALLOC


TDOMSHELL=tcldomsh
AC_SUBST(TDOMSHELL)

TDOM_EXPORT_CONFIG

#--------------------------------------------------------------------
# Finally, substitute all of the various values into the Makefile.
# You may alternatively have a special pkgIndex.tcl.in or other files
# which require substituting th AC variables in.  Include these here.
#--------------------------------------------------------------------

AC_OUTPUT([Makefile tdomConfig.sh])




<
<





>








>
>


|
>
>







|







 







|
|







 







>
>
>
>
>
>
>
>
>
>
>
>











<
<
<
|
<


>
>







>


|
|






<

<
<
<
<

<
>
>
>

>




<




|







 







|
|










|
|
|
|
|
<













>













1
2
3
4


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
..
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100



101

102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124




125

126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
...
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#!/bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tcl installation
dnl	to configure the system for the local environment.



#-----------------------------------------------------------------------
# Sample configure.in for Tcl Extensions.  The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------


#-----------------------------------------------------------------------
# __CHANGE__
# Set your package name and version numbers here.
#
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided.  These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
# This will also define a special symbol for Windows (BUILD_sample in
# this case) so that we create the export library with the dll.
#-----------------------------------------------------------------------

AC_INIT([tdom], [0.9.1])

TDOM_EXPAT_ENTROPY

#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------

TEA_INIT([3.13])

AC_CONFIG_AUX_DIR(tclconfig)

#--------------------------------------------------------------------
# Load the tclConfig.sh file
#--------------------------------------------------------------------

................................................................................
#-----------------------------------------------------------------------

TEA_PREFIX

#-----------------------------------------------------------------------
# Standard compiler checks.
# This sets up CC by using the CC env var, or looks for gcc otherwise.
# This also calls AC_PROG_CC and a few others to create the basic setup
# necessary to compile executables.
#-----------------------------------------------------------------------

TEA_SETUP_COMPILER

#-----------------------------------------------------------------------
# Those two are needed for compiling expat.
#-----------------------------------------------------------------------
................................................................................
AC_CHECK_FUNCS(memmove bcopy)

#--------------------------------------------------------------------
# Add optional AOLserver includes
#--------------------------------------------------------------------

TDOM_PATH_AOLSERVER

#--------------------------------------------------------------------
# Add shared expat includes
#--------------------------------------------------------------------

TDOM_PATH_EXPAT

#--------------------------------------------------------------------
# Add HTML5 parsing support.
#--------------------------------------------------------------------

TDOM_ENABLE_HTML5

#-----------------------------------------------------------------------
# __CHANGE__
# Specify the C source files to compile in TEA_ADD_SOURCES,
# public headers that need to be installed in TEA_ADD_HEADERS,
# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
# and PKG_TCL_SOURCES.
#-----------------------------------------------------------------------




TEA_ADD_SOURCES([generic/xmlsimple.c \

                 generic/dom.c       \
                 generic/domhtml.c   \
                 generic/domhtml5.c  \
                 generic/domjson.c   \
                 generic/domxpath.c  \
                 generic/domxslt.c   \
                 generic/domlock.c   \
                 generic/tcldom.c    \
                 generic/nodecmd.c   \
                 generic/tdominit.c  \
                 generic/tclexpat.c  \
                 generic/tclpull.c   \
                 generic/tdomStubInit.c])
TEA_ADD_HEADERS([generic/tdom.h])
TEA_ADD_INCLUDES([-I${srcdir}/generic ${AOL_INCLUDES} ${HTML5_INCLUDES}])
TEA_ADD_LIBS([${AOL_LIBS} ${HTML5_LIBS}])
TEA_ADD_CFLAGS([])
TEA_ADD_STUB_SOURCES([generic/tdomStubLib.c])
TEA_ADD_TCL_SOURCES([lib/tdom.tcl])

#--------------------------------------------------------------------
# __CHANGE__

#




# You can add more files to clean if your extension creates any extra

# files by extending CLEANFILES.
# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
#
# A few miscellaneous platform-specific items:
# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------

if test "${TEA_PLATFORM}" = "windows" ; then

    CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
    #TEA_ADD_SOURCES([win/winFile.c])
    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
else
    CLEANFILES="pkgIndex.tcl tdom.tcl tcldomsh"
    #TEA_ADD_SOURCES([unix/unixFile.c])
    #TEA_ADD_LIBS([-lsuperfly])
fi
AC_SUBST(CLEANFILES)

#--------------------------------------------------------------------
# __CHANGE__
................................................................................
#--------------------------------------------------------------------
# Everyone should be linking against the Tcl stub library.  If you
# can't for some reason, remove this definition.  If you aren't using
# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
# link against the non-stubbed Tcl library.  Add Tk too if necessary.
#--------------------------------------------------------------------

AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
#AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])

#--------------------------------------------------------------------
# This macro generates a line to use when building a library.  It
# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
# and TEA_LOAD_TCLCONFIG macros above.
#--------------------------------------------------------------------

TEA_MAKE_LIB

#--------------------------------------------------------------------
# Determine the name of the tclsh and/or wish executables in the
# Tcl and Tk build directories or the location they were installed
# into. These paths are used to support running test cases only,
# the Makefile should not be making use of these paths to generate
# a pkgIndex.tcl file or anything else at extension build time.

#--------------------------------------------------------------------

TEA_PROG_TCLSH
#TEA_PROG_WISH

#--------------------------------------------------------------------
# Add some private preprocessor options
#--------------------------------------------------------------------

TDOM_ENABLE_DTD
TDOM_ENABLE_NS
TDOM_ENABLE_UNKNOWN
TDOM_ENABLE_TDOMALLOC
TDOM_ENABLE_LESS_NS

TDOMSHELL=tcldomsh
AC_SUBST(TDOMSHELL)

TDOM_EXPORT_CONFIG

#--------------------------------------------------------------------
# Finally, substitute all of the various values into the Makefile.
# You may alternatively have a special pkgIndex.tcl.in or other files
# which require substituting th AC variables in.  Include these here.
#--------------------------------------------------------------------

AC_OUTPUT([Makefile tdomConfig.sh])

Added doc/INDEX.MAP.















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<INDEX title="tDOM manual" package="tDOM">
    <MAN id="dom" title="dom"/>
    <DEF cat="manpage" name="dom" manpage="dom"/>
    <DEF cat="cmd" name="dom" manpage="dom"/>
    <DEF cat="cmd" name="dom" manpage="dom"/>
    <KWD name="XML" manpage="dom"/>
    <KWD name="DOM" manpage="dom"/>
    <KWD name="document" manpage="dom"/>
    <KWD name="node" manpage="dom"/>
    <KWD name="parsing" manpage="dom"/>
    <MAN id="domDoc" title="domDoc"/>
    <DEF cat="manpage" name="domDoc" manpage="domDoc"/>
    <DEF cat="cmd" name="domDoc" manpage="domDoc"/>
    <KWD name="DOM node creation" manpage="domDoc"/>
    <KWD name="document element" manpage="domDoc"/>
    <MAN id="domNode" title="domNode"/>
    <DEF cat="manpage" name="domNode" manpage="domNode"/>
    <DEF cat="cmd" name="domNode" manpage="domNode"/>
    <KWD name="XML" manpage="domNode"/>
    <KWD name="DOM" manpage="domNode"/>
    <KWD name="document" manpage="domNode"/>
    <KWD name="node" manpage="domNode"/>
    <KWD name="parsing" manpage="domNode"/>
    <MAN id="expat" title="expat"/>
    <DEF cat="manpage" name="expat" manpage="expat"/>
    <DEF cat="cmd" name="expat" manpage="expat"/>
    <DEF cat="cmd" name="expat" manpage="expat"/>
    <DEF cat="cmd" name="xml::parser" manpage="expat"/>
    <KWD name="SAX" manpage="expat"/>
    <KWD name="push" manpage="expat"/>
    <KWD name="pushparser" manpage="expat"/>
    <MAN id="expatapi" title="expatapi"/>
    <DEF cat="manpage" name="expatapi" manpage="expatapi"/>
    <DEF cat="fun" name="CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove,&#xA;         CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo" manpage="expatapi"/>
    <KWD name="C handler set" manpage="expatapi"/>
    <MAN id="pullparser" title="pullparser"/>
    <DEF cat="manpage" name="pullparser" manpage="pullparser"/>
    <DEF cat="pullparser" name="tDOM::pullparser" manpage="pullparser"/>
    <DEF cat="cmd" name="tDOM::pullparser" manpage="pullparser"/>
    <KWD name="XML" manpage="pullparser"/>
    <KWD name="pull" manpage="pullparser"/>
    <KWD name="parsing" manpage="pullparser"/>
    <MAN id="tdomcmd" title="tdom"/>
    <DEF cat="manpage" name="tdomcmd" manpage="tdomcmd"/>
    <DEF cat="cmd" name="tdom" manpage="tdomcmd"/>
    <KWD name="DOM" manpage="tdomcmd"/>
    <KWD name="SAX" manpage="tdomcmd"/>
    <KWD name="C handler set" manpage="tdomcmd"/>
    <MAN id="tnc" title="tnc"/>
    <DEF cat="manpage" name="tnc" manpage="tnc"/>
    <DEF cat="cmd" name="tnc" manpage="tnc"/>
    <KWD name="Validation" manpage="tnc"/>
    <KWD name="DTD" manpage="tnc"/>
</INDEX>

Changes to doc/category-index.html.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
<head>
<title>tDOM manual: Index</title><link rel="stylesheet" href="manpage.css"><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile$ $Revision$">
</head><body>
<div class="header">
<h1 class="title" align="center">tDOM manual: Index</h1><p class="navaid" align="center">
<a class="navaid" href="index.html">Contents</a> <a class="navaid" href="category-index.html">Index</a> ท <a class="navaid" href="keyword-index.html">Keywords</a>
</p><hr class="navsep"><div class="navbar">
<a href="#cat_cmd">Tcl commands</a> <a href="#cat_fun">C functions</a> </div>
</div><div class="body">
<h2><a name="cat_cmd">Tcl commands</a></h2><a href="dom.html">dom</a> ท <a href="domDoc.html">domDoc</a> ท <a href="domNode.html">domNode</a> ท <a href="expat.html">expat</a> ท <a href="tdomcmd.html">tdom</a> ท <a href="tnc.html">tnc</a> ท <a href="expat.html">xml::parser</a><h2><a name="cat_fun">C functions</a></h2><a href="expatapi.html">CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove,
         CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo</a>
</div><div class="footer">
<hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> <a class="navaid" href="category-index.html">Index</a> ท <a class="navaid" href="keyword-index.html">Keywords</a>
</div>
</div>
</body>
</html>


|



|

|

|



|




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
<head>
<title>tDOM manual: Index</title><link rel="stylesheet" href="manpage.css"><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: category-index.xsl,v $ $Revision: 1.5 $"><meta charset="utf-8">
</head><body>
<div class="header">
<h1 class="title" align="center">tDOM manual: Index</h1><p class="navaid" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>
</p><hr class="navsep"><div class="navbar">
<a href="#cat_cmd">Tcl commands</a> ยท <a href="#cat_fun">C functions</a> ยท </div>
</div><div class="body">
<h2><a name="cat_cmd">Tcl commands</a></h2><a href="dom.html">dom</a> ยท <a href="dom.html">dom</a> ยท <a href="domDoc.html">domDoc</a> ยท <a href="domNode.html">domNode</a> ยท <a href="expat.html">expat</a> ยท <a href="expat.html">expat</a> ยท <a href="tdomcmd.html">tdom</a> ยท <a href="pullparser.html">tDOM::pullparser</a> ยท <a href="tnc.html">tnc</a> ยท <a href="expat.html">xml::parser</a><h2><a name="cat_fun">C functions</a></h2><a href="expatapi.html">CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove,
         CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo</a>
</div><div class="footer">
<hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>
</div>
</div>
</body>
</html>

Changes to doc/dom.html.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74




































































75
76
77
78
79
80
81













82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
109
110
111
112
113



114
115



























116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162

163

164
165

166
167

168
169



















170
171
172
173
174
175
176
...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

224

225
226
227
228



229
230
231

232
233
234
235
236
237
238
239
240
241

242












243
244
245
246
247
248
249
250
...
258
259
260
261
262
263
264
265


266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389











390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420










































































421

422


423
424
425
426
427
428
429
430
431
432


433
434
435
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: dom</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile$ $Revision$">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid0x80b16e8">NAME</a> ท <a href="#SECTid0x80b1760">SYNOPSIS</a> ท <a href="#SECTid0x80b1828">DESCRIPTION </a> ท <a href="#SECTid0x80b3f38">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
  <h2><a name="SECTid0x80b16e8">NAME</a></h2><p class="namesection">
<b class="names">dom - </b><br>Create an in-memory DOM tree from XML</p>
  
  <h2><a name="SECTid0x80b1760">SYNOPSIS</a></h2><pre class="syntax">package require tdom

<b class="cmd">dom</b> <i class="m">method</i> ?<i class="m">arg arg ...</i>?</pre>

  <h2><a name="SECTid0x80b1828">DESCRIPTION </a></h2><p>This command provides the creation of complete DOM trees in memory. In
the usual case a string containing a XML information is parsed and converted

into a DOM tree. <i class="m">method</i> indicates a specific subcommand. </p><p>The valid methods are:</p><dl class="commandlist">
        
          <dt>
<b class="cmd">dom</b> <b class="method">parse</b> ?<i class="m">options</i>? ?<i class="m">data</i>?</dt>
          <dd>Parses the XML information and builds up the DOM tree in memory
providing a Tcl object command to this DOM document object. Example:

      <pre class="example">
................................................................................
              
                <dt><b>-simple</b></dt> 
                <dd>If <i class="m">-simple</i> is
specified, a simple but fast parser is used (conforms not fully to XML
recommendation). That should double parsing and DOM generation speed. The
encoding of the data is not transformed inside the parser. The simple parser
does not respect any encoding information in the XML declaration. It skips over
the internal DTD subset and ignores any information in it. Therefor it doesn't
include defaulted attribute values into the tree, even if the according
attribute declaration is in the internal subset. It also doesn't expand
internal or external entity references other than the predefined entities and
character references.</dd>
              

              
                <dt><b>-html</b></dt>
                <dd>If <i class="m">-html</i> is specified, a fast HTML parser is 
used, which tries to even parse badly formed HTML into a DOM tree.</dd>
              
       
              




































































                <dt><b>-keepEmpties</b></dt> 
                <dd>If <i class="m">-keepEmpties</i> is
specified, text nodes, which contain only whitespaces, will be part of the
resulting DOM tree. In default case (<i class="m">-keepEmpties</i> not given) those empty
text nodes are removed at parsing time.</dd>
              














              
                <dt>
<b>-channel</b> <i>&lt;channel-ID&gt;</i>
</dt>
                
                <dd>If <i class="m">-channel &lt;channel-ID&gt;</i> is specified, the
input to be parsed is read from the specified channel. The encoding setting of
the channel (via fconfigure -encoding) is respected, ie the data read from the
channel are converted to UTF-8 according to the encoding settings, befor the
data is parsed.</dd>
              

              
                <dt>
<b>-baseurl</b> <i>&lt;baseURI&gt;</i>
</dt>
                
                <dd>If <i class="m">-baseurl &lt;baseURI&gt;</i> is specified, the
baseURI is used as the base URI of the document. External entities referenced

in the document are resolved relative to this base URI. This base URI is also
stored within the DOM tree.</dd>
              

              
                <dt>
<b>-feedbackAfter</b> <i>&lt;#bytes&gt;</i>
</dt>
                
                <dd>If <i class="m">-feedbackAfter &lt;#bytes&gt;</i> is specified, the
tcl command ::dom::domParseFeedback is evaluated after parsing every #bytes. If
you use this option, you have to create a tcl proc named
::dom::domParseFeedback, otherwise you will get an error. Please notice, that



the calls of ::dom::domParseFeedback are not done exactly every #bytes, but
always at the first element start after every #bytes.</dd>



























              

              
                <dt>
<b>-externalentitycommand</b> <i>&lt;script&gt;</i>
</dt>
                
                <dd>If <i class="m">-externalentitycommand &lt;script&gt;</i> is
specified, the specified tcl script is called to resolve any external entities
of the document. The actual evaluated command consists of this option followed
by three arguments: the base uri, the system identifier of the entity and the
public identifier of the entity. The base uri and the public identifier may be
the empty list. The script has to return a tcl list consisting of three
elements. The first element of this list signals, how the external entity is
returned to the processor. At the moment, the two allowed types are "string"
and "channel". The second element of the list has to be the (absolute) base URI
of the external entity to be parsed.  The third element of the list are data,
either the already read data out of the external entity as string in the case
of type "string", or the name of a tcl channel, in the case of type
"channel". Note that if the script returns a tcl channel, it will not be closed
by the processor.  It must be closed separately if it is no longer
required.</dd>
              

              
                <dt>
<b>-useForeignDTD</b> <i>&lt;boolean&gt;</i>
</dt>
                
                <dd>If &lt;boolean&gt; is true and the document does not have
an external subset, the parser will call the -externalentitycommand script with
empty values for the systemId and publicID arguments. Pleace notice, that, if
the document also doesn't have an internal subset, the
-startdoctypedeclcommand and -enddoctypedeclcommand scripts, if set, are not
called. The <i class="m">-useForeignDTD</i> respects </dd>
              

              
                <dt>
<b>-paramentityparsing</b> <i>&lt;always|never|notstandalone&gt;</i>
</dt>
                
                <dd>The <i class="m">-paramentityparsing</i> option controls, if the
parser tries to resolve the external entities (including the external DTD

subset) of the document, while building the DOM
tree. <i class="m">-paramentityparsing</i> requires an argument, which must be either
"always", "never", or "notstandalone". The value "always" means, that the

parser tries to resolves (recursively) all external entities of the XML

source. This is the default, in case <i class="m">-paramentityparsing</i> is omitted. The
value "never" means, that only the given XML source is parsed and no external

entity (including the external subset) will be resolved and parsed. The value
"notstandalone" means, that all external entities will be resolved and parsed,

with the execption of documents, which explicitly states standalone="yes" in
their XML declaration.</dd>



















              

            </dl>
<p></p>
</dd>
        

................................................................................
memory handling as explained above.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">createDocumentNode</b>
?<i class="m">objVar</i>?</dt>
          <dd>Creates a new, 'empty' DOM document object without any element
node. <i class="m">objVar</i> controls the memory handling as explained above.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">setResultEncoding</b> ?<i class="m">encodingName</i>?</dt>
          <dd>If <i class="m">encodingName</i> is not given the current global
result encoding is returned.  Otherwise the global result encoding is set to
<i class="m">encodingName</i>.  All character data, attribute values, etc. will
then be converted from UTF-8, which is delivered from the Expat XML parser, to
the given 8 bit encoding at XML/DOM parse time.  Valid values for
<i class="m">encodingName</i> are: utf-8, ascii, cp1250, cp1251, cp1252, cp1253,
cp1254, cp1255, cp1256, cp437, cp850, en, iso8859-1, iso8859-2, iso8859-3,
iso8859-4, iso8859-5, iso8859-6, iso8859-7, iso8859-8, iso8859-9, koi8-r.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">createNodeCmd</b>
<i class="m">?-returnNodeCmd?</i> <i class="m">(element|comment|text|cdata|pi)Node</i> <i class="m">commandName</i>
</dt>
          <dd>This method creates Tcl commands, which in turn create tDOM nodes.
Tcl commands created by this command are only avaliable inside a script given to the

domNode method <i class="m">appendFromScript</i>. If a command created with

<i class="m">createNodeCmd</i> is invoked in any other context, it will return error. The
created command <i class="m">commandName</i> replaces any existing command or procedure
with that name. If the <i class="m">commandName</i> includes any namespace qualifiers, 
it is created in the specified namespace.




<p>If such command is invoked inside a script given as argument to
the domNode method <i class="m">appendFromScript</i>, it creates a new node and

appends this node at the end of the child list of the invoking element
node. If the option <i class="m">-returnNodeCmd</i> was given, the command returns the
created node as Tcl command. If this option was omitted, the command returns
nothing. Each command creates always the same type of node. Which type of 
node is created by the command is determined by the first argument to the
<i class="m">createNodeCmd</i>. The syntax of the created command depends on the 
type of the node it creates.</p>

<p>If the first argument of the method is <i class="m">elementNode</i>, the created
command will create an element node. The tag name of the created

node is <i class="m">commandName</i> without namespace qualifiers. The syntax of the 












created command is:</p>

<pre class="syntax">
<b class="cmd">elementNodeCmd</b> <i class="m">?attributeName attributeValue ...? ?script?</i>
<b class="cmd">elementNodeCmd</b> <i class="m">?-attributeName attributeValue ...? ?script?</i>
<b class="cmd">elementNodeCmd</b> <i class="m">name_value_list script</i>
</pre>

................................................................................
will be stripped off.</p>

<p>Every <i class="m">elementNodeCmd</i> accepts an optional Tcl script as last
argument. This script is evaluated as recursive <i class="m">appendFromScript</i> script
with the node created by the <i class="m">elementNodeCmd</i> as parent of all nodes
created by the script.</p>

<p>If the first argument of the method is <i class="m">textNode</i>, the command will create


a text node. The syntax of the created command is:</p>

<pre class="syntax">
<b class="cmd">textNodeCmd</b> ?-disableOutputEscaping? <i class="m">data</i>
</pre>

<p>If the optional flag <i class="m">-disableOutputEscaping</i> is given, the
escaping of the ampersand character (&amp;) and the left angle bracket (&lt;)
inside the data is disabled. You should use this flag carefully.</p>

<p>If the first argument of the method is <i class="m">commentNode</i>, or 
<i class="m">cdataNode</i>, the command will create an comment node or CDATA section 
node. The syntax of the created command is:</p>

<pre class="syntax">
<b class="cmd">nodeCmd</b> <i class="m">data</i>
</pre>

<p>If the first argument of the method is <i class="m">piNode</i>, the command will
................................................................................
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">setStoreLineColumn</b> <i class="m">?boolean</i>?</dt>
          <dd>If switched on, the DOM nodes will contain line and column
position information for the original XML document after parsing. The default
is, not to store line and column position information.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">setNameCheck</b> <i class="m">?boolean</i>?</dt>
          <dd>If NameCheck is true, every method which expects an XML Name,
a full qualified name or a processing instructing target will check, if the
given string is valid according to his production rule. For commands created
with the <i class="m">createNodeCmd</i> method to be used in the context of
<i class="m">appendFromScript</i> the status of the flag at creation time
decides. If NameCheck is true at creation time, the command will
check his arguments, otherwise not. The <i class="m">setNameCheck</i>
set this flag. It returns the current NameCheck flag state. The
default state for NameCheck is true. </dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">setTextCheck</b> <i class="m">?boolean</i>?</dt>
          <dd>If TextCheck is true, every command which expects XML Chars,
a comment, a CDATA section value or a processing instructing value will check,
if the given string is valid according to his production rule. For commands
created with the <i class="m">createNodeCmd</i> method to be used in the
context of <i class="m">appendFromScript</i> the status of the flag at
creation time decides. If TextCheck is true at creation time, the
command will check his arguments, otherwise not.The
<i class="m">setTextCheck</i> method set this flag. It returns the current
TextCheck flag state. The default state for TextCheck is true.</dd>
      

        
          <dt>
<b class="cmd">dom</b> <b class="method">setObjectCommands</b> ?<i class="m">(automatic|token|command)</i>?</dt>
          <dd>Controls, if documents and nodes are created as tcl commands or
as token to be
used with the domNode and domDoc commands. If the mode is
'automatic', then methods used at tcl commands will create tcl
commands and methods used at doc or node tokes will create tokens. If
the mode is 'command' then always tcl commands will be created. If
the mode is 'token', then always token will be created. The method
returns the current mode. This method is an experimental interface.</dd>
      

        
          <dt>
<b class="cmd">dom</b> <b class="method">isName</b> <i class="m">name</i>
</dt>
          <dd>Returns 1, if <i class="m">name</i> is a valid XML Name according to
production 5 of the <a href="http://www.w3.org/TR/2004/REC-xml-20040204/#NT-NameChar">XML
            1.0</a> recommendation. This means, that <i class="m">name</i> is a valid
          XML element or attribute name. Otherwise it returns 0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isPIName</b> <i class="m">name</i>
</dt>
          <dd>Returns 1, if <i class="m">name</i> is a valid XML processing instruction
          target according to
production 17 of the <a href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</a> recommendation. Otherwise it returns 0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isNCName</b> <i class="m">name</i>
</dt>
          <dd>Returns 1, if <i class="m">name</i> is a valid NCName according
to production 4 of the of the <a href="http://www.w3.org/TR/1999/REC-xml-names-19990114">Namespaces in XML</a> recommendation. Otherwise it returns
0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isQName</b> <i class="m">name</i>
</dt>
          <dd>Returns 1, if <i class="m">name</i> is a valid QName according
to production 6 of the of the <a href="http://www.w3.org/TR/1999/REC-xml-names-19990114">Namespaces in XML</a> recommendation. Otherwise it returns
0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isCharData</b>
<i class="m">string</i>
</dt>
          <dd>Returns 1, if every character in <i class="m">string</i> is
a valid XML Char according to production 2 of the <a href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</a>
recommendation. Otherwise it returns 0.</dd>
        












        
          <dt>
<b class="cmd">dom</b> <b class="method">isComment</b>
<i class="m">string</i>
</dt>
          <dd>Returns 1, if <i class="m">string</i> is
a valid comment according to production 15 of the <a href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</a>
recommendation. Otherwise it returns 0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isCDATA</b>
<i class="m">string</i>
</dt>
          <dd>Returns 1, if <i class="m">string</i> is
valid according to production 20 of the <a href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</a>
recommendation. Otherwise it returns 0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isPIValue</b>
<i class="m">string</i>
</dt>
          <dd>Returns 1, if <i class="m">string</i> is
valid according to production 16 of the <a href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</a>
recommendation. Otherwise it returns 0.</dd>
        











































































      </dl>




  <h2><a name="SECTid0x80b3f38">KEYWORDS</a></h2><p class="keywords">
<a class="keyword" href="keyword-index.html#KW-XML">XML</a>, <a class="keyword" href="keyword-index.html#KW-DOM">DOM</a>, <a class="keyword" href="keyword-index.html#KW-document">document</a>, <a class="keyword" href="keyword-index.html#KW-node">node</a>, <a class="keyword" href="keyword-index.html#KW-parsing">parsing</a>
</p>
</div><div class="footer">
<hr class="navsep"><!-- footer.html: Standard navigational footer --><div class="navbar" align="center">
        <a class="navaid" href="index.html">tDOM Overview</a>
 ท	<a class="navaid" href="doc-index.html">Table of Contents</a>
 ท	<a class="navaid" href="category-index.html">Index</a>
 ท	<a class="navaid" href="keyword-index.html">Keywords</a>
</div>


</div>
</body>
</html>


|



|


|


|



|

>
|







 







|











|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|




>
>
>
>
>
>
>
>
>
>
>
>
>








|








|
|
>
|
|







|
|
|
|
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













|
|






|









|










|
|
>
|
|
|
>
|
>
|
|
>
|
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|



<
<
<
<
<
<
<
<
<
<
<
<
<



|

|
|
>
|
>
|
|
|
|
>
>
>

|
|
>
|
|
|
|
|
|
|

|
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|







 







|
>
>
|









|
|







 







|







|



|









|



|
|






|













|

|







|








|








|









|



>
>
>
>
>
>
>
>
>
>
>






|









|









|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
|


<
<
<
<
<
<
<
>
>



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
..
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
...
329
330
331
332
333
334
335
336
337
338
339













340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
...
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
...
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657







658
659
660
661
662
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: dom</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: tmml-html.xsl,v $ $Revision: 1.11 $"><meta charset="utf-8">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid0xc37960">NAME</a> ยท <a href="#SECTid0xbe8eb0">SYNOPSIS</a> ยท <a href="#SECTid0xb3ad40">DESCRIPTION </a> ยท <a href="#SECTid0xc83270">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
  <h2><a name="SECTid0xc37960">NAME</a></h2><p class="namesection">
<b class="names">dom - </b><br>Create an in-memory DOM tree from XML</p>
  
  <h2><a name="SECTid0xbe8eb0">SYNOPSIS</a></h2><pre class="syntax">package require tdom

<b class="cmd">dom</b> <i class="m">method</i> ?<i class="m">arg arg ...</i>?</pre>

  <h2><a name="SECTid0xb3ad40">DESCRIPTION </a></h2><p>This command provides the creation of DOM trees in memory. In
the usual case a string containing a XML information is parsed and converted
into a DOM tree. Other possible parse input may be HTML or JSON.
The <i class="m">method</i> indicates a specific subcommand. </p><p>The valid methods are:</p><dl class="commandlist">
        
          <dt>
<b class="cmd">dom</b> <b class="method">parse</b> ?<i class="m">options</i>? ?<i class="m">data</i>?</dt>
          <dd>Parses the XML information and builds up the DOM tree in memory
providing a Tcl object command to this DOM document object. Example:

      <pre class="example">
................................................................................
              
                <dt><b>-simple</b></dt> 
                <dd>If <i class="m">-simple</i> is
specified, a simple but fast parser is used (conforms not fully to XML
recommendation). That should double parsing and DOM generation speed. The
encoding of the data is not transformed inside the parser. The simple parser
does not respect any encoding information in the XML declaration. It skips over
the internal DTD subset and ignores any information in it. Therefore it doesn't
include defaulted attribute values into the tree, even if the according
attribute declaration is in the internal subset. It also doesn't expand
internal or external entity references other than the predefined entities and
character references.</dd>
              

              
                <dt><b>-html</b></dt>
                <dd>If <i class="m">-html</i> is specified, a fast HTML parser is 
used, which tries to even parse badly formed HTML into a DOM tree.</dd>
              

              
                <dt><b>-html5</b></dt>
                <dd>This option is only available if tDOM was build
                with --enable-html5. Try the <i class="m">featureinfo</i> method
                if you need to know if this feature is build in. If
                <i class="m">-html5</i> is specified, the gumbo lib html5 parser
                (https://github.com/google/gumbo-parser) is used to
                build the DOM tree. This is, as far as it goes, XML
                namespace-aware. Since this probably isn't wanted by a
                lot of users and adds only burden for no good in a lot
                of use cases <i class="m">-html5</i> can be combined with
                <i class="m">-ignorexmlns</i>, in which case all nodes and
                attributes in the DOM tree are not in an XML
                namespace. All tag and attribute names in the DOM tree
                will be lower case, even for foreign elements not in
                the xhtml, svg or mathml namespace. The DOM tree may
                include nodes, that the parser inserted because they
                are implied by the context (as &lt;head&gt;,
                &lt;tbody&gt;, etc.).</dd>
              

              
                <dt><b>-json</b></dt>
                <dd>If <i class="m">-json</i> is specified, the <i class="m">data</i> is
                expected to be a valid JSON string (according to RFC
                7159). The command returns an ordinary DOM document
                with nesting token inside the JSON data translated
                into tree hierarchy. If a JSON array value is itself
                an object or array then container element nodes named
                (in a default build) arraycontainer or
                objectcontainer, respectively, are inserted into the
                tree. The JSON serialization of this document (with
                the domDoc method <i class="m">asJSON</i>) is the same JSON
                information as the <i class="m">data</i>, preserving JSON
                datatypes, allowing non-unique member names of objects
                while preserving their order and the full range of
                JSON string values. JSON datatype handling is done
                with an additional property "sticking" at the doc and
                tree nodes. This property isn't contained in an XML
                serialization of the document. If you need to store
                the JSON data represented by a document, store the
                JSON serialization and parse it back from there. Apart
                from this JSON type information the returned doc
                command or handle is an ordinary DOM doc, which may be
                investigated or modified with the full range of the
                doc and node methods. Please note that the element
                node names and the text node values within the tree
                may be outside of what the appropriate XML productions
                allow.</dd>
              

              
                <dt>
<b>-jsonmaxnesting</b> <i>integer</i>
</dt>
                
                <dd>This option only has effect if used together
                with the <i class="m">-json</i> option. The current implementation uses recursive descent JSON parser. In order to avoid using excess stack space, any JSON input that has more than a certain levels of nesting is considered invalid. The default maximum nesting is 2000. The option -jsonmaxnesting allows the user to adjust that.</dd>
              
              
              
                <dt><b>--</b></dt> 
                <dd>The option <i class="m">--</i> marks the end of options.
                While respected in general this option is only needed
                in case of parsing JSON data, which may start with a
                "-".</dd>
              

              
                <dt><b>-keepEmpties</b></dt> 
                <dd>If <i class="m">-keepEmpties</i> is
specified then text nodes which contain only whitespaces will be part of the
resulting DOM tree. In default case (<i class="m">-keepEmpties</i> not given) those empty
text nodes are removed at parsing time.</dd>
              

              
                <dt><b>-keepCDATA</b></dt> 
                <dd>If <i class="m">-keepCDATA</i> is
specified then CDATA sections aren't added to the tree as text nodes
(and, if necessary, combined with sibling text nodes into one text
node) as without this option but are added as CDATA_SECTION_NODEs to
the tree. Please note that the resulting tree isn't prepared for XPath
selects or to be the source or the stylesheet of an XSLT
transformation. If not combined with <i class="m">-keepEmpties</i> only not
whitespace only CDATA sections will be added to the resulting DOM
                tree.</dd>
              
              
              
                <dt>
<b>-channel</b> <i>&lt;channel-ID&gt;</i>
</dt>
                
                <dd>If <i class="m">-channel &lt;channel-ID&gt;</i> is specified, the
input to be parsed is read from the specified channel. The encoding setting of
the channel (via fconfigure -encoding) is respected, ie the data read from the
channel are converted to UTF-8 according to the encoding settings before the
data is parsed.</dd>
              

              
                <dt>
<b>-baseurl</b> <i>&lt;baseURI&gt;</i>
</dt>
                
                <dd>If <i class="m">-baseurl &lt;baseURI&gt;</i> is specified,
                the baseURI is used as the base URI of the document.
                External entities references in the document are
                resolved relative to this base URI. This base URI is
                also stored within the DOM tree.</dd>
              

              
                <dt>
<b>-feedbackAfter</b> <i>&lt;#bytes&gt;</i>
</dt>
                
                <dd>If <i class="m">-feedbackAfter &lt;#bytes&gt;</i> is
                specified, the tcl command given by
                <i class="m">-feedbackcmd</i> is evaluated at the first element
                start within the document (or an external entity)
                after the start of the document or external entity or
                the last such call after #bytes. For backward
                compatibility if no -feedbackcmd is given but there is
                a tcl proc named ::dom::domParseFeedback this proc is

                used as -feedbackcmd. If there isn't such a proc and
                -feedbackAfter is used it is an error to not also use
                -feedbackcmd. If the called script raises error, then
                parsing will be aborted, the <i class="m">dom parse</i> call
                returns error, with the script error msg as error msg.
                If the called script <i class="m">return -code break</i>, the
                parsing will abort and the <i class="m">dom parse</i> call will
                return the empty string.</dd>
              

              
                <dt>
<b>-feedbackcmd</b> <i>&lt;script&gt;</i>
</dt>
                
                <dd>If <i class="m">-feedbackcmd &lt;script&gt;</i> is specified, the
script <i class="m">script</i> is evaluated at the first
element start within the document (or an external entity) after the
start of the document or external entity or the last such call after
#bytes value given by the <i class="m">-feedbackAfter</i> option. If
<i class="m">-feedbackAfter</i> isn't given, using this option
doesn't has any effect. If the called
script raises error, then parsing will be aborted, the
<i class="m">dom parse</i> call returns error, with the script
error msg as error msg. If the called script <i class="m">return
-code break</i>, the parsing will abort and the <i class="m">dom
parse</i> call will return the empty string.</dd>
              

              
                <dt>
<b>-externalentitycommand</b> <i>&lt;script&gt;</i>
</dt>
                
                <dd>If <i class="m">-externalentitycommand &lt;script&gt;</i> is
specified, the specified tcl script is called to resolve any external entities
of the document. The actual evaluated command consists of this option followed
by three arguments: the base uri, the system identifier of the entity and the
public identifier of the entity. The base uri and the public identifier may be
the empty list. The script has to return a tcl list consisting of three
elements. The first element of this list signals how the external entity is
returned to the processor. Currently the two allowed types are "string"
and "channel". The second element of the list has to be the (absolute) base URI
of the external entity to be parsed.  The third element of the list are data,
either the already read data out of the external entity as string in the case
of type "string", or the name of a tcl channel, in the case of type
"channel". Note that if the script returns a tcl channel, it will not be closed
by the processor.  It must be closed separately if it is no longer
needed.</dd>
              

              
                <dt>
<b>-useForeignDTD</b> <i>&lt;boolean&gt;</i>
</dt>
                
                <dd>If &lt;boolean&gt; is true and the document does not have
an external subset, the parser will call the -externalentitycommand script with
empty values for the systemId and publicID arguments. Please note that if
the document also doesn't have an internal subset, the
-startdoctypedeclcommand and -enddoctypedeclcommand scripts, if set, are not
called. The <i class="m">-useForeignDTD</i> respects </dd>
              

              
                <dt>
<b>-paramentityparsing</b> <i>&lt;always|never|notstandalone&gt;</i>
</dt>
                
                <dd>The <i class="m">-paramentityparsing</i> option controls,
                if the parser tries to resolve the external entities
                (including the external DTD subset) of the document
                while building the DOM tree.
                <i class="m">-paramentityparsing</i> requires an argument, which
                must be either "always", "never", or "notstandalone".
                The value "always" means that the parser tries to
                resolves (recursively) all external entities of the
                XML source. This is the default in case
                <i class="m">-paramentityparsing</i> is omitted. The value
                "never" means that only the given XML source is
                parsed and no external entity (including the external
                subset) will be resolved and parsed. The value
                "notstandalone" means, that all external entities will
                be resolved and parsed, with the exception of
                documents, which explicitly states standalone="yes" in
                their XML declaration.</dd>
              


              
                <dt><b>-ignorexmlns</b></dt>
                <dd>It is recommended, that you only use this option
                with the <i class="m">-html5</i> option. If this option is
                given, no node within the created DOM tree will be
                internally marked as placed into an XML Namespace,
                even if there is a default namespace in scope for
                un-prefixed elements or even if the element has a
                defined namespace prefix. One consequence is that
                XPath node expressions on such a DOM tree doesn't work
                as expected. Prefixed element nodes can't be selected
                and element nodes without prefix will be seen by XPath
                expressions as if they are not in any namespace (no
                matter if they are in fact should be in a default
                namespace).
                </dd>
              

            </dl>
<p></p>
</dd>
        

................................................................................
memory handling as explained above.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">createDocumentNode</b>
?<i class="m">objVar</i>?</dt>
          <dd>Creates a new 'empty' DOM document object without any element
node. <i class="m">objVar</i> controls the memory handling as explained above.</dd>
        














        
          <dt>
<b class="cmd">dom</b> <b class="method">createNodeCmd</b>
<i class="m">?-returnNodeCmd?</i> <i class="m">?-tagName name?</i> <i class="m">?-jsonType jsonType?</i> <i class="m">?-namespace URI?</i> <i class="m">(element|comment|text|cdata|pi)Node</i> <i class="m">commandName</i>
</dt>
          <dd>This method creates Tcl commands, which in turn create
          tDOM nodes. Tcl commands created by this command are only
          available inside a script given to the domNode methods
          <i class="m">appendFromScript</i> or <i class="m">insertBeforeFromScript</i>. If
          a command created with <i class="m">createNodeCmd</i> is invoked in
          any other context, it will return error. The created command
          <i class="m">commandName</i> replaces any existing command or
          procedure with that name. If the <i class="m">commandName</i> includes
          any namespace qualifiers, it is created in the specified
          namespace. The <i class="m">-tagName</i> option is only allowed for
          the elementNode type. The <i class="m">-jsonType</i> option is only
          allowed for elementNode and textNode types.

<p>If such command is invoked inside a script given as argument to the
domNode method <i class="m">appendFromScript</i> or
<i class="m">insertBeforeFromScript</i> it creates a new node and appends this
node at the end of the child list of the invoking element node. If the
option <i class="m">-returnNodeCmd</i> was given, the command returns the
created node as Tcl command. If this option was omitted, the command
returns nothing. Each command creates always the same type of node.
Which type of node is created by the command is determined by the
first argument to the <i class="m">createNodeCmd</i>. The syntax of the created
command depends on the type of the node it creates.</p>

<p>If the command type to create is <i class="m">elementNode</i>, the created
command will create an element node, if called. Without the
<i class="m">-tagName</i> option the tag name of the created node is
<i class="m">commandName</i> without namespace qualifiers. If the
<i class="m">-tagName</i> option was given then the created command the created
elements will have this tag name. If the <i class="m">-jsonType</i> option was
given then the created node elements will have the given JSON type. If
the <i class="m">-namespace</i> option is given the created element node will be
XML namespaced and in the namespace given by the option. The element
name will be literal as given either by the command name or the
<i class="m">-tagname</i> option, if that was given. An appropriate XML
namespace declaration will be automatically added, to bind the prefix
(if the element name has one) or the default namespace (if the element
name hasn't a prefix) to the namespace if such a binding isn't in
scope.</p>

<p>The syntax of the created command is:</p>

<pre class="syntax">
<b class="cmd">elementNodeCmd</b> <i class="m">?attributeName attributeValue ...? ?script?</i>
<b class="cmd">elementNodeCmd</b> <i class="m">?-attributeName attributeValue ...? ?script?</i>
<b class="cmd">elementNodeCmd</b> <i class="m">name_value_list script</i>
</pre>

................................................................................
will be stripped off.</p>

<p>Every <i class="m">elementNodeCmd</i> accepts an optional Tcl script as last
argument. This script is evaluated as recursive <i class="m">appendFromScript</i> script
with the node created by the <i class="m">elementNodeCmd</i> as parent of all nodes
created by the script.</p>

<p>If the first argument of the method is <i class="m">textNode</i>, the command
will create a text node. If the <i class="m">-jsonType</i> option was given then
the created text node will have that JSON type. The syntax of the
created command is:</p>

<pre class="syntax">
<b class="cmd">textNodeCmd</b> ?-disableOutputEscaping? <i class="m">data</i>
</pre>

<p>If the optional flag <i class="m">-disableOutputEscaping</i> is given, the
escaping of the ampersand character (&amp;) and the left angle bracket (&lt;)
inside the data is disabled. You should use this flag carefully.</p>

<p>If the first argument of the method is <i class="m">commentNode</i> or 
<i class="m">cdataNode</i> the command will create an comment node or CDATA section 
node. The syntax of the created command is:</p>

<pre class="syntax">
<b class="cmd">nodeCmd</b> <i class="m">data</i>
</pre>

<p>If the first argument of the method is <i class="m">piNode</i>, the command will
................................................................................
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">setStoreLineColumn</b> <i class="m">?boolean</i>?</dt>
          <dd>If switched on, the DOM nodes will contain line and column
position information for the original XML document after parsing. The default
is not to store line and column position information.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">setNameCheck</b> <i class="m">?boolean</i>?</dt>
          <dd>If NameCheck is true, every method which expects an XML Name,
a full qualified name or a processing instructing target will check, if the
given string is valid according to its production rule. For commands created
with the <i class="m">createNodeCmd</i> method to be used in the context of
<i class="m">appendFromScript</i> the status of the flag at creation time
decides. If NameCheck is true at creation time, the command will
check its arguments, otherwise not. The <i class="m">setNameCheck</i>
set this flag. It returns the current NameCheck flag state. The
default state for NameCheck is true. </dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">setTextCheck</b> <i class="m">?boolean</i>?</dt>
          <dd>If TextCheck is true, every command which expects XML Chars,
a comment, a CDATA section value or a processing instructing value will check,
if the given string is valid according to its production rule. For commands
created with the <i class="m">createNodeCmd</i> method to be used in the
context of <i class="m">appendFromScript</i> the status of the flag at
creation time decides. If TextCheck is true at creation time, the
command will check its arguments, otherwise not.The
<i class="m">setTextCheck</i> method sets this flag. It returns the current
TextCheck flag state. The default state for TextCheck is true.</dd>
      

        
          <dt>
<b class="cmd">dom</b> <b class="method">setObjectCommands</b> ?<i class="m">(automatic|token|command)</i>?</dt>
          <dd>Controls if documents and nodes are created as tcl commands or
as token to be
used with the domNode and domDoc commands. If the mode is
'automatic', then methods used at tcl commands will create tcl
commands and methods used at doc or node tokes will create tokens. If
the mode is 'command' then always tcl commands will be created. If
the mode is 'token', then always token will be created. The method
returns the current mode. This method is an experimental interface.</dd>
      

        
          <dt>
<b class="cmd">dom</b> <b class="method">isName</b> <i class="m">name</i>
</dt>
          <dd>Returns 1 if <i class="m">name</i> is a valid XML Name according to
production 5 of the <a href="http://www.w3.org/TR/2004/REC-xml-20040204/#NT-NameChar">XML
            1.0</a> recommendation. This means that <i class="m">name</i> is a valid
          XML element or attribute name. Otherwise it returns 0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isPIName</b> <i class="m">name</i>
</dt>
          <dd>Returns 1 if <i class="m">name</i> is a valid XML processing instruction
          target according to
production 17 of the <a href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</a> recommendation. Otherwise it returns 0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isNCName</b> <i class="m">name</i>
</dt>
          <dd>Returns 1 if <i class="m">name</i> is a valid NCName according
to production 4 of the of the <a href="http://www.w3.org/TR/1999/REC-xml-names-19990114">Namespaces in XML</a> recommendation. Otherwise it returns
0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isQName</b> <i class="m">name</i>
</dt>
          <dd>Returns 1 if <i class="m">name</i> is a valid QName according
to production 6 of the of the <a href="http://www.w3.org/TR/1999/REC-xml-names-19990114">Namespaces in XML</a> recommendation. Otherwise it returns
0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isCharData</b>
<i class="m">string</i>
</dt>
          <dd>Returns 1 if every character in <i class="m">string</i> is
a valid XML Char according to production 2 of the <a href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</a>
recommendation. Otherwise it returns 0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isBMPCharData</b>
<i class="m">string</i>
</dt>
          <dd>Returns 1 if every character in <i class="m">string</i> is
a valid XML Char with a Unicode code point within the Basic
Multilingual Plane (that means, that every character within the string
is at most 3 bytes long). Otherwise it returns 0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isComment</b>
<i class="m">string</i>
</dt>
          <dd>Returns 1 if <i class="m">string</i> is
a valid comment according to production 15 of the <a href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</a>
recommendation. Otherwise it returns 0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isCDATA</b>
<i class="m">string</i>
</dt>
          <dd>Returns 1 if <i class="m">string</i> is
valid according to production 20 of the <a href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</a>
recommendation. Otherwise it returns 0.</dd>
        

        
          <dt>
<b class="cmd">dom</b> <b class="method">isPIValue</b>
<i class="m">string</i>
</dt>
          <dd>Returns 1 if <i class="m">string</i> is
valid according to production 16 of the <a href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</a>
recommendation. Otherwise it returns 0.</dd>
        

        
            <dt>
<b class="cmd">dom</b> <b class="method">featureinfo</b> <i class="m">feature</i>
</dt>
            <dd>This method provides information about the used
            build options and the expat version. The valid values for
            the <i class="m">feature</i> argument are:
            <dl class="optlist">
                
                    <dt><b>expatversion</b></dt>
                    <dd>Returns the version of the underlyling expat
                    version as string, something like
                    "exapt_2.1.0". This is what the expat API
                    function XML_ExpatVersion() returns.</dd>
                
                
                    <dt><b>expatmajorversion</b></dt>
                    <dd>Returns the major version of the underlyling
                    expat version as integer.</dd>
                
                
                    <dt><b>expatminorversion</b></dt>
                    <dd>Returns the minor version of the underlyling
                    expat version as integer.</dd>
                
                
                    <dt><b>expatmicroversion</b></dt>
                    <dd>Returns the micro version of the underlyling
                    expat version as integer.</dd>
                
                
                    <dt><b>dtd</b></dt>
                    <dd>Returns as boolean if build with
                    <i class="m">--enable-dtd</i>.</dd>
                
                
                    <dt><b>ns</b></dt>
                    <dd>Returns as boolean if build with
                    <i class="m">--enable-ns</i>.</dd>
                
                
                    <dt><b>unknown</b></dt>
                    <dd>Returns as boolean if build with
                    <i class="m">--enable-unknown</i>.</dd>
                
                
                    <dt><b>tdomalloc</b></dt>
                    <dd>Returns as boolean if build with
                    <i class="m">--enable-tdomalloc</i>.</dd>
                
                
                    <dt><b>lessns</b></dt>
                    <dd>Returns as boolean if build with
                    <i class="m">--enable-lessns</i>.</dd>
                
                
                    <dt><b>TCL_UTF_MAX</b></dt>
                    <dd>Returns the TCL_UTF_MAX value of the tcl
                    core, tDOM was build with as integer</dd>
                
                
                    <dt><b>html5</b></dt>
                    <dd>Returns as boolean, if build with
                    <i class="m">--enable-html5</i>.</dd>
                
                
                    <dt><b>versionhash</b></dt>
                    <dd>Returns the fossil repository version hash.</dd>
                
                
                    <dt><b>pullparser</b></dt>
                    <dd>Returns as boolean if the pullparser command
                    is build in.</dd>
                
            </dl>
            </dd>   
        
    </dl>

<h2><a name="SECTid0xc83270">KEYWORDS</a></h2><p class="keywords">
<a class="keyword" href="keyword-index.html#KW-XML">XML</a>, <a class="keyword" href="keyword-index.html#KW-DOM">DOM</a>, <a class="keyword" href="keyword-index.html#KW-document">document</a>, <a class="keyword" href="keyword-index.html#KW-node">node</a>, <a class="keyword" href="keyword-index.html#KW-parsing">parsing</a>
</p>







</div><hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>
</div>
</body>
</html>

Changes to doc/dom.n.

166
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182
...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239





















































240
241
242
243
244










245
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260




261
262





















263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

289
290
291

292

293
294

295
296

297
298














299
300
301
302
303
304
305
...
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329


330
331
332
333
334



335
336
337
338

339
340
341
342
343
344
345
346
347
348

349












350
351
352
353
354
355
356
357
...
369
370
371
372
373
374
375
376


377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
...
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478






479
480
481
482
483
484
485
486
487
488
489
490
491
492















































493
494
package require tdom

\&\fBdom\fP \fImethod\fR ?\fIarg arg ...\fR?
.fi
.BE
.SH "DESCRIPTION "
.PP
This command provides the creation of complete DOM trees in memory. In
the usual case a string containing a XML information is parsed and converted

into a DOM tree. \fImethod\fR indicates a specific subcommand.
.PP
The valid methods are:
.TP
\&\fB\fBdom\fP \fBparse\fP ?\fIoptions\fB? ?\fIdata\fB?
\&\fRParses the XML information and builds up the DOM tree in memory
providing a Tcl object command to this DOM document object. Example:

................................................................................
The valid options are:
.IP "\fB-simple\fR"
If \fI-simple\fR is
specified, a simple but fast parser is used (conforms not fully to XML
recommendation). That should double parsing and DOM generation speed. The
encoding of the data is not transformed inside the parser. The simple parser
does not respect any encoding information in the XML declaration. It skips over
the internal DTD subset and ignores any information in it. Therefor it doesn't
include defaulted attribute values into the tree, even if the according
attribute declaration is in the internal subset. It also doesn't expand
internal or external entity references other than the predefined entities and
character references.
.IP "\fB-html\fR"
If \fI-html\fR is specified, a fast HTML parser is
used, which tries to even parse badly formed HTML into a DOM tree.





















































.IP "\fB-keepEmpties\fR"
If \fI-keepEmpties\fR is
specified, text nodes, which contain only whitespaces, will be part of the
resulting DOM tree. In default case (\fI-keepEmpties\fR not given) those empty
text nodes are removed at parsing time.










.IP "\fB-channel  \fI<channel-ID>\fP\fR"
If \fI-channel <channel-ID>\fR is specified, the
input to be parsed is read from the specified channel. The encoding setting of
the channel (via fconfigure -encoding) is respected, ie the data read from the
channel are converted to UTF-8 according to the encoding settings, befor the
data is parsed.
.IP "\fB-baseurl  \fI<baseURI>\fP\fR"
If \fI-baseurl <baseURI>\fR is specified, the
baseURI is used as the base URI of the document. External entities referenced

in the document are resolved relative to this base URI. This base URI is also
stored within the DOM tree.
.IP "\fB-feedbackAfter  \fI<#bytes>\fP\fR"
If \fI-feedbackAfter <#bytes>\fR is specified, the
tcl command ::dom::domParseFeedback is evaluated after parsing every #bytes. If
you use this option, you have to create a tcl proc named
::dom::domParseFeedback, otherwise you will get an error. Please notice, that




the calls of ::dom::domParseFeedback are not done exactly every #bytes, but
always at the first element start after every #bytes.





















.IP "\fB-externalentitycommand  \fI<script>\fP\fR"
If \fI-externalentitycommand <script>\fR is
specified, the specified tcl script is called to resolve any external entities
of the document. The actual evaluated command consists of this option followed
by three arguments: the base uri, the system identifier of the entity and the
public identifier of the entity. The base uri and the public identifier may be
the empty list. The script has to return a tcl list consisting of three
elements. The first element of this list signals, how the external entity is
returned to the processor. At the moment, the two allowed types are "string"
and "channel". The second element of the list has to be the (absolute) base URI
of the external entity to be parsed.  The third element of the list are data,
either the already read data out of the external entity as string in the case
of type "string", or the name of a tcl channel, in the case of type
"channel". Note that if the script returns a tcl channel, it will not be closed
by the processor.  It must be closed separately if it is no longer
required.
.IP "\fB-useForeignDTD  \fI<boolean>\fP\fR"
If <boolean> is true and the document does not have
an external subset, the parser will call the -externalentitycommand script with
empty values for the systemId and publicID arguments. Pleace notice, that, if
the document also doesn't have an internal subset, the
-startdoctypedeclcommand and -enddoctypedeclcommand scripts, if set, are not
called. The \fI-useForeignDTD\fR respects
.IP "\fB-paramentityparsing  \fI<always|never|notstandalone>\fP\fR"
The \fI-paramentityparsing\fR option controls, if the
parser tries to resolve the external entities (including the external DTD

subset) of the document, while building the DOM
tree. \fI-paramentityparsing\fR requires an argument, which must be either
"always", "never", or "notstandalone". The value "always" means, that the

parser tries to resolves (recursively) all external entities of the XML

source. This is the default, in case \fI-paramentityparsing\fR is omitted. The
value "never" means, that only the given XML source is parsed and no external

entity (including the external subset) will be resolved and parsed. The value
"notstandalone" means, that all external entities will be resolved and parsed,

with the execption of documents, which explicitly states standalone="yes" in
their XML declaration.














.PP
.RE
.TP
\&\fB\fBdom\fP \fBcreateDocument\fP \fIdocElemName\fB ?\fIobjVar\fB?
\&\fRCreates a new DOM document object with one element node with
node name \fIdocElemName\fR. The \fIobjVar\fR controls the
memory handling as explained above.
................................................................................
\&\fB\fBdom\fP \fBcreateDocumentNS\fP \fIuri\fB \fIdocElemName\fB ?\fIobjVar\fB?
\&\fRCreates a new DOM document object with one element node with
node name \fIdocElemName\fR. \fIUri\fR gives the namespace of the
document element to create. The \fIobjVar\fR controls the
memory handling as explained above.
.TP
\&\fB\fBdom\fP \fBcreateDocumentNode\fP ?\fIobjVar\fB?
\&\fRCreates a new, 'empty' DOM document object without any element
node. \fIobjVar\fR controls the memory handling as explained above.
.TP
\&\fB\fBdom\fP \fBsetResultEncoding\fP ?\fIencodingName\fB?
\&\fRIf \fIencodingName\fR is not given the current global
result encoding is returned.  Otherwise the global result encoding is set to
\&\fIencodingName\fR.  All character data, attribute values, etc. will
then be converted from UTF-8, which is delivered from the Expat XML parser, to
the given 8 bit encoding at XML/DOM parse time.  Valid values for
\&\fIencodingName\fR are: utf-8, ascii, cp1250, cp1251, cp1252, cp1253,
cp1254, cp1255, cp1256, cp437, cp850, en, iso8859-1, iso8859-2, iso8859-3,
iso8859-4, iso8859-5, iso8859-6, iso8859-7, iso8859-8, iso8859-9, koi8-r.
.TP
\&\fB\fBdom\fP \fBcreateNodeCmd\fP \fI?-returnNodeCmd?\fB \fI(element|comment|text|cdata|pi)Node\fB \fIcommandName\fB
\&\fRThis method creates Tcl commands, which in turn create tDOM nodes.
Tcl commands created by this command are only avaliable inside a script given to the


domNode method \fIappendFromScript\fR. If a command created with
\&\fIcreateNodeCmd\fR is invoked in any other context, it will return error. The
created command \fIcommandName\fR replaces any existing command or procedure
with that name. If the \fIcommandName\fR includes any namespace qualifiers,
it is created in the specified namespace.



.RS
.PP
If such command is invoked inside a script given as argument to
the domNode method \fIappendFromScript\fR, it creates a new node and

appends this node at the end of the child list of the invoking element
node. If the option \fI-returnNodeCmd\fR was given, the command returns the
created node as Tcl command. If this option was omitted, the command returns
nothing. Each command creates always the same type of node. Which type of
node is created by the command is determined by the first argument to the
\&\fIcreateNodeCmd\fR. The syntax of the created command depends on the
type of the node it creates.
.PP
If the first argument of the method is \fIelementNode\fR, the created
command will create an element node. The tag name of the created

node is \fIcommandName\fR without namespace qualifiers. The syntax of the












created command is:



.CS

\&\fBelementNodeCmd\fP \fI?attributeName attributeValue ...? ?script?\fR
\&\fBelementNodeCmd\fP \fI?-attributeName attributeValue ...? ?script?\fR
................................................................................
will be stripped off.
.PP
Every \fIelementNodeCmd\fR accepts an optional Tcl script as last
argument. This script is evaluated as recursive \fIappendFromScript\fR script
with the node created by the \fIelementNodeCmd\fR as parent of all nodes
created by the script.
.PP
If the first argument of the method is \fItextNode\fR, the command will create


a text node. The syntax of the created command is:



.CS

\&\fBtextNodeCmd\fP ?-disableOutputEscaping? \fIdata\fR

.CE
.PP
If the optional flag \fI-disableOutputEscaping\fR is given, the
escaping of the ampersand character (&) and the left angle bracket (<)
inside the data is disabled. You should use this flag carefully.
.PP
If the first argument of the method is \fIcommentNode\fR, or
\&\fIcdataNode\fR, the command will create an comment node or CDATA section
node. The syntax of the created command is:



.CS

\&\fBnodeCmd\fP \fIdata\fR
................................................................................

.CE
.RE
.TP
\&\fB\fBdom\fP \fBsetStoreLineColumn\fP \fI?boolean\fB?
\&\fRIf switched on, the DOM nodes will contain line and column
position information for the original XML document after parsing. The default
is, not to store line and column position information.
.TP
\&\fB\fBdom\fP \fBsetNameCheck\fP \fI?boolean\fB?
\&\fRIf NameCheck is true, every method which expects an XML Name,
a full qualified name or a processing instructing target will check, if the
given string is valid according to his production rule. For commands created
with the \fIcreateNodeCmd\fR method to be used in the context of
\&\fIappendFromScript\fR the status of the flag at creation time
decides. If NameCheck is true at creation time, the command will
check his arguments, otherwise not. The \fIsetNameCheck\fR
set this flag. It returns the current NameCheck flag state. The
default state for NameCheck is true.
.TP
\&\fB\fBdom\fP \fBsetTextCheck\fP \fI?boolean\fB?
\&\fRIf TextCheck is true, every command which expects XML Chars,
a comment, a CDATA section value or a processing instructing value will check,
if the given string is valid according to his production rule. For commands
created with the \fIcreateNodeCmd\fR method to be used in the
context of \fIappendFromScript\fR the status of the flag at
creation time decides. If TextCheck is true at creation time, the
command will check his arguments, otherwise not.The
\&\fIsetTextCheck\fR method set this flag. It returns the current
TextCheck flag state. The default state for TextCheck is true.
.TP
\&\fB\fBdom\fP \fBsetObjectCommands\fP ?\fI(automatic|token|command)\fB?
\&\fRControls, if documents and nodes are created as tcl commands or
as token to be
used with the domNode and domDoc commands. If the mode is
\&'automatic', then methods used at tcl commands will create tcl
commands and methods used at doc or node tokes will create tokens. If
the mode is 'command' then always tcl commands will be created. If
the mode is 'token', then always token will be created. The method
returns the current mode. This method is an experimental interface.
.TP
\&\fB\fBdom\fP \fBisName\fP \fIname\fB
\&\fRReturns 1, if \fIname\fR is a valid XML Name according to
production 5 of the XML
1.0 recommendation. This means, that \fIname\fR is a valid
XML element or attribute name. Otherwise it returns 0.
.TP
\&\fB\fBdom\fP \fBisPIName\fP \fIname\fB
\&\fRReturns 1, if \fIname\fR is a valid XML processing instruction
target according to
production 17 of the XML 1.0 recommendation. Otherwise it returns 0.
.TP
\&\fB\fBdom\fP \fBisNCName\fP \fIname\fB
\&\fRReturns 1, if \fIname\fR is a valid NCName according
to production 4 of the of the Namespaces in XML recommendation. Otherwise it returns
0.
.TP
\&\fB\fBdom\fP \fBisQName\fP \fIname\fB
\&\fRReturns 1, if \fIname\fR is a valid QName according
to production 6 of the of the Namespaces in XML recommendation. Otherwise it returns
0.
.TP
\&\fB\fBdom\fP \fBisCharData\fP \fIstring\fB
\&\fRReturns 1, if every character in \fIstring\fR is
a valid XML Char according to production 2 of the XML 1.0
recommendation. Otherwise it returns 0.
.TP






\&\fB\fBdom\fP \fBisComment\fP \fIstring\fB
\&\fRReturns 1, if \fIstring\fR is
a valid comment according to production 15 of the XML 1.0
recommendation. Otherwise it returns 0.
.TP
\&\fB\fBdom\fP \fBisCDATA\fP \fIstring\fB
\&\fRReturns 1, if \fIstring\fR is
valid according to production 20 of the XML 1.0
recommendation. Otherwise it returns 0.
.TP
\&\fB\fBdom\fP \fBisPIValue\fP \fIstring\fB
\&\fRReturns 1, if \fIstring\fR is
valid according to production 16 of the XML 1.0
recommendation. Otherwise it returns 0.















































.SH KEYWORDS
XML, DOM, document, node, parsing







|

>
|







 







|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|


>
>
>
>
>
>
>
>
>
>




|


|
|
>
|
|

|
<
|
|
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|
|






|



|




|
|
>
|
|
|
>
|
>
|
|
>
|
|
>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|


<
<
<
<
<
<
<
<
<
<
|
|
|
>
>
|
|
|
|
|
>
>
>


|
|
>
|
|
|
|
|
|
|

|
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|







 







|
>
>
|













|
|







 







|




|



|






|



|
|



|









|

|



|




|




|




|



>
>
>
>
>
>

|




|




|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
...
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
...
414
415
416
417
418
419
420
421
422
423










424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
...
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
...
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
package require tdom

\&\fBdom\fP \fImethod\fR ?\fIarg arg ...\fR?
.fi
.BE
.SH "DESCRIPTION "
.PP
This command provides the creation of DOM trees in memory. In
the usual case a string containing a XML information is parsed and converted
into a DOM tree. Other possible parse input may be HTML or JSON.
The \fImethod\fR indicates a specific subcommand.
.PP
The valid methods are:
.TP
\&\fB\fBdom\fP \fBparse\fP ?\fIoptions\fB? ?\fIdata\fB?
\&\fRParses the XML information and builds up the DOM tree in memory
providing a Tcl object command to this DOM document object. Example:

................................................................................
The valid options are:
.IP "\fB-simple\fR"
If \fI-simple\fR is
specified, a simple but fast parser is used (conforms not fully to XML
recommendation). That should double parsing and DOM generation speed. The
encoding of the data is not transformed inside the parser. The simple parser
does not respect any encoding information in the XML declaration. It skips over
the internal DTD subset and ignores any information in it. Therefore it doesn't
include defaulted attribute values into the tree, even if the according
attribute declaration is in the internal subset. It also doesn't expand
internal or external entity references other than the predefined entities and
character references.
.IP "\fB-html\fR"
If \fI-html\fR is specified, a fast HTML parser is
used, which tries to even parse badly formed HTML into a DOM tree.
.IP "\fB-html5\fR"
This option is only available if tDOM was build
with --enable-html5. Try the \fIfeatureinfo\fR method
if you need to know if this feature is build in. If
\&\fI-html5\fR is specified, the gumbo lib html5 parser
(https://github.com/google/gumbo-parser) is used to
build the DOM tree. This is, as far as it goes, XML
namespace-aware. Since this probably isn't wanted by a
lot of users and adds only burden for no good in a lot
of use cases \fI-html5\fR can be combined with
\&\fI-ignorexmlns\fR, in which case all nodes and
attributes in the DOM tree are not in an XML
namespace. All tag and attribute names in the DOM tree
will be lower case, even for foreign elements not in
the xhtml, svg or mathml namespace. The DOM tree may
include nodes, that the parser inserted because they
are implied by the context (as <head>,
<tbody>, etc.).
.IP "\fB-json\fR"
If \fI-json\fR is specified, the \fIdata\fR is
expected to be a valid JSON string (according to RFC
7159). The command returns an ordinary DOM document
with nesting token inside the JSON data translated
into tree hierarchy. If a JSON array value is itself
an object or array then container element nodes named
(in a default build) arraycontainer or
objectcontainer, respectively, are inserted into the
tree. The JSON serialization of this document (with
the domDoc method \fIasJSON\fR) is the same JSON
information as the \fIdata\fR, preserving JSON
datatypes, allowing non-unique member names of objects
while preserving their order and the full range of
JSON string values. JSON datatype handling is done
with an additional property "sticking" at the doc and
tree nodes. This property isn't contained in an XML
serialization of the document. If you need to store
the JSON data represented by a document, store the
JSON serialization and parse it back from there. Apart
from this JSON type information the returned doc
command or handle is an ordinary DOM doc, which may be
investigated or modified with the full range of the
doc and node methods. Please note that the element
node names and the text node values within the tree
may be outside of what the appropriate XML productions
allow.
.IP "\fB-jsonmaxnesting  \fIinteger\fP\fR"
This option only has effect if used together
with the \fI-json\fR option. The current implementation uses recursive descent JSON parser. In order to avoid using excess stack space, any JSON input that has more than a certain levels of nesting is considered invalid. The default maximum nesting is 2000. The option -jsonmaxnesting allows the user to adjust that.
.IP "\fB--\fR"
The option \fI--\fR marks the end of options.
While respected in general this option is only needed
in case of parsing JSON data, which may start with a
"-".
.IP "\fB-keepEmpties\fR"
If \fI-keepEmpties\fR is
specified then text nodes which contain only whitespaces will be part of the
resulting DOM tree. In default case (\fI-keepEmpties\fR not given) those empty
text nodes are removed at parsing time.
.IP "\fB-keepCDATA\fR"
If \fI-keepCDATA\fR is
specified then CDATA sections aren't added to the tree as text nodes
(and, if necessary, combined with sibling text nodes into one text
node) as without this option but are added as CDATA_SECTION_NODEs to
the tree. Please note that the resulting tree isn't prepared for XPath
selects or to be the source or the stylesheet of an XSLT
transformation. If not combined with \fI-keepEmpties\fR only not
whitespace only CDATA sections will be added to the resulting DOM
tree.
.IP "\fB-channel  \fI<channel-ID>\fP\fR"
If \fI-channel <channel-ID>\fR is specified, the
input to be parsed is read from the specified channel. The encoding setting of
the channel (via fconfigure -encoding) is respected, ie the data read from the
channel are converted to UTF-8 according to the encoding settings before the
data is parsed.
.IP "\fB-baseurl  \fI<baseURI>\fP\fR"
If \fI-baseurl <baseURI>\fR is specified,
the baseURI is used as the base URI of the document.
External entities references in the document are
resolved relative to this base URI. This base URI is
also stored within the DOM tree.
.IP "\fB-feedbackAfter  \fI<#bytes>\fP\fR"
If \fI-feedbackAfter <#bytes>\fR is

specified, the tcl command given by
\&\fI-feedbackcmd\fR is evaluated at the first element
start within the document (or an external entity)
after the start of the document or external entity or
the last such call after #bytes. For backward
compatibility if no -feedbackcmd is given but there is
a tcl proc named ::dom::domParseFeedback this proc is

used as -feedbackcmd. If there isn't such a proc and
-feedbackAfter is used it is an error to not also use
-feedbackcmd. If the called script raises error, then
parsing will be aborted, the \fIdom parse\fR call
returns error, with the script error msg as error msg.
If the called script \fIreturn -code break\fR, the
parsing will abort and the \fIdom parse\fR call will
return the empty string.
.IP "\fB-feedbackcmd  \fI<script>\fP\fR"
If \fI-feedbackcmd <script>\fR is specified, the
script \fIscript\fR is evaluated at the first
element start within the document (or an external entity) after the
start of the document or external entity or the last such call after
#bytes value given by the \fI-feedbackAfter\fR option. If
\&\fI-feedbackAfter\fR isn't given, using this option
doesn't has any effect. If the called
script raises error, then parsing will be aborted, the
\&\fIdom parse\fR call returns error, with the script
error msg as error msg. If the called script \fIreturn
-code break\fR, the parsing will abort and the \fIdom
parse\fR call will return the empty string.
.IP "\fB-externalentitycommand  \fI<script>\fP\fR"
If \fI-externalentitycommand <script>\fR is
specified, the specified tcl script is called to resolve any external entities
of the document. The actual evaluated command consists of this option followed
by three arguments: the base uri, the system identifier of the entity and the
public identifier of the entity. The base uri and the public identifier may be
the empty list. The script has to return a tcl list consisting of three
elements. The first element of this list signals how the external entity is
returned to the processor. Currently the two allowed types are "string"
and "channel". The second element of the list has to be the (absolute) base URI
of the external entity to be parsed.  The third element of the list are data,
either the already read data out of the external entity as string in the case
of type "string", or the name of a tcl channel, in the case of type
"channel". Note that if the script returns a tcl channel, it will not be closed
by the processor.  It must be closed separately if it is no longer
needed.
.IP "\fB-useForeignDTD  \fI<boolean>\fP\fR"
If <boolean> is true and the document does not have
an external subset, the parser will call the -externalentitycommand script with
empty values for the systemId and publicID arguments. Please note that if
the document also doesn't have an internal subset, the
-startdoctypedeclcommand and -enddoctypedeclcommand scripts, if set, are not
called. The \fI-useForeignDTD\fR respects
.IP "\fB-paramentityparsing  \fI<always|never|notstandalone>\fP\fR"
The \fI-paramentityparsing\fR option controls,
if the parser tries to resolve the external entities
(including the external DTD subset) of the document
while building the DOM tree.
\&\fI-paramentityparsing\fR requires an argument, which
must be either "always", "never", or "notstandalone".
The value "always" means that the parser tries to
resolves (recursively) all external entities of the
XML source. This is the default in case
\&\fI-paramentityparsing\fR is omitted. The value
"never" means that only the given XML source is
parsed and no external entity (including the external
subset) will be resolved and parsed. The value
"notstandalone" means, that all external entities will
be resolved and parsed, with the exception of
documents, which explicitly states standalone="yes" in
their XML declaration.
.IP "\fB-ignorexmlns\fR"
It is recommended, that you only use this option
with the \fI-html5\fR option. If this option is
given, no node within the created DOM tree will be
internally marked as placed into an XML Namespace,
even if there is a default namespace in scope for
un-prefixed elements or even if the element has a
defined namespace prefix. One consequence is that
XPath node expressions on such a DOM tree doesn't work
as expected. Prefixed element nodes can't be selected
and element nodes without prefix will be seen by XPath
expressions as if they are not in any namespace (no
matter if they are in fact should be in a default
namespace).
.PP
.RE
.TP
\&\fB\fBdom\fP \fBcreateDocument\fP \fIdocElemName\fB ?\fIobjVar\fB?
\&\fRCreates a new DOM document object with one element node with
node name \fIdocElemName\fR. The \fIobjVar\fR controls the
memory handling as explained above.
................................................................................
\&\fB\fBdom\fP \fBcreateDocumentNS\fP \fIuri\fB \fIdocElemName\fB ?\fIobjVar\fB?
\&\fRCreates a new DOM document object with one element node with
node name \fIdocElemName\fR. \fIUri\fR gives the namespace of the
document element to create. The \fIobjVar\fR controls the
memory handling as explained above.
.TP
\&\fB\fBdom\fP \fBcreateDocumentNode\fP ?\fIobjVar\fB?
\&\fRCreates a new 'empty' DOM document object without any element
node. \fIobjVar\fR controls the memory handling as explained above.
.TP










\&\fB\fBdom\fP \fBcreateNodeCmd\fP \fI?-returnNodeCmd?\fB \fI?-tagName name?\fB \fI?-jsonType jsonType?\fB \fI?-namespace URI?\fB \fI(element|comment|text|cdata|pi)Node\fB \fIcommandName\fB
\&\fRThis method creates Tcl commands, which in turn create
tDOM nodes. Tcl commands created by this command are only
available inside a script given to the domNode methods
\&\fIappendFromScript\fR or \fIinsertBeforeFromScript\fR. If
a command created with \fIcreateNodeCmd\fR is invoked in
any other context, it will return error. The created command
\&\fIcommandName\fR replaces any existing command or
procedure with that name. If the \fIcommandName\fR includes
any namespace qualifiers, it is created in the specified
namespace. The \fI-tagName\fR option is only allowed for
the elementNode type. The \fI-jsonType\fR option is only
allowed for elementNode and textNode types.
.RS
.PP
If such command is invoked inside a script given as argument to the
domNode method \fIappendFromScript\fR or
\&\fIinsertBeforeFromScript\fR it creates a new node and appends this
node at the end of the child list of the invoking element node. If the
option \fI-returnNodeCmd\fR was given, the command returns the
created node as Tcl command. If this option was omitted, the command
returns nothing. Each command creates always the same type of node.
Which type of node is created by the command is determined by the
first argument to the \fIcreateNodeCmd\fR. The syntax of the created
command depends on the type of the node it creates.
.PP
If the command type to create is \fIelementNode\fR, the created
command will create an element node, if called. Without the
\&\fI-tagName\fR option the tag name of the created node is
\&\fIcommandName\fR without namespace qualifiers. If the
\&\fI-tagName\fR option was given then the created command the created
elements will have this tag name. If the \fI-jsonType\fR option was
given then the created node elements will have the given JSON type. If
the \fI-namespace\fR option is given the created element node will be
XML namespaced and in the namespace given by the option. The element
name will be literal as given either by the command name or the
\&\fI-tagname\fR option, if that was given. An appropriate XML
namespace declaration will be automatically added, to bind the prefix
(if the element name has one) or the default namespace (if the element
name hasn't a prefix) to the namespace if such a binding isn't in
scope.
.PP
The syntax of the created command is:



.CS

\&\fBelementNodeCmd\fP \fI?attributeName attributeValue ...? ?script?\fR
\&\fBelementNodeCmd\fP \fI?-attributeName attributeValue ...? ?script?\fR
................................................................................
will be stripped off.
.PP
Every \fIelementNodeCmd\fR accepts an optional Tcl script as last
argument. This script is evaluated as recursive \fIappendFromScript\fR script
with the node created by the \fIelementNodeCmd\fR as parent of all nodes
created by the script.
.PP
If the first argument of the method is \fItextNode\fR, the command
will create a text node. If the \fI-jsonType\fR option was given then
the created text node will have that JSON type. The syntax of the
created command is:



.CS

\&\fBtextNodeCmd\fP ?-disableOutputEscaping? \fIdata\fR

.CE
.PP
If the optional flag \fI-disableOutputEscaping\fR is given, the
escaping of the ampersand character (&) and the left angle bracket (<)
inside the data is disabled. You should use this flag carefully.
.PP
If the first argument of the method is \fIcommentNode\fR or
\&\fIcdataNode\fR the command will create an comment node or CDATA section
node. The syntax of the created command is:



.CS

\&\fBnodeCmd\fP \fIdata\fR
................................................................................

.CE
.RE
.TP
\&\fB\fBdom\fP \fBsetStoreLineColumn\fP \fI?boolean\fB?
\&\fRIf switched on, the DOM nodes will contain line and column
position information for the original XML document after parsing. The default
is not to store line and column position information.
.TP
\&\fB\fBdom\fP \fBsetNameCheck\fP \fI?boolean\fB?
\&\fRIf NameCheck is true, every method which expects an XML Name,
a full qualified name or a processing instructing target will check, if the
given string is valid according to its production rule. For commands created
with the \fIcreateNodeCmd\fR method to be used in the context of
\&\fIappendFromScript\fR the status of the flag at creation time
decides. If NameCheck is true at creation time, the command will
check its arguments, otherwise not. The \fIsetNameCheck\fR
set this flag. It returns the current NameCheck flag state. The
default state for NameCheck is true.
.TP
\&\fB\fBdom\fP \fBsetTextCheck\fP \fI?boolean\fB?
\&\fRIf TextCheck is true, every command which expects XML Chars,
a comment, a CDATA section value or a processing instructing value will check,
if the given string is valid according to its production rule. For commands
created with the \fIcreateNodeCmd\fR method to be used in the
context of \fIappendFromScript\fR the status of the flag at
creation time decides. If TextCheck is true at creation time, the
command will check its arguments, otherwise not.The
\&\fIsetTextCheck\fR method sets this flag. It returns the current
TextCheck flag state. The default state for TextCheck is true.
.TP
\&\fB\fBdom\fP \fBsetObjectCommands\fP ?\fI(automatic|token|command)\fB?
\&\fRControls if documents and nodes are created as tcl commands or
as token to be
used with the domNode and domDoc commands. If the mode is
\&'automatic', then methods used at tcl commands will create tcl
commands and methods used at doc or node tokes will create tokens. If
the mode is 'command' then always tcl commands will be created. If
the mode is 'token', then always token will be created. The method
returns the current mode. This method is an experimental interface.
.TP
\&\fB\fBdom\fP \fBisName\fP \fIname\fB
\&\fRReturns 1 if \fIname\fR is a valid XML Name according to
production 5 of the XML
1.0 recommendation. This means that \fIname\fR is a valid
XML element or attribute name. Otherwise it returns 0.
.TP
\&\fB\fBdom\fP \fBisPIName\fP \fIname\fB
\&\fRReturns 1 if \fIname\fR is a valid XML processing instruction
target according to
production 17 of the XML 1.0 recommendation. Otherwise it returns 0.
.TP
\&\fB\fBdom\fP \fBisNCName\fP \fIname\fB
\&\fRReturns 1 if \fIname\fR is a valid NCName according
to production 4 of the of the Namespaces in XML recommendation. Otherwise it returns
0.
.TP
\&\fB\fBdom\fP \fBisQName\fP \fIname\fB
\&\fRReturns 1 if \fIname\fR is a valid QName according
to production 6 of the of the Namespaces in XML recommendation. Otherwise it returns
0.
.TP
\&\fB\fBdom\fP \fBisCharData\fP \fIstring\fB
\&\fRReturns 1 if every character in \fIstring\fR is
a valid XML Char according to production 2 of the XML 1.0
recommendation. Otherwise it returns 0.
.TP
\&\fB\fBdom\fP \fBisBMPCharData\fP \fIstring\fB
\&\fRReturns 1 if every character in \fIstring\fR is
a valid XML Char with a Unicode code point within the Basic
Multilingual Plane (that means, that every character within the string
is at most 3 bytes long). Otherwise it returns 0.
.TP
\&\fB\fBdom\fP \fBisComment\fP \fIstring\fB
\&\fRReturns 1 if \fIstring\fR is
a valid comment according to production 15 of the XML 1.0
recommendation. Otherwise it returns 0.
.TP
\&\fB\fBdom\fP \fBisCDATA\fP \fIstring\fB
\&\fRReturns 1 if \fIstring\fR is
valid according to production 20 of the XML 1.0
recommendation. Otherwise it returns 0.
.TP
\&\fB\fBdom\fP \fBisPIValue\fP \fIstring\fB
\&\fRReturns 1 if \fIstring\fR is
valid according to production 16 of the XML 1.0
recommendation. Otherwise it returns 0.
.TP
\&\fB\fBdom\fP \fBfeatureinfo\fP \fIfeature\fB
\&\fRThis method provides information about the used
build options and the expat version. The valid values for
the \fIfeature\fR argument are:
.RS
.IP "\fBexpatversion\fR"
Returns the version of the underlyling expat
version as string, something like
"exapt_2.1.0". This is what the expat API
function XML_ExpatVersion() returns.
.IP "\fBexpatmajorversion\fR"
Returns the major version of the underlyling
expat version as integer.
.IP "\fBexpatminorversion\fR"
Returns the minor version of the underlyling
expat version as integer.
.IP "\fBexpatmicroversion\fR"
Returns the micro version of the underlyling
expat version as integer.
.IP "\fBdtd\fR"
Returns as boolean if build with
\&\fI--enable-dtd\fR.
.IP "\fBns\fR"
Returns as boolean if build with
\&\fI--enable-ns\fR.
.IP "\fBunknown\fR"
Returns as boolean if build with
\&\fI--enable-unknown\fR.
.IP "\fBtdomalloc\fR"
Returns as boolean if build with
\&\fI--enable-tdomalloc\fR.
.IP "\fBlessns\fR"
Returns as boolean if build with
\&\fI--enable-lessns\fR.
.IP "\fBTCL_UTF_MAX\fR"
Returns the TCL_UTF_MAX value of the tcl
core, tDOM was build with as integer
.IP "\fBhtml5\fR"
Returns as boolean, if build with
\&\fI--enable-html5\fR.
.IP "\fBversionhash\fR"
Returns the fossil repository version hash.
.IP "\fBpullparser\fR"
Returns as boolean if the pullparser command
is build in.
.RE
.SH KEYWORDS
XML, DOM, document, node, parsing

Changes to doc/dom.xml.

16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
..
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83


































































84
85
86
87
88
89
90













91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114
115
116




117
118

























119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159

160

161
162

163
164

165
166



















167
168
169
170
171
172
173
...
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234







235
236
237
238
239
240
241
...
249
250
251
252
253
254
255
256


257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
...
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368









369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392











































































393
394
395
396
397
398
399
400
401
402
403

<cmd>dom</cmd> <m>method</m> ?<m>arg arg ...</m>?</syntax>
  </synopsis>

  <section>
    <title>DESCRIPTION </title>    

    <p>This command provides the creation of complete DOM trees in memory. In
the usual case a string containing a XML information is parsed and converted

into a DOM tree. <m>method</m> indicates a specific subcommand. </p>

    <p>The valid methods are:</p>

      <commandlist>
        <commanddef>
          <command><cmd>dom</cmd> <method>parse</method> ?<m>options</m>? ?<m>data</m>?</command>
          <desc>Parses the XML information and builds up the DOM tree in memory
................................................................................
              <optdef>
                <optname>-simple</optname> 
                <desc>If <m>-simple</m> is
specified, a simple but fast parser is used (conforms not fully to XML
recommendation). That should double parsing and DOM generation speed. The
encoding of the data is not transformed inside the parser. The simple parser
does not respect any encoding information in the XML declaration. It skips over
the internal DTD subset and ignores any information in it. Therefor it doesn't
include defaulted attribute values into the tree, even if the according
attribute declaration is in the internal subset. It also doesn't expand
internal or external entity references other than the predefined entities and
character references.</desc>
              </optdef>

              <optdef>
                <optname>-html</optname>
                <desc>If <m>-html</m> is specified, a fast HTML parser is 
used, which tries to even parse badly formed HTML into a DOM tree.</desc>
              </optdef>
       
              <optdef>


































































                <optname>-keepEmpties</optname> 
                <desc>If <m>-keepEmpties</m> is
specified, text nodes, which contain only whitespaces, will be part of the
resulting DOM tree. In default case (<m>-keepEmpties</m> not given) those empty
text nodes are removed at parsing time.</desc>
              </optdef>














              <optdef>
                <optname>-channel</optname>
                <optarg>&lt;channel-ID&gt;</optarg>
                <desc>If <m>-channel &lt;channel-ID&gt;</m> is specified, the
input to be parsed is read from the specified channel. The encoding setting of
the channel (via fconfigure -encoding) is respected, ie the data read from the
channel are converted to UTF-8 according to the encoding settings, befor the
data is parsed.</desc>
              </optdef>

              <optdef>
                <optname>-baseurl</optname>
                <optarg>&lt;baseURI&gt;</optarg>
                <desc>If <m>-baseurl &lt;baseURI&gt;</m> is specified, the
baseURI is used as the base URI of the document. External entities referenced

in the document are resolved relative to this base URI. This base URI is also
stored within the DOM tree.</desc>
              </optdef>

              <optdef>
                <optname>-feedbackAfter</optname>
                <optarg>&lt;#bytes&gt;</optarg>
                <desc>If <m>-feedbackAfter &lt;#bytes&gt;</m> is specified, the
tcl command ::dom::domParseFeedback is evaluated after parsing every #bytes. If
you use this option, you have to create a tcl proc named
::dom::domParseFeedback, otherwise you will get an error. Please notice, that




the calls of ::dom::domParseFeedback are not done exactly every #bytes, but
always at the first element start after every #bytes.</desc>

























              </optdef>

              <optdef>
                <optname>-externalentitycommand</optname>
                <optarg>&lt;script&gt;</optarg>
                <desc>If <m>-externalentitycommand &lt;script&gt;</m> is
specified, the specified tcl script is called to resolve any external entities
of the document. The actual evaluated command consists of this option followed
by three arguments: the base uri, the system identifier of the entity and the
public identifier of the entity. The base uri and the public identifier may be
the empty list. The script has to return a tcl list consisting of three
elements. The first element of this list signals, how the external entity is
returned to the processor. At the moment, the two allowed types are "string"
and "channel". The second element of the list has to be the (absolute) base URI
of the external entity to be parsed.  The third element of the list are data,
either the already read data out of the external entity as string in the case
of type "string", or the name of a tcl channel, in the case of type
"channel". Note that if the script returns a tcl channel, it will not be closed
by the processor.  It must be closed separately if it is no longer
required.</desc>
              </optdef>

              <optdef>
                <optname>-useForeignDTD</optname>
                <optarg>&lt;boolean&gt;</optarg>
                <desc>If &lt;boolean&gt; is true and the document does not have
an external subset, the parser will call the -externalentitycommand script with
empty values for the systemId and publicID arguments. Pleace notice, that, if
the document also doesn't have an internal subset, the
-startdoctypedeclcommand and -enddoctypedeclcommand scripts, if set, are not
called. The <m>-useForeignDTD</m> respects </desc>
              </optdef>

              <optdef>
                <optname>-paramentityparsing</optname>
                <optarg>&lt;always|never|notstandalone&gt;</optarg>
                <desc>The <m>-paramentityparsing</m> option controls, if the
parser tries to resolve the external entities (including the external DTD

subset) of the document, while building the DOM
tree. <m>-paramentityparsing</m> requires an argument, which must be either
"always", "never", or "notstandalone". The value "always" means, that the

parser tries to resolves (recursively) all external entities of the XML

source. This is the default, in case <m>-paramentityparsing</m> is omitted. The
value "never" means, that only the given XML source is parsed and no external

entity (including the external subset) will be resolved and parsed. The value
"notstandalone" means, that all external entities will be resolved and parsed,

with the execption of documents, which explicitly states standalone="yes" in
their XML declaration.</desc>



















              </optdef>

            </optlist>
<p/>
</desc>
        </commanddef>

................................................................................
document element to create. The <m>objVar</m> controls the
memory handling as explained above.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>createDocumentNode</method>
?<m>objVar</m>?</command>
          <desc>Creates a new, 'empty' DOM document object without any element
node. <m>objVar</m> controls the memory handling as explained above.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>setResultEncoding</method> ?<m>encodingName</m>?</command>
          <desc>If <m>encodingName</m> is not given the current global
result encoding is returned.  Otherwise the global result encoding is set to
<m>encodingName</m>.  All character data, attribute values, etc. will
then be converted from UTF-8, which is delivered from the Expat XML parser, to
the given 8 bit encoding at XML/DOM parse time.  Valid values for
<m>encodingName</m> are: utf-8, ascii, cp1250, cp1251, cp1252, cp1253,
cp1254, cp1255, cp1256, cp437, cp850, en, iso8859-1, iso8859-2, iso8859-3,
iso8859-4, iso8859-5, iso8859-6, iso8859-7, iso8859-8, iso8859-9, koi8-r.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>createNodeCmd</method>
<m>?-returnNodeCmd?</m> <m>(element|comment|text|cdata|pi)Node</m> <m>commandName</m></command>
          <desc>This method creates Tcl commands, which in turn create tDOM nodes.
Tcl commands created by this command are only avaliable inside a script given to the
domNode method <m>appendFromScript</m>. If a command created with
<m>createNodeCmd</m> is invoked in any other context, it will return error. The
created command <m>commandName</m> replaces any existing command or procedure
with that name. If the <m>commandName</m> includes any namespace qualifiers, 
it is created in the specified namespace.

<p>If such command is invoked inside a script given as argument to
the domNode method <m>appendFromScript</m>, it creates a new node and
appends this node at the end of the child list of the invoking element
node. If the option <m>-returnNodeCmd</m> was given, the command returns the
created node as Tcl command. If this option was omitted, the command returns
nothing. Each command creates always the same type of node. Which type of 
node is created by the command is determined by the first argument to the
<m>createNodeCmd</m>. The syntax of the created command depends on the 
type of the node it creates.</p>

<p>If the first argument of the method is <m>elementNode</m>, the created
command will create an element node. The tag name of the created
node is <m>commandName</m> without namespace qualifiers. The syntax of the 
created command is:</p>








<syntax>
<cmd>elementNodeCmd</cmd> <m>?attributeName attributeValue ...? ?script?</m>
<cmd>elementNodeCmd</cmd> <m>?-attributeName attributeValue ...? ?script?</m>
<cmd>elementNodeCmd</cmd> <m>name_value_list script</m>
</syntax>

................................................................................
will be stripped off.</p>

<p>Every <m>elementNodeCmd</m> accepts an optional Tcl script as last
argument. This script is evaluated as recursive <m>appendFromScript</m> script
with the node created by the <m>elementNodeCmd</m> as parent of all nodes
created by the script.</p>

<p>If the first argument of the method is <m>textNode</m>, the command will create


a text node. The syntax of the created command is:</p>

<syntax>
<cmd>textNodeCmd</cmd> ?-disableOutputEscaping? <m>data</m>
</syntax>

<p>If the optional flag <m>-disableOutputEscaping</m> is given, the
escaping of the ampersand character (&amp;) and the left angle bracket (&lt;)
inside the data is disabled. You should use this flag carefully.</p>

<p>If the first argument of the method is <m>commentNode</m>, or 
<m>cdataNode</m>, the command will create an comment node or CDATA section 
node. The syntax of the created command is:</p>

<syntax>
<cmd>nodeCmd</cmd> <m>data</m>
</syntax>

<p>If the first argument of the method is <m>piNode</m>, the command will
................................................................................
</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>setStoreLineColumn</method> <m>?boolean</m>?</command>
          <desc>If switched on, the DOM nodes will contain line and column
position information for the original XML document after parsing. The default
is, not to store line and column position information.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>setNameCheck</method> <m>?boolean</m>?</command>
          <desc>If NameCheck is true, every method which expects an XML Name,
a full qualified name or a processing instructing target will check, if the
given string is valid according to his production rule. For commands created
with the <m>createNodeCmd</m> method to be used in the context of
<m>appendFromScript</m> the status of the flag at creation time
decides. If NameCheck is true at creation time, the command will
check his arguments, otherwise not. The <m>setNameCheck</m>
set this flag. It returns the current NameCheck flag state. The
default state for NameCheck is true. </desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>setTextCheck</method> <m>?boolean</m>?</command>
          <desc>If TextCheck is true, every command which expects XML Chars,
a comment, a CDATA section value or a processing instructing value will check,
if the given string is valid according to his production rule. For commands
created with the <m>createNodeCmd</m> method to be used in the
context of <m>appendFromScript</m> the status of the flag at
creation time decides. If TextCheck is true at creation time, the
command will check his arguments, otherwise not.The
<m>setTextCheck</m> method set this flag. It returns the current
TextCheck flag state. The default state for TextCheck is true.</desc>
      </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>setObjectCommands</method> ?<m>(automatic|token|command)</m>?</command>
          <desc>Controls, if documents and nodes are created as tcl commands or
as token to be
used with the domNode and domDoc commands. If the mode is
'automatic', then methods used at tcl commands will create tcl
commands and methods used at doc or node tokes will create tokens. If
the mode is 'command' then always tcl commands will be created. If
the mode is 'token', then always token will be created. The method
returns the current mode. This method is an experimental interface.</desc>
      </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isName</method> <m>name</m></command>
          <desc>Returns 1, if <m>name</m> is a valid XML Name according to
production 5 of the <ref
            href="http://www.w3.org/TR/2004/REC-xml-20040204/#NT-NameChar">XML
            1.0</ref> recommendation. This means, that <m>name</m> is a valid
          XML element or attribute name. Otherwise it returns 0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isPIName</method> <m>name</m></command>
          <desc>Returns 1, if <m>name</m> is a valid XML processing instruction
          target according to
production 17 of the <ref href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</ref> recommendation. Otherwise it returns 0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isNCName</method> <m>name</m></command>
          <desc>Returns 1, if <m>name</m> is a valid NCName according
to production 4 of the of the <ref href="http://www.w3.org/TR/1999/REC-xml-names-19990114">Namespaces in XML</ref> recommendation. Otherwise it returns
0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isQName</method> <m>name</m></command>
          <desc>Returns 1, if <m>name</m> is a valid QName according
to production 6 of the of the <ref href="http://www.w3.org/TR/1999/REC-xml-names-19990114">Namespaces in XML</ref> recommendation. Otherwise it returns
0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isCharData</method>
<m>string</m></command>
          <desc>Returns 1, if every character in <m>string</m> is
a valid XML Char according to production 2 of the <ref href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</ref>
recommendation. Otherwise it returns 0.</desc>
        </commanddef>










        <commanddef>
          <command><cmd>dom</cmd> <method>isComment</method>
<m>string</m></command>
          <desc>Returns 1, if <m>string</m> is
a valid comment according to production 15 of the <ref href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</ref>
recommendation. Otherwise it returns 0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isCDATA</method>
<m>string</m></command>
          <desc>Returns 1, if <m>string</m> is
valid according to production 20 of the <ref href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</ref>
recommendation. Otherwise it returns 0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isPIValue</method>
<m>string</m></command>
          <desc>Returns 1, if <m>string</m> is
valid according to production 16 of the <ref href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</ref>
recommendation. Otherwise it returns 0.</desc>
        </commanddef>












































































      </commandlist>
  </section>

  <keywords>
    <keyword>XML</keyword>
    <keyword>DOM</keyword>
    <keyword>document</keyword>
    <keyword>node</keyword>
    <keyword>parsing</keyword>
  </keywords>
</manpage>







|

>
|







 







|











|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|




>
>
>
>
>
>
>
>
>
>
>
>
>






|






|
|
>
|
|





|
<
|
|
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











|
|






|







|








|
|
>
|
|
|
>
|
>
|
|
>
|
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>







 







|
>
>
|









|
|







 







|






|



|








|



|
|





|











|


|





|






|






|







|




>
>
>
>
>
>
>
>
>



|







|







|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|

|





|

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
...
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
...
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
...
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628

<cmd>dom</cmd> <m>method</m> ?<m>arg arg ...</m>?</syntax>
  </synopsis>

  <section>
    <title>DESCRIPTION </title>    

    <p>This command provides the creation of DOM trees in memory. In
the usual case a string containing a XML information is parsed and converted
into a DOM tree. Other possible parse input may be HTML or JSON.
The <m>method</m> indicates a specific subcommand. </p>

    <p>The valid methods are:</p>

      <commandlist>
        <commanddef>
          <command><cmd>dom</cmd> <method>parse</method> ?<m>options</m>? ?<m>data</m>?</command>
          <desc>Parses the XML information and builds up the DOM tree in memory
................................................................................
              <optdef>
                <optname>-simple</optname> 
                <desc>If <m>-simple</m> is
specified, a simple but fast parser is used (conforms not fully to XML
recommendation). That should double parsing and DOM generation speed. The
encoding of the data is not transformed inside the parser. The simple parser
does not respect any encoding information in the XML declaration. It skips over
the internal DTD subset and ignores any information in it. Therefore it doesn't
include defaulted attribute values into the tree, even if the according
attribute declaration is in the internal subset. It also doesn't expand
internal or external entity references other than the predefined entities and
character references.</desc>
              </optdef>

              <optdef>
                <optname>-html</optname>
                <desc>If <m>-html</m> is specified, a fast HTML parser is 
used, which tries to even parse badly formed HTML into a DOM tree.</desc>
              </optdef>

              <optdef>
                <optname>-html5</optname>
                <desc>This option is only available if tDOM was build
                with --enable-html5. Try the <m>featureinfo</m> method
                if you need to know if this feature is build in. If
                <m>-html5</m> is specified, the gumbo lib html5 parser
                (https://github.com/google/gumbo-parser) is used to
                build the DOM tree. This is, as far as it goes, XML
                namespace-aware. Since this probably isn't wanted by a
                lot of users and adds only burden for no good in a lot
                of use cases <m>-html5</m> can be combined with
                <m>-ignorexmlns</m>, in which case all nodes and
                attributes in the DOM tree are not in an XML
                namespace. All tag and attribute names in the DOM tree
                will be lower case, even for foreign elements not in
                the xhtml, svg or mathml namespace. The DOM tree may
                include nodes, that the parser inserted because they
                are implied by the context (as &lt;head&gt;,
                &lt;tbody&gt;, etc.).</desc>
              </optdef>

              <optdef>
                <optname>-json</optname>
                <desc>If <m>-json</m> is specified, the <m>data</m> is
                expected to be a valid JSON string (according to RFC
                7159). The command returns an ordinary DOM document
                with nesting token inside the JSON data translated
                into tree hierarchy. If a JSON array value is itself
                an object or array then container element nodes named
                (in a default build) arraycontainer or
                objectcontainer, respectively, are inserted into the
                tree. The JSON serialization of this document (with
                the domDoc method <m>asJSON</m>) is the same JSON
                information as the <m>data</m>, preserving JSON
                datatypes, allowing non-unique member names of objects
                while preserving their order and the full range of
                JSON string values. JSON datatype handling is done
                with an additional property "sticking" at the doc and
                tree nodes. This property isn't contained in an XML
                serialization of the document. If you need to store
                the JSON data represented by a document, store the
                JSON serialization and parse it back from there. Apart
                from this JSON type information the returned doc
                command or handle is an ordinary DOM doc, which may be
                investigated or modified with the full range of the
                doc and node methods. Please note that the element
                node names and the text node values within the tree
                may be outside of what the appropriate XML productions
                allow.</desc>
              </optdef>

              <optdef>
                <optname>-jsonmaxnesting</optname>
                <optarg>integer</optarg>
                <desc>This option only has effect if used together
                with the <m>-json</m> option. The current implementation uses recursive descent JSON parser. In order to avoid using excess stack space, any JSON input that has more than a certain levels of nesting is considered invalid. The default maximum nesting is 2000. The option -jsonmaxnesting allows the user to adjust that.</desc>
              </optdef>
              
              <optdef>
                <optname>--</optname> 
                <desc>The option <m>--</m> marks the end of options.
                While respected in general this option is only needed
                in case of parsing JSON data, which may start with a
                "-".</desc>
              </optdef>

              <optdef>
                <optname>-keepEmpties</optname> 
                <desc>If <m>-keepEmpties</m> is
specified then text nodes which contain only whitespaces will be part of the
resulting DOM tree. In default case (<m>-keepEmpties</m> not given) those empty
text nodes are removed at parsing time.</desc>
              </optdef>

              <optdef>
                <optname>-keepCDATA</optname> 
                <desc>If <m>-keepCDATA</m> is
specified then CDATA sections aren't added to the tree as text nodes
(and, if necessary, combined with sibling text nodes into one text
node) as without this option but are added as CDATA_SECTION_NODEs to
the tree. Please note that the resulting tree isn't prepared for XPath
selects or to be the source or the stylesheet of an XSLT
transformation. If not combined with <m>-keepEmpties</m> only not
whitespace only CDATA sections will be added to the resulting DOM
                tree.</desc>
              </optdef>
              
              <optdef>
                <optname>-channel</optname>
                <optarg>&lt;channel-ID&gt;</optarg>
                <desc>If <m>-channel &lt;channel-ID&gt;</m> is specified, the
input to be parsed is read from the specified channel. The encoding setting of
the channel (via fconfigure -encoding) is respected, ie the data read from the
channel are converted to UTF-8 according to the encoding settings before the
data is parsed.</desc>
              </optdef>

              <optdef>
                <optname>-baseurl</optname>
                <optarg>&lt;baseURI&gt;</optarg>
                <desc>If <m>-baseurl &lt;baseURI&gt;</m> is specified,
                the baseURI is used as the base URI of the document.
                External entities references in the document are
                resolved relative to this base URI. This base URI is
                also stored within the DOM tree.</desc>
              </optdef>

              <optdef>
                <optname>-feedbackAfter</optname>
                <optarg>&lt;#bytes&gt;</optarg>
                <desc>If <m>-feedbackAfter &lt;#bytes&gt;</m> is

                specified, the tcl command given by
                <m>-feedbackcmd</m> is evaluated at the first element
                start within the document (or an external entity)
                after the start of the document or external entity or
                the last such call after #bytes. For backward
                compatibility if no -feedbackcmd is given but there is
                a tcl proc named ::dom::domParseFeedback this proc is

                used as -feedbackcmd. If there isn't such a proc and
                -feedbackAfter is used it is an error to not also use
                -feedbackcmd. If the called script raises error, then
                parsing will be aborted, the <m>dom parse</m> call
                returns error, with the script error msg as error msg.
                If the called script <m>return -code break</m>, the
                parsing will abort and the <m>dom parse</m> call will
                return the empty string.</desc>
              </optdef>

              <optdef>
                <optname>-feedbackcmd</optname>
                <optarg>&lt;script&gt;</optarg>
                <desc>If <m>-feedbackcmd &lt;script&gt;</m> is specified, the
script <m>script</m> is evaluated at the first
element start within the document (or an external entity) after the
start of the document or external entity or the last such call after
#bytes value given by the <m>-feedbackAfter</m> option. If
<m>-feedbackAfter</m> isn't given, using this option
doesn't has any effect. If the called
script raises error, then parsing will be aborted, the
<m>dom parse</m> call returns error, with the script
error msg as error msg. If the called script <m>return
-code break</m>, the parsing will abort and the <m>dom
parse</m> call will return the empty string.</desc>
              </optdef>

              <optdef>
                <optname>-externalentitycommand</optname>
                <optarg>&lt;script&gt;</optarg>
                <desc>If <m>-externalentitycommand &lt;script&gt;</m> is
specified, the specified tcl script is called to resolve any external entities
of the document. The actual evaluated command consists of this option followed
by three arguments: the base uri, the system identifier of the entity and the
public identifier of the entity. The base uri and the public identifier may be
the empty list. The script has to return a tcl list consisting of three
elements. The first element of this list signals how the external entity is
returned to the processor. Currently the two allowed types are "string"
and "channel". The second element of the list has to be the (absolute) base URI
of the external entity to be parsed.  The third element of the list are data,
either the already read data out of the external entity as string in the case
of type "string", or the name of a tcl channel, in the case of type
"channel". Note that if the script returns a tcl channel, it will not be closed
by the processor.  It must be closed separately if it is no longer
needed.</desc>
              </optdef>

              <optdef>
                <optname>-useForeignDTD</optname>
                <optarg>&lt;boolean&gt;</optarg>
                <desc>If &lt;boolean&gt; is true and the document does not have
an external subset, the parser will call the -externalentitycommand script with
empty values for the systemId and publicID arguments. Please note that if
the document also doesn't have an internal subset, the
-startdoctypedeclcommand and -enddoctypedeclcommand scripts, if set, are not
called. The <m>-useForeignDTD</m> respects </desc>
              </optdef>

              <optdef>
                <optname>-paramentityparsing</optname>
                <optarg>&lt;always|never|notstandalone&gt;</optarg>
                <desc>The <m>-paramentityparsing</m> option controls,
                if the parser tries to resolve the external entities
                (including the external DTD subset) of the document
                while building the DOM tree.
                <m>-paramentityparsing</m> requires an argument, which
                must be either "always", "never", or "notstandalone".
                The value "always" means that the parser tries to
                resolves (recursively) all external entities of the
                XML source. This is the default in case
                <m>-paramentityparsing</m> is omitted. The value
                "never" means that only the given XML source is
                parsed and no external entity (including the external
                subset) will be resolved and parsed. The value
                "notstandalone" means, that all external entities will
                be resolved and parsed, with the exception of
                documents, which explicitly states standalone="yes" in
                their XML declaration.</desc>
              </optdef>


              <optdef>
                <optname>-ignorexmlns</optname>
                <desc>It is recommended, that you only use this option
                with the <m>-html5</m> option. If this option is
                given, no node within the created DOM tree will be
                internally marked as placed into an XML Namespace,
                even if there is a default namespace in scope for
                un-prefixed elements or even if the element has a
                defined namespace prefix. One consequence is that
                XPath node expressions on such a DOM tree doesn't work
                as expected. Prefixed element nodes can't be selected
                and element nodes without prefix will be seen by XPath
                expressions as if they are not in any namespace (no
                matter if they are in fact should be in a default
                namespace).
                </desc>
              </optdef>

            </optlist>
<p/>
</desc>
        </commanddef>

................................................................................
document element to create. The <m>objVar</m> controls the
memory handling as explained above.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>createDocumentNode</method>
?<m>objVar</m>?</command>
          <desc>Creates a new 'empty' DOM document object without any element
node. <m>objVar</m> controls the memory handling as explained above.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>createNodeCmd</method>
<m>?-returnNodeCmd?</m> <m>?-tagName name?</m> <m>?-jsonType jsonType?</m> <m>?-namespace URI?</m> <m>(element|comment|text|cdata|pi)Node</m> <m>commandName</m></command>
          <desc>This method creates Tcl commands, which in turn create
          tDOM nodes. Tcl commands created by this command are only
          available inside a script given to the domNode methods
          <m>appendFromScript</m> or <m>insertBeforeFromScript</m>. If
          a command created with <m>createNodeCmd</m> is invoked in
          any other context, it will return error. The created command
          <m>commandName</m> replaces any existing command or
          procedure with that name. If the <m>commandName</m> includes
          any namespace qualifiers, it is created in the specified
          namespace. The <m>-tagName</m> option is only allowed for
          the elementNode type. The <m>-jsonType</m> option is only
          allowed for elementNode and textNode types.

<p>If such command is invoked inside a script given as argument to the
domNode method <m>appendFromScript</m> or
<m>insertBeforeFromScript</m> it creates a new node and appends this
node at the end of the child list of the invoking element node. If the
option <m>-returnNodeCmd</m> was given, the command returns the
created node as Tcl command. If this option was omitted, the command
returns nothing. Each command creates always the same type of node.
Which type of node is created by the command is determined by the
first argument to the <m>createNodeCmd</m>. The syntax of the created
command depends on the type of the node it creates.</p>

<p>If the command type to create is <m>elementNode</m>, the created
command will create an element node, if called. Without the
<m>-tagName</m> option the tag name of the created node is
<m>commandName</m> without namespace qualifiers. If the
<m>-tagName</m> option was given then the created command the created
elements will have this tag name. If the <m>-jsonType</m> option was
given then the created node elements will have the given JSON type. If
the <m>-namespace</m> option is given the created element node will be
XML namespaced and in the namespace given by the option. The element
name will be literal as given either by the command name or the
<m>-tagname</m> option, if that was given. An appropriate XML
namespace declaration will be automatically added, to bind the prefix
(if the element name has one) or the default namespace (if the element
name hasn't a prefix) to the namespace if such a binding isn't in
scope.</p>

<p>The syntax of the created command is:</p>

<syntax>
<cmd>elementNodeCmd</cmd> <m>?attributeName attributeValue ...? ?script?</m>
<cmd>elementNodeCmd</cmd> <m>?-attributeName attributeValue ...? ?script?</m>
<cmd>elementNodeCmd</cmd> <m>name_value_list script</m>
</syntax>

................................................................................
will be stripped off.</p>

<p>Every <m>elementNodeCmd</m> accepts an optional Tcl script as last
argument. This script is evaluated as recursive <m>appendFromScript</m> script
with the node created by the <m>elementNodeCmd</m> as parent of all nodes
created by the script.</p>

<p>If the first argument of the method is <m>textNode</m>, the command
will create a text node. If the <m>-jsonType</m> option was given then
the created text node will have that JSON type. The syntax of the
created command is:</p>

<syntax>
<cmd>textNodeCmd</cmd> ?-disableOutputEscaping? <m>data</m>
</syntax>

<p>If the optional flag <m>-disableOutputEscaping</m> is given, the
escaping of the ampersand character (&amp;) and the left angle bracket (&lt;)
inside the data is disabled. You should use this flag carefully.</p>

<p>If the first argument of the method is <m>commentNode</m> or 
<m>cdataNode</m> the command will create an comment node or CDATA section 
node. The syntax of the created command is:</p>

<syntax>
<cmd>nodeCmd</cmd> <m>data</m>
</syntax>

<p>If the first argument of the method is <m>piNode</m>, the command will
................................................................................
</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>setStoreLineColumn</method> <m>?boolean</m>?</command>
          <desc>If switched on, the DOM nodes will contain line and column
position information for the original XML document after parsing. The default
is not to store line and column position information.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>setNameCheck</method> <m>?boolean</m>?</command>
          <desc>If NameCheck is true, every method which expects an XML Name,
a full qualified name or a processing instructing target will check, if the
given string is valid according to its production rule. For commands created
with the <m>createNodeCmd</m> method to be used in the context of
<m>appendFromScript</m> the status of the flag at creation time
decides. If NameCheck is true at creation time, the command will
check its arguments, otherwise not. The <m>setNameCheck</m>
set this flag. It returns the current NameCheck flag state. The
default state for NameCheck is true. </desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>setTextCheck</method> <m>?boolean</m>?</command>
          <desc>If TextCheck is true, every command which expects XML Chars,
a comment, a CDATA section value or a processing instructing value will check,
if the given string is valid according to its production rule. For commands
created with the <m>createNodeCmd</m> method to be used in the
context of <m>appendFromScript</m> the status of the flag at
creation time decides. If TextCheck is true at creation time, the
command will check its arguments, otherwise not.The
<m>setTextCheck</m> method sets this flag. It returns the current
TextCheck flag state. The default state for TextCheck is true.</desc>
      </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>setObjectCommands</method> ?<m>(automatic|token|command)</m>?</command>
          <desc>Controls if documents and nodes are created as tcl commands or
as token to be
used with the domNode and domDoc commands. If the mode is
'automatic', then methods used at tcl commands will create tcl
commands and methods used at doc or node tokes will create tokens. If
the mode is 'command' then always tcl commands will be created. If
the mode is 'token', then always token will be created. The method
returns the current mode. This method is an experimental interface.</desc>
      </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isName</method> <m>name</m></command>
          <desc>Returns 1 if <m>name</m> is a valid XML Name according to
production 5 of the <ref
            href="http://www.w3.org/TR/2004/REC-xml-20040204/#NT-NameChar">XML
            1.0</ref> recommendation. This means that <m>name</m> is a valid
          XML element or attribute name. Otherwise it returns 0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isPIName</method> <m>name</m></command>
          <desc>Returns 1 if <m>name</m> is a valid XML processing instruction
          target according to
production 17 of the <ref href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</ref> recommendation. Otherwise it returns 0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isNCName</method> <m>name</m></command>
          <desc>Returns 1 if <m>name</m> is a valid NCName according
to production 4 of the of the <ref href="http://www.w3.org/TR/1999/REC-xml-names-19990114">Namespaces in XML</ref> recommendation. Otherwise it returns
0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isQName</method> <m>name</m></command>
          <desc>Returns 1 if <m>name</m> is a valid QName according
to production 6 of the of the <ref href="http://www.w3.org/TR/1999/REC-xml-names-19990114">Namespaces in XML</ref> recommendation. Otherwise it returns
0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isCharData</method>
<m>string</m></command>
          <desc>Returns 1 if every character in <m>string</m> is
a valid XML Char according to production 2 of the <ref href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</ref>
recommendation. Otherwise it returns 0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isBMPCharData</method>
<m>string</m></command>
          <desc>Returns 1 if every character in <m>string</m> is
a valid XML Char with a Unicode code point within the Basic
Multilingual Plane (that means, that every character within the string
is at most 3 bytes long). Otherwise it returns 0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isComment</method>
<m>string</m></command>
          <desc>Returns 1 if <m>string</m> is
a valid comment according to production 15 of the <ref href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</ref>
recommendation. Otherwise it returns 0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isCDATA</method>
<m>string</m></command>
          <desc>Returns 1 if <m>string</m> is
valid according to production 20 of the <ref href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</ref>
recommendation. Otherwise it returns 0.</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>isPIValue</method>
<m>string</m></command>
          <desc>Returns 1 if <m>string</m> is
valid according to production 16 of the <ref href="http://www.w3.org/TR/2000/REC-xml-20001006.html">XML 1.0</ref>
recommendation. Otherwise it returns 0.</desc>
        </commanddef>

        <commanddef>
            <command><cmd>dom</cmd> <method>featureinfo</method> <m>feature</m></command>
            <desc>This method provides information about the used
            build options and the expat version. The valid values for
            the <m>feature</m> argument are:
            <optlist>
                <optdef>
                    <optname>expatversion</optname>
                    <desc>Returns the version of the underlyling expat
                    version as string, something like
                    "exapt_2.1.0". This is what the expat API
                    function XML_ExpatVersion() returns.</desc>
                </optdef>
                <optdef>
                    <optname>expatmajorversion</optname>
                    <desc>Returns the major version of the underlyling
                    expat version as integer.</desc>
                </optdef>
                <optdef>
                    <optname>expatminorversion</optname>
                    <desc>Returns the minor version of the underlyling
                    expat version as integer.</desc>
                </optdef>
                <optdef>
                    <optname>expatmicroversion</optname>
                    <desc>Returns the micro version of the underlyling
                    expat version as integer.</desc>
                </optdef>
                <optdef>
                    <optname>dtd</optname>
                    <desc>Returns as boolean if build with
                    <m>--enable-dtd</m>.</desc>
                </optdef>
                <optdef>
                    <optname>ns</optname>
                    <desc>Returns as boolean if build with
                    <m>--enable-ns</m>.</desc>
                </optdef>
                <optdef>
                    <optname>unknown</optname>
                    <desc>Returns as boolean if build with
                    <m>--enable-unknown</m>.</desc>
                </optdef>
                <optdef>
                    <optname>tdomalloc</optname>
                    <desc>Returns as boolean if build with
                    <m>--enable-tdomalloc</m>.</desc>
                </optdef>
                <optdef>
                    <optname>lessns</optname>
                    <desc>Returns as boolean if build with
                    <m>--enable-lessns</m>.</desc>
                </optdef>
                <optdef>
                    <optname>TCL_UTF_MAX</optname>
                    <desc>Returns the TCL_UTF_MAX value of the tcl
                    core, tDOM was build with as integer</desc>
                </optdef>
                <optdef>
                    <optname>html5</optname>
                    <desc>Returns as boolean, if build with
                    <m>--enable-html5</m>.</desc>
                </optdef>
                <optdef>
                    <optname>versionhash</optname>
                    <desc>Returns the fossil repository version hash.</desc>
                </optdef>
                <optdef>
                    <optname>pullparser</optname>
                    <desc>Returns as boolean if the pullparser command
                    is build in.</desc>
                </optdef>
            </optlist>
            </desc>   
        </commanddef>
    </commandlist>
</section>

<keywords>
    <keyword>XML</keyword>
    <keyword>DOM</keyword>
    <keyword>document</keyword>
    <keyword>node</keyword>
    <keyword>parsing</keyword>
</keywords>
</manpage>

Changes to doc/domDoc.html.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
...
107
108
109
110
111
112
113
114
115

116
117


118
119
120


121
122

123
124
125














126
127

128




129




130





131



132
133
134
135
136
137

138
139
140
141
142
143
144
145

146
147
148
149

150
151
152
153
154
155
156
157
158
159
160
161
















































































162
163
164
165
166
167
168
...
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243

244
245
246
247
248
249
250
...
251
252
253
254
255
256
257
258
259





260
261
262
263
264
265
266





267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
...
286
287
288
289
290
291
292

293
294
295
296
297
298
299
...
301
302
303
304
305
306
307
308
309





310
311
312
313
314
315
316
...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
...
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
...
455
456
457
458
459
460
461
462


463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493


494
495
496
497
498
499
500
...
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516
517
...
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: domDoc</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile$ $Revision$">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid0x80a9a60">NAME</a> ท <a href="#SECTid0x80a7380">SYNOPSIS</a> ท <a href="#SECTid0x80967e0">DESCRIPTION </a> ท <a href="#SECTid0x80cf590">SEE ALSO</a> ท <a href="#SECTid0x80cf7b0">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
  <h2><a name="SECTid0x80a9a60">NAME</a></h2><p class="namesection">
<b class="names">domDoc - </b><br>Manipulates an instance of a DOM document object</p>
  
  <h2><a name="SECTid0x80a7380">SYNOPSIS</a></h2><pre class="syntax">
<b class="cmd">domDocObjCmd</b> <i class="m">method</i> ?<i class="m">arg arg ...</i>?</pre>

  <h2><a name="SECTid0x80967e0">DESCRIPTION </a></h2><p>This command manipulates one particular instance of a document
object. <i class="m">method</i> indicates a specific method of the document class. These
methods should closely conform to the W3C recommendation "Document Object Model
(Core) Level 1" (<a href="http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html">http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html</a>). Look
at these documents for a deeper understanding of the functionality.</p><p>The valid methods are:</p><dl class="commandlist">
        
          <dt>
<b class="method">documentElement</b> ?<i class="m">objVar</i>?</dt>
................................................................................

        
          <dt>
<b class="method">createElement</b> <i class="m">tagName</i> ?<i class="m">objVar</i>?</dt>
          <dd>Creates (allocates) a new element node with node name
<i class="m">tagName</i>, append it to the hidden fragment list in the document
object and returns the node object.  If <i class="m">objVar</i> is given the new
node object store in this variable.</dd>
        

        
          <dt>
<b class="method">createElementNS</b> <i class="m">url</i> <i class="m">tagName</i> ?<i class="m">objVar</i>?</dt>
          <dd>Creates (allocates) a new element node within a namespace
having <i class="m">uri</i> as the URI and node name <i class="m">tagName</i>, which
could include the namespace prefix, append it to the hidden fragment list in
the document object and returns the node object.  If <i class="m">objVar</i> is
given the new node object store in this variable.</dd>
        

        
          <dt>
<b class="method">createTextNode</b> <i class="m">text</i> ?<i class="m">objVar</i>?</dt>
          <dd>Creates (allocates) a new text node with node value
<i class="m">text</i>, appends it to the hidden fragment list in the document
................................................................................
          <dt><b class="method">getDefaultOutputMethod</b></dt>
          <dd>Returns the default output method of the document. This is
usually a result of a XSLT transformation.</dd>
        

      
        <dt>
<b class="method">asXML</b> <b class="option">?-indent none/1..8?</b> <b class="option">?-channel channelId?</b> <b class="option">?-escapeNonASCII?</b> <b class="option">?-doctypeDeclaration &lt;boolean&gt;?</b> <b class="option">?-escapeAllQuot?</b>
</dt>

        <dd>Returns the DOM tree as an (optional indented) XML
string or sends the output directly to the given channelId. If the


option <i class="m">-escapeNonASCII</i> is given, every non 7 bit ASCII
character in attribute values or element PCDATA content will be
escaped as character reference in decimal representation. The flag


<i class="m">-doctypeDeclaration</i> determines, whether there will be a DOCTYPE
declaration emitted before the first node of the document. The default

is, to do not. The DOCTYPE name will always be the element name of the
document element. An external entity declaration of the external
subset is only emitted, if the document has a system identifier. If














the option <i class="m">-escapeAllQuot</i> is given, quotation marks will be
escaped with &amp;quot; even in text content of elements.</dd>






      










      



        <dt>
<b class="method">asHTML</b> <b class="option">?-channel
channelId?</b> <b class="option">?-escapeNonASCII?</b> <b class="option">?-htmlEntities?</b> <b class="option">?-doctypeDeclaration &lt;boolean&gt;?</b>
</dt> 
        <dd>Returns the DOM tree serialized acording to HTML rules (HTML
elements are recognized regardless of case, without end tags for emtpy HTML

elements etc.), as string or sends the output directly to the given
channelId. If the option <i class="m">-escapeNonASCII</i> is given, every non 7 bit ASCII
character in attribute values or element PCDATA content will be escaped as
character reference in decimal representation. If the option
<i class="m">-htmlEntities</i> is given, a character is outputed using a HTML 4.01
character entity reference, if one is defined for it. The flag
<i class="m">-doctypeDeclaration</i> determines, whether there will be a DOCTYPE
declaration emitted before the first node of the document. The default is, to

do not. The DOCTYPE name will always be the element name of the document
element without case normalization. An external entity declaration of the
external subset is only emitted, if the document has a system identifier. The
doctype declaration will be written from the avaliable informations, without

check, if this is a known (w3c) HTML version information or if the document
confirms to the given HTML version.</dd>
      

      
        <dt><b class="method">asText</b></dt>
          <dd>The asText method outputs the result tree by outputting
the string-value of every text node in the result tree in document
order without any escaping. In effect, this is what the xslt output method
"text" (XSLT 1.0 recommendation, section 16.3) does.</dd>
      

















































































      
        <dt>
<b class="method">publicId</b> <i class="m">?publicId?</i>
</dt>
        <dd>Returns the public identifier of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the public identifier of the document is set to this
................................................................................
        <dd>Returns the system identifier of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the system identifier of the document is set to this
value.</dd>
      

      

        <dt><b class="method">internalSubset <i class="m">?internalSubset?</i>
</b></dt>
        <dd>Returns the internal subset of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the internal subset of the document is set to this
value. Note, that none of the parsing methods preserve the internal subset
of a document; a freshly parsed document will always have an empty internal
subset. Also note, that the method doesen't do any syntactical check on a
given internal subset.</dd>
      

      
        <dt>
<b class="method">cdataSectionElements</b> <i class="m">(?URI:?localname|*) ?&lt;boolean&gt;?</i>
</dt>
        <dd>This method allows to control, for which element nodes
the text node childs will be serialized as CDATA sections (this affects only
serialization with the asXML method, no text node is altered in any
way by this method). IF the method is called with an element name as
first argument and a boolean with value true as second argument, every
text node child of every element node in the document with the same
name as the first argument will be serialized as CDATA section. If the
second argument is a boolean with value false, all text nodes of all
elements with the same name as the first argument will be serialized
as usual. Namespaced element names have to given in the form
namespace_URI:localname, not in the otherwise usual prefix:localname
form. With two arguments called, the method returns the used boolean
value. If the method is called with only an element name, it will
return a boolean value, indicating, if the text nodes childs of all
elements with that name in the document will be serialized as CDATA
section elements (return value 1) or not (return value 0). If the
method is called with only one argument and that argument is an
asterisk ('*'), then the method returns an unordered list of all
element names of the document, for which the text node childs will be
serialized as CDATA section nodes.</dd>
      

      
        <dt>
<b class="method">selectNodesNamespaces</b> <b class="option">?prefixUriList?</b>
</dt>
        <dd>This method allows to control a document global prefix
to namespace URI mapping, which will be used for selectNodes method
calls (on document as well as on all nodes, which belongs to the
document), if it is not overwritten by using the -namespaces option of

the selectNodes method. Any namespace prefix within an xpath
expression will be first resolved against this list. If the list bind
the same prefix to different namespaces, then the first binding will
win. If a prefix could not resolved against the document global prefix
/ namespaces list, then the namespace definitions in scope of the
context node will be used to resolve the prefix, as usual. If the
optional argument <i class="m">prefixUriList</i> is given, then the global prefix /
namespace list is set to this list and returns it. Without
the optional argument the method returns the current list. The
default is the empty list.</dd>
      

      
        <dt>
<b class="method">xslt</b> <b class="option">?-parameters
parameterList?</b> <b class="option">?-ignoreUndeclaredParameters?</b>

<b class="option">?-xsltmessagecmd script?</b> <i class="m">stylesheet</i> <i class="m">?outputVar?</i>
</dt>
        <dd>Applies an XSLT transformation on the whole document of the node
object using the XSLT <i class="m">stylesheet</i> (given as domDoc). Returns a document
object containing the result document of the transformation and stores that
document object in the optional <i class="m">outputVar</i>, if that was given.

................................................................................
<p>The optional <i class="m">-parameters</i> option sets top level
&lt;xsl:param&gt; to string values. The <i class="m">parameterList</i> has to be a tcl
list consisting of parameter name and value pairs.</p>

<p>If the option <i class="m">-ignoreUndeclaredParameters</i> is given, then parameter
names in the <i class="m">parameterList</i> given to the <i class="m">-parameters</i> options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised, if the user tries to set a
top-level parameter, which is not declared in the stylesheet.</p>






<p>The <i class="m">-xsltmessagecmd</i> option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes".</p>





</dd>
      

      
        <dt>
<b class="method">toXSLTcmd</b> ?<i class="m">objVar</i>?</dt>
     
        <dd>If the DOM tree represents a valid XSLT stylesheet, this method
transforms the DOM tree into an xslt command, otherwise it returns error. The
created xsltCmd is returnd and stored in the <i class="m">objVar</i>, if a var name was
given. A successful transformation of the DOM tree to an xsltCmd removes the
domDoc cmd and all nodeCmds of the document. 

<p>The syntax of the created xsltCmd is:</p>
 
<pre class="syntax">
<b class="cmd">xsltCmd</b> <b class="option">method</b> <b class="option">?arg ...?</b>
................................................................................
<p>The valid methods are:</p>

<dl class="commandlist">
  
    <dt>
<b class="method">transform</b> <b class="option">?-parameters
parameterList?</b> <b class="option">?-ignoreUndeclaredParameters?</b>

<b class="option">?-xsltmessagecmd script?</b> <i class="m">domDoc</i> <i class="m">?outputVar?</i>
</dt>          

        <dd>Applies XSLT transformation on the document
<i class="m">domDoc</i>. Returns a document object containing the
result document of that transformation and stores it in the optional
<i class="m">outputVar</i>. 
................................................................................
<p>The optional <i class="m">-parameters</i> option sets top level
&lt;xsl:param&gt; to string values. The <i class="m">parameterList</i> has to be a tcl
list consisting of parameter name and value pairs.</p>

<p>If the option <i class="m">-ignoreUndeclaredParameters</i> is given, then parameter
names in the <i class="m">parameterList</i> given to the <i class="m">-parameters</i> options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised, if the user tries to set a
top-level parameter, which is not declared in the stylesheet.</p>






<p>The <i class="m">-xsltmessagecmd</i> option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes".</p>
................................................................................
 </dd>
      

      
        <dt>
<b class="method">normalize</b> <i class="m">?-forXPath?</i>
</dt>
        <dd>Puts all Text nodes in the document
into a "normal" form where only structure (e.g., elements,
comments, processing instructions and CDATA
sections) separates Text nodes, i.e., there
are neither adjacent Text nodes nor empty Text nodes. If the option
<i class="m">-forXPath</i> is given, all CDATA sections in the nodes are
converted to text nodes, as a first step before the
normalization. </dd>
      

      
        <dt><b class="method">nodeType</b></dt>
................................................................................
      

      
        <dt>
<b class="method">getElementById</b> <i class="m">id</i>
</dt>
        <dd>Returns the node having a id attribute with value
<i class="m">id</i> or the emtpy string, if no node has an id attribute with that value.</dd>
      

      
        <dt>
<b class="method">firstChild</b> <b class="variable">?objVar?</b>
</dt>
        <dd>Returns the first top level node of the document.</dd>
................................................................................
      

      
        <dt>
<b class="method">insertBefore</b> <i class="m">newChild</i>  <i class="m">refChild</i>
</dt>
        <dd>Insert <i class="m">newChild</i> before the <i class="m">refChild</i> into the list of
top level nodes of the document. If <i class="m">refChild</i> is the empty string, insert
<i class="m">newChild</i> at the end of the top level nodes.</dd>
      

      
        <dt>
<b class="method">replaceChild</b> <i class="m">newChild</i>  <i class="m">oldChild</i>
</dt>
        <dd>Replace <i class="m">oldChild</i> with <i class="m">newChild</i> in the list of
children of that node. The <i class="m">oldChild</i> node will be part of the
document fragment list after this operation.</dd>
      

      
        <dt>
<b class="method">appendFromList</b> <i class="m">list</i>
................................................................................
<p>The argument <i class="m">xpathQuery</i> has to be a valid XPath
expression. However, there is one exception to that rule. Tcl variable
names can appear in the XPath statement at any position where it is
legal according to the rules of the XPath syntax to put an XPath
variable. The value of the variable is substituted for the variable
name. Ignoring the syntax rules of XPath the Tcl variable name may be
any legal Tcl var name: local variables, global variables, array
entries and so on.</p>



<p>The option <i class="m">-namespaces</i> expects a tcl list with prefix /
namespace pairs as argument. If this option is not given, then any
namespace prefix within the xpath expression will be first resolved
against the list of prefix / namespace pairs set with the
selectNodesNamespaces method for the document, the node belongs to. If
this fails, then the namespace definitions in scope of the context
node will be used to resolve the prefix. If this option is given, any
namespace prefix within the xpath expression will be first resolved
against that given list (and ignoring the document global prefix /
namespace list). If the list bind the same prefix to different
namespaces, then the first binding will win.  If this fails, then the
namespace definitions in scope of the context node will be used to
resolve the prefix, as usual.</p>

<p>If the <i class="m">-cache</i> option is used with a true value, then the
<i class="m">xpathQuery</i> will be looked up in a document specific cache. If the query
is found, then the stored pre-compiled query will be used. If the
query isn't found, it will be pre-compiled and stored in the cache,
for use in further calls. Please notice, that the <i class="m">xpathQuery</i> as given as
string is used as key for the cache. This means, that equal XPath
expressions, which differ only in white space are treated as
different cache entries. Special care is needed, if the XPath
expression includes namespace prefixes. During pre-compilation, the
prefixes will be resolved first to the prefix / namespace pairs of
the <i class="m">-namespaces</i> option, if given, and to the namespaces
in scope of the context node at pre-compilation time. If the XPath
is found in the cache, neither the <i class="m">-namespaces</i> option nor
the namespaces in scope of the context node will be taken in
account but the already resolved (stored) namespaces will be used
for the query.</p>



<p>Examples:</p>
          <pre class="example">set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
foreach paragraph $paragraphNodes {
    lappend  values [$paragraph selectNodes attribute::type]
}

................................................................................
set root [$doc documentElement]
set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]</pre>

          </dd>
      

      

        <dt><b class="method">baseURI <i class="m">?URI?</i>
</b></dt>
        <dd>Returns the present baseURI of the document. If the optional 
argument URI is given, sets the base URI of the document to the given URI.</dd>
      

      
        <dt>
<b class="method">appendFromScript</b> <i class="m">tclScript</i>
................................................................................
expressions of the document are freed. If called with the optional
argument <i class="m">xpathQuery</i>, this single XPath query will be removed
from the cache, if it is there. The method always returns an
empty string.</dd>
      

  </dl><p>Otherwise, if an unknown method name is given, the command with the
same name as the given metho within the namespace <tt class="samp">::dom::domDoc</tt> is
tried to be executed. This allows quick method additions on Tcl level.</p><p>Newly created nodes are appended to a hidden fragment list. If they
are not moved into the tree they are automaticaly deleted, when the whole
document gets deleted.</p>

    <h2><a name="SECTid0x80cf590">SEE ALSO</a></h2><p class="seealso">dom, domNode</p>

    <h2><a name="SECTid0x80cf7b0">KEYWORDS</a></h2><p class="keywords">
<a class="keyword" href="keyword-index.html#KW-DOMnodecreation">DOM node creation</a>, <a class="keyword" href="keyword-index.html#KW-documentelement">document element</a>
</p>

</div><hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> <a class="navaid" href="category-index.html">Index</a> ท <a class="navaid" href="keyword-index.html">Keywords</a>
</div>
</body>
</html>


|



|


|


|
<

|







 







|









|







 







|

>
|
|
>
>
|
|
|
>
>
|
|
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>

>
>
>
>
|
>
>
>
>

>
>
>
>
>
|
>
>
>




|
|
>
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|




|
|
|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
|
|



|

|







|
|







|



|




|







|
|
|
|
>
|
|
|
|
|
|
|
|
|
|






>







 







|
|
>
>
>
>
>






|
>
>
>
>
>









|







 







>







 







|

>
>
>
>
>







 







|


|
|







 







|







 







|







|







 







|
>
>





|




|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>







 







>
|
|







 







|

|


|

|




|



1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
..
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
...
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
...
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
...
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
...
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
...
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
...
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
...
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
...
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
...
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
...
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: domDoc</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: tmml-html.xsl,v $ $Revision: 1.11 $"><meta charset="utf-8">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid0x1eae960">NAME</a> ยท <a href="#SECTid0x1e5ff20">SYNOPSIS</a> ยท <a href="#SECTid0x1e97f70">DESCRIPTION </a> ยท <a href="#SECTid0x1efaea0">SEE ALSO</a> ยท <a href="#SECTid0x1efb230">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
  <h2><a name="SECTid0x1eae960">NAME</a></h2><p class="namesection">
<b class="names">domDoc - </b><br>Manipulates an instance of a DOM document object</p>
  
  <h2><a name="SECTid0x1e5ff20">SYNOPSIS</a></h2><pre class="syntax">domDocObjCmd <i class="m">method</i> ?<i class="m">arg arg ...</i>?</pre><pre class="syntax">domDoc <i class="m">docToken</i> <i class="m">method</i> ?<i class="m">arg arg ...</i>?</pre>


  <h2><a name="SECTid0x1e97f70">DESCRIPTION </a></h2><p>This command manipulates one particular instance of a document
object. <i class="m">method</i> indicates a specific method of the document class. These
methods should closely conform to the W3C recommendation "Document Object Model
(Core) Level 1" (<a href="http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html">http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html</a>). Look
at these documents for a deeper understanding of the functionality.</p><p>The valid methods are:</p><dl class="commandlist">
        
          <dt>
<b class="method">documentElement</b> ?<i class="m">objVar</i>?</dt>
................................................................................

        
          <dt>
<b class="method">createElement</b> <i class="m">tagName</i> ?<i class="m">objVar</i>?</dt>
          <dd>Creates (allocates) a new element node with node name
<i class="m">tagName</i>, append it to the hidden fragment list in the document
object and returns the node object.  If <i class="m">objVar</i> is given the new
node object is stored in this variable.</dd>
        

        
          <dt>
<b class="method">createElementNS</b> <i class="m">url</i> <i class="m">tagName</i> ?<i class="m">objVar</i>?</dt>
          <dd>Creates (allocates) a new element node within a namespace
having <i class="m">uri</i> as the URI and node name <i class="m">tagName</i>, which
could include the namespace prefix, append it to the hidden fragment list in
the document object and returns the node object.  If <i class="m">objVar</i> is
given the new node object is stored in this variable.</dd>
        

        
          <dt>
<b class="method">createTextNode</b> <i class="m">text</i> ?<i class="m">objVar</i>?</dt>
          <dd>Creates (allocates) a new text node with node value
<i class="m">text</i>, appends it to the hidden fragment list in the document
................................................................................
          <dt><b class="method">getDefaultOutputMethod</b></dt>
          <dd>Returns the default output method of the document. This is
usually a result of a XSLT transformation.</dd>
        

      
        <dt>
<b class="method">asXML</b> <b class="option">?-indent none/1..8?</b> <b class="option">?-channel channelId?</b> <b class="option">?-escapeNonASCII?</b> <b class="option">?-doctypeDeclaration &lt;boolean&gt;?</b> <b class="option">-xmlDeclaration &lt;boolean&gt;?</b> <b class="option">-encString &lt;string&gt;</b> <b class="option">?-escapeAllQuot?</b> <b class="option">?-indentAttrs?</b> <b class="option">?-nogtescape?</b> <b class="option">?-noEmptyElementTag?</b>
</dt>
        <dd>
<p>Returns the DOM tree as an (optional indented) XML
        string or sends the output directly to the given
        channelId.</p>

        <p>If the option <i class="m">-escapeNonASCII</i> is given,
        every non 7 bit ASCII character in attribute values or element
        PCDATA content will be escaped as character reference in
        decimal representation.</p>

        <p>The flag <i class="m">-doctypeDeclaration</i> determines whether
        there will be a DOCTYPE declaration emitted before the first
        node of the document. The default is not to emit it. The
        DOCTYPE name will always be the element name of the document
        element. An external entity declaration of the external subset
        is only emitted if the document has a system identifier.</p>

        <p>The flag <i class="m">-xmlDeclaration</i> determines whether there
        will be an XML Declaration and a newline emitted before
        anything else. The default is not to emit one. If this flag is
        given with a true argument then</p>

        <p>
<i class="m">-encString</i> sets the encoding value in the XML
        Declaration. Otherwise this option is ignored. Please note
        that this option just enhances the string representation of the
        generated XML Declaration with an encoding information string,
        nothing more. It's up to the user to handle encoding in case
        of writing to a channel or reparsing.</p>
            
        <p>If the option <i class="m">-escapeAllQuot</i> is given,
        quotation marks will be escaped with &amp;quot; even in text
        content of elements.</p>

        <p>If the option <i class="m">-indentAttrs</i> is
        given, then attributes will each be separated with newlines
        and indented to the same level as the parent node plus the
        value given as argument to <i class="m">-indentAttrs</i> (0..8).</p>

        <p>If the option <i class="m">-nogtescape</i> is given then the
        character '&gt;' won't get escaped in attribute values and text
        content of elements. The default is to escape this
        character.</p>

        <p>If the option <i class="m">-noEmptyElementTag</i> is given then no
        empty tag syntax will be used. Instead, if an element has
        empty content it will be serialized with an element start tag
        and an immediately following element end tag.</p>
</dd>

      

      
        <dt>
<b class="method">asHTML</b> <b class="option">?-channel
channelId?</b> <b class="option">?-escapeNonASCII?</b> <b class="option">?-htmlEntities?</b> <b class="option">?-doctypeDeclaration &lt;boolean&gt;?</b>
</dt> 
        <dd>Returns the DOM tree serialized according to HTML rules
        (HTML elements are recognized regardless of case, without end
        tags for empty HTML elements etc.) as string or sends the
        output directly to the given channelId. If the option
        <i class="m">-escapeNonASCII</i> is given, every non 7 bit ASCII
        character in attribute values or element PCDATA content will
        be escaped as character reference in decimal representation.
        If the option <i class="m">-htmlEntities</i> is given, a character is
        written using its HTML 4.01 character entity reference, if it
        has one. If the flag <i class="m">-doctypeDeclaration</i> is given there
        will be a DOCTYPE declaration emitted before the first node of
        the document. The default is, to do not. The DOCTYPE name will
        always be the element name of the document element without
        case normalization. An external entity declaration of the
        external subset is only emitted, if the document has a system
        identifier. The doctype declaration will be written from the
        available information, without check, if this is a known
        (w3c) HTML version information or if the document confirms to
        the given HTML version.</dd>
      

      
        <dt><b class="method">asText</b></dt>
          <dd>The asText method returns the tree by serializing the
          string-value of every text node in document order without
          any escaping. In effect, this is what the xslt output method
          "text" (XSLT 1.0 recommendation, section 16.3) does.</dd>
      

      
        <dt>
<b class="method">asJSON</b> <b class="option">?-indent none/0..8?</b> <b class="option">?-channel channelId?</b>
</dt>
          <dd>
<p>The asJSON method serializes the tree into a valid
          JSON data string. In general, this may be a lossy
          serialization. For this serialization all comment, character
          data sections and processing instruction nodes, all
          attributes and all XML namespaces are ignored. Only element
          and text nodes may be reflected in the generated JSON
          serialization. Appropriate JSON data type information of a
          node will be respected.</p>

          <p>If an element node has the JSON type OBJECT, then every
          element node child of this element will be serialized as
          member of that object, with the node name of the child as
          the member name and the relevant children of that child as
          the value. Every other child nodes will be ignored.</p>

          <p>If an element node has the JSON type ARRAY, then the text
          and element node children of that element node are serialized
          as the consecutive values of the array. Element node children
          of an ARRAY element will be container nodes for nested ARRAY
          or OBJECT values.</p>

          <p>Text nodes with the JSON types TRUE, FALSE or NULL will
          be serialized to the corresponding JSON token without
          looking at the value of the text node. A text node without
          JSON type will always be serialized as a JSON string token.
          A text node with JSON type NUMBER will be serialized as JSON
          number token if the text node value is in fact a valid JSON
          number and as a JSON string if not.</p>

          <p>If an element node doesn't has a JSON type then the
          serialization of its children is determined by the following
          rules:</p>

          <p>Only text and element node child are relevant. If the
          element node to serialize is the member of a JSON object and
          there is no relevant child node the value of that member
          will be an empty JSON string. If the only relevant child
          node of this element node is a text node then the JSON
          value of that text node will be the value of the object
          member. If the element has more than one relevant child
          nodes and the first one is a text node then the relevant
          children will be serialized as JSON array. If the only
          relevant child node is an element node or the first relevant
          child is an element node and the node name of that only or
          first relevant child isn't equal to the array container node
          name all element node children will be serialized as the
          members of a JSON object (while ignoring any intermixed text
          nodes). If the only or first relevant child is an element
          node and the node name of this child is equal to the array
          container element name then all relevant children will be
          serialized as the values of a JSON array.</p>

          <p>If the element to serialize is a value of a JSON array
          and the node name of this element isn't equal to the array
          container node name that element will be seen as a container
          node for a JSON object and all element node children will be
          serialized as the members of that array while ignoring any
          text node children. If the element to serialize is a value of
          a JSON array and the node name of this element is equal to
          the array container node name, all relevant children will be
          serialized as JSON array.</p>

          <p>If the <i class="m">-channel</i> option is given the serialization
          isn't returned as string but send directly to the channel,
          given as argument to the option.</p>

          <p>If the <i class="m">-indent</i> option is given and the argument
          given to this option isn't "none" then the returned JSON
          string is "pretty-printed". The numeric argument to this
          option defines the number of spaces for any indentation
          level. The default is to not emit any additional
          white space.</p>
</dd>
      
      
      
        <dt>
<b class="method">publicId</b> <i class="m">?publicId?</i>
</dt>
        <dd>Returns the public identifier of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the public identifier of the document is set to this
................................................................................
        <dd>Returns the system identifier of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the system identifier of the document is set to this
value.</dd>
      

      
        <dt>
<b class="method">internalSubset</b> <i class="m">?internalSubset?</i>
</dt>
        <dd>Returns the internal subset of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the internal subset of the document is set to this
value. Note that none of the parsing methods preserve the internal subset
of a document; a freshly parsed document will always have an empty internal
subset. Also note, that the method doesn't do any syntactical check on a
given internal subset.</dd>
      

      
        <dt>
<b class="method">cdataSectionElements</b> <i class="m">(?URI:?localname|*) ?&lt;boolean&gt;?</i>
</dt>
        <dd>This method allows one to control for which element nodes
the text node children will be serialized as CDATA sections (this affects only
serialization with the asXML method, no text node is altered in any
way by this method). IF the method is called with an element name as
first argument and a boolean with value true as second argument, every
text node child of every element node in the document with the same
name as the first argument will be serialized as CDATA section. If the
second argument is a boolean with value false, all text nodes of all
elements with the same name as the first argument will be serialized
as usual. Namespaced element names have to be given in the form
namespace_URI:localname, not in the otherwise usual prefix:localname
form. With two arguments called, the method returns the used boolean
value. If the method is called with only an element name, it will
return a boolean value, indicating that the text node children of all
elements with that name in the document will be serialized as CDATA
section elements (return value 1) or not (return value 0). If the
method is called with only one argument and that argument is an
asterisk ('*'), then the method returns an unordered list of all
element names of the document, for which the text node children will be
serialized as CDATA section nodes.</dd>
      

      
        <dt>
<b class="method">selectNodesNamespaces</b> <b class="option">?prefixUriList?</b>
</dt>
        <dd>This method allows one to control a document global prefix
        to namespace URI mapping, which will be used for selectNodes
        method calls (on document as well as on all nodes, which
        belongs to the document) if it is not overwritten by using
        the -namespaces option of the selectNodes method. Any
        namespace prefix within an xpath expression will be first
        resolved against this list. If the list binds the same prefix
        to different namespaces, then the first binding will win. If a
        prefix could not resolved against the document global prefix /
        namespaces list, then the namespace definitions in scope of
        the context node will be used to resolve the prefix, as usual.
        If the optional argument <i class="m">prefixUriList</i> is given, then
        the global prefix / namespace list is set to this list and
        returns it. Without the optional argument the method returns
        the current list. The default is the empty list.</dd>
      

      
        <dt>
<b class="method">xslt</b> <b class="option">?-parameters
parameterList?</b> <b class="option">?-ignoreUndeclaredParameters?</b>
<b class="option">?-maxApplyDepth int?</b>
<b class="option">?-xsltmessagecmd script?</b> <i class="m">stylesheet</i> <i class="m">?outputVar?</i>
</dt>
        <dd>Applies an XSLT transformation on the whole document of the node
object using the XSLT <i class="m">stylesheet</i> (given as domDoc). Returns a document
object containing the result document of the transformation and stores that
document object in the optional <i class="m">outputVar</i>, if that was given.

................................................................................
<p>The optional <i class="m">-parameters</i> option sets top level
&lt;xsl:param&gt; to string values. The <i class="m">parameterList</i> has to be a tcl
list consisting of parameter name and value pairs.</p>

<p>If the option <i class="m">-ignoreUndeclaredParameters</i> is given, then parameter
names in the <i class="m">parameterList</i> given to the <i class="m">-parameters</i> options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised if the user tries to set a
top-level parameter that is not declared in the stylesheet.</p>

<p>The option <i class="m">-maxApplyDepth</i> expects a positiv integer as
argument. By default, the xslt engine allows xslt templates to nest up
to 3000 levels (and raises error if they nest deeper). This limit can
be set by the <i class="m">-maxApplyDepth</i> option.</p>

<p>The <i class="m">-xsltmessagecmd</i> option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes". If the
called script returns anything else then TCL_OK then the xslt
transformation will be aborted, returning error. If the called script
returns -code break, the error message is empty, otherwise the result
code is reported. In case of terminated transformation, the outputVar,
if given, is set to the empty string.</p>
</dd>
      

      
        <dt>
<b class="method">toXSLTcmd</b> ?<i class="m">objVar</i>?</dt>
     
        <dd>If the DOM tree represents a valid XSLT stylesheet, this method
transforms the DOM tree into an xslt command, otherwise it returns error. The
created xsltCmd is returned and stored in the <i class="m">objVar</i>, if a var name was
given. A successful transformation of the DOM tree to an xsltCmd removes the
domDoc cmd and all nodeCmds of the document. 

<p>The syntax of the created xsltCmd is:</p>
 
<pre class="syntax">
<b class="cmd">xsltCmd</b> <b class="option">method</b> <b class="option">?arg ...?</b>
................................................................................
<p>The valid methods are:</p>

<dl class="commandlist">
  
    <dt>
<b class="method">transform</b> <b class="option">?-parameters
parameterList?</b> <b class="option">?-ignoreUndeclaredParameters?</b>
<b class="option">?-maxApplyDepth int?</b> 
<b class="option">?-xsltmessagecmd script?</b> <i class="m">domDoc</i> <i class="m">?outputVar?</i>
</dt>          

        <dd>Applies XSLT transformation on the document
<i class="m">domDoc</i>. Returns a document object containing the
result document of that transformation and stores it in the optional
<i class="m">outputVar</i>. 
................................................................................
<p>The optional <i class="m">-parameters</i> option sets top level
&lt;xsl:param&gt; to string values. The <i class="m">parameterList</i> has to be a tcl
list consisting of parameter name and value pairs.</p>

<p>If the option <i class="m">-ignoreUndeclaredParameters</i> is given, then parameter
names in the <i class="m">parameterList</i> given to the <i class="m">-parameters</i> options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised if the user tries to set a
top-level parameter, which is not declared in the stylesheet.</p>

<p>The option <i class="m">-maxApplyDepth</i> expects a positiv integer as
argument. By default, the xslt engine allows xslt templates to nest up
to 3000 levels (and raises error if they nest deeper). This limit can
be set by the <i class="m">-maxApplyDepth</i> option.</p>

<p>The <i class="m">-xsltmessagecmd</i> option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes".</p>
................................................................................
 </dd>
      

      
        <dt>
<b class="method">normalize</b> <i class="m">?-forXPath?</i>
</dt>
        <dd>Puts all text nodes in the document
into a "normal" form where only structure (e.g., elements,
comments, processing instructions and CDATA
sections) separates text nodes, i.e., there
are neither adjacent text nodes nor empty text nodes. If the option
<i class="m">-forXPath</i> is given, all CDATA sections in the nodes are
converted to text nodes, as a first step before the
normalization. </dd>
      

      
        <dt><b class="method">nodeType</b></dt>
................................................................................
      

      
        <dt>
<b class="method">getElementById</b> <i class="m">id</i>
</dt>
        <dd>Returns the node having a id attribute with value
<i class="m">id</i> or the empty string, if no node has an id attribute with that value.</dd>
      

      
        <dt>
<b class="method">firstChild</b> <b class="variable">?objVar?</b>
</dt>
        <dd>Returns the first top level node of the document.</dd>
................................................................................
      

      
        <dt>
<b class="method">insertBefore</b> <i class="m">newChild</i>  <i class="m">refChild</i>
</dt>
        <dd>Insert <i class="m">newChild</i> before the <i class="m">refChild</i> into the list of
top level nodes of the document. If <i class="m">refChild</i> is the empty string, inserts
<i class="m">newChild</i> at the end of the top level nodes.</dd>
      

      
        <dt>
<b class="method">replaceChild</b> <i class="m">newChild</i>  <i class="m">oldChild</i>
</dt>
        <dd>Replaces <i class="m">oldChild</i> with <i class="m">newChild</i> in the list of
children of that node. The <i class="m">oldChild</i> node will be part of the
document fragment list after this operation.</dd>
      

      
        <dt>
<b class="method">appendFromList</b> <i class="m">list</i>
................................................................................
<p>The argument <i class="m">xpathQuery</i> has to be a valid XPath
expression. However, there is one exception to that rule. Tcl variable
names can appear in the XPath statement at any position where it is
legal according to the rules of the XPath syntax to put an XPath
variable. The value of the variable is substituted for the variable
name. Ignoring the syntax rules of XPath the Tcl variable name may be
any legal Tcl var name: local variables, global variables, array
entries and so on.  The value will always be seen as string literal by
the xpath engine. Cast the value explicitly with the according xpath
functions (number(), boolean()) to another data type, if needed.</p>

<p>The option <i class="m">-namespaces</i> expects a tcl list with prefix /
namespace pairs as argument. If this option is not given, then any
namespace prefix within the xpath expression will be first resolved
against the list of prefix / namespace pairs set with the
selectNodesNamespaces method for the document the node belongs to. If
this fails, then the namespace definitions in scope of the context
node will be used to resolve the prefix. If this option is given, any
namespace prefix within the xpath expression will be first resolved
against that given list (and ignoring the document global prefix /
namespace list). If the list binds the same prefix to different
namespaces, then the first binding will win.  If this fails, then the
namespace definitions in scope of the context node will be used to
resolve the prefix, as usual.</p>

<p>If the <i class="m">-cache</i> option is used with a true value, then the
<i class="m">xpathQuery</i> will be looked up in a document specific cache. If
the query is found, then the stored pre-compiled query will be used.
If the query isn't found, it will be compiled and stored in the cache,
for use in further calls. Please notice, that the <i class="m">xpathQuery</i> as
given as string is used as key for the cache. This means that equal
XPath expressions, which differ only in white space, are treated as
different cache entries. Special care is needed if the XPath
expression includes namespace prefixes or references to tcl variables.
Both namespace prefixes and tcl variable references will be resolved
according to the XML prefix namespace mappings and tcl variable values
at expression compilation time. If the same XPath expression is used
later on in a context with other XML prefix namespace mappings or
values of the used tcl variables, make sure to first remove the
compiled expression from the cache with the help of the
<b class="method">deleteXPathCache</b> method, to force a recompilation.
Without using the <i class="m">-cache</i> option such consideration is never
needed.</p>

<p>Examples:</p>
          <pre class="example">set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
foreach paragraph $paragraphNodes {
    lappend  values [$paragraph selectNodes attribute::type]
}

................................................................................
set root [$doc documentElement]
set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]</pre>

          </dd>
      

      
        <dt>
<b class="method">baseURI</b> <i class="m">?URI?</i>
</dt>
        <dd>Returns the present baseURI of the document. If the optional 
argument URI is given, sets the base URI of the document to the given URI.</dd>
      

      
        <dt>
<b class="method">appendFromScript</b> <i class="m">tclScript</i>
................................................................................
expressions of the document are freed. If called with the optional
argument <i class="m">xpathQuery</i>, this single XPath query will be removed
from the cache, if it is there. The method always returns an
empty string.</dd>
      

  </dl><p>Otherwise, if an unknown method name is given, the command with the
same name as the given method within the namespace <tt class="samp">::dom::domDoc</tt> is
tried to be executed. This allows quick method additions on Tcl level.</p><p>Newly created nodes are appended to a hidden fragment list. If they
are not moved into the tree they are automatically deleted as soon as the whole
document gets deleted.</p>

    <h2><a name="SECTid0x1efaea0">SEE ALSO</a></h2><p class="seealso">dom, domNode</p>

    <h2><a name="SECTid0x1efb230">KEYWORDS</a></h2><p class="keywords">
<a class="keyword" href="keyword-index.html#KW-DOMnodecreation">DOM node creation</a>, <a class="keyword" href="keyword-index.html#KW-documentelement">document element</a>
</p>

</div><hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>
</div>
</body>
</html>

Changes to doc/domDoc.n.

159
160
161
162
163
164
165
166



167
168
169
170
171
172
173
...
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
...
230
231
232
233
234
235
236
237



238
239


240
241
242


243
244

245
246
247













248
249

















250
251
252
253

254
255
256
257
258
259
260
261

262
263
264
265

266
267
268
269
270
271
272
273














































































274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349





350
351
352
353
354
355
356





357
358
359
360
361
362
363
364
365
366
367
368
369
...
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394





395
396
397
398
399
400
401
...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
...
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
...
484
485
486
487
488
489
490
491


492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522


523
524
525
526
527
528
529
...
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
...
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
'\" END man.macros
.TH domDoc n "" Tcl ""
.BS
.SH NAME
domDoc \- Manipulates an instance of a DOM document object
.SH SYNOPSIS
.nf
\&\fBdomDocObjCmd\fP \fImethod\fR ?\fIarg arg ...\fR?



.fi
.BE
.SH "DESCRIPTION "
.PP
This command manipulates one particular instance of a document
object. \fImethod\fR indicates a specific method of the document class. These
methods should closely conform to the W3C recommendation "Document Object Model
................................................................................
matching (glob style) \fIlocalname\fR and having the given namespace
\&\fIuri\fR.
.TP
\&\fB\fBcreateElement\fP \fItagName\fB ?\fIobjVar\fB?
\&\fRCreates (allocates) a new element node with node name
\&\fItagName\fR, append it to the hidden fragment list in the document
object and returns the node object.  If \fIobjVar\fR is given the new
node object store in this variable.
.TP
\&\fB\fBcreateElementNS\fP \fIurl\fB \fItagName\fB ?\fIobjVar\fB?
\&\fRCreates (allocates) a new element node within a namespace
having \fIuri\fR as the URI and node name \fItagName\fR, which
could include the namespace prefix, append it to the hidden fragment list in
the document object and returns the node object.  If \fIobjVar\fR is
given the new node object store in this variable.
.TP
\&\fB\fBcreateTextNode\fP \fItext\fB ?\fIobjVar\fB?
\&\fRCreates (allocates) a new text node with node value
\&\fItext\fR, appends it to the hidden fragment list in the document
object and returns the node object.  If \fIobjVar\fR is given, the new
node object is stored in this variable.
.TP
................................................................................
Tcl object commands (for nodes, fragment/new nodes, the document object itself)
and the underlying DOM tree.
.TP
\&\fB\fBgetDefaultOutputMethod\fP
\&\fRReturns the default output method of the document. This is
usually a result of a XSLT transformation.
.TP
\&\fB\fBasXML\fP \fB?-indent none/1..8?\fP \fB?-channel channelId?\fP \fB?-escapeNonASCII?\fP \fB?-doctypeDeclaration <boolean>?\fP \fB?-escapeAllQuot?\fP



\&\fRReturns the DOM tree as an (optional indented) XML
string or sends the output directly to the given channelId. If the


option \fI-escapeNonASCII\fR is given, every non 7 bit ASCII
character in attribute values or element PCDATA content will be
escaped as character reference in decimal representation. The flag


\&\fI-doctypeDeclaration\fR determines, whether there will be a DOCTYPE
declaration emitted before the first node of the document. The default

is, to do not. The DOCTYPE name will always be the element name of the
document element. An external entity declaration of the external
subset is only emitted, if the document has a system identifier. If













the option \fI-escapeAllQuot\fR is given, quotation marks will be
escaped with &quot; even in text content of elements.

















.TP
\&\fB\fBasHTML\fP \fB?-channel channelId?\fP \fB?-escapeNonASCII?\fP \fB?-htmlEntities?\fP \fB?-doctypeDeclaration <boolean>?\fP
\&\fRReturns the DOM tree serialized acording to HTML rules (HTML
elements are recognized regardless of case, without end tags for emtpy HTML

elements etc.), as string or sends the output directly to the given
channelId. If the option \fI-escapeNonASCII\fR is given, every non 7 bit ASCII
character in attribute values or element PCDATA content will be escaped as
character reference in decimal representation. If the option
\&\fI-htmlEntities\fR is given, a character is outputed using a HTML 4.01
character entity reference, if one is defined for it. The flag
\&\fI-doctypeDeclaration\fR determines, whether there will be a DOCTYPE
declaration emitted before the first node of the document. The default is, to

do not. The DOCTYPE name will always be the element name of the document
element without case normalization. An external entity declaration of the
external subset is only emitted, if the document has a system identifier. The
doctype declaration will be written from the avaliable informations, without

check, if this is a known (w3c) HTML version information or if the document
confirms to the given HTML version.
.TP
\&\fB\fBasText\fP
\&\fRThe asText method outputs the result tree by outputting
the string-value of every text node in the result tree in document
order without any escaping. In effect, this is what the xslt output method
"text" (XSLT 1.0 recommendation, section 16.3) does.














































































.TP
\&\fB\fBpublicId\fP \fI?publicId?\fB
\&\fRReturns the public identifier of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the public identifier of the document is set to this
value.
.TP
\&\fB\fBsystemId\fP \fI?systemId?\fB
\&\fRReturns the system identifier of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the system identifier of the document is set to this
value.
.TP
\&\fB\fBinternalSubset \fI?internalSubset?\fB\fP
\&\fRReturns the internal subset of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the internal subset of the document is set to this
value. Note, that none of the parsing methods preserve the internal subset
of a document; a freshly parsed document will always have an empty internal
subset. Also note, that the method doesen't do any syntactical check on a
given internal subset.
.TP
\&\fB\fBcdataSectionElements\fP \fI(?URI:?localname|*) ?<boolean>?\fB
\&\fRThis method allows to control, for which element nodes
the text node childs will be serialized as CDATA sections (this affects only
serialization with the asXML method, no text node is altered in any
way by this method). IF the method is called with an element name as
first argument and a boolean with value true as second argument, every
text node child of every element node in the document with the same
name as the first argument will be serialized as CDATA section. If the
second argument is a boolean with value false, all text nodes of all
elements with the same name as the first argument will be serialized
as usual. Namespaced element names have to given in the form
namespace_URI:localname, not in the otherwise usual prefix:localname
form. With two arguments called, the method returns the used boolean
value. If the method is called with only an element name, it will
return a boolean value, indicating, if the text nodes childs of all
elements with that name in the document will be serialized as CDATA
section elements (return value 1) or not (return value 0). If the
method is called with only one argument and that argument is an
asterisk ('*'), then the method returns an unordered list of all
element names of the document, for which the text node childs will be
serialized as CDATA section nodes.
.TP
\&\fB\fBselectNodesNamespaces\fP \fB?prefixUriList?\fP
\&\fRThis method allows to control a document global prefix
to namespace URI mapping, which will be used for selectNodes method
calls (on document as well as on all nodes, which belongs to the
document), if it is not overwritten by using the -namespaces option of

the selectNodes method. Any namespace prefix within an xpath
expression will be first resolved against this list. If the list bind
the same prefix to different namespaces, then the first binding will
win. If a prefix could not resolved against the document global prefix
/ namespaces list, then the namespace definitions in scope of the
context node will be used to resolve the prefix, as usual. If the
optional argument \fIprefixUriList\fR is given, then the global prefix /
namespace list is set to this list and returns it. Without
the optional argument the method returns the current list. The
default is the empty list.
.TP
\&\fB\fBxslt\fP \fB?-parameters parameterList?\fP \fB?-ignoreUndeclaredParameters?\fP \fB?-xsltmessagecmd script?\fP \fIstylesheet\fB \fI?outputVar?\fB
\&\fRApplies an XSLT transformation on the whole document of the node
object using the XSLT \fIstylesheet\fR (given as domDoc). Returns a document
object containing the result document of the transformation and stores that
document object in the optional \fIoutputVar\fR, if that was given.
.RS
.PP
The optional \fI-parameters\fR option sets top level
<xsl:param> to string values. The \fIparameterList\fR has to be a tcl
list consisting of parameter name and value pairs.
.PP
If the option \fI-ignoreUndeclaredParameters\fR is given, then parameter
names in the \fIparameterList\fR given to the \fI-parameters\fR options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised, if the user tries to set a
top-level parameter, which is not declared in the stylesheet.





.PP
The \fI-xsltmessagecmd\fR option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes".





.RE
.TP
\&\fB\fBtoXSLTcmd\fP ?\fIobjVar\fB?
\&\fRIf the DOM tree represents a valid XSLT stylesheet, this method
transforms the DOM tree into an xslt command, otherwise it returns error. The
created xsltCmd is returnd and stored in the \fIobjVar\fR, if a var name was
given. A successful transformation of the DOM tree to an xsltCmd removes the
domDoc cmd and all nodeCmds of the document.
.RS
.PP
The syntax of the created xsltCmd is:

 
................................................................................

\&\fBxsltCmd\fP \fBmethod\fP \fB?arg ...?\fP

.CE
.PP
The valid methods are:
.TP
\&\fB\fBtransform\fP \fB?-parameters parameterList?\fP \fB?-ignoreUndeclaredParameters?\fP \fB?-xsltmessagecmd script?\fP \fIdomDoc\fB \fI?outputVar?\fB
\&\fRApplies XSLT transformation on the document
\&\fIdomDoc\fR. Returns a document object containing the
result document of that transformation and stores it in the optional
\&\fIoutputVar\fR.
.RS
.PP
The optional \fI-parameters\fR option sets top level
<xsl:param> to string values. The \fIparameterList\fR has to be a tcl
list consisting of parameter name and value pairs.
.PP
If the option \fI-ignoreUndeclaredParameters\fR is given, then parameter
names in the \fIparameterList\fR given to the \fI-parameters\fR options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised, if the user tries to set a
top-level parameter, which is not declared in the stylesheet.





.PP
The \fI-xsltmessagecmd\fR option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes".
................................................................................
.PP
If the first argument to an xsltCmd is a domDoc or starts with a "-",
then the command is processed in the same way as
\&\fI<xsltCmd> transform\fR.
.RE
.TP
\&\fB\fBnormalize\fP \fI?-forXPath?\fB
\&\fRPuts all Text nodes in the document
into a "normal" form where only structure (e.g., elements,
comments, processing instructions and CDATA
sections) separates Text nodes, i.e., there
are neither adjacent Text nodes nor empty Text nodes. If the option
\&\fI-forXPath\fR is given, all CDATA sections in the nodes are
converted to text nodes, as a first step before the
normalization.
.TP
\&\fB\fBnodeType\fP
\&\fRReturns the node type of the document node. This is always
DOCUMENT_NODE.
.TP
\&\fB\fBgetElementById\fP \fIid\fB
\&\fRReturns the node having a id attribute with value
\&\fIid\fR or the emtpy string, if no node has an id attribute with that value.
.TP
\&\fB\fBfirstChild\fP \fB?objVar?\fP
\&\fRReturns the first top level node of the document.
.TP
\&\fB\fBlastChild\fP \fB?objVar?\fP
\&\fRReturns the last top level node of the document.
.TP
................................................................................
\&\fRReturns a list of the top level nodes of the document.
.TP
\&\fB\fBownerDocument\fP \fB?domObjVar?\fP
\&\fRReturns the document itself.
.TP
\&\fB\fBinsertBefore\fP \fInewChild\fB  \fIrefChild\fB
\&\fRInsert \fInewChild\fR before the \fIrefChild\fR into the list of
top level nodes of the document. If \fIrefChild\fR is the empty string, insert
\&\fInewChild\fR at the end of the top level nodes.
.TP
\&\fB\fBreplaceChild\fP \fInewChild\fB  \fIoldChild\fB
\&\fRReplace \fIoldChild\fR with \fInewChild\fR in the list of
children of that node. The \fIoldChild\fR node will be part of the
document fragment list after this operation.
.TP
\&\fB\fBappendFromList\fP \fIlist\fB
\&\fRParses \fIlist\fR , creates an according DOM subtree and
appends this subtree at the end of the current list of top level nodes of the document.
.TP
................................................................................
The argument \fIxpathQuery\fR has to be a valid XPath
expression. However, there is one exception to that rule. Tcl variable
names can appear in the XPath statement at any position where it is
legal according to the rules of the XPath syntax to put an XPath
variable. The value of the variable is substituted for the variable
name. Ignoring the syntax rules of XPath the Tcl variable name may be
any legal Tcl var name: local variables, global variables, array
entries and so on.


.PP
The option \fI-namespaces\fR expects a tcl list with prefix /
namespace pairs as argument. If this option is not given, then any
namespace prefix within the xpath expression will be first resolved
against the list of prefix / namespace pairs set with the
selectNodesNamespaces method for the document, the node belongs to. If
this fails, then the namespace definitions in scope of the context
node will be used to resolve the prefix. If this option is given, any
namespace prefix within the xpath expression will be first resolved
against that given list (and ignoring the document global prefix /
namespace list). If the list bind the same prefix to different
namespaces, then the first binding will win.  If this fails, then the
namespace definitions in scope of the context node will be used to
resolve the prefix, as usual.
.PP
If the \fI-cache\fR option is used with a true value, then the
\&\fIxpathQuery\fR will be looked up in a document specific cache. If the query
is found, then the stored pre-compiled query will be used. If the
query isn't found, it will be pre-compiled and stored in the cache,
for use in further calls. Please notice, that the \fIxpathQuery\fR as given as
string is used as key for the cache. This means, that equal XPath
expressions, which differ only in white space are treated as
different cache entries. Special care is needed, if the XPath
expression includes namespace prefixes. During pre-compilation, the
prefixes will be resolved first to the prefix / namespace pairs of
the \fI-namespaces\fR option, if given, and to the namespaces
in scope of the context node at pre-compilation time. If the XPath
is found in the cache, neither the \fI-namespaces\fR option nor
the namespaces in scope of the context node will be taken in
account but the already resolved (stored) namespaces will be used
for the query.


.PP
Examples:

          
.CS
set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
foreach paragraph $paragraphNodes {
................................................................................

set doc [dom parse {<doc xmlns="http://www.defaultnamespace.org"><child/></doc>}]
set root [$doc documentElement]
set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]
.CE
.RE
.TP
\&\fB\fBbaseURI \fI?URI?\fB\fP
\&\fRReturns the present baseURI of the document. If the optional
argument URI is given, sets the base URI of the document to the given URI.
.TP
\&\fB\fBappendFromScript\fP \fItclScript\fB
\&\fRAppends the nodes created by the \fItclScript\fR by
Tcl functions, which have been built using \fIdom createNodeCmd\fR, at the end
of the current list of top level nodes of the document.
................................................................................
\&\fRIf called without the optional argument, all cached XPath
expressions of the document are freed. If called with the optional
argument \fIxpathQuery\fR, this single XPath query will be removed
from the cache, if it is there. The method always returns an
empty string.
.PP
Otherwise, if an unknown method name is given, the command with the
same name as the given metho within the namespace \fB::dom::domDoc\fR is
tried to be executed. This allows quick method additions on Tcl level.
.PP
Newly created nodes are appended to a hidden fragment list. If they
are not moved into the tree they are automaticaly deleted, when the whole
document gets deleted.
.SH "SEE ALSO"
dom, domNode
.SH KEYWORDS
DOM node creation, document element







|
>
>
>







 







|






|







 







|
>
>
>
|
|
>
>
|
|
|
>
>
|
|
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
|
>
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|


|
|
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













|



|

|



|
|







|



|




|



|
|
|
|
>
|
|
|
|
|
|
|
|
|
|

|













|
|
>
>
>
>
>






|
>
>
>
>
>





|







 







|













|

>
>
>
>
>







 







|


|
|










|







 







|



|







 







|
>
>





|




|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>







 







|







 







|



|





159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
...
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
...
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
...
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
...
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
...
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
...
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
...
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
...
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
'\" END man.macros
.TH domDoc n "" Tcl ""
.BS
.SH NAME
domDoc \- Manipulates an instance of a DOM document object
.SH SYNOPSIS
.nf
domDocObjCmd \fImethod\fR ?\fIarg arg ...\fR?
.fi
.nf
domDoc \fIdocToken\fR \fImethod\fR ?\fIarg arg ...\fR?
.fi
.BE
.SH "DESCRIPTION "
.PP
This command manipulates one particular instance of a document
object. \fImethod\fR indicates a specific method of the document class. These
methods should closely conform to the W3C recommendation "Document Object Model
................................................................................
matching (glob style) \fIlocalname\fR and having the given namespace
\&\fIuri\fR.
.TP
\&\fB\fBcreateElement\fP \fItagName\fB ?\fIobjVar\fB?
\&\fRCreates (allocates) a new element node with node name
\&\fItagName\fR, append it to the hidden fragment list in the document
object and returns the node object.  If \fIobjVar\fR is given the new
node object is stored in this variable.
.TP
\&\fB\fBcreateElementNS\fP \fIurl\fB \fItagName\fB ?\fIobjVar\fB?
\&\fRCreates (allocates) a new element node within a namespace
having \fIuri\fR as the URI and node name \fItagName\fR, which
could include the namespace prefix, append it to the hidden fragment list in
the document object and returns the node object.  If \fIobjVar\fR is
given the new node object is stored in this variable.
.TP
\&\fB\fBcreateTextNode\fP \fItext\fB ?\fIobjVar\fB?
\&\fRCreates (allocates) a new text node with node value
\&\fItext\fR, appends it to the hidden fragment list in the document
object and returns the node object.  If \fIobjVar\fR is given, the new
node object is stored in this variable.
.TP
................................................................................
Tcl object commands (for nodes, fragment/new nodes, the document object itself)
and the underlying DOM tree.
.TP
\&\fB\fBgetDefaultOutputMethod\fP
\&\fRReturns the default output method of the document. This is
usually a result of a XSLT transformation.
.TP
\&\fB\fBasXML\fP \fB?-indent none/1..8?\fP \fB?-channel channelId?\fP \fB?-escapeNonASCII?\fP \fB?-doctypeDeclaration <boolean>?\fP \fB-xmlDeclaration <boolean>?\fP \fB-encString <string>\fP \fB?-escapeAllQuot?\fP \fB?-indentAttrs?\fP \fB?-nogtescape?\fP \fB?-noEmptyElementTag?\fP
\&\fR
.RS
.PP
Returns the DOM tree as an (optional indented) XML
string or sends the output directly to the given
channelId.
.PP
If the option \fI-escapeNonASCII\fR is given,
every non 7 bit ASCII character in attribute values or element
PCDATA content will be escaped as character reference in
decimal representation.
.PP
The flag \fI-doctypeDeclaration\fR determines whether
there will be a DOCTYPE declaration emitted before the first
node of the document. The default is not to emit it. The
DOCTYPE name will always be the element name of the document
element. An external entity declaration of the external subset
is only emitted if the document has a system identifier.
.PP
The flag \fI-xmlDeclaration\fR determines whether there
will be an XML Declaration and a newline emitted before
anything else. The default is not to emit one. If this flag is
given with a true argument then
.PP
\&\fI-encString\fR sets the encoding value in the XML
Declaration. Otherwise this option is ignored. Please note
that this option just enhances the string representation of the
generated XML Declaration with an encoding information string,
nothing more. It's up to the user to handle encoding in case
of writing to a channel or reparsing.
.PP
If the option \fI-escapeAllQuot\fR is given,
quotation marks will be escaped with &quot; even in text
content of elements.
.PP
If the option \fI-indentAttrs\fR is
given, then attributes will each be separated with newlines
and indented to the same level as the parent node plus the
value given as argument to \fI-indentAttrs\fR (0..8).
.PP
If the option \fI-nogtescape\fR is given then the
character '>' won't get escaped in attribute values and text
content of elements. The default is to escape this
character.
.PP
If the option \fI-noEmptyElementTag\fR is given then no
empty tag syntax will be used. Instead, if an element has
empty content it will be serialized with an element start tag
and an immediately following element end tag.
.RE
.TP
\&\fB\fBasHTML\fP \fB?-channel channelId?\fP \fB?-escapeNonASCII?\fP \fB?-htmlEntities?\fP \fB?-doctypeDeclaration <boolean>?\fP
\&\fRReturns the DOM tree serialized according to HTML rules
(HTML elements are recognized regardless of case, without end
tags for empty HTML elements etc.) as string or sends the
output directly to the given channelId. If the option
\&\fI-escapeNonASCII\fR is given, every non 7 bit ASCII
character in attribute values or element PCDATA content will
be escaped as character reference in decimal representation.
If the option \fI-htmlEntities\fR is given, a character is
written using its HTML 4.01 character entity reference, if it
has one. If the flag \fI-doctypeDeclaration\fR is given there
will be a DOCTYPE declaration emitted before the first node of
the document. The default is, to do not. The DOCTYPE name will
always be the element name of the document element without
case normalization. An external entity declaration of the
external subset is only emitted, if the document has a system
identifier. The doctype declaration will be written from the
available information, without check, if this is a known
(w3c) HTML version information or if the document confirms to
the given HTML version.
.TP
\&\fB\fBasText\fP
\&\fRThe asText method returns the tree by serializing the
string-value of every text node in document order without
any escaping. In effect, this is what the xslt output method
"text" (XSLT 1.0 recommendation, section 16.3) does.
.TP
\&\fB\fBasJSON\fP \fB?-indent none/0..8?\fP \fB?-channel channelId?\fP
\&\fR
.RS
.PP
The asJSON method serializes the tree into a valid
JSON data string. In general, this may be a lossy
serialization. For this serialization all comment, character
data sections and processing instruction nodes, all
attributes and all XML namespaces are ignored. Only element
and text nodes may be reflected in the generated JSON
serialization. Appropriate JSON data type information of a
node will be respected.
.PP
If an element node has the JSON type OBJECT, then every
element node child of this element will be serialized as
member of that object, with the node name of the child as
the member name and the relevant children of that child as
the value. Every other child nodes will be ignored.
.PP
If an element node has the JSON type ARRAY, then the text
and element node children of that element node are serialized
as the consecutive values of the array. Element node children
of an ARRAY element will be container nodes for nested ARRAY
or OBJECT values.
.PP
Text nodes with the JSON types TRUE, FALSE or NULL will
be serialized to the corresponding JSON token without
looking at the value of the text node. A text node without
JSON type will always be serialized as a JSON string token.
A text node with JSON type NUMBER will be serialized as JSON
number token if the text node value is in fact a valid JSON
number and as a JSON string if not.
.PP
If an element node doesn't has a JSON type then the
serialization of its children is determined by the following
rules:
.PP
Only text and element node child are relevant. If the
element node to serialize is the member of a JSON object and
there is no relevant child node the value of that member
will be an empty JSON string. If the only relevant child
node of this element node is a text node then the JSON
value of that text node will be the value of the object
member. If the element has more than one relevant child
nodes and the first one is a text node then the relevant
children will be serialized as JSON array. If the only
relevant child node is an element node or the first relevant
child is an element node and the node name of that only or
first relevant child isn't equal to the array container node
name all element node children will be serialized as the
members of a JSON object (while ignoring any intermixed text
nodes). If the only or first relevant child is an element
node and the node name of this child is equal to the array
container element name then all relevant children will be
serialized as the values of a JSON array.
.PP
If the element to serialize is a value of a JSON array
and the node name of this element isn't equal to the array
container node name that element will be seen as a container
node for a JSON object and all element node children will be
serialized as the members of that array while ignoring any
text node children. If the element to serialize is a value of
a JSON array and the node name of this element is equal to
the array container node name, all relevant children will be
serialized as JSON array.
.PP
If the \fI-channel\fR option is given the serialization
isn't returned as string but send directly to the channel,
given as argument to the option.
.PP
If the \fI-indent\fR option is given and the argument
given to this option isn't "none" then the returned JSON
string is "pretty-printed". The numeric argument to this
option defines the number of spaces for any indentation
level. The default is to not emit any additional
white space.
.RE
.TP
\&\fB\fBpublicId\fP \fI?publicId?\fB
\&\fRReturns the public identifier of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the public identifier of the document is set to this
value.
.TP
\&\fB\fBsystemId\fP \fI?systemId?\fB
\&\fRReturns the system identifier of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the system identifier of the document is set to this
value.
.TP
\&\fB\fBinternalSubset\fP \fI?internalSubset?\fB
\&\fRReturns the internal subset of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the internal subset of the document is set to this
value. Note that none of the parsing methods preserve the internal subset
of a document; a freshly parsed document will always have an empty internal
subset. Also note, that the method doesn't do any syntactical check on a
given internal subset.
.TP
\&\fB\fBcdataSectionElements\fP \fI(?URI:?localname|*) ?<boolean>?\fB
\&\fRThis method allows one to control for which element nodes
the text node children will be serialized as CDATA sections (this affects only
serialization with the asXML method, no text node is altered in any
way by this method). IF the method is called with an element name as
first argument and a boolean with value true as second argument, every
text node child of every element node in the document with the same
name as the first argument will be serialized as CDATA section. If the
second argument is a boolean with value false, all text nodes of all
elements with the same name as the first argument will be serialized
as usual. Namespaced element names have to be given in the form
namespace_URI:localname, not in the otherwise usual prefix:localname
form. With two arguments called, the method returns the used boolean
value. If the method is called with only an element name, it will
return a boolean value, indicating that the text node children of all
elements with that name in the document will be serialized as CDATA
section elements (return value 1) or not (return value 0). If the
method is called with only one argument and that argument is an
asterisk ('*'), then the method returns an unordered list of all
element names of the document, for which the text node children will be
serialized as CDATA section nodes.
.TP
\&\fB\fBselectNodesNamespaces\fP \fB?prefixUriList?\fP
\&\fRThis method allows one to control a document global prefix
to namespace URI mapping, which will be used for selectNodes
method calls (on document as well as on all nodes, which
belongs to the document) if it is not overwritten by using
the -namespaces option of the selectNodes method. Any
namespace prefix within an xpath expression will be first
resolved against this list. If the list binds the same prefix
to different namespaces, then the first binding will win. If a
prefix could not resolved against the document global prefix /
namespaces list, then the namespace definitions in scope of
the context node will be used to resolve the prefix, as usual.
If the optional argument \fIprefixUriList\fR is given, then
the global prefix / namespace list is set to this list and
returns it. Without the optional argument the method returns
the current list. The default is the empty list.
.TP
\&\fB\fBxslt\fP \fB?-parameters parameterList?\fP \fB?-ignoreUndeclaredParameters?\fP \fB?-maxApplyDepth int?\fP \fB?-xsltmessagecmd script?\fP \fIstylesheet\fB \fI?outputVar?\fB
\&\fRApplies an XSLT transformation on the whole document of the node
object using the XSLT \fIstylesheet\fR (given as domDoc). Returns a document
object containing the result document of the transformation and stores that
document object in the optional \fIoutputVar\fR, if that was given.
.RS
.PP
The optional \fI-parameters\fR option sets top level
<xsl:param> to string values. The \fIparameterList\fR has to be a tcl
list consisting of parameter name and value pairs.
.PP
If the option \fI-ignoreUndeclaredParameters\fR is given, then parameter
names in the \fIparameterList\fR given to the \fI-parameters\fR options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised if the user tries to set a
top-level parameter that is not declared in the stylesheet.
.PP
The option \fI-maxApplyDepth\fR expects a positiv integer as
argument. By default, the xslt engine allows xslt templates to nest up
to 3000 levels (and raises error if they nest deeper). This limit can
be set by the \fI-maxApplyDepth\fR option.
.PP
The \fI-xsltmessagecmd\fR option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes". If the
called script returns anything else then TCL_OK then the xslt
transformation will be aborted, returning error. If the called script
returns -code break, the error message is empty, otherwise the result
code is reported. In case of terminated transformation, the outputVar,
if given, is set to the empty string.
.RE
.TP
\&\fB\fBtoXSLTcmd\fP ?\fIobjVar\fB?
\&\fRIf the DOM tree represents a valid XSLT stylesheet, this method
transforms the DOM tree into an xslt command, otherwise it returns error. The
created xsltCmd is returned and stored in the \fIobjVar\fR, if a var name was
given. A successful transformation of the DOM tree to an xsltCmd removes the
domDoc cmd and all nodeCmds of the document.
.RS
.PP
The syntax of the created xsltCmd is:

 
................................................................................

\&\fBxsltCmd\fP \fBmethod\fP \fB?arg ...?\fP

.CE
.PP
The valid methods are:
.TP
\&\fB\fBtransform\fP \fB?-parameters parameterList?\fP \fB?-ignoreUndeclaredParameters?\fP \fB?-maxApplyDepth int?\fP  \fB?-xsltmessagecmd script?\fP \fIdomDoc\fB \fI?outputVar?\fB
\&\fRApplies XSLT transformation on the document
\&\fIdomDoc\fR. Returns a document object containing the
result document of that transformation and stores it in the optional
\&\fIoutputVar\fR.
.RS
.PP
The optional \fI-parameters\fR option sets top level
<xsl:param> to string values. The \fIparameterList\fR has to be a tcl
list consisting of parameter name and value pairs.
.PP
If the option \fI-ignoreUndeclaredParameters\fR is given, then parameter
names in the \fIparameterList\fR given to the \fI-parameters\fR options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised if the user tries to set a
top-level parameter, which is not declared in the stylesheet.
.PP
The option \fI-maxApplyDepth\fR expects a positiv integer as
argument. By default, the xslt engine allows xslt templates to nest up
to 3000 levels (and raises error if they nest deeper). This limit can
be set by the \fI-maxApplyDepth\fR option.
.PP
The \fI-xsltmessagecmd\fR option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes".
................................................................................
.PP
If the first argument to an xsltCmd is a domDoc or starts with a "-",
then the command is processed in the same way as
\&\fI<xsltCmd> transform\fR.
.RE
.TP
\&\fB\fBnormalize\fP \fI?-forXPath?\fB
\&\fRPuts all text nodes in the document
into a "normal" form where only structure (e.g., elements,
comments, processing instructions and CDATA
sections) separates text nodes, i.e., there
are neither adjacent text nodes nor empty text nodes. If the option
\&\fI-forXPath\fR is given, all CDATA sections in the nodes are
converted to text nodes, as a first step before the
normalization.
.TP
\&\fB\fBnodeType\fP
\&\fRReturns the node type of the document node. This is always
DOCUMENT_NODE.
.TP
\&\fB\fBgetElementById\fP \fIid\fB
\&\fRReturns the node having a id attribute with value
\&\fIid\fR or the empty string, if no node has an id attribute with that value.
.TP
\&\fB\fBfirstChild\fP \fB?objVar?\fP
\&\fRReturns the first top level node of the document.
.TP
\&\fB\fBlastChild\fP \fB?objVar?\fP
\&\fRReturns the last top level node of the document.
.TP
................................................................................
\&\fRReturns a list of the top level nodes of the document.
.TP
\&\fB\fBownerDocument\fP \fB?domObjVar?\fP
\&\fRReturns the document itself.
.TP
\&\fB\fBinsertBefore\fP \fInewChild\fB  \fIrefChild\fB
\&\fRInsert \fInewChild\fR before the \fIrefChild\fR into the list of
top level nodes of the document. If \fIrefChild\fR is the empty string, inserts
\&\fInewChild\fR at the end of the top level nodes.
.TP
\&\fB\fBreplaceChild\fP \fInewChild\fB  \fIoldChild\fB
\&\fRReplaces \fIoldChild\fR with \fInewChild\fR in the list of
children of that node. The \fIoldChild\fR node will be part of the
document fragment list after this operation.
.TP
\&\fB\fBappendFromList\fP \fIlist\fB
\&\fRParses \fIlist\fR , creates an according DOM subtree and
appends this subtree at the end of the current list of top level nodes of the document.
.TP
................................................................................
The argument \fIxpathQuery\fR has to be a valid XPath
expression. However, there is one exception to that rule. Tcl variable
names can appear in the XPath statement at any position where it is
legal according to the rules of the XPath syntax to put an XPath
variable. The value of the variable is substituted for the variable
name. Ignoring the syntax rules of XPath the Tcl variable name may be
any legal Tcl var name: local variables, global variables, array
entries and so on.  The value will always be seen as string literal by
the xpath engine. Cast the value explicitly with the according xpath
functions (number(), boolean()) to another data type, if needed.
.PP
The option \fI-namespaces\fR expects a tcl list with prefix /
namespace pairs as argument. If this option is not given, then any
namespace prefix within the xpath expression will be first resolved
against the list of prefix / namespace pairs set with the
selectNodesNamespaces method for the document the node belongs to. If
this fails, then the namespace definitions in scope of the context
node will be used to resolve the prefix. If this option is given, any
namespace prefix within the xpath expression will be first resolved
against that given list (and ignoring the document global prefix /
namespace list). If the list binds the same prefix to different
namespaces, then the first binding will win.  If this fails, then the
namespace definitions in scope of the context node will be used to
resolve the prefix, as usual.
.PP
If the \fI-cache\fR option is used with a true value, then the
\&\fIxpathQuery\fR will be looked up in a document specific cache. If
the query is found, then the stored pre-compiled query will be used.
If the query isn't found, it will be compiled and stored in the cache,
for use in further calls. Please notice, that the \fIxpathQuery\fR as
given as string is used as key for the cache. This means that equal
XPath expressions, which differ only in white space, are treated as
different cache entries. Special care is needed if the XPath
expression includes namespace prefixes or references to tcl variables.
Both namespace prefixes and tcl variable references will be resolved
according to the XML prefix namespace mappings and tcl variable values
at expression compilation time. If the same XPath expression is used
later on in a context with other XML prefix namespace mappings or
values of the used tcl variables, make sure to first remove the
compiled expression from the cache with the help of the
\&\fBdeleteXPathCache\fP method, to force a recompilation.
Without using the \fI-cache\fR option such consideration is never
needed.
.PP
Examples:

          
.CS
set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
foreach paragraph $paragraphNodes {
................................................................................

set doc [dom parse {<doc xmlns="http://www.defaultnamespace.org"><child/></doc>}]
set root [$doc documentElement]
set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]
.CE
.RE
.TP
\&\fB\fBbaseURI\fP \fI?URI?\fB
\&\fRReturns the present baseURI of the document. If the optional
argument URI is given, sets the base URI of the document to the given URI.
.TP
\&\fB\fBappendFromScript\fP \fItclScript\fB
\&\fRAppends the nodes created by the \fItclScript\fR by
Tcl functions, which have been built using \fIdom createNodeCmd\fR, at the end
of the current list of top level nodes of the document.
................................................................................
\&\fRIf called without the optional argument, all cached XPath
expressions of the document are freed. If called with the optional
argument \fIxpathQuery\fR, this single XPath query will be removed
from the cache, if it is there. The method always returns an
empty string.
.PP
Otherwise, if an unknown method name is given, the command with the
same name as the given method within the namespace \fB::dom::domDoc\fR is
tried to be executed. This allows quick method additions on Tcl level.
.PP
Newly created nodes are appended to a hidden fragment list. If they
are not moved into the tree they are automatically deleted as soon as the whole
document gets deleted.
.SH "SEE ALSO"
dom, domNode
.SH KEYWORDS
DOM node creation, document element

Changes to doc/domDoc.xml.

9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
..
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
...
106
107
108
109
110
111
112
113
114
115


116
117
118


119
120

121
122
123













124
125

126















127
128
129
130
131
132
133

134
135
136
137
138
139
140
141

142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
157












































































158
159
160
161
162
163
164
...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
237
238
239
240
241
242
243
244





245
246
247
248
249
250
251





252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
...
269
270
271
272
273
274
275

276
277
278
279
280
281
282
...
283
284
285
286
287
288
289
290
291





292
293
294
295
296
297
298
...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
...
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
...
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
...
412
413
414
415
416
417
418
419


420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450


451
452
453
454
455
456
457
...
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
...
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
  Copyright (c) 2002-2005 Rolf Ade (rolf@pointsman.de)

  See the file "LICENSE" for information on usage and redistribution
  of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  
  -->
  <synopsis>
    <syntax><cmd>domDocObjCmd</cmd> <m>method</m> ?<m>arg arg ...</m>?</syntax>

  </synopsis>

  <section>
    <title>DESCRIPTION </title>

    <p>This command manipulates one particular instance of a document
object. <m>method</m> indicates a specific method of the document class. These
................................................................................
      </commanddef>

        <commanddef>
          <command><method>createElement</method> <m>tagName</m> ?<m>objVar</m>?</command>
          <desc>Creates (allocates) a new element node with node name
<m>tagName</m>, append it to the hidden fragment list in the document
object and returns the node object.  If <m>objVar</m> is given the new
node object store in this variable.</desc>
        </commanddef>

        <commanddef>
          <command><method>createElementNS</method> <m>url</m> <m>tagName</m> ?<m>objVar</m>?</command>
          <desc>Creates (allocates) a new element node within a namespace
having <m>uri</m> as the URI and node name <m>tagName</m>, which
could include the namespace prefix, append it to the hidden fragment list in
the document object and returns the node object.  If <m>objVar</m> is
given the new node object store in this variable.</desc>
        </commanddef>

        <commanddef>
          <command><method>createTextNode</method> <m>text</m> ?<m>objVar</m>?</command>
          <desc>Creates (allocates) a new text node with node value
<m>text</m>, appends it to the hidden fragment list in the document
object and returns the node object.  If <m>objVar</m> is given, the new
................................................................................
        <commanddef>
          <command><method>getDefaultOutputMethod</method></command>
          <desc>Returns the default output method of the document. This is
usually a result of a XSLT transformation.</desc>
        </commanddef>

      <commanddef>
        <command><method>asXML</method> <option>?-indent none/1..8?</option> <option>?-channel channelId?</option> <option>?-escapeNonASCII?</option> <option>?-doctypeDeclaration &lt;boolean&gt;?</option> <option>?-escapeAllQuot?</option></command>
        <desc>Returns the DOM tree as an (optional indented) XML
string or sends the output directly to the given channelId. If the


option <m>-escapeNonASCII</m> is given, every non 7 bit ASCII
character in attribute values or element PCDATA content will be
escaped as character reference in decimal representation. The flag


<m>-doctypeDeclaration</m> determines, whether there will be a DOCTYPE
declaration emitted before the first node of the document. The default

is, to do not. The DOCTYPE name will always be the element name of the
document element. An external entity declaration of the external
subset is only emitted, if the document has a system identifier. If













the option <m>-escapeAllQuot</m> is given, quotation marks will be
escaped with &amp;quot; even in text content of elements.</desc>

















      </commanddef>

      <commanddef>
        <command><method>asHTML</method> <option>?-channel
channelId?</option> <option>?-escapeNonASCII?</option> <option>?-htmlEntities?</option> <option>?-doctypeDeclaration &lt;boolean&gt;?</option></command> 
        <desc>Returns the DOM tree serialized acording to HTML rules (HTML
elements are recognized regardless of case, without end tags for emtpy HTML

elements etc.), as string or sends the output directly to the given
channelId. If the option <m>-escapeNonASCII</m> is given, every non 7 bit ASCII
character in attribute values or element PCDATA content will be escaped as
character reference in decimal representation. If the option
<m>-htmlEntities</m> is given, a character is outputed using a HTML 4.01
character entity reference, if one is defined for it. The flag
<m>-doctypeDeclaration</m> determines, whether there will be a DOCTYPE
declaration emitted before the first node of the document. The default is, to

do not. The DOCTYPE name will always be the element name of the document
element without case normalization. An external entity declaration of the
external subset is only emitted, if the document has a system identifier. The
doctype declaration will be written from the avaliable informations, without

check, if this is a known (w3c) HTML version information or if the document
confirms to the given HTML version.</desc>
      </commanddef>

      <commanddef>
        <command><method>asText</method></command>
          <desc>The asText method outputs the result tree by outputting
the string-value of every text node in the result tree in document
order without any escaping. In effect, this is what the xslt output method
"text" (XSLT 1.0 recommendation, section 16.3) does.</desc>
      </commanddef>













































































      <commanddef>
        <command><method>publicId</method> <m>?publicId?</m></command>
        <desc>Returns the public identifier of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the public identifier of the document is set to this
value.</desc>
      </commanddef>
................................................................................
        <desc>Returns the system identifier of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the system identifier of the document is set to this
value.</desc>
      </commanddef>

      <commanddef>
        <command><method>internalSubset <m>?internalSubset?</m></method></command>
        <desc>Returns the internal subset of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the internal subset of the document is set to this
value. Note, that none of the parsing methods preserve the internal subset
of a document; a freshly parsed document will always have an empty internal
subset. Also note, that the method doesen't do any syntactical check on a
given internal subset.</desc>
      </commanddef>

      <commanddef>
        <command><method>cdataSectionElements</method> <m>(?URI:?localname|*) ?&lt;boolean&gt;?</m></command>
        <desc>This method allows to control, for which element nodes
the text node childs will be serialized as CDATA sections (this affects only
serialization with the asXML method, no text node is altered in any
way by this method). IF the method is called with an element name as
first argument and a boolean with value true as second argument, every
text node child of every element node in the document with the same
name as the first argument will be serialized as CDATA section. If the
second argument is a boolean with value false, all text nodes of all
elements with the same name as the first argument will be serialized
as usual. Namespaced element names have to given in the form
namespace_URI:localname, not in the otherwise usual prefix:localname
form. With two arguments called, the method returns the used boolean
value. If the method is called with only an element name, it will
return a boolean value, indicating, if the text nodes childs of all
elements with that name in the document will be serialized as CDATA
section elements (return value 1) or not (return value 0). If the
method is called with only one argument and that argument is an
asterisk ('*'), then the method returns an unordered list of all
element names of the document, for which the text node childs will be
serialized as CDATA section nodes.</desc>
      </commanddef>

      <commanddef>
        <command><method>selectNodesNamespaces</method> <option>?prefixUriList?</option></command>
        <desc>This method allows to control a document global prefix
to namespace URI mapping, which will be used for selectNodes method
calls (on document as well as on all nodes, which belongs to the
document), if it is not overwritten by using the -namespaces option of

the selectNodes method. Any namespace prefix within an xpath
expression will be first resolved against this list. If the list bind
the same prefix to different namespaces, then the first binding will
win. If a prefix could not resolved against the document global prefix
/ namespaces list, then the namespace definitions in scope of the
context node will be used to resolve the prefix, as usual. If the
optional argument <m>prefixUriList</m> is given, then the global prefix /
namespace list is set to this list and returns it. Without
the optional argument the method returns the current list. The
default is the empty list.</desc>
      </commanddef>

      <commanddef>
        <command><method>xslt</method> <option>?-parameters
parameterList?</option> <option>?-ignoreUndeclaredParameters?</option>

<option>?-xsltmessagecmd script?</option> <m>stylesheet</m> <m>?outputVar?</m></command>
        <desc>Applies an XSLT transformation on the whole document of the node
object using the XSLT <m>stylesheet</m> (given as domDoc). Returns a document
object containing the result document of the transformation and stores that
document object in the optional <m>outputVar</m>, if that was given.

<p>The optional <m>-parameters</m> option sets top level
&lt;xsl:param&gt; to string values. The <m>parameterList</m> has to be a tcl
list consisting of parameter name and value pairs.</p>

<p>If the option <m>-ignoreUndeclaredParameters</m> is given, then parameter
names in the <m>parameterList</m> given to the <m>-parameters</m> options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised, if the user tries to set a
top-level parameter, which is not declared in the stylesheet.</p>






<p>The <m>-xsltmessagecmd</m> option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes".</p>





</desc>
      </commanddef>

      <commanddef>
        <command><method>toXSLTcmd</method> ?<m>objVar</m>?</command>
     
        <desc>If the DOM tree represents a valid XSLT stylesheet, this method
transforms the DOM tree into an xslt command, otherwise it returns error. The
created xsltCmd is returnd and stored in the <m>objVar</m>, if a var name was
given. A successful transformation of the DOM tree to an xsltCmd removes the
domDoc cmd and all nodeCmds of the document. 

<p>The syntax of the created xsltCmd is:</p>
 
<syntax>
<cmd>xsltCmd</cmd> <option>method</option> <option>?arg ...?</option>
................................................................................

<p>The valid methods are:</p>

<commandlist>
  <commanddef>
    <command><method>transform</method> <option>?-parameters
parameterList?</option> <option>?-ignoreUndeclaredParameters?</option>

<option>?-xsltmessagecmd script?</option> <m>domDoc</m> <m>?outputVar?</m></command>          

        <desc>Applies XSLT transformation on the document
<m>domDoc</m>. Returns a document object containing the
result document of that transformation and stores it in the optional
<m>outputVar</m>. 

................................................................................
<p>The optional <m>-parameters</m> option sets top level
&lt;xsl:param&gt; to string values. The <m>parameterList</m> has to be a tcl
list consisting of parameter name and value pairs.</p>

<p>If the option <m>-ignoreUndeclaredParameters</m> is given, then parameter
names in the <m>parameterList</m> given to the <m>-parameters</m> options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised, if the user tries to set a
top-level parameter, which is not declared in the stylesheet.</p>






<p>The <m>-xsltmessagecmd</m> option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes".</p>
................................................................................
then the command is processed in the same way as 
<m>&lt;xsltCmd&gt; transform</m>.</p>
 </desc>
      </commanddef>

      <commanddef>
        <command><method>normalize</method> <m>?-forXPath?</m></command>
        <desc>Puts all Text nodes in the document
into a "normal" form where only structure (e.g., elements,
comments, processing instructions and CDATA
sections) separates Text nodes, i.e., there
are neither adjacent Text nodes nor empty Text nodes. If the option
<m>-forXPath</m> is given, all CDATA sections in the nodes are
converted to text nodes, as a first step before the
normalization. </desc>
      </commanddef>

      <commanddef>
        <command><method>nodeType</method></command>
................................................................................
        <desc>Returns the node type of the document node. This is always
DOCUMENT_NODE.</desc>
      </commanddef>

      <commanddef>
        <command><method>getElementById</method> <m>id</m></command>
        <desc>Returns the node having a id attribute with value
<m>id</m> or the emtpy string, if no node has an id attribute with that value.</desc>
      </commanddef>

      <commanddef>
        <command><method>firstChild</method> <variable>?objVar?</variable></command>
        <desc>Returns the first top level node of the document.</desc>
      </commanddef>

................................................................................
        <command><method>ownerDocument</method> <variable>?domObjVar?</variable></command>
        <desc>Returns the document itself.</desc>
      </commanddef>

      <commanddef>
        <command><method>insertBefore</method> <m>newChild</m>  <m>refChild</m></command>
        <desc>Insert <m>newChild</m> before the <m>refChild</m> into the list of
top level nodes of the document. If <m>refChild</m> is the empty string, insert
<m>newChild</m> at the end of the top level nodes.</desc>
      </commanddef>

      <commanddef>
        <command><method>replaceChild</method> <m>newChild</m>  <m>oldChild</m></command>
        <desc>Replace <m>oldChild</m> with <m>newChild</m> in the list of
children of that node. The <m>oldChild</m> node will be part of the
document fragment list after this operation.</desc>
      </commanddef>

      <commanddef>
        <command><method>appendFromList</method> <m>list</m></command>
        <desc>Parses <m>list</m> , creates an according DOM subtree and
................................................................................
<p>The argument <m>xpathQuery</m> has to be a valid XPath
expression. However, there is one exception to that rule. Tcl variable
names can appear in the XPath statement at any position where it is
legal according to the rules of the XPath syntax to put an XPath
variable. The value of the variable is substituted for the variable
name. Ignoring the syntax rules of XPath the Tcl variable name may be
any legal Tcl var name: local variables, global variables, array
entries and so on.</p>



<p>The option <m>-namespaces</m> expects a tcl list with prefix /
namespace pairs as argument. If this option is not given, then any
namespace prefix within the xpath expression will be first resolved
against the list of prefix / namespace pairs set with the
selectNodesNamespaces method for the document, the node belongs to. If
this fails, then the namespace definitions in scope of the context
node will be used to resolve the prefix. If this option is given, any
namespace prefix within the xpath expression will be first resolved
against that given list (and ignoring the document global prefix /
namespace list). If the list bind the same prefix to different
namespaces, then the first binding will win.  If this fails, then the
namespace definitions in scope of the context node will be used to
resolve the prefix, as usual.</p>

<p>If the <m>-cache</m> option is used with a true value, then the
<m>xpathQuery</m> will be looked up in a document specific cache. If the query
is found, then the stored pre-compiled query will be used. If the
query isn't found, it will be pre-compiled and stored in the cache,
for use in further calls. Please notice, that the <m>xpathQuery</m> as given as
string is used as key for the cache. This means, that equal XPath
expressions, which differ only in white space are treated as
different cache entries. Special care is needed, if the XPath
expression includes namespace prefixes. During pre-compilation, the
prefixes will be resolved first to the prefix / namespace pairs of
the <m>-namespaces</m> option, if given, and to the namespaces
in scope of the context node at pre-compilation time. If the XPath
is found in the cache, neither the <m>-namespaces</m> option nor
the namespaces in scope of the context node will be taken in
account but the already resolved (stored) namespaces will be used
for the query.</p>



<p>Examples:</p>
          <example>set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
foreach paragraph $paragraphNodes {
    lappend  values [$paragraph selectNodes attribute::type]
}

................................................................................
set root [$doc documentElement]
set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]</example>

          </desc>
      </commanddef>

      <commanddef>
        <command><method>baseURI <m>?URI?</m></method></command>
        <desc>Returns the present baseURI of the document. If the optional 
argument URI is given, sets the base URI of the document to the given URI.</desc>
      </commanddef>

      <commanddef>
        <command><method>appendFromScript</method> <m>tclScript</m></command>
        <desc>Appends the nodes created by the <m>tclScript</m> by
................................................................................
from the cache, if it is there. The method always returns an
empty string.</desc>
      </commanddef>

  </commandlist>

      <p>Otherwise, if an unknown method name is given, the command with the
same name as the given metho within the namespace <samp>::dom::domDoc</samp> is
tried to be executed. This allows quick method additions on Tcl level.</p>

      <p>Newly created nodes are appended to a hidden fragment list. If they
are not moved into the tree they are automaticaly deleted, when the whole
document gets deleted.</p>

    </section>

    <seealso>
      <ref>dom</ref>
      <ref>domNode</ref>







|
>







 







|








|







 







|
|
|
>
>
|
|
|
>
>
|
|
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
|
>
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|




|
|
|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|



|

|





|
|







|



|




|





|
|
|
|
>
|
|
|
|
|
|
|
|
|
|





>













|
|
>
>
>
>
>






|
>
>
>
>
>








|







 







>







 







|

>
>
>
>
>







 







|


|
|







 







|







 







|





|







 







|
>
>





|




|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>







 







|







 







|



|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
...
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
...
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
...
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
...
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
...
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
...
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
...
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
  Copyright (c) 2002-2005 Rolf Ade (rolf@pointsman.de)

  See the file "LICENSE" for information on usage and redistribution
  of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  
  -->
  <synopsis>
    <syntax>domDocObjCmd <m>method</m> ?<m>arg arg ...</m>?</syntax>
    <syntax>domDoc <m>docToken</m> <m>method</m> ?<m>arg arg ...</m>?</syntax>
  </synopsis>

  <section>
    <title>DESCRIPTION </title>

    <p>This command manipulates one particular instance of a document
object. <m>method</m> indicates a specific method of the document class. These
................................................................................
      </commanddef>

        <commanddef>
          <command><method>createElement</method> <m>tagName</m> ?<m>objVar</m>?</command>
          <desc>Creates (allocates) a new element node with node name
<m>tagName</m>, append it to the hidden fragment list in the document
object and returns the node object.  If <m>objVar</m> is given the new
node object is stored in this variable.</desc>
        </commanddef>

        <commanddef>
          <command><method>createElementNS</method> <m>url</m> <m>tagName</m> ?<m>objVar</m>?</command>
          <desc>Creates (allocates) a new element node within a namespace
having <m>uri</m> as the URI and node name <m>tagName</m>, which
could include the namespace prefix, append it to the hidden fragment list in
the document object and returns the node object.  If <m>objVar</m> is
given the new node object is stored in this variable.</desc>
        </commanddef>

        <commanddef>
          <command><method>createTextNode</method> <m>text</m> ?<m>objVar</m>?</command>
          <desc>Creates (allocates) a new text node with node value
<m>text</m>, appends it to the hidden fragment list in the document
object and returns the node object.  If <m>objVar</m> is given, the new
................................................................................
        <commanddef>
          <command><method>getDefaultOutputMethod</method></command>
          <desc>Returns the default output method of the document. This is
usually a result of a XSLT transformation.</desc>
        </commanddef>

      <commanddef>
        <command><method>asXML</method> <option>?-indent none/1..8?</option> <option>?-channel channelId?</option> <option>?-escapeNonASCII?</option> <option>?-doctypeDeclaration &lt;boolean&gt;?</option> <option>-xmlDeclaration &lt;boolean&gt;?</option> <option>-encString &lt;string&gt;</option> <option>?-escapeAllQuot?</option> <option>?-indentAttrs?</option> <option>?-nogtescape?</option> <option>?-noEmptyElementTag?</option></command>
        <desc><p>Returns the DOM tree as an (optional indented) XML
        string or sends the output directly to the given
        channelId.</p>

        <p>If the option <m>-escapeNonASCII</m> is given,
        every non 7 bit ASCII character in attribute values or element
        PCDATA content will be escaped as character reference in
        decimal representation.</p>

        <p>The flag <m>-doctypeDeclaration</m> determines whether
        there will be a DOCTYPE declaration emitted before the first
        node of the document. The default is not to emit it. The
        DOCTYPE name will always be the element name of the document
        element. An external entity declaration of the external subset
        is only emitted if the document has a system identifier.</p>

        <p>The flag <m>-xmlDeclaration</m> determines whether there
        will be an XML Declaration and a newline emitted before
        anything else. The default is not to emit one. If this flag is
        given with a true argument then</p>

        <p><m>-encString</m> sets the encoding value in the XML
        Declaration. Otherwise this option is ignored. Please note
        that this option just enhances the string representation of the
        generated XML Declaration with an encoding information string,
        nothing more. It's up to the user to handle encoding in case
        of writing to a channel or reparsing.</p>
            
        <p>If the option <m>-escapeAllQuot</m> is given,
        quotation marks will be escaped with &amp;quot; even in text
        content of elements.</p>

        <p>If the option <m>-indentAttrs</m> is
        given, then attributes will each be separated with newlines
        and indented to the same level as the parent node plus the
        value given as argument to <m>-indentAttrs</m> (0..8).</p>

        <p>If the option <m>-nogtescape</m> is given then the
        character '>' won't get escaped in attribute values and text
        content of elements. The default is to escape this
        character.</p>

        <p>If the option <m>-noEmptyElementTag</m> is given then no
        empty tag syntax will be used. Instead, if an element has
        empty content it will be serialized with an element start tag
        and an immediately following element end tag.</p></desc>

      </commanddef>

      <commanddef>
        <command><method>asHTML</method> <option>?-channel
channelId?</option> <option>?-escapeNonASCII?</option> <option>?-htmlEntities?</option> <option>?-doctypeDeclaration &lt;boolean&gt;?</option></command> 
        <desc>Returns the DOM tree serialized according to HTML rules
        (HTML elements are recognized regardless of case, without end
        tags for empty HTML elements etc.) as string or sends the
        output directly to the given channelId. If the option
        <m>-escapeNonASCII</m> is given, every non 7 bit ASCII
        character in attribute values or element PCDATA content will
        be escaped as character reference in decimal representation.
        If the option <m>-htmlEntities</m> is given, a character is
        written using its HTML 4.01 character entity reference, if it
        has one. If the flag <m>-doctypeDeclaration</m> is given there
        will be a DOCTYPE declaration emitted before the first node of
        the document. The default is, to do not. The DOCTYPE name will
        always be the element name of the document element without
        case normalization. An external entity declaration of the
        external subset is only emitted, if the document has a system
        identifier. The doctype declaration will be written from the
        available information, without check, if this is a known
        (w3c) HTML version information or if the document confirms to
        the given HTML version.</desc>
      </commanddef>

      <commanddef>
        <command><method>asText</method></command>
          <desc>The asText method returns the tree by serializing the
          string-value of every text node in document order without
          any escaping. In effect, this is what the xslt output method
          "text" (XSLT 1.0 recommendation, section 16.3) does.</desc>
      </commanddef>

      <commanddef>
        <command><method>asJSON</method> <option>?-indent none/0..8?</option> <option>?-channel channelId?</option></command>
          <desc><p>The asJSON method serializes the tree into a valid
          JSON data string. In general, this may be a lossy
          serialization. For this serialization all comment, character
          data sections and processing instruction nodes, all
          attributes and all XML namespaces are ignored. Only element
          and text nodes may be reflected in the generated JSON
          serialization. Appropriate JSON data type information of a
          node will be respected.</p>

          <p>If an element node has the JSON type OBJECT, then every
          element node child of this element will be serialized as
          member of that object, with the node name of the child as
          the member name and the relevant children of that child as
          the value. Every other child nodes will be ignored.</p>

          <p>If an element node has the JSON type ARRAY, then the text
          and element node children of that element node are serialized
          as the consecutive values of the array. Element node children
          of an ARRAY element will be container nodes for nested ARRAY
          or OBJECT values.</p>

          <p>Text nodes with the JSON types TRUE, FALSE or NULL will
          be serialized to the corresponding JSON token without
          looking at the value of the text node. A text node without
          JSON type will always be serialized as a JSON string token.
          A text node with JSON type NUMBER will be serialized as JSON
          number token if the text node value is in fact a valid JSON
          number and as a JSON string if not.</p>

          <p>If an element node doesn't has a JSON type then the
          serialization of its children is determined by the following
          rules:</p>

          <p>Only text and element node child are relevant. If the
          element node to serialize is the member of a JSON object and
          there is no relevant child node the value of that member
          will be an empty JSON string. If the only relevant child
          node of this element node is a text node then the JSON
          value of that text node will be the value of the object
          member. If the element has more than one relevant child
          nodes and the first one is a text node then the relevant
          children will be serialized as JSON array. If the only
          relevant child node is an element node or the first relevant
          child is an element node and the node name of that only or
          first relevant child isn't equal to the array container node
          name all element node children will be serialized as the
          members of a JSON object (while ignoring any intermixed text
          nodes). If the only or first relevant child is an element
          node and the node name of this child is equal to the array
          container element name then all relevant children will be
          serialized as the values of a JSON array.</p>

          <p>If the element to serialize is a value of a JSON array
          and the node name of this element isn't equal to the array
          container node name that element will be seen as a container
          node for a JSON object and all element node children will be
          serialized as the members of that array while ignoring any
          text node children. If the element to serialize is a value of
          a JSON array and the node name of this element is equal to
          the array container node name, all relevant children will be
          serialized as JSON array.</p>

          <p>If the <m>-channel</m> option is given the serialization
          isn't returned as string but send directly to the channel,
          given as argument to the option.</p>

          <p>If the <m>-indent</m> option is given and the argument
          given to this option isn't "none" then the returned JSON
          string is "pretty-printed". The numeric argument to this
          option defines the number of spaces for any indentation
          level. The default is to not emit any additional
          white space.</p></desc>
      </commanddef>
      
      <commanddef>
        <command><method>publicId</method> <m>?publicId?</m></command>
        <desc>Returns the public identifier of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the public identifier of the document is set to this
value.</desc>
      </commanddef>
................................................................................
        <desc>Returns the system identifier of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the system identifier of the document is set to this
value.</desc>
      </commanddef>

      <commanddef>
        <command><method>internalSubset</method> <m>?internalSubset?</m></command>
        <desc>Returns the internal subset of the doctype declaration of the
document, if there is one, otherwise the empty string. If there is a value
given to the method, the internal subset of the document is set to this
value. Note that none of the parsing methods preserve the internal subset
of a document; a freshly parsed document will always have an empty internal
subset. Also note, that the method doesn't do any syntactical check on a
given internal subset.</desc>
      </commanddef>

      <commanddef>
        <command><method>cdataSectionElements</method> <m>(?URI:?localname|*) ?&lt;boolean&gt;?</m></command>
        <desc>This method allows one to control for which element nodes
the text node children will be serialized as CDATA sections (this affects only
serialization with the asXML method, no text node is altered in any
way by this method). IF the method is called with an element name as
first argument and a boolean with value true as second argument, every
text node child of every element node in the document with the same
name as the first argument will be serialized as CDATA section. If the
second argument is a boolean with value false, all text nodes of all
elements with the same name as the first argument will be serialized
as usual. Namespaced element names have to be given in the form
namespace_URI:localname, not in the otherwise usual prefix:localname
form. With two arguments called, the method returns the used boolean
value. If the method is called with only an element name, it will
return a boolean value, indicating that the text node children of all
elements with that name in the document will be serialized as CDATA
section elements (return value 1) or not (return value 0). If the
method is called with only one argument and that argument is an
asterisk ('*'), then the method returns an unordered list of all
element names of the document, for which the text node children will be
serialized as CDATA section nodes.</desc>
      </commanddef>

      <commanddef>
        <command><method>selectNodesNamespaces</method> <option>?prefixUriList?</option></command>
        <desc>This method allows one to control a document global prefix
        to namespace URI mapping, which will be used for selectNodes
        method calls (on document as well as on all nodes, which
        belongs to the document) if it is not overwritten by using
        the -namespaces option of the selectNodes method. Any
        namespace prefix within an xpath expression will be first
        resolved against this list. If the list binds the same prefix
        to different namespaces, then the first binding will win. If a
        prefix could not resolved against the document global prefix /
        namespaces list, then the namespace definitions in scope of
        the context node will be used to resolve the prefix, as usual.
        If the optional argument <m>prefixUriList</m> is given, then
        the global prefix / namespace list is set to this list and
        returns it. Without the optional argument the method returns
        the current list. The default is the empty list.</desc>
      </commanddef>

      <commanddef>
        <command><method>xslt</method> <option>?-parameters
parameterList?</option> <option>?-ignoreUndeclaredParameters?</option>
<option>?-maxApplyDepth int?</option>
<option>?-xsltmessagecmd script?</option> <m>stylesheet</m> <m>?outputVar?</m></command>
        <desc>Applies an XSLT transformation on the whole document of the node
object using the XSLT <m>stylesheet</m> (given as domDoc). Returns a document
object containing the result document of the transformation and stores that
document object in the optional <m>outputVar</m>, if that was given.

<p>The optional <m>-parameters</m> option sets top level
&lt;xsl:param&gt; to string values. The <m>parameterList</m> has to be a tcl
list consisting of parameter name and value pairs.</p>

<p>If the option <m>-ignoreUndeclaredParameters</m> is given, then parameter
names in the <m>parameterList</m> given to the <m>-parameters</m> options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised if the user tries to set a
top-level parameter that is not declared in the stylesheet.</p>

<p>The option <m>-maxApplyDepth</m> expects a positiv integer as
argument. By default, the xslt engine allows xslt templates to nest up
to 3000 levels (and raises error if they nest deeper). This limit can
be set by the <m>-maxApplyDepth</m> option.</p>

<p>The <m>-xsltmessagecmd</m> option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes". If the
called script returns anything else then TCL_OK then the xslt
transformation will be aborted, returning error. If the called script
returns -code break, the error message is empty, otherwise the result
code is reported. In case of terminated transformation, the outputVar,
if given, is set to the empty string.</p>
</desc>
      </commanddef>

      <commanddef>
        <command><method>toXSLTcmd</method> ?<m>objVar</m>?</command>
     
        <desc>If the DOM tree represents a valid XSLT stylesheet, this method
transforms the DOM tree into an xslt command, otherwise it returns error. The
created xsltCmd is returned and stored in the <m>objVar</m>, if a var name was
given. A successful transformation of the DOM tree to an xsltCmd removes the
domDoc cmd and all nodeCmds of the document. 

<p>The syntax of the created xsltCmd is:</p>
 
<syntax>
<cmd>xsltCmd</cmd> <option>method</option> <option>?arg ...?</option>
................................................................................

<p>The valid methods are:</p>

<commandlist>
  <commanddef>
    <command><method>transform</method> <option>?-parameters
parameterList?</option> <option>?-ignoreUndeclaredParameters?</option>
<option>?-maxApplyDepth int?</option> 
<option>?-xsltmessagecmd script?</option> <m>domDoc</m> <m>?outputVar?</m></command>          

        <desc>Applies XSLT transformation on the document
<m>domDoc</m>. Returns a document object containing the
result document of that transformation and stores it in the optional
<m>outputVar</m>. 

................................................................................
<p>The optional <m>-parameters</m> option sets top level
&lt;xsl:param&gt; to string values. The <m>parameterList</m> has to be a tcl
list consisting of parameter name and value pairs.</p>

<p>If the option <m>-ignoreUndeclaredParameters</m> is given, then parameter
names in the <m>parameterList</m> given to the <m>-parameters</m> options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised if the user tries to set a
top-level parameter, which is not declared in the stylesheet.</p>

<p>The option <m>-maxApplyDepth</m> expects a positiv integer as
argument. By default, the xslt engine allows xslt templates to nest up
to 3000 levels (and raises error if they nest deeper). This limit can
be set by the <m>-maxApplyDepth</m> option.</p>

<p>The <m>-xsltmessagecmd</m> option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes".</p>
................................................................................
then the command is processed in the same way as 
<m>&lt;xsltCmd&gt; transform</m>.</p>
 </desc>
      </commanddef>

      <commanddef>
        <command><method>normalize</method> <m>?-forXPath?</m></command>
        <desc>Puts all text nodes in the document
into a "normal" form where only structure (e.g., elements,
comments, processing instructions and CDATA
sections) separates text nodes, i.e., there
are neither adjacent text nodes nor empty text nodes. If the option
<m>-forXPath</m> is given, all CDATA sections in the nodes are
converted to text nodes, as a first step before the
normalization. </desc>
      </commanddef>

      <commanddef>
        <command><method>nodeType</method></command>
................................................................................
        <desc>Returns the node type of the document node. This is always
DOCUMENT_NODE.</desc>
      </commanddef>

      <commanddef>
        <command><method>getElementById</method> <m>id</m></command>
        <desc>Returns the node having a id attribute with value
<m>id</m> or the empty string, if no node has an id attribute with that value.</desc>
      </commanddef>

      <commanddef>
        <command><method>firstChild</method> <variable>?objVar?</variable></command>
        <desc>Returns the first top level node of the document.</desc>
      </commanddef>

................................................................................
        <command><method>ownerDocument</method> <variable>?domObjVar?</variable></command>
        <desc>Returns the document itself.</desc>
      </commanddef>

      <commanddef>
        <command><method>insertBefore</method> <m>newChild</m>  <m>refChild</m></command>
        <desc>Insert <m>newChild</m> before the <m>refChild</m> into the list of
top level nodes of the document. If <m>refChild</m> is the empty string, inserts
<m>newChild</m> at the end of the top level nodes.</desc>
      </commanddef>

      <commanddef>
        <command><method>replaceChild</method> <m>newChild</m>  <m>oldChild</m></command>
        <desc>Replaces <m>oldChild</m> with <m>newChild</m> in the list of
children of that node. The <m>oldChild</m> node will be part of the
document fragment list after this operation.</desc>
      </commanddef>

      <commanddef>
        <command><method>appendFromList</method> <m>list</m></command>
        <desc>Parses <m>list</m> , creates an according DOM subtree and
................................................................................
<p>The argument <m>xpathQuery</m> has to be a valid XPath
expression. However, there is one exception to that rule. Tcl variable
names can appear in the XPath statement at any position where it is
legal according to the rules of the XPath syntax to put an XPath
variable. The value of the variable is substituted for the variable
name. Ignoring the syntax rules of XPath the Tcl variable name may be
any legal Tcl var name: local variables, global variables, array
entries and so on.  The value will always be seen as string literal by
the xpath engine. Cast the value explicitly with the according xpath
functions (number(), boolean()) to another data type, if needed.</p>

<p>The option <m>-namespaces</m> expects a tcl list with prefix /
namespace pairs as argument. If this option is not given, then any
namespace prefix within the xpath expression will be first resolved
against the list of prefix / namespace pairs set with the
selectNodesNamespaces method for the document the node belongs to. If
this fails, then the namespace definitions in scope of the context
node will be used to resolve the prefix. If this option is given, any
namespace prefix within the xpath expression will be first resolved
against that given list (and ignoring the document global prefix /
namespace list). If the list binds the same prefix to different
namespaces, then the first binding will win.  If this fails, then the
namespace definitions in scope of the context node will be used to
resolve the prefix, as usual.</p>

<p>If the <m>-cache</m> option is used with a true value, then the
<m>xpathQuery</m> will be looked up in a document specific cache. If
the query is found, then the stored pre-compiled query will be used.
If the query isn't found, it will be compiled and stored in the cache,
for use in further calls. Please notice, that the <m>xpathQuery</m> as
given as string is used as key for the cache. This means that equal
XPath expressions, which differ only in white space, are treated as
different cache entries. Special care is needed if the XPath
expression includes namespace prefixes or references to tcl variables.
Both namespace prefixes and tcl variable references will be resolved
according to the XML prefix namespace mappings and tcl variable values
at expression compilation time. If the same XPath expression is used
later on in a context with other XML prefix namespace mappings or
values of the used tcl variables, make sure to first remove the
compiled expression from the cache with the help of the
<method>deleteXPathCache</method> method, to force a recompilation.
Without using the <m>-cache</m> option such consideration is never
needed.</p>

<p>Examples:</p>
          <example>set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
foreach paragraph $paragraphNodes {
    lappend  values [$paragraph selectNodes attribute::type]
}

................................................................................
set root [$doc documentElement]
set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]</example>

          </desc>
      </commanddef>

      <commanddef>
        <command><method>baseURI</method> <m>?URI?</m></command>
        <desc>Returns the present baseURI of the document. If the optional 
argument URI is given, sets the base URI of the document to the given URI.</desc>
      </commanddef>

      <commanddef>
        <command><method>appendFromScript</method> <m>tclScript</m></command>
        <desc>Appends the nodes created by the <m>tclScript</m> by
................................................................................
from the cache, if it is there. The method always returns an
empty string.</desc>
      </commanddef>

  </commandlist>

      <p>Otherwise, if an unknown method name is given, the command with the
same name as the given method within the namespace <samp>::dom::domDoc</samp> is
tried to be executed. This allows quick method additions on Tcl level.</p>

      <p>Newly created nodes are appended to a hidden fragment list. If they
are not moved into the tree they are automatically deleted as soon as the whole
document gets deleted.</p>

    </section>

    <seealso>
      <ref>dom</ref>
      <ref>domNode</ref>

Changes to doc/domNode.html.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
..
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
..
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
..
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
...
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165


166
167
168
169
170
171
172
...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233
...
234
235
236
237
238
239
240


















241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
...
400
401
402
403
404
405
406
407
408

409
410
411
412
413
414











415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445


446
447
448
449
450
451
452
...
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483

484
485
486


487

488
489














490

491

















492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
...
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
...
551
552
553
554
555
556
557
558
559
560
561
562
563
564

565

566
567
568

569
570
571
572
573
574
575
576
577

578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
...
625
626
627
628
629
630
631

632
633
634
635
636
637
638
...
639
640
641
642
643
644
645
646
647





648
649
650
651
652
653
654





655
656
657
658
659
660
661
662















663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: domNode</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile$ $Revision$">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid0x80a9a60">NAME</a> ท <a href="#SECTid0x80a7378">SYNOPSIS</a> ท <a href="#SECTid0x80967a8"> DESCRIPTION </a> ท <a href="#SECTid0x80d2050">SEE ALSO</a> ท <a href="#SECTid0x80d2270">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
  <h2><a name="SECTid0x80a9a60">NAME</a></h2><p class="namesection">
<b class="names">domNode - </b><br>Manipulates an instance of a DOM node object</p>



  <h2><a name="SECTid0x80a7378">SYNOPSIS</a></h2><pre class="syntax"> $nodeObject <i class="m">method</i>  <i class="m">arg arg ...</i>

</pre>
  <h2><a name="SECTid0x80967a8"> DESCRIPTION </a></h2><p>This command manipulates one particular instance of a DOM node object.
<i class="m">method</i> indicates a specific method of the node class. These methods
should closely conform to the W3C recommendation "Document Object Model
(Core) Level 1" (<a href="http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html">http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html</a>)
as well to parts of the W3C draft "XML Pointer Language (XPointer)"
(<a href="http://www.w3.org/TR/1998/WD-xptr-19980303">http://www.w3.org/TR/1998/WD-xptr-19980303</a>).
Please note, that the XPointer methods are deprecated. Use DOM methods
or XPath expressions instead of them.</p><p>The selectNodes method implements the "XML Path
................................................................................
nodes.</dd>
      

      
        <dt>
<b class="method">nodeValue</b> <i class="m">?newValue?</i>
</dt>
        <dd>Returns the value of that node object. This is the the text or
the data for element nodes of type TEXT_NODE, COMMENT_NODE,
PROCESSING_INSTRUCTION_NODE or CDATA_SECTION_NODE). Otherwise it is empty. If
the node is a TEXT_NODE, COMMENT_NODE or PROCESSING_INSTRUCTION_NODE and the
optional argument <i class="m">newValue</i> is given, the node is set to that
value.</dd>

      

      
        <dt><b class="method">hasChildNodes</b></dt>
        <dd>Returns 1 if the has children. Otherwise 0 is returned.</dd>
      

      
        <dt>
<b class="method">parentNode</b> <b class="variable">?objVar?</b>
</dt>
        <dd>Returns the parent node.</dd>
................................................................................
      
        <dt><b class="method">childNodesLive</b></dt>
        <dd>Returns a "live" nodeList object of the child nodes of
the node in the sense of the DOM recommendation. This nodeList object is
"live" in the sense that, for instance, changes to the children of
the node object that it was created from are immediately reflected in the nodes
returned by the NodeList accessors; it is not a static snapshot of the content
of the node. The both accessors know by the nodeList object are "item
&lt;index&gt;", which returns the indexth item in the collection, and
"length", which returns the number of nodes in the list.</dd>
      

      
        <dt>
<b class="method">firstChild</b> <b class="variable">?objVar?</b>
................................................................................
        <dd>Returns the last child as a node object.</dd>
      
      
      
        <dt>
<b class="method">nextSibling</b>  <b class="variable">?objVar?</b>
</dt>
        <dd>Returns the next sibling relativ to the current node as a node
object.</dd>
      

      
        <dt>
<b class="method">previousSibling</b> <b class="variable">?objVar?</b>
</dt>
        <dd>Returns the next sibling relativ to the current node as a node
object.</dd>
      

      
        <dt>
<b class="method">getElementsByTagName</b> <i class="m">name</i>
</dt>
................................................................................
<i class="m">uri</i>.</dd>
      

      
        <dt>
<b class="method">getElementById</b> <i class="m">id</i>
</dt>
        <dd>Returns the node having a id attribute with value
<i class="m">id</i> or the emtpy string, if no node has an id attribute with that value.</dd>
      

      
        <dt>
<b class="method">hasAttribute</b> <i class="m">attributeName</i>
</dt>
        <dd>Returns 1 if the object node contains an attribute with name
................................................................................
<i class="m">attributeName</i> . Otherwise 0 is returned.</dd>
      

      
        <dt>
<b class="method">getAttribute</b> <i class="m">attributeName  ?defaultValue?</i>
</dt>
        <dd>Returns the value of the attribute <i class="m">attributeName</i>. If
attribute is not available <i class="m">defaultValue</i> is returned.</dd>
      

      
        <dt>
<b class="method">setAttribute</b> <i class="m">attributeName newValue 
?attributeName newValue ...?</i>
</dt>
        <dd>Sets the value for one or more attributes. Every
<i class="m">attributeName</i> is set to the corresponding <i class="m">newValue</i>. If there
isn't an attribute for one or more of the <i class="m">attributeName</i> this will
create that attribute.</dd>



      

      
        <dt>
<b class="method">removeAttribute</b> <i class="m">attributeName</i>
</dt>
        <dd>Removes the attribute <i class="m">attributeName</i>.</dd>
................................................................................
        <pre class="example">$node setAttributeNS "http://some.uri.com/wow" prefix:attr1 attrValue</pre>

<p>If the uri is the empty string and the attribute name hasn't a prefix, this
method has the same effect as the method <b>setAttribute</b>.</p>

        <pre class="example">$node setAttributeNS "" attri "some Value"</pre>

<p>XML namespace nodes are not in any namespace. Set them this way:</p>

        <pre class="example">$node setAttributeNS "" xmlns:myprefix "myNamespaceURI"
$node setAttributeNS "" xmlns "newDefaultNamespace"</pre>

<p>If your <i class="m">qualifiedName</i> has the prefix "xml" and you give the empty
string as <i class="m">uri</i>, the namespace of the attribute defaults to
"http://www.w3.org/XML/1998/namespace", as the DOM 2 recommendation
requests. With the exceptions of the special prefixes "xmlns" and "xml" you
always must provide a non emtpy <i class="m">uri</i>, if your <i class="m">qualifiedName</i> has a
prefix.</p>

        </dd>
      

      
        <dt>
<b class="method">removeAttributeNS</b> <i class="m">uri</i> <i class="m">localName</i>
</dt>
        <dd>Removes the attribute with the local name <i class="m">localName</i> within
................................................................................
 the namespace <i class="m">uri</i>.</dd>
      

      
        <dt>
<b class="method">attributes</b> <b class="option">?attributeNamePattern?</b>
</dt>


















        <dd>Returns all attributes matching the <i class="m">attributeNamePattern</i>.
If <i class="m">attributeNamePattern</i> isn't given all attributes are returned as a Tcl
list.</dd>
      

      
        <dt>
<b class="method">appendChild</b> <i class="m">newChild</i>
</dt>
        <dd>Append <i class="m">newChild</i> to the end of the child list of the
node.</dd>
      

      
        <dt>
<b class="method">insertBefore</b> <i class="m">newChild</i>  <i class="m">refChild</i>
</dt>
        <dd>Insert <i class="m">newChild</i> before the <i class="m">refChild</i> into the list of
children of node. If <i class="m">refChild</i> is the empty string, insert
<i class="m">newChild</i> at the end of the child nodes list of that node.</dd>
      

      
        <dt>
<b class="method">replaceChild</b> <i class="m">newChild</i>  <i class="m">oldChild</i>
</dt>
        <dd>Replace <i class="m">oldChild</i> with <i class="m">newChild</i> in the list of
children of that node. The <i class="m">oldChild</i> node will be part of the
document fragment list after this operation.</dd>
      

      
        <dt>
<b class="method">removeChild</b> <i class="m">child</i>
</dt>
        <dd>Removes <i class="m">child</i> from the list of children of that node
<i class="m">child</i> will be part of the document fragment list after this
operation. It is not physically deleted.</dd>
      

      
        <dt><b class="method">delete</b></dt>
        <dd>Deletes the given node and its complete child tree
and frees the complete internal memory. The affected nodes are not accessible
through the document fragment list.</dd>
................................................................................
<p>Returns the result of applying the XPath query
<i class="m">xpathQuery</i> to the subtree. This can be a
string/value, a list of strings, a list of nodes or a list
of attribute name / value pairs. If <i class="m">typeVar</i> is given
the result type name is stored into that variable (empty,
bool, number, string, nodes, attrnodes or mixed).</p>

<p>The argument <i class="m">xpathQuery</i> has to be a valid XPath
expression. However, there is one exception to that rule. Tcl variable

names can appear in the XPath statement at any position where it is
legal according to the rules of the XPath syntax to put an XPath
variable. The value of the variable is substituted for the variable
name. Ignoring the syntax rules of XPath the Tcl variable name may be
any legal Tcl var name: local variables, global variables, array
entries and so on.</p>












<p>The option <i class="m">-namespaces</i> expects a tcl list with prefix /
namespace pairs as argument. If this option is not given, then any
namespace prefix within the xpath expression will be first resolved
against the list of prefix / namespace pairs set with the
selectNodesNamespaces method for the document, the node belongs to. If
this fails, then the namespace definitions in scope of the context
node will be used to resolve the prefix. If this option is given, any
namespace prefix within the xpath expression will be first resolved
against that given list (and ignoring the document global prefix /
namespace list). If the list bind the same prefix to different
namespaces, then the first binding will win.  If this fails, then the
namespace definitions in scope of the context node will be used to
resolve the prefix, as usual.</p>

<p>If the <i class="m">-cache</i> option is used with a true value, then the
<i class="m">xpathQuery</i> will be looked up in a document specific cache. If the query
is found, then the stored pre-compiled query will be used. If the
query isn't found, it will be pre-compiled and stored in the cache,
for use in further calls. Please notice, that the <i class="m">xpathQuery</i> as given as
string is used as key for the cache. This means, that equal XPath
expressions, which differ only in white space are treated as
different cache entries. Special care is needed, if the XPath
expression includes namespace prefixes. During pre-compilation, the
prefixes will be resolved first to the prefix / namespace pairs of
the <i class="m">-namespaces</i> option, if given, and to the namespaces
in scope of the context node at pre-compilation time. If the XPath
is found in the cache, neither the <i class="m">-namespaces</i> option nor
the namespaces in scope of the context node will be taken in
account but the already resolved (stored) namespaces will be used
for the query.</p>



<p>Examples:</p>
          <pre class="example">set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
foreach paragraph $paragraphNodes {
    lappend  values [$paragraph selectNodes attribute::type]
}

................................................................................
set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]</pre>

          </dd>
      

      
        <dt><b class="method">getLine</b></dt>
        <dd>Returns the line number of that node in the orignal parsed
XML.</dd>
      
      
      
        <dt><b class="method">getColumn</b></dt>
        <dd>Returns the column number of that node in the orignal parsed
XML.</dd>
      

      
        <dt><b class="method">asList</b></dt>
        <dd>Returns the DOM substree starting form the current node as a
nested Tcl list.</dd>
      

      
        <dt>
<b class="method">asXML</b> <b class="option">?-indent none/1..8?</b>
<b class="option">?-channel channelId?</b> <b class="option">?-escapeNonASCII?</b><b class="option">?-escapeAllQuot?</b>
</dt>


        <dd>Returns the DOM substree starting from the current node
as the root node of the result as an (optional indented) XML string or
sends the output directly to the given channelId. If the option


<i class="m">-escapeNonASCII</i> is given, every non 7 bit ASCII character in

attribute values or element PCDATA content will be escaped as
character reference in decimal representation. If the option














<i class="m">-escapeAllQuot</i> is given, quotation marks will be escaped with

&amp;quot; even in text content of elements.</dd>

















      

      
        <dt>
<b class="method">asHTML</b> <b class="option">?-channel channelId?</b>
<b class="option">?-escapeNonASCII?</b>  <b class="option">?-htmlEntities?</b>
</dt>
        <dd>Returns the DOM substree starting from the current node as the
root node of the result serialized acording to HTML rules (HTML elements are
recognized regardless of case, without end tags for emtpy HTML elements etc.),
as string or sends the output directly to the given channelId. If the option
<i class="m">-escapeNonASCII</i> is given, every non 7 bit ASCII character in attribute
values or element PCDATA content will be escaped as character reference in
decimal representation. If the option <i class="m">-htmlEntities</i> is given, a
character is outputed using a HTML 4.01 character entity reference, if one is
defined for it.</dd>
      

      
        <dt><b class="method">asText</b></dt>
          <dd>For ELEMENT_NODEs, the asText method outputs 
the string-value of every text node descendant of node in document
order without any escaping. For every other node type, this method outputs the
the XPath string value of that node.</dd>
      

      
        <dt>
<b class="method">appendFromList</b> <i class="m">list</i>
</dt>
        <dd>Parses <i class="m">list</i> , creates an according DOM subtree and
................................................................................

      
        <dt>
<b class="method">insertBeforeFromScript</b> <i class="m">tclScript</i> <i class="m">refChild</i>
</dt>
        <dd>Inserts the nodes created in the <i class="m">tclScript</i> by
Tcl functions, which have been built using <i class="m">dom createNodeCmd</i>, before the
<i class="m">refChild</i> into to the list of children of node. If <i class="m">refChild</i> is
the empty string, the new nodes will be appended.</dd>
      

      
        <dt>
<b class="method">appendXML</b> <i class="m">XMLstring</i>
</dt>
................................................................................
      

      
        <dt>
<b class="method">simpleTranslate</b> <i class="m">outputVar</i>
<i class="m">specifications</i>
</dt>
        <dd>Translate the subtree starting at the object node according to
the specifications in <i class="m">specifications</i> and outputs the result in the
variable <i class="m">outputVar</i> . The translation is very similar to Cost Simple
mode.</dd>
      

      

        <dt><b class="method">toXPath</b></dt>

        <dd>Returns an XPath, which exactly addresses the given
node in its document. This XPath is only valid as there are no changes to DOM
tree made later one.</dd>

      

      
        <dt><b class="method">getBaseURI</b></dt>
        <dd>Returns the baseURI of the node. This method is deprecated in
          favor of the <i class="m">baseURI</i> method.</dd>
      

      

        <dt><b class="method">baseURI <i class="m">?URI?</i>
</b></dt>
        <dd>Returns the present baseURI of the node. If the optional 
argument URI is given, sets the base URI of the node and of all of its child
nodes out of the same enitity as node to the given URI.</dd>
      

      
        <dt>
<b class="method">disableOutputEscaping</b> <i class="m">?boolean?</i>
</dt>
        <dd>This method works only for text nodes; for every other nodes it
returns error. Without the optional argument it returns, if disabling output
escaping is on. The return value 0 means, the characters of the text node will
be escaped, to generate valid XML, if serialized. This is the default for
every parsed or created text node (with the exception of that text nodes in a
result tree of an XSLT transformation, for which disabling output escaping was
requested explicitely in the stylesheet). The return value 1 means, that output
escaping is disabled for this text node. If such a text node is serialized
(with asXML or asHTML), it is literarily written, without escaping of the
special XML characters. If the optional boolean value <i class="m">boolean</i> is given,
the flag is set accordingly. You should not set this flag to 1, until you
really know, what you do.</dd>
      

      
        <dt>
<b class="method">precedes</b> <i class="m">refnode</i>
</dt>
        <dd>Compares the relative order of the node and <i class="m">refnode</i>. Both
nodes must be part of the same documents and not out of the fragment list of
the document. Returns true, if node is in document order (in the sense of the
XPath 1.0 recommendation) before <i class="m">refnode</i> and false otherwise.</dd>
      


      
        <dt>
<b class="method">normalize</b> <i class="m">?-forXPath?</i>
</dt>
................................................................................
normalization. </dd>
      

      
        <dt>
<b class="method">xslt</b> <b class="option">?-parameters
parameterList?</b> <b class="option">?-ignoreUndeclaredParameters?</b>

<b class="option">?-xsltmessagecmd script?</b> <i class="m">stylesheet</i> <i class="m">?outputVar?</i>
</dt>
        <dd>Applies an XSLT transformation on the document using the XSLT
<i class="m">stylesheet</i> (given as domDoc). Returns a document object containing the
result document of that transformation and stores it in the optional
<i class="m">outputVar</i>. 

................................................................................
<p>The optional <i class="m">-parameters</i> option sets top level
&lt;xsl:param&gt; to string values. The <i class="m">parameterList</i> has to be a tcl
list consisting of parameter name and value pairs.</p>

<p>If the option <i class="m">-ignoreUndeclaredParameters</i> is given, then parameter
names in the <i class="m">parameterList</i> given to the <i class="m">-parameters</i> options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised, if the user tries to set a
top-level parameter, which is not declared in the stylesheet.</p>






<p>The <i class="m">-xsltmessagecmd</i> option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes".</p>





</dd>
      

      
        <dt><i class="m">@attrName</i></dt>
        <dd>Returns the value of the attribute <i class="m">attrName</i>.  Short cut
for <i class="m">getAttribute</i>.</dd>
      















    </dl><p>Otherwise, if an unknown method name is given, the command with the same
name as the given method within the namespace <tt class="l">::dom::domNode</tt> is tried to
be executed. This allows quick method additions on Tcl level.</p>


  <h2><a name="SECTid0x80d2050">SEE ALSO</a></h2><p class="seealso">dom, domDoc</p>
  
  <h2><a name="SECTid0x80d2270">KEYWORDS</a></h2><p class="keywords">
<a class="keyword" href="keyword-index.html#KW-XML">XML</a>, <a class="keyword" href="keyword-index.html#KW-DOM">DOM</a>, <a class="keyword" href="keyword-index.html#KW-document">document</a>, <a class="keyword" href="keyword-index.html#KW-node">node</a>, <a class="keyword" href="keyword-index.html#KW-parsing">parsing</a>
</p>
  
</div><hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> <a class="navaid" href="category-index.html">Index</a> ท <a class="navaid" href="keyword-index.html">Keywords</a>
</div>
</body>
</html>


|



|


|




|
>

|







 







|










|







 







|







 







|







|







 







|
|







 







|









|
|
|
<
>
>







 







<
<
<
<
<
<
<
<
|
|
<
>
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|

|




|







|








|








|

|







 







|
|
>
|
|
<
|
|
|
>
>
>
>
>
>
>
>
>
>
>










|





|
|
|
|
|
|

|
|
|
|
|
|
|
|
>
>







 







|





|











|
<

<
>
|
|
|
>
>
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|
|




|







|
<







 







|







 







|






>
|
>


|
>









>
|
|

|
|






|





|

|

|
|








|
|







 







>







 







|
|
>
>
>
>
>





|
|
>
>
>
>
>








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|

|




|



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
..
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
..
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
...
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173
174
...
210
211
212
213
214
215
216








217
218

219
220
221
222
223
224
225
226
227
...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
...
412
413
414
415
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
...
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505

506

507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573

574
575
576
577
578
579
580
...
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
...
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
...
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
...
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: domNode</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: tmml-html.xsl,v $ $Revision: 1.11 $"><meta charset="utf-8">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid0xd75c60">NAME</a> ยท <a href="#SECTid0xc89db0">SYNOPSIS</a> ยท <a href="#SECTid0xd6fd90"> DESCRIPTION </a> ยท <a href="#SECTid0xdd72b0">SEE ALSO</a> ยท <a href="#SECTid0xdd7640">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
  <h2><a name="SECTid0xd75c60">NAME</a></h2><p class="namesection">
<b class="names">domNode - </b><br>Manipulates an instance of a DOM node object</p>



  <h2><a name="SECTid0xc89db0">SYNOPSIS</a></h2><pre class="syntax">$nodeObject <i class="m">method</i> <i class="m">arg arg ...</i>
</pre><pre class="syntax">domNode <i class="m">nodeToken</i> <i class="m">method</i> <i class="m">arg arg ...</i>
</pre>
  <h2><a name="SECTid0xd6fd90"> DESCRIPTION </a></h2><p>This command manipulates one particular instance of a DOM node object.
<i class="m">method</i> indicates a specific method of the node class. These methods
should closely conform to the W3C recommendation "Document Object Model
(Core) Level 1" (<a href="http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html">http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html</a>)
as well to parts of the W3C draft "XML Pointer Language (XPointer)"
(<a href="http://www.w3.org/TR/1998/WD-xptr-19980303">http://www.w3.org/TR/1998/WD-xptr-19980303</a>).
Please note, that the XPointer methods are deprecated. Use DOM methods
or XPath expressions instead of them.</p><p>The selectNodes method implements the "XML Path
................................................................................
nodes.</dd>
      

      
        <dt>
<b class="method">nodeValue</b> <i class="m">?newValue?</i>
</dt>
        <dd>Returns the value of that node object. This is the text or
the data for element nodes of type TEXT_NODE, COMMENT_NODE,
PROCESSING_INSTRUCTION_NODE or CDATA_SECTION_NODE). Otherwise it is empty. If
the node is a TEXT_NODE, COMMENT_NODE or PROCESSING_INSTRUCTION_NODE and the
optional argument <i class="m">newValue</i> is given, the node is set to that
value.</dd>

      

      
        <dt><b class="method">hasChildNodes</b></dt>
        <dd>Returns 1 if the node has children. Otherwise 0 is returned.</dd>
      

      
        <dt>
<b class="method">parentNode</b> <b class="variable">?objVar?</b>
</dt>
        <dd>Returns the parent node.</dd>
................................................................................
      
        <dt><b class="method">childNodesLive</b></dt>
        <dd>Returns a "live" nodeList object of the child nodes of
the node in the sense of the DOM recommendation. This nodeList object is
"live" in the sense that, for instance, changes to the children of
the node object that it was created from are immediately reflected in the nodes
returned by the NodeList accessors; it is not a static snapshot of the content
of the node. The two accessors known by the nodeList object are "item
&lt;index&gt;", which returns the indexth item in the collection, and
"length", which returns the number of nodes in the list.</dd>
      

      
        <dt>
<b class="method">firstChild</b> <b class="variable">?objVar?</b>
................................................................................
        <dd>Returns the last child as a node object.</dd>
      
      
      
        <dt>
<b class="method">nextSibling</b>  <b class="variable">?objVar?</b>
</dt>
        <dd>Returns the next sibling relative to the current node as a node
object.</dd>
      

      
        <dt>
<b class="method">previousSibling</b> <b class="variable">?objVar?</b>
</dt>
        <dd>Returns the next sibling relative to the current node as a node
object.</dd>
      

      
        <dt>
<b class="method">getElementsByTagName</b> <i class="m">name</i>
</dt>
................................................................................
<i class="m">uri</i>.</dd>
      

      
        <dt>
<b class="method">getElementById</b> <i class="m">id</i>
</dt>
        <dd>Returns the node having an id attribute with value
<i class="m">id</i> or the empty string if no node has an id attribute with that value.</dd>
      

      
        <dt>
<b class="method">hasAttribute</b> <i class="m">attributeName</i>
</dt>
        <dd>Returns 1 if the object node contains an attribute with name
................................................................................
<i class="m">attributeName</i> . Otherwise 0 is returned.</dd>
      

      
        <dt>
<b class="method">getAttribute</b> <i class="m">attributeName  ?defaultValue?</i>
</dt>
        <dd>Returns the value of the attribute <i class="m">attributeName</i>. If the
attribute is not available <i class="m">defaultValue</i> is returned.</dd>
      

      
        <dt>
<b class="method">setAttribute</b> <i class="m">attributeName newValue 
?attributeName newValue ...?</i>
</dt>
        <dd>Sets the value for one or more attributes. Every
        <i class="m">attributeName</i> is set to the corresponding
        <i class="m">newValue</i>. If there isn't an attribute for one or more
        of the <i class="m">attributeName</i>, this will create that attribute.

        It is not recommended to set attributes that look like xml
        namespace declarations.</dd>
      

      
        <dt>
<b class="method">removeAttribute</b> <i class="m">attributeName</i>
</dt>
        <dd>Removes the attribute <i class="m">attributeName</i>.</dd>
................................................................................
        <pre class="example">$node setAttributeNS "http://some.uri.com/wow" prefix:attr1 attrValue</pre>

<p>If the uri is the empty string and the attribute name hasn't a prefix, this
method has the same effect as the method <b>setAttribute</b>.</p>

        <pre class="example">$node setAttributeNS "" attri "some Value"</pre>









<p>With the exceptions of the special prefixes "xmlns" and "xml" you
always must provide a non empty <i class="m">uri</i>, if your <i class="m">qualifiedName</i> has a

prefix. It is not recommended to set xml namespace declarations. The effects are complicated and not always obvious up to resulting a not well-formed serializations after further processing.</p>
</dd>
      

      
        <dt>
<b class="method">removeAttributeNS</b> <i class="m">uri</i> <i class="m">localName</i>
</dt>
        <dd>Removes the attribute with the local name <i class="m">localName</i> within
................................................................................
 the namespace <i class="m">uri</i>.</dd>
      

      
        <dt>
<b class="method">attributes</b> <b class="option">?attributeNamePattern?</b>
</dt>
        <dd>Returns information about the attriubtes matching the
        <i class="m">attributeNamePattern</i>. If <i class="m">attributeNamePattern</i>
        isn't given, information about all attributes are returned.
        The return value is a Tcl list, the elements just the
        attriubute name in case of non namespaced attriubtes and three
        element sublists for namespaced attributes. n case of an
        "ordinary" namespaced attribute, the sublist elements are
        {&lt;localname&gt; &lt;prefix&gt; &lt;namespace_uri&gt;}. In the special case of
        an xml namespace declaration it is {&lt;the prefix defined&gt;
        &lt;localname&gt; ""}.
        </dd>
      

      
        <dt>
<b class="method">attributeNames</b> <b class="option">?attributeNamePattern?</b>
</dt>
        <dd>Returns a flat list of all attributes names (as found in
        the XML source) matching the <i class="m">attributeNamePattern</i>. If
        <i class="m">attributeNamePattern</i> isn't given, all attribute names
        are returned as a Tcl list.</dd>
      
      
      
        <dt>
<b class="method">appendChild</b> <i class="m">newChild</i>
</dt>
        <dd>Appends <i class="m">newChild</i> to the end of the child list of the
node.</dd>
      

      
        <dt>
<b class="method">insertBefore</b> <i class="m">newChild</i>  <i class="m">refChild</i>
</dt>
        <dd>Inserts <i class="m">newChild</i> before the <i class="m">refChild</i> into the list of
children of node. If <i class="m">refChild</i> is the empty string, insert
<i class="m">newChild</i> at the end of the child nodes list of that node.</dd>
      

      
        <dt>
<b class="method">replaceChild</b> <i class="m">newChild</i>  <i class="m">oldChild</i>
</dt>
        <dd>Replaces <i class="m">oldChild</i> with <i class="m">newChild</i> in the list of
children of that node. The <i class="m">oldChild</i> node will be part of the
document fragment list after this operation.</dd>
      

      
        <dt>
<b class="method">removeChild</b> <i class="m">child</i>
</dt>
        <dd>Removes <i class="m">child</i> from the list of children of that node.
<i class="m">child</i> will be part of the document fragment list after this
operation.</dd>
      

      
        <dt><b class="method">delete</b></dt>
        <dd>Deletes the given node and its complete child tree
and frees the complete internal memory. The affected nodes are not accessible
through the document fragment list.</dd>
................................................................................
<p>Returns the result of applying the XPath query
<i class="m">xpathQuery</i> to the subtree. This can be a
string/value, a list of strings, a list of nodes or a list
of attribute name / value pairs. If <i class="m">typeVar</i> is given
the result type name is stored into that variable (empty,
bool, number, string, nodes, attrnodes or mixed).</p>

<p>The argument <i class="m">xpathQuery</i> has to be a valid XPath expression.
However there are a few exceptions to that rule. Tcl variable
references (in the usual tcl syntax: $varname) may appear in the XPath
statement at any position where it is legal according to the rules of
the XPath syntax to put an XPath variable. Ignoring the syntax rules of

XPath the Tcl variable name may be any legal Tcl var name: local
variables, global variables, array entries and so on. The value will
always be seen as string literal by the xpath engine. Cast the value
explicitly with the according xpath functions (number(), boolean()) to
another data type, if needed.</p>

<p>Similar to the way described above to inject literals in a secure
way into the XPath expression using tcl variable references there is a
syntax to inject element names from tcl variables. At every place
where the XPath syntax allows a node test there could be a tcl
variable reference (in any form), just the leading $ replaced with %.
This allows one to select nodes with 'strange' (invalid, according to the
appropriate XML production rule) node names which may be needed in
case of working with JSON data.</p>

<p>The option <i class="m">-namespaces</i> expects a tcl list with prefix /
namespace pairs as argument. If this option is not given, then any
namespace prefix within the xpath expression will be first resolved
against the list of prefix / namespace pairs set with the
selectNodesNamespaces method for the document, the node belongs to. If
this fails, then the namespace definitions in scope of the context
node will be used to resolve the prefix. If this option is given, any
namespace prefix within the xpath expression will be first resolved
against that given list (and ignoring the document global prefix /
namespace list). If the list binds the same prefix to different
namespaces, then the first binding will win.  If this fails, then the
namespace definitions in scope of the context node will be used to
resolve the prefix, as usual.</p>

<p>If the <i class="m">-cache</i> option is used with a true value, then the
<i class="m">xpathQuery</i> will be looked up in a document specific cache. If
the query is found, then the stored pre-compiled query will be used.
If the query isn't found, it will be compiled and stored in the cache,
for use in further calls. Please note that the <i class="m">xpathQuery</i> 
given as string is used as key for the cache. This means, that equal
XPath expressions, which differ only in white space are treated as
different cache entries. Special care is needed, if the XPath
expression includes namespace prefixes or references to tcl variables.
Both namespace prefixes and tcl variable references will be resolved
according to the XML prefix namespace mappings and tcl variable values
at expression compilation time. If the same XPath expression is used
later on in a context with other XML prefix namespace mappings or
values of the used tcl variables, make sure to first remove the
compiled expression from the cache with the help of the
<b class="method">deleteXPathCache</b> method, to force a recompilation.
Without using the <i class="m">-cache</i> option such consideration is never
needed.</p>

<p>Examples:</p>
          <pre class="example">set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
foreach paragraph $paragraphNodes {
    lappend  values [$paragraph selectNodes attribute::type]
}

................................................................................
set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]</pre>

          </dd>
      

      
        <dt><b class="method">getLine</b></dt>
        <dd>Returns the line number of that node in the originally parsed
XML.</dd>
      
      
      
        <dt><b class="method">getColumn</b></dt>
        <dd>Returns the column number of that node in the originally parsed
XML.</dd>
      

      
        <dt><b class="method">asList</b></dt>
        <dd>Returns the DOM substree starting form the current node as a
nested Tcl list.</dd>
      

      
        <dt>
<b class="method">asXML</b> <b class="option">?-indent none/1..8?</b> <b class="option">?-channel channelId?</b> <b class="option">?-escapeNonASCII?</b> <b class="option">-xmlDeclaration &lt;boolean&gt;?</b> <b class="option">-encString &lt;string&gt;</b> <b class="option">?-escapeAllQuot?</b> <b class="option">?-indentAttrs?</b> <b class="option">?-nogtescape?</b> <b class="option">?-noEmptyElementTag?</b>

</dt>

        <dd>
<p>Returns the DOM substree starting from the current
        node as the root node of the result as an (optional indented)
        XML string or sends the output directly to the given
        channelId.</p>

        <p>If the option <i class="m">-escapeNonASCII</i> is given,
        every non 7 bit ASCII character in attribute values or element
        PCDATA content will be escaped as character reference in
        decimal representation.</p>

        <p>The flag <i class="m">-xmlDeclaration</i> determines whether there
        will be an XML Declaration and a newline emitted before
        anything else. The default is, to do not. If this flag is
        given with a true argument then</p>

        <p>
<i class="m">-encString</i> sets the encoding value in the XML
        Declaration. Otherwise, this option is ignored. Please note,
        that this option just enhance the string representation of the
        generated XML Declaration with an encoding information string,
        nothing more. It's up to the user to handle encoding in case
        of writing to a channel or reparsing.</p>
            
        <p>If the option <i class="m">-escapeAllQuot</i> is given,
        quotation marks will be escaped with &amp;quot; even in text
        content of elements.</p>

        <p>If the option <i class="m">-indentAttrs</i> is
        given, then attributes will each be separated with newlines
        and indented to the same level as the parent node plus the
        value given as argument to <i class="m">-indentAttrs</i> (0..8).</p>

        <p>If the option <i class="m">-nogtescape</i> is given then the
        character '&gt;' won't get escaped in attribute values and text
        content of elements. The default is to escape this
        character.</p>

        <p>If the option <i class="m">-noEmptyElementTag</i> is given then no
        empty tag syntax will be used. Instead, if an element has
        empty content it will be serialized with an element start tag
        and an immediately following element end tag.</p>
</dd>

      

      
        <dt>
<b class="method">asHTML</b> <b class="option">?-channel channelId?</b>
<b class="option">?-escapeNonASCII?</b>  <b class="option">?-htmlEntities?</b>
</dt>
        <dd>Returns the DOM substree starting from the current node as the
root node of the result serialized according to HTML rules (HTML elements are
recognized regardless of case, without end tags for empty HTML elements etc.),
as string or sends the output directly to the given channelId. If the option
<i class="m">-escapeNonASCII</i> is given, every non 7 bit ASCII character in attribute
values or element PCDATA content will be escaped as character reference in
decimal representation. If the option <i class="m">-htmlEntities</i> is given, a
character is written using its HTML 4.01 character entity reference, if one is
defined for it.</dd>
      

      
        <dt><b class="method">asText</b></dt>
          <dd>For ELEMENT_NODEs, the asText method outputs 
the string-value of every text node descendant of node in document
order without any escaping. For every other node type, this method outputs the XPath string value of that node.</dd>

      

      
        <dt>
<b class="method">appendFromList</b> <i class="m">list</i>
</dt>
        <dd>Parses <i class="m">list</i> , creates an according DOM subtree and
................................................................................

      
        <dt>
<b class="method">insertBeforeFromScript</b> <i class="m">tclScript</i> <i class="m">refChild</i>
</dt>
        <dd>Inserts the nodes created in the <i class="m">tclScript</i> by
Tcl functions, which have been built using <i class="m">dom createNodeCmd</i>, before the
<i class="m">refChild</i> into the list of children of node. If <i class="m">refChild</i> is
the empty string, the new nodes will be appended.</dd>
      

      
        <dt>
<b class="method">appendXML</b> <i class="m">XMLstring</i>
</dt>
................................................................................
      

      
        <dt>
<b class="method">simpleTranslate</b> <i class="m">outputVar</i>
<i class="m">specifications</i>
</dt>
        <dd>Translates the subtree starting at the object node according to
the specifications in <i class="m">specifications</i> and outputs the result in the
variable <i class="m">outputVar</i> . The translation is very similar to Cost Simple
mode.</dd>
      

      
        <dt>
<b class="method">toXPath</b> <i class="m">?-legacy?</i>
</dt>
        <dd>Returns an XPath, which exactly addresses the given
node in its document. This XPath is only valid as there are no changes to DOM
tree made later one. With the -legacy option, other XPath expressions
are returned, which doesn't work in all cases.</dd>
      

      
        <dt><b class="method">getBaseURI</b></dt>
        <dd>Returns the baseURI of the node. This method is deprecated in
          favor of the <i class="m">baseURI</i> method.</dd>
      

      
        <dt>
<b class="method">baseURI</b> <i class="m">?URI?</i>
</dt>
        <dd>Returns the present baseURI of the node. If the optional 
argument URI is given, it sets the base URI of the node and of all of its child
nodes out of the same entity as node to the given URI.</dd>
      

      
        <dt>
<b class="method">disableOutputEscaping</b> <i class="m">?boolean?</i>
</dt>
        <dd>This method works only for text nodes; for every other node it
returns error. Without the optional argument it returns, if disabling output
escaping is on. The return value 0 means, the characters of the text node will
be escaped, to generate valid XML, if serialized. This is the default for
every parsed or created text node (with the exception of that text nodes in a
result tree of an XSLT transformation, for which disabling output escaping was
requested explicitly in the stylesheet). The return value 1 means, that output
escaping is disabled for this text node. If such a text node is serialized
(with asXML or asHTML), it is literally written, without escaping of the
special XML characters. If the optional boolean value <i class="m">boolean</i> is given,
the flag is set accordingly. You should not set this flag to 1 until you
really know what you do.</dd>
      

      
        <dt>
<b class="method">precedes</b> <i class="m">refnode</i>
</dt>
        <dd>Compares the relative order of the node and <i class="m">refnode</i>. Both
nodes must be part of the same documents and not out of the fragment list of
the document. Returns true if node is in document order (in the sense of the
XPath 1.0 recommendation) before <i class="m">refnode</i>, and false otherwise.</dd>
      


      
        <dt>
<b class="method">normalize</b> <i class="m">?-forXPath?</i>
</dt>
................................................................................
normalization. </dd>
      

      
        <dt>
<b class="method">xslt</b> <b class="option">?-parameters
parameterList?</b> <b class="option">?-ignoreUndeclaredParameters?</b>
<b class="option">?-maxApplyDepth int?</b>
<b class="option">?-xsltmessagecmd script?</b> <i class="m">stylesheet</i> <i class="m">?outputVar?</i>
</dt>
        <dd>Applies an XSLT transformation on the document using the XSLT
<i class="m">stylesheet</i> (given as domDoc). Returns a document object containing the
result document of that transformation and stores it in the optional
<i class="m">outputVar</i>. 

................................................................................
<p>The optional <i class="m">-parameters</i> option sets top level
&lt;xsl:param&gt; to string values. The <i class="m">parameterList</i> has to be a tcl
list consisting of parameter name and value pairs.</p>

<p>If the option <i class="m">-ignoreUndeclaredParameters</i> is given, then parameter
names in the <i class="m">parameterList</i> given to the <i class="m">-parameters</i> options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised if the user tries to set a
top-level parameter which is not declared in the stylesheet.</p>

<p>The option <i class="m">-maxApplyDepth</i> expects a positive integer as
argument. By default, the xslt engine allows xslt templates to nest up
to 3000 levels (and raises error if they nest deeper). This limit can
be set by the <i class="m">-maxApplyDepth</i> option.</p>

<p>The <i class="m">-xsltmessagecmd</i> option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates whether the
xsl:message has an attribute "terminate" with the value "yes". If the
called script returns anything else then TCL_OK then the xslt
transformation will be aborted, returning error. If the called script
returns -code break the error message is empty, otherwise the result
code is reported. In case of terminated transformation the outputVar,
if given, is set to the empty string.</p>
</dd>
      

      
        <dt><i class="m">@attrName</i></dt>
        <dd>Returns the value of the attribute <i class="m">attrName</i>.  Short cut
for <i class="m">getAttribute</i>.</dd>
      

      
        <dt>
<b class="method">jsonType</b> <i class="m">?OBJECT|ARRAY|NONE)|(STRING|NUMBER|TRUE|FALSE|NULL|NONE)?</i>
</dt>
        <dd>Only element and text nodes may have a JSON type and
        only this types of nodes support the <i class="m">jsonType</i> method;
        the other node types return error if called with this method.
        Returns the jsonType of the node. If the optional argument is
        given, the JSON type of the node is set to the given type and
        returned. Valid type arguments for element nodes are OBJECT,
        ARRAY and NONE. Valid type arguments for text nodes are
        STRING, NUMBER, TRUE, FALSE, NULL and NONE.</dd>
      

    </dl><p>Otherwise, if an unknown method name is given, the command with the same
name as the given method within the namespace <tt class="l">::dom::domNode</tt> is tried to
be executed. This allows quick method additions on Tcl level.</p>


  <h2><a name="SECTid0xdd72b0">SEE ALSO</a></h2><p class="seealso">dom, domDoc</p>
  
  <h2><a name="SECTid0xdd7640">KEYWORDS</a></h2><p class="keywords">
<a class="keyword" href="keyword-index.html#KW-XML">XML</a>, <a class="keyword" href="keyword-index.html#KW-DOM">DOM</a>, <a class="keyword" href="keyword-index.html#KW-document">document</a>, <a class="keyword" href="keyword-index.html#KW-node">node</a>, <a class="keyword" href="keyword-index.html#KW-parsing">parsing</a>
</p>
  
</div><hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>
</div>
</body>
</html>

Changes to doc/domNode.n.

159
160
161
162
163
164
165
166



167
168
169
170
171
172
173
...
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264


265
266
267
268
269
270
271
...
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321

322
323
324
325
326
327
328













329
330
331

332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
...
414
415
416
417
418
419
420
421
422

423
424
425
426
427
428











429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459


460
461
462
463
464
465
466
...
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488



489
490
491


492

493
494














495
496
















497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543

544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599





600
601
602
603
604
605
606





607
608
609
610
611










612
613
614
615
616
617
618
619
'\" END man.macros
.TH domNode n "" Tcl ""
.BS
.SH NAME
domNode \- Manipulates an instance of a DOM node object
.SH SYNOPSIS
.nf
 $nodeObject \fImethod\fR  \fIarg arg ...\fR



.fi
.BE
.SH " DESCRIPTION "
.PP
This command manipulates one particular instance of a DOM node object.
\&\fImethod\fR indicates a specific method of the node class. These methods
should closely conform to the W3C recommendation "Document Object Model
................................................................................
\&\fRReturns the node name of that node object. This is the element
(tag) name for element nodes (type ELEMENT_NODE), the processing-instruction
target for processing-instructions, "#text" for text node,
"#comment" for comment nodes or "#cdata" for cdata section
nodes.
.TP
\&\fB\fBnodeValue\fP \fI?newValue?\fB
\&\fRReturns the value of that node object. This is the the text or
the data for element nodes of type TEXT_NODE, COMMENT_NODE,
PROCESSING_INSTRUCTION_NODE or CDATA_SECTION_NODE). Otherwise it is empty. If
the node is a TEXT_NODE, COMMENT_NODE or PROCESSING_INSTRUCTION_NODE and the
optional argument \fInewValue\fR is given, the node is set to that
value.
.TP
\&\fB\fBhasChildNodes\fP
\&\fRReturns 1 if the has children. Otherwise 0 is returned.
.TP
\&\fB\fBparentNode\fP \fB?objVar?\fP
\&\fRReturns the parent node.
.TP
\&\fB\fBchildNodes\fP
\&\fRReturns a list of direct children node objects.
.TP
\&\fB\fBchildNodesLive\fP
\&\fRReturns a "live" nodeList object of the child nodes of
the node in the sense of the DOM recommendation. This nodeList object is
"live" in the sense that, for instance, changes to the children of
the node object that it was created from are immediately reflected in the nodes
returned by the NodeList accessors; it is not a static snapshot of the content
of the node. The both accessors know by the nodeList object are "item
<index>", which returns the indexth item in the collection, and
"length", which returns the number of nodes in the list.
.TP
\&\fB\fBfirstChild\fP \fB?objVar?\fP
\&\fRReturns the first child as a node object.
.TP
\&\fB\fBlastChild\fP \fB?objVar?\fP
\&\fRReturns the last child as a node object.
.TP
\&\fB\fBnextSibling\fP  \fB?objVar?\fP
\&\fRReturns the next sibling relativ to the current node as a node
object.
.TP
\&\fB\fBpreviousSibling\fP \fB?objVar?\fP
\&\fRReturns the next sibling relativ to the current node as a node
object.
.TP
\&\fB\fBgetElementsByTagName\fP \fIname\fB
\&\fRReturns a list of all elements in the subtree matching (glob
style) \fIname\fR.
.TP
\&\fB\fBgetElementsByTagNameNS\fP \fIuri\fB \fIlocalname\fB
\&\fRReturns a list of all elements in the subtree
matching (glob style) \fIlocalname\fR and having the given namespace
\&\fIuri\fR.
.TP
\&\fB\fBgetElementById\fP \fIid\fB
\&\fRReturns the node having a id attribute with value
\&\fIid\fR or the emtpy string, if no node has an id attribute with that value.
.TP
\&\fB\fBhasAttribute\fP \fIattributeName\fB
\&\fRReturns 1 if the object node contains an attribute with name
\&\fIattributeName\fR . Otherwise 0 is returned.
.TP
\&\fB\fBgetAttribute\fP \fIattributeName  ?defaultValue?\fB
\&\fRReturns the value of the attribute \fIattributeName\fR. If
attribute is not available \fIdefaultValue\fR is returned.
.TP
\&\fB\fBsetAttribute\fP \fIattributeName newValue  ?attributeName newValue ...?\fB
\&\fRSets the value for one or more attributes. Every
\&\fIattributeName\fR is set to the corresponding \fInewValue\fR. If there
isn't an attribute for one or more of the \fIattributeName\fR this will
create that attribute.


.TP
\&\fB\fBremoveAttribute\fP \fIattributeName\fB
\&\fRRemoves the attribute \fIattributeName\fR.
.TP
\&\fB\fBhasAttributeNS\fP \fIuri\fB \fIlocalName\fB
\&\fRReturns 1 if the object node contains an attribute with the
local name \fIlocalName\fR within the namespace \fIuri\fR.  Otherwise 0 is
................................................................................


        
.CS
$node setAttributeNS "" attri "some Value"
.CE
.PP
XML namespace nodes are not in any namespace. Set them this way:


        
.CS
$node setAttributeNS "" xmlns:myprefix "myNamespaceURI"
$node setAttributeNS "" xmlns "newDefaultNamespace"
.CE
.PP
If your \fIqualifiedName\fR has the prefix "xml" and you give the empty
string as \fIuri\fR, the namespace of the attribute defaults to
"http://www.w3.org/XML/1998/namespace", as the DOM 2 recommendation
requests. With the exceptions of the special prefixes "xmlns" and "xml" you
always must provide a non emtpy \fIuri\fR, if your \fIqualifiedName\fR has a
prefix.

.RE
.TP
\&\fB\fBremoveAttributeNS\fP \fIuri\fB \fIlocalName\fB
\&\fRRemoves the attribute with the local name \fIlocalName\fR within
the namespace \fIuri\fR.
.TP
\&\fB\fBattributes\fP \fB?attributeNamePattern?\fP













\&\fRReturns all attributes matching the \fIattributeNamePattern\fR.
If \fIattributeNamePattern\fR isn't given all attributes are returned as a Tcl
list.

.TP
\&\fB\fBappendChild\fP \fInewChild\fB
\&\fRAppend \fInewChild\fR to the end of the child list of the
node.
.TP
\&\fB\fBinsertBefore\fP \fInewChild\fB  \fIrefChild\fB
\&\fRInsert \fInewChild\fR before the \fIrefChild\fR into the list of
children of node. If \fIrefChild\fR is the empty string, insert
\&\fInewChild\fR at the end of the child nodes list of that node.
.TP
\&\fB\fBreplaceChild\fP \fInewChild\fB  \fIoldChild\fB
\&\fRReplace \fIoldChild\fR with \fInewChild\fR in the list of
children of that node. The \fIoldChild\fR node will be part of the
document fragment list after this operation.
.TP
\&\fB\fBremoveChild\fP \fIchild\fB
\&\fRRemoves \fIchild\fR from the list of children of that node
\&\fIchild\fR will be part of the document fragment list after this
operation. It is not physically deleted.
.TP
\&\fB\fBdelete\fP
\&\fRDeletes the given node and its complete child tree
and frees the complete internal memory. The affected nodes are not accessible
through the document fragment list.
.TP
\&\fB\fBcloneNode\fP \fB?-deep?\fP
................................................................................
Returns the result of applying the XPath query
\&\fIxpathQuery\fR to the subtree. This can be a
string/value, a list of strings, a list of nodes or a list
of attribute name / value pairs. If \fItypeVar\fR is given
the result type name is stored into that variable (empty,
bool, number, string, nodes, attrnodes or mixed).
.PP
The argument \fIxpathQuery\fR has to be a valid XPath
expression. However, there is one exception to that rule. Tcl variable

names can appear in the XPath statement at any position where it is
legal according to the rules of the XPath syntax to put an XPath
variable. The value of the variable is substituted for the variable
name. Ignoring the syntax rules of XPath the Tcl variable name may be
any legal Tcl var name: local variables, global variables, array
entries and so on.











.PP
The option \fI-namespaces\fR expects a tcl list with prefix /
namespace pairs as argument. If this option is not given, then any
namespace prefix within the xpath expression will be first resolved
against the list of prefix / namespace pairs set with the
selectNodesNamespaces method for the document, the node belongs to. If
this fails, then the namespace definitions in scope of the context
node will be used to resolve the prefix. If this option is given, any
namespace prefix within the xpath expression will be first resolved
against that given list (and ignoring the document global prefix /
namespace list). If the list bind the same prefix to different
namespaces, then the first binding will win.  If this fails, then the
namespace definitions in scope of the context node will be used to
resolve the prefix, as usual.
.PP
If the \fI-cache\fR option is used with a true value, then the
\&\fIxpathQuery\fR will be looked up in a document specific cache. If the query
is found, then the stored pre-compiled query will be used. If the
query isn't found, it will be pre-compiled and stored in the cache,
for use in further calls. Please notice, that the \fIxpathQuery\fR as given as
string is used as key for the cache. This means, that equal XPath
expressions, which differ only in white space are treated as
different cache entries. Special care is needed, if the XPath
expression includes namespace prefixes. During pre-compilation, the
prefixes will be resolved first to the prefix / namespace pairs of
the \fI-namespaces\fR option, if given, and to the namespaces
in scope of the context node at pre-compilation time. If the XPath
is found in the cache, neither the \fI-namespaces\fR option nor
the namespaces in scope of the context node will be taken in
account but the already resolved (stored) namespaces will be used
for the query.


.PP
Examples:

          
.CS
set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
foreach paragraph $paragraphNodes {
................................................................................
set doc [dom parse {<doc xmlns="http://www.defaultnamespace.org"><child/></doc>}]
set root [$doc documentElement]
set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]
.CE
.RE
.TP
\&\fB\fBgetLine\fP
\&\fRReturns the line number of that node in the orignal parsed
XML.
.TP
\&\fB\fBgetColumn\fP
\&\fRReturns the column number of that node in the orignal parsed
XML.
.TP
\&\fB\fBasList\fP
\&\fRReturns the DOM substree starting form the current node as a
nested Tcl list.
.TP
\&\fB\fBasXML\fP \fB?-indent none/1..8?\fP \fB?-channel channelId?\fP \fB?-escapeNonASCII?\fP\fB?-escapeAllQuot?\fP



\&\fRReturns the DOM substree starting from the current node
as the root node of the result as an (optional indented) XML string or
sends the output directly to the given channelId. If the option


\&\fI-escapeNonASCII\fR is given, every non 7 bit ASCII character in

attribute values or element PCDATA content will be escaped as
character reference in decimal representation. If the option














\&\fI-escapeAllQuot\fR is given, quotation marks will be escaped with
&quot; even in text content of elements.
















.TP
\&\fB\fBasHTML\fP \fB?-channel channelId?\fP \fB?-escapeNonASCII?\fP  \fB?-htmlEntities?\fP
\&\fRReturns the DOM substree starting from the current node as the
root node of the result serialized acording to HTML rules (HTML elements are
recognized regardless of case, without end tags for emtpy HTML elements etc.),
as string or sends the output directly to the given channelId. If the option
\&\fI-escapeNonASCII\fR is given, every non 7 bit ASCII character in attribute
values or element PCDATA content will be escaped as character reference in
decimal representation. If the option \fI-htmlEntities\fR is given, a
character is outputed using a HTML 4.01 character entity reference, if one is
defined for it.
.TP
\&\fB\fBasText\fP
\&\fRFor ELEMENT_NODEs, the asText method outputs
the string-value of every text node descendant of node in document
order without any escaping. For every other node type, this method outputs the
the XPath string value of that node.
.TP
\&\fB\fBappendFromList\fP \fIlist\fB
\&\fRParses \fIlist\fR , creates an according DOM subtree and
appends this subtree to the current node.
.TP
\&\fB\fBappendFromScript\fP \fItclScript\fB
\&\fRAppends the nodes created in the \fItclScript\fR by
Tcl functions, which have been built using \fIdom createNodeCmd\fR, to the
given node.
.TP
\&\fB\fBinsertBeforeFromScript\fP \fItclScript\fB \fIrefChild\fB
\&\fRInserts the nodes created in the \fItclScript\fR by
Tcl functions, which have been built using \fIdom createNodeCmd\fR, before the
\&\fIrefChild\fR into to the list of children of node. If \fIrefChild\fR is
the empty string, the new nodes will be appended.
.TP
\&\fB\fBappendXML\fP \fIXMLstring\fB
\&\fRParses \fIXMLstring\fR, creates an according DOM subtree and
appends this subtree to the current node.
.TP
\&\fB\fBsimpleTranslate\fP \fIoutputVar\fB \fIspecifications\fB
\&\fRTranslate the subtree starting at the object node according to
the specifications in \fIspecifications\fR and outputs the result in the
variable \fIoutputVar\fR . The translation is very similar to Cost Simple
mode.
.TP
\&\fB\fBtoXPath\fP
\&\fRReturns an XPath, which exactly addresses the given
node in its document. This XPath is only valid as there are no changes to DOM
tree made later one.

.TP
\&\fB\fBgetBaseURI\fP
\&\fRReturns the baseURI of the node. This method is deprecated in
favor of the \fIbaseURI\fR method.
.TP
\&\fB\fBbaseURI \fI?URI?\fB\fP
\&\fRReturns the present baseURI of the node. If the optional
argument URI is given, sets the base URI of the node and of all of its child
nodes out of the same enitity as node to the given URI.
.TP
\&\fB\fBdisableOutputEscaping\fP \fI?boolean?\fB
\&\fRThis method works only for text nodes; for every other nodes it
returns error. Without the optional argument it returns, if disabling output
escaping is on. The return value 0 means, the characters of the text node will
be escaped, to generate valid XML, if serialized. This is the default for
every parsed or created text node (with the exception of that text nodes in a
result tree of an XSLT transformation, for which disabling output escaping was
requested explicitely in the stylesheet). The return value 1 means, that output
escaping is disabled for this text node. If such a text node is serialized
(with asXML or asHTML), it is literarily written, without escaping of the
special XML characters. If the optional boolean value \fIboolean\fR is given,
the flag is set accordingly. You should not set this flag to 1, until you
really know, what you do.
.TP
\&\fB\fBprecedes\fP \fIrefnode\fB
\&\fRCompares the relative order of the node and \fIrefnode\fR. Both
nodes must be part of the same documents and not out of the fragment list of
the document. Returns true, if node is in document order (in the sense of the
XPath 1.0 recommendation) before \fIrefnode\fR and false otherwise.
.TP
\&\fB\fBnormalize\fP \fI?-forXPath?\fB
\&\fRPuts all Text nodes in the full depth of the sub-tree underneath
this Node into a "normal" form where only structure (e.g., elements,
comments, processing instructions and CDATA
sections) separates Text nodes, i.e., there
are neither adjacent Text nodes nor empty Text nodes. If the option
\&\fI-forXPath\fR is given, all CDATA sections in the nodes are
converted to text nodes, as a first step before the
normalization.
.TP
\&\fB\fBxslt\fP \fB?-parameters parameterList?\fP \fB?-ignoreUndeclaredParameters?\fP \fB?-xsltmessagecmd script?\fP \fIstylesheet\fB \fI?outputVar?\fB
\&\fRApplies an XSLT transformation on the document using the XSLT
\&\fIstylesheet\fR (given as domDoc). Returns a document object containing the
result document of that transformation and stores it in the optional
\&\fIoutputVar\fR.
.RS
.PP
The optional \fI-parameters\fR option sets top level
<xsl:param> to string values. The \fIparameterList\fR has to be a tcl
list consisting of parameter name and value pairs.
.PP
If the option \fI-ignoreUndeclaredParameters\fR is given, then parameter
names in the \fIparameterList\fR given to the \fI-parameters\fR options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised, if the user tries to set a
top-level parameter, which is not declared in the stylesheet.





.PP
The \fI-xsltmessagecmd\fR option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes".





.RE
.TP
\&\fB\fI@attrName\fB
\&\fRReturns the value of the attribute \fIattrName\fR.  Short cut
for \fIgetAttribute\fR.










.PP
Otherwise, if an unknown method name is given, the command with the same
name as the given method within the namespace \fB::dom::domNode\fR is tried to
be executed. This allows quick method additions on Tcl level.
.SH "SEE ALSO"
dom, domDoc
.SH KEYWORDS
XML, DOM, document, node, parsing







|
>
>
>







 







|







|













|










|



|












|
|






|




|
|
|
>
>







 







<
<
<
<
<
<
<
<
<
<
<
<
|
|
<
>







>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
>


|



|




|




|

|







 







|
|
>
|
|
<
|
|
|
>
>
>
>
>
>
>
>
>
>
>










|





|
|
|
|
|
|

|
|
|
|
|
|
|
|
>
>







 







|



|






|
>
>
>
|
|
|
>
>
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
|




|





|
<













|







|




|


|
>





|

|
|


|





|

|

|
|




|
|











|













|
|
>
>
>
>
>





|
|
>
>
>
>
>





>
>
>
>
>
>
>
>
>
>








159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
...
305
306
307
308
309
310
311












312
313

314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
...
420
421
422
423
424
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
...
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567

568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
'\" END man.macros
.TH domNode n "" Tcl ""
.BS
.SH NAME
domNode \- Manipulates an instance of a DOM node object
.SH SYNOPSIS
.nf
$nodeObject \fImethod\fR \fIarg arg ...\fR
.fi
.nf
domNode \fInodeToken\fR \fImethod\fR \fIarg arg ...\fR
.fi
.BE
.SH " DESCRIPTION "
.PP
This command manipulates one particular instance of a DOM node object.
\&\fImethod\fR indicates a specific method of the node class. These methods
should closely conform to the W3C recommendation "Document Object Model
................................................................................
\&\fRReturns the node name of that node object. This is the element
(tag) name for element nodes (type ELEMENT_NODE), the processing-instruction
target for processing-instructions, "#text" for text node,
"#comment" for comment nodes or "#cdata" for cdata section
nodes.
.TP
\&\fB\fBnodeValue\fP \fI?newValue?\fB
\&\fRReturns the value of that node object. This is the text or
the data for element nodes of type TEXT_NODE, COMMENT_NODE,
PROCESSING_INSTRUCTION_NODE or CDATA_SECTION_NODE). Otherwise it is empty. If
the node is a TEXT_NODE, COMMENT_NODE or PROCESSING_INSTRUCTION_NODE and the
optional argument \fInewValue\fR is given, the node is set to that
value.
.TP
\&\fB\fBhasChildNodes\fP
\&\fRReturns 1 if the node has children. Otherwise 0 is returned.
.TP
\&\fB\fBparentNode\fP \fB?objVar?\fP
\&\fRReturns the parent node.
.TP
\&\fB\fBchildNodes\fP
\&\fRReturns a list of direct children node objects.
.TP
\&\fB\fBchildNodesLive\fP
\&\fRReturns a "live" nodeList object of the child nodes of
the node in the sense of the DOM recommendation. This nodeList object is
"live" in the sense that, for instance, changes to the children of
the node object that it was created from are immediately reflected in the nodes
returned by the NodeList accessors; it is not a static snapshot of the content
of the node. The two accessors known by the nodeList object are "item
<index>", which returns the indexth item in the collection, and
"length", which returns the number of nodes in the list.
.TP
\&\fB\fBfirstChild\fP \fB?objVar?\fP
\&\fRReturns the first child as a node object.
.TP
\&\fB\fBlastChild\fP \fB?objVar?\fP
\&\fRReturns the last child as a node object.
.TP
\&\fB\fBnextSibling\fP  \fB?objVar?\fP
\&\fRReturns the next sibling relative to the current node as a node
object.
.TP
\&\fB\fBpreviousSibling\fP \fB?objVar?\fP
\&\fRReturns the next sibling relative to the current node as a node
object.
.TP
\&\fB\fBgetElementsByTagName\fP \fIname\fB
\&\fRReturns a list of all elements in the subtree matching (glob
style) \fIname\fR.
.TP
\&\fB\fBgetElementsByTagNameNS\fP \fIuri\fB \fIlocalname\fB
\&\fRReturns a list of all elements in the subtree
matching (glob style) \fIlocalname\fR and having the given namespace
\&\fIuri\fR.
.TP
\&\fB\fBgetElementById\fP \fIid\fB
\&\fRReturns the node having an id attribute with value
\&\fIid\fR or the empty string if no node has an id attribute with that value.
.TP
\&\fB\fBhasAttribute\fP \fIattributeName\fB
\&\fRReturns 1 if the object node contains an attribute with name
\&\fIattributeName\fR . Otherwise 0 is returned.
.TP
\&\fB\fBgetAttribute\fP \fIattributeName  ?defaultValue?\fB
\&\fRReturns the value of the attribute \fIattributeName\fR. If the
attribute is not available \fIdefaultValue\fR is returned.
.TP
\&\fB\fBsetAttribute\fP \fIattributeName newValue  ?attributeName newValue ...?\fB
\&\fRSets the value for one or more attributes. Every
\&\fIattributeName\fR is set to the corresponding
\&\fInewValue\fR. If there isn't an attribute for one or more
of the \fIattributeName\fR, this will create that attribute.
It is not recommended to set attributes that look like xml
namespace declarations.
.TP
\&\fB\fBremoveAttribute\fP \fIattributeName\fB
\&\fRRemoves the attribute \fIattributeName\fR.
.TP
\&\fB\fBhasAttributeNS\fP \fIuri\fB \fIlocalName\fB
\&\fRReturns 1 if the object node contains an attribute with the
local name \fIlocalName\fR within the namespace \fIuri\fR.  Otherwise 0 is
................................................................................


        
.CS
$node setAttributeNS "" attri "some Value"
.CE
.PP












With the exceptions of the special prefixes "xmlns" and "xml" you
always must provide a non empty \fIuri\fR, if your \fIqualifiedName\fR has a

prefix. It is not recommended to set xml namespace declarations. The effects are complicated and not always obvious up to resulting a not well-formed serializations after further processing.
.RE
.TP
\&\fB\fBremoveAttributeNS\fP \fIuri\fB \fIlocalName\fB
\&\fRRemoves the attribute with the local name \fIlocalName\fR within
the namespace \fIuri\fR.
.TP
\&\fB\fBattributes\fP \fB?attributeNamePattern?\fP
\&\fRReturns information about the attriubtes matching the
\&\fIattributeNamePattern\fR. If \fIattributeNamePattern\fR
isn't given, information about all attributes are returned.
The return value is a Tcl list, the elements just the
attriubute name in case of non namespaced attriubtes and three
element sublists for namespaced attributes. n case of an
"ordinary" namespaced attribute, the sublist elements are
{<localname> <prefix> <namespace_uri>}. In the special case of
an xml namespace declaration it is {<the prefix defined>
<localname> ""}.
.TP
\&\fB\fBattributeNames\fP \fB?attributeNamePattern?\fP
\&\fRReturns a flat list of all attributes names (as found in
the XML source) matching the \fIattributeNamePattern\fR. If
\&\fIattributeNamePattern\fR isn't given, all attribute names

are returned as a Tcl list.
.TP
\&\fB\fBappendChild\fP \fInewChild\fB
\&\fRAppends \fInewChild\fR to the end of the child list of the
node.
.TP
\&\fB\fBinsertBefore\fP \fInewChild\fB  \fIrefChild\fB
\&\fRInserts \fInewChild\fR before the \fIrefChild\fR into the list of
children of node. If \fIrefChild\fR is the empty string, insert
\&\fInewChild\fR at the end of the child nodes list of that node.
.TP
\&\fB\fBreplaceChild\fP \fInewChild\fB  \fIoldChild\fB
\&\fRReplaces \fIoldChild\fR with \fInewChild\fR in the list of
children of that node. The \fIoldChild\fR node will be part of the
document fragment list after this operation.
.TP
\&\fB\fBremoveChild\fP \fIchild\fB
\&\fRRemoves \fIchild\fR from the list of children of that node.
\&\fIchild\fR will be part of the document fragment list after this
operation.
.TP
\&\fB\fBdelete\fP
\&\fRDeletes the given node and its complete child tree
and frees the complete internal memory. The affected nodes are not accessible
through the document fragment list.
.TP
\&\fB\fBcloneNode\fP \fB?-deep?\fP
................................................................................
Returns the result of applying the XPath query
\&\fIxpathQuery\fR to the subtree. This can be a
string/value, a list of strings, a list of nodes or a list
of attribute name / value pairs. If \fItypeVar\fR is given
the result type name is stored into that variable (empty,
bool, number, string, nodes, attrnodes or mixed).
.PP
The argument \fIxpathQuery\fR has to be a valid XPath expression.
However there are a few exceptions to that rule. Tcl variable
references (in the usual tcl syntax: $varname) may appear in the XPath
statement at any position where it is legal according to the rules of
the XPath syntax to put an XPath variable. Ignoring the syntax rules of

XPath the Tcl variable name may be any legal Tcl var name: local
variables, global variables, array entries and so on. The value will
always be seen as string literal by the xpath engine. Cast the value
explicitly with the according xpath functions (number(), boolean()) to
another data type, if needed.
.PP
Similar to the way described above to inject literals in a secure
way into the XPath expression using tcl variable references there is a
syntax to inject element names from tcl variables. At every place
where the XPath syntax allows a node test there could be a tcl
variable reference (in any form), just the leading $ replaced with %.
This allows one to select nodes with 'strange' (invalid, according to the
appropriate XML production rule) node names which may be needed in
case of working with JSON data.
.PP
The option \fI-namespaces\fR expects a tcl list with prefix /
namespace pairs as argument. If this option is not given, then any
namespace prefix within the xpath expression will be first resolved
against the list of prefix / namespace pairs set with the
selectNodesNamespaces method for the document, the node belongs to. If
this fails, then the namespace definitions in scope of the context
node will be used to resolve the prefix. If this option is given, any
namespace prefix within the xpath expression will be first resolved
against that given list (and ignoring the document global prefix /
namespace list). If the list binds the same prefix to different
namespaces, then the first binding will win.  If this fails, then the
namespace definitions in scope of the context node will be used to
resolve the prefix, as usual.
.PP
If the \fI-cache\fR option is used with a true value, then the
\&\fIxpathQuery\fR will be looked up in a document specific cache. If
the query is found, then the stored pre-compiled query will be used.
If the query isn't found, it will be compiled and stored in the cache,
for use in further calls. Please note that the \fIxpathQuery\fR
given as string is used as key for the cache. This means, that equal
XPath expressions, which differ only in white space are treated as
different cache entries. Special care is needed, if the XPath
expression includes namespace prefixes or references to tcl variables.
Both namespace prefixes and tcl variable references will be resolved
according to the XML prefix namespace mappings and tcl variable values
at expression compilation time. If the same XPath expression is used
later on in a context with other XML prefix namespace mappings or
values of the used tcl variables, make sure to first remove the
compiled expression from the cache with the help of the
\&\fBdeleteXPathCache\fP method, to force a recompilation.
Without using the \fI-cache\fR option such consideration is never
needed.
.PP
Examples:

          
.CS
set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
foreach paragraph $paragraphNodes {
................................................................................
set doc [dom parse {<doc xmlns="http://www.defaultnamespace.org"><child/></doc>}]
set root [$doc documentElement]
set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]
.CE
.RE
.TP
\&\fB\fBgetLine\fP
\&\fRReturns the line number of that node in the originally parsed
XML.
.TP
\&\fB\fBgetColumn\fP
\&\fRReturns the column number of that node in the originally parsed
XML.
.TP
\&\fB\fBasList\fP
\&\fRReturns the DOM substree starting form the current node as a
nested Tcl list.
.TP
\&\fB\fBasXML\fP \fB?-indent none/1..8?\fP \fB?-channel channelId?\fP \fB?-escapeNonASCII?\fP \fB-xmlDeclaration <boolean>?\fP \fB-encString <string>\fP \fB?-escapeAllQuot?\fP \fB?-indentAttrs?\fP \fB?-nogtescape?\fP \fB?-noEmptyElementTag?\fP
\&\fR
.RS
.PP
Returns the DOM substree starting from the current
node as the root node of the result as an (optional indented)
XML string or sends the output directly to the given
channelId.
.PP
If the option \fI-escapeNonASCII\fR is given,
every non 7 bit ASCII character in attribute values or element
PCDATA content will be escaped as character reference in
decimal representation.
.PP
The flag \fI-xmlDeclaration\fR determines whether there
will be an XML Declaration and a newline emitted before
anything else. The default is, to do not. If this flag is
given with a true argument then
.PP
\&\fI-encString\fR sets the encoding value in the XML
Declaration. Otherwise, this option is ignored. Please note,
that this option just enhance the string representation of the
generated XML Declaration with an encoding information string,
nothing more. It's up to the user to handle encoding in case
of writing to a channel or reparsing.
.PP
If the option \fI-escapeAllQuot\fR is given,
quotation marks will be escaped with &quot; even in text
content of elements.
.PP
If the option \fI-indentAttrs\fR is
given, then attributes will each be separated with newlines
and indented to the same level as the parent node plus the
value given as argument to \fI-indentAttrs\fR (0..8).
.PP
If the option \fI-nogtescape\fR is given then the
character '>' won't get escaped in attribute values and text
content of elements. The default is to escape this
character.
.PP
If the option \fI-noEmptyElementTag\fR is given then no
empty tag syntax will be used. Instead, if an element has
empty content it will be serialized with an element start tag
and an immediately following element end tag.
.RE
.TP
\&\fB\fBasHTML\fP \fB?-channel channelId?\fP \fB?-escapeNonASCII?\fP  \fB?-htmlEntities?\fP
\&\fRReturns the DOM substree starting from the current node as the
root node of the result serialized according to HTML rules (HTML elements are
recognized regardless of case, without end tags for empty HTML elements etc.),
as string or sends the output directly to the given channelId. If the option
\&\fI-escapeNonASCII\fR is given, every non 7 bit ASCII character in attribute
values or element PCDATA content will be escaped as character reference in
decimal representation. If the option \fI-htmlEntities\fR is given, a
character is written using its HTML 4.01 character entity reference, if one is
defined for it.
.TP
\&\fB\fBasText\fP
\&\fRFor ELEMENT_NODEs, the asText method outputs
the string-value of every text node descendant of node in document
order without any escaping. For every other node type, this method outputs the XPath string value of that node.

.TP
\&\fB\fBappendFromList\fP \fIlist\fB
\&\fRParses \fIlist\fR , creates an according DOM subtree and
appends this subtree to the current node.
.TP
\&\fB\fBappendFromScript\fP \fItclScript\fB
\&\fRAppends the nodes created in the \fItclScript\fR by
Tcl functions, which have been built using \fIdom createNodeCmd\fR, to the
given node.
.TP
\&\fB\fBinsertBeforeFromScript\fP \fItclScript\fB \fIrefChild\fB
\&\fRInserts the nodes created in the \fItclScript\fR by
Tcl functions, which have been built using \fIdom createNodeCmd\fR, before the
\&\fIrefChild\fR into the list of children of node. If \fIrefChild\fR is
the empty string, the new nodes will be appended.
.TP
\&\fB\fBappendXML\fP \fIXMLstring\fB
\&\fRParses \fIXMLstring\fR, creates an according DOM subtree and
appends this subtree to the current node.
.TP
\&\fB\fBsimpleTranslate\fP \fIoutputVar\fB \fIspecifications\fB
\&\fRTranslates the subtree starting at the object node according to
the specifications in \fIspecifications\fR and outputs the result in the
variable \fIoutputVar\fR . The translation is very similar to Cost Simple
mode.
.TP
\&\fB\fBtoXPath\fP \fI?-legacy?\fB
\&\fRReturns an XPath, which exactly addresses the given
node in its document. This XPath is only valid as there are no changes to DOM
tree made later one. With the -legacy option, other XPath expressions
are returned, which doesn't work in all cases.
.TP
\&\fB\fBgetBaseURI\fP
\&\fRReturns the baseURI of the node. This method is deprecated in
favor of the \fIbaseURI\fR method.
.TP
\&\fB\fBbaseURI\fP \fI?URI?\fB
\&\fRReturns the present baseURI of the node. If the optional
argument URI is given, it sets the base URI of the node and of all of its child
nodes out of the same entity as node to the given URI.
.TP
\&\fB\fBdisableOutputEscaping\fP \fI?boolean?\fB
\&\fRThis method works only for text nodes; for every other node it
returns error. Without the optional argument it returns, if disabling output
escaping is on. The return value 0 means, the characters of the text node will
be escaped, to generate valid XML, if serialized. This is the default for
every parsed or created text node (with the exception of that text nodes in a
result tree of an XSLT transformation, for which disabling output escaping was
requested explicitly in the stylesheet). The return value 1 means, that output
escaping is disabled for this text node. If such a text node is serialized
(with asXML or asHTML), it is literally written, without escaping of the
special XML characters. If the optional boolean value \fIboolean\fR is given,
the flag is set accordingly. You should not set this flag to 1 until you
really know what you do.
.TP
\&\fB\fBprecedes\fP \fIrefnode\fB
\&\fRCompares the relative order of the node and \fIrefnode\fR. Both
nodes must be part of the same documents and not out of the fragment list of
the document. Returns true if node is in document order (in the sense of the
XPath 1.0 recommendation) before \fIrefnode\fR, and false otherwise.
.TP
\&\fB\fBnormalize\fP \fI?-forXPath?\fB
\&\fRPuts all Text nodes in the full depth of the sub-tree underneath
this Node into a "normal" form where only structure (e.g., elements,
comments, processing instructions and CDATA
sections) separates Text nodes, i.e., there
are neither adjacent Text nodes nor empty Text nodes. If the option
\&\fI-forXPath\fR is given, all CDATA sections in the nodes are
converted to text nodes, as a first step before the
normalization.
.TP
\&\fB\fBxslt\fP \fB?-parameters parameterList?\fP \fB?-ignoreUndeclaredParameters?\fP \fB?-maxApplyDepth int?\fP \fB?-xsltmessagecmd script?\fP \fIstylesheet\fB \fI?outputVar?\fB
\&\fRApplies an XSLT transformation on the document using the XSLT
\&\fIstylesheet\fR (given as domDoc). Returns a document object containing the
result document of that transformation and stores it in the optional
\&\fIoutputVar\fR.
.RS
.PP
The optional \fI-parameters\fR option sets top level
<xsl:param> to string values. The \fIparameterList\fR has to be a tcl
list consisting of parameter name and value pairs.
.PP
If the option \fI-ignoreUndeclaredParameters\fR is given, then parameter
names in the \fIparameterList\fR given to the \fI-parameters\fR options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised if the user tries to set a
top-level parameter which is not declared in the stylesheet.
.PP
The option \fI-maxApplyDepth\fR expects a positive integer as
argument. By default, the xslt engine allows xslt templates to nest up
to 3000 levels (and raises error if they nest deeper). This limit can
be set by the \fI-maxApplyDepth\fR option.
.PP
The \fI-xsltmessagecmd\fR option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates whether the
xsl:message has an attribute "terminate" with the value "yes". If the
called script returns anything else then TCL_OK then the xslt
transformation will be aborted, returning error. If the called script
returns -code break the error message is empty, otherwise the result
code is reported. In case of terminated transformation the outputVar,
if given, is set to the empty string.
.RE
.TP
\&\fB\fI@attrName\fB
\&\fRReturns the value of the attribute \fIattrName\fR.  Short cut
for \fIgetAttribute\fR.
.TP
\&\fB\fBjsonType\fP \fI?OBJECT|ARRAY|NONE)|(STRING|NUMBER|TRUE|FALSE|NULL|NONE)?\fB
\&\fROnly element and text nodes may have a JSON type and
only this types of nodes support the \fIjsonType\fR method;
the other node types return error if called with this method.
Returns the jsonType of the node. If the optional argument is
given, the JSON type of the node is set to the given type and
returned. Valid type arguments for element nodes are OBJECT,
ARRAY and NONE. Valid type arguments for text nodes are
STRING, NUMBER, TRUE, FALSE, NULL and NONE.
.PP
Otherwise, if an unknown method name is given, the command with the same
name as the given method within the namespace \fB::dom::domNode\fR is tried to
be executed. This allows quick method additions on Tcl level.
.SH "SEE ALSO"
dom, domDoc
.SH KEYWORDS
XML, DOM, document, node, parsing

Changes to doc/domNode.xml.

11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
..
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
..
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156


157
158
159
160
161
162
163
...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

210
211
212
213
214
215
216
217
218
219
















220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
...
350
351
352
353
354
355
356
357
358

359
360
361
362
363
364











365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395


396
397
398
399
400
401
402
...
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434


435

436
437














438
439
















440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
...
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504

505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
...
553
554
555
556
557
558
559

560
561
562
563
564
565
566
567
568
569
570
571
572
573
574





575
576
577
578
579
580
581





582
583
584
585
586
587
588
589













590
591

592
593
594
595
596
597
598

 See the file "LICENSE" for information on usage and redistribution
 of this file, and for a DISCLAIMER OF ALL WARRANTIES.

-->

  <synopsis>
    <syntax> $nodeObject <m>method</m>  <m>arg arg ...</m></syntax>

  </synopsis>
  <section>
    <title> DESCRIPTION </title>

    <p>This command manipulates one particular instance of a DOM node object.
<m>method</m> indicates a specific method of the node class. These methods
should closely conform to the W3C recommendation &quot;Document Object Model
................................................................................
target for processing-instructions, &quot;#text&quot; for text node,
&quot;#comment&quot; for comment nodes or &quot;#cdata&quot; for cdata section
nodes.</desc>
      </commanddef>

      <commanddef>
        <command><method>nodeValue</method> <m>?newValue?</m></command>
        <desc>Returns the value of that node object. This is the the text or
the data for element nodes of type TEXT_NODE, COMMENT_NODE,
PROCESSING_INSTRUCTION_NODE or CDATA_SECTION_NODE). Otherwise it is empty. If
the node is a TEXT_NODE, COMMENT_NODE or PROCESSING_INSTRUCTION_NODE and the
optional argument <m>newValue</m> is given, the node is set to that
value.</desc>

      </commanddef>

      <commanddef>
        <command><method>hasChildNodes</method></command>
        <desc>Returns 1 if the has children. Otherwise 0 is returned.</desc>
      </commanddef>

      <commanddef>
        <command><method>parentNode</method> <variable>?objVar?</variable></command>
        <desc>Returns the parent node.</desc>
      </commanddef>

................................................................................
      <commanddef>
        <command><method>childNodesLive</method></command>
        <desc>Returns a &quot;live&quot; nodeList object of the child nodes of
the node in the sense of the DOM recommendation. This nodeList object is
&quot;live&quot; in the sense that, for instance, changes to the children of
the node object that it was created from are immediately reflected in the nodes
returned by the NodeList accessors; it is not a static snapshot of the content
of the node. The both accessors know by the nodeList object are &quot;item
&lt;index&gt;&quot;, which returns the indexth item in the collection, and
&quot;length&quot;, which returns the number of nodes in the list.</desc>
      </commanddef>

      <commanddef>
        <command><method>firstChild</method> <variable>?objVar?</variable></command>
        <desc>Returns the first child as a node object.</desc>
................................................................................
      <commanddef>
        <command><method>lastChild</method> <variable>?objVar?</variable></command>
        <desc>Returns the last child as a node object.</desc>
      </commanddef>
      
      <commanddef>
        <command><method>nextSibling</method>  <variable>?objVar?</variable></command>
        <desc>Returns the next sibling relativ to the current node as a node
object.</desc>
      </commanddef>

      <commanddef>
        <command><method>previousSibling</method> <variable>?objVar?</variable></command>
        <desc>Returns the next sibling relativ to the current node as a node
object.</desc>
      </commanddef>

      <commanddef>
        <command><method>getElementsByTagName</method> <m>name</m></command>
        <desc>Returns a list of all elements in the subtree matching (glob
style) <m>name</m>.</desc>
................................................................................
        <desc>Returns a list of all elements in the subtree
matching (glob style) <m>localname</m> and having the given namespace
<m>uri</m>.</desc>
      </commanddef>

      <commanddef>
        <command><method>getElementById</method> <m>id</m></command>
        <desc>Returns the node having a id attribute with value
<m>id</m> or the emtpy string, if no node has an id attribute with that value.</desc>
      </commanddef>

      <commanddef>
        <command><method>hasAttribute</method> <m>attributeName</m></command>
        <desc>Returns 1 if the object node contains an attribute with name
<m>attributeName</m> . Otherwise 0 is returned.</desc>
      </commanddef>

      <commanddef>
        <command><method>getAttribute</method> <m>attributeName  ?defaultValue?</m></command>
        <desc>Returns the value of the attribute <m>attributeName</m>. If
attribute is not available <m>defaultValue</m> is returned.</desc>
      </commanddef>

      <commanddef>
        <command><method>setAttribute</method> <m>attributeName newValue 
?attributeName newValue ...?</m></command>
        <desc>Sets the value for one or more attributes. Every
<m>attributeName</m> is set to the corresponding <m>newValue</m>. If there
isn't an attribute for one or more of the <m>attributeName</m> this will
create that attribute.</desc>



      </commanddef>

      <commanddef>
        <command><method>removeAttribute</method> <m>attributeName</m></command>
        <desc>Removes the attribute <m>attributeName</m>.</desc>
      </commanddef>

................................................................................
        <example>$node setAttributeNS "http://some.uri.com/wow" prefix:attr1 attrValue</example>

<p>If the uri is the empty string and the attribute name hasn't a prefix, this
method has the same effect as the method <b>setAttribute</b>.</p>

        <example>$node setAttributeNS "" attri "some Value"</example>

<p>XML namespace nodes are not in any namespace. Set them this way:</p>

        <example>$node setAttributeNS "" xmlns:myprefix "myNamespaceURI"
$node setAttributeNS "" xmlns "newDefaultNamespace"</example>

<p>If your <m>qualifiedName</m> has the prefix "xml" and you give the empty
string as <m>uri</m>, the namespace of the attribute defaults to
"http://www.w3.org/XML/1998/namespace", as the DOM 2 recommendation
requests. With the exceptions of the special prefixes "xmlns" and "xml" you
always must provide a non emtpy <m>uri</m>, if your <m>qualifiedName</m> has a
prefix.</p>
        </desc>

      </commanddef>

      <commanddef>
        <command><method>removeAttributeNS</method> <m>uri</m> <m>localName</m></command>
        <desc>Removes the attribute with the local name <m>localName</m> within
 the namespace <m>uri</m>.</desc>
      </commanddef>

      <commanddef>
        <command><method>attributes</method> <option>?attributeNamePattern?</option></command>
















        <desc>Returns all attributes matching the <m>attributeNamePattern</m>.
If <m>attributeNamePattern</m> isn't given all attributes are returned as a Tcl
list.</desc>
      </commanddef>

      <commanddef>
        <command><method>appendChild</method> <m>newChild</m></command>
        <desc>Append <m>newChild</m> to the end of the child list of the
node.</desc>
      </commanddef>

      <commanddef>
        <command><method>insertBefore</method> <m>newChild</m>  <m>refChild</m></command>
        <desc>Insert <m>newChild</m> before the <m>refChild</m> into the list of
children of node. If <m>refChild</m> is the empty string, insert
<m>newChild</m> at the end of the child nodes list of that node.</desc>
      </commanddef>

      <commanddef>
        <command><method>replaceChild</method> <m>newChild</m>  <m>oldChild</m></command>
        <desc>Replace <m>oldChild</m> with <m>newChild</m> in the list of
children of that node. The <m>oldChild</m> node will be part of the
document fragment list after this operation.</desc>
      </commanddef>

      <commanddef>
        <command><method>removeChild</method> <m>child</m></command>
        <desc>Removes <m>child</m> from the list of children of that node
<m>child</m> will be part of the document fragment list after this
operation. It is not physically deleted.</desc>
      </commanddef>

      <commanddef>
        <command><method>delete</method></command>
        <desc>Deletes the given node and its complete child tree
and frees the complete internal memory. The affected nodes are not accessible
through the document fragment list.</desc>
................................................................................
          <desc><p>Returns the result of applying the XPath query
<m>xpathQuery</m> to the subtree. This can be a
string/value, a list of strings, a list of nodes or a list
of attribute name / value pairs. If <m>typeVar</m> is given
the result type name is stored into that variable (empty,
bool, number, string, nodes, attrnodes or mixed).</p>

<p>The argument <m>xpathQuery</m> has to be a valid XPath
expression. However, there is one exception to that rule. Tcl variable

names can appear in the XPath statement at any position where it is
legal according to the rules of the XPath syntax to put an XPath
variable. The value of the variable is substituted for the variable
name. Ignoring the syntax rules of XPath the Tcl variable name may be
any legal Tcl var name: local variables, global variables, array
entries and so on.</p>












<p>The option <m>-namespaces</m> expects a tcl list with prefix /
namespace pairs as argument. If this option is not given, then any
namespace prefix within the xpath expression will be first resolved
against the list of prefix / namespace pairs set with the
selectNodesNamespaces method for the document, the node belongs to. If
this fails, then the namespace definitions in scope of the context
node will be used to resolve the prefix. If this option is given, any
namespace prefix within the xpath expression will be first resolved
against that given list (and ignoring the document global prefix /
namespace list). If the list bind the same prefix to different
namespaces, then the first binding will win.  If this fails, then the
namespace definitions in scope of the context node will be used to
resolve the prefix, as usual.</p>

<p>If the <m>-cache</m> option is used with a true value, then the
<m>xpathQuery</m> will be looked up in a document specific cache. If the query
is found, then the stored pre-compiled query will be used. If the
query isn't found, it will be pre-compiled and stored in the cache,
for use in further calls. Please notice, that the <m>xpathQuery</m> as given as
string is used as key for the cache. This means, that equal XPath
expressions, which differ only in white space are treated as
different cache entries. Special care is needed, if the XPath
expression includes namespace prefixes. During pre-compilation, the
prefixes will be resolved first to the prefix / namespace pairs of
the <m>-namespaces</m> option, if given, and to the namespaces
in scope of the context node at pre-compilation time. If the XPath
is found in the cache, neither the <m>-namespaces</m> option nor
the namespaces in scope of the context node will be taken in
account but the already resolved (stored) namespaces will be used
for the query.</p>



<p>Examples:</p>
          <example>set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
foreach paragraph $paragraphNodes {
    lappend  values [$paragraph selectNodes attribute::type]
}

................................................................................
set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]</example>

          </desc>
      </commanddef>

      <commanddef>
        <command><method>getLine</method></command>
        <desc>Returns the line number of that node in the orignal parsed
XML.</desc>
      </commanddef>
      
      <commanddef>
        <command><method>getColumn</method></command>
        <desc>Returns the column number of that node in the orignal parsed
XML.</desc>
      </commanddef>

      <commanddef>
        <command><method>asList</method></command>
        <desc>Returns the DOM substree starting form the current node as a
nested Tcl list.</desc>
      </commanddef>

      <commanddef>
        <command><method>asXML</method> <option>?-indent none/1..8?</option>
<option>?-channel channelId?</option> <option>?-escapeNonASCII?</option><option>?-escapeAllQuot?</option></command>

        <desc>Returns the DOM substree starting from the current node
as the root node of the result as an (optional indented) XML string or
sends the output directly to the given channelId. If the option


<m>-escapeNonASCII</m> is given, every non 7 bit ASCII character in

attribute values or element PCDATA content will be escaped as
character reference in decimal representation. If the option














<m>-escapeAllQuot</m> is given, quotation marks will be escaped with
&amp;quot; even in text content of elements.</desc>
















      </commanddef>

      <commanddef>
        <command><method>asHTML</method> <option>?-channel channelId?</option>
<option>?-escapeNonASCII?</option>  <option>?-htmlEntities?</option></command>
        <desc>Returns the DOM substree starting from the current node as the
root node of the result serialized acording to HTML rules (HTML elements are
recognized regardless of case, without end tags for emtpy HTML elements etc.),
as string or sends the output directly to the given channelId. If the option
<m>-escapeNonASCII</m> is given, every non 7 bit ASCII character in attribute
values or element PCDATA content will be escaped as character reference in
decimal representation. If the option <m>-htmlEntities</m> is given, a
character is outputed using a HTML 4.01 character entity reference, if one is
defined for it.</desc>
      </commanddef>

      <commanddef>
        <command><method>asText</method></command>
          <desc>For ELEMENT_NODEs, the asText method outputs 
the string-value of every text node descendant of node in document
order without any escaping. For every other node type, this method outputs the
the XPath string value of that node.</desc>
      </commanddef>

      <commanddef>
        <command><method>appendFromList</method> <m>list</m></command>
        <desc>Parses <m>list</m> , creates an according DOM subtree and
appends this subtree to the current node.</desc>
      </commanddef>
................................................................................
given node.</desc>
      </commanddef>

      <commanddef>
        <command><method>insertBeforeFromScript</method> <m>tclScript</m> <m>refChild</m></command>
        <desc>Inserts the nodes created in the <m>tclScript</m> by
Tcl functions, which have been built using <m>dom createNodeCmd</m>, before the
<m>refChild</m> into to the list of children of node. If <m>refChild</m> is
the empty string, the new nodes will be appended.</desc>
      </commanddef>

      <commanddef>
        <command><method>appendXML</method> <m>XMLstring</m></command>
        <desc>Parses <m>XMLstring</m>, creates an according DOM subtree and
appends this subtree to the current node.</desc>
      </commanddef>

      <commanddef>
        <command><method>simpleTranslate</method> <m>outputVar</m>
<m>specifications</m></command>
        <desc>Translate the subtree starting at the object node according to
the specifications in <m>specifications</m> and outputs the result in the
variable <m>outputVar</m> . The translation is very similar to Cost Simple
mode.</desc>
      </commanddef>

      <commanddef>
        <command><method>toXPath</method></command>
        <desc>Returns an XPath, which exactly addresses the given
node in its document. This XPath is only valid as there are no changes to DOM
tree made later one.</desc>

      </commanddef>

      <commanddef>
        <command><method>getBaseURI</method></command>
        <desc>Returns the baseURI of the node. This method is deprecated in
          favor of the <m>baseURI</m> method.</desc>
      </commanddef>

      <commanddef>
        <command><method>baseURI <m>?URI?</m></method></command>
        <desc>Returns the present baseURI of the node. If the optional 
argument URI is given, sets the base URI of the node and of all of its child
nodes out of the same enitity as node to the given URI.</desc>
      </commanddef>

      <commanddef>
        <command><method>disableOutputEscaping</method> <m>?boolean?</m></command>
        <desc>This method works only for text nodes; for every other nodes it
returns error. Without the optional argument it returns, if disabling output
escaping is on. The return value 0 means, the characters of the text node will
be escaped, to generate valid XML, if serialized. This is the default for
every parsed or created text node (with the exception of that text nodes in a
result tree of an XSLT transformation, for which disabling output escaping was
requested explicitely in the stylesheet). The return value 1 means, that output
escaping is disabled for this text node. If such a text node is serialized
(with asXML or asHTML), it is literarily written, without escaping of the
special XML characters. If the optional boolean value <m>boolean</m> is given,
the flag is set accordingly. You should not set this flag to 1, until you
really know, what you do.</desc>
      </commanddef>

      <commanddef>
        <command><method>precedes</method> <m>refnode</m></command>
        <desc>Compares the relative order of the node and <m>refnode</m>. Both
nodes must be part of the same documents and not out of the fragment list of
the document. Returns true, if node is in document order (in the sense of the
XPath 1.0 recommendation) before <m>refnode</m> and false otherwise.</desc>
      </commanddef>


      <commanddef>
        <command><method>normalize</method> <m>?-forXPath?</m></command>
        <desc>Puts all Text nodes in the full depth of the sub-tree underneath
this Node into a "normal" form where only structure (e.g., elements,
................................................................................
converted to text nodes, as a first step before the
normalization. </desc>
      </commanddef>

      <commanddef>
        <command><method>xslt</method> <option>?-parameters
parameterList?</option> <option>?-ignoreUndeclaredParameters?</option>

<option>?-xsltmessagecmd script?</option> <m>stylesheet</m> <m>?outputVar?</m></command>
        <desc>Applies an XSLT transformation on the document using the XSLT
<m>stylesheet</m> (given as domDoc). Returns a document object containing the
result document of that transformation and stores it in the optional
<m>outputVar</m>. 

<p>The optional <m>-parameters</m> option sets top level
&lt;xsl:param&gt; to string values. The <m>parameterList</m> has to be a tcl
list consisting of parameter name and value pairs.</p>

<p>If the option <m>-ignoreUndeclaredParameters</m> is given, then parameter
names in the <m>parameterList</m> given to the <m>-parameters</m> options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised, if the user tries to set a
top-level parameter, which is not declared in the stylesheet.</p>






<p>The <m>-xsltmessagecmd</m> option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates, if the
xsl:message has an attribute "terminate" with the value "yes".</p>





</desc>
      </commanddef>

      <commanddef>
        <command><m>@attrName</m></command>
        <desc>Returns the value of the attribute <m>attrName</m>.  Short cut
for <m>getAttribute</m>.</desc>
      </commanddef>













    </commandlist>


    <p>Otherwise, if an unknown method name is given, the command with the same
name as the given method within the namespace <l>::dom::domNode</l> is tried to
be executed. This allows quick method additions on Tcl level.</p>

  </section>









|
>







 







|










|







 







|







 







|





|







 







|
|










|







|
|
|
<
>
>







 







<
<
<
<
<
<
<
<
|
|
<
<
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|

|


|





|






|






|

|







 







|
|
>
|
|
<
|
|
|
>
>
>
>
>
>
>
>
>
>
>










|





|
|
|
|
|
|

|
|
|
|
|
|
|
|
>
>







 







|





|










|
<
<
|
|
|
>
>
|
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
|




|







|
<







 







|












|






|


|
>









|

|
|




|





|

|

|
|






|
|







 







>













|
|
>
>
>
>
>





|
|
>
>
>
>
>








>
>
>
>
>
>
>
>
>
>
>
>
>


>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
164
165
...
193
194
195
196
197
198
199








200
201


202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
...
359
360
361
362
363
364
365
366
367
368
369
370

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
...
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451


452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
...
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
...
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676

 See the file "LICENSE" for information on usage and redistribution
 of this file, and for a DISCLAIMER OF ALL WARRANTIES.

-->

  <synopsis>
    <syntax>$nodeObject <m>method</m> <m>arg arg ...</m></syntax>
    <syntax>domNode <m>nodeToken</m> <m>method</m> <m>arg arg ...</m></syntax>
  </synopsis>
  <section>
    <title> DESCRIPTION </title>

    <p>This command manipulates one particular instance of a DOM node object.
<m>method</m> indicates a specific method of the node class. These methods
should closely conform to the W3C recommendation &quot;Document Object Model
................................................................................
target for processing-instructions, &quot;#text&quot; for text node,
&quot;#comment&quot; for comment nodes or &quot;#cdata&quot; for cdata section
nodes.</desc>
      </commanddef>

      <commanddef>
        <command><method>nodeValue</method> <m>?newValue?</m></command>
        <desc>Returns the value of that node object. This is the text or
the data for element nodes of type TEXT_NODE, COMMENT_NODE,
PROCESSING_INSTRUCTION_NODE or CDATA_SECTION_NODE). Otherwise it is empty. If
the node is a TEXT_NODE, COMMENT_NODE or PROCESSING_INSTRUCTION_NODE and the
optional argument <m>newValue</m> is given, the node is set to that
value.</desc>

      </commanddef>

      <commanddef>
        <command><method>hasChildNodes</method></command>
        <desc>Returns 1 if the node has children. Otherwise 0 is returned.</desc>
      </commanddef>

      <commanddef>
        <command><method>parentNode</method> <variable>?objVar?</variable></command>
        <desc>Returns the parent node.</desc>
      </commanddef>

................................................................................
      <commanddef>
        <command><method>childNodesLive</method></command>
        <desc>Returns a &quot;live&quot; nodeList object of the child nodes of
the node in the sense of the DOM recommendation. This nodeList object is
&quot;live&quot; in the sense that, for instance, changes to the children of
the node object that it was created from are immediately reflected in the nodes
returned by the NodeList accessors; it is not a static snapshot of the content
of the node. The two accessors known by the nodeList object are &quot;item
&lt;index&gt;&quot;, which returns the indexth item in the collection, and
&quot;length&quot;, which returns the number of nodes in the list.</desc>
      </commanddef>

      <commanddef>
        <command><method>firstChild</method> <variable>?objVar?</variable></command>
        <desc>Returns the first child as a node object.</desc>
................................................................................
      <commanddef>
        <command><method>lastChild</method> <variable>?objVar?</variable></command>
        <desc>Returns the last child as a node object.</desc>
      </commanddef>
      
      <commanddef>
        <command><method>nextSibling</method>  <variable>?objVar?</variable></command>
        <desc>Returns the next sibling relative to the current node as a node
object.</desc>
      </commanddef>

      <commanddef>
        <command><method>previousSibling</method> <variable>?objVar?</variable></command>
        <desc>Returns the next sibling relative to the current node as a node
object.</desc>
      </commanddef>

      <commanddef>
        <command><method>getElementsByTagName</method> <m>name</m></command>
        <desc>Returns a list of all elements in the subtree matching (glob
style) <m>name</m>.</desc>
................................................................................
        <desc>Returns a list of all elements in the subtree
matching (glob style) <m>localname</m> and having the given namespace
<m>uri</m>.</desc>
      </commanddef>

      <commanddef>
        <command><method>getElementById</method> <m>id</m></command>
        <desc>Returns the node having an id attribute with value
<m>id</m> or the empty string if no node has an id attribute with that value.</desc>
      </commanddef>

      <commanddef>
        <command><method>hasAttribute</method> <m>attributeName</m></command>
        <desc>Returns 1 if the object node contains an attribute with name
<m>attributeName</m> . Otherwise 0 is returned.</desc>
      </commanddef>

      <commanddef>
        <command><method>getAttribute</method> <m>attributeName  ?defaultValue?</m></command>
        <desc>Returns the value of the attribute <m>attributeName</m>. If the
attribute is not available <m>defaultValue</m> is returned.</desc>
      </commanddef>

      <commanddef>
        <command><method>setAttribute</method> <m>attributeName newValue 
?attributeName newValue ...?</m></command>
        <desc>Sets the value for one or more attributes. Every
        <m>attributeName</m> is set to the corresponding
        <m>newValue</m>. If there isn't an attribute for one or more
        of the <m>attributeName</m>, this will create that attribute.

        It is not recommended to set attributes that look like xml
        namespace declarations.</desc>
      </commanddef>

      <commanddef>
        <command><method>removeAttribute</method> <m>attributeName</m></command>
        <desc>Removes the attribute <m>attributeName</m>.</desc>
      </commanddef>

................................................................................
        <example>$node setAttributeNS "http://some.uri.com/wow" prefix:attr1 attrValue</example>

<p>If the uri is the empty string and the attribute name hasn't a prefix, this
method has the same effect as the method <b>setAttribute</b>.</p>

        <example>$node setAttributeNS "" attri "some Value"</example>









<p>With the exceptions of the special prefixes "xmlns" and "xml" you
always must provide a non empty <m>uri</m>, if your <m>qualifiedName</m> has a


prefix. It is not recommended to set xml namespace declarations. The effects are complicated and not always obvious up to resulting a not well-formed serializations after further processing.</p></desc>
      </commanddef>

      <commanddef>
        <command><method>removeAttributeNS</method> <m>uri</m> <m>localName</m></command>
        <desc>Removes the attribute with the local name <m>localName</m> within
 the namespace <m>uri</m>.</desc>
      </commanddef>

      <commanddef>
        <command><method>attributes</method> <option>?attributeNamePattern?</option></command>
        <desc>Returns information about the attriubtes matching the
        <m>attributeNamePattern</m>. If <m>attributeNamePattern</m>
        isn't given, information about all attributes are returned.
        The return value is a Tcl list, the elements just the
        attriubute name in case of non namespaced attriubtes and three
        element sublists for namespaced attributes. n case of an
        "ordinary" namespaced attribute, the sublist elements are
        {&lt;localname&gt; &lt;prefix&gt; &lt;namespace_uri&gt;}. In the special case of
        an xml namespace declaration it is {&lt;the prefix defined&gt;
        &lt;localname&gt; ""}.
        </desc>
      </commanddef>

      <commanddef>
        <command><method>attributeNames</method> <option>?attributeNamePattern?</option></command>
        <desc>Returns a flat list of all attributes names (as found in
        the XML source) matching the <m>attributeNamePattern</m>. If
        <m>attributeNamePattern</m> isn't given, all attribute names
        are returned as a Tcl list.</desc>
      </commanddef>
      
      <commanddef>
        <command><method>appendChild</method> <m>newChild</m></command>
        <desc>Appends <m>newChild</m> to the end of the child list of the
node.</desc>
      </commanddef>

      <commanddef>
        <command><method>insertBefore</method> <m>newChild</m>  <m>refChild</m></command>
        <desc>Inserts <m>newChild</m> before the <m>refChild</m> into the list of
children of node. If <m>refChild</m> is the empty string, insert
<m>newChild</m> at the end of the child nodes list of that node.</desc>
      </commanddef>

      <commanddef>
        <command><method>replaceChild</method> <m>newChild</m>  <m>oldChild</m></command>
        <desc>Replaces <m>oldChild</m> with <m>newChild</m> in the list of
children of that node. The <m>oldChild</m> node will be part of the
document fragment list after this operation.</desc>
      </commanddef>

      <commanddef>
        <command><method>removeChild</method> <m>child</m></command>
        <desc>Removes <m>child</m> from the list of children of that node.
<m>child</m> will be part of the document fragment list after this
operation.</desc>
      </commanddef>

      <commanddef>
        <command><method>delete</method></command>
        <desc>Deletes the given node and its complete child tree
and frees the complete internal memory. The affected nodes are not accessible
through the document fragment list.</desc>
................................................................................
          <desc><p>Returns the result of applying the XPath query
<m>xpathQuery</m> to the subtree. This can be a
string/value, a list of strings, a list of nodes or a list
of attribute name / value pairs. If <m>typeVar</m> is given
the result type name is stored into that variable (empty,
bool, number, string, nodes, attrnodes or mixed).</p>

<p>The argument <m>xpathQuery</m> has to be a valid XPath expression.
However there are a few exceptions to that rule. Tcl variable
references (in the usual tcl syntax: $varname) may appear in the XPath
statement at any position where it is legal according to the rules of
the XPath syntax to put an XPath variable. Ignoring the syntax rules of

XPath the Tcl variable name may be any legal Tcl var name: local
variables, global variables, array entries and so on. The value will
always be seen as string literal by the xpath engine. Cast the value
explicitly with the according xpath functions (number(), boolean()) to
another data type, if needed.</p>

<p>Similar to the way described above to inject literals in a secure
way into the XPath expression using tcl variable references there is a
syntax to inject element names from tcl variables. At every place
where the XPath syntax allows a node test there could be a tcl
variable reference (in any form), just the leading $ replaced with %.
This allows one to select nodes with 'strange' (invalid, according to the
appropriate XML production rule) node names which may be needed in
case of working with JSON data.</p>

<p>The option <m>-namespaces</m> expects a tcl list with prefix /
namespace pairs as argument. If this option is not given, then any
namespace prefix within the xpath expression will be first resolved
against the list of prefix / namespace pairs set with the
selectNodesNamespaces method for the document, the node belongs to. If
this fails, then the namespace definitions in scope of the context
node will be used to resolve the prefix. If this option is given, any
namespace prefix within the xpath expression will be first resolved
against that given list (and ignoring the document global prefix /
namespace list). If the list binds the same prefix to different
namespaces, then the first binding will win.  If this fails, then the
namespace definitions in scope of the context node will be used to
resolve the prefix, as usual.</p>

<p>If the <m>-cache</m> option is used with a true value, then the
<m>xpathQuery</m> will be looked up in a document specific cache. If
the query is found, then the stored pre-compiled query will be used.
If the query isn't found, it will be compiled and stored in the cache,
for use in further calls. Please note that the <m>xpathQuery</m> 
given as string is used as key for the cache. This means, that equal
XPath expressions, which differ only in white space are treated as
different cache entries. Special care is needed, if the XPath
expression includes namespace prefixes or references to tcl variables.
Both namespace prefixes and tcl variable references will be resolved
according to the XML prefix namespace mappings and tcl variable values
at expression compilation time. If the same XPath expression is used
later on in a context with other XML prefix namespace mappings or
values of the used tcl variables, make sure to first remove the
compiled expression from the cache with the help of the
<method>deleteXPathCache</method> method, to force a recompilation.
Without using the <m>-cache</m> option such consideration is never
needed.</p>

<p>Examples:</p>
          <example>set paragraphNodes [$node selectNodes {chapter[3]//para[@type='warning' or @type='error'} ]
foreach paragraph $paragraphNodes {
    lappend  values [$paragraph selectNodes attribute::type]
}

................................................................................
set childNodes [$root selectNodes -namespaces {default http://www.defaultnamespace.org} default:child]</example>

          </desc>
      </commanddef>

      <commanddef>
        <command><method>getLine</method></command>
        <desc>Returns the line number of that node in the originally parsed
XML.</desc>
      </commanddef>
      
      <commanddef>
        <command><method>getColumn</method></command>
        <desc>Returns the column number of that node in the originally parsed
XML.</desc>
      </commanddef>

      <commanddef>
        <command><method>asList</method></command>
        <desc>Returns the DOM substree starting form the current node as a
nested Tcl list.</desc>
      </commanddef>

      <commanddef>
        <command><method>asXML</method> <option>?-indent none/1..8?</option> <option>?-channel channelId?</option> <option>?-escapeNonASCII?</option> <option>-xmlDeclaration &lt;boolean&gt;?</option> <option>-encString &lt;string&gt;</option> <option>?-escapeAllQuot?</option> <option>?-indentAttrs?</option> <option>?-nogtescape?</option> <option>?-noEmptyElementTag?</option></command>


        <desc><p>Returns the DOM substree starting from the current
        node as the root node of the result as an (optional indented)
        XML string or sends the output directly to the given
        channelId.</p>

        <p>If the option <m>-escapeNonASCII</m> is given,
        every non 7 bit ASCII character in attribute values or element
        PCDATA content will be escaped as character reference in
        decimal representation.</p>

        <p>The flag <m>-xmlDeclaration</m> determines whether there
        will be an XML Declaration and a newline emitted before
        anything else. The default is, to do not. If this flag is
        given with a true argument then</p>

        <p><m>-encString</m> sets the encoding value in the XML
        Declaration. Otherwise, this option is ignored. Please note,
        that this option just enhance the string representation of the
        generated XML Declaration with an encoding information string,
        nothing more. It's up to the user to handle encoding in case
        of writing to a channel or reparsing.</p>
            
        <p>If the option <m>-escapeAllQuot</m> is given,
        quotation marks will be escaped with &amp;quot; even in text
        content of elements.</p>

        <p>If the option <m>-indentAttrs</m> is
        given, then attributes will each be separated with newlines
        and indented to the same level as the parent node plus the
        value given as argument to <m>-indentAttrs</m> (0..8).</p>

        <p>If the option <m>-nogtescape</m> is given then the
        character '>' won't get escaped in attribute values and text
        content of elements. The default is to escape this
        character.</p>

        <p>If the option <m>-noEmptyElementTag</m> is given then no
        empty tag syntax will be used. Instead, if an element has
        empty content it will be serialized with an element start tag
        and an immediately following element end tag.</p></desc>

      </commanddef>

      <commanddef>
        <command><method>asHTML</method> <option>?-channel channelId?</option>
<option>?-escapeNonASCII?</option>  <option>?-htmlEntities?</option></command>
        <desc>Returns the DOM substree starting from the current node as the
root node of the result serialized according to HTML rules (HTML elements are
recognized regardless of case, without end tags for empty HTML elements etc.),
as string or sends the output directly to the given channelId. If the option
<m>-escapeNonASCII</m> is given, every non 7 bit ASCII character in attribute
values or element PCDATA content will be escaped as character reference in
decimal representation. If the option <m>-htmlEntities</m> is given, a
character is written using its HTML 4.01 character entity reference, if one is
defined for it.</desc>
      </commanddef>

      <commanddef>
        <command><method>asText</method></command>
          <desc>For ELEMENT_NODEs, the asText method outputs 
the string-value of every text node descendant of node in document
order without any escaping. For every other node type, this method outputs the XPath string value of that node.</desc>

      </commanddef>

      <commanddef>
        <command><method>appendFromList</method> <m>list</m></command>
        <desc>Parses <m>list</m> , creates an according DOM subtree and
appends this subtree to the current node.</desc>
      </commanddef>
................................................................................
given node.</desc>
      </commanddef>

      <commanddef>
        <command><method>insertBeforeFromScript</method> <m>tclScript</m> <m>refChild</m></command>
        <desc>Inserts the nodes created in the <m>tclScript</m> by
Tcl functions, which have been built using <m>dom createNodeCmd</m>, before the
<m>refChild</m> into the list of children of node. If <m>refChild</m> is
the empty string, the new nodes will be appended.</desc>
      </commanddef>

      <commanddef>
        <command><method>appendXML</method> <m>XMLstring</m></command>
        <desc>Parses <m>XMLstring</m>, creates an according DOM subtree and
appends this subtree to the current node.</desc>
      </commanddef>

      <commanddef>
        <command><method>simpleTranslate</method> <m>outputVar</m>
<m>specifications</m></command>
        <desc>Translates the subtree starting at the object node according to
the specifications in <m>specifications</m> and outputs the result in the
variable <m>outputVar</m> . The translation is very similar to Cost Simple
mode.</desc>
      </commanddef>

      <commanddef>
        <command><method>toXPath</method> <m>?-legacy?</m></command>
        <desc>Returns an XPath, which exactly addresses the given
node in its document. This XPath is only valid as there are no changes to DOM
tree made later one. With the -legacy option, other XPath expressions
are returned, which doesn't work in all cases.</desc>
      </commanddef>

      <commanddef>
        <command><method>getBaseURI</method></command>
        <desc>Returns the baseURI of the node. This method is deprecated in
          favor of the <m>baseURI</m> method.</desc>
      </commanddef>

      <commanddef>
        <command><method>baseURI</method> <m>?URI?</m></command>
        <desc>Returns the present baseURI of the node. If the optional 
argument URI is given, it sets the base URI of the node and of all of its child
nodes out of the same entity as node to the given URI.</desc>
      </commanddef>

      <commanddef>
        <command><method>disableOutputEscaping</method> <m>?boolean?</m></command>
        <desc>This method works only for text nodes; for every other node it
returns error. Without the optional argument it returns, if disabling output
escaping is on. The return value 0 means, the characters of the text node will
be escaped, to generate valid XML, if serialized. This is the default for
every parsed or created text node (with the exception of that text nodes in a
result tree of an XSLT transformation, for which disabling output escaping was
requested explicitly in the stylesheet). The return value 1 means, that output
escaping is disabled for this text node. If such a text node is serialized
(with asXML or asHTML), it is literally written, without escaping of the
special XML characters. If the optional boolean value <m>boolean</m> is given,
the flag is set accordingly. You should not set this flag to 1 until you
really know what you do.</desc>
      </commanddef>

      <commanddef>
        <command><method>precedes</method> <m>refnode</m></command>
        <desc>Compares the relative order of the node and <m>refnode</m>. Both
nodes must be part of the same documents and not out of the fragment list of
the document. Returns true if node is in document order (in the sense of the
XPath 1.0 recommendation) before <m>refnode</m>, and false otherwise.</desc>
      </commanddef>


      <commanddef>
        <command><method>normalize</method> <m>?-forXPath?</m></command>
        <desc>Puts all Text nodes in the full depth of the sub-tree underneath
this Node into a "normal" form where only structure (e.g., elements,
................................................................................
converted to text nodes, as a first step before the
normalization. </desc>
      </commanddef>

      <commanddef>
        <command><method>xslt</method> <option>?-parameters
parameterList?</option> <option>?-ignoreUndeclaredParameters?</option>
<option>?-maxApplyDepth int?</option>
<option>?-xsltmessagecmd script?</option> <m>stylesheet</m> <m>?outputVar?</m></command>
        <desc>Applies an XSLT transformation on the document using the XSLT
<m>stylesheet</m> (given as domDoc). Returns a document object containing the
result document of that transformation and stores it in the optional
<m>outputVar</m>. 

<p>The optional <m>-parameters</m> option sets top level
&lt;xsl:param&gt; to string values. The <m>parameterList</m> has to be a tcl
list consisting of parameter name and value pairs.</p>

<p>If the option <m>-ignoreUndeclaredParameters</m> is given, then parameter
names in the <m>parameterList</m> given to the <m>-parameters</m> options that
are not declared as top-level parameters in the stylesheet are silently
ignored. Without this option, an error is raised if the user tries to set a
top-level parameter which is not declared in the stylesheet.</p>

<p>The option <m>-maxApplyDepth</m> expects a positive integer as
argument. By default, the xslt engine allows xslt templates to nest up
to 3000 levels (and raises error if they nest deeper). This limit can
be set by the <m>-maxApplyDepth</m> option.</p>

<p>The <m>-xsltmessagecmd</m> option sets a callback for xslt:message elements
in the stylesheet. The actual command consists of the script, given as argument
to the option, appended with the XML Fragment from instantiating the
xsl:message element content as string (as if the XPath string() function would
have been applied to the XML Fragment) and a flag, which indicates whether the
xsl:message has an attribute "terminate" with the value "yes". If the
called script returns anything else then TCL_OK then the xslt
transformation will be aborted, returning error. If the called script
returns -code break the error message is empty, otherwise the result
code is reported. In case of terminated transformation the outputVar,
if given, is set to the empty string.</p>
</desc>
      </commanddef>

      <commanddef>
        <command><m>@attrName</m></command>
        <desc>Returns the value of the attribute <m>attrName</m>.  Short cut
for <m>getAttribute</m>.</desc>
      </commanddef>

      <commanddef>
        <command><method>jsonType</method> <m>?OBJECT|ARRAY|NONE)|(STRING|NUMBER|TRUE|FALSE|NULL|NONE)?</m></command>
        <desc>Only element and text nodes may have a JSON type and
        only this types of nodes support the <m>jsonType</m> method;
        the other node types return error if called with this method.
        Returns the jsonType of the node. If the optional argument is
        given, the JSON type of the node is set to the given type and
        returned. Valid type arguments for element nodes are OBJECT,
        ARRAY and NONE. Valid type arguments for text nodes are
        STRING, NUMBER, TRUE, FALSE, NULL and NONE.</desc>
      </commanddef>

    </commandlist>

    
    <p>Otherwise, if an unknown method name is given, the command with the same
name as the given method within the namespace <l>::dom::domNode</l> is tried to
be executed. This allows quick method additions on Tcl level.</p>

  </section>


Changes to doc/expat.html.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
..
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644












645
646
647
648
649
650
651









652
653
654
655
656
657
658
...
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770

771
772
773
774
775
776
777
778
779
780
781
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: expat</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile$ $Revision$">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid80acb10">NAME</a> ท <a href="#SECTid80acb88">SYNOPSIS</a> ท <a href="#SECTid80acd40">DESCRIPTION</a> ท <a href="#SECTid80ace80">COMMAND OPTIONS</a> ท <a href="#SECTid80aeac8"> COMMAND METHODS </a> ท <a href="#SECTid80af860">Callback Command Return Codes</a> ท <a href="#SECTid80af950">SEE ALSO</a> ท <a href="#SECTid80af9c8">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
    <h2><a name="SECTid80acb10">NAME</a></h2><p class="namesection">
<b class="names">expat - </b><br>Creates an instance of an expat parser object</p>



    <h2><a name="SECTid80acb88">SYNOPSIS</a></h2><pre class="syntax">
<b class="cmd">package require tdom</b>

<b class="cmd">expat</b> ?<i class="m">parsername</i>? ?<i class="m">-namespace</i>? ?<i class="m">arg arg ..</i>

<b class="cmd">xml::parser</b> ?<i class="m">parsername</i>? ?<i class="m">-namespace</i>? ?<i class="m">arg arg ..</i>
</pre>
    <h2><a name="SECTid80acd40">DESCRIPTION</a></h2><p>The parser created with <i class="m">expat</i> or <i class="m">xml::parser</i>
(which is just another name for the same command in an own namespace) are able
to parse any kind of well-formed XML. The parsers are stream oriented XML
parser. This means that you register handler scripts with the parser prior to
starting the parse. These handler scripts are called when the parser discovers
the associated structures in the document being parsed.  A start tag is an
example of the kind of structures for which you may register a handler
script.</p><p>The parsers do not validate the XML document. They do parse the internal DTD
................................................................................
there).</p><p>Additionly, the Tcl extension code that implements this command provides an
API for adding C level coded handlers. Up to now, there exists the parser
extension command "tdom". The handler set installed by this extension build an
in memory "tDOM" DOM tree, while the parser is parsing the input.</p><p>It is possible to register an arbitrary amount of different handler scripts
and C level handlers for most of the events. If the event occurs, they are
called in turn.</p>

    <h2><a name="SECTid80ace80">COMMAND OPTIONS</a></h2><dl class="optlist">
        
          <dt><b>-namespace</b></dt>

          <dd>
<p>Enables namespace parsing. You must use this option while
creating the parser with the <tt class="samp">expat</tt> or <tt class="samp">xml::parser</tt>
command. You can't enable (nor disable) namespace parsing with
................................................................................
</dt>
          
          <dd>If &lt;boolen&gt; is true and the document does not have an
external subset, the parser will call the -externalentitycommand script with
empty values for the systemId and publicID arguments. This option must be set,
before the first piece of data is parsed. Setting this option, after the
parsing has started has no effect. The default is not to use a foreign DTD. The
default is restored, after reseting the parser. Pleace notice, that a
-paramentityparsing value of "never" (which is the default) suppresses any call
to the -externalentitycommand script. Pleace notice, that, if the document also
doesn't have an internal subset, the -startdoctypedeclcommand and
enddoctypedeclcommand scripts, if set, are not called.</dd>
        

      </dl>
    <h2><a name="SECTid80aeac8"> COMMAND METHODS </a></h2><dl class="commandlist">
        
          <dt>
<b class="cmd">parser</b> <b class="method">configure</b> <i class="m">option value ?option value?</i>
</dt>

          <dd><p>Sets configuration options for the parser. Every command
option, except <i class="m">-namespace</i> can be set or modified with this method.</p></dd>
        

        
          <dt>
<b class="cmd">parser</b> <b class="method">cget <i class="m">?-handlerset name? option</i>
</b>
</dt>

          <dd>
<p>Return the current configuration value option for the
parser.</p> 
          <p>If the -handlerset option is used, the configuration for the
named handler set is returned.</p>
          </dd>
        

        
          <dt>












<b class="cmd">parser</b> <b class="method">free</b>
</dt>

          <dd><p>Deletes the parser and the parser command. A parser cannot
be freed from within one of its handler callbacks (neither directly nor
indirectly) and will raise a tcl error in this case.</p></dd>
        










        
          <dt>
<b class="cmd">parser</b> <b class="method">get</b> <i class="m">-specifiedattributecount|-idattributeindex|-currentbytecount|-currentlinenumber|-currentcolumnnumber|-currentbyteindex</i>
</dt>
          <dd>
<dl class="optlist">
................................................................................

        
          <dt>
<b class="cmd">parser</b> <b class="method">reset</b>
</dt>

          <dd><p>Resets the parser in preparation for parsing another
document. A parser cannot be reseted from within one of its handler callbacks
(neither directly nor indirectly) and will raise a tcl error in this
cases.</p></dd>
        
      </dl>

    <h2><a name="SECTid80af860">Callback Command Return Codes</a></h2><p>A script invoked for any of the parser callback commands, such as
-elementstartcommand, -elementendcommand, etc, may return an error code other
than "ok" or "error". All callbacks may in addition return
"break" or "continue".</p><p>If a callback script returns an "error" error code then
processing of the document is terminated and the error is propagated in the
usual fashion.</p><p>If a callback script returns a "break" error code then all
further processing of every handler script out of this Tcl handler set is
suppressed for the further parsing. This does not influence any other handler
set.</p><p>If a callback script returns a "continue" error code then
processing of the current element, and its children, ceases for every handler
script out of this Tcl handler set and processing continues with the next
(sibling) element. This does not influence any other handler set.</p>


    <h2><a name="SECTid80af950">SEE ALSO</a></h2><p class="seealso">
<a href="expatapi.html">expatapi</a>, <a href="tdomcmd.html">tdom</a>
</p>

    <h2><a name="SECTid80af9c8">KEYWORDS</a></h2><p class="keywords"><a class="keyword" href="keyword-index.html#KW-SAX">SAX</a></p>
  </div><hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> <a class="navaid" href="category-index.html">Index</a> ท <a class="navaid" href="keyword-index.html">Keywords</a>
</div>
</body>
</html>


|



|


|




|
<





|







 







|







 







|







|











|
<












>
>
>
>
>
>
>
>
>
>
>
>
|



|


>
>
>
>
>
>
>
>
>







 







|





|










|
>

|



|

|



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
..
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
...
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
...
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: expat</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: tmml-html.xsl,v $ $Revision: 1.11 $"><meta charset="utf-8">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid0x1708960">NAME</a> ยท <a href="#SECTid0x160bf00">SYNOPSIS</a> ยท <a href="#SECTid0x16ee020">DESCRIPTION</a> ยท <a href="#SECTid0x16eed60">COMMAND OPTIONS</a> ยท <a href="#SECTid0x1746b80"> COMMAND METHODS </a> ยท <a href="#SECTid0x174d660">Callback Command Return Codes</a> ยท <a href="#SECTid0x174e1f0">SEE ALSO</a> ยท <a href="#SECTid0x174e5b0">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
    <h2><a name="SECTid0x1708960">NAME</a></h2><p class="namesection">
<b class="names">expat - </b><br>Creates an instance of an expat parser object</p>



    <h2><a name="SECTid0x160bf00">SYNOPSIS</a></h2><pre class="syntax">package require tdom


<b class="cmd">expat</b> ?<i class="m">parsername</i>? ?<i class="m">-namespace</i>? ?<i class="m">arg arg ..</i>

<b class="cmd">xml::parser</b> ?<i class="m">parsername</i>? ?<i class="m">-namespace</i>? ?<i class="m">arg arg ..</i>
</pre>
    <h2><a name="SECTid0x16ee020">DESCRIPTION</a></h2><p>The parser created with <i class="m">expat</i> or <i class="m">xml::parser</i>
(which is just another name for the same command in an own namespace) are able
to parse any kind of well-formed XML. The parsers are stream oriented XML
parser. This means that you register handler scripts with the parser prior to
starting the parse. These handler scripts are called when the parser discovers
the associated structures in the document being parsed.  A start tag is an
example of the kind of structures for which you may register a handler
script.</p><p>The parsers do not validate the XML document. They do parse the internal DTD
................................................................................
there).</p><p>Additionly, the Tcl extension code that implements this command provides an
API for adding C level coded handlers. Up to now, there exists the parser
extension command "tdom". The handler set installed by this extension build an
in memory "tDOM" DOM tree, while the parser is parsing the input.</p><p>It is possible to register an arbitrary amount of different handler scripts
and C level handlers for most of the events. If the event occurs, they are
called in turn.</p>

    <h2><a name="SECTid0x16eed60">COMMAND OPTIONS</a></h2><dl class="optlist">
        
          <dt><b>-namespace</b></dt>

          <dd>
<p>Enables namespace parsing. You must use this option while
creating the parser with the <tt class="samp">expat</tt> or <tt class="samp">xml::parser</tt>
command. You can't enable (nor disable) namespace parsing with
................................................................................
</dt>
          
          <dd>If &lt;boolen&gt; is true and the document does not have an
external subset, the parser will call the -externalentitycommand script with
empty values for the systemId and publicID arguments. This option must be set,
before the first piece of data is parsed. Setting this option, after the
parsing has started has no effect. The default is not to use a foreign DTD. The
default is restored, after resetting the parser. Pleace notice, that a
-paramentityparsing value of "never" (which is the default) suppresses any call
to the -externalentitycommand script. Pleace notice, that, if the document also
doesn't have an internal subset, the -startdoctypedeclcommand and
enddoctypedeclcommand scripts, if set, are not called.</dd>
        

      </dl>
    <h2><a name="SECTid0x1746b80"> COMMAND METHODS </a></h2><dl class="commandlist">
        
          <dt>
<b class="cmd">parser</b> <b class="method">configure</b> <i class="m">option value ?option value?</i>
</dt>

          <dd><p>Sets configuration options for the parser. Every command
option, except <i class="m">-namespace</i> can be set or modified with this method.</p></dd>
        

        
          <dt>
<b class="cmd">parser</b> <b class="method">cget</b> <i class="m">?-handlerset name? option</i>

</dt>

          <dd>
<p>Return the current configuration value option for the
parser.</p> 
          <p>If the -handlerset option is used, the configuration for the
named handler set is returned.</p>
          </dd>
        

        
          <dt>
<b class="cmd">parser</b> <b class="method">currentmarkup</b>
</dt>

          <dd><p>Returns the current markup as found in the XML, if
          called from within one of its markup event handler script
          (-elementstartcommand, -elementendcommand, -commentcommand
          and -processinginstructioncommand). Otherwise it return the
          empty string.</p></dd>
        

        
          <dt>
<b class="cmd">parser</b> <b class="method">delete</b>
</dt>

          <dd><p>Deletes the parser and the parser command. A parser cannot
be deleted from within one of its handler callbacks (neither directly nor
indirectly) and will raise a tcl error in this case.</p></dd>
        

        
          <dt>
<b class="cmd">parser</b> <b class="method">free</b>
</dt>

          <dd><p>Another name to call the method <i class="m">delete</i>, see
          there.</p></dd>
        

        
          <dt>
<b class="cmd">parser</b> <b class="method">get</b> <i class="m">-specifiedattributecount|-idattributeindex|-currentbytecount|-currentlinenumber|-currentcolumnnumber|-currentbyteindex</i>
</dt>
          <dd>
<dl class="optlist">
................................................................................

        
          <dt>
<b class="cmd">parser</b> <b class="method">reset</b>
</dt>

          <dd><p>Resets the parser in preparation for parsing another
document. A parser cannot be reset from within one of its handler callbacks
(neither directly nor indirectly) and will raise a tcl error in this
cases.</p></dd>
        
      </dl>

    <h2><a name="SECTid0x174d660">Callback Command Return Codes</a></h2><p>A script invoked for any of the parser callback commands, such as
-elementstartcommand, -elementendcommand, etc, may return an error code other
than "ok" or "error". All callbacks may in addition return
"break" or "continue".</p><p>If a callback script returns an "error" error code then
processing of the document is terminated and the error is propagated in the
usual fashion.</p><p>If a callback script returns a "break" error code then all
further processing of every handler script out of this Tcl handler set is
suppressed for the further parsing. This does not influence any other handler
set.</p><p>If a callback script returns a "continue" error code then
processing of the current element, and its children, ceases for every handler
script out of this Tcl handler set and processing continues with the next
(sibling) element. This does not influence any other handler set.</p><p>If a callback script returns a "return" error
code then parsing is canceled altogether, but no error is raised.</p>

    <h2><a name="SECTid0x174e1f0">SEE ALSO</a></h2><p class="seealso">
<a href="expatapi.html">expatapi</a>, <a href="tdomcmd.html">tdom</a>
</p>

    <h2><a name="SECTid0x174e5b0">KEYWORDS</a></h2><p class="keywords"><a class="keyword" href="keyword-index.html#KW-SAX">SAX</a></p>
  </div><hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>
</div>
</body>
</html>

Changes to doc/expat.n.

159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
...
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
...
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727











728
729
730
731
732
733
734
735








736
737
738
739
740
741
742
...
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
...
842
843
844
845
846
847
848



849
850
851
852
'\" END man.macros
.TH expat n "" Tcl ""
.BS
.SH NAME
expat \- Creates an instance of an expat parser object
.SH SYNOPSIS
.nf
\&\fBpackage require tdom\fP

\&\fBexpat\fP ?\fIparsername\fR? ?\fI-namespace\fR? ?\fIarg arg ..\fR

\&\fBxml::parser\fP ?\fIparsername\fR? ?\fI-namespace\fR? ?\fIarg arg ..\fR
.fi
.BE
.SH DESCRIPTION
................................................................................
.RE
.IP "\fB-useForeignDTD  \fI<boolen>\fP\fR"
If <boolen> is true and the document does not have an
external subset, the parser will call the -externalentitycommand script with
empty values for the systemId and publicID arguments. This option must be set,
before the first piece of data is parsed. Setting this option, after the
parsing has started has no effect. The default is not to use a foreign DTD. The
default is restored, after reseting the parser. Pleace notice, that a
-paramentityparsing value of "never" (which is the default) suppresses any call
to the -externalentitycommand script. Pleace notice, that, if the document also
doesn't have an internal subset, the -startdoctypedeclcommand and
enddoctypedeclcommand scripts, if set, are not called.
.SH " COMMAND METHODS "
.TP
\&\fB\fBparser\fP \fBconfigure\fP \fIoption value ?option value?\fB
................................................................................
\&\fR
.RS
.PP
Sets configuration options for the parser. Every command
option, except \fI-namespace\fR can be set or modified with this method.
.RE
.TP
\&\fB\fBparser\fP \fBcget \fI?-handlerset name? option\fB\fP
\&\fR
.RS
.PP
Return the current configuration value option for the
parser.
.PP
If the -handlerset option is used, the configuration for the
named handler set is returned.
.RE
.TP











\&\fB\fBparser\fP \fBfree\fP
\&\fR
.RS
.PP
Deletes the parser and the parser command. A parser cannot
be freed from within one of its handler callbacks (neither directly nor
indirectly) and will raise a tcl error in this case.
.RE








.TP
\&\fB\fBparser\fP \fBget\fP \fI-specifiedattributecount|-idattributeindex|-currentbytecount|-currentlinenumber|-currentcolumnnumber|-currentbyteindex\fB
\&\fR
.RS
.IP "\fB-specifiedattributecount\fR"
.RS
.PP
................................................................................
.RE
.TP
\&\fB\fBparser\fP \fBreset\fP
\&\fR
.RS
.PP
Resets the parser in preparation for parsing another
document. A parser cannot be reseted from within one of its handler callbacks
(neither directly nor indirectly) and will raise a tcl error in this
cases.
.RE
.SH "Callback Command Return Codes"
.PP
A script invoked for any of the parser callback commands, such as
-elementstartcommand, -elementendcommand, etc, may return an error code other
................................................................................
suppressed for the further parsing. This does not influence any other handler
set.
.PP
If a callback script returns a "continue" error code then
processing of the current element, and its children, ceases for every handler
script out of this Tcl handler set and processing continues with the next
(sibling) element. This does not influence any other handler set.



.SH "SEE ALSO"
expatapi, tdom
.SH KEYWORDS
SAX







|







 







|







 







|










>
>
>
>
>
>
>
>
>
>
>
|




|


>
>
>
>
>
>
>
>







 







|







 







>
>
>




159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
...
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
...
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
...
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
...
861
862
863
864
865
866
867
868
869
870
871
872
873
874
'\" END man.macros
.TH expat n "" Tcl ""
.BS
.SH NAME
expat \- Creates an instance of an expat parser object
.SH SYNOPSIS
.nf
package require tdom

\&\fBexpat\fP ?\fIparsername\fR? ?\fI-namespace\fR? ?\fIarg arg ..\fR

\&\fBxml::parser\fP ?\fIparsername\fR? ?\fI-namespace\fR? ?\fIarg arg ..\fR
.fi
.BE
.SH DESCRIPTION
................................................................................
.RE
.IP "\fB-useForeignDTD  \fI<boolen>\fP\fR"
If <boolen> is true and the document does not have an
external subset, the parser will call the -externalentitycommand script with
empty values for the systemId and publicID arguments. This option must be set,
before the first piece of data is parsed. Setting this option, after the
parsing has started has no effect. The default is not to use a foreign DTD. The
default is restored, after resetting the parser. Pleace notice, that a
-paramentityparsing value of "never" (which is the default) suppresses any call
to the -externalentitycommand script. Pleace notice, that, if the document also
doesn't have an internal subset, the -startdoctypedeclcommand and
enddoctypedeclcommand scripts, if set, are not called.
.SH " COMMAND METHODS "
.TP
\&\fB\fBparser\fP \fBconfigure\fP \fIoption value ?option value?\fB
................................................................................
\&\fR
.RS
.PP
Sets configuration options for the parser. Every command
option, except \fI-namespace\fR can be set or modified with this method.
.RE
.TP
\&\fB\fBparser\fP \fBcget\fP \fI?-handlerset name? option\fB
\&\fR
.RS
.PP
Return the current configuration value option for the
parser.
.PP
If the -handlerset option is used, the configuration for the
named handler set is returned.
.RE
.TP
\&\fB\fBparser\fP \fBcurrentmarkup\fP
\&\fR
.RS
.PP
Returns the current markup as found in the XML, if
called from within one of its markup event handler script
(-elementstartcommand, -elementendcommand, -commentcommand
and -processinginstructioncommand). Otherwise it return the
empty string.
.RE
.TP
\&\fB\fBparser\fP \fBdelete\fP
\&\fR
.RS
.PP
Deletes the parser and the parser command. A parser cannot
be deleted from within one of its handler callbacks (neither directly nor
indirectly) and will raise a tcl error in this case.
.RE
.TP
\&\fB\fBparser\fP \fBfree\fP
\&\fR
.RS
.PP
Another name to call the method \fIdelete\fR, see
there.
.RE
.TP
\&\fB\fBparser\fP \fBget\fP \fI-specifiedattributecount|-idattributeindex|-currentbytecount|-currentlinenumber|-currentcolumnnumber|-currentbyteindex\fB
\&\fR
.RS
.IP "\fB-specifiedattributecount\fR"
.RS
.PP
................................................................................
.RE
.TP
\&\fB\fBparser\fP \fBreset\fP
\&\fR
.RS
.PP
Resets the parser in preparation for parsing another
document. A parser cannot be reset from within one of its handler callbacks
(neither directly nor indirectly) and will raise a tcl error in this
cases.
.RE
.SH "Callback Command Return Codes"
.PP
A script invoked for any of the parser callback commands, such as
-elementstartcommand, -elementendcommand, etc, may return an error code other
................................................................................
suppressed for the further parsing. This does not influence any other handler
set.
.PP
If a callback script returns a "continue" error code then
processing of the current element, and its children, ceases for every handler
script out of this Tcl handler set and processing continues with the next
(sibling) element. This does not influence any other handler set.
.PP
If a callback script returns a "return" error
code then parsing is canceled altogether, but no error is raised.
.SH "SEE ALSO"
expatapi, tdom
.SH KEYWORDS
SAX

Changes to doc/expat.xml.

1
2
3
4
5
6
7
8
..
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
...
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590










591
592
593
594
595
596
597







598
599
600
601
602
603
604
...
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
...
710
711
712
713
714
715
716



717
718
719
720
721
722
723
724
725


726
727
728
729
730
731
  <manpage id="expat" cat="cmd" title="expat">
    <namesection>
      <name>expat</name>
      <desc>Creates an instance of an expat parser object</desc>
    </namesection>

<!--

................................................................................

 See the file "LICENSE" for information on usage and redistribution
 of this file, and for a DISCLAIMER OF ALL WARRANTIES.

-->

    <synopsis>
      <syntax><cmd>package require tdom</cmd>

<cmd>expat</cmd> ?<m>parsername</m>? ?<m>-namespace</m>? ?<m>arg arg ..</m>

<cmd>xml::parser</cmd> ?<m>parsername</m>? ?<m>-namespace</m>? ?<m>arg arg ..</m></syntax>
    </synopsis>
    <section>
      <title>DESCRIPTION</title>
................................................................................
          <optname>-useForeignDTD</optname>
          <optarg>&lt;boolen&gt;</optarg>
          <desc>If &lt;boolen&gt; is true and the document does not have an
external subset, the parser will call the -externalentitycommand script with
empty values for the systemId and publicID arguments. This option must be set,
before the first piece of data is parsed. Setting this option, after the
parsing has started has no effect. The default is not to use a foreign DTD. The
default is restored, after reseting the parser. Pleace notice, that a
-paramentityparsing value of "never" (which is the default) suppresses any call
to the -externalentitycommand script. Pleace notice, that, if the document also
doesn't have an internal subset, the -startdoctypedeclcommand and
enddoctypedeclcommand scripts, if set, are not called.</desc>
        </optdef>

      </optlist>
................................................................................
          <command><cmd>parser</cmd> <method>configure</method> <m>option value ?option value?</m></command>

          <desc><p>Sets configuration options for the parser. Every command
option, except <m>-namespace</m> can be set or modified with this method.</p></desc>
        </commanddef>

        <commanddef>
          <command><cmd>parser</cmd> <method>cget <m>?-handlerset name? option</m></method></command>

          <desc><p>Return the current configuration value option for the
parser.</p> 
          <p>If the -handlerset option is used, the configuration for the
named handler set is returned.</p>
          </desc>
        </commanddef>

        <commanddef>










          <command><cmd>parser</cmd> <method>free</method></command>

          <desc><p>Deletes the parser and the parser command. A parser cannot
be freed from within one of its handler callbacks (neither directly nor
indirectly) and will raise a tcl error in this case.</p></desc>
        </commanddef>








        <commanddef>
          <command><cmd>parser</cmd> <method>get</method> <m>-specifiedattributecount|-idattributeindex|-currentbytecount|-currentlinenumber|-currentcolumnnumber|-currentbyteindex</m></command>
          <desc>
<optlist>
              <optdef>
                <optname>-specifiedattributecount</optname>

................................................................................
of the parser to be used and will raise an error in this case.</p></desc>
        </commanddef>

        <commanddef>
          <command><cmd>parser</cmd> <method>reset</method></command>

          <desc><p>Resets the parser in preparation for parsing another
document. A parser cannot be reseted from within one of its handler callbacks
(neither directly nor indirectly) and will raise a tcl error in this
cases.</p></desc>
        </commanddef>
      </commandlist>
    </section>

    <section>
................................................................................
set.</p>

      <p>If a callback script returns a &quot;continue&quot; error code then
processing of the current element, and its children, ceases for every handler
script out of this Tcl handler set and processing continues with the next
(sibling) element. This does not influence any other handler set.</p>




    </section>

    <seealso>
      <ref>expatapi</ref>
      <ref>tdom</ref>
    </seealso>

    <keywords>
      <keyword>SAX</keyword>


    </keywords>
  </manpage>



  
|







 







|







 







|







 







|









>
>
>
>
>
>
>
>
>
>
|


|



>
>
>
>
>
>
>







 







|







 







>
>
>









>
>






1
2
3
4
5
6
7
8
..
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
...
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
...
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
...
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
<manpage id="expat" cat="cmd" title="expat">
    <namesection>
      <name>expat</name>
      <desc>Creates an instance of an expat parser object</desc>
    </namesection>

<!--

................................................................................

 See the file "LICENSE" for information on usage and redistribution
 of this file, and for a DISCLAIMER OF ALL WARRANTIES.

-->

    <synopsis>
      <syntax>package require tdom

<cmd>expat</cmd> ?<m>parsername</m>? ?<m>-namespace</m>? ?<m>arg arg ..</m>

<cmd>xml::parser</cmd> ?<m>parsername</m>? ?<m>-namespace</m>? ?<m>arg arg ..</m></syntax>
    </synopsis>
    <section>
      <title>DESCRIPTION</title>
................................................................................
          <optname>-useForeignDTD</optname>
          <optarg>&lt;boolen&gt;</optarg>
          <desc>If &lt;boolen&gt; is true and the document does not have an
external subset, the parser will call the -externalentitycommand script with
empty values for the systemId and publicID arguments. This option must be set,
before the first piece of data is parsed. Setting this option, after the
parsing has started has no effect. The default is not to use a foreign DTD. The
default is restored, after resetting the parser. Pleace notice, that a
-paramentityparsing value of "never" (which is the default) suppresses any call
to the -externalentitycommand script. Pleace notice, that, if the document also
doesn't have an internal subset, the -startdoctypedeclcommand and
enddoctypedeclcommand scripts, if set, are not called.</desc>
        </optdef>

      </optlist>
................................................................................
          <command><cmd>parser</cmd> <method>configure</method> <m>option value ?option value?</m></command>

          <desc><p>Sets configuration options for the parser. Every command
option, except <m>-namespace</m> can be set or modified with this method.</p></desc>
        </commanddef>

        <commanddef>
          <command><cmd>parser</cmd> <method>cget</method> <m>?-handlerset name? option</m></command>

          <desc><p>Return the current configuration value option for the
parser.</p> 
          <p>If the -handlerset option is used, the configuration for the
named handler set is returned.</p>
          </desc>
        </commanddef>

        <commanddef>
          <command><cmd>parser</cmd> <method>currentmarkup</method></command>

          <desc><p>Returns the current markup as found in the XML, if
          called from within one of its markup event handler script
          (-elementstartcommand, -elementendcommand, -commentcommand
          and -processinginstructioncommand). Otherwise it return the
          empty string.</p></desc>
        </commanddef>

        <commanddef>
          <command><cmd>parser</cmd> <method>delete</method></command>

          <desc><p>Deletes the parser and the parser command. A parser cannot
be deleted from within one of its handler callbacks (neither directly nor
indirectly) and will raise a tcl error in this case.</p></desc>
        </commanddef>

        <commanddef>
          <command><cmd>parser</cmd> <method>free</method></command>

          <desc><p>Another name to call the method <m>delete</m>, see
          there.</p></desc>
        </commanddef>

        <commanddef>
          <command><cmd>parser</cmd> <method>get</method> <m>-specifiedattributecount|-idattributeindex|-currentbytecount|-currentlinenumber|-currentcolumnnumber|-currentbyteindex</m></command>
          <desc>
<optlist>
              <optdef>
                <optname>-specifiedattributecount</optname>

................................................................................
of the parser to be used and will raise an error in this case.</p></desc>
        </commanddef>

        <commanddef>
          <command><cmd>parser</cmd> <method>reset</method></command>

          <desc><p>Resets the parser in preparation for parsing another
document. A parser cannot be reset from within one of its handler callbacks
(neither directly nor indirectly) and will raise a tcl error in this
cases.</p></desc>
        </commanddef>
      </commandlist>
    </section>

    <section>
................................................................................
set.</p>

      <p>If a callback script returns a &quot;continue&quot; error code then
processing of the current element, and its children, ceases for every handler
script out of this Tcl handler set and processing continues with the next
(sibling) element. This does not influence any other handler set.</p>

      <p>If a callback script returns a &quot;return&quot; error
code then parsing is canceled altogether, but no error is raised.</p>

    </section>

    <seealso>
      <ref>expatapi</ref>
      <ref>tdom</ref>
    </seealso>

    <keywords>
      <keyword>SAX</keyword>
      <keyword>push</keyword>
      <keyword>pushparser</keyword>
    </keywords>
  </manpage>



  

Changes to doc/expatapi.html.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
...
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: expatapi</title><meta name="xsl-processor" content="Jochen Loewer et. al. (loewerj@hotmail.com)"><meta name="generator" content="$RCSfile$ $Revision$">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTnode8831">NAME</a> ท <a href="#SECTnode8840">SYNOPSIS</a> ท <a href="#SECTnode8918">ARGUMENTS</a> ท <a href="#SECTnode8999">DESCRIPTION</a> ท <a href="#SECTnode9184">SEE ALSO</a> ท <a href="#SECTnode9190">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
    <h2><a name="SECTnode8831">NAME</a></h2><p class="namesection">
<b class="names">CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove,
         CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo - </b><br>Functions to create, install and remove expat parser object
extensions.</p>
  <h2><a name="SECTnode8840">SYNOPSIS</a></h2><pre class="syntax">#include &lt;tclexpat.h&gt;

int 
<b class="fun">CheckExpatParserObj</b> (<a href="#ARG-interp"><i>interp</i></a>, <a href="#ARG-nameObj"><i>nameObj</i></a>)  

int
<b class="fun">CHandlerSetInstall</b> (<a href="#ARG-interp"><i>interp</i></a>, <a href="#ARG-expatObj"><i>expatObj</i></a>, <a href="#ARG-handlerSet"><i>handlerSet</i></a>)

................................................................................
void*
<b class="fun">CHandlerSetGetUserData</b> (<a href="#ARG-interp"><i>interp</i></a>, <a href="#ARG-expatObj"><i>expatObj</i></a>, <a href="#ARG-handlerSetName"><i>handlerSetName</i></a>)

TclGenExpatInfo*
<b class="fun">GetExpatInfo</b> (<a href="#ARG-interp"><i>interp</i></a>, <a href="#ARG-expatObj"><i>expatObj</i></a>)
</pre>

  <h2><a name="SECTnode8918">ARGUMENTS</a></h2><div class="arglist"><table width="100%" rules="none" cellpadding="5%">
<thead><tr class="heading">
<th width="20%">Type</th><th width="70%">Name</th><th width="10%">Mode</th>
</tr></thead><tr class="syntax">
<td class="type" width="20%" align="left">Tcl_Interp</td><td class="name" width="70%" align="left"><a name="ARG-interp">*interp</a></td><td class="mode" width="10%" align="center">in</td>
</tr><tr class="desc">
<td class="padding" width="20%"</td><td class="argdesc" width="80%" align="left" colspan="2">Interpreter with the expat parser object.</td>
</tr><tr class="syntax">
<td class="type" width="20%" align="left">Tcl_Obj</td><td class="name" width="70%" align="left"><a name="ARG-expatObj">*expatObj</a></td><td class="mode" width="10%" align="center">in</td>
</tr><tr class="desc">
<td class="padding" width="20%"</td><td class="argdesc" width="80%" align="left" colspan="2">A Tcl Object containing the command name of the expat parser object to be queried or modified.</td>
</tr><tr class="syntax">
<td class="type" width="20%" align="left">char</td><td class="name" width="70%" align="left"><a name="ARG-handlerSetName">*handlerSetName</a></td><td class="mode" width="10%" align="center">in</td>
</tr><tr class="desc">
<td class="padding" width="20%"</td><td class="argdesc" width="80%" align="left" colspan="2">Identifier of the handler set.</td>
</tr><tr class="syntax">
<td class="type" width="20%" align="left">CHandlerSet</td><td class="name" width="70%" align="left"><a name="ARG-handlerSet">*handlerSet</a></td><td class="mode" width="10%" align="center">in</td>
</tr><tr class="desc">
<td class="padding" width="20%"</td><td class="argdesc" width="80%" align="left" colspan="2">Pointer to a C handler set.</td>
</tr><tr class="syntax">
<td class="type" width="20%" align="left">Tcl_Obj</td><td class="name" width="70%" align="left"><a name="ARG-nameObj">*nameObj</a></td><td class="mode" width="10%" align="center"></td>
</tr><tr class="desc">
<td class="padding" width="20%"</td><td class="argdesc" width="80%" align="left" colspan="2">A Tcl Object containing the name of a expat parser object</td>
</tr>
</table></div>

  <h2><a name="SECTnode8999">DESCRIPTION</a></h2><p>The functions described in this manual allows to add C level coded event
handler to an tDOM Tcl expat parser objects. A tDOM Tcl expat parser object is
able to have several Tcl scripts and C functions associated with an specific
event. If the event occurs, first the Tcl scripts then the C functions
associated with the event are called in turn.</p><p>A tDOM Tcl expat parser extension is an ordinary Tcl extension and loaded
like every other Tcl extension. It must install at least one new Tcl Level
command, that manipulates a tDOM Tcl expat parser object.</p><p>A C level handler set is a data structure like this:</p><pre class="example">
typedef struct CHandlerSet {
    struct CHandlerSet *nextHandlerSet;
    char *name;                     /* refname of the handler set */
    int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */

    void *userData;                 /* Handler set specific Data Structure;
                                       the C handler set extention has to
                                       malloc the needed structure in his
                                       init func and has to provide a
                                       cleanup func (to free it). */

    CHandlerSet_userDataReset        resetProc;
    CHandlerSet_userDataFree         freeProc;

................................................................................
    XML_NotationDeclHandler          notationcommand;
    /* C func for external entity */
    XML_ExternalEntityRefHandler     externalentitycommand;
    /* C func for unknown encoding */
    XML_UnknownEncodingHandler       unknownencodingcommand;
    /* C func for comments */
    XML_CommentHandler               commentCommand;
    /* C func for &quot;not standalone&quot; docs */
    XML_NotStandaloneHandler         notStandaloneCommand;
    /* C func for CDATA section start */
    XML_StartCdataSectionHandler     startCdataSectionCommand;
    /* C func for CDATA section end */
    XML_EndCdataSectionHandler       endCdataSectionCommand;
    /* C func for !ELEMENT decl's */
    XML_ElementDeclHandler           elementDeclCommand;
................................................................................
initialized to NULL by CHandlerSetCreate).</p><p>The <i class="m">name</i> of this structure is used to identify the handler set.
</p><p>If the flag <i class="m">ignoreWhiteCDATAs</i> is set, element content which
contain only whitespace isn't reported with the datacommand.  </p><p>The <i class="m">userData</i> element points to the handler set specific data. The
event handler functions are called with this pointer as userData argument.
</p><p>
<i class="m">resetProc</i> and <i class="m">freeProc</i> must have arguments that match the
type</p><pre class="syntax">void (Tcl_Interp *interp, void *userData)</pre><p>
<i class="m">resetProc</i> is called in case the parser is reseted with
<tt class="samp">&lt;parserObj&gt; reset</tt> and should do any necessary cleanup and
reinitializing to prepare the C handler set for a new XML document. The
<i class="m">freeProc</i> is called, if the parser is deleted and should do memory
cleanup etc.  </p><p> <i class="m">CHandlerSetCreate</i> create a C handler set, gives it the name
<i class="m">name</i> and initializes any other element with NULL.</p><p> <i class="m">CHandlerSetInstall</i> adds the <i class="m">handlerSet</i> to the parser
<i class="m">expatObj</i>. The parser has to be a tDOM Tcl expat parser object in the
interpreter <i class="m">interp</i>. The name of the C handler set has to be unique for
................................................................................
parser object in the interpreter <i class="m">interp</i>, otherwise it returns
0. Example:</p><pre class="example">
int
TclExampleObjCmd(dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *CONST objv[];
{
    char          *method;
    CHandlerSet   *handlerSet;
    int            methodIndex, result;
    simpleCounter *counter;
    

    static char *exampleMethods[] = {
        &quot;enable&quot;, &quot;getresult&quot;, &quot;remove&quot;,
        NULL
    };
    enum exampleMethod {
        m_enable, m_getresult, m_remove
    };

    if (objc != 3) {
        Tcl_WrongNumArgs (interp, 1, objv, example_usage);
        return TCL_ERROR;
    }

    if (!CheckExpatParserObj (interp, objv[1])) {
        Tcl_SetResult (interp, &quot;First argument has to be a expat parser object&quot;, NULL);
        return TCL_ERROR;
    }
    /* ... */
</pre><p> <i class="m">CHandlerSetGet</i> returns a pointer to the C handler Set referenced
by the name <i class="m">handlerSetName</i> of the parser object
<i class="m">expatObj</i>. <i class="m">expatObj</i> has to be an expat parser object in the
interpreter <i class="m">interp</i>. Returns NULL in case of error.</p><p>
................................................................................
TclGenExpatInfo structure of the tDOM Tcl expat parser object
<i class="m">expatObj</i>. The <i class="m">expatObj</i> has to be a tDOM Tcl expat parser object
in the interpreter <i class="m">interp</i>. This is most useful, to set the application
status of the parser object.</p><p>See the simple but full functionally example in the extensions/example
dir or the more complex example tnc in the extensions/tnc dir (a simple DTD
validation extension).</p>

  <h2><a name="SECTnode9184">SEE ALSO</a></h2><p class="seealso"><a href="expat.html">expat</a></p>

  <h2><a name="SECTnode9190">KEYWORDS</a></h2><p class="keywords"><a class="keyword" href="keyword-index.html#KW-Chandlerset">C handler set</a></p>
</div><div class="footer">
<hr class="navsep"><!-- footer.html: Standard navigational footer --><div class="navbar" align="center">
	<a class="navaid" href="index.html">Table of Contents</a>
 ท	<a class="navaid" href="category-index.html">Index</a>
 ท	<a class="navaid" href="keyword-index.html">Keywords</a>
</div>
</div>
</body>
</html>


|



|


|



|







 







|





|



|



|



|



|



|












|







 







|







 







|







 







|








|












|







 







|

|
|
|
<
<
<
<



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
...
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
...
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
195
196
197
198
199
200
201
202
203
204
205
206




207
208
209
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: expatapi</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: tmml-html.xsl,v $ $Revision: 1.11 $"><meta charset="utf-8">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid0x1e7b920">NAME</a> ยท <a href="#SECTid0x1d90950">SYNOPSIS</a> ยท <a href="#SECTid0x1eef570">ARGUMENTS</a> ยท <a href="#SECTid0x1ef1660">DESCRIPTION</a> ยท <a href="#SECTid0x1ea6080">SEE ALSO</a> ยท <a href="#SECTid0x1ea6320">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
    <h2><a name="SECTid0x1e7b920">NAME</a></h2><p class="namesection">
<b class="names">CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove,
         CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo - </b><br>Functions to create, install and remove expat parser object
extensions.</p>
  <h2><a name="SECTid0x1d90950">SYNOPSIS</a></h2><pre class="syntax">#include &lt;tclexpat.h&gt;

int 
<b class="fun">CheckExpatParserObj</b> (<a href="#ARG-interp"><i>interp</i></a>, <a href="#ARG-nameObj"><i>nameObj</i></a>)  

int
<b class="fun">CHandlerSetInstall</b> (<a href="#ARG-interp"><i>interp</i></a>, <a href="#ARG-expatObj"><i>expatObj</i></a>, <a href="#ARG-handlerSet"><i>handlerSet</i></a>)

................................................................................
void*
<b class="fun">CHandlerSetGetUserData</b> (<a href="#ARG-interp"><i>interp</i></a>, <a href="#ARG-expatObj"><i>expatObj</i></a>, <a href="#ARG-handlerSetName"><i>handlerSetName</i></a>)

TclGenExpatInfo*
<b class="fun">GetExpatInfo</b> (<a href="#ARG-interp"><i>interp</i></a>, <a href="#ARG-expatObj"><i>expatObj</i></a>)
</pre>

  <h2><a name="SECTid0x1eef570">ARGUMENTS</a></h2><div class="arglist"><table width="100%" rules="none" cellpadding="5%">
<thead><tr class="heading">
<th width="20%">Type</th><th width="70%">Name</th><th width="10%">Mode</th>
</tr></thead><tr class="syntax">
<td class="type" width="20%" align="left">Tcl_Interp</td><td class="name" width="70%" align="left"><a name="ARG-interp">*interp</a></td><td class="mode" width="10%" align="center">in</td>
</tr><tr class="desc">
<td class="padding" width="20%">ย </td><td class="argdesc" width="80%" align="left" colspan="2">Interpreter with the expat parser object.</td>
</tr><tr class="syntax">
<td class="type" width="20%" align="left">Tcl_Obj</td><td class="name" width="70%" align="left"><a name="ARG-expatObj">*expatObj</a></td><td class="mode" width="10%" align="center">in</td>
</tr><tr class="desc">
<td class="padding" width="20%">ย </td><td class="argdesc" width="80%" align="left" colspan="2">A Tcl Object containing the command name of the expat parser object to be queried or modified.</td>
</tr><tr class="syntax">
<td class="type" width="20%" align="left">char</td><td class="name" width="70%" align="left"><a name="ARG-handlerSetName">*handlerSetName</a></td><td class="mode" width="10%" align="center">in</td>
</tr><tr class="desc">
<td class="padding" width="20%">ย </td><td class="argdesc" width="80%" align="left" colspan="2">Identifier of the handler set.</td>
</tr><tr class="syntax">
<td class="type" width="20%" align="left">CHandlerSet</td><td class="name" width="70%" align="left"><a name="ARG-handlerSet">*handlerSet</a></td><td class="mode" width="10%" align="center">in</td>
</tr><tr class="desc">
<td class="padding" width="20%">ย </td><td class="argdesc" width="80%" align="left" colspan="2">Pointer to a C handler set.</td>
</tr><tr class="syntax">
<td class="type" width="20%" align="left">Tcl_Obj</td><td class="name" width="70%" align="left"><a name="ARG-nameObj">*nameObj</a></td><td class="mode" width="10%" align="center"></td>
</tr><tr class="desc">
<td class="padding" width="20%">ย </td><td class="argdesc" width="80%" align="left" colspan="2">A Tcl Object containing the name of a expat parser object</td>
</tr>
</table></div>

  <h2><a name="SECTid0x1ef1660">DESCRIPTION</a></h2><p>The functions described in this manual allows one to add C level coded event
handler to an tDOM Tcl expat parser objects. A tDOM Tcl expat parser object is
able to have several Tcl scripts and C functions associated with an specific
event. If the event occurs, first the Tcl scripts then the C functions
associated with the event are called in turn.</p><p>A tDOM Tcl expat parser extension is an ordinary Tcl extension and loaded
like every other Tcl extension. It must install at least one new Tcl Level
command, that manipulates a tDOM Tcl expat parser object.</p><p>A C level handler set is a data structure like this:</p><pre class="example">
typedef struct CHandlerSet {
    struct CHandlerSet *nextHandlerSet;
    char *name;                     /* refname of the handler set */
    int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */

    void *userData;                 /* Handler set specific Data Structure;
                                       the C handler set extension has to
                                       malloc the needed structure in his
                                       init func and has to provide a
                                       cleanup func (to free it). */

    CHandlerSet_userDataReset        resetProc;
    CHandlerSet_userDataFree         freeProc;

................................................................................
    XML_NotationDeclHandler          notationcommand;
    /* C func for external entity */
    XML_ExternalEntityRefHandler     externalentitycommand;
    /* C func for unknown encoding */
    XML_UnknownEncodingHandler       unknownencodingcommand;
    /* C func for comments */
    XML_CommentHandler               commentCommand;
    /* C func for "not standalone" docs */
    XML_NotStandaloneHandler         notStandaloneCommand;
    /* C func for CDATA section start */
    XML_StartCdataSectionHandler     startCdataSectionCommand;
    /* C func for CDATA section end */
    XML_EndCdataSectionHandler       endCdataSectionCommand;
    /* C func for !ELEMENT decl's */
    XML_ElementDeclHandler           elementDeclCommand;
................................................................................
initialized to NULL by CHandlerSetCreate).</p><p>The <i class="m">name</i> of this structure is used to identify the handler set.
</p><p>If the flag <i class="m">ignoreWhiteCDATAs</i> is set, element content which
contain only whitespace isn't reported with the datacommand.  </p><p>The <i class="m">userData</i> element points to the handler set specific data. The
event handler functions are called with this pointer as userData argument.
</p><p>
<i class="m">resetProc</i> and <i class="m">freeProc</i> must have arguments that match the
type</p><pre class="syntax">void (Tcl_Interp *interp, void *userData)</pre><p>
<i class="m">resetProc</i> is called in case the parser is reset with
<tt class="samp">&lt;parserObj&gt; reset</tt> and should do any necessary cleanup and
reinitializing to prepare the C handler set for a new XML document. The
<i class="m">freeProc</i> is called, if the parser is deleted and should do memory
cleanup etc.  </p><p> <i class="m">CHandlerSetCreate</i> create a C handler set, gives it the name
<i class="m">name</i> and initializes any other element with NULL.</p><p> <i class="m">CHandlerSetInstall</i> adds the <i class="m">handlerSet</i> to the parser
<i class="m">expatObj</i>. The parser has to be a tDOM Tcl expat parser object in the
interpreter <i class="m">interp</i>. The name of the C handler set has to be unique for
................................................................................
parser object in the interpreter <i class="m">interp</i>, otherwise it returns
0. Example:</p><pre class="example">
int
TclExampleObjCmd(dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *const objv[];
{
    char          *method;
    CHandlerSet   *handlerSet;
    int            methodIndex, result;
    simpleCounter *counter;
    

    static char *exampleMethods[] = {
        "enable", "getresult", "remove",
        NULL
    };
    enum exampleMethod {
        m_enable, m_getresult, m_remove
    };

    if (objc != 3) {
        Tcl_WrongNumArgs (interp, 1, objv, example_usage);
        return TCL_ERROR;
    }

    if (!CheckExpatParserObj (interp, objv[1])) {
        Tcl_SetResult (interp, "First argument has to be a expat parser object", NULL);
        return TCL_ERROR;
    }
    /* ... */
</pre><p> <i class="m">CHandlerSetGet</i> returns a pointer to the C handler Set referenced
by the name <i class="m">handlerSetName</i> of the parser object
<i class="m">expatObj</i>. <i class="m">expatObj</i> has to be an expat parser object in the
interpreter <i class="m">interp</i>. Returns NULL in case of error.</p><p>
................................................................................
TclGenExpatInfo structure of the tDOM Tcl expat parser object
<i class="m">expatObj</i>. The <i class="m">expatObj</i> has to be a tDOM Tcl expat parser object
in the interpreter <i class="m">interp</i>. This is most useful, to set the application
status of the parser object.</p><p>See the simple but full functionally example in the extensions/example
dir or the more complex example tnc in the extensions/tnc dir (a simple DTD
validation extension).</p>

  <h2><a name="SECTid0x1ea6080">SEE ALSO</a></h2><p class="seealso">expat</p>

  <h2><a name="SECTid0x1ea6320">KEYWORDS</a></h2><p class="keywords"><a class="keyword" href="keyword-index.html#KW-Chandlerset">C handler set</a></p>
</div><hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>




</div>
</body>
</html>

Changes to doc/expatapi.n.

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
...
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
.AP CHandlerSet "*handlerSet" in
Pointer to a C handler set.
.AP Tcl_Obj "*nameObj" ""
A Tcl Object containing the name of a expat parser object
.BE
.SH DESCRIPTION
.PP
The functions described in this manual allows to add C level coded event
handler to an tDOM Tcl expat parser objects. A tDOM Tcl expat parser object is
able to have several Tcl scripts and C functions associated with an specific
event. If the event occurs, first the Tcl scripts then the C functions
associated with the event are called in turn.
.PP
A tDOM Tcl expat parser extension is an ordinary Tcl extension and loaded
like every other Tcl extension. It must install at least one new Tcl Level
................................................................................

typedef struct CHandlerSet {
    struct CHandlerSet *nextHandlerSet;
    char *name;                     /* refname of the handler set */
    int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */

    void *userData;                 /* Handler set specific Data Structure;
                                       the C handler set extention has to
                                       malloc the needed structure in his
                                       init func and has to provide a
                                       cleanup func (to free it). */

    CHandlerSet_userDataReset        resetProc;
    CHandlerSet_userDataFree         freeProc;

................................................................................
.PP
\&\fIresetProc\fR and \fIfreeProc\fR must have arguments that match the
type
.CS
void (Tcl_Interp *interp, void *userData)
.CE
.PP
\&\fIresetProc\fR is called in case the parser is reseted with
\&\fB<parserObj> reset\fR and should do any necessary cleanup and
reinitializing to prepare the C handler set for a new XML document. The
\&\fIfreeProc\fR is called, if the parser is deleted and should do memory
cleanup etc.
.PP
\&\fICHandlerSetCreate\fR create a C handler set, gives it the name
\&\fIname\fR and initializes any other element with NULL.
................................................................................
.CS

int
TclExampleObjCmd(dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *CONST objv[];
{
    char          *method;
    CHandlerSet   *handlerSet;
    int            methodIndex, result;
    simpleCounter *counter;
    








|







 







|







 







|







 







|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
...
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
.AP CHandlerSet "*handlerSet" in
Pointer to a C handler set.
.AP Tcl_Obj "*nameObj" ""
A Tcl Object containing the name of a expat parser object
.BE
.SH DESCRIPTION
.PP
The functions described in this manual allows one to add C level coded event
handler to an tDOM Tcl expat parser objects. A tDOM Tcl expat parser object is
able to have several Tcl scripts and C functions associated with an specific
event. If the event occurs, first the Tcl scripts then the C functions
associated with the event are called in turn.
.PP
A tDOM Tcl expat parser extension is an ordinary Tcl extension and loaded
like every other Tcl extension. It must install at least one new Tcl Level
................................................................................

typedef struct CHandlerSet {
    struct CHandlerSet *nextHandlerSet;
    char *name;                     /* refname of the handler set */
    int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */

    void *userData;                 /* Handler set specific Data Structure;
                                       the C handler set extension has to
                                       malloc the needed structure in his
                                       init func and has to provide a
                                       cleanup func (to free it). */

    CHandlerSet_userDataReset        resetProc;
    CHandlerSet_userDataFree         freeProc;

................................................................................
.PP
\&\fIresetProc\fR and \fIfreeProc\fR must have arguments that match the
type
.CS
void (Tcl_Interp *interp, void *userData)
.CE
.PP
\&\fIresetProc\fR is called in case the parser is reset with
\&\fB<parserObj> reset\fR and should do any necessary cleanup and
reinitializing to prepare the C handler set for a new XML document. The
\&\fIfreeProc\fR is called, if the parser is deleted and should do memory
cleanup etc.
.PP
\&\fICHandlerSetCreate\fR create a C handler set, gives it the name
\&\fIname\fR and initializes any other element with NULL.
................................................................................
.CS

int
TclExampleObjCmd(dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *const objv[];
{
    char          *method;
    CHandlerSet   *handlerSet;
    int            methodIndex, result;
    simpleCounter *counter;
    

Changes to doc/expatapi.xml.

1
2
3
4
5
6
7
8
..
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
  <manpage id="expatapi" cat="fun" title="expatapi">
    <namesection>
      <name>CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove,
         CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo</name>

      <desc>Functions to create, install and remove expat parser object
extensions.</desc>
    </namesection>
................................................................................
        <desc>A Tcl Object containing the name of a expat parser object</desc>
      </argdef>
    </arglist>
  </section>

  <section>
    <title>DESCRIPTION</title>
<p>The functions described in this manual allows to add C level coded event
handler to an tDOM Tcl expat parser objects. A tDOM Tcl expat parser object is
able to have several Tcl scripts and C functions associated with an specific
event. If the event occurs, first the Tcl scripts then the C functions
associated with the event are called in turn.</p>  

<p>A tDOM Tcl expat parser extension is an ordinary Tcl extension and loaded
like every other Tcl extension. It must install at least one new Tcl Level
................................................................................
<example>
typedef struct CHandlerSet {
    struct CHandlerSet *nextHandlerSet;
    char *name;                     /* refname of the handler set */
    int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */

    void *userData;                 /* Handler set specific Data Structure;
                                       the C handler set extention has to
                                       malloc the needed structure in his
                                       init func and has to provide a
                                       cleanup func (to free it). */

    CHandlerSet_userDataReset        resetProc;
    CHandlerSet_userDataFree         freeProc;

................................................................................
event handler functions are called with this pointer as userData argument.
</p>

    <p><m>resetProc</m> and <m>freeProc</m> must have arguments that match the
type</p>
    <syntax>void (Tcl_Interp *interp, void *userData)</syntax>

    <p><m>resetProc</m> is called in case the parser is reseted with
<samp>&lt;parserObj&gt; reset</samp> and should do any necessary cleanup and
reinitializing to prepare the C handler set for a new XML document. The
<m>freeProc</m> is called, if the parser is deleted and should do memory
cleanup etc.  </p>

    <p> <m>CHandlerSetCreate</m> create a C handler set, gives it the name
<m>name</m> and initializes any other element with NULL.</p>
................................................................................

<example>
int
TclExampleObjCmd(dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *CONST objv[];
{
    char          *method;
    CHandlerSet   *handlerSet;
    int            methodIndex, result;
    simpleCounter *counter;
    

|







 







|







 







|







 







|







 







|







1
2
3
4
5
6
7
8
..
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
<manpage id="expatapi" cat="fun" title="expatapi">
    <namesection>
      <name>CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove,
         CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo</name>

      <desc>Functions to create, install and remove expat parser object
extensions.</desc>
    </namesection>
................................................................................
        <desc>A Tcl Object containing the name of a expat parser object</desc>
      </argdef>
    </arglist>
  </section>

  <section>
    <title>DESCRIPTION</title>
<p>The functions described in this manual allows one to add C level coded event
handler to an tDOM Tcl expat parser objects. A tDOM Tcl expat parser object is
able to have several Tcl scripts and C functions associated with an specific
event. If the event occurs, first the Tcl scripts then the C functions
associated with the event are called in turn.</p>  

<p>A tDOM Tcl expat parser extension is an ordinary Tcl extension and loaded
like every other Tcl extension. It must install at least one new Tcl Level
................................................................................
<example>
typedef struct CHandlerSet {
    struct CHandlerSet *nextHandlerSet;
    char *name;                     /* refname of the handler set */
    int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */

    void *userData;                 /* Handler set specific Data Structure;
                                       the C handler set extension has to
                                       malloc the needed structure in his
                                       init func and has to provide a
                                       cleanup func (to free it). */

    CHandlerSet_userDataReset        resetProc;
    CHandlerSet_userDataFree         freeProc;

................................................................................
event handler functions are called with this pointer as userData argument.
</p>

    <p><m>resetProc</m> and <m>freeProc</m> must have arguments that match the
type</p>
    <syntax>void (Tcl_Interp *interp, void *userData)</syntax>

    <p><m>resetProc</m> is called in case the parser is reset with
<samp>&lt;parserObj&gt; reset</samp> and should do any necessary cleanup and
reinitializing to prepare the C handler set for a new XML document. The
<m>freeProc</m> is called, if the parser is deleted and should do memory
cleanup etc.  </p>

    <p> <m>CHandlerSetCreate</m> create a C handler set, gives it the name
<m>name</m> and initializes any other element with NULL.</p>
................................................................................

<example>
int
TclExampleObjCmd(dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *const objv[];
{
    char          *method;
    CHandlerSet   *handlerSet;
    int            methodIndex, result;
    simpleCounter *counter;
    

Changes to doc/index.html.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
<head>
<title>tDOM manual</title><link rel="stylesheet" href="manpage.css"><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile$ $Revision$">
</head><body>
<div class="header">
<h1 class="title" align="center">tDOM manual: Contents</h1><p class="navaid" align="center">
<a class="navaid" href="index.html">Contents</a> <a class="navaid" href="category-index.html">Index</a> ท <a class="navaid" href="keyword-index.html">Keywords</a>
</p><hr class="navsep">
</div><div class="body"><ul class="toc">
<li class="tocentry"><a href="dom.html">dom - Create an in-memory DOM tree from XML</a></li><li class="tocentry"><a href="domDoc.html">domDoc - Manipulates an instance of a DOM document object</a></li><li class="tocentry"><a href="domNode.html">domNode - Manipulates an instance of a DOM node object</a></li><li class="tocentry"><a href="expat.html">expat - Creates an instance of an expat parser object</a></li><li class="tocentry"><a href="expatapi.html">expatapi - Functions to create, install and remove expat parser object
extensions.</a></li><li class="tocentry"><a href="tdomcmd.html">tdom - tdom is an expat parser object extension to create an in-memory
DOM tree from the input while parsing.</a></li><li class="tocentry"><a href="tnc.html">tnc - tnc is an expat parser object extension, that validates the XML
stream against the document DTD while parsing.</a></li>
</ul></div><div class="footer">
<hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> <a class="navaid" href="category-index.html">Index</a> ท <a class="navaid" href="keyword-index.html">Keywords</a>
</div>
</div>
</body>
</html>


|



|



|




|




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
<head>
<title>tDOM manual</title><link rel="stylesheet" href="manpage.css"><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: master-index.xsl,v $ $Revision: 1.6 $"><meta charset="utf-8">
</head><body>
<div class="header">
<h1 class="title" align="center">tDOM manual: Contents</h1><p class="navaid" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>
</p><hr class="navsep">
</div><div class="body"><ul class="toc">
<li class="tocentry"><a href="dom.html">dom - Create an in-memory DOM tree from XML</a></li><li class="tocentry"><a href="domDoc.html">domDoc - Manipulates an instance of a DOM document object</a></li><li class="tocentry"><a href="domNode.html">domNode - Manipulates an instance of a DOM node object</a></li><li class="tocentry"><a href="expat.html">expat - Creates an instance of an expat parser object</a></li><li class="tocentry"><a href="expatapi.html">expatapi - Functions to create, install and remove expat parser object
extensions.</a></li><li class="tocentry"><a href="pullparser.html">pullparser - Create an XML pull parser command</a></li><li class="tocentry"><a href="tdomcmd.html">tdom - tdom is an expat parser object extension to create an in-memory
DOM tree from the input while parsing.</a></li><li class="tocentry"><a href="tnc.html">tnc - tnc is an expat parser object extension, that validates the XML
stream against the document DTD while parsing.</a></li>
</ul></div><div class="footer">
<hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>
</div>
</div>
</body>
</html>

Changes to doc/keyword-index.html.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
35
36
37
38
39
40
41
42
43
44
45
46
47








48
49
50
51
52
53
54


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<html>
<head>
<title>tDOM manual: Keyword Index</title><link rel="stylesheet" href="manpage.css"><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile$ $Revision$">
</head><body>
<div class="header">
<h1 class="title" align="center">tDOM manual: Keywords</h1><p class="navaid" align="center">
<a class="navaid" href="index.html">Contents</a> <a class="navaid" href="category-index.html">Index</a> ท <a class="navaid" href="keyword-index.html">Keywords</a>
</p><hr class="navsep"><div class="navbar">
<a href="#KEYWORDS-C">C</a> ท <a href="#KEYWORDS-D">D</a> ท <a href="#KEYWORDS-E">E</a> ท <a href="#KEYWORDS-N">N</a> ท <a href="#KEYWORDS-P">P</a> ท <a href="#KEYWORDS-S">S</a> ท <a href="#KEYWORDS-T">T</a> ท <a href="#KEYWORDS-V">V</a> ท <a href="#KEYWORDS-X">X</a> ท </div>
</div><div class="body"><div class="table"><table width="100%">
<tr class="header"><th colspan="2"><a name="KEYWORDS-C">Keywords: C</a></th></tr><tr class="row1">
<td width="35%"><a name="KW-Chandlerset">C handler set</a></td><td width="65%">
<a href="expatapi.html">expatapi</a> <a href="tdomcmd.html">tdom</a>
</td>
</tr><tr class="row0">
<td width="35%"><a name="KW-CheckExpatParserObj,CHandlerSetInstall,CHandlerSetRemove,CHandlerSetCreate,CHandlerSetGetUserData,GetExpatInfo">CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove,
         CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo</a></td><td width="65%"><a href="expatapi.html">expatapi</a></td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-D">Keywords: D</a></th></tr><tr class="row1">
<td width="35%"><a name="KW-Document">Document</a></td><td width="65%">
<a href="dom.html">dom</a> <a href="domNode.html">domNode</a>
</td>
</tr><tr class="row0">
<td width="35%"><a name="KW-documentelement">document element</a></td><td width="65%"><a href="domDoc.html">domDoc</a></td>
</tr><tr class="row1">
<td width="35%"><a name="KW-dom">dom</a></td><td width="65%">
<a href="dom.html">dom</a> <a href="domNode.html">domNode</a> <a href="tdomcmd.html">tdom</a>
</td>
</tr><tr class="row0">
<td width="35%"><a name="KW-DOMnodecreation">DOM node creation</a></td><td width="65%"><a href="domDoc.html">domDoc</a></td>
</tr><tr class="row1">
<td width="35%"><a name="KW-domDoc">domDoc</a></td><td width="65%"><a href="domDoc.html">domDoc</a></td>
</tr><tr class="row0">
<td width="35%"><a name="KW-domNode">domNode</a></td><td width="65%"><a href="domNode.html">domNode</a></td>
................................................................................
<td width="35%"><a name="KW-DTD">DTD</a></td><td width="65%"><a href="tnc.html">tnc</a></td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-E">Keywords: E</a></th></tr><tr class="row0">
<td width="35%"><a name="KW-expat">expat</a></td><td width="65%"><a href="expat.html">expat</a></td>
</tr><tr class="row1">
<td width="35%"><a name="KW-expatapi">expatapi</a></td><td width="65%"><a href="expatapi.html">expatapi</a></td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-N">Keywords: N</a></th></tr><tr class="row0">
<td width="35%"><a name="KW-node">node</a></td><td width="65%">
<a href="dom.html">dom</a> <a href="domNode.html">domNode</a>
</td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-P">Keywords: P</a></th></tr><tr class="row1">
<td width="35%"><a name="KW-parsing">parsing</a></td><td width="65%">
<a href="dom.html">dom</a> <a href="domNode.html">domNode</a>
</td>








</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-S">Keywords: S</a></th></tr><tr class="row0">
<td width="35%"><a name="KW-SAX">SAX</a></td><td width="65%">
<a href="expat.html">expat</a> <a href="tdomcmd.html">tdom</a>
</td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-T">Keywords: T</a></th></tr><tr class="row1">
<td width="35%"><a name="KW-tdom">tdom</a></td><td width="65%"><a href="tdomcmd.html">tdom</a></td>
</tr><tr class="row0">


<td width="35%"><a name="KW-tdomcmd">tdomcmd</a></td><td width="65%"><a href="tdomcmd.html">tdom</a></td>
</tr><tr class="row1">
<td width="35%"><a name="KW-tnc">tnc</a></td><td width="65%"><a href="tnc.html">tnc</a></td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-V">Keywords: V</a></th></tr><tr class="row0">
<td width="35%"><a name="KW-Validation">Validation</a></td><td width="65%"><a href="tnc.html">tnc</a></td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-X">Keywords: X</a></th></tr><tr class="row1">
<td width="35%"><a name="KW-XML">XML</a></td><td width="65%">
<a href="dom.html">dom</a> <a href="domNode.html">domNode</a>
</td>
</tr><tr class="row0">
<td width="35%"><a name="KW-xml::parser">xml::parser</a></td><td width="65%"><a href="expat.html">expat</a></td>
</tr>
</table></div></div><div class="footer">
<hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> <a class="navaid" href="category-index.html">Index</a> ท <a class="navaid" href="keyword-index.html">Keywords</a>
</div>
</div>
</body>
</html>


|



|

|



|





|
|





|







 







|



|

>
>
>
>
>
>
>
>


|




>
>

|

|

|

|

|




|




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<html>
<head>
<title>tDOM manual: Keyword Index</title><link rel="stylesheet" href="manpage.css"><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: make-keywords.xsl,v $ $Revision: 1.5 $"><meta charset="utf-8">
</head><body>
<div class="header">
<h1 class="title" align="center">tDOM manual: Keywords</h1><p class="navaid" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>
</p><hr class="navsep"><div class="navbar">
<a href="#KEYWORDS-C">C</a> ยท <a href="#KEYWORDS-D">D</a> ยท <a href="#KEYWORDS-E">E</a> ยท <a href="#KEYWORDS-N">N</a> ยท <a href="#KEYWORDS-P">P</a> ยท <a href="#KEYWORDS-S">S</a> ยท <a href="#KEYWORDS-T">T</a> ยท <a href="#KEYWORDS-V">V</a> ยท <a href="#KEYWORDS-X">X</a> ยท </div>
</div><div class="body"><div class="table"><table width="100%">
<tr class="header"><th colspan="2"><a name="KEYWORDS-C">Keywords: C</a></th></tr><tr class="row1">
<td width="35%"><a name="KW-Chandlerset">C handler set</a></td><td width="65%">
<a href="expatapi.html">expatapi</a> ยท <a href="tdomcmd.html">tdom</a>
</td>
</tr><tr class="row0">
<td width="35%"><a name="KW-CheckExpatParserObj,CHandlerSetInstall,CHandlerSetRemove,CHandlerSetCreate,CHandlerSetGetUserData,GetExpatInfo">CheckExpatParserObj, CHandlerSetInstall, CHandlerSetRemove,
         CHandlerSetCreate, CHandlerSetGetUserData, GetExpatInfo</a></td><td width="65%"><a href="expatapi.html">expatapi</a></td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-D">Keywords: D</a></th></tr><tr class="row1">
<td width="35%"><a name="KW-document">document</a></td><td width="65%">
<a href="dom.html">dom</a> ยท <a href="domNode.html">domNode</a>
</td>
</tr><tr class="row0">
<td width="35%"><a name="KW-documentelement">document element</a></td><td width="65%"><a href="domDoc.html">domDoc</a></td>
</tr><tr class="row1">
<td width="35%"><a name="KW-dom">dom</a></td><td width="65%">
<a href="dom.html">dom</a> ยท <a href="domNode.html">domNode</a> ยท <a href="tdomcmd.html">tdom</a>
</td>
</tr><tr class="row0">
<td width="35%"><a name="KW-DOMnodecreation">DOM node creation</a></td><td width="65%"><a href="domDoc.html">domDoc</a></td>
</tr><tr class="row1">
<td width="35%"><a name="KW-domDoc">domDoc</a></td><td width="65%"><a href="domDoc.html">domDoc</a></td>
</tr><tr class="row0">
<td width="35%"><a name="KW-domNode">domNode</a></td><td width="65%"><a href="domNode.html">domNode</a></td>
................................................................................
<td width="35%"><a name="KW-DTD">DTD</a></td><td width="65%"><a href="tnc.html">tnc</a></td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-E">Keywords: E</a></th></tr><tr class="row0">
<td width="35%"><a name="KW-expat">expat</a></td><td width="65%"><a href="expat.html">expat</a></td>
</tr><tr class="row1">
<td width="35%"><a name="KW-expatapi">expatapi</a></td><td width="65%"><a href="expatapi.html">expatapi</a></td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-N">Keywords: N</a></th></tr><tr class="row0">
<td width="35%"><a name="KW-node">node</a></td><td width="65%">
<a href="dom.html">dom</a> ยท <a href="domNode.html">domNode</a>
</td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-P">Keywords: P</a></th></tr><tr class="row1">
<td width="35%"><a name="KW-parsing">parsing</a></td><td width="65%">
<a href="dom.html">dom</a> ยท <a href="domNode.html">domNode</a> ยท <a href="pullparser.html">pullparser</a>
</td>
</tr><tr class="row0">
<td width="35%"><a name="KW-pull">pull</a></td><td width="65%"><a href="pullparser.html">pullparser</a></td>
</tr><tr class="row1">
<td width="35%"><a name="KW-pullparser">pullparser</a></td><td width="65%"><a href="pullparser.html">pullparser</a></td>
</tr><tr class="row0">
<td width="35%"><a name="KW-push">push</a></td><td width="65%"><a href="expat.html">expat</a></td>
</tr><tr class="row1">
<td width="35%"><a name="KW-pushparser">pushparser</a></td><td width="65%"><a href="expat.html">expat</a></td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-S">Keywords: S</a></th></tr><tr class="row0">
<td width="35%"><a name="KW-SAX">SAX</a></td><td width="65%">
<a href="expat.html">expat</a> ยท <a href="tdomcmd.html">tdom</a>
</td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-T">Keywords: T</a></th></tr><tr class="row1">
<td width="35%"><a name="KW-tdom">tdom</a></td><td width="65%"><a href="tdomcmd.html">tdom</a></td>
</tr><tr class="row0">
<td width="35%"><a name="KW-tDOM::pullparser">tDOM::pullparser</a></td><td width="65%"><a href="pullparser.html">pullparser</a></td>
</tr><tr class="row1">
<td width="35%"><a name="KW-tdomcmd">tdomcmd</a></td><td width="65%"><a href="tdomcmd.html">tdom</a></td>
</tr><tr class="row0">
<td width="35%"><a name="KW-tnc">tnc</a></td><td width="65%"><a href="tnc.html">tnc</a></td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-V">Keywords: V</a></th></tr><tr class="row1">
<td width="35%"><a name="KW-Validation">Validation</a></td><td width="65%"><a href="tnc.html">tnc</a></td>
</tr><tr class="header"><th colspan="2"><a name="KEYWORDS-X">Keywords: X</a></th></tr><tr class="row0">
<td width="35%"><a name="KW-XML">XML</a></td><td width="65%">
<a href="dom.html">dom</a> ยท <a href="domNode.html">domNode</a> ยท <a href="pullparser.html">pullparser</a>
</td>
</tr><tr class="row1">
<td width="35%"><a name="KW-xml::parser">xml::parser</a></td><td width="65%"><a href="expat.html">expat</a></td>
</tr>
</table></div></div><div class="footer">
<hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>
</div>
</div>
</body>
</html>

Changes to doc/manpage.css.

1
2
3
4
5
6
7
8
9
/*
 * $Id$
 * Author: 	Joe English, <jenglish@flightab.com>
 * Created: 	26 Jun 2000
 * Description:	CSS stylesheet for TCL man pages
 */

HTML {
    background: 	#FFFFFF;

|







1
2
3
4
5
6
7
8
9
/*
 * $Id: manpage.css,v 1.4 2002/06/20 00:44:17 jenglish Exp $
 * Author: 	Joe English, <jenglish@flightab.com>
 * Created: 	26 Jun 2000
 * Description:	CSS stylesheet for TCL man pages
 */

HTML {
    background: 	#FFFFFF;

Added doc/pullparser.html.



















































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: pullparser</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: tmml-html.xsl,v $ $Revision: 1.11 $"><meta charset="utf-8">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid0x11bc970">NAME</a> ยท <a href="#SECTid0x10a6540">SYNOPSIS</a> ยท <a href="#SECTid0x10bbbc0">DESCRIPTION </a> ยท <a href="#SECTid0x11e0cb0">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
  <h2><a name="SECTid0x11bc970">NAME</a></h2><p class="namesection">
<b class="names">tdom::pullparser - </b><br>Create an XML pull parser command</p>

  <h2><a name="SECTid0x10a6540">SYNOPSIS</a></h2><pre class="syntax">package require tdom

    <b class="cmd">tdom::pullparser</b> <i class="m">cmdName</i>  ? -ignorewhitecdata ? 
    </pre>

  <h2><a name="SECTid0x10bbbc0">DESCRIPTION </a></h2><p>This command creates XML pull parser commands with a simple
    API, along the lines of a simple StAX parser. After creation,
    you've to set an input source, to do anything useful with the pull
    parser. For this see the methods <i class="m">input</i>, <i class="m">inputchannel</i>
    and <i class="m">inputfile</i>.</p><p>The parser has always a <i class="m">state</i>. You start parsing the XML
    data until some next state, do what has to be done and skip again
    to the next state. XML well-formedness errors along the way will
    be reported as TCL_ERROR with additional info in the error
    message.</p><p>The pull parsers don't follow external entities and are XML
    1.0 only, they know nothing about XML Namespaces. You get the tags
    and attribute names as in the source. You aren't noticed about
    comments, processing instructions and external entities; they are
    silently ignored for you. CDATA Sections are handled as if their
    content would have been provided without using a CDATA Section.
    </p><p>On the brighter side is that character entity and attribute
    default declarations in the internal subset are respected (because
    of using expat as underlying parser). It is probably somewhat
    faster than a comperable implementation with the SAX interface.
    It's a nice programming model. It's a slim interface.
    </p><p>If the option <i class="m">-ignorewhitecdata</i> is given, the created
    XML pull parser command will ignore any white space only ('ย ', \t,
    \n and \r) text content between START_TAG and START_TAG / END_TAG.
    The parser won't stop at such input and will create TEXT state
    events only for not white space only text. </p><p>Not all methods are valid in every state. The parser will raise
    TCL_ERROR if a method is called in a state the method isn't valid
    for. Valid methods of the created commands are:</p><dl class="commandlist">
      
        <dt><b class="method">state</b></dt>
        <dd>This method is valid in all parser states. The
        possible return values and their meanings are:
        <ul>
            <li>
<i class="m">READY</i> - The parser is created or reset, but no
            input is set.</li>
            <li>
<i class="m">START_DOCUMENT</i> - Input is set, parser is ready
            to start parsing.</li>
            <li>
<i class="m">START_TAG</i> - Parser has stopped parsing at a
            start tag.</li>
            <li>
<i class="m">END_TAG</i> - Parser has stopped parsing at an end tag</li>
            <li>
<i class="m">TEXT</i> - Parser has stopped parsing to report
            text between tags.</li>
            <li>
<i class="m">END_DOKUMENT</i> - Parser has finished parsing
            without error.</li>
            <li>
<i class="m">PARSE_ERROR</i> - Parser stopped parsing at XML
            error in input.</li>
        </ul>
        </dd>
      

      
        <dt>
<b class="method">input</b> <i class="m">data</i>
</dt>
        <dd>This method is only valid in state <i class="m">READY</i>. It
        prepares the parser to use <i class="m">data</i> as XML input to parse
        and switches the parser into state START_DOCUMENT.</dd>
      

      
        <dt>
<b class="method">inputchannel</b> <i class="m">channel</i>
</dt>
        <dd>This method is only valid in state <i class="m">READY</i>. It
        prepares the parser to read the XML input to parse out of
        <i class="m">channel</i> and switches the parser into state START_DOCUMENT.</dd>
      

      
        <dt>
<b class="method">inputfile</b> <i class="m">filename</i>
</dt>
        <dd>This method is only valid in state <i class="m">READY</i>. It
        open <i class="m">filename</i> and prepares the parser to read the XML
        input to parse out of that file. The method returns TCL_ERROR,
        if the file could not be open in read mode. Otherwise it
        switches the parser into state START_DOCUMENT.</dd>
      

      
        <dt><b class="method">next</b></dt>
        <dd>This method is valid in state <i class="m">START_DOCUMENT</i>,
        <i class="m">START_TAG</i>, <i class="m">END_TAG</i> and <i class="m">TEXT</i>. It continues
        parsing of the XML input until the next event, which it will
        return.</dd>
      

      
        <dt><b class="method">tag</b></dt>
        <dd>This method is only valid in states <i class="m">START_TAG</i> and
        <i class="m">END_TAG</i>. It returns the tag name of the current start
        or end tag.</dd>
      

      
        <dt><b class="method">attributes</b></dt>
        <dd>This method is only valid in state <i class="m">START_TAG</i>. It
        returns all attributes of the element in a name value list.</dd>
      

      
        <dt><b class="method">text</b></dt>
        <dd>This method is only valid in state <i class="m">TEXT</i>. It
        returns the character data of the event. There will be always
        at most one TEXT event between START_TAG and the next
        START_TAG or END_TAG event.</dd>
      

      
        <dt><b class="method">skip</b></dt>
        <dd>This method is only valid in state <i class="m">START_TAG</i>. It
        skips to the corresponding end tag and ignores all events (but
        not XML parsing errors) on the way and returns the new state
        END_TAG.</dd>
      

      
        <dt>
<b class="method">find-element</b> <i class="m">tagname</i>
</dt>
        <dd>This method is only valid in states
        <i class="m">START_DOCUMENT</i>, <i class="m">START_TAG</i> and <i class="m">END_TAG</i>. It
        skips forward until the next element start tag with tag name
        <i class="m">tagname</i> and returns the new start START_TAG. If there
        isn't such an element the parser stops at the end of the input
        and returns END_DOCUMENT.</dd>
      

      
        <dt><b class="method">reset</b></dt>
        <dd>This method is valid in all parser states. It resets the
        parser into READY state and returns that.</dd>
      

      
        <dt><b class="method">delete</b></dt>
        <dd>This method is valid in all parser states. It deletes
        the parser command.</dd>
      
    </dl><p>Miscellaneous methods:</p><dl class="commandlist">
      
        <dt><b class="method">line</b></dt>
        <dd>This method is valid in all parser states except READY
        and TEXT. It returns the line number of the parsing
        position.</dd>
      

      
        <dt><b class="method">line</b></dt>
        <dd>This method is valid in all parser states except READY
        and TEXT. It returns the offset, from the beginning of the
        current line, of the parsing position.</dd>
      
    </dl>

  <h2><a name="SECTid0x11e0cb0">KEYWORDS</a></h2><p class="keywords">
<a class="keyword" href="keyword-index.html#KW-XML">XML</a>, <a class="keyword" href="keyword-index.html#KW-pull">pull</a>, <a class="keyword" href="keyword-index.html#KW-parsing">parsing</a>
</p>
</div><hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>
</div>
</body>
</html>

Added doc/pullparser.n.







































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
'\"
'\" Generated from pullparser.xml
'\"
'\" BEGIN man.macros
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
.   ie !"\\$2"" .TP \\n()Cu
.   el          .TP 15
.\}
.ta \\n()Au \\n()Bu
.ie !"\\$3"" \{\
\&\\$1	\\fI\\$2\\fP	(\\$3)
.\".b
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1	\\fI\\$2\\fP
.\}
.el \{\
\&\\fI\\$1\\fP
.\}
.\}
..
.de AS
.nr )A 10n
.if !"\\$1"" .nr )A \\w'\\$1'u+3n
.nr )B \\n()Au+15n
.\"
.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
.nr )C \\n()Bu+\\w'(in/out)'u+2n
..
.AS Tcl_Interp Tcl_CreateInterp in/out
.de BS
.br
.mk ^y
.nr ^b 1u
.if n .nf
.if n .ti 0
.if n \l'\\n(.lu\(ul'
.if n .fi
..
.de BE
.nf
.ti 0
.mk ^t
.ie n \l'\\n(^lu\(ul'
.el \{\
.\"	Draw four-sided box normally, but don't draw top of
.\"	box if the box started on an earlier page.
.ie !\\n(^b-1 \{\
\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.el \}\
\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.\}
.fi
.br
.nr ^b 0
..
.de VS
.if !"\\$2"" .br
.mk ^Y
.ie n 'mc \s12\(br\s0
.el .nr ^v 1u
..
.de VE
.ie n 'mc
.el \{\
.ev 2
.nf
.ti 0
.mk ^t
\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
.sp -1
.fi
.ev
.\}
.nr ^v 0
..
.de ^B
.ev 2
'ti 0
'nf
.mk ^t
.if \\n(^b \{\
.\"	Draw three-sided box if this is the box's first page,
.\"	draw two sides but no top otherwise.
.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.\}
.if \\n(^v \{\
.nr ^x \\n(^tu+1v-\\n(^Yu
\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
.\}
.bp
'fi
.ev
.if \\n(^b \{\
.mk ^y
.nr ^b 2
.\}
.if \\n(^v \{\
.mk ^Y
.\}
..
.de DS
.RS
.nf
.sp
..
.de DE
.fi
.RE
.sp
..
.de SO
.SH "STANDARD OPTIONS"
.LP
.nf
.ta 5.5c 11c
.ft B
..
.de SE
.fi
.ft R
.LP
See the \\fBoptions\\fR manual entry for details on the standard options.
..
.de OP
.LP
.nf
.ta 4c
Command-Line Name:	\\fB\\$1\\fR
Database Name:	\\fB\\$2\\fR
Database Class:	\\fB\\$3\\fR
.fi
.IP
..
.de CS
.RS
.nf
.ta .25i .5i .75i 1i
.if t .ft C
..
.de CE
.fi
.if t .ft R
.RE
..
.de UL
\\$1\l'|0\(ul'\\$2
..
'\" END man.macros
.TH pullparser n "" Tcl ""
.BS
.SH NAME
tdom::pullparser \- Create an XML pull parser command
.SH SYNOPSIS
.nf
package require tdom

    \fBtdom::pullparser\fP \fIcmdName\fR  \fR?\fP -ignorewhitecdata \fR?\fP 
    
.fi
.BE
.SH "DESCRIPTION "
.PP
This command creates XML pull parser commands with a simple
API, along the lines of a simple StAX parser. After creation,
you've to set an input source, to do anything useful with the pull
parser. For this see the methods \fIinput\fR, \fIinputchannel\fR
and \fIinputfile\fR.
.PP
The parser has always a \fIstate\fR. You start parsing the XML
data until some next state, do what has to be done and skip again
to the next state. XML well-formedness errors along the way will
be reported as TCL_ERROR with additional info in the error
message.
.PP
The pull parsers don't follow external entities and are XML
1.0 only, they know nothing about XML Namespaces. You get the tags
and attribute names as in the source. You aren't noticed about
comments, processing instructions and external entities; they are
silently ignored for you. CDATA Sections are handled as if their
content would have been provided without using a CDATA Section.
.PP
On the brighter side is that character entity and attribute
default declarations in the internal subset are respected (because
of using expat as underlying parser). It is probably somewhat
faster than a comperable implementation with the SAX interface.
It's a nice programming model. It's a slim interface.
.PP
If the option \fI-ignorewhitecdata\fR is given, the created
XML pull parser command will ignore any white space only ('ย ', \et,
\&\en and \er) text content between START_TAG and START_TAG / END_TAG.
The parser won't stop at such input and will create TEXT state
events only for not white space only text.
.PP
Not all methods are valid in every state. The parser will raise
TCL_ERROR if a method is called in a state the method isn't valid
for. Valid methods of the created commands are:
.TP
\&\fB\fBstate\fP
\&\fRThis method is valid in all parser states. The
possible return values and their meanings are:
.RS
.IP "\(bu"
\&\fIREADY\fR - The parser is created or reset, but no
input is set.
.IP "\(bu"
\&\fISTART_DOCUMENT\fR - Input is set, parser is ready
to start parsing.
.IP "\(bu"
\&\fISTART_TAG\fR - Parser has stopped parsing at a
start tag.
.IP "\(bu"
\&\fIEND_TAG\fR - Parser has stopped parsing at an end tag
.IP "\(bu"
\&\fITEXT\fR - Parser has stopped parsing to report
text between tags.
.IP "\(bu"
\&\fIEND_DOKUMENT\fR - Parser has finished parsing
without error.
.IP "\(bu"
\&\fIPARSE_ERROR\fR - Parser stopped parsing at XML
error in input.
.RE
.TP
\&\fB\fBinput\fP \fIdata\fB
\&\fRThis method is only valid in state \fIREADY\fR. It
prepares the parser to use \fIdata\fR as XML input to parse
and switches the parser into state START_DOCUMENT.
.TP
\&\fB\fBinputchannel\fP \fIchannel\fB
\&\fRThis method is only valid in state \fIREADY\fR. It
prepares the parser to read the XML input to parse out of
\&\fIchannel\fR and switches the parser into state START_DOCUMENT.
.TP
\&\fB\fBinputfile\fP \fIfilename\fB
\&\fRThis method is only valid in state \fIREADY\fR. It
open \fIfilename\fR and prepares the parser to read the XML
input to parse out of that file. The method returns TCL_ERROR,
if the file could not be open in read mode. Otherwise it
switches the parser into state START_DOCUMENT.
.TP
\&\fB\fBnext\fP
\&\fRThis method is valid in state \fISTART_DOCUMENT\fR,
\&\fISTART_TAG\fR, \fIEND_TAG\fR and \fITEXT\fR. It continues
parsing of the XML input until the next event, which it will
return.
.TP
\&\fB\fBtag\fP
\&\fRThis method is only valid in states \fISTART_TAG\fR and
\&\fIEND_TAG\fR. It returns the tag name of the current start
or end tag.
.TP
\&\fB\fBattributes\fP
\&\fRThis method is only valid in state \fISTART_TAG\fR. It
returns all attributes of the element in a name value list.
.TP
\&\fB\fBtext\fP
\&\fRThis method is only valid in state \fITEXT\fR. It
returns the character data of the event. There will be always
at most one TEXT event between START_TAG and the next
START_TAG or END_TAG event.
.TP
\&\fB\fBskip\fP
\&\fRThis method is only valid in state \fISTART_TAG\fR. It
skips to the corresponding end tag and ignores all events (but
not XML parsing errors) on the way and returns the new state
END_TAG.
.TP
\&\fB\fBfind-element\fP \fItagname\fB
\&\fRThis method is only valid in states
\&\fISTART_DOCUMENT\fR, \fISTART_TAG\fR and \fIEND_TAG\fR. It
skips forward until the next element start tag with tag name
\&\fItagname\fR and returns the new start START_TAG. If there
isn't such an element the parser stops at the end of the input
and returns END_DOCUMENT.
.TP
\&\fB\fBreset\fP
\&\fRThis method is valid in all parser states. It resets the
parser into READY state and returns that.
.TP
\&\fB\fBdelete\fP
\&\fRThis method is valid in all parser states. It deletes
the parser command.
.PP
Miscellaneous methods:
.TP
\&\fB\fBline\fP
\&\fRThis method is valid in all parser states except READY
and TEXT. It returns the line number of the parsing
position.
.TP
\&\fB\fBline\fP
\&\fRThis method is valid in all parser states except READY
and TEXT. It returns the offset, from the beginning of the
current line, of the parsing position.
.SH KEYWORDS
XML, pull, parsing

Added doc/pullparser.xml.













































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<manpage id="pullparser" cat="pullparser" title="pullparser">
  <namesection>
    <name>tdom::pullparser</name>
    <desc>Create an XML pull parser command</desc>
  </namesection>

  <synopsis>
    <syntax>package require tdom

    <cmd>tdom::pullparser</cmd> <m>cmdName</m> <o>-ignorewhitecdata</o>
    </syntax>
  </synopsis>

  <section>
    <title>DESCRIPTION </title>    
    
    <p>This command creates XML pull parser commands with a simple
    API, along the lines of a simple StAX parser. After creation,
    you've to set an input source, to do anything useful with the pull
    parser. For this see the methods <m>input</m>, <m>inputchannel</m>
    and <m>inputfile</m>.</p>

    <p>The parser has always a <m>state</m>. You start parsing the XML
    data until some next state, do what has to be done and skip again
    to the next state. XML well-formedness errors along the way will
    be reported as TCL_ERROR with additional info in the error
    message.</p>

    <p>The pull parsers don't follow external entities and are XML
    1.0 only, they know nothing about XML Namespaces. You get the tags
    and attribute names as in the source. You aren't noticed about
    comments, processing instructions and external entities; they are
    silently ignored for you. CDATA Sections are handled as if their
    content would have been provided without using a CDATA Section.
    </p>

    <p>On the brighter side is that character entity and attribute
    default declarations in the internal subset are respected (because
    of using expat as underlying parser). It is probably somewhat
    faster than a comperable implementation with the SAX interface.
    It's a nice programming model. It's a slim interface.
    </p>

    <p>If the option <m>-ignorewhitecdata</m> is given, the created
    XML pull parser command will ignore any white space only ('ย ', \t,
    \n and \r) text content between START_TAG and START_TAG / END_TAG.
    The parser won't stop at such input and will create TEXT state
    events only for not white space only text. </p>

    <p>Not all methods are valid in every state. The parser will raise
    TCL_ERROR if a method is called in a state the method isn't valid
    for. Valid methods of the created commands are:</p>
    <commandlist>
      <commanddef>
        <command><method>state</method></command>
        <desc>This method is valid in all parser states. The
        possible return values and their meanings are:
        <ul>
            <li><m>READY</m> - The parser is created or reset, but no
            input is set.</li>
            <li><m>START_DOCUMENT</m> - Input is set, parser is ready
            to start parsing.</li>
            <li><m>START_TAG</m> - Parser has stopped parsing at a
            start tag.</li>
            <li><m>END_TAG</m> - Parser has stopped parsing at an end tag</li>
            <li><m>TEXT</m> - Parser has stopped parsing to report
            text between tags.</li>
            <li><m>END_DOKUMENT</m> - Parser has finished parsing
            without error.</li>
            <li><m>PARSE_ERROR</m> - Parser stopped parsing at XML
            error in input.</li>
        </ul>
        </desc>
      </commanddef>

      <commanddef>
        <command><method>input</method> <m>data</m></command>
        <desc>This method is only valid in state <m>READY</m>. It
        prepares the parser to use <m>data</m> as XML input to parse
        and switches the parser into state START_DOCUMENT.</desc>
      </commanddef>

      <commanddef>
        <command><method>inputchannel</method> <m>channel</m></command>
        <desc>This method is only valid in state <m>READY</m>. It
        prepares the parser to read the XML input to parse out of
        <m>channel</m> and switches the parser into state START_DOCUMENT.</desc>
      </commanddef>

      <commanddef>
        <command><method>inputfile</method> <m>filename</m></command>
        <desc>This method is only valid in state <m>READY</m>. It
        open <m>filename</m> and prepares the parser to read the XML
        input to parse out of that file. The method returns TCL_ERROR,
        if the file could not be open in read mode. Otherwise it
        switches the parser into state START_DOCUMENT.</desc>
      </commanddef>

      <commanddef>
        <command><method>next</method></command>
        <desc>This method is valid in state <m>START_DOCUMENT</m>,
        <m>START_TAG</m>, <m>END_TAG</m> and <m>TEXT</m>. It continues
        parsing of the XML input until the next event, which it will
        return.</desc>
      </commanddef>

      <commanddef>
        <command><method>tag</method></command>
        <desc>This method is only valid in states <m>START_TAG</m> and
        <m>END_TAG</m>. It returns the tag name of the current start
        or end tag.</desc>
      </commanddef>

      <commanddef>
        <command><method>attributes</method></command>
        <desc>This method is only valid in state <m>START_TAG</m>. It
        returns all attributes of the element in a name value list.</desc>
      </commanddef>

      <commanddef>
        <command><method>text</method></command>
        <desc>This method is only valid in state <m>TEXT</m>. It
        returns the character data of the event. There will be always
        at most one TEXT event between START_TAG and the next
        START_TAG or END_TAG event.</desc>
      </commanddef>

      <commanddef>
        <command><method>skip</method></command>
        <desc>This method is only valid in state <m>START_TAG</m>. It
        skips to the corresponding end tag and ignores all events (but
        not XML parsing errors) on the way and returns the new state
        END_TAG.</desc>
      </commanddef>

      <commanddef>
        <command><method>find-element</method> <m>tagname</m></command>
        <desc>This method is only valid in states
        <m>START_DOCUMENT</m>, <m>START_TAG</m> and <m>END_TAG</m>. It
        skips forward until the next element start tag with tag name
        <m>tagname</m> and returns the new start START_TAG. If there
        isn't such an element the parser stops at the end of the input
        and returns END_DOCUMENT.</desc>
      </commanddef>

      <commanddef>
        <command><method>reset</method></command>
        <desc>This method is valid in all parser states. It resets the
        parser into READY state and returns that.</desc>
      </commanddef>

      <commanddef>
        <command><method>delete</method></command>
        <desc>This method is valid in all parser states. It deletes
        the parser command.</desc>
      </commanddef>
    </commandlist>

    <p>Miscellaneous methods:</p>
    <commandlist>
      <commanddef>
        <command><method>line</method></command>
        <desc>This method is valid in all parser states except READY
        and TEXT. It returns the line number of the parsing
        position.</desc>
      </commanddef>

      <commanddef>
        <command><method>line</method></command>
        <desc>This method is valid in all parser states except READY
        and TEXT. It returns the offset, from the beginning of the
        current line, of the parsing position.</desc>
      </commanddef>
    </commandlist>
  </section>

  <keywords>
    <keyword>XML</keyword>
    <keyword>pull</keyword>
    <keyword>parsing</keyword>
  </keywords>
</manpage>

Changes to doc/tDOM.xml.

1
2
3
4
5
6

7
8
9
10
11
12
13
..
15
16
17
18
19
20
21


22
23
24
25
26
27
28
<!DOCTYPE manual PUBLIC "-//jenglish//DTD TMML 0.5//EN" "tmml.dtd" [
<!ENTITY dom SYSTEM "dom.xml">
<!ENTITY domDoc SYSTEM "domDoc.xml">
<!ENTITY domNode SYSTEM "domNode.xml">
<!ENTITY expat SYSTEM "expat.xml">
<!ENTITY expatapi SYSTEM "expatapi.xml">

<!ENTITY tdomcmd SYSTEM "tdomcmd.xml">
<!ENTITY tnc SYSTEM "tnc.xml">
]>
<manual package="tDOM">
<title>tDOM manual</title>

&dom;
................................................................................
&domDoc;

&domNode;

&expat;

&expatapi;



&tdomcmd;

&tnc;

</manual>







>







 







>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
..
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE manual PUBLIC "-//jenglish//DTD TMML 0.5//EN" "tmml.dtd" [
<!ENTITY dom SYSTEM "dom.xml">
<!ENTITY domDoc SYSTEM "domDoc.xml">
<!ENTITY domNode SYSTEM "domNode.xml">
<!ENTITY expat SYSTEM "expat.xml">
<!ENTITY expatapi SYSTEM "expatapi.xml">
<!ENTITY pullparser SYSTEM "pullparser.xml">
<!ENTITY tdomcmd SYSTEM "tdomcmd.xml">
<!ENTITY tnc SYSTEM "tnc.xml">
]>
<manual package="tDOM">
<title>tDOM manual</title>

&dom;
................................................................................
&domDoc;

&domNode;

&expat;

&expatapi;

&pullparser;

&tdomcmd;

&tnc;

</manual>

Changes to doc/tdomcmd.html.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
..
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
..
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: tdom</title><meta name="xsl-processor" content="Jochen Loewer et. al. (loewerj@hotmail.com)"><meta name="generator" content="$RCSfile$ $Revision$">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTnode13446">NAME</a> ท <a href="#SECTnode13455">SYNOPSIS</a> ท <a href="#SECTnode13461">DESCRIPTION</a> ท <a href="#SECTnode13620">SEE ALSO</a> ท <a href="#SECTnode13629">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
    <h2><a name="SECTnode13446">NAME</a></h2><p class="namesection">
<b class="names">tdom - </b><br>tdom is an expat parser object extension to create an in-memory
DOM tree from the input while parsing.</p>


  <h2><a name="SECTnode13455">SYNOPSIS</a></h2><pre class="syntax">package require tdom

set parser [expat]

tdom $parser enable</pre>

  <h2><a name="SECTnode13461">DESCRIPTION</a></h2><p>
<i class="m">tdom</i> adds the C handler set &quot;tdom&quot; to an tcl expat
parser obj. This handler set builds an in-memory DOM tree out of the input,
parsed by the parser. A DOM tree created this way behave exactly like a DOM
tree created by the &quot;dom&quot; command (see there). In fact, tdom is only
another interface to the same functionality; it uses the code behind the
<tt class="samp">dom</tt> code for building the DOM tree.</p><dl class="commandlist">
      
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">enable</b>
</dt>

................................................................................
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">getdoc</b>
</dt>

        <dd><p>Returns the DOM tree as domDoc (see there) object.</p></dd>
      

      
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">setResultEncoding</b>
</dt>

        <dd><p>See the method <tt class="samp">setResultEncoding</tt> of the
<b class="cmd"><a href="dom.html">dom</a></b> command.</p></dd>
      

      
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">setStoreLineColumn</b> ?<i class="m">boolean</i>?</dt>

        <dd><p>See the method <tt class="samp">setStoreLineColumn</tt> of the
<b class="cmd"><a href="dom.html">dom</a></b> command.</p></dd>
      

      
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">remove</b>
</dt>

................................................................................
      

      
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">keepEmpties</b>
</dt>

        <dd><p>See the option <tt class="samp">-keepEmpties</tt> of the <b class="cmd"><a href="dom.html">dom</a></b> command.</p></dd>
      

      
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">setExternalEntityResolver</b> <i class="m">script</i>
</dt>
        <dd></dd>
      

    </dl>

  <h2><a name="SECTnode13620">SEE ALSO</a></h2><p class="seealso">
<a href="dom.html">dom</a>, <a href="expat.html">expat</a>
</p>

  <h2><a name="SECTnode13629">KEYWORDS</a></h2><p class="keywords">
<a class="keyword" href="keyword-index.html#KW-DOM">DOM</a>, <a class="keyword" href="keyword-index.html#KW-SAX">SAX</a>, <a class="keyword" href="keyword-index.html#KW-Chandlerset">C handler set</a>
</p>

</div><div class="footer">
<hr class="navsep"><!-- footer.html: Standard navigational footer --><div class="navbar" align="center">
	<a class="navaid" href="index.html">Table of Contents</a>
 ท	<a class="navaid" href="category-index.html">Index</a>
 ท	<a class="navaid" href="keyword-index.html">Keywords</a>
</div>
</div>
</body>
</html>


|



|


|




|





|
|


|







 







<
<
<
<
<
<
<
<
<





|







 







|











|
<
<

|



|
|
<
<
<
<



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
..
39
40
41
42
43
44
45









46
47
48
49
50
51
52
53
54
55
56
57
58
..
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80


81
82
83
84
85
86
87




88
89
90
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: tdom</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: tmml-html.xsl,v $ $Revision: 1.11 $"><meta charset="utf-8">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid0x1e30200">NAME</a> ยท <a href="#SECTid0x1f5add0">SYNOPSIS</a> ยท <a href="#SECTid0x1e4db90">DESCRIPTION</a> ยท <a href="#SECTid0x1f20b70">SEE ALSO</a> ยท <a href="#SECTid0x1f20f00">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
    <h2><a name="SECTid0x1e30200">NAME</a></h2><p class="namesection">
<b class="names">tdom - </b><br>tdom is an expat parser object extension to create an in-memory
DOM tree from the input while parsing.</p>


  <h2><a name="SECTid0x1f5add0">SYNOPSIS</a></h2><pre class="syntax">package require tdom

set parser [expat]

tdom $parser enable</pre>

  <h2><a name="SECTid0x1e4db90">DESCRIPTION</a></h2><p>
<i class="m">tdom</i> adds the C handler set "tdom" to an tcl expat
parser obj. This handler set builds an in-memory DOM tree out of the input,
parsed by the parser. A DOM tree created this way behave exactly like a DOM
tree created by the "dom" command (see there). In fact, tdom is only
another interface to the same functionality; it uses the code behind the
<tt class="samp">dom</tt> code for building the DOM tree.</p><dl class="commandlist">
      
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">enable</b>
</dt>

................................................................................
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">getdoc</b>
</dt>

        <dd><p>Returns the DOM tree as domDoc (see there) object.</p></dd>
      










      
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">setStoreLineColumn</b> ?<i class="m">boolean</i>?</dt>

        <dd><p>See the method <tt class="samp">setStoreLineColumn</tt> of the
<b class="cmd">dom</b> command.</p></dd>
      

      
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">remove</b>
</dt>

................................................................................
      

      
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">keepEmpties</b>
</dt>

        <dd><p>See the option <tt class="samp">-keepEmpties</tt> of the <b class="cmd">dom</b> command.</p></dd>
      

      
        <dt>
<b class="cmd">tdom</b> <i class="m">parserObj</i> <b class="method">setExternalEntityResolver</b> <i class="m">script</i>
</dt>
        <dd></dd>
      

    </dl>

  <h2><a name="SECTid0x1f20b70">SEE ALSO</a></h2><p class="seealso">dom, expat</p>



  <h2><a name="SECTid0x1f20f00">KEYWORDS</a></h2><p class="keywords">
<a class="keyword" href="keyword-index.html#KW-DOM">DOM</a>, <a class="keyword" href="keyword-index.html#KW-SAX">SAX</a>, <a class="keyword" href="keyword-index.html#KW-Chandlerset">C handler set</a>
</p>

</div><hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>




</div>
</body>
</html>

Changes to doc/tdomcmd.n.

191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
.TP
\&\fB\fBtdom\fP \fIparserObj\fB \fBgetdoc\fP
\&\fR
.RS
.PP
Returns the DOM tree as domDoc (see there) object.
.RE
.TP
\&\fB\fBtdom\fP \fIparserObj\fB \fBsetResultEncoding\fP
\&\fR
.RS
.PP
See the method \fBsetResultEncoding\fR of the
\&\fBdom\fP command.
.RE
.TP
\&\fB\fBtdom\fP \fIparserObj\fB \fBsetStoreLineColumn\fP ?\fIboolean\fB?
\&\fR
.RS
.PP
See the method \fBsetStoreLineColumn\fR of the
\&\fBdom\fP command.







<
<
<
<
<
<
<
<







191
192
193
194
195
196
197








198
199
200
201
202
203
204
.TP
\&\fB\fBtdom\fP \fIparserObj\fB \fBgetdoc\fP
\&\fR
.RS
.PP
Returns the DOM tree as domDoc (see there) object.
.RE








.TP
\&\fB\fBtdom\fP \fIparserObj\fB \fBsetStoreLineColumn\fP ?\fIboolean\fB?
\&\fR
.RS
.PP
See the method \fBsetStoreLineColumn\fR of the
\&\fBdom\fP command.

Changes to doc/tdomcmd.xml.

1
2
3
4
5
6
7
8
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  <manpage id="tdomcmd" cat="cmd" title="tdom">
    <namesection>
      <name>tdom</name>

      <desc>tdom is an expat parser object extension to create an in-memory
DOM tree from the input while parsing.</desc>
    </namesection>

................................................................................

      <commanddef>
        <command><cmd>tdom</cmd> <m>parserObj</m> <method>getdoc</method></command>

        <desc><p>Returns the DOM tree as domDoc (see there) object.</p></desc>
      </commanddef>

      <commanddef>
        <command><cmd>tdom</cmd> <m>parserObj</m> <method>setResultEncoding</method></command>

        <desc><p>See the method <samp>setResultEncoding</samp> of the
<cmd>dom</cmd> command.</p></desc>
      </commanddef>

      <commanddef>
        <command><cmd>tdom</cmd> <m>parserObj</m> <method>setStoreLineColumn</method> ?<m>boolean</m>?</command>

        <desc><p>See the method <samp>setStoreLineColumn</samp> of the
<cmd>dom</cmd> command.</p></desc>
      </commanddef>

|







 







<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
..
36
37
38
39
40
41
42







43
44
45
46
47
48
49
<manpage id="tdomcmd" cat="cmd" title="tdom">
    <namesection>
      <name>tdom</name>

      <desc>tdom is an expat parser object extension to create an in-memory
DOM tree from the input while parsing.</desc>
    </namesection>

................................................................................

      <commanddef>
        <command><cmd>tdom</cmd> <m>parserObj</m> <method>getdoc</method></command>

        <desc><p>Returns the DOM tree as domDoc (see there) object.</p></desc>
      </commanddef>








      <commanddef>
        <command><cmd>tdom</cmd> <m>parserObj</m> <method>setStoreLineColumn</method> ?<m>boolean</m>?</command>

        <desc><p>See the method <samp>setStoreLineColumn</samp> of the
<cmd>dom</cmd> command.</p></desc>
      </commanddef>

Changes to doc/tmml.options.

1
2
3
4


5
array set Options {
    xsltProcessor       tdom
    masterDocument      "tDOM.xml"
    tomanOptions        -soelim


}




>
>

1
2
3
4
5
6
7
array set Options {
    xsltProcessor       tdom
    masterDocument      "tDOM.xml"
    tomanOptions        -soelim
    htmlDirectory       .
    nroffDirectory      .
}

Added doc/tmml.rnc.









































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# $Id: tmml.dtd,v 1.8 2002/05/20 20:46:11 jenglish Exp $
# 
# Author:	Joe English, <jenglish@users.sourceforge.net>
# Created:	8 Feb 1999
# Revised:	24 Jul 1999
# Usage:
# 
# <!DOCTYPE  (manpage | manual)  PUBLIC "-//jenglish//DTD TMML 0.6//EN" >
# 
# XML DTD for TMML, Tcl Manual Markup language.
# 
# See  <URL: http://tmml.sourceforge.net/ > for more information

# ============================================================
# 
# Information pool parameter entities:
# 
# e.syntax 	Phrase-level elements that refer to Tcl syntactic entities.
# e.phrase	Other phrase-level elements
# e.block	Block-level elements
# e.struct	Structural elements that can appear directly in a section
# 
# x.block
# x.inline	Used for customization

namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0"

e.syntax =
  m
  | l
  | o
  | i
  | b
  | br
  | term
  | cmd
  | variable
  | method
  | option
  | file
  | syscmd
  | fun
  | widget
  | package
  | type
  | class
e.phrase = emph | ref | url | samp | command | new
e.block =
  p | ul | ol | dl | sl | xl | example | syntax | commandlist | optlist
e.struct = arglist | optionlist
x.inline = notAllowed
x.block = notAllowed
# ============================================================
# Content models:
# 
# m.code	(computer) text
# m.inline	inline text
# m.mixed	mixed inline and block elements
# m.top	top-level elements (inside sections)
m.inline = (text | e.phrase | e.syntax | x.inline)*
m.code = (text | new | e.syntax | x.inline)*
m.mixed = (text | e.phrase | e.syntax | e.block | x.block | x.inline)*
m.top = (e.block | e.struct | x.block)*
# ============================================================
# Common attributes:
a.version = attribute version { text }?
# ============================================================
# Top-level element: manual
m.division =
  title,
  (division* | (manpage | subdoc | extref)*)
m.manual =
  title,
  head?,
  (division* | (manpage | subdoc | extref)*)
manual = element manual { attlist.manual, m.manual }
division = element division { attlist.division, m.division }
attlist.division &= empty
subdoc = element subdoc { attlist.subdoc, empty }
extref = element extref { attlist.extref, empty }
attlist.manual &=
  attribute package { text },
  attribute version { text }?
attlist.extref &=
  attribute href { text },
  attribute title { text },
  attribute type { text }
attlist.subdoc &= attribute href { text }
# ============================================================
# Top-level element: manpage
manpage =
  element manpage {
    attlist.manpage,
    head?,
    namesection,
    synopsis?,
    section*,
    seealso?,
    keywords?
  }
attlist.manpage &=
  attribute id { xsd:ID },
  attribute cat { text },
  attribute title { text },
  attribute package { text }?,
  a.version
section = element section { attlist.section, title, m.top, subsection* }
attlist.section &=
  attribute id { xsd:ID }?,
  a.version
subsection = element subsection { attlist.subsection, title, m.top }
attlist.subsection &=
  attribute id { xsd:ID }?,
  a.version
# ============================================================
# Standard sections:
namesection =
  element namesection {
    attlist.namesection,
    (name+ | (title, name*)),
    desc
  }
attlist.namesection &= empty
synopsis = element synopsis { attlist.synopsis, (syntax | example)+ }
attlist.synopsis &= empty
keywords = element keywords { attlist.keywords, keyword+ }
attlist.keywords &= empty
keyword = element keyword { attlist.keyword, text }
attlist.keyword &= empty
seealso = element seealso { attlist.seealso, (ref | url)+ }
attlist.seealso &= empty
# ============================================================
# Common Constructs
title = element title { attlist.title, text }
attlist.title &= empty
name = element name { attlist.name, text }
desc = element desc { attlist.desc, m.mixed }
attlist.desc &= empty
# OR: desc: %m.inline;  description:  %m.mixed;
attlist.name &=
  attribute name { text }?,
  attribute cat { text }?
# ============================================================
# Block-level elements:
ul = element ul { attlist.ul, li+ }
attlist.ul &= empty
ol = element ol { attlist.ol, li+ }
attlist.ol &= empty
li = element li { attlist.li, m.mixed }
attlist.li &= a.version
sl = element sl { attlist.sl, li+ }
attlist.sl &=
  attribute cols { text }?,
  attribute cat { text }?
dl =
  element dl {
    attlist.dl,
    (dle | (dt, dd))+
  }
dle = element dle { attlist.dle, dt+, dd }
attlist.dle &= a.version
dt = element dt { attlist.dt, m.inline }
attlist.dt &= empty
dd = element dd { attlist.dd, m.mixed }
attlist.dd &= empty
attlist.dl &=
  [ a:defaultValue = "local" ] attribute scope { "local" | "global" }?,
  attribute cat { text }?
# Extended lists:  
# Similar to DocBook SegmentedLists
xl = element xl { attlist.xl, xlh?, xle+ }
attlist.xl &= empty
xlh = element xlh { attlist.xlh, xh+ }
xh = element xh { attlist.xh, m.inline }
attlist.xh &= empty
xle = element xle { attlist.xle, xt+, desc? }
attlist.xle &= empty
xt = element xt { attlist.xt, m.inline }
attlist.xt &= empty
p = element p { attlist.p, m.inline }
attlist.p &= a.version
example = element example { attlist.example, m.code }
attlist.example &= empty
syntax = element syntax { attlist.syntax, m.code }
attlist.syntax &=
  attribute scope { "local" | "global" }?,
  attribute cat { text }?,
  attribute name { text }?
# ============================================================
# Inline elements:
i = element i { attlist.i, m.inline }
attlist.i &= attribute cat { text }?
b = element b { attlist.b, m.inline }
attlist.b &= attribute cat { text }?
emph = element emph { attlist.emph, m.inline }
attlist.emph &= empty
samp = element samp { attlist.samp, m.code }
attlist.samp &= empty
o = element o { attlist.o, m.code }
attlist.o &= empty
url = element url { attlist.url, text }
attlist.url &= empty
ref = element ref { attlist.ref, m.inline }
attlist.ref &=
  attribute refid { text }?,
  attribute href { text }?,
  attribute cat { text }?
# @@ ALSO:
#	package	CDATA	#IMPLIED
#	manpage	CDATA	#IMPLIED
#	cat	CDATA	#IMPLIED
#	name	CDATA	#IMPLIED
# Legal combinations: (package? & ((manpage? & refid?) | (name? & cat?)))
new = element new { attlist.new, m.inline }
attlist.new &= attribute version { text }
br = element br { attlist.br, empty }
attlist.br &= empty
# ============================================================
# Syntax elements:
m = element m { attlist.m, text }
attlist.m &= empty
l = element l { attlist.l, text }
attlist.l &= empty
term = element term { attlist.term, text }
attlist.term &= attribute cat { text }?
cmd = element cmd { attlist.cmd, text }
attlist.cmd &= empty
method = element method { attlist.method, text }
attlist.method &= empty
option = element option { attlist.option, text }
attlist.option &= empty
syscmd = element syscmd { attlist.syscmd, text }
attlist.syscmd &= empty
widget = element widget { attlist.widget, text }
attlist.widget &= empty
fun = element fun { attlist.fun, text }
attlist.fun &= empty
variable = element variable { attlist.variable, text }
attlist.variable &= empty
package = element package { attlist.package, text }
attlist.package &= empty
type = element type { attlist.type, text }
attlist.type &= empty
class = element class { attlist.class, text }
attlist.class &= empty
file = element file { attlist.file, text }
attlist.file &= empty
# ============================================================
# Tcl entity definition elements:
arglist = element arglist { attlist.arglist, argdef+ }
attlist.arglist &= empty
argdef =
  element argdef { attlist.argdef, argtype, name, argmode?, desc }
attlist.argdef &= a.version
argtype = element argtype { attlist.argtype, text }
attlist.argtype &= empty
argmode = element argmode { attlist.argmode, text }
attlist.argmode &= empty
commandlist = element commandlist { attlist.commandlist, commanddef+ }
attlist.commandlist &= empty
commanddef = element commanddef { attlist.commanddef, command, desc }
attlist.commanddef &= a.version
command = element command { attlist.command, m.code }
attlist.command &= empty
optlist = element optlist { attlist.optlist, optdef+ }
attlist.optlist &= empty
optdef = element optdef { attlist.optdef, optname, optarg?, desc }
attlist.optdef &= empty
optname = element optname { attlist.optname, text }
attlist.optname &= empty
optarg = element optarg { attlist.optarg, text }
attlist.optarg &= empty
optionlist = element optionlist { attlist.optionlist, optiondef+ }
optiondef =
  element optiondef { attlist.optiondef, name, dbname, dbclass, desc }
attlist.optiondef &= a.version
dbname = element dbname { attlist.dbname, text }
attlist.dbname &= empty
dbclass = element dbclass { attlist.dbclass, text }
attlist.dbclass &= empty
attlist.optionlist &=
  [ a:defaultValue = "local" ] attribute scope { "local" | "global" }?,
  attribute cat { text }?
# ============================================================
# #FIXED attributes:
# A DTD-aware processor may take advantage of these
# if it simplifies processing.

# ============================================================
# Metainformation:
# Note that these elements do not normally appear
# inside TMML documents; they're for administrative
# purposes only.
head =
  element head { attlist.head, (extensions | info | link | category)* }
attlist.head &= empty
extensions =
  element extensions { attlist.extensions, (extension | xlh)* }
attlist.extensions &= empty
extension = element extension { attlist.extension, empty }
attlist.extension &=
  attribute gi { text },
  attribute tmml { text }
attlist.xlh &= attribute gi { text }?
info = element info { attlist.info, empty }
attlist.info &=
  attribute key { text },
  attribute value { text }
link = element link { attlist.link, empty }
attlist.link &=
  attribute rel { text },
  attribute href { text }
categories = element categories { attlist.categories, category+ }
attlist.categories &= empty
category = element category { attlist.category, empty }
attlist.category &=
  attribute id { xsd:ID },
  attribute title { text }?
INDEX = element INDEX { attlist.INDEX, head?, (MAN | DEF | KWD)* }
attlist.INDEX &=
  attribute title { text },
  attribute standalone { text }?,
  attribute package { text }?
DEF = element DEF { attlist.DEF, empty }
attlist.DEF &=
  attribute name { text },
  attribute cat { text }?,
  attribute package { text }?,
  attribute manpage { text }?,
  attribute subpart { text }?
KWD = element KWD { attlist.KWD, empty }
attlist.KWD &=
  attribute name { text },
  attribute manpage { text }?
MAN = element MAN { attlist.MAN, empty }
attlist.MAN &=
  attribute id { text },
  attribute title { text }
start = INDEX | manual | manpage | categories
# EOF

Changes to doc/tnc.html.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
..
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
..
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: tnc</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile$ $Revision$">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid883">NAME</a> ท <a href="#SECTid892">SYNOPSIS</a> ท <a href="#SECTid898">DESCRIPTION</a> ท <a href="#SECTid1068">BUGS</a> ท <a href="#SECTid1086">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
  <h2><a name="SECTid883">NAME</a></h2><p class="namesection">
<b class="names">tnc - </b><br>tnc is an expat parser object extension, that validates the XML
stream against the document DTD while parsing.</p>
  
  <h2><a name="SECTid892">SYNOPSIS</a></h2><pre class="syntax">package require tdom
package require tnc

set parser [expat]

tnc $parser enable</pre>

  <h2><a name="SECTid898">DESCRIPTION</a></h2><p>
<i class="m">tnc</i> adds the C handler set "tnc" to a tcl expat parser
obj. This handler set is a simple DTD validator. If the validator detects a
validation error, it sets the interp result, signals error and stops
parsing. There isn't any validation error recovering. As a consequence, only
valid documents are completely parsed.</p><p>This handler set has only three methods:</p><dl class="commandlist">
      
        <dt>
................................................................................

      
        <dt>
<b class="cmd">tnc</b> <i class="m">parserObj</i> <b class="method">getValidateCmd</b> <b class="option">?validateCmdName?</b>
</dt>

        <dd>
<p>Returns a new created validation command, if one is avaliable
from the parser command, otherwise it signals error. The name of the validation
command is the <i class="m">validateCmdName</i>, if this optional argument was given, or
a random choosen name. A validation command is avaliable in a parser command,
if the parser with tnc enabled was previously used, to parse an XML document
with a valid doctype declaration, a valid external subset, if one was given by
the doctype declaration, and a valid internal subset. The further document
doesn't need to be valid, to make the validation command avaliable. The
validation command can only get received one time from the parser command. The
created validation command has this syntax:</p>

<pre class="syntax">
<b class="cmd">validationCmd</b> <i class="m">method</i> <i class="m">?args?</i>
</pre>

................................................................................

      
        <dt>
<b class="method">validateTree</b> <i class="m">elementNode</i> <i class="m">?varName?</i>
</dt>

        <dd>Checks, if the given subtree with <i class="m">domNode</i> as root element
is a posible valid subtree of a document conforming to the DTD information
represented by teh validation command. IDREF could not checked, while
validating only a subtree, but it is checked, that every known ID attribute in
the subtree is unique. Returns 1, if the subtree is OK, 0 otherwise. If the
<i class="m">varName</i> argument is given, then the variable it names is set to the
detected reason for the validation error or to the empty string in case of
a valid subtree.</dd>

      
................................................................................
      

      </dl>
     </dd>
      
    </dl>

  <h2><a name="SECTid1068">BUGS</a></h2><p>The validation error reports could be much more informative and
user-friendly.</p><p>The validator doesn't detect ambiguous content models (see XML
recomendation Section 3.2.1 and Appendix E). Most Java validators also doesn't,
but handle such content models right anyhow. Tnc does not; if your DTD has
such ambiguous content models, tnc can not used to validate documents against
such (not completely XML spec compliant) DTDs.</p><p>It isn't possible to validate XML documents with standalone="yes" in the
XML Declaration</p><p>Violations of the validity constraints Proper Group/PE Nesting and
Proper Conditional Section/PE Nesting are not detected. They could only happen
inside a invalid DTD, not in the content of a document.</p>
  <h2><a name="SECTid1086">KEYWORDS</a></h2><p class="keywords">
<a class="keyword" href="keyword-index.html#KW-Validation">Validation</a>, <a class="keyword" href="keyword-index.html#KW-DTD">DTD</a>
</p>
  
</div><hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Table of Contents</a> ท <a class="navaid" href="category-index.html">Index</a> ท <a class="navaid" href="keyword-index.html">Keywords</a>
</div>
</body>
</html>


|



|


|



|






|







 







|


|



|







 







|
|







 







|








|




|



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
..
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
..
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<html>
<head>
<link rel="stylesheet" href="manpage.css"><title>tDOM manual: tnc</title><meta name="xsl-processor" content="Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."><meta name="generator" content="$RCSfile: tmml-html.xsl,v $ $Revision: 1.11 $"><meta charset="utf-8">
</head><body>
<div class="header">
<div class="navbar" align="center">
<a href="#SECTid0x1ee4b70">NAME</a> ยท <a href="#SECTid0x1d90950">SYNOPSIS</a> ยท <a href="#SECTid0x1ec21b0">DESCRIPTION</a> ยท <a href="#SECTid0x1ebb7b0">BUGS</a> ยท <a href="#SECTid0x1ebc120">KEYWORDS</a>
</div><hr class="navsep">
</div><div class="body">
  <h2><a name="SECTid0x1ee4b70">NAME</a></h2><p class="namesection">
<b class="names">tnc - </b><br>tnc is an expat parser object extension, that validates the XML
stream against the document DTD while parsing.</p>
  
  <h2><a name="SECTid0x1d90950">SYNOPSIS</a></h2><pre class="syntax">package require tdom
package require tnc

set parser [expat]

tnc $parser enable</pre>

  <h2><a name="SECTid0x1ec21b0">DESCRIPTION</a></h2><p>
<i class="m">tnc</i> adds the C handler set "tnc" to a tcl expat parser
obj. This handler set is a simple DTD validator. If the validator detects a
validation error, it sets the interp result, signals error and stops
parsing. There isn't any validation error recovering. As a consequence, only
valid documents are completely parsed.</p><p>This handler set has only three methods:</p><dl class="commandlist">
      
        <dt>
................................................................................

      
        <dt>
<b class="cmd">tnc</b> <i class="m">parserObj</i> <b class="method">getValidateCmd</b> <b class="option">?validateCmdName?</b>
</dt>

        <dd>
<p>Returns a new created validation command, if one is available
from the parser command, otherwise it signals error. The name of the validation
command is the <i class="m">validateCmdName</i>, if this optional argument was given, or
a random chosen name. A validation command is available in a parser command,
if the parser with tnc enabled was previously used, to parse an XML document
with a valid doctype declaration, a valid external subset, if one was given by
the doctype declaration, and a valid internal subset. The further document
doesn't need to be valid, to make the validation command available. The
validation command can only get received one time from the parser command. The
created validation command has this syntax:</p>

<pre class="syntax">
<b class="cmd">validationCmd</b> <i class="m">method</i> <i class="m">?args?</i>
</pre>

................................................................................

      
        <dt>
<b class="method">validateTree</b> <i class="m">elementNode</i> <i class="m">?varName?</i>
</dt>

        <dd>Checks, if the given subtree with <i class="m">domNode</i> as root element
is a possible valid subtree of a document conforming to the DTD information
represented by the validation command. IDREF could not checked, while
validating only a subtree, but it is checked, that every known ID attribute in
the subtree is unique. Returns 1, if the subtree is OK, 0 otherwise. If the
<i class="m">varName</i> argument is given, then the variable it names is set to the
detected reason for the validation error or to the empty string in case of
a valid subtree.</dd>

      
................................................................................
      

      </dl>
     </dd>
      
    </dl>

  <h2><a name="SECTid0x1ebb7b0">BUGS</a></h2><p>The validation error reports could be much more informative and
user-friendly.</p><p>The validator doesn't detect ambiguous content models (see XML
recomendation Section 3.2.1 and Appendix E). Most Java validators also doesn't,
but handle such content models right anyhow. Tnc does not; if your DTD has
such ambiguous content models, tnc can not used to validate documents against
such (not completely XML spec compliant) DTDs.</p><p>It isn't possible to validate XML documents with standalone="yes" in the
XML Declaration</p><p>Violations of the validity constraints Proper Group/PE Nesting and
Proper Conditional Section/PE Nesting are not detected. They could only happen
inside a invalid DTD, not in the content of a document.</p>
  <h2><a name="SECTid0x1ebc120">KEYWORDS</a></h2><p class="keywords">
<a class="keyword" href="keyword-index.html#KW-Validation">Validation</a>, <a class="keyword" href="keyword-index.html#KW-DTD">DTD</a>
</p>
  
</div><hr class="navsep"><div class="navbar" align="center">
<a class="navaid" href="index.html">Contents</a> ยท <a class="navaid" href="category-index.html">Index</a> ยท <a class="navaid" href="keyword-index.html">Keywords</a> ยท <a class="navaid" href="http://tdom.org">Repository</a>
</div>
</body>
</html>

Changes to doc/tnc.n.

197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
and frees all information, stored by it.
.RE
.TP
\&\fB\fBtnc\fP \fIparserObj\fB \fBgetValidateCmd\fP \fB?validateCmdName?\fP
\&\fR
.RS
.PP
Returns a new created validation command, if one is avaliable
from the parser command, otherwise it signals error. The name of the validation
command is the \fIvalidateCmdName\fR, if this optional argument was given, or
a random choosen name. A validation command is avaliable in a parser command,
if the parser with tnc enabled was previously used, to parse an XML document
with a valid doctype declaration, a valid external subset, if one was given by
the doctype declaration, and a valid internal subset. The further document
doesn't need to be valid, to make the validation command avaliable. The
validation command can only get received one time from the parser command. The
created validation command has this syntax:



.CS
\&\fBvalidationCmd\fP \fImethod\fR \fI?args?\fR
................................................................................
information represented by the validation command. Returns 1, if the document
ist valid, 0 otherwise. If the \fIvarName\fR argument is given, then the
variable it names is set to the detected reason for the validation error or to
the empty string in case of a valid document.
.TP
\&\fB\fBvalidateTree\fP \fIelementNode\fB \fI?varName?\fB
\&\fRChecks, if the given subtree with \fIdomNode\fR as root element
is a posible valid subtree of a document conforming to the DTD information
represented by teh validation command. IDREF could not checked, while
validating only a subtree, but it is checked, that every known ID attribute in
the subtree is unique. Returns 1, if the subtree is OK, 0 otherwise. If the
\&\fIvarName\fR argument is given, then the variable it names is set to the
detected reason for the validation error or to the empty string in case of
a valid subtree.
.TP
\&\fB\fBvalidateAttributes\fP \fIelementNode\fB \fI?varName?\fB







|


|



|







 







|
|







197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
and frees all information, stored by it.
.RE
.TP
\&\fB\fBtnc\fP \fIparserObj\fB \fBgetValidateCmd\fP \fB?validateCmdName?\fP
\&\fR
.RS
.PP
Returns a new created validation command, if one is available
from the parser command, otherwise it signals error. The name of the validation
command is the \fIvalidateCmdName\fR, if this optional argument was given, or
a random chosen name. A validation command is available in a parser command,
if the parser with tnc enabled was previously used, to parse an XML document
with a valid doctype declaration, a valid external subset, if one was given by
the doctype declaration, and a valid internal subset. The further document
doesn't need to be valid, to make the validation command available. The
validation command can only get received one time from the parser command. The
created validation command has this syntax:



.CS
\&\fBvalidationCmd\fP \fImethod\fR \fI?args?\fR
................................................................................
information represented by the validation command. Returns 1, if the document
ist valid, 0 otherwise. If the \fIvarName\fR argument is given, then the
variable it names is set to the detected reason for the validation error or to
the empty string in case of a valid document.
.TP
\&\fB\fBvalidateTree\fP \fIelementNode\fB \fI?varName?\fB
\&\fRChecks, if the given subtree with \fIdomNode\fR as root element
is a possible valid subtree of a document conforming to the DTD information
represented by the validation command. IDREF could not checked, while
validating only a subtree, but it is checked, that every known ID attribute in
the subtree is unique. Returns 1, if the subtree is OK, 0 otherwise. If the
\&\fIvarName\fR argument is given, then the variable it names is set to the
detected reason for the validation error or to the empty string in case of
a valid subtree.
.TP
\&\fB\fBvalidateAttributes\fP \fIelementNode\fB \fI?varName?\fB

Changes to doc/tnc.xml.

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
..
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
        <desc><p>Removes the tnc validatore from the parser <m>parserObj</m>
and frees all information, stored by it.</p></desc>
      </commanddef>

      <commanddef>
        <command><cmd>tnc</cmd> <m>parserObj</m> <method>getValidateCmd</method> <option>?validateCmdName?</option></command>

        <desc><p>Returns a new created validation command, if one is avaliable
from the parser command, otherwise it signals error. The name of the validation
command is the <m>validateCmdName</m>, if this optional argument was given, or
a random choosen name. A validation command is avaliable in a parser command,
if the parser with tnc enabled was previously used, to parse an XML document
with a valid doctype declaration, a valid external subset, if one was given by
the doctype declaration, and a valid internal subset. The further document
doesn't need to be valid, to make the validation command avaliable. The
validation command can only get received one time from the parser command. The
created validation command has this syntax:</p>

<syntax><cmd>validationCmd</cmd> <m>method</m> <m>?args?</m></syntax>

    <p>The valid methods are:</p>

................................................................................
the empty string in case of a valid document.</desc>
      </commanddef>

      <commanddef>
        <command><method>validateTree</method> <m>elementNode</m> <m>?varName?</m></command>

        <desc>Checks, if the given subtree with <m>domNode</m> as root element
is a posible valid subtree of a document conforming to the DTD information
represented by teh validation command. IDREF could not checked, while
validating only a subtree, but it is checked, that every known ID attribute in
the subtree is unique. Returns 1, if the subtree is OK, 0 otherwise. If the
<m>varName</m> argument is given, then the variable it names is set to the
detected reason for the validation error or to the empty string in case of
a valid subtree.</desc>

      </commanddef>







|


|



|







 







|
|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
..
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
        <desc><p>Removes the tnc validatore from the parser <m>parserObj</m>
and frees all information, stored by it.</p></desc>
      </commanddef>

      <commanddef>
        <command><cmd>tnc</cmd> <m>parserObj</m> <method>getValidateCmd</method> <option>?validateCmdName?</option></command>

        <desc><p>Returns a new created validation command, if one is available
from the parser command, otherwise it signals error. The name of the validation
command is the <m>validateCmdName</m>, if this optional argument was given, or
a random chosen name. A validation command is available in a parser command,
if the parser with tnc enabled was previously used, to parse an XML document
with a valid doctype declaration, a valid external subset, if one was given by
the doctype declaration, and a valid internal subset. The further document
doesn't need to be valid, to make the validation command available. The
validation command can only get received one time from the parser command. The
created validation command has this syntax:</p>

<syntax><cmd>validationCmd</cmd> <m>method</m> <m>?args?</m></syntax>

    <p>The valid methods are:</p>

................................................................................
the empty string in case of a valid document.</desc>
      </commanddef>

      <commanddef>
        <command><method>validateTree</method> <m>elementNode</m> <m>?varName?</m></command>

        <desc>Checks, if the given subtree with <m>domNode</m> as root element
is a possible valid subtree of a document conforming to the DTD information
represented by the validation command. IDREF could not checked, while
validating only a subtree, but it is checked, that every known ID attribute in
the subtree is unique. Returns 1, if the subtree is OK, 0 otherwise. If the
<m>varName</m> argument is given, then the variable it names is set to the
detected reason for the validation error or to the empty string in case of
a valid subtree.</desc>

      </commanddef>

Deleted encodings/GenCompactCodings.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
#!/opt/tcl/bin/tclsh
#-----------------------------------------------------------------------------
#   Copyright (c) 1999 Jochen C. Loewer (loewerj@hotmail.com) 
#-----------------------------------------------------------------------------
#
#
#   Script to generate 'space and time optimal' C code for fixed 
#   converting tables from Unicode to 8bit encodings (ISO-8859*,CP850...)
#   from the Tcl 8.2 encoding files (*.enc)
#
#
#
#   The contents of this file are subject to the Mozilla Public License
#   Version 1.1 (the "License"); you may not use this file except in
#   compliance with the License. You may obtain a copy of the License at
#   http://www.mozilla.org/MPL/
#
#   Software distributed under the License is distributed on an "AS IS"
#   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
#   License for the specific language governing rights and limitations
#   under the License.
#
#   The Original Code is tDOM.
#
#   The Initial Developer of the Original Code is Jochen Loewer
#   Portions created by Jochen Loewer are Copyright (C) 1998, 1999
#   Jochen Loewer. All Rights Reserved.
#
#   Contributor(s):                                      
#   
#
#   written by Jochen Loewer
#   November, 1999
#
#-----------------------------------------------------------------------------



#-----------------------------------------------------------------------------
#   Log
#
#-----------------------------------------------------------------------------
proc Log { message } {
    puts stderr $message
}


#-----------------------------------------------------------------------------
#   HexValue
#
#-----------------------------------------------------------------------------
proc HexValue { v } {
    return [format "0x%2X" $v]
}


#-----------------------------------------------------------------------------
#   HEX
#
#-----------------------------------------------------------------------------
proc HEX { v } {
    return [format "\\%03o" $v]
}


#-----------------------------------------------------------------------------
#   ReadEncodingFile
#
#-----------------------------------------------------------------------------
proc ReadEncodingFile { encodingFile info_var map_var } {

    upvar $info_var info $map_var map

    catch { unset info }
    catch { unset map  }

    set info(max) 0

    Log "Reading encoding file $encodingFile ..."

    set fd [open $encodingFile r]

    #--------------------------------------------------------------
    #   read header
    #
    #--------------------------------------------------------------
    set line [gets $fd]   ;# ignore comment line

    set line [gets $fd]   

    if {$line != "S"} {
        error "Only single byte encodings are supported"
    }
    set line [gets $fd]
    scan $line "%s %d %d" fbHex info(symbol) info(npages)

    set fb [binary format H2 [string range $fbHex 2 4]]
    binary scan $fb c info(fallback)
 
    #--------------------------------------------------------------
    #   read each single mapping page
    #
    #--------------------------------------------------------------
    for {set p 0} {$p < $info(npages)} {incr p} {
 
        set line [gets $fd]

        binary scan [binary format H2 $line] c page

        #----------------------------------------------------
        #   read 16 * 16 hex number -> 256 mappings
        #
        #----------------------------------------------------
        for {set l 0} {$l < 16} {incr l} {

            set line [gets $fd]

            for {set k 0} {$k < 16} {incr k} {

                set hex [string range $line 0 3]
                set line [string range $line 4 end]
                binary scan [binary format H4 $hex] S from
                set to [expr ($page << 8) + ($l * 16) + $k]
                Log "$from -> $to"

                #------------------------------
                #   set mapping
                #------------------------------
                set map($from) $to

                if {$from > $info(max)} {set info(max) $from}
            }
        }
    }
    close $fd
    Log "fallback='$info(fallback)' max=$info(max) symbol=$info(symbol) npages=$info(npages)"
    Log "Reading done."
    Log ""
}




#-----------------------------------------------------------------------------
#   BuildInitalRanges
#
#-----------------------------------------------------------------------------
proc BuildInitalRanges { info_var map_var} {

    upvar $info_var info $map_var map

    set mode different
    set last -1

    set ranges {}

    for {set from 1} {$from <= $info(max)} {incr from} {
        if {![info exists map($from)]} {
            set to $info(fallback)
        } else {   
            set to $map($from)
        }
        if {$mode == "identic"} {
            if {$from == $to} {
                set last $from
            } else {
                lappend ranges [list $identicStart [expr $last - $identicStart +1] {}]            
                Log "$identicStart, $last, IDENTIC, NULL, "
                if {$to == $info(fallback)} { 
                    set mode fallback
                } else {
                    lappend ranges [list $from 1 $to]            
                    Log "$from -> $to"
                    set mode different
                }
            }
        } elseif {$mode == "different"} {
            if {$from == $to} {
                set identicStart $from
                set last         $from
                set mode identic
            } elseif {$to == $info(fallback)} {
                set mode fallback
            } else {
                lappend ranges [list $from 1 $to]            
                Log"$from -> $to"
            }        
        } else {
            if {$to != $info(fallback)} {
                if {$from == $to} {
                    set identicStart $from
                    set last         $from
                    set mode identic
                } else {
                    lappend ranges [list $from 1 $to]            
                    Log "$from -> $to"
                }        
            }
        } 
    }
    if {$mode == "identic"} {
        lappend ranges [list $identicStart [expr $last - $identicStart +1] {}]            
        Log "$identicStart, $last, IDENTIC, NULL, "
    }
    return $ranges
}


#-----------------------------------------------------------------------------
#   OptimizeRanges
#
#-----------------------------------------------------------------------------
proc OptimizeRanges { fallback ranges } {

    set newranges {}
    set lastfrom  {}

    foreach range $ranges {
        foreach {from len values} $range break

        if {($len > 50) && ($values == {}) } {
            if {$lastfrom != {} } {
                lappend newranges [list $lastfrom $lastlen $lastvalues]
            }
            lappend newranges [list $from $len $values]
            set lastfrom {}
        } elseif {$lastfrom != {} } {
            #Log "lastfrom=$lastfrom lastlen=$lastlen"
            if { ($lastfrom + $lastlen + 20) > $from} {
 
                if {$lastvalues == {}} {
                    for {set j 0} {$j < $lastlen} {incr j} {
                        lappend lastvalues [expr $lastfrom + $j]
                    }
                    incr lastlen $lastlen
                }
                for {set i [expr $lastfrom + $lastlen]} {$i < $from} {incr i} { 
                    lappend lastvalues $fallback
                    incr lastlen 
                }
                if {$values == {}} {
                    for {set j 0} {$j < $len} {incr j} {
                        lappend lastvalues [expr $from + $j]
                    }
                    incr lastlen $len
                } else {
                    set lastvalues [concat $lastvalues $values]
                    incr lastlen $len
                }
            } else {
                lappend newranges [list $lastfrom $lastlen $lastvalues]
                set lastfrom   $from
                set lastlen    $len
                set lastvalues $values
            }
        } else {
            set lastfrom   $from
            set lastlen    $len
            set lastvalues $values
        }
    }
    if {$lastfrom != {} } {
        lappend newranges [list $lastfrom $lastlen $lastvalues]
    }
    return $newranges
}


#-----------------------------------------------------------------------------
#   OutputCode
#
#-----------------------------------------------------------------------------
proc OutputCode { encVar fallback ranges } {   

    puts "static TEncodingRule TDOM_UnicodeTo$encVar \[\] = \{"

    foreach range $ranges {
        foreach {from len values} $range break
        if {$values == {}} {
            puts "    \{ ENC_IDENTITY, $from, $len, \"\" \}, "
        } else {
            puts "    \{ ENC_MAP, $from, $len, "
            set i 0
            foreach value $values {
                if {$i == 0} { 
                    puts -nonewline "        \""
                }
                puts -nonewline "[HEX $value]"
                incr i
                if {$i == 14} { 
                    puts -nonewline "\"\n"
                    set i 0 
                }
            }
            if {$i > 0} {
                puts  -nonewline "\" \},\n"
            } else {
                puts  -nonewline "    \},\n"
            }
        }
    }
    puts "    \{ ENC_END, 0, 0, NULL \} "
    puts "\};\n"
}



#-----------------------------------------------------------------------------
#   begin of main part
#-----------------------------------------------------------------------------


  puts "/*------------------------------------------------------------------------"
  puts "|   WARNING! This is file automatically generated by GenCompactCodings !  "
  puts "|   WARNING!         Do not edit!                                         "
  puts "|                                                                         "
  puts "|   Unicode(UTF) ---> 8bit code conversion tables                         "
  puts "|                                                                         "
  puts "\\-----------------------------------------------------------------------*/"


  set fallbacks {}
  set encodings {}

  foreach encodingFile $argv {

      regsub {(\.enc)$} $encodingFile {} encoding
      set encVar [string toupper $encoding]
      regsub -- {-} $encVar {} encVar
     
      ReadEncodingFile $encodingFile info map

      foreach from [lsort -integer [array names map]] {
          Log "$from -> $map($from)"
      }

      #-------------------------------------------
      #   build the initial map ranges
      #-------------------------------------------
      set ranges [ BuildInitalRanges info map ]

      Log "Starting ranges [llength $ranges]:"
      foreach range $ranges {
          foreach {from len values} $range break
          Log [format "%3d %3d '%s'" $from $len $values]
      }

      #-------------------------------------------
      #   iterate to optimize ranges
      #-------------------------------------------
      for {set loop 0} {$loop < 4} {incr loop} {
          set ranges [OptimizeRanges $info(fallback) $ranges]
      }

      Log "End ranges [llength $ranges]:"
      foreach range $ranges {
          foreach {from len values} $range break
          Log [format "%3d %3d '%s'\n" $from $len $values]
      }

      lappend fallbacks $info(fallback)  
      lappend encodings $encoding $encVar  

      OutputCode $encVar $info(fallback) $ranges
  }

  puts ""
  puts "static TEncoding TDOM_UnicodeTo8bitEncodings \[\] = \{"
  foreach {encoding encVar} $encodings fallback $fallbacks {
      puts stdout  [format "    { %-12s, %4s, %s }," \
                           "\"$encoding\""           \
                           [HexValue $fallback]      \
                           TDOM_UnicodeTo$encVar     ]
     
  }
  puts "    { NULL, 0, NULL }"
  puts "\};"


#-----------------------------------------------------------------------------
#   end of main part
#-----------------------------------------------------------------------------

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































Deleted encodings/ascii.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: ascii, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/cp1250.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1250, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00800081201A0083201E2026202020210088203001602039015A0164017D0179
009020182019201C201D202220132014009821220161203A015B0165017E017A
00A002C702D8014100A4010400A600A700A800A9015E00AB000000AD00AE017B
00B000B102DB014200B400B500B600B700B80105015F00BB013D02DD013E017C
015400C100C2010200C40139010600C7010C00C9011800CB011A00CD00CE010E
01100143014700D300D4015000D600D70158016E00DA017000DC00DD016200DF
015500E100E2010300E4013A010700E7010D00E9011900EB011B00ED00EE010F
01110144014800F300F4015100F600F70159016F00FA017100FC00FD016302D9
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/cp1251.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1251, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
04020403201A0453201E2026202020210088203004092039040A040C040B040F
045220182019201C201D202220132014009821220459203A045A045C045B045F
00A0040E045E040800A4049000A600A7040100A9040400AB00AC00AD00AE0407
00B000B104060456049100B500B600B704512116045400BB0458040504550457
0410041104120413041404150416041704180419041A041B041C041D041E041F
0420042104220423042404250426042704280429042A042B042C042D042E042F
0430043104320433043404350436043704380439043A043B043C043D043E043F
0440044104420443044404450446044704480449044A044B044C044D044E044F
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/cp1252.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1252, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00800081201A0192201E20262020202102C62030016020390152008D008E008F
009020182019201C201D20222013201402DC21220161203A0153009D009E0178
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
00D000D100D200D300D400D500D600D700D800D900DA00DB00DC00DD00DE00DF
00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
00F000F100F200F300F400F500F600F700F800F900FA00FB00FC00FD00FE00FF
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/cp1253.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1253, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00800081201A0192201E20262020202100882030008A2039008C008D008E008F
009020182019201C201D20222013201400982122009A203A009C009D009E009F
00A00385038600A300A400A500A600A700A800A9000000AB00AC00AD00AE2015
00B000B100B200B3038400B500B600B703880389038A00BB038C00BD038E038F
0390039103920393039403950396039703980399039A039B039C039D039E039F
03A003A1000003A303A403A503A603A703A803A903AA03AB03AC03AD03AE03AF
03B003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C203C303C403C503C603C703C803C903CA03CB03CC03CD03CE0000
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/cp1254.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1254, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00800081201A0192201E20262020202102C62030016020390152008D008E008F
009020182019201C201D20222013201402DC21220161203A0153009D009E0178
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
011E00D100D200D300D400D500D600D700D800D900DA00DB00DC0130015E00DF
00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
011F00F100F200F300F400F500F600F700F800F900FA00FB00FC0131015F00FF
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/cp1255.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1255, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00800081201A0192201E20262020202102C62030008A2039008C008D008E008F
009020182019201C201D20222013201402DC2122009A203A009C009D009E009F
00A0000000A200A320AA00A500A600A700A800A9000000AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B7000000B9000000BB00BC00BD00BE0000
05B005B105B205B305B405B505B605B705B805B905BA05BB05BC05BD05BE05BF
05C005C105C205C305F005F105F2000000000000000000000000000000000000
05D005D105D205D305D405D505D605D705D805D905DA05DB05DC05DD05DE05DF
05E005E105E205E305E405E505E605E705E805E905EA00000000200E200F0000
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/cp1256.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp1256, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080067E201A0192201E20262020202102C62030008A2039015206860698008F
06AF20182019201C201D20222013201400982122009A203A0153200C200D009F
00A0060C00A200A300A400A500A600A700A800A9000000AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B9061B00BB00BC00BD00BE061F
0000062106220623062406250626062706280629062A062B062C062D062E062F
063006310632063306340635063600D7063706380639063A0640064106420643
00E0064400E2064506460647064800E700E800E900EA00EB0649064A00EE00EF
064B064C064D064E00F4064F065000F7065100F9065200FB00FC200E200F0000
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/cp437.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp437, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5
00C900E600C600F400F600F200FB00F900FF00D600DC00A200A300A520A70192
00E100ED00F300FA00F100D100AA00BA00BF231000AC00BD00BC00A100AB00BB
259125922593250225242561256225562555256325512557255D255C255B2510
25142534252C251C2500253C255E255F255A25542569256625602550256C2567
2568256425652559255825522553256B256A2518250C25882584258C25902580
03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/cp850.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: cp850, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5
00C900E600C600F400F600F200FB00F900FF00D600DC00F800A300D800D70192
00E100ED00F300FA00F100D100AA00BA00BF00AE00AC00BD00BC00A100AB00BB
2591259225932502252400C100C200C000A9256325512557255D00A200A52510
25142534252C251C2500253C00E300C3255A25542569256625602550256C00A4
00F000D000CA00CB00C8013100CD00CE00CF2518250C2588258400A600CC2580
00D300DF00D400D200F500D500B500FE00DE00DA00DB00D900FD00DD00AF00B4
00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/iso8859-1.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-1, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
00D000D100D200D300D400D500D600D700D800D900DA00DB00DC00DD00DE00DF
00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
00F000F100F200F300F400F500F600F700F800F900FA00FB00FC00FD00FE00FF
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/iso8859-2.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-2, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A0010402D8014100A4013D015A00A700A80160015E0164017900AD017D017B
00B0010502DB014200B4013E015B02C700B80161015F0165017A02DD017E017C
015400C100C2010200C40139010600C7010C00C9011800CB011A00CD00CE010E
01100143014700D300D4015000D600D70158016E00DA017000DC00DD016200DF
015500E100E2010300E4013A010700E7010D00E9011900EB011B00ED00EE010F
01110144014800F300F4015100F600F70159016F00FA017100FC00FD016302D9
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/iso8859-3.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-3, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A0012602D800A300A40000012400A700A80130015E011E013400AD0000017B
00B0012700B200B300B400B5012500B700B80131015F011F013500BD0000017C
00C000C100C2000000C4010A010800C700C800C900CA00CB00CC00CD00CE00CF
000000D100D200D300D4012000D600D7011C00D900DA00DB00DC016C015C00DF
00E000E100E2000000E4010B010900E700E800E900EA00EB00EC00ED00EE00EF
000000F100F200F300F4012100F600F7011D00F900FA00FB00FC016D015D02D9
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/iso8859-4.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-4, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A001040138015600A40128013B00A700A8016001120122016600AD017D00AF
00B0010502DB015700B40129013C02C700B80161011301230167014A017E014B
010000C100C200C300C400C500C6012E010C00C9011800CB011600CD00CE012A
01100145014C013600D400D500D600D700D8017200DA00DB00DC0168016A00DF
010100E100E200E300E400E500E6012F010D00E9011900EB011700ED00EE012B
01110146014D013700F400F500F600F700F8017300FA00FB00FC0169016B02D9
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/iso8859-5.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-5, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A0040104020403040404050406040704080409040A040B040C00AD040E040F
0410041104120413041404150416041704180419041A041B041C041D041E041F
0420042104220423042404250426042704280429042A042B042C042D042E042F
0430043104320433043404350436043704380439043A043B043C043D043E043F
0440044104420443044404450446044704480449044A044B044C044D044E044F
2116045104520453045404550456045704580459045A045B045C00A7045E045F
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/iso8859-6.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-6, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0660066106620663066406650666066706680669003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A000000000000000A40000000000000000000000000000060C00AD00000000
00000000000000000000000000000000000000000000061B000000000000061F
0000062106220623062406250626062706280629062A062B062C062D062E062F
0630063106320633063406350636063706380639063A00000000000000000000
0640064106420643064406450646064706480649064A064B064C064D064E064F
0650065106520000000000000000000000000000000000000000000000000000
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/iso8859-7.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-7, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A002BD02BC00A30000000000A600A700A800A9000000AB00AC00AD00002015
00B000B100B200B303840385038600B703880389038A00BB038C00BD038E038F
0390039103920393039403950396039703980399039A039B039C039D039E039F
03A003A1000003A303A403A503A603A703A803A903AA03AB03AC03AD03AE03AF
03B003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
03C003C103C203C303C403C503C603C703C803C903CA03CB03CC03CD03CE0000
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/iso8859-8.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-8, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A0000000A200A300A400A500A600A700A800A900D700AB00AC00AD00AE203E
00B000B100B200B300B400B500B600B700B800B900F700BB00BC00BD00BE0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000002017
05D005D105D205D305D405D505D605D705D805D905DA05DB05DC05DD05DE05DF
05E005E105E205E305E405E505E605E705E805E905EA00000000000000000000
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/iso8859-9.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: iso8859-9, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
011E00D100D200D300D400D500D600D700D800D900DA00DB00DC0130015E00DF
00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
011F00F100F200F300F400F500F600F700F800F900FA00FB00FC0131015F00FF
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted encodings/koi8-r.enc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: koi8-r, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
25002502250C251025142518251C2524252C2534253C258025842588258C2590
259125922593232025A02219221A22482264226500A0232100B000B200B700F7
25502551255204512553255425552556255725582559255A255B255C255D255E
255F25602561040125622563256425652566256725682569256A256B256C00A9
044E0430043104460434043504440433044504380439043A043B043C043D043E
043F044F044004410442044304360432044C044B04370448044D04490447044A
042E0410041104260414041504240413042504180419041A041B041C041D041E
041F042F042004210422042304160412042C042B04170428042D04290427042A
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Changes to expat/COPYING.

1
2
3
4
5
6
7
8
9
10
Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
                               and Clark Cooper
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.

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
|
|
<







1
2

3
4
5
6
7
8
9
Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper
Copyright (c) 2001-2017 Expat maintainers


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

Changes to expat/Changes.
































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
..
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
..
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126































































































































































































































































































































































































Release 2.0.1 Tue June 5 2007
        - Fixed bugs #1515266, 1515600: The character data handler's calling
          of XML_StopParser() was not handled properly; if the parser was
          stopped and the handler set to NULL, the parser would segfault.
        - Fixed bug #1690883: Expat failed on EBCDIC systems as it assumed
          some character constants to be ASCII encoded.
        - Minor cleanups of the test harness.
        - Fixed xmlwf bug #1513566: "out of memory" error on file size zero.
        - Fixed outline.c bug #1543233: missing a final XML_ParserFree() call.
        - Fixes and improvements for Windows platform:
          bugs #1409451, #1476160, 1548182, 1602769, 1717322.
        - Build fixes for various platforms:
          HP-UX, Tru64, Solaris 9: patch #1437840, bug #1196180.
          All Unix: #1554618 (refreshed config.sub/config.guess).
                    #1490371, #1613457: support both, DESTDIR and INSTALL_ROOT,
                    without relying on GNU-Make specific features.
          #1647805: Patched configure.in to work better with Intel compiler.
        - Fixes to Makefile.in to have make check work correctly:
................................................................................
        - Fixed headers for use from C++.
        - XML_GetCurrentLineNumber() and  XML_GetCurrentColumnNumber()
          now return unsigned integers.
        - Added XML_LARGE_SIZE switch to enable 64-bit integers for
          byte indexes and line/column numbers.
        - Updated to use libtool 1.5.22 (the most recent).
        - Added support for AmigaOS.
        - Some mostly minor bug fixes. SF issues include: 1006708,
          1021776, 1023646, 1114960, 1156398, 1221160, 1271642.

Release 1.95.8 Fri Jul 23 2004
        - Major new feature: suspend/resume.  Handlers can now request
          that a parse be suspended for later resumption or aborted
          altogether.  See "Temporarily Stopping Parsing" in the
          documentation for more details.
        - Some mostly minor bug fixes, but compilation should no
          longer generate warnings on most platforms.  SF issues
          include: 827319, 840173, 846309, 888329, 896188, 923913,
          928113, 961698, 985192.

Release 1.95.7 Mon Oct 20 2003
        - Fixed enum XML_Status issue (reported on SourceForge many
          times), so compilers that are properly picky will be happy.
        - Introduced an XMLCALL macro to control the calling
          convention used by the Expat API; this macro should be used
          to annotate prototypes and definitions of callback
          implementations in code compiled with a calling convention
          other than the default convention for the host platform.
        - Improved ability to build without the configure-generated
          expat_config.h header.  This is useful for applications
          which embed Expat rather than linking in the library.
        - Fixed a variety of bugs: see SF issues 458907, 609603,
          676844, 679754, 692878, 692964, 695401, 699323, 699487,
          820946.
        - Improved hash table lookups.
        - Added more regression tests and improved documentation.

Release 1.95.6 Tue Jan 28 2003
        - Added XML_FreeContentModel().
        - Added XML_MemMalloc(), XML_MemRealloc(), XML_MemFree().
        - Fixed a variety of bugs: see SF issues 615606, 616863,
          618199, 653180, 673791.
        - Enhanced the regression test suite.
        - Man page improvements: includes SF issue 632146.

Release 1.95.5 Fri Sep 6 2002
        - Added XML_UseForeignDTD() for improved SAX2 support.
        - Added XML_GetFeatureList().
        - Defined XML_Bool type and the values XML_TRUE and XML_FALSE.
        - Use an incomplete struct instead of a void* for the parser
          (may not retain).
................................................................................
          Initial patch contributed by Darryl Miles.
        - Removed unnecessary DllMain() function that caused static
          linking into a DLL to be difficult.
        - Added VC++ projects for building static libraries.
        - Reduced line-length for all source code and headers to be
          no longer than 80 characters, to help with AS/400 support.
        - Reduced memory copying during parsing (SF patch #600964).
        - Fixed a variety of bugs: see SF issues 580793, 434664,
          483514, 580503, 581069, 584041, 584183, 584832, 585537,
          596555, 596678, 598352, 598944, 599715, 600479, 600971.

Release 1.95.4 Fri Jul 12 2002
        - Added support for VMS, contributed by Craig Berry.  See
          vms/README.vms for more information.
        - Added Mac OS (classic) support, with a makefile for MPW,
          contributed by Thomas Wegner and Daryle Walker.
        - Added Borland C++ Builder 5 / BCC 5.5 support, contributed
          by Patrick McConnell (SF patch #538032).
        - Fixed a variety of bugs: see SF issues 441449, 563184,
          564342, 566334, 566901, 569461, 570263, 575168, 579196.
        - Made skippedEntityHandler conform to SAX2 (see source comment)
        - Re-implemented WFC: Entity Declared from XML 1.0 spec and
          added a new error "entity declared in parameter entity":
          see SF bug report 569461 and SF patch 578161
        - Re-implemented section 5.1 from XML 1.0 spec:
          see SF bug report 570263 and SF patch 578161

Release 1.95.3 Mon Jun 3 2002
        - Added a project to the MSVC workspace to create a wchar_t
          version of the library; the DLLs are named libexpatw.dll.
        - Changed the name of the Windows DLLs from expat.dll to
          libexpat.dll; this fixes SF bug #432456.
        - Added the XML_ParserReset() API function.
        - Fixed XML_SetReturnNSTriplet() to work for element names.
        - Made the XML_UNICODE builds usable (thanks, Karl!).
        - Allow xmlwf to read from standard input.
        - Install a man page for xmlwf on Unix systems.
        - Fixed many bugs; see SF bug reports 231864, 461380, 464837,
          466885, 469226, 477667, 484419, 487840, 494749, 496505,
          547350.  Other bugs which we can't test as easily may also
          have been fixed, especially in the area of build support.

Release 1.95.2 Fri Jul 27 2001
        - More changes to make MSVC happy with the build; add a single
          workspace to support both the library and xmlwf application.
        - Added a Windows installer for Windows users; includes
          xmlwf.exe.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|








|







 







|
|








|
|












|
|
|






|
|

|







 







|
|
|








|
|



|

|











|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
...
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
...
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
NOTE: We are looking for help with a few things:
      https://github.com/libexpat/libexpat/labels/help%20wanted
      If you can help, please get in touch.  Thanks!

Release 2.2.5 Tue October 31 2017
        Bug fixes:
              #8  If the parser runs out of memory, make sure its internal
                    state reflects the memory it actually has, not the memory
                    it wanted to have.
             #11  The default handler wasn't being called when it should for
                    a SYSTEM or PUBLIC doctype if an entity declaration handler
                    was registered.
       #137 #138  Fix a case of mistakenly reported parsing success where
                    XML_StopParser was called from an element handler
            #162  Function XML_ErrorString was returning NULL rather than
                    a message for code XML_ERROR_INVALID_ARGUMENT
                    introduced with release 2.2.1

        Other changes:
            #106  xmlwf: Add argument -N adding notation declarations
        #75 #106  Test suite: Resolve expected failure cases where xmlwf
                    output was incomplete
            #127  Windows: Fix test suite compilation
       #126 #127  Windows: Fix compilation for Visual Studio 2012
        #33 #132  tests: Mass-fix compilation for XML_UNICODE_WCHAR_T
            #129  examples: Fix compilation for XML_UNICODE_WCHAR_T
            #130  benchmark: Fix compilation for XML_UNICODE_WCHAR_T
            #144  xmlwf: Fix compilation for XML_UNICODE_WCHAR_T; still needs
                    Windows or MinGW for 2-byte wchar_t
              #9  Address two Clang Static Analyzer false positives
             #59  Resolve troublesome macros hiding parser struct membership
                    and dereferencing that pointer
              #6  Resolve superfluous internal malloc/realloc switch
       #153 #155  Improve docbook2x-man detection
            #160  Undefine NDEBUG in the test suite (rather than rejecting it)
            #161  Address compiler warnings
                  Version info bumped from 7:6:6 to 7:7:6

        Special thanks to:
            Benbuck Nason
            Hans Wennborg
            Josรฉ Gutiรฉrrez de la Concha
            Pedro Monreal Gonzalez
            Rhodri James
            Rolf Ade
            Stephen Groat
                 and
            Core Infrastructure Initiative

Release 2.2.4 Sat August 19 2017
        Bug fixes:
            #115  Fix copying of partial characters for UTF-8 input

        Other changes:
            #109  Fix "make check" for non-x86 architectures that default
                    to unsigned type char (-128..127 rather than 0..255)
            #109  coverage.sh: Cover -funsigned-char
                  Autotools: Introduce --without-xmlwf argument
             #65  Autotools: Replace handwritten Makefile with GNU Automake
             #43  CMake: Auto-detect high quality entropy extractors, add new
                    option USE_libbsd=ON to use arc4random_buf of libbsd
             #74  CMake: Add -fno-strict-aliasing only where supported
            #114  CMake: Always honor manually set BUILD_* options
            #114  CMake: Compile man page if docbook2x-man is available, only
            #117  Include file tests/xmltest.log.expected in source tarball
                    (required for "make run-xmltest")
            #117  Include (existing) Visual Studio 2013 files in source tarball
                  Improve test suite error output
            #111  Fix some typos in documentation
                  Version info bumped from 7:5:6 to 7:6:6

        Special thanks to:
            Jakub Wilk
            Joe Orton
            Lin Tian
            Rolf Eike Beer

Release 2.2.3 Wed August 2 2017
        Security fixes:
             #82  CVE-2017-11742 -- Windows: Fix DLL hijacking vulnerability
                    using Steve Holme's LoadLibrary wrapper for/of cURL

        Bug fixes:
             #85  Fix a dangling pointer issue related to realloc

        Other changes:
                  Increase code coverage
             #91  Linux: Allow getrandom to fail if nonblocking pool has not
                    yet been initialized and read /dev/urandom then, instead.
                    This is in line with what recent Python does.
             #81  Pre-10.7/Lion macOS: Support entropy from arc4random
             #86  Check that a UTF-16 encoding in an XML declaration has the
                    right endianness
        #4 #5 #7  Recover correctly when some reallocations fail
                  Repair "./configure && make" for systems without any
                    provider of high quality entropy
                    and try reading /dev/urandom on those
                  Ensure that user-defined character encodings have converter
                    functions when they are needed
                  Fix mis-leading description of argument -c in xmlwf.1
                  Rely on macro HAVE_ARC4RANDOM_BUF (rather than __CloudABI__)
                    for CloudABI
            #100  Fix use of SIPHASH_MAIN in siphash.h
             #23  Test suite: Fix memory leaks
                  Version info bumped from 7:4:6 to 7:5:6

        Special thanks to:
            Chanho Park
            Joe Orton
            Pascal Cuoq
            Rhodri James
            Simon McVittie
            Vadim Zeitlin
            Viktor Szakats
                 and
            Core Infrastructure Initiative

Release 2.2.2 Wed July 12 2017
        Security fixes:
             #43  Protect against compilation without any source of high
                    quality entropy enabled, e.g. with CMake build system;
                    commit ff0207e6076e9828e536b8d9cd45c9c92069b895
             #60  Windows with _UNICODE:
                    Unintended use of LoadLibraryW with a non-wide string
                    resulted in failure to load advapi32.dll and degradation
                    in quality of used entropy when compiled with _UNICODE for
                    Windows; you can launch existing binaries with
                    EXPAT_ENTROPY_DEBUG=1 in the environment to inspect the
                    quality of entropy used during runtime; commits
                    * 95b95032f907ef1cd17ee7a9a1768010a825d61d
                    * 73a5a2e9c081f49f2d775cf7ced864158b68dc80
   [MOX-006]      Fix non-NULL parser parameter validation in XML_Parse;
                    resulted in NULL dereference, previously;
                    commit ac256dafdffc9622ab0dc2c62fcecb0dfcfa71fe

        Bug fixes:
             #69  Fix improper use of unsigned long long integer literals

        Other changes:
             #73  Start requiring a C99 compiler
             #49  Fix "==" Bashism in configure script
             #50  Fix too eager getrandom detection for Debian GNU/kFreeBSD
             #52    and macOS
             #51  Address lack of stdint.h in Visual Studio 2003 to 2008
             #58  Address compile warnings
             #68  Fix "./buildconf.sh && ./configure" for some versions
                    of Dash for /bin/sh
             #72  CMake: Ease use of Expat in context of a parent project
                    with multiple CMakeLists.txt files
             #72  CMake: Resolve mistaken executable permissions
             #76  Address compile warning with -DNDEBUG (not recommended!)
             #77  Address compile warning about macro redefinition

        Special thanks to:
            Alexander Bluhm
            Ben Boeckel
            Cฤƒtฤƒlin Rฤƒceanu
            Kerin Millar
            Lรกszlรณ Bรถszรถrmรฉnyi
            S. P. Zeidler
            Segev Finer
            Vรกclav Slavรญk
            Victor Stinner
            Viktor Szakats
                 and
            Radically Open Security

Release 2.2.1 Sat June 17 2017
        Security fixes:
                  CVE-2017-9233 -- External entity infinite loop DoS
                    Details: https://libexpat.github.io/doc/cve-2017-9233/
                    Commit c4bf96bb51dd2a1b0e185374362ee136fe2c9d7f
   [MOX-002]      CVE-2016-9063 -- Detect integer overflow; commit
                    d4f735b88d9932bd5039df2335eefdd0723dbe20
                    (Fixed version of existing downstream patches!)
   (SF.net) #539  Fix regression from fix to CVE-2016-0718 cutting off
                    longer tag names; commits
                    * 896b6c1fd3b842f377d1b62135dccf0a579cf65d
                    * af507cef2c93cb8d40062a0abe43a4f4e9158fb2
             #16    * 0dbbf43fdb20f593ddf4fa1ff67288000dd4a7fd
             #25  More integer overflow detection (function poolGrow); commits
                    * 810b74e4703dcfdd8f404e3cb177d44684775143
                    * 44178553f3539ce69d34abee77a05e879a7982ac
   [MOX-002]      Detect overflow from len=INT_MAX call to XML_Parse; commits
                    * 4be2cb5afcc018d996f34bbbce6374b7befad47f
                    * 7e5b71b748491b6e459e5c9a1d090820f94544d8
   [MOX-005] #30  Use high quality entropy for hash initialization:
                    * arc4random_buf on BSD, systems with libbsd
                      (when configured with --with-libbsd), CloudABI
                    * RtlGenRandom on Windows XP / Server 2003 and later
                    * getrandom on Linux 3.17+
                    In a way, that's still part of CVE-2016-5300.
                    https://github.com/libexpat/libexpat/pull/30/commits
   [MOX-005]      For the low quality entropy extraction fallback code,
                    the parser instance address can no longer leak, commit
                    04ad658bd3079dd15cb60fc67087900f0ff4b083
   [MOX-003]      Prevent use of uninitialised variable; commit
   [MOX-004]        a4dc944f37b664a3ca7199c624a98ee37babdb4b
                  Add missing parameter validation to public API functions
                    and dedicated error code XML_ERROR_INVALID_ARGUMENT:
   [MOX-006]        * NULL checks; commits
                      * d37f74b2b7149a3a95a680c4c4cd2a451a51d60a (merge/many)
                      * 9ed727064b675b7180c98cb3d4f75efba6966681
                      * 6a747c837c50114dfa413994e07c0ba477be4534
                    * Negative length (XML_Parse); commit
   [MOX-002]          70db8d2538a10f4c022655d6895e4c3e78692e7f
   [MOX-001] #35  Change hash algorithm to William Ahern's version of SipHash
                    to go further with fixing CVE-2012-0876.
                    https://github.com/libexpat/libexpat/pull/39/commits

        Bug fixes:
             #32  Fix sharing of hash salt across parsers;
                    relevant where XML_ExternalEntityParserCreate is called
                    prior to XML_Parse, in particular (e.g. FBReader)
             #28  xmlwf: Auto-disable use of memory-mapping (and parsing
                    as a single chunk) for files larger than ~1 GB (2^30 bytes)
                    rather than failing with error "out of memory"
              #3  Fix double free after malloc failure in DTD code; commit
                    7ae9c3d3af433cd4defe95234eae7dc8ed15637f
             #17  Fix memory leak on parser error for unbound XML attribute
                    prefix with new namespaces defined in the same tag;
                    found by Google's OSS-Fuzz; commits
                    * 16f87daae5a16132e479e4f71862128c7a915c73
                    * b47dbc9745932c160893d433220e462bd605f8cd
                  xmlwf on Windows: Add missing calls to CloseHandle

        New features:
             #30  Introduced environment switch EXPAT_ENTROPY_DEBUG=1
                    for runtime debugging of entropy extraction

        Other changes:
                  Increase code coverage
             #33  Reject use of XML_UNICODE_WCHAR_T with sizeof(wchar_t) != 2;
                    XML_UNICODE_WCHAR_T was never meant to be used outside
                    of Windows; 4-byte wchar_t is common on Linux
   (SF.net) #538  Start using -fno-strict-aliasing
   (SF.net) #540  Support compilation against cloudlibc of CloudABI
                  Allow MinGW cross-compilation
   (SF.net) #534  CMake: Introduce option "BUILD_doc" (enabled by default)
                    to bypass compilation of the xmlwf.1 man page
   (SF.net)  pr2  CMake: Introduce option "INSTALL" (enabled by default)
                    to bypass installation of expat files
                  CMake: Fix ninja support
                  Autotools: Add parameters --enable-xml-context [COUNT]
                    and --disable-xml-context; default of context of 1024
                    bytes enabled unchanged
             #14  Drop AmigaOS 4.x code and includes
             #14  Drop ancient build systems:
                    * Borland C++ Builder
                    * OpenVMS
                    * Open Watcom
                    * Visual Studio 6.0
                    * Pre-X Mac OS (MPW Makefile)
                    If you happen to rely on some of these, please get in
                    touch for joining with maintenance.
             #10  Move from WIN32 to _WIN32
             #13  Fix "make run-xmltest" order instability
                  Address compile warnings
                  Bump version info from 7:2:6 to 7:3:6
                  Add AUTHORS file

        Infrastructure:
              #1  Migrate from SourceForge to GitHub (except downloads):
                    https://github.com/libexpat/
              #1  Re-create http://libexpat.org/ project website
                  Start utilizing Travis CI

        Special thanks to:
            Andy Wang
            Don Lewis
            Ed Schouten
            Karl Waclawek
            Pascal Cuoq
            Rhodri James
            Sergei Nikulov
            Tobias Taschner
            Viktor Szakats
                 and
            Core Infrastructure Initiative
            Mozilla Foundation (MOSS Track 3: Secure Open Source)
            Radically Open Security

Release 2.2.0 Tue June 21 2016
        Security fixes:
            #537  CVE-2016-0718 -- Fix crash on malformed input
                  CVE-2016-4472 -- Improve insufficient fix to CVE-2015-1283 /
                                   CVE-2015-2716 introduced with Expat 2.1.1
            #499  CVE-2016-5300 -- Use more entropy for hash initialization
                                   than the original fix to CVE-2012-0876
            #519  CVE-2012-6702 -- Resolve troublesome internal call to srand
                                   that was introduced with Expat 2.1.0
                                   when addressing CVE-2012-0876 (issue #496)

        Bug fixes:
                  Fix uninitialized reads of size 1
                    (e.g. in little2_updatePosition)
                  Fix detection of UTF-8 character boundaries

        Other changes:
            #532  Fix compilation for Visual Studio 2010 (keyword "C99")
                  Autotools: Resolve use of "$<" to better support bmake
                  Autotools: Add QA script "qa.sh" (and make target "qa")
                  Autotools: Respect CXXFLAGS if given
                  Autotools: Fix "make run-xmltest"
                  Autotools: Have "make run-xmltest" check for expected output
             p90  CMake: Fix static build (BUILD_shared=OFF) on Windows
            #536  CMake: Add soversion, support -DNO_SONAME=yes to bypass
            #323  CMake: Add suffix "d" to differentiate debug from release
                  CMake: Define WIN32 with CMake on Windows
                  Annotate memory allocators for GCC
                  Address all currently known compile warnings
                  Make sure that API symbols remain visible despite
                    -fvisibility=hidden
                  Remove executable flag from source files
                  Resolve COMPILED_FROM_DSP in favor of WIN32

        Special thanks to:
            Bjรถrn Lindahl
            Christian Heimes
            Cristian Rodrรญguez
            Daniel Krรผgler
            Gustavo Grieco
            Karl Waclawek
            Lรกszlรณ Bรถszรถrmรฉnyi
            Marco Grassi
            Pascal Cuoq
            Sergei Nikulov
            Thomas Beutlich
            Warren Young
            Yann Droneaud

Release 2.1.1 Sat March 12 2016
        Security fixes:
            #582: CVE-2015-1283 - Multiple integer overflows in XML_GetBuffer

        Bug fixes:
            #502: Fix potential null pointer dereference
            #520: Symbol XML_SetHashSalt was not exported
            Output of "xmlwf -h" was incomplete

        Other changes:
            #503: Document behavior of calling XML_SetHashSalt with salt 0
            Minor improvements to man page xmlwf(1)
            Improvements to the experimental CMake build system
            libtool now invoked with --verbose

Release 2.1.0 Sat March 24 2012
        - Security fixes:
          #2958794: CVE-2012-1148 - Memory leak in poolGrow.
          #2895533: CVE-2012-1147 - Resource leak in readfilemap.c.
          #3496608: CVE-2012-0876 - Hash DOS attack.
          #2894085: CVE-2009-3560 - Buffer over-read and crash in big2_toUtf8().
          #1990430: CVE-2009-3720 - Parser crash with special UTF-8 sequences.
        - Bug Fixes:
          #1742315: Harmful XML_ParserCreateNS suggestion.
          #1785430: Expat build fails on linux-amd64 with gcc version>=4.1 -O3.
          #1983953, 2517952, 2517962, 2649838: 
                Build modifications using autoreconf instead of buildconf.sh.
          #2815947, #2884086: OBJEXT and EXEEXT support while building.
          #2517938: xmlwf should return non-zero exit status if not well-formed.
          #2517946: Wrong statement about XMLDecl in xmlwf.1 and xmlwf.sgml.
          #2855609: Dangling positionPtr after error.
          #2990652: CMake support.
          #3010819: UNEXPECTED_STATE with a trailing "%" in entity value.
          #3206497: Uninitialized memory returned from XML_Parse.
          #3287849: make check fails on mingw-w64.
        - Patches:
          #1749198: pkg-config support.
          #3010222: Fix for bug #3010819.
          #3312568: CMake support.
          #3446384: Report byte offsets for attr names and values.
        - New Features / API changes:
          Added new API member XML_SetHashSalt() that allows setting an initial
                value (salt) for hash calculations. This is part of the fix for
                bug #3496608 to randomize hash parameters.
          When compiled with XML_ATTR_INFO defined, adds new API member
                XML_GetAttributeInfo() that allows retrieving the byte
                offsets for attribute names and values (patch #3446384).
          Added CMake build system.
                See bug #2990652 and patch #3312568.
          Added run-benchmark target to Makefile.in - relies on testdata module
                present in the same relative location as in the repository.
          
Release 2.0.1 Tue June 5 2007
        - Fixed bugs #1515266, #1515600: The character data handler's calling
          of XML_StopParser() was not handled properly; if the parser was
          stopped and the handler set to NULL, the parser would segfault.
        - Fixed bug #1690883: Expat failed on EBCDIC systems as it assumed
          some character constants to be ASCII encoded.
        - Minor cleanups of the test harness.
        - Fixed xmlwf bug #1513566: "out of memory" error on file size zero.
        - Fixed outline.c bug #1543233: missing a final XML_ParserFree() call.
        - Fixes and improvements for Windows platform:
          bugs #1409451, #1476160, #1548182, #1602769, #1717322.
        - Build fixes for various platforms:
          HP-UX, Tru64, Solaris 9: patch #1437840, bug #1196180.
          All Unix: #1554618 (refreshed config.sub/config.guess).
                    #1490371, #1613457: support both, DESTDIR and INSTALL_ROOT,
                    without relying on GNU-Make specific features.
          #1647805: Patched configure.in to work better with Intel compiler.
        - Fixes to Makefile.in to have make check work correctly:
................................................................................
        - Fixed headers for use from C++.
        - XML_GetCurrentLineNumber() and  XML_GetCurrentColumnNumber()
          now return unsigned integers.
        - Added XML_LARGE_SIZE switch to enable 64-bit integers for
          byte indexes and line/column numbers.
        - Updated to use libtool 1.5.22 (the most recent).
        - Added support for AmigaOS.
        - Some mostly minor bug fixes. SF issues include: #1006708,
          #1021776, #1023646, #1114960, #1156398, #1221160, #1271642.

Release 1.95.8 Fri Jul 23 2004
        - Major new feature: suspend/resume.  Handlers can now request
          that a parse be suspended for later resumption or aborted
          altogether.  See "Temporarily Stopping Parsing" in the
          documentation for more details.
        - Some mostly minor bug fixes, but compilation should no
          longer generate warnings on most platforms.  SF issues
          include: #827319, #840173, #846309, #888329, #896188, #923913,
          #928113, #961698, #985192.

Release 1.95.7 Mon Oct 20 2003
        - Fixed enum XML_Status issue (reported on SourceForge many
          times), so compilers that are properly picky will be happy.
        - Introduced an XMLCALL macro to control the calling
          convention used by the Expat API; this macro should be used
          to annotate prototypes and definitions of callback
          implementations in code compiled with a calling convention
          other than the default convention for the host platform.
        - Improved ability to build without the configure-generated
          expat_config.h header.  This is useful for applications
          which embed Expat rather than linking in the library.
        - Fixed a variety of bugs: see SF issues #458907, #609603,
          #676844, #679754, #692878, #692964, #695401, #699323, #699487,
          #820946.
        - Improved hash table lookups.
        - Added more regression tests and improved documentation.

Release 1.95.6 Tue Jan 28 2003
        - Added XML_FreeContentModel().
        - Added XML_MemMalloc(), XML_MemRealloc(), XML_MemFree().
        - Fixed a variety of bugs: see SF issues #615606, #616863,
          #618199, #653180, #673791.
        - Enhanced the regression test suite.
        - Man page improvements: includes SF issue #632146.

Release 1.95.5 Fri Sep 6 2002
        - Added XML_UseForeignDTD() for improved SAX2 support.
        - Added XML_GetFeatureList().
        - Defined XML_Bool type and the values XML_TRUE and XML_FALSE.
        - Use an incomplete struct instead of a void* for the parser
          (may not retain).
................................................................................
          Initial patch contributed by Darryl Miles.
        - Removed unnecessary DllMain() function that caused static
          linking into a DLL to be difficult.
        - Added VC++ projects for building static libraries.
        - Reduced line-length for all source code and headers to be
          no longer than 80 characters, to help with AS/400 support.
        - Reduced memory copying during parsing (SF patch #600964).
        - Fixed a variety of bugs: see SF issues #580793, #434664,
          #483514, #580503, #581069, #584041, #584183, #584832, #585537,
          #596555, #596678, #598352, #598944, #599715, #600479, #600971.

Release 1.95.4 Fri Jul 12 2002
        - Added support for VMS, contributed by Craig Berry.  See
          vms/README.vms for more information.
        - Added Mac OS (classic) support, with a makefile for MPW,
          contributed by Thomas Wegner and Daryle Walker.
        - Added Borland C++ Builder 5 / BCC 5.5 support, contributed
          by Patrick McConnell (SF patch #538032).
        - Fixed a variety of bugs: see SF issues #441449, #563184,
          #564342, #566334, #566901, #569461, #570263, #575168, #579196.
        - Made skippedEntityHandler conform to SAX2 (see source comment)
        - Re-implemented WFC: Entity Declared from XML 1.0 spec and
          added a new error "entity declared in parameter entity":
          see SF bug report #569461 and SF patch #578161
        - Re-implemented section 5.1 from XML 1.0 spec:
          see SF bug report #570263 and SF patch #578161

Release 1.95.3 Mon Jun 3 2002
        - Added a project to the MSVC workspace to create a wchar_t
          version of the library; the DLLs are named libexpatw.dll.
        - Changed the name of the Windows DLLs from expat.dll to
          libexpat.dll; this fixes SF bug #432456.
        - Added the XML_ParserReset() API function.
        - Fixed XML_SetReturnNSTriplet() to work for element names.
        - Made the XML_UNICODE builds usable (thanks, Karl!).
        - Allow xmlwf to read from standard input.
        - Install a man page for xmlwf on Unix systems.
        - Fixed many bugs; see SF bug reports #231864, #461380, #464837,
          #466885, #469226, #477667, #484419, #487840, #494749, #496505,
          #547350.  Other bugs which we can't test as easily may also
          have been fixed, especially in the area of build support.

Release 1.95.2 Fri Jul 27 2001
        - More changes to make MSVC happy with the build; add a single
          workspace to support both the library and xmlwf application.
        - Added a Windows installer for Windows users; includes
          xmlwf.exe.

Deleted expat/README.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

                        Expat, Release 2.0.1

This is Expat, a C library for parsing XML, written by James Clark.
Expat is a stream-oriented XML parser.  This means that you register
handlers with the parser before starting the parse.  These handlers
are called when the parser discovers the associated structures in the
document being parsed.  A start tag is an example of the kind of
structures for which you may register handlers.

Windows users should use the expat_win32bin package, which includes
both precompiled libraries and executables, and source code for
developers.

Expat is free software.  You may copy, distribute, and modify it under
the terms of the License contained in the file COPYING distributed
with this package.  This license is the same as the MIT/X Consortium
license.

Versions of Expat that have an odd minor version (the middle number in
the release above), are development releases and should be considered
as beta software.  Releases with even minor version numbers are
intended to be production grade software.

If you are building Expat from a check-out from the CVS repository,
you need to run a script that generates the configure script using the
GNU autoconf and libtool tools.  To do this, you need to have
autoconf 2.52 or newer and libtool 1.4 or newer (1.5 or newer preferred).
Run the script like this:

        ./buildconf.sh

Once this has been done, follow the same instructions as for building
from a source distribution.

To build Expat from a source distribution, you first run the
configuration shell script in the top level distribution directory:

        ./configure

There are many options which you may provide to configure (which you
can discover by running configure with the --help option).  But the
one of most interest is the one that sets the installation directory.
By default, the configure script will set things up to install
libexpat into /usr/local/lib, expat.h into /usr/local/include, and
xmlwf into /usr/local/bin.  If, for example, you'd prefer to install
into /home/me/mystuff/lib, /home/me/mystuff/include, and
/home/me/mystuff/bin, you can tell configure about that with:

        ./configure --prefix=/home/me/mystuff
        
Another interesting option is to enable 64-bit integer support for
line and column numbers and the over-all byte index:

        ./configure CPPFLAGS=-DXML_LARGE_SIZE
        
However, such a modification would be a breaking change to the ABI
and is therefore not recommended for general use - e.g. as part of
a Linux distribution - but rather for builds with special requirements.

After running the configure script, the "make" command will build
things and "make install" will install things into their proper
location.  Have a look at the "Makefile" to learn about additional
"make" options.  Note that you need to have write permission into
the directories into which things will be installed.

If you are interested in building Expat to provide document
information in UTF-16 rather than the default UTF-8, follow these
instructions (after having run "make distclean"):

        1. For UTF-16 output as unsigned short (and version/error
           strings as char), run:

               ./configure CPPFLAGS=-DXML_UNICODE

           For UTF-16 output as wchar_t (incl. version/error strings),
           run:

               ./configure CFLAGS="-g -O2 -fshort-wchar" \
                           CPPFLAGS=-DXML_UNICODE_WCHAR_T

        2. Edit the MakeFile, changing:

               LIBRARY = libexpat.la

           to:

               LIBRARY = libexpatw.la

           (Note the additional "w" in the library name.)

        3. Run "make buildlib" (which builds the library only).
           Or, to save step 2, run "make buildlib LIBRARY=libexpatw.la".

        4. Run "make installlib" (which installs the library only).
           Or, if step 2 was omitted, run "make installlib LIBRARY=libexpatw.la".
           
Using DESTDIR or INSTALL_ROOT is enabled, with INSTALL_ROOT being the default
value for DESTDIR, and the rest of the make file using only DESTDIR.
It works as follows:
   $ make install DESTDIR=/path/to/image
overrides the in-makefile set DESTDIR, while both
   $ INSTALL_ROOT=/path/to/image make install
   $ make install INSTALL_ROOT=/path/to/image
use DESTDIR=$(INSTALL_ROOT), even if DESTDIR eventually is defined in the
environment, because variable-setting priority is
1) commandline
2) in-makefile
3) environment           

Note for Solaris users:  The "ar" command is usually located in
"/usr/ccs/bin", which is not in the default PATH.  You will need to
add this to your path for the "make" command, and probably also switch
to GNU make (the "make" found in /usr/ccs/bin does not seem to work
properly -- appearantly it does not understand .PHONY directives).  If
you're using ksh or bash, use this command to build:

        PATH=/usr/ccs/bin:$PATH make

When using Expat with a project using autoconf for configuration, you
can use the probing macro in conftools/expat.m4 to determine how to
include Expat.  See the comments at the top of that file for more
information.

A reference manual is available in the file doc/reference.html in this
distribution.

The homepage for this project is http://www.libexpat.org/.  There
are links there to connect you to the bug reports page.  If you need
to report a bug when you don't have access to a browser, you may also
send a bug report by email to expat-bugs@mail.libexpat.org.

Discussion related to the direction of future expat development takes
place on expat-discuss@mail.libexpat.org.  Archives of this list and
other Expat-related lists may be found at:

        http://mail.libexpat.org/mailman/listinfo/
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































Added expat/README.md.





























































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
[![Travis CI Build Status](https://travis-ci.org/libexpat/libexpat.svg?branch=master)](https://travis-ci.org/libexpat/libexpat)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/libexpat/libexpat?svg=true)](https://ci.appveyor.com/project/libexpat/libexpat)


# Expat, Release 2.2.5

This is Expat, a C library for parsing XML, started by
[James Clark](https://en.wikipedia.org/wiki/James_Clark_(programmer)) in 1997.
Expat is a stream-oriented XML parser.  This means that you register
handlers with the parser before starting the parse.  These handlers
are called when the parser discovers the associated structures in the
document being parsed.  A start tag is an example of the kind of
structures for which you may register handlers.

Windows users should use the
[`expat_win32` package](https://sourceforge.net/projects/expat/files/expat_win32/),
which includes both precompiled libraries and executables, and source code for
developers.

Expat is [free software](https://www.gnu.org/philosophy/free-sw.en.html).
You may copy, distribute, and modify it under the terms of the License
contained in the file
[`COPYING`](https://github.com/libexpat/libexpat/blob/master/expat/COPYING)
distributed with this package.
This license is the same as the MIT/X Consortium license.

If you are building Expat from a check-out from the
[Git repository](https://github.com/libexpat/libexpat/),
you need to run a script that generates the configure script using the
GNU autoconf and libtool tools.  To do this, you need to have
autoconf 2.58 or newer. Run the script like this:

```console
./buildconf.sh
```

Once this has been done, follow the same instructions as for building
from a source distribution.

To build Expat from a source distribution, you first run the
configuration shell script in the top level distribution directory:

```console
./configure
```

There are many options which you may provide to configure (which you
can discover by running configure with the `--help` option).  But the
one of most interest is the one that sets the installation directory.
By default, the configure script will set things up to install
libexpat into `/usr/local/lib`, `expat.h` into `/usr/local/include`, and
`xmlwf` into `/usr/local/bin`.  If, for example, you'd prefer to install
into `/home/me/mystuff/lib`, `/home/me/mystuff/include`, and
`/home/me/mystuff/bin`, you can tell `configure` about that with:

```console
./configure --prefix=/home/me/mystuff
```

Another interesting option is to enable 64-bit integer support for
line and column numbers and the over-all byte index:

```console
./configure CPPFLAGS=-DXML_LARGE_SIZE
```

However, such a modification would be a breaking change to the ABI
and is therefore not recommended for general use &mdash; e.g. as part of
a Linux distribution &mdash; but rather for builds with special requirements.

After running the configure script, the `make` command will build
things and `make install` will install things into their proper
location.  Have a look at the `Makefile` to learn about additional
`make` options.  Note that you need to have write permission into
the directories into which things will be installed.

If you are interested in building Expat to provide document
information in UTF-16 encoding rather than the default UTF-8, follow
these instructions (after having run `make distclean`).
Please note that we configure with `--without-xmlwf` as xmlwf does not
support this mode of compilation (yet):

1. Mass-patch `Makefile.am` files to use `libexpatw.la` for a library name:
   <br/>
   `find -name Makefile.am -exec sed
       -e 's,libexpat\.la,libexpatw.la,'
       -e 's,libexpat_la,libexpatw_la,'
       -i {} +`

1. Run `automake` to re-write `Makefile.in` files:<br/>
   `automake`

1. For UTF-16 output as unsigned short (and version/error strings as char),
   run:<br/>
   `./configure CPPFLAGS=-DXML_UNICODE --without-xmlwf`<br/>
   For UTF-16 output as `wchar_t` (incl. version/error strings), run:<br/>
   `./configure CFLAGS="-g -O2 -fshort-wchar" CPPFLAGS=-DXML_UNICODE_WCHAR_T
       --without-xmlwf`
   <br/>Note: The latter requires libc compiled with `-fshort-wchar`, as well.

1. Run `make` (which excludes xmlwf).

1. Run `make install` (again, excludes xmlwf).

Using `DESTDIR` is supported.  It works as follows:

```console
make install DESTDIR=/path/to/image
```

overrides the in-makefile set `DESTDIR`, because variable-setting priority is

1. commandline
1. in-makefile
1. environment

Note: This only applies to the Expat library itself, building UTF-16 versions
of xmlwf and the tests is currently not supported.

When using Expat with a project using autoconf for configuration, you
can use the probing macro in `conftools/expat.m4` to determine how to
include Expat.  See the comments at the top of that file for more
information.

A reference manual is available in the file `doc/reference.html` in this
distribution.

Changes to expat/VERSION.

1
expat-2.0.1
|
1
expat-2.2.5

Deleted expat/amigaconfig.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#ifndef AMIGACONFIG_H
#define AMIGACONFIG_H

/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
#define BYTEORDER 4321

/* Define to 1 if you have the `bcopy' function. */
#define HAVE_BCOPY 1

/* Define to 1 if you have the <check.h> header file. */
#undef HAVE_CHECK_H

/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1

/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1

/* whether byteorder is bigendian */
#define WORDS_BIGENDIAN

/* Define to specify how much context to retain around the current parse
   point. */
#define XML_CONTEXT_BYTES 1024

/* Define to make parameter entity parsing functionality available. */
#define XML_DTD

/* Define to make XML Namespaces functionality available. */
#define XML_NS

#endif  /* AMIGACONFIG_H */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































Changes to expat/ascii.h.









1
2





















3
4
5
6
7
8
9








/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
   See the file COPYING for copying permission.





















*/

#define ASCII_A 0x41
#define ASCII_B 0x42
#define ASCII_C 0x43
#define ASCII_D 0x44
#define ASCII_E 0x45
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

#define ASCII_A 0x41
#define ASCII_B 0x42
#define ASCII_C 0x43
#define ASCII_D 0x44
#define ASCII_E 0x45

Changes to expat/asciitab.h.









1
2





















3
4
5
6
7
8
9








/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
   See the file COPYING 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,
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

/* 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,

Changes to expat/expat.h.









1
2





















3
4
5
6
7
8
9
..
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
..
91
92
93
94
95
96
97
98


99
100
101
102
103
104
105
...
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
...
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
...
702
703
704
705
706
707
708

709
710
711
712
713
714
715
...
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740

741
742
743























744
745
746
747
748
749
750
...
874
875
876
877
878
879
880

881
882
883
884










885
886
887
888
889
890
891
...
900
901
902
903
904
905
906




907
908
909
910
911
912
913
...
937
938
939
940
941
942
943


944
945
946

947
948
949
950
951
952
953
...
980
981
982
983
984
985
986
987

988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014








/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
   See the file COPYING for copying permission.





















*/

#ifndef Expat_INCLUDED
#define Expat_INCLUDED 1

#ifdef __VMS
/*      0        1         2         3      0        1         2         3
................................................................................
#ifdef __cplusplus
extern "C" {
#endif

struct XML_ParserStruct;
typedef struct XML_ParserStruct *XML_Parser;

/* Should this be defined using stdbool.h when C99 is available? */
typedef unsigned char XML_Bool;
#define XML_TRUE   ((XML_Bool) 1)
#define XML_FALSE  ((XML_Bool) 0)

/* The XML_Status enum gives the possible return values for several
   API functions.  The preprocessor #defines are included so this
   stanza can be added to code that still needs to support older
................................................................................
  XML_ERROR_NOT_SUSPENDED,
  XML_ERROR_ABORTED,
  XML_ERROR_FINISHED,
  XML_ERROR_SUSPEND_PE,
  /* Added in 2.0. */
  XML_ERROR_RESERVED_PREFIX_XML,
  XML_ERROR_RESERVED_PREFIX_XMLNS,
  XML_ERROR_RESERVED_NAMESPACE_URI


};

enum XML_Content_Type {
  XML_CTYPE_EMPTY = 1,
  XML_CTYPE_ANY,
  XML_CTYPE_MIXED,
  XML_CTYPE_NAME,
................................................................................
*/
XMLPARSEAPI(XML_Parser)
XML_ParserCreate_MM(const XML_Char *encoding,
                    const XML_Memory_Handling_Suite *memsuite,
                    const XML_Char *namespaceSeparator);

/* Prepare a parser object to be re-used.  This is particularly
   valuable when memory allocation overhead is disproportionatly high,
   such as when a large number of small documnents need to be parsed.
   All handlers are cleared from the parser, except for the
   unknownEncodingHandler. The parser's external state is re-initialized
   except for the values of ns and ns_triplets.

   Added in Expat 1.95.3.
*/
................................................................................
                              const XML_Char *notationName);

XMLPARSEAPI(void)
XML_SetEntityDeclHandler(XML_Parser parser,
                         XML_EntityDeclHandler handler);

/* OBSOLETE -- OBSOLETE -- OBSOLETE
   This handler has been superceded by the EntityDeclHandler above.
   It is provided here for backward compatibility.

   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.
*/
................................................................................
     have no effect after that.  Returns
     XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
   Note: If the document does not have a DOCTYPE declaration at all,
     then startDoctypeDeclHandler and endDoctypeDeclHandler will not
     be called, despite an external subset being parsed.
   Note: If XML_DTD is not defined when Expat is compiled, returns
     XML_ERROR_FEATURE_REQUIRES_XML_DTD.

*/
XMLPARSEAPI(enum XML_Error)
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);


/* Sets the base to be used for resolving relative URIs in system
   identifiers in declarations.  Resolving relative identifiers is
................................................................................
XMLPARSEAPI(const XML_Char *)
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.
*/
XMLPARSEAPI(int)
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.

*/
XMLPARSEAPI(int)
XML_GetIdAttributeIndex(XML_Parser parser);
























/* Parses some input. Returns XML_STATUS_ERROR 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).

   Though the return values for these functions has always been
   described as a Boolean value, the implementation, at least for the
................................................................................
   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.
   Note: If XML_SetParamEntityParsing is called after XML_Parse or
      XML_ParseBuffer, then it has no effect and will always return 0.

*/
XMLPARSEAPI(int)
XML_SetParamEntityParsing(XML_Parser parser,
                          enum XML_ParamEntityParsing parsing);











/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
   XML_GetErrorCode returns information about the error.
*/
XMLPARSEAPI(enum XML_Error)
XML_GetErrorCode(XML_Parser parser);

................................................................................
   event (regardless of whether there was an associated callback).
   
   They may also be called after returning from a call to XML_Parse
   or XML_ParseBuffer.  If the return value is XML_STATUS_ERROR then
   the location is the location of the character at which the error
   was detected; otherwise the location is the location of the last
   parse event, as described above.




*/
XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);

/* Return the number of bytes in the current event.
   Returns 0 if the event is in an internal entity.
................................................................................

/* Frees the content model passed to the element declaration handler */
XMLPARSEAPI(void)
XML_FreeContentModel(XML_Parser parser, XML_Content *model);

/* Exposing the memory handling functions used in Expat */
XMLPARSEAPI(void *)


XML_MemMalloc(XML_Parser parser, size_t size);

XMLPARSEAPI(void *)

XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);

XMLPARSEAPI(void)
XML_MemFree(XML_Parser parser, void *ptr);

/* Frees memory used by the parser. */
XMLPARSEAPI(void)
................................................................................
  XML_FEATURE_UNICODE_WCHAR_T,
  XML_FEATURE_DTD,
  XML_FEATURE_CONTEXT_BYTES,
  XML_FEATURE_MIN_SIZE,
  XML_FEATURE_SIZEOF_XML_CHAR,
  XML_FEATURE_SIZEOF_XML_LCHAR,
  XML_FEATURE_NS,
  XML_FEATURE_LARGE_SIZE

  /* Additional features must be added to the end of this enum. */
};

typedef struct {
  enum XML_FeatureEnum  feature;
  const XML_LChar       *name;
  long int              value;
} XML_Feature;

XMLPARSEAPI(const XML_Feature *)
XML_GetFeatureList(void);


/* Expat follows the GNU/Linux convention of odd number minor version for
   beta/development releases and even number minor version for stable
   releases. Micro is bumped with each release, and set to 0 with each
   change to major or minor version.
*/
#define XML_MAJOR_VERSION 2
#define XML_MINOR_VERSION 0
#define XML_MICRO_VERSION 1

#ifdef __cplusplus
}
#endif

#endif /* not Expat_INCLUDED */
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<







 







|
>
>







 







|







 







|







 







>







 







|





|
|
|
>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>




>
>
>
>
>
>
>
>
>
>







 







>
>
>
>







 







>
>



>







 







|
>













|
|
<
<


|
|






1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
48
49
50
51
52
53
54

55
56
57
58
59
60
61
...
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
...
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
...
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
...
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
...
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
...
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
....
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
....
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075


1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

#ifndef Expat_INCLUDED
#define Expat_INCLUDED 1

#ifdef __VMS
/*      0        1         2         3      0        1         2         3
................................................................................
#ifdef __cplusplus
extern "C" {
#endif

struct XML_ParserStruct;
typedef struct XML_ParserStruct *XML_Parser;


typedef unsigned char XML_Bool;
#define XML_TRUE   ((XML_Bool) 1)
#define XML_FALSE  ((XML_Bool) 0)

/* The XML_Status enum gives the possible return values for several
   API functions.  The preprocessor #defines are included so this
   stanza can be added to code that still needs to support older
................................................................................
  XML_ERROR_NOT_SUSPENDED,
  XML_ERROR_ABORTED,
  XML_ERROR_FINISHED,
  XML_ERROR_SUSPEND_PE,
  /* Added in 2.0. */
  XML_ERROR_RESERVED_PREFIX_XML,
  XML_ERROR_RESERVED_PREFIX_XMLNS,
  XML_ERROR_RESERVED_NAMESPACE_URI,
  /* Added in 2.2.1. */
  XML_ERROR_INVALID_ARGUMENT
};

enum XML_Content_Type {
  XML_CTYPE_EMPTY = 1,
  XML_CTYPE_ANY,
  XML_CTYPE_MIXED,
  XML_CTYPE_NAME,
................................................................................
*/
XMLPARSEAPI(XML_Parser)
XML_ParserCreate_MM(const XML_Char *encoding,
                    const XML_Memory_Handling_Suite *memsuite,
                    const XML_Char *namespaceSeparator);

/* Prepare a parser object to be re-used.  This is particularly
   valuable when memory allocation overhead is disproportionately high,
   such as when a large number of small documnents need to be parsed.
   All handlers are cleared from the parser, except for the
   unknownEncodingHandler. The parser's external state is re-initialized
   except for the values of ns and ns_triplets.

   Added in Expat 1.95.3.
*/
................................................................................
                              const XML_Char *notationName);

XMLPARSEAPI(void)
XML_SetEntityDeclHandler(XML_Parser parser,
                         XML_EntityDeclHandler handler);

/* OBSOLETE -- OBSOLETE -- OBSOLETE
   This handler has been superseded by the EntityDeclHandler above.
   It is provided here for backward compatibility.

   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.
*/
................................................................................
     have no effect after that.  Returns
     XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
   Note: If the document does not have a DOCTYPE declaration at all,
     then startDoctypeDeclHandler and endDoctypeDeclHandler will not
     be called, despite an external subset being parsed.
   Note: If XML_DTD is not defined when Expat is compiled, returns
     XML_ERROR_FEATURE_REQUIRES_XML_DTD.
   Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT.
*/
XMLPARSEAPI(enum XML_Error)
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);


/* Sets the base to be used for resolving relative URIs in system
   identifiers in declarations.  Resolving relative identifiers is
................................................................................
XMLPARSEAPI(const XML_Char *)
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.  Returns -1 if parser == NULL.
*/
XMLPARSEAPI(int)
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 or
   parser == NULL.  Each attribute/value pair counts as 2; thus this
   correspondds to an index into the atts array passed to the
   XML_StartElementHandler.
*/
XMLPARSEAPI(int)
XML_GetIdAttributeIndex(XML_Parser parser);

#ifdef XML_ATTR_INFO
/* Source file byte offsets for the start and end of attribute names and values.
   The value indices are exclusive of surrounding quotes; thus in a UTF-8 source
   file an attribute value of "blah" will yield:
   info->valueEnd - info->valueStart = 4 bytes.
*/
typedef struct {
  XML_Index  nameStart;  /* Offset to beginning of the attribute name. */
  XML_Index  nameEnd;    /* Offset after the attribute name's last byte. */
  XML_Index  valueStart; /* Offset to beginning of the attribute value. */
  XML_Index  valueEnd;   /* Offset after the attribute value's last byte. */
} XML_AttrInfo;

/* Returns an array of XML_AttrInfo structures for 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 1; thus the number of entries in the array is
   XML_GetSpecifiedAttributeCount(parser) / 2.
*/
XMLPARSEAPI(const XML_AttrInfo *)
XML_GetAttributeInfo(XML_Parser parser);
#endif

/* Parses some input. Returns XML_STATUS_ERROR 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).

   Though the return values for these functions has always been
   described as a Boolean value, the implementation, at least for the
................................................................................
   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.
   Note: If XML_SetParamEntityParsing is called after XML_Parse or
      XML_ParseBuffer, then it has no effect and will always return 0.
   Note: If parser == NULL, the function will do nothing and return 0.
*/
XMLPARSEAPI(int)
XML_SetParamEntityParsing(XML_Parser parser,
                          enum XML_ParamEntityParsing parsing);

/* Sets the hash salt to use for internal hash calculations.
   Helps in preventing DoS attacks based on predicting hash
   function behavior. This must be called before parsing is started.
   Returns 1 if successful, 0 when called after parsing has started.
   Note: If parser == NULL, the function will do nothing and return 0.
*/
XMLPARSEAPI(int)
XML_SetHashSalt(XML_Parser parser,
                unsigned long hash_salt);

/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
   XML_GetErrorCode returns information about the error.
*/
XMLPARSEAPI(enum XML_Error)
XML_GetErrorCode(XML_Parser parser);

................................................................................
   event (regardless of whether there was an associated callback).
   
   They may also be called after returning from a call to XML_Parse
   or XML_ParseBuffer.  If the return value is XML_STATUS_ERROR then
   the location is the location of the character at which the error
   was detected; otherwise the location is the location of the last
   parse event, as described above.

   Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber
   return 0 to indicate an error.
   Note: XML_GetCurrentByteIndex returns -1 to indicate an error.
*/
XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);

/* Return the number of bytes in the current event.
   Returns 0 if the event is in an internal entity.
................................................................................

/* Frees the content model passed to the element declaration handler */
XMLPARSEAPI(void)
XML_FreeContentModel(XML_Parser parser, XML_Content *model);

/* Exposing the memory handling functions used in Expat */
XMLPARSEAPI(void *)
XML_ATTR_MALLOC
XML_ATTR_ALLOC_SIZE(2)
XML_MemMalloc(XML_Parser parser, size_t size);

XMLPARSEAPI(void *)
XML_ATTR_ALLOC_SIZE(3)
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);

XMLPARSEAPI(void)
XML_MemFree(XML_Parser parser, void *ptr);

/* Frees memory used by the parser. */
XMLPARSEAPI(void)
................................................................................
  XML_FEATURE_UNICODE_WCHAR_T,
  XML_FEATURE_DTD,
  XML_FEATURE_CONTEXT_BYTES,
  XML_FEATURE_MIN_SIZE,
  XML_FEATURE_SIZEOF_XML_CHAR,
  XML_FEATURE_SIZEOF_XML_LCHAR,
  XML_FEATURE_NS,
  XML_FEATURE_LARGE_SIZE,
  XML_FEATURE_ATTR_INFO
  /* Additional features must be added to the end of this enum. */
};

typedef struct {
  enum XML_FeatureEnum  feature;
  const XML_LChar       *name;
  long int              value;
} XML_Feature;

XMLPARSEAPI(const XML_Feature *)
XML_GetFeatureList(void);


/* Expat follows the semantic versioning convention.
   See http://semver.org.


*/
#define XML_MAJOR_VERSION 2
#define XML_MINOR_VERSION 2
#define XML_MICRO_VERSION 5

#ifdef __cplusplus
}
#endif

#endif /* not Expat_INCLUDED */

Changes to expat/expat_external.h.









1
2





















3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
..
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67



68
69
70
71
72
73











74
75
76
77
78
79
80
81

82




83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115








/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
   See the file COPYING for copying permission.





















*/

#ifndef Expat_External_INCLUDED
#define Expat_External_INCLUDED 1

/* External API definitions */

#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
#define XML_USE_MSC_EXTENSIONS 1
#endif

/* Expat tries very hard to make the API boundary very specifically
   defined.  There are two macros defined to control this boundary;
   each of these can be defined before including this header to
   achieve some different behavior, but doing so it not recommended or
   tested frequently.
................................................................................
   expected to be directly useful in client code is XMLCALL.

   Note that on at least some Unix versions, the Expat library must be
   compiled with the cdecl calling convention as the default since
   system headers may assume the cdecl convention.
*/
#ifndef XMLCALL
#if defined(_MSC_VER)
#define XMLCALL __cdecl
#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
#define XMLCALL __attribute__((cdecl))
#else
/* For any platform which uses this definition and supports more than
   one calling convention, we need to extend this definition to
   declare the convention used on that platform, if it's possible to
   do so.

   If this is the case for your platform, please file a bug report
   with information on how to identify your platform via the C
   pre-processor and how to specify the same calling convention as the
   platform's malloc() implementation.
*/
#define XMLCALL
#endif
#endif  /* not defined XMLCALL */


#if !defined(XML_STATIC) && !defined(XMLIMPORT)
#ifndef XML_BUILDING_EXPAT
/* using Expat from an application */

#ifdef XML_USE_MSC_EXTENSIONS
#define XMLIMPORT __declspec(dllimport)
#endif

#endif
#endif  /* not defined XML_STATIC */





/* If we didn't define it above, define it away: */
#ifndef XMLIMPORT
#define XMLIMPORT
#endif













#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL

#ifdef __cplusplus
extern "C" {
#endif

#ifdef XML_UNICODE_WCHAR_T

#define XML_UNICODE




#endif

#ifdef XML_UNICODE     /* Information is UTF-16 encoded. */
#ifdef XML_UNICODE_WCHAR_T
typedef wchar_t XML_Char;
typedef wchar_t XML_LChar;
#else
typedef unsigned short XML_Char;
typedef char XML_LChar;
#endif /* XML_UNICODE_WCHAR_T */
#else                  /* Information is UTF-8 encoded. */
typedef char XML_Char;
typedef char XML_LChar;
#endif /* XML_UNICODE */

#ifdef XML_LARGE_SIZE  /* Use large integers for file/stream positions. */
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
typedef __int64 XML_Index; 
typedef unsigned __int64 XML_Size;
#else
typedef long long XML_Index;
typedef unsigned long long XML_Size;
#endif
#else
typedef long XML_Index;
typedef unsigned long XML_Size;
#endif /* XML_LARGE_SIZE */

#ifdef __cplusplus
}
#endif

#endif /* not Expat_External_INCLUDED */
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|







 







|
|
|
|
|










|
|




|


|
|
|

|


>
>
>



|


>
>
>
>
>
>
>
>
>
>
>








>
|
>
>
>
>



|


|


|






|


|


|










1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
..
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

#ifndef Expat_External_INCLUDED
#define Expat_External_INCLUDED 1

/* External API definitions */

#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
# define XML_USE_MSC_EXTENSIONS 1
#endif

/* Expat tries very hard to make the API boundary very specifically
   defined.  There are two macros defined to control this boundary;
   each of these can be defined before including this header to
   achieve some different behavior, but doing so it not recommended or
   tested frequently.
................................................................................
   expected to be directly useful in client code is XMLCALL.

   Note that on at least some Unix versions, the Expat library must be
   compiled with the cdecl calling convention as the default since
   system headers may assume the cdecl convention.
*/
#ifndef XMLCALL
# if defined(_MSC_VER)
#  define XMLCALL __cdecl
# elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
#  define XMLCALL __attribute__((cdecl))
# else
/* For any platform which uses this definition and supports more than
   one calling convention, we need to extend this definition to
   declare the convention used on that platform, if it's possible to
   do so.

   If this is the case for your platform, please file a bug report
   with information on how to identify your platform via the C
   pre-processor and how to specify the same calling convention as the
   platform's malloc() implementation.
*/
#  define XMLCALL
# endif
#endif  /* not defined XMLCALL */


#if !defined(XML_STATIC) && !defined(XMLIMPORT)
# ifndef XML_BUILDING_EXPAT
/* using Expat from an application */

#  ifdef XML_USE_MSC_EXTENSIONS
#   define XMLIMPORT __declspec(dllimport)
#  endif

# endif
#endif  /* not defined XML_STATIC */

#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)
# define XMLIMPORT __attribute__ ((visibility ("default")))
#endif

/* If we didn't define it above, define it away: */
#ifndef XMLIMPORT
# define XMLIMPORT
#endif

#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
# define XML_ATTR_MALLOC __attribute__((__malloc__))
#else
# define XML_ATTR_MALLOC
#endif

#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
# define XML_ATTR_ALLOC_SIZE(x)  __attribute__((__alloc_size__(x)))
#else
# define XML_ATTR_ALLOC_SIZE(x)
#endif

#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL

#ifdef __cplusplus
extern "C" {
#endif

#ifdef XML_UNICODE_WCHAR_T
# ifndef XML_UNICODE
#  define XML_UNICODE
# endif
# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
#  error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
# endif
#endif

#ifdef XML_UNICODE     /* Information is UTF-16 encoded. */
# ifdef XML_UNICODE_WCHAR_T
typedef wchar_t XML_Char;
typedef wchar_t XML_LChar;
# else
typedef unsigned short XML_Char;
typedef char XML_LChar;
# endif /* XML_UNICODE_WCHAR_T */
#else                  /* Information is UTF-8 encoded. */
typedef char XML_Char;
typedef char XML_LChar;
#endif /* XML_UNICODE */

#ifdef XML_LARGE_SIZE  /* Use large integers for file/stream positions. */
# if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
typedef __int64 XML_Index; 
typedef unsigned __int64 XML_Size;
# else
typedef long long XML_Index;
typedef unsigned long long XML_Size;
# endif
#else
typedef long XML_Index;
typedef unsigned long XML_Size;
#endif /* XML_LARGE_SIZE */

#ifdef __cplusplus
}
#endif

#endif /* not Expat_External_INCLUDED */

Changes to expat/iasciitab.h.









1
2





















3
4
5
6
7
8
9








/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
   See the file COPYING 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,
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

/* 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,

Changes to expat/internal.h.

14
15
16
17
18
19
20





























21
22
23
24
25
26
27
..
67
68
69
70
71
72
73






















   PTRFASTCALL - Like PTRCALL, but for low number of arguments.

   inline      - Used for selected internal functions for which inlining
                 may improve performance on some platforms.

   Note: Use of these macros is based on judgement, not hard rules,
         and therefore subject to change.





























*/

#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)
/* We'll use this version by default only where we know it helps.

   regparm() generates warnings on Solaris boxes.   See SF bug #692878.

................................................................................
#ifdef __cplusplus
#define inline inline
#else
#ifndef inline
#define inline
#endif
#endif





























>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
..
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
   PTRFASTCALL - Like PTRCALL, but for low number of arguments.

   inline      - Used for selected internal functions for which inlining
                 may improve performance on some platforms.

   Note: Use of these macros is based on judgement, not hard rules,
         and therefore subject to change.
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)
/* We'll use this version by default only where we know it helps.

   regparm() generates warnings on Solaris boxes.   See SF bug #692878.

................................................................................
#ifdef __cplusplus
#define inline inline
#else
#ifndef inline
#define inline
#endif
#endif

#ifndef UNUSED_P
# ifdef __GNUC__
#  define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))
# else
#  define UNUSED_P(p) UNUSED_ ## p
# endif
#endif


#ifdef __cplusplus
extern "C" {
#endif


void
_INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** fromLimRef);


#ifdef __cplusplus
}
#endif

Changes to expat/latin1tab.h.









1
2





















3
4
5
6
7
8
9








/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
   See the file COPYING 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,
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

/* 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,

Added expat/loadlibrary.c.































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 2016 - 2017, Steve Holme, <steve_holme@hotmail.com>.
 * Copyright (C) 2017, Expat development team
 *
 * All rights reserved.
 * Licensed under the MIT license:
 *
 * Permission to  use, copy,  modify, and distribute  this software  for any
 * purpose with  or without fee is  hereby granted, provided that  the above
 * copyright notice and this permission notice appear in all copies.
 *
 * 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 OF
 * THIRD PARTY RIGHTS. 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.
 *
 * Except as contained in this notice,  the name of a copyright holder shall
 * not be used in advertising or otherwise to promote the sale, use or other
 * dealings  in this  Software without  prior written  authorization of  the
 * copyright holder.
 *
 ***************************************************************************/

#if defined(_WIN32)

#include <windows.h>
#include <tchar.h>


HMODULE _Expat_LoadLibrary(LPCTSTR filename);


#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH)
#define LOAD_WITH_ALTERED_SEARCH_PATH  0x00000008
#endif

#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
#define LOAD_LIBRARY_SEARCH_SYSTEM32   0x00000800
#endif

/* We use our own typedef here since some headers might lack these */
typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD);

/* See function definitions in winbase.h */
#ifdef UNICODE
#  ifdef _WIN32_WCE
#    define LOADLIBARYEX  L"LoadLibraryExW"
#  else
#    define LOADLIBARYEX  "LoadLibraryExW"
#  endif
#else
#  define LOADLIBARYEX    "LoadLibraryExA"
#endif


/*
 * _Expat_LoadLibrary()
 *
 * This is used to dynamically load DLLs using the most secure method available
 * for the version of Windows that we are running on.
 *
 * Parameters:
 *
 * filename  [in] - The filename or full path of the DLL to load. If only the
 *                  filename is passed then the DLL will be loaded from the
 *                  Windows system directory.
 *
 * Returns the handle of the module on success; otherwise NULL.
 */
HMODULE _Expat_LoadLibrary(LPCTSTR filename)
{
  HMODULE hModule = NULL;
  LOADLIBRARYEX_FN pLoadLibraryEx = NULL;

  /* Get a handle to kernel32 so we can access it's functions at runtime */
  HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32"));
  if(!hKernel32)
    return NULL;  /* LCOV_EXCL_LINE */

  /* Attempt to find LoadLibraryEx() which is only available on Windows 2000
     and above */
  pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX);

  /* Detect if there's already a path in the filename and load the library if
     there is. Note: Both back slashes and forward slashes have been supported
     since the earlier days of DOS at an API level although they are not
     supported by command prompt */
  if(_tcspbrk(filename, TEXT("\\/"))) {
    /** !checksrc! disable BANNEDFUNC 1 **/
    hModule = pLoadLibraryEx ?
      pLoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
      LoadLibrary(filename);
  }
  /* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only
     supported on Windows Vista, Windows Server 2008, Windows 7 and Windows
     Server 2008 R2 with this patch or natively on Windows 8 and above */
  else if(pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) {
    /* Load the DLL from the Windows system directory */
    hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
  }
  else {
    /* Attempt to get the Windows system path */
    UINT systemdirlen = GetSystemDirectory(NULL, 0);
    if(systemdirlen) {
      /* Allocate space for the full DLL path (Room for the null terminator
         is included in systemdirlen) */
      size_t filenamelen = _tcslen(filename);
      TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen));
      if(path && GetSystemDirectory(path, systemdirlen)) {
        /* Calculate the full DLL path */
        _tcscpy(path + _tcslen(path), TEXT("\\"));
        _tcscpy(path + _tcslen(path), filename);

        /* Load the DLL from the Windows system directory */
        /** !checksrc! disable BANNEDFUNC 1 **/
        hModule = pLoadLibraryEx ?
          pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) :
          LoadLibrary(path);

      }
      free(path);
    }
  }

  return hModule;
}

#else /* defined(_WIN32) */

/* ISO C requires a translation unit to contain at least one declaration
   [-Wempty-translation-unit] */
typedef int _TRANSLATION_UNIT_LOAD_LIBRARY_C_NOT_EMTPY;

#endif /* defined(_WIN32) */

Changes to expat/nametab.h.

































1
2
3
4
5
6
7
































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,
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

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,

Added expat/siphash.h.













































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
/* ==========================================================================
 * siphash.h - SipHash-2-4 in a single header file
 * --------------------------------------------------------------------------
 * Derived by William Ahern from the reference implementation[1] published[2]
 * by Jean-Philippe Aumasson and Daniel J. Berstein.
 * Minimal changes by Sebastian Pipping and Victor Stinner on top, see below.
 * Licensed under the CC0 Public Domain Dedication license.
 *
 * 1. https://www.131002.net/siphash/siphash24.c
 * 2. https://www.131002.net/siphash/
 * --------------------------------------------------------------------------
 * HISTORY:
 *
 * 2017-07-25  (Vadim Zeitlin)
 *   - Fix use of SIPHASH_MAIN macro
 *
 * 2017-07-05  (Sebastian Pipping)
 *   - Use _SIP_ULL macro to not require a C++11 compiler if compiled as C++
 *   - Add const qualifiers at two places
 *   - Ensure <=80 characters line length (assuming tab width 4)
 *
 * 2017-06-23  (Victor Stinner)
 *   - Address Win64 compile warnings
 *
 * 2017-06-18  (Sebastian Pipping)
 *   - Clarify license note in the header
 *   - Address C89 issues:
 *     - Stop using inline keyword (and let compiler decide)
 *     - Replace _Bool by int
 *     - Turn macro siphash24 into a function
 *     - Address invalid conversion (void pointer) by explicit cast
 *   - Address lack of stdint.h for Visual Studio 2003 to 2008
 *   - Always expose sip24_valid (for self-tests)
 *
 * 2012-11-04 - Born.  (William Ahern)
 * --------------------------------------------------------------------------
 * USAGE:
 *
 * SipHash-2-4 takes as input two 64-bit words as the key, some number of
 * message bytes, and outputs a 64-bit word as the message digest. This
 * implementation employs two data structures: a struct sipkey for
 * representing the key, and a struct siphash for representing the hash
 * state.
 *
 * For converting a 16-byte unsigned char array to a key, use either the
 * macro sip_keyof or the routine sip_tokey. The former instantiates a
 * compound literal key, while the latter requires a key object as a
 * parameter.
 *
 * 	unsigned char secret[16];
 * 	arc4random_buf(secret, sizeof secret);
 * 	struct sipkey *key = sip_keyof(secret);
 *
 * For hashing a message, use either the convenience macro siphash24 or the
 * routines sip24_init, sip24_update, and sip24_final.
 *
 * 	struct siphash state;
 * 	void *msg;
 * 	size_t len;
 * 	uint64_t hash;
 *
 * 	sip24_init(&state, key);
 * 	sip24_update(&state, msg, len);
 * 	hash = sip24_final(&state);
 *
 * or
 *
 * 	hash = siphash24(msg, len, key);
 *
 * To convert the 64-bit hash value to a canonical 8-byte little-endian
 * binary representation, use either the macro sip_binof or the routine
 * sip_tobin. The former instantiates and returns a compound literal array,
 * while the latter requires an array object as a parameter.
 * --------------------------------------------------------------------------
 * NOTES:
 *
 * o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers
 *   lacking compound literal support. Instead, you must use the lower-level
 *   interfaces which take as parameters the temporary state objects.
 *
 * o Uppercase macros may evaluate parameters more than once. Lowercase
 *   macros should not exhibit any such side effects.
 * ==========================================================================
 */
#ifndef SIPHASH_H
#define SIPHASH_H

#include <stddef.h> /* size_t */

#if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1600)
  /* For vs2003/7.1 up to vs2008/9.0; _MSC_VER 1600 is vs2010/10.0 */
  typedef unsigned __int8   uint8_t;
  typedef unsigned __int32 uint32_t;
  typedef unsigned __int64 uint64_t;
#else
 #include <stdint.h> /* uint64_t uint32_t uint8_t */
#endif


/*
 * Workaround to not require a C++11 compiler for using ULL suffix
 * if this code is included and compiled as C++; related GCC warning is:
 * warning: use of C++11 long long integer constant [-Wlong-long]
 */
#define _SIP_ULL(high, low)  (((uint64_t)high << 32) | low)


#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ( (x) >> (64 - (b))))

#define SIP_U32TO8_LE(p, v) \
	(p)[0] = (uint8_t)((v) >>  0); (p)[1] = (uint8_t)((v) >>  8); \
	(p)[2] = (uint8_t)((v) >> 16); (p)[3] = (uint8_t)((v) >> 24);

#define SIP_U64TO8_LE(p, v) \
	SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >>  0)); \
	SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));

#define SIP_U8TO64_LE(p) \
	(((uint64_t)((p)[0]) <<  0) | \
	 ((uint64_t)((p)[1]) <<  8) | \
	 ((uint64_t)((p)[2]) << 16) | \
	 ((uint64_t)((p)[3]) << 24) | \
	 ((uint64_t)((p)[4]) << 32) | \
	 ((uint64_t)((p)[5]) << 40) | \
	 ((uint64_t)((p)[6]) << 48) | \
	 ((uint64_t)((p)[7]) << 56))


#define SIPHASH_INITIALIZER { 0, 0, 0, 0, { 0 }, 0, 0 }

struct siphash {
	uint64_t v0, v1, v2, v3;

	unsigned char buf[8], *p;
	uint64_t c;
}; /* struct siphash */


#define SIP_KEYLEN 16

struct sipkey {
	uint64_t k[2];
}; /* struct sipkey */

#define sip_keyof(k) sip_tokey(&(struct sipkey){ { 0 } }, (k))

static struct sipkey *sip_tokey(struct sipkey *key, const void *src) {
	key->k[0] = SIP_U8TO64_LE((const unsigned char *)src);
	key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8);
	return key;
} /* sip_tokey() */


#define sip_binof(v) sip_tobin((unsigned char[8]){ 0 }, (v))

static void *sip_tobin(void *dst, uint64_t u64) {
	SIP_U64TO8_LE((unsigned char *)dst, u64);
	return dst;
} /* sip_tobin() */


static void sip_round(struct siphash *H, const int rounds) {
	int i;

	for (i = 0; i < rounds; i++) {
		H->v0 += H->v1;
		H->v1 = SIP_ROTL(H->v1, 13);
		H->v1 ^= H->v0;
		H->v0 = SIP_ROTL(H->v0, 32);

		H->v2 += H->v3;
		H->v3 = SIP_ROTL(H->v3, 16);
		H->v3 ^= H->v2;

		H->v0 += H->v3;
		H->v3 = SIP_ROTL(H->v3, 21);
		H->v3 ^= H->v0;

		H->v2 += H->v1;
		H->v1 = SIP_ROTL(H->v1, 17);
		H->v1 ^= H->v2;
		H->v2 = SIP_ROTL(H->v2, 32);
	}
} /* sip_round() */


static struct siphash *sip24_init(struct siphash *H,
		const struct sipkey *key) {
	H->v0 = _SIP_ULL(0x736f6d65U, 0x70736575U) ^ key->k[0];
	H->v1 = _SIP_ULL(0x646f7261U, 0x6e646f6dU) ^ key->k[1];
	H->v2 = _SIP_ULL(0x6c796765U, 0x6e657261U) ^ key->k[0];
	H->v3 = _SIP_ULL(0x74656462U, 0x79746573U) ^ key->k[1];

	H->p = H->buf;
	H->c = 0;

	return H;
} /* sip24_init() */


#define sip_endof(a) (&(a)[sizeof (a) / sizeof *(a)])

static struct siphash *sip24_update(struct siphash *H, const void *src,
		size_t len) {
	const unsigned char *p = (const unsigned char *)src, *pe = p + len;
	uint64_t m;

	do {
		while (p < pe && H->p < sip_endof(H->buf))
			*H->p++ = *p++;

		if (H->p < sip_endof(H->buf))
			break;

		m = SIP_U8TO64_LE(H->buf);
		H->v3 ^= m;
		sip_round(H, 2);
		H->v0 ^= m;

		H->p = H->buf;
		H->c += 8;
	} while (p < pe);

	return H;
} /* sip24_update() */


static uint64_t sip24_final(struct siphash *H) {
	const char left = (char)(H->p - H->buf);
	uint64_t b = (H->c + left) << 56;

	switch (left) {
	case 7: b |= (uint64_t)H->buf[6] << 48;
	case 6: b |= (uint64_t)H->buf[5] << 40;
	case 5: b |= (uint64_t)H->buf[4] << 32;
	case 4: b |= (uint64_t)H->buf[3] << 24;
	case 3: b |= (uint64_t)H->buf[2] << 16;
	case 2: b |= (uint64_t)H->buf[1] << 8;
	case 1: b |= (uint64_t)H->buf[0] << 0;
	case 0: break;
	}

	H->v3 ^= b;
	sip_round(H, 2);
	H->v0 ^= b;
	H->v2 ^= 0xff;
	sip_round(H, 4);

	return H->v0 ^ H->v1 ^ H->v2  ^ H->v3;
} /* sip24_final() */


static uint64_t siphash24(const void *src, size_t len,
		const struct sipkey *key) {
	struct siphash state = SIPHASH_INITIALIZER;
	return sip24_final(sip24_update(sip24_init(&state, key), src, len));
} /* siphash24() */


/*
 * SipHash-2-4 output with
 * k = 00 01 02 ...
 * and
 * in = (empty string)
 * in = 00 (1 byte)
 * in = 00 01 (2 bytes)
 * in = 00 01 02 (3 bytes)
 * ...
 * in = 00 01 02 ... 3e (63 bytes)
 */
static int sip24_valid(void) {
	static const unsigned char vectors[64][8] = {
		{ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
		{ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
		{ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
		{ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
		{ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
		{ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
		{ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
		{ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
		{ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
		{ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
		{ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
		{ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
		{ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
		{ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
		{ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
		{ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
		{ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
		{ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
		{ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
		{ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
		{ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
		{ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
		{ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
		{ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
		{ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
		{ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
		{ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
		{ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
		{ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
		{ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
		{ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
		{ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
		{ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
		{ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
		{ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
		{ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
		{ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
		{ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
		{ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
		{ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
		{ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
		{ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
		{ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
		{ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
		{ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
		{ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
		{ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
		{ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
		{ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
		{ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
		{ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
		{ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
		{ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
		{ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
		{ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
		{ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
		{ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
		{ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
		{ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
		{ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
		{ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
		{ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
		{ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
		{ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
	};
	unsigned char in[64];
	struct sipkey k;
	size_t i;

	sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011"
			"\012\013\014\015\016\017");

	for (i = 0; i < sizeof in; ++i) {
		in[i] = (unsigned char)i;

		if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i]))
			return 0;
	}

	return 1;
} /* sip24_valid() */


#ifdef SIPHASH_MAIN

#include <stdio.h>

int main(void) {
	const int ok = sip24_valid();

	if (ok)
		puts("OK");
	else
		puts("FAIL");

	return !ok;
} /* main() */

#endif /* SIPHASH_MAIN */


#endif /* SIPHASH_H */

Changes to expat/utf8tab.h.









1
2
3


4



















5
6
7
8
9
10
11








/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
   See the file COPYING 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,
>
>
>
>
>
>
>
>
|
<
<
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd


   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

/* 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,

Changes to expat/winconfig.h.

1
2
3
4

5
6
7























8
9
10
11
12
13
14
15
16
17
18






19
20
21
22
23
24
25
26
27
28
29




30
/*================================================================
** Copyright 2000, Clark Cooper
** All rights reserved.
**

** This is free software. You are permitted to copy, distribute, or modify
** it under the terms of the MIT/X license (contained in the COPYING file
** with this distribution.)























*/

#ifndef WINCONFIG_H
#define WINCONFIG_H

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN

#include <memory.h>
#include <string.h>







#define XML_NS 1
#define XML_DTD 1
#define XML_CONTEXT_BYTES 1024

/* we will assume all Windows platforms are little endian */
#define BYTEORDER 1234

/* Windows has memmove() available. */
#define HAVE_MEMMOVE





#endif /* ndef WINCONFIG_H */
|
|
|
<
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











>
>
>
>
>
>











>
>
>
>

1
2
3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_

                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

#ifndef WINCONFIG_H
#define WINCONFIG_H

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN

#include <memory.h>
#include <string.h>


#if defined(HAVE_EXPAT_CONFIG_H)  /* e.g. MinGW */
# include <expat_config.h>
#else  /* !defined(HAVE_EXPAT_CONFIG_H) */


#define XML_NS 1
#define XML_DTD 1
#define XML_CONTEXT_BYTES 1024

/* we will assume all Windows platforms are little endian */
#define BYTEORDER 1234

/* Windows has memmove() available. */
#define HAVE_MEMMOVE


#endif /* !defined(HAVE_EXPAT_CONFIG_H) */


#endif /* ndef WINCONFIG_H */

Changes to expat/xmlparse.c.









1
2





















3




4
5
6
7













8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

















































25
26
27
28
29
30
31
..
96
97
98
99
100
101
102
103
104
105
106

107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348


349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
...
382
383
384
385
386
387
388
389
390
391
392
393

394
395

396
397
398
399
400
401
402
403
404
405
406
...
425
426
427
428
429
430
431






432
433
434
435
436

437
438
439
440
441
442
443
...
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
...
529
530
531
532
533
534
535



536
537
538
539
540
541
542
543
544
545
546
547
548

549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
...
666
667
668
669
670
671
672
673
674
675
676
677
678
679



























































































































































































































680
681
682
683
684
685



686
687
688
689
690
691

692
693
694





695
696
697
698
699
700
701
702
...
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739








740
741
742




743
744
745
746
747
748
749
750
751
752
753
754




755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777


778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806

807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868

869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887




888
889
890
891

892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913


914
915
916

917
918
919
920
921


922
923
924
925
926
927




928

929
930
931


932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984






985
































986












987
988
989
990
991
992
993
994
995
996

997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037

1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122

1123
1124
1125
1126
1127
1128
1129
1130
1131
1132



1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145

1146
1147
1148
1149
1150
1151


1152
1153
1154

1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165


1166
1167

1168
1169
1170
1171
1172
1173
1174


1175
1176
1177
1178
1179
1180
1181
1182
1183


1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197

1198

1199
1200
1201
1202
1203


1204
1205
1206
1207
1208
1209

1210

1211










1212
1213
1214
1215
1216
1217


1218
1219
1220
1221
1222
1223
1224

1225
1226
1227
1228
1229
1230

1231
1232
1233
1234
1235
1236
1237

1238
1239
1240
1241
1242
1243
1244

1245
1246
1247
1248
1249
1250
1251

1252
1253
1254
1255
1256
1257
1258
1259


1260
1261
1262
1263
1264
1265
1266

1267
1268
1269
1270
1271
1272

1273
1274
1275
1276
1277
1278
1279


1280
1281
1282
1283
1284
1285
1286
1287


1288
1289
1290
1291
1292
1293
1294
1295
1296


1297
1298
1299
1300
1301
1302
1303

1304
1305
1306
1307
1308
1309

1310
1311
1312
1313
1314
1315
1316

1317
1318
1319
1320
1321
1322
1323

1324
1325
1326
1327
1328
1329
1330
1331


1332
1333
1334
1335
1336
1337
1338

1339
1340
1341
1342
1343
1344

1345
1346
1347
1348
1349
1350
1351

1352
1353
1354
1355
1356
1357
1358

1359
1360
1361
1362
1363
1364


1365
1366
1367
1368
1369
1370
1371
1372
1373
1374

1375
1376
1377
1378
1379
1380
1381
1382


1383
1384
1385
1386
1387
1388
1389
1390

1391
1392
1393
1394
1395
1396
1397

1398
1399
1400
1401
1402
1403
1404

1405
1406
1407
1408
1409
1410

1411
1412
1413
1414
1415
1416
1417


1418
1419

1420
1421
1422
1423
1424
1425
1426
1427















1428
1429
1430
1431
1432





1433
1434
1435
1436
1437
1438





1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459












1460
1461

1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478







1479
1480
1481
1482
1483

1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501



1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513

1514
1515
1516
1517
1518
1519
1520
1521

1522
1523
1524
1525


1526
1527
1528
1529
1530

1531
1532
1533

1534
1535
1536
1537
1538
1539
1540
1541
....
1548
1549
1550
1551
1552
1553
1554
1555


1556
1557
1558
1559
1560
1561





1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573

1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603






1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616


1617




1618


1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643

1644




1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656

1657
1658
1659
1660


1661
1662
1663
1664

1665
1666
1667
1668

1669
1670
1671
1672

1673
1674


1675
1676
1677
1678
1679
1680
1681
1682


1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713


1714
1715
1716
1717
1718
1719
1720

1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749


1750
1751
1752
1753
1754
1755
1756
1757


1758
1759
1760
1761
1762
1763
1764


1765
1766
1767
1768
1769
1770
1771
1772


1773
1774
1775
1776
1777
1778
1779
1780
1781
1782




1783
1784




1785
1786
1787
1788
1789
1790
1791
1792
1793


1794
1795
1796
1797
1798
1799
1800
1801
1802
1803


1804
1805
1806
1807
1808
1809
1810
1811

1812
1813
1814
1815
1816
1817


1818
1819
1820
1821
1822
1823


1824
1825
1826
1827
1828
1829

1830
1831
1832
1833
1834
1835


1836
1837
1838
1839
1840
1841
1842
1843

1844
1845
1846
1847
1848
1849
1850
1851




1852

1853

1854

1855

1856

1857

1858

1859

1860

1861

1862

1863

1864

1865

1866

1867

1868

1869

1870

1871

1872

1873

1874

1875

1876

1877


1878


1879

1880

1881

1882

1883

1884

1885

1886

1887

1888


1889

1890

1891
1892
1893
1894




1895
1896
1897
1898
1899
1900
1901
....
1952
1953
1954
1955
1956
1957
1958
1959



1960
1961
1962
1963
1964
1965
1966
....
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
....
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
....
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
....
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
....
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
....
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382

2383

2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408

2409

2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586







2587
2588
2589

2590
2591
2592

2593
2594
2595
2596
2597
2598
2599
2600
2601
2602























2603
2604
2605
2606
2607
2608
2609
....
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651



2652
2653

2654

2655

2656








2657
2658
2659
2660
2661
2662




2663
2664
2665

2666
2667
2668








2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
....
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
....
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
....
2770
2771
2772
2773
2774
2775
2776
2777
2778

2779
2780

2781
2782
2783
2784
2785
2786
2787
2788


2789

2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807






2808
2809

















2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820



2821
2822



2823
2824
2825
2826
2827
2828
2829


2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
....
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
....
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
....
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
....
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
....
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
....
3175
3176
3177
3178
3179
3180
3181







3182
3183

3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
....
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
....
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242











3243
3244

3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
....
3270
3271
3272
3273
3274
3275
3276







3277
3278

3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290

3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373






3374

3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
....
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
....
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
....
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523


3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542








3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
....
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
....
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
....
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
....
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
....
3699
3700
3701
3702
3703
3704
3705



3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777

3778
3779
3780
3781
3782
3783
3784

3785
3786
3787
3788
3789
3790

3791
3792
3793

3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812



3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832

3833
3834
3835





3836

3837
3838
3839
3840

3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090

4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108



4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314

4315

4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327

4328
4329
4330

4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391




















4392

4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
....
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
....
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
....
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
....
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
....
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
....
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710


4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
....
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755


4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
....
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864





4865
4866
4867
4868
4869
4870
4871
....
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938

















4939

4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965











4966
4967
4968

4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
....
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
....
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
....
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106




5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126







5127
5128
5129
5130

5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
....
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219

5220
5221
5222
5223
5224
5225
5226
















5227
5228

5229
5230
5231
5232
5233
5234

5235
5236

5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
....
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263

5264

5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
....
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
....
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
....
5357
5358
5359
5360
5361
5362
5363
5364
5365


5366
5367
5368
5369
5370
5371
5372
....
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396



















5397


5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409






5410

5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
....
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
....
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
....
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
....
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739

5740
5741
5742
5743
5744
5745

5746
5747
5748
5749
5750
5751
5752
5753
....
5762
5763
5764
5765
5766
5767
5768

5769
5770
5771
5772
5773
5774
5775
5776
....
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
....
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851




















5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
....
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
....
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
....
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
....
6053
6054
6055
6056
6057
6058
6059
6060











6061

6062
6063
6064
6065
6066
6067
6068
....
6086
6087
6088
6089
6090
6091
6092





























6093
6094
6095
6096
6097
6098
6099
....
6114
6115
6116
6117
6118
6119
6120

6121




















6122
6123
6124
6125
6126
6127

6128
6129
6130
6131
6132
6133
6134
6135















6136
6137
6138




6139






6140
6141
6142
6143
6144
6145
6146
6147
6148
....
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
....
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
....
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
....
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287































/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
   See the file COPYING for copying permission.





















*/





#include <stddef.h>
#include <string.h>                     /* memset(), memcpy() */
#include <assert.h>














#define XML_BUILDING_EXPAT 1

#ifdef COMPILED_FROM_DSP
#include "winconfig.h"
#elif defined(MACOS_CLASSIC)
#include "macconfig.h"
#elif defined(__amigaos4__)
#include "amigaconfig.h"
#elif defined(__WATCOMC__)
#include "watcomconfig.h"
#elif defined(HAVE_EXPAT_CONFIG_H)
#include <expat_config.h>
#endif /* ndef COMPILED_FROM_DSP */

#include "ascii.h"
#include "expat.h"


















































#ifdef XML_UNICODE
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
#define XmlConvert XmlUtf16Convert
#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
#define XmlEncode XmlUtf16Encode
................................................................................
  NAMED **v;
  unsigned char power;
  size_t size;
  size_t used;
  const XML_Memory_Handling_Suite *mem;
} HASH_TABLE;

/* Basic character hash algorithm, taken from Python's string hash:
   h = h * 1000003 ^ character, the constant being a prime number.

*/

#ifdef XML_UNICODE
#define CHAR_HASH(h, c) \
  (((h) * 0xF4243) ^ (unsigned short)(c))
#else
#define CHAR_HASH(h, c) \
  (((h) * 0xF4243) ^ (unsigned char)(c))
#endif

/* For probing (after a collision) we need a step size relative prime
   to the hash table size, which is a power of 2. We use double-hashing,
   since we can calculate a second hash value cheaply by taking those bits
   of the first hash value that were discarded (masked out) when the table
   index was calculated: index = hash & mask, where mask = table->size - 1.
   We limit the maximum step size to table->size / 4 (mask >> 2) and make
................................................................................
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
static enum XML_Error
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
               const char *s, const char *next);
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, 
         XML_Bool haveMore);
static enum XML_Error
processInternalEntity(XML_Parser parser, ENTITY *entity, 
                      XML_Bool betweenDecl);
static enum XML_Error
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
          const char *start, const char *end, const char **endPtr, 
          XML_Bool haveMore);
static enum XML_Error
doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
               const char *end, const char **nextPtr, XML_Bool haveMore);
#ifdef XML_DTD
static enum XML_Error
doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
                const char *end, const char **nextPtr, XML_Bool haveMore);
#endif /* XML_DTD */



static enum XML_Error
storeAtts(XML_Parser parser, const ENCODING *, const char *s,
          TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
static enum XML_Error
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
           const XML_Char *uri, BINDING **bindingsPtr);
static int
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata, 
                XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
static enum XML_Error
storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
                    const char *, const char *, STRING_POOL *);
static enum XML_Error
appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
                     const char *, const char *, STRING_POOL *);
................................................................................
static const XML_Char * getContext(XML_Parser parser);
static XML_Bool
setContext(XML_Parser parser, const XML_Char *context);

static void FASTCALL normalizePublicId(XML_Char *s);

static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
/* do not call if parentParser != NULL */
static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
static void
dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
static int

dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
static int

copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);

static NAMED *
lookup(HASH_TABLE *table, KEY name, size_t createSize);
static void FASTCALL
hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
static void FASTCALL hashTableClear(HASH_TABLE *);
static void FASTCALL hashTableDestroy(HASH_TABLE *);
static void FASTCALL
hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
................................................................................

static int FASTCALL nextScaffoldPart(XML_Parser parser);
static XML_Content * build_model(XML_Parser parser);
static ELEMENT_TYPE *
getElementType(XML_Parser parser, const ENCODING *enc,
               const char *ptr, const char *end);







static XML_Parser
parserCreate(const XML_Char *encodingName,
             const XML_Memory_Handling_Suite *memsuite,
             const XML_Char *nameSep,
             DTD *dtd);

static void
parserInit(XML_Parser parser, const XML_Char *encodingName);

#define poolStart(pool) ((pool)->start)
#define poolEnd(pool) ((pool)->ptr)
#define poolLength(pool) ((pool)->ptr - (pool)->start)
#define poolChop(pool) ((void)--(pool->ptr))
................................................................................
#define poolFinish(pool) ((pool)->start = (pool)->ptr)
#define poolAppendChar(pool, c) \
  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
   ? 0 \
   : ((*((pool)->ptr)++ = c), 1))

struct XML_ParserStruct {
  /* The first member must be userData so that the XML_GetUserData
     macro works. */
  void *m_userData;
  void *m_handlerArg;
  char *m_buffer;
  const XML_Memory_Handling_Suite m_mem;
  /* 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;
  XML_Index m_parseEndByteIndex;
  const char *m_parseEndPtr;
  XML_Char *m_dataBuf;
  XML_Char *m_dataBufEnd;
  XML_StartElementHandler m_startElementHandler;
  XML_EndElementHandler m_endElementHandler;
................................................................................
  int m_attsSize;
  int m_nSpecifiedAtts;
  int m_idAttIndex;
  ATTRIBUTE *m_atts;
  NS_ATT *m_nsAtts;
  unsigned long m_nsAttsVersion;
  unsigned char m_nsAttsPower;



  POSITION m_position;
  STRING_POOL m_tempPool;
  STRING_POOL m_temp2Pool;
  char *m_groupConnector;
  unsigned int m_groupSize;
  XML_Char m_namespaceSeparator;
  XML_Parser m_parentParser;
  XML_ParsingStatus m_parsingStatus;
#ifdef XML_DTD
  XML_Bool m_isParamEntity;
  XML_Bool m_useForeignDTD;
  enum XML_ParamEntityParsing m_paramEntityParsing;
#endif

};

#define MALLOC(s) (parser->m_mem.malloc_fcn((s)))
#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s)))
#define FREE(p) (parser->m_mem.free_fcn((p)))

#define userData (parser->m_userData)
#define handlerArg (parser->m_handlerArg)
#define startElementHandler (parser->m_startElementHandler)
#define endElementHandler (parser->m_endElementHandler)
#define characterDataHandler (parser->m_characterDataHandler)
#define processingInstructionHandler \
        (parser->m_processingInstructionHandler)
#define commentHandler (parser->m_commentHandler)
#define startCdataSectionHandler \
        (parser->m_startCdataSectionHandler)
#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
#define defaultHandler (parser->m_defaultHandler)
#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
#define unparsedEntityDeclHandler \
        (parser->m_unparsedEntityDeclHandler)
#define notationDeclHandler (parser->m_notationDeclHandler)
#define startNamespaceDeclHandler \
        (parser->m_startNamespaceDeclHandler)
#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
#define notStandaloneHandler (parser->m_notStandaloneHandler)
#define externalEntityRefHandler \
        (parser->m_externalEntityRefHandler)
#define externalEntityRefHandlerArg \
        (parser->m_externalEntityRefHandlerArg)
#define internalEntityRefHandler \
        (parser->m_internalEntityRefHandler)
#define skippedEntityHandler (parser->m_skippedEntityHandler)
#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
#define elementDeclHandler (parser->m_elementDeclHandler)
#define attlistDeclHandler (parser->m_attlistDeclHandler)
#define entityDeclHandler (parser->m_entityDeclHandler)
#define xmlDeclHandler (parser->m_xmlDeclHandler)
#define encoding (parser->m_encoding)
#define initEncoding (parser->m_initEncoding)
#define internalEncoding (parser->m_internalEncoding)
#define unknownEncodingMem (parser->m_unknownEncodingMem)
#define unknownEncodingData (parser->m_unknownEncodingData)
#define unknownEncodingHandlerData \
  (parser->m_unknownEncodingHandlerData)
#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
#define protocolEncodingName (parser->m_protocolEncodingName)
#define ns (parser->m_ns)
#define ns_triplets (parser->m_ns_triplets)
#define prologState (parser->m_prologState)
#define processor (parser->m_processor)
#define errorCode (parser->m_errorCode)
#define eventPtr (parser->m_eventPtr)
#define eventEndPtr (parser->m_eventEndPtr)
#define positionPtr (parser->m_positionPtr)
#define position (parser->m_position)
#define openInternalEntities (parser->m_openInternalEntities)
#define freeInternalEntities (parser->m_freeInternalEntities)
#define defaultExpandInternalEntities \
        (parser->m_defaultExpandInternalEntities)
#define tagLevel (parser->m_tagLevel)
#define buffer (parser->m_buffer)
#define bufferPtr (parser->m_bufferPtr)
#define bufferEnd (parser->m_bufferEnd)
#define parseEndByteIndex (parser->m_parseEndByteIndex)
#define parseEndPtr (parser->m_parseEndPtr)
#define bufferLim (parser->m_bufferLim)
#define dataBuf (parser->m_dataBuf)
#define dataBufEnd (parser->m_dataBufEnd)
#define _dtd (parser->m_dtd)
#define curBase (parser->m_curBase)
#define declEntity (parser->m_declEntity)
#define doctypeName (parser->m_doctypeName)
#define doctypeSysid (parser->m_doctypeSysid)
#define doctypePubid (parser->m_doctypePubid)
#define declAttributeType (parser->m_declAttributeType)
#define declNotationName (parser->m_declNotationName)
#define declNotationPublicId (parser->m_declNotationPublicId)
#define declElementType (parser->m_declElementType)
#define declAttributeId (parser->m_declAttributeId)
#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
#define declAttributeIsId (parser->m_declAttributeIsId)
#define freeTagList (parser->m_freeTagList)
#define freeBindingList (parser->m_freeBindingList)
#define inheritedBindings (parser->m_inheritedBindings)
#define tagStack (parser->m_tagStack)
#define atts (parser->m_atts)
#define attsSize (parser->m_attsSize)
#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
#define idAttIndex (parser->m_idAttIndex)
#define nsAtts (parser->m_nsAtts)
#define nsAttsVersion (parser->m_nsAttsVersion)
#define nsAttsPower (parser->m_nsAttsPower)
#define tempPool (parser->m_tempPool)
#define temp2Pool (parser->m_temp2Pool)
#define groupConnector (parser->m_groupConnector)
#define groupSize (parser->m_groupSize)
#define namespaceSeparator (parser->m_namespaceSeparator)
#define parentParser (parser->m_parentParser)
#define ps_parsing (parser->m_parsingStatus.parsing)
#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer)
#ifdef XML_DTD
#define isParamEntity (parser->m_isParamEntity)
#define useForeignDTD (parser->m_useForeignDTD)
#define paramEntityParsing (parser->m_paramEntityParsing)
#endif /* XML_DTD */

XML_Parser XMLCALL
XML_ParserCreate(const XML_Char *encodingName)
{
  return XML_ParserCreate_MM(encodingName, NULL, NULL);
}

................................................................................
  XML_Char tmp[2];
  *tmp = nsSep;
  return XML_ParserCreate_MM(encodingName, NULL, tmp);
}

static const XML_Char implicitContext[] = {
  ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
  ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w, 
  ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
  ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
  ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
  ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
};




























































































































































































































XML_Parser XMLCALL
XML_ParserCreate_MM(const XML_Char *encodingName,
                    const XML_Memory_Handling_Suite *memsuite,
                    const XML_Char *nameSep)
{
  XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL);



  if (parser != NULL && ns) {
    /* implicit context only set for root parser, since child
       parsers (i.e. external entity parsers) will inherit it
    */
    if (!setContext(parser, implicitContext)) {
      XML_ParserFree(parser);

      return NULL;
    }
  }





  return parser;
}

static XML_Parser
parserCreate(const XML_Char *encodingName,
             const XML_Memory_Handling_Suite *memsuite,
             const XML_Char *nameSep,
             DTD *dtd)
................................................................................
      mtemp->free_fcn = free;
    }
  }

  if (!parser)
    return parser;

  buffer = NULL;
  bufferLim = NULL;

  attsSize = INIT_ATTS_SIZE;
  atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE));
  if (atts == NULL) {
    FREE(parser);
    return NULL;
  }








  dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
  if (dataBuf == NULL) {
    FREE(atts);




    FREE(parser);
    return NULL;
  }
  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;

  if (dtd)
    _dtd = dtd;
  else {
    _dtd = dtdCreate(&parser->m_mem);
    if (_dtd == NULL) {
      FREE(dataBuf);
      FREE(atts);




      FREE(parser);
      return NULL;
    }
  }

  freeBindingList = NULL;
  freeTagList = NULL;
  freeInternalEntities = NULL;

  groupSize = 0;
  groupConnector = NULL;

  unknownEncodingHandler = NULL;
  unknownEncodingHandlerData = NULL;

  namespaceSeparator = ASCII_EXCL;
  ns = XML_FALSE;
  ns_triplets = XML_FALSE;

  nsAtts = NULL;
  nsAttsVersion = 0;
  nsAttsPower = 0;



  poolInit(&tempPool, &(parser->m_mem));
  poolInit(&temp2Pool, &(parser->m_mem));
  parserInit(parser, encodingName);

  if (encodingName && !protocolEncodingName) {
    XML_ParserFree(parser);
    return NULL;
  }

  if (nameSep) {
    ns = XML_TRUE;
    internalEncoding = XmlGetInternalEncodingNS();
    namespaceSeparator = *nameSep;
  }
  else {
    internalEncoding = XmlGetInternalEncoding();
  }

  return parser;
}

static void
parserInit(XML_Parser parser, const XML_Char *encodingName)
{
  processor = prologInitProcessor;
  XmlPrologStateInit(&prologState);
  protocolEncodingName = (encodingName != NULL
                          ? poolCopyString(&tempPool, encodingName)
                          : NULL);

  curBase = NULL;
  XmlInitEncoding(&initEncoding, &encoding, 0);
  userData = NULL;
  handlerArg = NULL;
  startElementHandler = NULL;
  endElementHandler = NULL;
  characterDataHandler = NULL;
  processingInstructionHandler = NULL;
  commentHandler = NULL;
  startCdataSectionHandler = NULL;
  endCdataSectionHandler = NULL;
  defaultHandler = NULL;
  startDoctypeDeclHandler = NULL;
  endDoctypeDeclHandler = NULL;
  unparsedEntityDeclHandler = NULL;
  notationDeclHandler = NULL;
  startNamespaceDeclHandler = NULL;
  endNamespaceDeclHandler = NULL;
  notStandaloneHandler = NULL;
  externalEntityRefHandler = NULL;
  externalEntityRefHandlerArg = parser;
  skippedEntityHandler = NULL;
  elementDeclHandler = NULL;
  attlistDeclHandler = NULL;
  entityDeclHandler = NULL;
  xmlDeclHandler = NULL;
  bufferPtr = buffer;
  bufferEnd = buffer;
  parseEndByteIndex = 0;
  parseEndPtr = NULL;
  declElementType = NULL;
  declAttributeId = NULL;
  declEntity = NULL;
  doctypeName = NULL;
  doctypeSysid = NULL;
  doctypePubid = NULL;
  declAttributeType = NULL;
  declNotationName = NULL;
  declNotationPublicId = NULL;
  declAttributeIsCdata = XML_FALSE;
  declAttributeIsId = XML_FALSE;
  memset(&position, 0, sizeof(POSITION));
  errorCode = XML_ERROR_NONE;
  eventPtr = NULL;
  eventEndPtr = NULL;
  positionPtr = NULL;
  openInternalEntities = NULL;
  defaultExpandInternalEntities = XML_TRUE;
  tagLevel = 0;
  tagStack = NULL;
  inheritedBindings = NULL;
  nSpecifiedAtts = 0;
  unknownEncodingMem = NULL;
  unknownEncodingRelease = NULL;
  unknownEncodingData = NULL;
  parentParser = NULL;
  ps_parsing = XML_INITIALIZED;
#ifdef XML_DTD
  isParamEntity = XML_FALSE;
  useForeignDTD = XML_FALSE;
  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
#endif

}

/* moves list of bindings to freeBindingList */
static void FASTCALL
moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
{
  while (bindings) {
    BINDING *b = bindings;
    bindings = bindings->nextTagBinding;
    b->nextTagBinding = freeBindingList;
    freeBindingList = b;
  }
}

XML_Bool XMLCALL
XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
{
  TAG *tStk;
  OPEN_INTERNAL_ENTITY *openEntityList;




  if (parentParser)
    return XML_FALSE;
  /* move tagStack to freeTagList */
  tStk = tagStack;

  while (tStk) {
    TAG *tag = tStk;
    tStk = tStk->parent;
    tag->parent = freeTagList;
    moveToFreeBindingList(parser, tag->bindings);
    tag->bindings = NULL;
    freeTagList = tag;
  }
  /* move openInternalEntities to freeInternalEntities */
  openEntityList = openInternalEntities;
  while (openEntityList) {
    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
    openEntityList = openEntity->next;
    openEntity->next = freeInternalEntities;
    freeInternalEntities = openEntity;
  }
  moveToFreeBindingList(parser, inheritedBindings);
  FREE(unknownEncodingMem);
  if (unknownEncodingRelease)
    unknownEncodingRelease(unknownEncodingData);
  poolClear(&tempPool);
  poolClear(&temp2Pool);


  parserInit(parser, encodingName);
  dtdReset(_dtd, &parser->m_mem);
  return setContext(parser, implicitContext);

}

enum XML_Status XMLCALL
XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
{


  /* Block after XML_Parse()/XML_ParseBuffer() has been called.
     XXX There's no way for the caller to determine which of the
     XXX possible error cases caused the XML_STATUS_ERROR return.
  */
  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
    return XML_STATUS_ERROR;




  if (encodingName == NULL)

    protocolEncodingName = NULL;
  else {
    protocolEncodingName = poolCopyString(&tempPool, encodingName);


    if (!protocolEncodingName)
      return XML_STATUS_ERROR;
  }
  return XML_STATUS_OK;
}

XML_Parser XMLCALL
XML_ExternalEntityParserCreate(XML_Parser oldParser,
                               const XML_Char *context,
                               const XML_Char *encodingName)
{
  XML_Parser parser = oldParser;
  DTD *newDtd = NULL;
  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_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
      = startNamespaceDeclHandler;
  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
      = endNamespaceDeclHandler;
  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
  XML_ExternalEntityRefHandler oldExternalEntityRefHandler
      = externalEntityRefHandler;
  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
  XML_UnknownEncodingHandler oldUnknownEncodingHandler
      = unknownEncodingHandler;
  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
  ELEMENT_TYPE * oldDeclElementType = declElementType;

  void *oldUserData = userData;
  void *oldHandlerArg = handlerArg;
  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
#ifdef XML_DTD
  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
  int oldInEntityValue = prologState.inEntityValue;
#endif
  XML_Bool oldns_triplets = ns_triplets;







































#ifdef XML_DTD












  if (!context)
    newDtd = oldDtd;
#endif /* XML_DTD */

  /* Note that the magical uses of the pre-processor to make field
     access look more like C++ require that `parser' be overwritten
     here.  This makes this function more painful to follow than it
     would be otherwise.
  */
  if (ns) {

    XML_Char tmp[2];
    *tmp = namespaceSeparator;
    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
  }
  else {
    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
  }

  if (!parser)
    return NULL;

  startElementHandler = oldStartElementHandler;
  endElementHandler = oldEndElementHandler;
  characterDataHandler = oldCharacterDataHandler;
  processingInstructionHandler = oldProcessingInstructionHandler;
  commentHandler = oldCommentHandler;
  startCdataSectionHandler = oldStartCdataSectionHandler;
  endCdataSectionHandler = oldEndCdataSectionHandler;
  defaultHandler = oldDefaultHandler;
  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
  notationDeclHandler = oldNotationDeclHandler;
  startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
  endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
  notStandaloneHandler = oldNotStandaloneHandler;
  externalEntityRefHandler = oldExternalEntityRefHandler;
  skippedEntityHandler = oldSkippedEntityHandler;
  unknownEncodingHandler = oldUnknownEncodingHandler;
  elementDeclHandler = oldElementDeclHandler;
  attlistDeclHandler = oldAttlistDeclHandler;
  entityDeclHandler = oldEntityDeclHandler;
  xmlDeclHandler = oldXmlDeclHandler;
  declElementType = oldDeclElementType;
  userData = oldUserData;
  if (oldUserData == oldHandlerArg)
    handlerArg = userData;
  else
    handlerArg = parser;
  if (oldExternalEntityRefHandlerArg != oldParser)
    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
  defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
  ns_triplets = oldns_triplets;

  parentParser = oldParser;
#ifdef XML_DTD
  paramEntityParsing = oldParamEntityParsing;
  prologState.inEntityValue = oldInEntityValue;
  if (context) {
#endif /* XML_DTD */
    if (!dtdCopy(_dtd, oldDtd, &parser->m_mem)
      || !setContext(parser, context)) {
      XML_ParserFree(parser);
      return NULL;
    }
    processor = externalEntityInitProcessor;
#ifdef XML_DTD
  }
  else {
    /* The DTD instance referenced by _dtd is shared between the document's
       root parser and external PE parsers, therefore one does not need to
       call setContext. In addition, one also *must* not call setContext,
       because this would overwrite existing prefix->binding pointers in
       _dtd with ones that get destroyed with the external PE parser.
       This would leave those prefixes with dangling pointers.
    */
    isParamEntity = XML_TRUE;
    XmlPrologStateInitExternalEntity(&prologState);
    processor = externalParEntInitProcessor;
  }
#endif /* XML_DTD */
  return parser;
}

static void FASTCALL
destroyBindings(BINDING *bindings, XML_Parser parser)
{
  for (;;) {
    BINDING *b = bindings;
    if (!b)
      break;
    bindings = b->nextTagBinding;
    FREE(b->uri);
    FREE(b);
  }
}

void XMLCALL
XML_ParserFree(XML_Parser parser)
{
  TAG *tagList;
  OPEN_INTERNAL_ENTITY *entityList;
  if (parser == NULL)
    return;
  /* free tagStack and freeTagList */
  tagList = tagStack;
  for (;;) {
    TAG *p;
    if (tagList == NULL) {
      if (freeTagList == NULL)
        break;
      tagList = freeTagList;
      freeTagList = NULL;
    }
    p = tagList;
    tagList = tagList->parent;
    FREE(p->buf);
    destroyBindings(p->bindings, parser);
    FREE(p);
  }
  /* free openInternalEntities and freeInternalEntities */
  entityList = openInternalEntities;
  for (;;) {
    OPEN_INTERNAL_ENTITY *openEntity;
    if (entityList == NULL) {
      if (freeInternalEntities == NULL)
        break;
      entityList = freeInternalEntities;
      freeInternalEntities = NULL;
    }
    openEntity = entityList;
    entityList = entityList->next;
    FREE(openEntity);
  }

  destroyBindings(freeBindingList, parser);
  destroyBindings(inheritedBindings, parser);
  poolDestroy(&tempPool);
  poolDestroy(&temp2Pool);

#ifdef XML_DTD
  /* external parameter entity parsers share the DTD structure
     parser->m_dtd with the root parser, so we must not destroy it
  */
  if (!isParamEntity && _dtd)
#else
  if (_dtd)
#endif /* XML_DTD */
    dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
  FREE((void *)atts);



  FREE(groupConnector);
  FREE(buffer);
  FREE(dataBuf);
  FREE(nsAtts);
  FREE(unknownEncodingMem);
  if (unknownEncodingRelease)
    unknownEncodingRelease(unknownEncodingData);
  FREE(parser);
}

void XMLCALL
XML_UseParserAsHandlerArg(XML_Parser parser)
{

  handlerArg = parser;
}

enum XML_Error XMLCALL
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
{


#ifdef XML_DTD
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)

    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
  useForeignDTD = useDTD;
  return XML_ERROR_NONE;
#else
  return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
#endif
}

void XMLCALL
XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
{


  /* block after XML_Parse()/XML_ParseBuffer() has been called */
  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)

    return;
  ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
}

void XMLCALL
XML_SetUserData(XML_Parser parser, void *p)
{


  if (handlerArg == userData)
    handlerArg = userData = p;
  else
    userData = p;
}

enum XML_Status XMLCALL
XML_SetBase(XML_Parser parser, const XML_Char *p)
{


  if (p) {
    p = poolCopyString(&_dtd->pool, p);
    if (!p)
      return XML_STATUS_ERROR;
    curBase = p;
  }
  else
    curBase = NULL;
  return XML_STATUS_OK;
}

const XML_Char * XMLCALL
XML_GetBase(XML_Parser parser)
{

  return curBase;

}

int XMLCALL
XML_GetSpecifiedAttributeCount(XML_Parser parser)
{


  return nSpecifiedAtts;
}

int XMLCALL
XML_GetIdAttributeIndex(XML_Parser parser)
{

  return idAttIndex;

}











void XMLCALL
XML_SetElementHandler(XML_Parser parser,
                      XML_StartElementHandler start,
                      XML_EndElementHandler end)
{


  startElementHandler = start;
  endElementHandler = end;
}

void XMLCALL
XML_SetStartElementHandler(XML_Parser parser,
                           XML_StartElementHandler start) {

  startElementHandler = start;
}

void XMLCALL
XML_SetEndElementHandler(XML_Parser parser,
                         XML_EndElementHandler end) {

  endElementHandler = end;
}

void XMLCALL
XML_SetCharacterDataHandler(XML_Parser parser,
                            XML_CharacterDataHandler handler)
{

  characterDataHandler = handler;
}

void XMLCALL
XML_SetProcessingInstructionHandler(XML_Parser parser,
                                    XML_ProcessingInstructionHandler handler)
{

  processingInstructionHandler = handler;
}

void XMLCALL
XML_SetCommentHandler(XML_Parser parser,
                      XML_CommentHandler handler)
{

  commentHandler = handler;
}

void XMLCALL
XML_SetCdataSectionHandler(XML_Parser parser,
                           XML_StartCdataSectionHandler start,
                           XML_EndCdataSectionHandler end)
{


  startCdataSectionHandler = start;
  endCdataSectionHandler = end;
}

void XMLCALL
XML_SetStartCdataSectionHandler(XML_Parser parser,
                                XML_StartCdataSectionHandler start) {

  startCdataSectionHandler = start;
}

void XMLCALL
XML_SetEndCdataSectionHandler(XML_Parser parser,
                              XML_EndCdataSectionHandler end) {

  endCdataSectionHandler = end;
}

void XMLCALL
XML_SetDefaultHandler(XML_Parser parser,
                      XML_DefaultHandler handler)
{


  defaultHandler = handler;
  defaultExpandInternalEntities = XML_FALSE;
}

void XMLCALL
XML_SetDefaultHandlerExpand(XML_Parser parser,
                            XML_DefaultHandler handler)
{


  defaultHandler = handler;
  defaultExpandInternalEntities = XML_TRUE;
}

void XMLCALL
XML_SetDoctypeDeclHandler(XML_Parser parser,
                          XML_StartDoctypeDeclHandler start,
                          XML_EndDoctypeDeclHandler end)
{


  startDoctypeDeclHandler = start;
  endDoctypeDeclHandler = end;
}

void XMLCALL
XML_SetStartDoctypeDeclHandler(XML_Parser parser,
                               XML_StartDoctypeDeclHandler start) {

  startDoctypeDeclHandler = start;
}

void XMLCALL
XML_SetEndDoctypeDeclHandler(XML_Parser parser,
                             XML_EndDoctypeDeclHandler end) {

  endDoctypeDeclHandler = end;
}

void XMLCALL
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
                                 XML_UnparsedEntityDeclHandler handler)
{

  unparsedEntityDeclHandler = handler;
}

void XMLCALL
XML_SetNotationDeclHandler(XML_Parser parser,
                           XML_NotationDeclHandler handler)
{

  notationDeclHandler = handler;
}

void XMLCALL
XML_SetNamespaceDeclHandler(XML_Parser parser,
                            XML_StartNamespaceDeclHandler start,
                            XML_EndNamespaceDeclHandler end)
{


  startNamespaceDeclHandler = start;
  endNamespaceDeclHandler = end;
}

void XMLCALL
XML_SetStartNamespaceDeclHandler(XML_Parser parser,
                                 XML_StartNamespaceDeclHandler start) {

  startNamespaceDeclHandler = start;
}

void XMLCALL
XML_SetEndNamespaceDeclHandler(XML_Parser parser,
                               XML_EndNamespaceDeclHandler end) {

  endNamespaceDeclHandler = end;
}

void XMLCALL
XML_SetNotStandaloneHandler(XML_Parser parser,
                            XML_NotStandaloneHandler handler)
{

  notStandaloneHandler = handler;
}

void XMLCALL
XML_SetExternalEntityRefHandler(XML_Parser parser,
                                XML_ExternalEntityRefHandler handler)
{

  externalEntityRefHandler = handler;
}

void XMLCALL
XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
{


  if (arg)
    externalEntityRefHandlerArg = (XML_Parser)arg;
  else
    externalEntityRefHandlerArg = parser;
}

void XMLCALL
XML_SetSkippedEntityHandler(XML_Parser parser,
                            XML_SkippedEntityHandler handler)
{

  skippedEntityHandler = handler;
}

void XMLCALL
XML_SetUnknownEncodingHandler(XML_Parser parser,
                              XML_UnknownEncodingHandler handler,
                              void *data)
{


  unknownEncodingHandler = handler;
  unknownEncodingHandlerData = data;
}

void XMLCALL
XML_SetElementDeclHandler(XML_Parser parser,
                          XML_ElementDeclHandler eldecl)
{

  elementDeclHandler = eldecl;
}

void XMLCALL
XML_SetAttlistDeclHandler(XML_Parser parser,
                          XML_AttlistDeclHandler attdecl)
{

  attlistDeclHandler = attdecl;
}

void XMLCALL
XML_SetEntityDeclHandler(XML_Parser parser,
                         XML_EntityDeclHandler handler)
{

  entityDeclHandler = handler;
}

void XMLCALL
XML_SetXmlDeclHandler(XML_Parser parser,
                      XML_XmlDeclHandler handler) {

  xmlDeclHandler = handler;
}

int XMLCALL
XML_SetParamEntityParsing(XML_Parser parser,
                          enum XML_ParamEntityParsing peParsing)
{


  /* block after XML_Parse()/XML_ParseBuffer() has been called */
  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)

    return 0;
#ifdef XML_DTD
  paramEntityParsing = peParsing;
  return 1;
#else
  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
#endif
}
















enum XML_Status XMLCALL
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
{
  switch (ps_parsing) {





  case XML_SUSPENDED:
    errorCode = XML_ERROR_SUSPENDED;
    return XML_STATUS_ERROR;
  case XML_FINISHED:
    errorCode = XML_ERROR_FINISHED;
    return XML_STATUS_ERROR;





  default:
    ps_parsing = XML_PARSING;
  }

  if (len == 0) {
    ps_finalBuffer = (XML_Bool)isFinal;
    if (!isFinal)
      return XML_STATUS_OK;
    positionPtr = bufferPtr;
    parseEndPtr = bufferEnd;

    /* If data are left over from last buffer, and we now know that these
       data are the final chunk of input, then we have to check them again
       to detect errors based on that fact.
    */
    errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);

    if (errorCode == XML_ERROR_NONE) {
      switch (ps_parsing) {
      case XML_SUSPENDED:
        XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);












        positionPtr = bufferPtr;
        return XML_STATUS_SUSPENDED;

      case XML_INITIALIZED: 
      case XML_PARSING:
        ps_parsing = XML_FINISHED;
        /* fall through */
      default:
        return XML_STATUS_OK;
      }
    }
    eventEndPtr = eventPtr;
    processor = errorProcessor;
    return XML_STATUS_ERROR;
  }
#ifndef XML_CONTEXT_BYTES
  else if (bufferPtr == bufferEnd) {
    const char *end;
    int nLeftOver;
    enum XML_Error result;







    parseEndByteIndex += len;
    positionPtr = s;
    ps_finalBuffer = (XML_Bool)isFinal;

    errorCode = processor(parser, s, parseEndPtr = s + len, &end);


    if (errorCode != XML_ERROR_NONE) {
      eventEndPtr = eventPtr;
      processor = errorProcessor;
      return XML_STATUS_ERROR;
    }
    else {
      switch (ps_parsing) {
      case XML_SUSPENDED:
        result = XML_STATUS_SUSPENDED;
        break;
      case XML_INITIALIZED:
      case XML_PARSING:
        result = XML_STATUS_OK;
        if (isFinal) {
          ps_parsing = XML_FINISHED;
          return result;
        }



      }
    }

    XmlUpdatePosition(encoding, positionPtr, end, &position);
    nLeftOver = s + len - end;
    if (nLeftOver) {
      if (buffer == NULL || nLeftOver > bufferLim - buffer) {
        /* FIXME avoid integer overflow */
        char *temp;
        temp = (buffer == NULL
                ? (char *)MALLOC(len * 2)
                : (char *)REALLOC(buffer, len * 2));

        if (temp == NULL) {
          errorCode = XML_ERROR_NO_MEMORY;
          return XML_STATUS_ERROR;
        }
        buffer = temp;
        if (!buffer) {
          errorCode = XML_ERROR_NO_MEMORY;
          eventPtr = eventEndPtr = NULL;

          processor = errorProcessor;
          return XML_STATUS_ERROR;
        }
        bufferLim = buffer + len * 2;


      }
      memcpy(buffer, end, nLeftOver);
    }
    bufferPtr = buffer;
    bufferEnd = buffer + nLeftOver;

    positionPtr = bufferPtr;
    parseEndPtr = bufferEnd;
    eventPtr = bufferPtr;

    eventEndPtr = bufferPtr;
    return result;
  }
#endif  /* not defined XML_CONTEXT_BYTES */
  else {
    void *buff = XML_GetBuffer(parser, len);
    if (buff == NULL)
      return XML_STATUS_ERROR;
................................................................................

enum XML_Status XMLCALL
XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
{
  const char *start;
  enum XML_Status result = XML_STATUS_OK;

  switch (ps_parsing) {


  case XML_SUSPENDED:
    errorCode = XML_ERROR_SUSPENDED;
    return XML_STATUS_ERROR;
  case XML_FINISHED:
    errorCode = XML_ERROR_FINISHED;
    return XML_STATUS_ERROR;





  default:
    ps_parsing = XML_PARSING;
  }

  start = bufferPtr;
  positionPtr = start;
  bufferEnd += len;
  parseEndPtr = bufferEnd;
  parseEndByteIndex += len;
  ps_finalBuffer = (XML_Bool)isFinal;

  errorCode = processor(parser, start, parseEndPtr, &bufferPtr);


  if (errorCode != XML_ERROR_NONE) {
    eventEndPtr = eventPtr;
    processor = errorProcessor;
    return XML_STATUS_ERROR;
  }
  else {
    switch (ps_parsing) {
    case XML_SUSPENDED:
      result = XML_STATUS_SUSPENDED;
      break;
    case XML_INITIALIZED: 
    case XML_PARSING:
      if (isFinal) {
        ps_parsing = XML_FINISHED;
        return result;
      }
    default: ;  /* should not happen */
    }
  }

  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
  positionPtr = bufferPtr;
  return result;
}

void * XMLCALL
XML_GetBuffer(XML_Parser parser, int len)
{
  switch (ps_parsing) {






  case XML_SUSPENDED:
    errorCode = XML_ERROR_SUSPENDED;
    return NULL;
  case XML_FINISHED:
    errorCode = XML_ERROR_FINISHED;
    return NULL;
  default: ;
  }

  if (len > bufferLim - bufferEnd) {
    /* FIXME avoid integer overflow */
    int neededSize = len + (int)(bufferEnd - bufferPtr);
#ifdef XML_CONTEXT_BYTES


    int keep = (int)(bufferPtr - buffer);







    if (keep > XML_CONTEXT_BYTES)
      keep = XML_CONTEXT_BYTES;
    neededSize += keep;
#endif  /* defined XML_CONTEXT_BYTES */
    if (neededSize  <= bufferLim - buffer) {
#ifdef XML_CONTEXT_BYTES
      if (keep < bufferPtr - buffer) {
        int offset = (int)(bufferPtr - buffer) - keep;
        memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
        bufferEnd -= offset;
        bufferPtr -= offset;
      }
#else
      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
      bufferEnd = buffer + (bufferEnd - bufferPtr);
      bufferPtr = buffer;
#endif  /* not defined XML_CONTEXT_BYTES */
    }
    else {
      char *newBuf;
      int bufferSize = (int)(bufferLim - bufferPtr);
      if (bufferSize == 0)
        bufferSize = INIT_BUFFER_SIZE;
      do {
        bufferSize *= 2;

      } while (bufferSize < neededSize);




      newBuf = (char *)MALLOC(bufferSize);
      if (newBuf == 0) {
        errorCode = XML_ERROR_NO_MEMORY;
        return NULL;
      }
      bufferLim = newBuf + bufferSize;
#ifdef XML_CONTEXT_BYTES
      if (bufferPtr) {
        int keep = (int)(bufferPtr - buffer);
        if (keep > XML_CONTEXT_BYTES)
          keep = XML_CONTEXT_BYTES;
        memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);

        FREE(buffer);
        buffer = newBuf;
        bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
        bufferPtr = buffer + keep;


      }
      else {
        bufferEnd = newBuf + (bufferEnd - bufferPtr);
        bufferPtr = buffer = newBuf;

      }
#else
      if (bufferPtr) {
        memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);

        FREE(buffer);
      }
      bufferEnd = newBuf + (bufferEnd - bufferPtr);
      bufferPtr = buffer = newBuf;

#endif  /* not defined XML_CONTEXT_BYTES */
    }


  }
  return bufferEnd;
}

enum XML_Status XMLCALL
XML_StopParser(XML_Parser parser, XML_Bool resumable)
{
  switch (ps_parsing) {


  case XML_SUSPENDED:
    if (resumable) {
      errorCode = XML_ERROR_SUSPENDED;
      return XML_STATUS_ERROR;
    }
    ps_parsing = XML_FINISHED;
    break;
  case XML_FINISHED:
    errorCode = XML_ERROR_FINISHED;
    return XML_STATUS_ERROR;
  default:
    if (resumable) {
#ifdef XML_DTD
      if (isParamEntity) {
        errorCode = XML_ERROR_SUSPEND_PE;
        return XML_STATUS_ERROR;
      }
#endif
      ps_parsing = XML_SUSPENDED;
    }
    else
      ps_parsing = XML_FINISHED;
  }
  return XML_STATUS_OK;
}

enum XML_Status XMLCALL
XML_ResumeParser(XML_Parser parser)
{
  enum XML_Status result = XML_STATUS_OK;



  if (ps_parsing != XML_SUSPENDED) {
    errorCode = XML_ERROR_NOT_SUSPENDED;
    return XML_STATUS_ERROR;
  }
  ps_parsing = XML_PARSING;

  errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);


  if (errorCode != XML_ERROR_NONE) {
    eventEndPtr = eventPtr;
    processor = errorProcessor;
    return XML_STATUS_ERROR;
  }
  else {
    switch (ps_parsing) {
    case XML_SUSPENDED:
      result = XML_STATUS_SUSPENDED;
      break;
    case XML_INITIALIZED: 
    case XML_PARSING:
      if (ps_finalBuffer) {
        ps_parsing = XML_FINISHED;
        return result;
      }
    default: ;
    }
  }

  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
  positionPtr = bufferPtr;
  return result;
}

void XMLCALL
XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
{


  assert(status != NULL);
  *status = parser->m_parsingStatus;
}

enum XML_Error XMLCALL
XML_GetErrorCode(XML_Parser parser)
{
  return errorCode;


}

XML_Index XMLCALL
XML_GetCurrentByteIndex(XML_Parser parser)
{
  if (eventPtr)
    return parseEndByteIndex - (parseEndPtr - eventPtr);


  return -1;
}

int XMLCALL
XML_GetCurrentByteCount(XML_Parser parser)
{
  if (eventEndPtr && eventPtr)
    return (int)(eventEndPtr - eventPtr);


  return 0;
}

const char * XMLCALL
XML_GetInputContext(XML_Parser parser, int *offset, int *size)
{
#ifdef XML_CONTEXT_BYTES
  if (eventPtr && buffer) {
    *offset = (int)(eventPtr - buffer);
    *size   = (int)(bufferEnd - buffer);




    return buffer;
  }




#endif /* defined XML_CONTEXT_BYTES */
  return (char *) 0;
}

XML_Size XMLCALL
XML_GetCurrentLineNumber(XML_Parser parser)
{
  if (eventPtr && eventPtr >= positionPtr) {
    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);


    positionPtr = eventPtr;
  }
  return position.lineNumber + 1;
}

XML_Size XMLCALL
XML_GetCurrentColumnNumber(XML_Parser parser)
{
  if (eventPtr && eventPtr >= positionPtr) {
    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);


    positionPtr = eventPtr;
  }
  return position.columnNumber;
}

void XMLCALL
XML_FreeContentModel(XML_Parser parser, XML_Content *model)
{

  FREE(model);
}

void * XMLCALL
XML_MemMalloc(XML_Parser parser, size_t size)
{


  return MALLOC(size);
}

void * XMLCALL
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
{


  return REALLOC(ptr, size);
}

void XMLCALL
XML_MemFree(XML_Parser parser, void *ptr)
{

  FREE(ptr);
}

void XMLCALL
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 * XMLCALL
XML_ErrorString(enum XML_Error code)
{
  static const XML_LChar* const message[] = {
    0,




    XML_L("out of memory"),

    XML_L("syntax error"),

    XML_L("no element found"),

    XML_L("not well-formed (invalid token)"),

    XML_L("unclosed token"),

    XML_L("partial character"),

    XML_L("mismatched tag"),

    XML_L("duplicate attribute"),

    XML_L("junk after document element"),

    XML_L("illegal parameter entity reference"),

    XML_L("undefined entity"),

    XML_L("recursive entity reference"),

    XML_L("asynchronous entity"),

    XML_L("reference to invalid character number"),

    XML_L("reference to binary entity"),

    XML_L("reference to external entity in attribute"),

    XML_L("XML or text declaration not at start of entity"),

    XML_L("unknown encoding"),

    XML_L("encoding specified in XML declaration is incorrect"),

    XML_L("unclosed CDATA section"),

    XML_L("error in processing external entity reference"),

    XML_L("document is not standalone"),

    XML_L("unexpected parser state - please send a bug report"),

    XML_L("entity declared in parameter entity"),

    XML_L("requested feature requires XML_DTD support in Expat"),

    XML_L("cannot change setting once parsing has begun"),


    XML_L("unbound prefix"),


    XML_L("must not undeclare prefix"),

    XML_L("incomplete markup in parameter entity"),

    XML_L("XML declaration not well-formed"),

    XML_L("text declaration not well-formed"),

    XML_L("illegal character(s) in public id"),

    XML_L("parser suspended"),

    XML_L("parser not suspended"),

    XML_L("parsing aborted"),

    XML_L("parsing finished"),

    XML_L("cannot suspend in external parameter entity"),


    XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),

    XML_L("reserved prefix (xmlns) must not be declared or undeclared"),

    XML_L("prefix must not be bound to one of the reserved namespace names")
  };
  if (code > 0 && code < sizeof(message)/sizeof(message[0]))
    return message[code];




  return NULL;
}

const XML_LChar * XMLCALL
XML_ExpatVersion(void) {

  /* V1 is used to string-ize the version number. However, it would
................................................................................
    {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
#endif
#ifdef XML_NS
    {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
#endif
#ifdef XML_LARGE_SIZE
    {XML_FEATURE_LARGE_SIZE,       XML_L("XML_LARGE_SIZE"), 0},
#endif    



    {XML_FEATURE_END,              NULL, 0}
  };

  return features;
}

/* Initially tag->rawName always points into the parse buffer;
................................................................................
   for those TAG instances opened while the current parse buffer was
   processed, and not yet closed, we need to store tag->rawName in a more
   permanent location, since the parse buffer is about to be discarded.
*/
static XML_Bool
storeRawNames(XML_Parser parser)
{
  TAG *tag = tagStack;
  while (tag) {
    int bufSize;
    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
    char *rawNameBuf = tag->buf + nameLen;
    /* Stop if already stored.  Since tagStack is a stack, we can stop
       at the first entry that has already been copied; everything
       below it in the stack is already been accounted for in a
       previous call to this function.
    */
    if (tag->rawName == rawNameBuf)
      break;
    /* For re-use purposes we need to ensure that the
       size of tag->buf is a multiple of sizeof(XML_Char).
    */
    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
    if (bufSize > tag->bufEnd - tag->buf) {
      char *temp = (char *)REALLOC(tag->buf, bufSize);
      if (temp == NULL)
        return XML_FALSE;
      /* if tag->name.str points to tag->buf (only when namespace
         processing is off) then we have to update it
      */
      if (tag->name.str == (XML_Char *)tag->buf)
        tag->name.str = (XML_Char *)temp;
................................................................................

static enum XML_Error PTRCALL
contentProcessor(XML_Parser parser,
                 const char *start,
                 const char *end,
                 const char **endPtr)
{
  enum XML_Error result = doContent(parser, 0, encoding, start, end, 
                                    endPtr, (XML_Bool)!ps_finalBuffer);
  if (result == XML_ERROR_NONE) {
    if (!storeRawNames(parser))
      return XML_ERROR_NO_MEMORY;
  }
  return result;
}

................................................................................
                            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 PTRCALL
externalEntityInitProcessor2(XML_Parser parser,
                             const char *start,
                             const char *end,
                             const char **endPtr)
{
  const char *next = start; /* XmlContentTok doesn't always set the last arg */
  int tok = XmlContentTok(encoding, start, end, &next);
  switch (tok) {
  case XML_TOK_BOM:
    /* If we are at the end of the buffer, this would cause the next stage,
       i.e. externalEntityInitProcessor3, to pass control directly to
       doContent (by detecting XML_TOK_NONE) without processing any xml text
       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
    */
    if (next == end && !ps_finalBuffer) {
      *endPtr = next;
      return XML_ERROR_NONE;
    }
    start = next;
    break;
  case XML_TOK_PARTIAL:
    if (!ps_finalBuffer) {
      *endPtr = start;
      return XML_ERROR_NONE;
    }
    eventPtr = start;
    return XML_ERROR_UNCLOSED_TOKEN;
  case XML_TOK_PARTIAL_CHAR:
    if (!ps_finalBuffer) {
      *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 PTRCALL
externalEntityInitProcessor3(XML_Parser parser,
                             const char *start,
                             const char *end,
                             const char **endPtr)
{
  int tok;
  const char *next = start; /* XmlContentTok doesn't always set the last arg */
  eventPtr = start;
  tok = XmlContentTok(encoding, start, end, &next);
  eventEndPtr = next;

  switch (tok) {
  case XML_TOK_XML_DECL:
    {
      enum XML_Error result;
      result = processXmlDecl(parser, 1, start, next);
      if (result != XML_ERROR_NONE)
        return result;
      switch (ps_parsing) {
      case XML_SUSPENDED: 
        *endPtr = next;
        return XML_ERROR_NONE;
      case XML_FINISHED:
        return XML_ERROR_ABORTED;
      default:
        start = next;
      }
    }
    break;
  case XML_TOK_PARTIAL:
    if (!ps_finalBuffer) {
      *endPtr = start;
      return XML_ERROR_NONE;
    }
    return XML_ERROR_UNCLOSED_TOKEN;
  case XML_TOK_PARTIAL_CHAR:
    if (!ps_finalBuffer) {
      *endPtr = start;
      return XML_ERROR_NONE;
    }
    return XML_ERROR_PARTIAL_CHAR;
  }
  processor = externalEntityContentProcessor;
  tagLevel = 1;
  return externalEntityContentProcessor(parser, start, end, endPtr);
}

static enum XML_Error PTRCALL
externalEntityContentProcessor(XML_Parser parser,
                               const char *start,
                               const char *end,
                               const char **endPtr)
{
  enum XML_Error result = doContent(parser, 1, encoding, start, end, 
                                    endPtr, (XML_Bool)!ps_finalBuffer);
  if (result == XML_ERROR_NONE) {
    if (!storeRawNames(parser))
      return XML_ERROR_NO_MEMORY;
  }
  return result;
}

................................................................................
          const ENCODING *enc,
          const char *s,
          const char *end,
          const char **nextPtr,
          XML_Bool haveMore)
{
  /* save one level of indirection */
  DTD * const dtd = _dtd;  

  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 (haveMore) {
        *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);
      /* We are at the end of the final buffer, should we check for 
         XML_SUSPENDED, XML_FINISHED? 
      */
      if (startTagLevel == 0)
        return XML_ERROR_NO_ELEMENTS;
      if (tagLevel != startTagLevel)
        return XML_ERROR_ASYNC_ENTITY;
      *nextPtr = end;
      return XML_ERROR_NONE;
    case XML_TOK_NONE:
      if (haveMore) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      if (startTagLevel > 0) {
        if (tagLevel != startTagLevel)
          return XML_ERROR_ASYNC_ENTITY;
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      return XML_ERROR_NO_ELEMENTS;
    case XML_TOK_INVALID:
      *eventPP = next;
................................................................................
      {
        const XML_Char *name;
        ENTITY *entity;
        XML_Char ch = (XML_Char) 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);
        /* First, determine if a check for an existing declaration is needed;
           if yes, check that the entity exists, and that it is internal,
           otherwise call the skipped entity or default handler.
        */
        if (!dtd->hasParamEntityRefs || dtd->standalone) {
          if (!entity)
            return XML_ERROR_UNDEFINED_ENTITY;
          else if (!entity->is_internal)
            return XML_ERROR_ENTITY_DECLARED_IN_PE;
        }
        else if (!entity) {
          if (skippedEntityHandler)
            skippedEntityHandler(handlerArg, name, 0);
          else 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->textPtr) {
          enum XML_Error result;
          if (!defaultExpandInternalEntities) {
            if (skippedEntityHandler)
              skippedEntityHandler(handlerArg, entity->name, 0);
            else if (defaultHandler)
              reportDefault(parser, enc, s, next);
            break;
          }
          result = processInternalEntity(parser, entity, XML_FALSE);
          if (result != XML_ERROR_NONE)
            return result;
        }
        else if (externalEntityRefHandler) {
          const XML_Char *context;
          entity->open = XML_TRUE;
          context = getContext(parser);
          entity->open = XML_FALSE;
          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_NO_ATTS:
      /* fall through */
    case XML_TOK_START_TAG_WITH_ATTS:
      {
        TAG *tag;
        enum XML_Error result;
        XML_Char *toPtr;
        if (freeTagList) {
          tag = freeTagList;
          freeTagList = freeTagList->parent;
        }
        else {
          tag = (TAG *)MALLOC(sizeof(TAG));
          if (!tag)
            return XML_ERROR_NO_MEMORY;
          tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
          if (!tag->buf) {
            FREE(tag);
            return XML_ERROR_NO_MEMORY;
          }
          tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
        }
        tag->bindings = NULL;
        tag->parent = tagStack;
        tagStack = tag;
        tag->name.localPart = NULL;
        tag->name.prefix = NULL;
        tag->rawName = s + enc->minBytesPerChar;
        tag->rawNameLength = XmlNameLength(enc, tag->rawName);
        ++tagLevel;
        {
          const char *rawNameEnd = tag->rawName + tag->rawNameLength;
          const char *fromPtr = tag->rawName;
          toPtr = (XML_Char *)tag->buf;
          for (;;) {
            int bufSize;
            int convLen;
            XmlConvert(enc,
                       &fromPtr, rawNameEnd,
                       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
            convLen = (int)(toPtr - (XML_Char *)tag->buf);
            if (fromPtr == rawNameEnd) {
              tag->name.strLen = convLen;
              break;
            }
            bufSize = (int)(tag->bufEnd - tag->buf) << 1;
            {
              char *temp = (char *)REALLOC(tag->buf, bufSize);
              if (temp == NULL)
                return XML_ERROR_NO_MEMORY;
              tag->buf = temp;
              tag->bufEnd = temp + bufSize;
              toPtr = (XML_Char *)temp + convLen;
            }
          }
        }
        tag->name.str = (XML_Char *)tag->buf;
        *toPtr = XML_T('\0');
        result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
        if (result)
          return result;
        if (startElementHandler)
          startElementHandler(handlerArg, tag->name.str,
                              (const XML_Char **)atts);
        else if (defaultHandler)
          reportDefault(parser, enc, s, next);
        poolClear(&tempPool);
        break;
      }
    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
      /* fall through */
    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
      {
        const char *rawName = s + enc->minBytesPerChar;
        enum XML_Error result;
        BINDING *bindings = NULL;
        XML_Bool noElmHandlers = XML_TRUE;
        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);
          noElmHandlers = XML_FALSE;
        }
        if (endElementHandler) {
          if (startElementHandler)
            *eventPP = *eventEndPP;
          endElementHandler(handlerArg, name.str);
          noElmHandlers = XML_FALSE;
        }
        if (noElmHandlers && defaultHandler)
          reportDefault(parser, enc, s, next);
        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;
        }
      }
      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) {
          const XML_Char *localPart;
          const XML_Char *prefix;
          XML_Char *uri;
          localPart = tag->name.localPart;
          if (ns && localPart) {
            /* localPart and prefix may have been overwritten in
               tag->name.str, since this points to the binding->uri
               buffer which gets re-used; so we have to add them again
            */
            uri = (XML_Char *)tag->name.str + tag->name.uriLen;
            /* don't need to check for space - already done in storeAtts() */
            while (*localPart) *uri++ = *localPart++;
            prefix = (XML_Char *)tag->name.prefix;
            if (ns_triplets && prefix) {
              *uri++ = namespaceSeparator;
              while (*prefix) *uri++ = *prefix++;
             }
            *uri = XML_T('\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, haveMore);
        if (result != XML_ERROR_NONE)
          return result;
        else if (!next) {
          processor = cdataSectionProcessor;
          return result;
        }
      }
      break;
    case XML_TOK_TRAILING_RSQB:
      if (haveMore) {
        *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,
                               (int)(dataPtr - (ICHAR *)dataBuf));
        }
        else
          characterDataHandler(handlerArg,
                               (XML_Char *)s,
                               (int)((XML_Char *)end - (XML_Char *)s));
      }
      else if (defaultHandler)
        reportDefault(parser, enc, s, end);
      /* We are at the end of the final buffer, should we check for 
         XML_SUSPENDED, XML_FINISHED? 
      */
      if (startTagLevel == 0) {
        *eventPP = end;
        return XML_ERROR_NO_ELEMENTS;
      }
      if (tagLevel != startTagLevel) {
        *eventPP = end;
        return XML_ERROR_ASYNC_ENTITY;
      }
      *nextPtr = end;
      return XML_ERROR_NONE;
    case XML_TOK_DATA_CHARS: 
      {
        XML_CharacterDataHandler charDataHandler = characterDataHandler;
        if (charDataHandler) {
          if (MUST_CONVERT(enc, s)) {
            for (;;) {
              ICHAR *dataPtr = (ICHAR *)dataBuf;
              XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
              *eventEndPP = s;
              charDataHandler(handlerArg, dataBuf,
                              (int)(dataPtr - (ICHAR *)dataBuf));
              if (s == next)
                break;
              *eventPP = s;
            }
          }
          else
            charDataHandler(handlerArg,
                            (XML_Char *)s,
                            (int)((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;
    switch (ps_parsing) {

    case XML_SUSPENDED: 
      *nextPtr = next;
      return XML_ERROR_NONE;
    case XML_FINISHED:
      return XML_ERROR_ABORTED;
    default: ;
    }
  }
  /* not reached */
}
























/* Precondition: all arguments must be non-NULL;
   Purpose:
   - normalize attributes
   - check attributes for well-formedness
   - generate namespace aware attribute names (URI, prefix)
   - build list of attributes for startElementHandler
................................................................................
   - generate namespace aware element name (URI, prefix)
*/
static enum XML_Error
storeAtts(XML_Parser parser, const ENCODING *enc,
          const char *attStr, TAG_NAME *tagNamePtr,
          BINDING **bindingsPtr)
{
  DTD * const dtd = _dtd;  /* save one level of indirection */
  ELEMENT_TYPE *elementType;
  int nDefaultAtts;
  const XML_Char **appAtts;   /* the attribute list for the application */
  int attIndex = 0;
  int prefixLen;
  int i;
  int n;
  XML_Char *uri;
  int nPrefixes = 0;
  BINDING *binding;
  const XML_Char *localPart;

  /* lookup the element type name */
  elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0);
  if (!elementType) {
    const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
    if (!name)
      return XML_ERROR_NO_MEMORY;
    elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name,
                                         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;
    ATTRIBUTE *temp;



    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
    temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));

    if (temp == NULL)

      return XML_ERROR_NO_MEMORY;

    atts = temp;








    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 by their QNames. This does not work when
       namespace processing is turned on and different prefixes for the same
       namespace are used. For this case we have a check further down.
    */
    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;
      XML_Bool isCdata = XML_TRUE;

      /* figure out whether declared as other than CDATA */
      if (attId->maybeTokenized) {
        int j;
        for (j = 0; j < nDefaultAtts; j++) {
................................................................................
            break;
          }
        }
      }

      /* normalize the attribute value */
      result = storeAttributeValue(parser, enc, isCdata,
                                   atts[i].valuePtr, atts[i].valueEnd,
                                   &tempPool);
      if (result)
        return result;
      appAtts[attIndex] = poolStart(&tempPool);
      poolFinish(&tempPool);
    }
    else {
      /* 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) {
      if (attId->xmlns) {
        /* deal with namespace declarations here */
        enum XML_Error result = addBinding(parser, attId->prefix, attId,
                                           appAtts[attIndex], bindingsPtr);
................................................................................
      }
    }
    else
      attIndex++;
  }

  /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
  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 (i = 0; i < nDefaultAtts; i++) {
    const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
    if (!(da->id->name)[-1] && da->value) {
      if (da->id->prefix) {
        if (da->id->xmlns) {
................................................................................
  appAtts[attIndex] = 0;

  /* expand prefixed attribute names, check for duplicates,
     and clear flags that say whether attributes were specified */
  i = 0;
  if (nPrefixes) {
    int j;  /* hash table index */
    unsigned long version = nsAttsVersion;
    int nsAttsSize = (int)1 << nsAttsPower;

    /* size of hash table must be at least 2 * (# of prefixed attributes) */
    if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */

      NS_ATT *temp;
      /* hash table size must also be a power of 2 and >= 8 */
      while (nPrefixes >> nsAttsPower++);
      if (nsAttsPower < 3)
        nsAttsPower = 3;
      nsAttsSize = (int)1 << nsAttsPower;
      temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
      if (!temp)


        return XML_ERROR_NO_MEMORY;

      nsAtts = temp;
      version = 0;  /* force re-initialization of nsAtts hash table */
    }
    /* using a version flag saves us from initializing nsAtts every time */
    if (!version) {  /* initialize version flags when version wraps around */
      version = INIT_ATTS_VERSION;
      for (j = nsAttsSize; j != 0; )
        nsAtts[--j].version = version;
    }
    nsAttsVersion = --version;

    /* expand prefixed names and check for duplicates */
    for (; i < attIndex; i += 2) {
      const XML_Char *s = appAtts[i];
      if (s[-1] == 2) {  /* prefixed */
        ATTRIBUTE_ID *id;
        const BINDING *b;
        unsigned long uriHash = 0;






        ((XML_Char *)s)[-1] = 0;  /* clear flag */
        id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0);

















        b = id->prefix->binding;
        if (!b)
          return XML_ERROR_UNBOUND_PREFIX;

        /* as we expand the name we also calculate its hash value */
        for (j = 0; j < b->uriLen; j++) {
          const XML_Char c = b->uri[j];
          if (!poolAppendChar(&tempPool, c))
            return XML_ERROR_NO_MEMORY;
          uriHash = CHAR_HASH(uriHash, c);
        }



        while (*s++ != XML_T(ASCII_COLON))
          ;



        do {  /* copies null terminator */
          const XML_Char c = *s;
          if (!poolAppendChar(&tempPool, *s))
            return XML_ERROR_NO_MEMORY;
          uriHash = CHAR_HASH(uriHash, c);
        } while (*s++);



        { /* Check hash table for duplicate of expanded name (uriName).
             Derived from code in lookup(HASH_TABLE *table, ...).
          */
          unsigned char step = 0;
          unsigned long mask = nsAttsSize - 1;
          j = uriHash & mask;  /* index into hash table */
          while (nsAtts[j].version == version) {
            /* for speed we compare stored hash values first */
            if (uriHash == nsAtts[j].hash) {
              const XML_Char *s1 = poolStart(&tempPool);
              const XML_Char *s2 = nsAtts[j].uriName;
              /* s1 is null terminated, but not s2 */
              for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
              if (*s1 == 0)
                return XML_ERROR_DUPLICATE_ATTRIBUTE;
            }
            if (!step)
              step = PROBE_STEP(uriHash, mask, nsAttsPower);
            j < step ? (j += nsAttsSize - step) : (j -= step);
          }
        }

        if (ns_triplets) {  /* append namespace separator and prefix */
          tempPool.ptr[-1] = namespaceSeparator;
          s = b->prefix->name;
          do {
            if (!poolAppendChar(&tempPool, *s))
              return XML_ERROR_NO_MEMORY;
          } while (*s++);
        }

        /* store expanded name in attribute list */
        s = poolStart(&tempPool);
        poolFinish(&tempPool);
        appAtts[i] = s;

        /* fill empty slot with new version, uriName and hash value */
        nsAtts[j].version = version;
        nsAtts[j].hash = uriHash;
        nsAtts[j].uriName = s;

        if (!--nPrefixes) {
          i += 2;
          break;
        }
      }
      else  /* not prefixed */
................................................................................
  }
  /* clear flags for the remaining attributes */
  for (; i < attIndex; i += 2)
    ((XML_Char *)(appAtts[i]))[-1] = 0;
  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
    binding->attId->name[-1] = 0;

  if (!ns)
    return XML_ERROR_NONE;

  /* expand the element type name */
  if (elementType->prefix) {
    binding = elementType->prefix->binding;
    if (!binding)
      return XML_ERROR_UNBOUND_PREFIX;
................................................................................
  else if (dtd->defaultPrefix.binding) {
    binding = dtd->defaultPrefix.binding;
    localPart = tagNamePtr->str;
  }
  else
    return XML_ERROR_NONE;
  prefixLen = 0;
  if (ns_triplets && binding->prefix->name) {
    for (; binding->prefix->name[prefixLen++];)
      ;  /* prefixLen includes null terminator */
  }
  tagNamePtr->localPart = localPart;
  tagNamePtr->uriLen = binding->uriLen;
  tagNamePtr->prefix = binding->prefix->name;
  tagNamePtr->prefixLen = prefixLen;
  for (i = 0; localPart[i++];)
    ;  /* i includes null terminator */
  n = i + binding->uriLen + prefixLen;
  if (n > binding->uriAlloc) {
    TAG *p;
    uri = (XML_Char *)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;
  }
  /* if namespaceSeparator != '\0' then uri includes it already */
  uri = binding->uri + binding->uriLen;
  memcpy(uri, localPart, i * sizeof(XML_Char));
  /* we always have a namespace separator between localPart and prefix */
  if (prefixLen) {
    uri += i - 1;
    *uri = namespaceSeparator;  /* replace null terminator */
    memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
  }
  tagNamePtr->str = binding->uri;
  return XML_ERROR_NONE;
}

/* addBinding() overwrites the value of prefix->binding without checking.
................................................................................
static enum XML_Error
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
           const XML_Char *uri, BINDING **bindingsPtr)
{
  static const XML_Char xmlNamespace[] = {
    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, 
    ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
    ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
    ASCII_e, '\0'
  };
  static const int xmlLen = 
    (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
  static const XML_Char xmlnsNamespace[] = {
    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0, 
    ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s, 
    ASCII_SLASH, '\0'
  };
  static const int xmlnsLen = 
    (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;

  XML_Bool mustBeXML = XML_FALSE;
  XML_Bool isXML = XML_TRUE;
  XML_Bool isXMLNS = XML_TRUE;
  
  BINDING *b;
  int len;

  /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
  if (*uri == XML_T('\0') && prefix->name)
    return XML_ERROR_UNDECLARING_PREFIX;

................................................................................
      mustBeXML = XML_TRUE;
  }

  for (len = 0; uri[len]; len++) {
    if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
      isXML = XML_FALSE;

    if (!mustBeXML && isXMLNS 
        && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
      isXMLNS = XML_FALSE;
  }
  isXML = isXML && len == xmlLen;
  isXMLNS = isXMLNS && len == xmlnsLen;

  if (mustBeXML != isXML)
    return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
                     : XML_ERROR_RESERVED_NAMESPACE_URI;

  if (isXMLNS)
    return XML_ERROR_RESERVED_NAMESPACE_URI;

  if (namespaceSeparator)
    len++;
  if (freeBindingList) {
    b = freeBindingList;
    if (len > b->uriAlloc) {
      XML_Char *temp = (XML_Char *)REALLOC(b->uri,
                          sizeof(XML_Char) * (len + EXPAND_SPARE));
      if (temp == NULL)
        return XML_ERROR_NO_MEMORY;
      b->uri = temp;
      b->uriAlloc = len + EXPAND_SPARE;
    }
    freeBindingList = b->nextTagBinding;
  }
  else {
    b = (BINDING *)MALLOC(sizeof(BINDING));
    if (!b)
      return XML_ERROR_NO_MEMORY;
    b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
    if (!b->uri) {
      FREE(b);
      return XML_ERROR_NO_MEMORY;
    }
    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;
  /* NULL binding when default namespace undeclared */
  if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix)
    prefix->binding = NULL;
  else
    prefix->binding = b;
  b->nextTagBinding = *bindingsPtr;
  *bindingsPtr = b;
  /* if attId == NULL then we are not starting a namespace scope */
  if (attId && startNamespaceDeclHandler)
    startNamespaceDeclHandler(handlerArg, prefix->name,
                              prefix->binding ? uri : 0);
  return XML_ERROR_NONE;
}

/* 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 PTRCALL
cdataSectionProcessor(XML_Parser parser,
                      const char *start,
                      const char *end,
                      const char **endPtr)
{
  enum XML_Error result = doCdataSection(parser, encoding, &start, end,
                                         endPtr, (XML_Bool)!ps_finalBuffer);
  if (result != XML_ERROR_NONE)
    return result;
  if (start) {
    if (parentParser) {  /* we are parsing an external entity */
      processor = externalEntityContentProcessor;
      return externalEntityContentProcessor(parser, start, end, endPtr);
    }
    else {
      processor = contentProcessor;
      return contentProcessor(parser, start, end, endPtr);
    }
  }
  return result;
}

/* startPtr gets set to non-null if the section is closed, and to null if
................................................................................
               const char *end,
               const char **nextPtr,
               XML_Bool haveMore)
{
  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 = NULL;

  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;
      *nextPtr = next;
      if (ps_parsing == XML_FINISHED)
        return XML_ERROR_ABORTED;
      else
        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:
      {
        XML_CharacterDataHandler charDataHandler = characterDataHandler;
        if (charDataHandler) {
          if (MUST_CONVERT(enc, s)) {
            for (;;) {
              ICHAR *dataPtr = (ICHAR *)dataBuf;
              XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
              *eventEndPP = next;
              charDataHandler(handlerArg, dataBuf,
                              (int)(dataPtr - (ICHAR *)dataBuf));
              if (s == next)
                break;
              *eventPP = s;
            }
          }
          else
            charDataHandler(handlerArg,
                            (XML_Char *)s,
                            (int)((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:
................................................................................
    case XML_TOK_NONE:
      if (haveMore) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      return XML_ERROR_UNCLOSED_CDATA_SECTION;
    default:







      *eventPP = next;
      return XML_ERROR_UNEXPECTED_STATE;

    }

    *eventPP = s = next;
    switch (ps_parsing) {
    case XML_SUSPENDED:
      *nextPtr = next;
      return XML_ERROR_NONE;
    case XML_FINISHED:
      return XML_ERROR_ABORTED;
    default: ;
    }
................................................................................
*/
static enum XML_Error PTRCALL
ignoreSectionProcessor(XML_Parser parser,
                       const char *start,
                       const char *end,
                       const char **endPtr)
{
  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, 
                                          endPtr, (XML_Bool)!ps_finalBuffer);
  if (result != XML_ERROR_NONE)
    return result;
  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.
................................................................................
                XML_Bool haveMore)
{
  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 = NULL;
  tok = XmlIgnoreSectionTok(enc, s, end, &next);
  *eventEndPP = next;
  switch (tok) {
  case XML_TOK_IGNORE_SECT:
    if (defaultHandler)
      reportDefault(parser, enc, s, next);
    *startPtr = next;
    *nextPtr = next;
    if (ps_parsing == XML_FINISHED)
      return XML_ERROR_ABORTED;
    else
      return XML_ERROR_NONE;
  case XML_TOK_INVALID:
    *eventPP = next;
    return XML_ERROR_INVALID_TOKEN;
  case XML_TOK_PARTIAL_CHAR:
................................................................................
  case XML_TOK_NONE:
    if (haveMore) {
      *nextPtr = s;
      return XML_ERROR_NONE;
    }
    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
  default:







    *eventPP = next;
    return XML_ERROR_UNEXPECTED_STATE;

  }
  /* 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 = NULL;
  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 = NULL;
  const XML_Char *storedEncName = NULL;
  const ENCODING *newEncoding = NULL;
  const char *version = NULL;
  const char *versionend;
  const XML_Char *storedversion = NULL;
  int standalone = -1;
  if (!(ns
        ? XmlParseXmlDeclNS
        : XmlParseXmlDecl)(isGeneralTextEntity,
                           encoding,
                           s,
                           next,
                           &eventPtr,
                           &version,
                           &versionend,
                           &encodingName,
                           &newEncoding,
                           &standalone)) {
    if (isGeneralTextEntity)
      return XML_ERROR_TEXT_DECL;
    else
      return XML_ERROR_XML_DECL;
  }
  if (!isGeneralTextEntity && standalone == 1) {
    _dtd->standalone = XML_TRUE;
#ifdef XML_DTD
    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
#endif /* XML_DTD */
  }
  if (xmlDeclHandler) {
    if (encodingName != NULL) {
      storedEncName = poolStoreString(&temp2Pool,
                                      encoding,
                                      encodingName,
                                      encodingName
                                      + XmlNameLength(encoding, encodingName));
      if (!storedEncName)
              return XML_ERROR_NO_MEMORY;
      poolFinish(&temp2Pool);
    }
    if (version) {
      storedversion = poolStoreString(&temp2Pool,
                                      encoding,
                                      version,
                                      versionend - encoding->minBytesPerChar);
      if (!storedversion)
        return XML_ERROR_NO_MEMORY;
    }
    xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
  }
  else if (defaultHandler)
    reportDefault(parser, encoding, s, next);
  if (protocolEncodingName == NULL) {
    if (newEncoding) {






      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {

        eventPtr = encodingName;
        return XML_ERROR_INCORRECT_ENCODING;
      }
      encoding = newEncoding;
    }
    else if (encodingName) {
      enum XML_Error result;
      if (!storedEncName) {
        storedEncName = poolStoreString(
          &temp2Pool, encoding, encodingName,
          encodingName + XmlNameLength(encoding, encodingName));
        if (!storedEncName)
          return XML_ERROR_NO_MEMORY;
      }
      result = handleUnknownEncoding(parser, storedEncName);
      poolClear(&temp2Pool);
      if (result == XML_ERROR_UNKNOWN_ENCODING)
        eventPtr = encodingName;
      return result;
    }
  }

  if (storedEncName || storedversion)
    poolClear(&temp2Pool);

  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 = NULL;
    info.data = NULL;
    info.release = NULL;
    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 != NULL)
      info.release(info.data);
  }
  return XML_ERROR_UNKNOWN_ENCODING;
................................................................................
                    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);
}

#ifdef XML_DTD

static enum XML_Error PTRCALL
externalParEntInitProcessor(XML_Parser parser,
................................................................................
{
  enum XML_Error result = initializeEncoding(parser);
  if (result != XML_ERROR_NONE)
    return result;

  /* we know now that XML_Parse(Buffer) has been called,
     so we consider the external parameter entity read */
  _dtd->paramEntityRead = XML_TRUE;

  if (prologState.inEntityValue) {
    processor = entityValueInitProcessor;
    return entityValueInitProcessor(parser, s, end, nextPtr);
  }
  else {
    processor = externalParEntProcessor;
    return externalParEntProcessor(parser, s, end, nextPtr);
  }
}

static enum XML_Error PTRCALL
entityValueInitProcessor(XML_Parser parser,
                         const char *s,
                         const char *end,
                         const char **nextPtr)
{
  int tok;
  const char *start = s;
  const char *next = start;
  eventPtr = start;

  for (;;) {  
    tok = XmlPrologTok(encoding, start, end, &next);
    eventEndPtr = next;
    if (tok <= 0) {
      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      switch (tok) {
      case XML_TOK_INVALID:
        return XML_ERROR_INVALID_TOKEN;
      case XML_TOK_PARTIAL:
................................................................................
      case XML_TOK_PARTIAL_CHAR:
        return XML_ERROR_PARTIAL_CHAR;
      case XML_TOK_NONE:   /* start == end */
      default:
        break;
      }
      /* found end of entity value - can store it now */
      return storeEntityValue(parser, encoding, s, end);
    }
    else if (tok == XML_TOK_XML_DECL) {
      enum XML_Error result;
      result = processXmlDecl(parser, 0, start, next);
      if (result != XML_ERROR_NONE)
        return result;
      switch (ps_parsing) {
      case XML_SUSPENDED: 
        *nextPtr = next;
        return XML_ERROR_NONE;
      case XML_FINISHED:


        return XML_ERROR_ABORTED;
      default:
        *nextPtr = next;
      }
      /* stop scanning for text declaration - we found one */
      processor = entityValueProcessor;
      return entityValueProcessor(parser, next, end, nextPtr);
    }
    /* If we are at the end of the buffer, this would cause XmlPrologTok to
       return XML_TOK_NONE on the next call, which would then cause the
       function to exit with *nextPtr set to s - that is what we want for other
       tokens, but not for the BOM - we would rather like to skip it;
       then, when this routine is entered the next time, XmlPrologTok will
       return XML_TOK_INVALID, since the BOM is still in the buffer
    */
    else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
      *nextPtr = next;
      return XML_ERROR_NONE;
    }








    start = next;
    eventPtr = start;
  }
}

static enum XML_Error PTRCALL
externalParEntProcessor(XML_Parser parser,
                        const char *s,
                        const char *end,
                        const char **nextPtr)
{
  const char *next = s;
  int tok;

  tok = XmlPrologTok(encoding, s, end, &next);
  if (tok <= 0) {
    if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
      *nextPtr = s;
      return XML_ERROR_NONE;
    }
    switch (tok) {
    case XML_TOK_INVALID:
      return XML_ERROR_INVALID_TOKEN;
    case XML_TOK_PARTIAL:
................................................................................
  }
  /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
     However, when parsing an external subset, doProlog will not accept a BOM
     as valid, and report a syntax error, so we have to skip the BOM
  */
  else if (tok == XML_TOK_BOM) {
    s = next;
    tok = XmlPrologTok(encoding, s, end, &next);
  }

  processor = prologProcessor;
  return doProlog(parser, encoding, s, end, tok, next, 
                  nextPtr, (XML_Bool)!ps_finalBuffer);
}

static enum XML_Error PTRCALL
entityValueProcessor(XML_Parser parser,
                     const char *s,
                     const char *end,
                     const char **nextPtr)
{
  const char *start = s;
  const char *next = s;
  const ENCODING *enc = encoding;
  int tok;

  for (;;) {
    tok = XmlPrologTok(enc, start, end, &next);
    if (tok <= 0) {
      if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      switch (tok) {
      case XML_TOK_INVALID:
        return XML_ERROR_INVALID_TOKEN;
      case XML_TOK_PARTIAL:
................................................................................
static enum XML_Error PTRCALL
prologProcessor(XML_Parser parser,
                const char *s,
                const char *end,
                const char **nextPtr)
{
  const char *next = s;
  int tok = XmlPrologTok(encoding, s, end, &next);
  return doProlog(parser, encoding, s, end, tok, next, 
                  nextPtr, (XML_Bool)!ps_finalBuffer);
}

static enum XML_Error
doProlog(XML_Parser parser,
         const ENCODING *enc,
         const char *s,
         const char *end,
................................................................................
         const char *next,
         const char **nextPtr,
         XML_Bool haveMore)
{
#ifdef XML_DTD
  static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
#endif /* XML_DTD */
  static const XML_Char atypeCDATA[] = 
      { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
  static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
  static const XML_Char atypeIDREF[] =
      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
  static const XML_Char atypeIDREFS[] =
      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
  static const XML_Char atypeENTITY[] =
................................................................................
      ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
  static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
      ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
  static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
  static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };

  /* save one level of indirection */
  DTD * const dtd = _dtd; 

  const char **eventPP;
  const char **eventEndPP;
  enum XML_Content_Quant quant;

  if (enc == encoding) {
    eventPP = &eventPtr;
    eventEndPP = &eventEndPtr;
  }
  else {
    eventPP = &(openInternalEntities->internalEventPtr);
    eventEndPP = &(openInternalEntities->internalEventEndPtr);
  }

  for (;;) {
    int role;
    XML_Bool handleDefault = XML_TRUE;
    *eventPP = s;
    *eventEndPP = next;
................................................................................
      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
        /* for internal PE NOT referenced between declarations */
        if (enc != encoding && !openInternalEntities->betweenDecl) {
          *nextPtr = s;
          return XML_ERROR_NONE;
        }
        /* WFC: PE Between Declarations - must check that PE contains
           complete markup, not only for external PEs, but also for
           internal PEs if the reference occurs between declarations.
        */
        if (isParamEntity || enc != encoding) {
          if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
              == XML_ROLE_ERROR)
            return XML_ERROR_INCOMPLETE_PE;
          *nextPtr = s;
          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;
        handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_DOCTYPE_NAME:
      if (startDoctypeDeclHandler) {
        doctypeName = poolStoreString(&tempPool, enc, s, next);
        if (!doctypeName)
          return XML_ERROR_NO_MEMORY;
        poolFinish(&tempPool);
        doctypePubid = NULL;
        handleDefault = XML_FALSE;
      }
      doctypeSysid = NULL; /* always initialize to NULL */
      break;
    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
      if (startDoctypeDeclHandler) {
        startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
                                doctypePubid, 1);
        doctypeName = NULL;
        poolClear(&tempPool);
        handleDefault = XML_FALSE;
      }
      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;
        handleDefault = XML_FALSE;
      }
      break;
#endif /* XML_DTD */
    case XML_ROLE_DOCTYPE_PUBLIC_ID:
#ifdef XML_DTD
      useForeignDTD = XML_FALSE;
      declEntity = (ENTITY *)lookup(&dtd->paramEntities,

                                    externalSubsetName,
                                    sizeof(ENTITY));
      if (!declEntity)
        return XML_ERROR_NO_MEMORY;
#endif /* XML_DTD */
      dtd->hasParamEntityRefs = XML_TRUE;
      if (startDoctypeDeclHandler) {

        if (!XmlIsPublicId(enc, s, next, eventPP))
          return XML_ERROR_PUBLICID;
        doctypePubid = poolStoreString(&tempPool, enc,
                                       s + enc->minBytesPerChar,
                                       next - enc->minBytesPerChar);
        if (!doctypePubid)

          return XML_ERROR_NO_MEMORY;
        normalizePublicId((XML_Char *)doctypePubid);
        poolFinish(&tempPool);

        handleDefault = XML_FALSE;
        goto alreadyChecked;
      }
      /* fall through */
    case XML_ROLE_ENTITY_PUBLIC_ID:
      if (!XmlIsPublicId(enc, s, next, eventPP))
        return XML_ERROR_PUBLICID;
    alreadyChecked:
      if (dtd->keepProcessing && 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);
        if (entityDeclHandler)



          handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_DOCTYPE_CLOSE:
      if (doctypeName) {
        startDoctypeDeclHandler(handlerArg, doctypeName,
                                doctypeSysid, doctypePubid, 0);
        poolClear(&tempPool);
        handleDefault = XML_FALSE;
      }
      /* doctypeSysid will be non-NULL in the case of a previous
         XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
         was not set, indicating an external subset
      */
#ifdef XML_DTD
      if (doctypeSysid || useForeignDTD) {
        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
        dtd->hasParamEntityRefs = XML_TRUE;
        if (paramEntityParsing && externalEntityRefHandler) {
          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,

                                            externalSubsetName,
                                            sizeof(ENTITY));
          if (!entity)





            return XML_ERROR_NO_MEMORY;

          if (useForeignDTD)
            entity->base = curBase;
          dtd->paramEntityRead = XML_FALSE;
          if (!externalEntityRefHandler(externalEntityRefHandlerArg,

                                        0,
                                        entity->base,
                                        entity->systemId,
                                        entity->publicId))
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
          if (dtd->paramEntityRead) {
            if (!dtd->standalone && 
                notStandaloneHandler && 
                !notStandaloneHandler(handlerArg))
              return XML_ERROR_NOT_STANDALONE;
          }
          /* if we didn't read the foreign DTD then this means that there
             is no external subset and we must reset dtd->hasParamEntityRefs
          */
          else if (!doctypeSysid)
            dtd->hasParamEntityRefs = hadParamEntityRefs;
          /* end of DTD - no need to update dtd->keepProcessing */
        }
        useForeignDTD = XML_FALSE;
      }
#endif /* XML_DTD */
      if (endDoctypeDeclHandler) {
        endDoctypeDeclHandler(handlerArg);
        handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_INSTANCE_START:
#ifdef XML_DTD
      /* if there is no DOCTYPE declaration then now is the
         last chance to read the foreign DTD
      */
      if (useForeignDTD) {
        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
        dtd->hasParamEntityRefs = XML_TRUE;
        if (paramEntityParsing && externalEntityRefHandler) {
          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
                                            externalSubsetName,
                                            sizeof(ENTITY));
          if (!entity)
            return XML_ERROR_NO_MEMORY;
          entity->base = curBase;
          dtd->paramEntityRead = XML_FALSE;
          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
                                        0,
                                        entity->base,
                                        entity->systemId,
                                        entity->publicId))
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
          if (dtd->paramEntityRead) {
            if (!dtd->standalone &&
                notStandaloneHandler &&
                !notStandaloneHandler(handlerArg))
              return XML_ERROR_NOT_STANDALONE;
          }
          /* if we didn't read the foreign DTD then this means that there
             is no external subset and we must reset dtd->hasParamEntityRefs
          */
          else
            dtd->hasParamEntityRefs = hadParamEntityRefs;
          /* end of DTD - no need to update dtd->keepProcessing */
        }
      }
#endif /* XML_DTD */
      processor = contentProcessor;
      return contentProcessor(parser, s, end, nextPtr);
    case XML_ROLE_ATTLIST_ELEMENT_NAME:
      declElementType = getElementType(parser, enc, s, next);
      if (!declElementType)
        return XML_ERROR_NO_MEMORY;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_NAME:
      declAttributeId = getAttributeId(parser, enc, s, next);
      if (!declAttributeId)
        return XML_ERROR_NO_MEMORY;
      declAttributeIsCdata = XML_FALSE;
      declAttributeType = NULL;
      declAttributeIsId = XML_FALSE;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
      declAttributeIsCdata = XML_TRUE;
      declAttributeType = atypeCDATA;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_ID:
      declAttributeIsId = XML_TRUE;
      declAttributeType = atypeID;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
      declAttributeType = atypeIDREF;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
      declAttributeType = atypeIDREFS;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
      declAttributeType = atypeENTITY;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
      declAttributeType = atypeENTITIES;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
      declAttributeType = atypeNMTOKEN;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
      declAttributeType = atypeNMTOKENS;
    checkAttListDeclHandler:
      if (dtd->keepProcessing && attlistDeclHandler)
        handleDefault = XML_FALSE;
      break;
    case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
      if (dtd->keepProcessing && attlistDeclHandler) {
        const XML_Char *prefix;
        if (declAttributeType) {
          prefix = enumValueSep;
        }
        else {
          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
                    ? notationPrefix
                    : enumValueStart);
        }
        if (!poolAppendString(&tempPool, prefix))
          return XML_ERROR_NO_MEMORY;
        if (!poolAppend(&tempPool, enc, s, next))
          return XML_ERROR_NO_MEMORY;
        declAttributeType = tempPool.start;
        handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
      if (dtd->keepProcessing) {
        if (!defineAttribute(declElementType, declAttributeId,
                             declAttributeIsCdata, declAttributeIsId,
                             0, parser))
          return XML_ERROR_NO_MEMORY;
        if (attlistDeclHandler && declAttributeType) {
          if (*declAttributeType == XML_T(ASCII_LPAREN)
              || (*declAttributeType == XML_T(ASCII_N)
                  && declAttributeType[1] == XML_T(ASCII_O))) {
            /* Enumerated or Notation type */
            if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
                || !poolAppendChar(&tempPool, XML_T('\0')))
              return XML_ERROR_NO_MEMORY;
            declAttributeType = tempPool.start;
            poolFinish(&tempPool);
          }
          *eventEndPP = s;
          attlistDeclHandler(handlerArg, declElementType->name,
                             declAttributeId->name, declAttributeType,
                             0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
          poolClear(&tempPool);
          handleDefault = XML_FALSE;
        }
      }
      break;
    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
      if (dtd->keepProcessing) {
        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);
        /* ID attributes aren't allowed to have a default */
        if (!defineAttribute(declElementType, declAttributeId,
                             declAttributeIsCdata, XML_FALSE, attVal, parser))
          return XML_ERROR_NO_MEMORY;
        if (attlistDeclHandler && declAttributeType) {
          if (*declAttributeType == XML_T(ASCII_LPAREN)
              || (*declAttributeType == XML_T(ASCII_N)
                  && declAttributeType[1] == XML_T(ASCII_O))) {
            /* Enumerated or Notation type */
            if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN))
                || !poolAppendChar(&tempPool, XML_T('\0')))
              return XML_ERROR_NO_MEMORY;
            declAttributeType = tempPool.start;
            poolFinish(&tempPool);
          }
          *eventEndPP = s;
          attlistDeclHandler(handlerArg, declElementType->name,
                             declAttributeId->name, declAttributeType,
                             attVal,
                             role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
          poolClear(&tempPool);
          handleDefault = XML_FALSE;
        }
      }
      break;
    case XML_ROLE_ENTITY_VALUE:
      if (dtd->keepProcessing) {
        enum XML_Error result = storeEntityValue(parser, enc,
                                            s + enc->minBytesPerChar,
                                            next - enc->minBytesPerChar);
        if (declEntity) {
          declEntity->textPtr = poolStart(&dtd->entityValuePool);
          declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
          poolFinish(&dtd->entityValuePool);
          if (entityDeclHandler) {
            *eventEndPP = s;
            entityDeclHandler(handlerArg,
                              declEntity->name,
                              declEntity->is_param,
                              declEntity->textPtr,
                              declEntity->textLen,
                              curBase, 0, 0, 0);
            handleDefault = XML_FALSE;
          }
        }
        else
          poolDiscard(&dtd->entityValuePool);
        if (result != XML_ERROR_NONE)
          return result;
      }
      break;
    case XML_ROLE_DOCTYPE_SYSTEM_ID:
#ifdef XML_DTD
      useForeignDTD = XML_FALSE;
#endif /* XML_DTD */
      dtd->hasParamEntityRefs = XML_TRUE;
      if (startDoctypeDeclHandler) {
        doctypeSysid = poolStoreString(&tempPool, enc,
                                       s + enc->minBytesPerChar,
                                       next - enc->minBytesPerChar);
        if (doctypeSysid == NULL)
          return XML_ERROR_NO_MEMORY;
        poolFinish(&tempPool);
        handleDefault = XML_FALSE;
      }
#ifdef XML_DTD
      else
        /* use externalSubsetName to make doctypeSysid non-NULL
           for the case where no startDoctypeDeclHandler is set */
        doctypeSysid = externalSubsetName;
#endif /* XML_DTD */
      if (!dtd->standalone
#ifdef XML_DTD
          && !paramEntityParsing
#endif /* XML_DTD */
          && notStandaloneHandler
          && !notStandaloneHandler(handlerArg))
        return XML_ERROR_NOT_STANDALONE;
#ifndef XML_DTD
      break;
#else /* XML_DTD */
      if (!declEntity) {
        declEntity = (ENTITY *)lookup(&dtd->paramEntities,

                                      externalSubsetName,
                                      sizeof(ENTITY));
        if (!declEntity)
          return XML_ERROR_NO_MEMORY;
        declEntity->publicId = NULL;
      }
      /* fall through */
#endif /* XML_DTD */
    case XML_ROLE_ENTITY_SYSTEM_ID:
      if (dtd->keepProcessing && 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);
        if (entityDeclHandler)



          handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_ENTITY_COMPLETE:
      if (dtd->keepProcessing && declEntity && entityDeclHandler) {
        *eventEndPP = s;
        entityDeclHandler(handlerArg,
                          declEntity->name,
                          declEntity->is_param,
                          0,0,
                          declEntity->base,
                          declEntity->systemId,
                          declEntity->publicId,
                          0);
        handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_ENTITY_NOTATION_NAME:
      if (dtd->keepProcessing && 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);
          handleDefault = XML_FALSE;
        }
        else if (entityDeclHandler) {
          *eventEndPP = s;
          entityDeclHandler(handlerArg,
                            declEntity->name,
                            0,0,0,
                            declEntity->base,
                            declEntity->systemId,
                            declEntity->publicId,
                            declEntity->notation);
          handleDefault = XML_FALSE;
        }
      }
      break;
    case XML_ROLE_GENERAL_ENTITY_NAME:
      {
        if (XmlPredefinedEntityName(enc, s, next)) {
          declEntity = NULL;
          break;
        }
        if (dtd->keepProcessing) {
          const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
          if (!name)
            return XML_ERROR_NO_MEMORY;
          declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
                                        sizeof(ENTITY));
          if (!declEntity)
            return XML_ERROR_NO_MEMORY;
          if (declEntity->name != name) {
            poolDiscard(&dtd->pool);
            declEntity = NULL;
          }
          else {
            poolFinish(&dtd->pool);
            declEntity->publicId = NULL;
            declEntity->is_param = XML_FALSE;
            /* if we have a parent parser or are reading an internal parameter
               entity, then the entity declaration is not considered "internal"
            */
            declEntity->is_internal = !(parentParser || openInternalEntities);
            if (entityDeclHandler)
              handleDefault = XML_FALSE;
          }
        }
        else {
          poolDiscard(&dtd->pool);
          declEntity = NULL;
        }
      }
      break;
    case XML_ROLE_PARAM_ENTITY_NAME:
#ifdef XML_DTD
      if (dtd->keepProcessing) {
        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 = NULL;
        }
        else {
          poolFinish(&dtd->pool);
          declEntity->publicId = NULL;
          declEntity->is_param = XML_TRUE;
          /* if we have a parent parser or are reading an internal parameter
             entity, then the entity declaration is not considered "internal"
          */
          declEntity->is_internal = !(parentParser || openInternalEntities);
          if (entityDeclHandler)
            handleDefault = XML_FALSE;
        }
      }
      else {
        poolDiscard(&dtd->pool);
        declEntity = NULL;
      }
#else /* not XML_DTD */
      declEntity = NULL;
#endif /* XML_DTD */
      break;
    case XML_ROLE_NOTATION_NAME:
      declNotationPublicId = NULL;
      declNotationName = NULL;
      if (notationDeclHandler) {
        declNotationName = poolStoreString(&tempPool, enc, s, next);
        if (!declNotationName)
          return XML_ERROR_NO_MEMORY;
        poolFinish(&tempPool);
        handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_NOTATION_PUBLIC_ID:
      if (!XmlIsPublicId(enc, s, next, eventPP))
        return XML_ERROR_PUBLICID;
      if (declNotationName) {  /* means notationDeclHandler != NULL */
        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);
        handleDefault = XML_FALSE;
      }
      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);
        handleDefault = XML_FALSE;
      }
      poolClear(&tempPool);
      break;
    case XML_ROLE_NOTATION_NO_SYSTEM_ID:
      if (declNotationPublicId && notationDeclHandler) {
        *eventEndPP = s;
        notationDeclHandler(handlerArg,
                            declNotationName,
                            curBase,
                            0,
                            declNotationPublicId);
        handleDefault = XML_FALSE;
      }
      poolClear(&tempPool);
      break;
    case XML_ROLE_ERROR:
      switch (tok) {
      case XML_TOK_PARAM_ENTITY_REF:
        /* PE references in internal subset are
           not allowed within declarations. */  
        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);
        handleDefault = XML_FALSE;
        result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
        if (result != XML_ERROR_NONE)
          return result;
        else if (!next) {
          processor = ignoreSectionProcessor;
          return result;
        }
      }
      break;
#endif /* XML_DTD */
    case XML_ROLE_GROUP_OPEN:
      if (prologState.level >= groupSize) {
        if (groupSize) {
          char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
          if (temp == NULL)

            return XML_ERROR_NO_MEMORY;

          groupConnector = temp;
          if (dtd->scaffIndex) {
            int *temp = (int *)REALLOC(dtd->scaffIndex,
                          groupSize * sizeof(int));
            if (temp == NULL)
              return XML_ERROR_NO_MEMORY;
            dtd->scaffIndex = temp;
          }
        }
        else {
          groupConnector = (char *)MALLOC(groupSize = 32);
          if (!groupConnector)

            return XML_ERROR_NO_MEMORY;
        }
      }

      groupConnector[prologState.level] = 0;
      if (dtd->in_eldecl) {
        int myindex = nextScaffoldPart(parser);
        if (myindex < 0)
          return XML_ERROR_NO_MEMORY;
        dtd->scaffIndex[dtd->scaffLevel] = myindex;
        dtd->scaffLevel++;
        dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
        if (elementDeclHandler)
          handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_GROUP_SEQUENCE:
      if (groupConnector[prologState.level] == ASCII_PIPE)
        return XML_ERROR_SYNTAX;
      groupConnector[prologState.level] = ASCII_COMMA;
      if (dtd->in_eldecl && elementDeclHandler)
        handleDefault = XML_FALSE;
      break;
    case XML_ROLE_GROUP_CHOICE:
      if (groupConnector[prologState.level] == ASCII_COMMA)
        return XML_ERROR_SYNTAX;
      if (dtd->in_eldecl
          && !groupConnector[prologState.level]
          && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
              != XML_CTYPE_MIXED)
          ) {
        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
            = XML_CTYPE_CHOICE;
        if (elementDeclHandler)
          handleDefault = XML_FALSE;
      }
      groupConnector[prologState.level] = ASCII_PIPE;
      break;
    case XML_ROLE_PARAM_ENTITY_REF:
#ifdef XML_DTD
    case XML_ROLE_INNER_PARAM_ENTITY_REF:
      dtd->hasParamEntityRefs = XML_TRUE;
      if (!paramEntityParsing)
        dtd->keepProcessing = dtd->standalone;
      else {
        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);
        /* first, determine if a check for an existing declaration is needed;
           if yes, check that the entity exists, and that it is internal,
           otherwise call the skipped entity handler
        */
        if (prologState.documentEntity &&
            (dtd->standalone
             ? !openInternalEntities
             : !dtd->hasParamEntityRefs)) {
          if (!entity)
            return XML_ERROR_UNDEFINED_ENTITY;
          else if (!entity->is_internal)




















            return XML_ERROR_ENTITY_DECLARED_IN_PE;

        }
        else if (!entity) {
          dtd->keepProcessing = dtd->standalone;
          /* cannot report skipped entities in declarations */
          if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
            skippedEntityHandler(handlerArg, name, 1);
            handleDefault = XML_FALSE;
          }
          break;
        }
        if (entity->open)
          return XML_ERROR_RECURSIVE_ENTITY_REF;
        if (entity->textPtr) {
          enum XML_Error result;
          XML_Bool betweenDecl = 
            (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
          result = processInternalEntity(parser, entity, betweenDecl);
          if (result != XML_ERROR_NONE)
            return result;
          handleDefault = XML_FALSE;
          break;
        }
        if (externalEntityRefHandler) {
          dtd->paramEntityRead = XML_FALSE;
          entity->open = XML_TRUE;
          if (!externalEntityRefHandler(externalEntityRefHandlerArg,
                                        0,
                                        entity->base,
                                        entity->systemId,
                                        entity->publicId)) {
            entity->open = XML_FALSE;
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
          }
................................................................................
        else {
          dtd->keepProcessing = dtd->standalone;
          break;
        }
      }
#endif /* XML_DTD */
      if (!dtd->standalone &&
          notStandaloneHandler &&
          !notStandaloneHandler(handlerArg))
        return XML_ERROR_NOT_STANDALONE;
      break;

    /* Element declaration stuff */

    case XML_ROLE_ELEMENT_NAME:
      if (elementDeclHandler) {
        declElementType = getElementType(parser, enc, s, next);
        if (!declElementType)
          return XML_ERROR_NO_MEMORY;
        dtd->scaffLevel = 0;
        dtd->scaffCount = 0;
        dtd->in_eldecl = XML_TRUE;
        handleDefault = XML_FALSE;
      }
      break;

    case XML_ROLE_CONTENT_ANY:
    case XML_ROLE_CONTENT_EMPTY:
      if (dtd->in_eldecl) {
        if (elementDeclHandler) {
          XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
          if (!content)
            return XML_ERROR_NO_MEMORY;
          content->quant = XML_CQUANT_NONE;
          content->name = NULL;
          content->numchildren = 0;
          content->children = NULL;
          content->type = ((role == XML_ROLE_CONTENT_ANY) ?
                           XML_CTYPE_ANY :
                           XML_CTYPE_EMPTY);
          *eventEndPP = s;
          elementDeclHandler(handlerArg, declElementType->name, content);
          handleDefault = XML_FALSE;
        }
        dtd->in_eldecl = XML_FALSE;
      }
      break;

    case XML_ROLE_CONTENT_PCDATA:
      if (dtd->in_eldecl) {
        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
            = XML_CTYPE_MIXED;
        if (elementDeclHandler)
          handleDefault = XML_FALSE;
      }
      break;

    case XML_ROLE_CONTENT_ELEMENT:
      quant = XML_CQUANT_NONE;
      goto elementContent;
................................................................................
        if (!el)
          return XML_ERROR_NO_MEMORY;
        name = el->name;
        dtd->scaffold[myindex].name = name;
        nameLen = 0;
        for (; name[nameLen++]; );
        dtd->contentStringLen +=  nameLen;
        if (elementDeclHandler)
          handleDefault = XML_FALSE;
      }
      break;

    case XML_ROLE_GROUP_CLOSE:
      quant = XML_CQUANT_NONE;
      goto closeGroup;
................................................................................
    case XML_ROLE_GROUP_CLOSE_REP:
      quant = XML_CQUANT_REP;
      goto closeGroup;
    case XML_ROLE_GROUP_CLOSE_PLUS:
      quant = XML_CQUANT_PLUS;
    closeGroup:
      if (dtd->in_eldecl) {
        if (elementDeclHandler)
          handleDefault = XML_FALSE;
        dtd->scaffLevel--;
        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
        if (dtd->scaffLevel == 0) {
          if (!handleDefault) {
            XML_Content *model = build_model(parser);
            if (!model)
              return XML_ERROR_NO_MEMORY;
            *eventEndPP = s;
            elementDeclHandler(handlerArg, declElementType->name, model);
          }
          dtd->in_eldecl = XML_FALSE;
          dtd->contentStringLen = 0;
        }
      }
      break;
      /* End element declaration stuff */
................................................................................
      switch (tok) {
      case XML_TOK_BOM:
        handleDefault = XML_FALSE;
        break;
      }
      break;
    case XML_ROLE_DOCTYPE_NONE:
      if (startDoctypeDeclHandler)
        handleDefault = XML_FALSE;
      break;
    case XML_ROLE_ENTITY_NONE:
      if (dtd->keepProcessing && entityDeclHandler)
        handleDefault = XML_FALSE;
      break;
    case XML_ROLE_NOTATION_NONE:
      if (notationDeclHandler)
        handleDefault = XML_FALSE;
      break;
    case XML_ROLE_ATTLIST_NONE:
      if (dtd->keepProcessing && attlistDeclHandler)
        handleDefault = XML_FALSE;
      break;
    case XML_ROLE_ELEMENT_NONE:
      if (elementDeclHandler)
        handleDefault = XML_FALSE;
      break;
    } /* end of big switch */

    if (handleDefault && defaultHandler)
      reportDefault(parser, enc, s, next);

    switch (ps_parsing) {
    case XML_SUSPENDED: 
      *nextPtr = next;
      return XML_ERROR_NONE;
    case XML_FINISHED:
      return XML_ERROR_ABORTED;
    default:
      s = next;
      tok = XmlPrologTok(enc, s, end, &next);
................................................................................

static enum XML_Error PTRCALL
epilogProcessor(XML_Parser parser,
                const char *s,
                const char *end,
                const char **nextPtr)
{
  processor = epilogProcessor;
  eventPtr = s;
  for (;;) {
    const char *next = NULL;
    int tok = XmlPrologTok(encoding, s, end, &next);
    eventEndPtr = next;
    switch (tok) {
    /* report partial linebreak - it might be the last token */
    case -XML_TOK_PROLOG_S:
      if (defaultHandler) {
        reportDefault(parser, encoding, s, next);
        if (ps_parsing == XML_FINISHED)
          return XML_ERROR_ABORTED;
      }
      *nextPtr = next;
      return XML_ERROR_NONE;
    case XML_TOK_NONE:
      *nextPtr = s;
      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 (!ps_finalBuffer) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      return XML_ERROR_UNCLOSED_TOKEN;
    case XML_TOK_PARTIAL_CHAR:
      if (!ps_finalBuffer) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      return XML_ERROR_PARTIAL_CHAR;
    default:
      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
    }
    eventPtr = s = next;
    switch (ps_parsing) {
    case XML_SUSPENDED: 
      *nextPtr = next;
      return XML_ERROR_NONE;
    case XML_FINISHED:
      return XML_ERROR_ABORTED;
    default: ;
    }
  }
................................................................................
                      XML_Bool betweenDecl)
{
  const char *textStart, *textEnd;
  const char *next;
  enum XML_Error result;
  OPEN_INTERNAL_ENTITY *openEntity;

  if (freeInternalEntities) {
    openEntity = freeInternalEntities;
    freeInternalEntities = openEntity->next;
  }
  else {
    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
    if (!openEntity)
      return XML_ERROR_NO_MEMORY;
  }
  entity->open = XML_TRUE;
  entity->processed = 0;
  openEntity->next = openInternalEntities;
  openInternalEntities = openEntity;
  openEntity->entity = entity;
  openEntity->startTagLevel = tagLevel;
  openEntity->betweenDecl = betweenDecl;
  openEntity->internalEventPtr = NULL;
  openEntity->internalEventEndPtr = NULL;
  textStart = (char *)entity->textPtr;
  textEnd = (char *)(entity->textPtr + entity->textLen);



#ifdef XML_DTD
  if (entity->is_param) {
    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
    result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
                      next, &next, XML_FALSE);
  }
  else 
#endif /* XML_DTD */
    result = doContent(parser, tagLevel, internalEncoding, textStart, 
                       textEnd, &next, XML_FALSE);

  if (result == XML_ERROR_NONE) {
    if (textEnd != next && ps_parsing == XML_SUSPENDED) {
      entity->processed = (int)(next - textStart);
      processor = internalEntityProcessor;
    }
    else {
      entity->open = XML_FALSE;
      openInternalEntities = openEntity->next;
      /* put openEntity back in list of free instances */
      openEntity->next = freeInternalEntities;
      freeInternalEntities = openEntity;
    }
  }
  return result;
}

static enum XML_Error PTRCALL
internalEntityProcessor(XML_Parser parser,
................................................................................
                        const char *end,
                        const char **nextPtr)
{
  ENTITY *entity;
  const char *textStart, *textEnd;
  const char *next;
  enum XML_Error result;
  OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
  if (!openEntity)
    return XML_ERROR_UNEXPECTED_STATE;

  entity = openEntity->entity;
  textStart = ((char *)entity->textPtr) + entity->processed;
  textEnd = (char *)(entity->textPtr + entity->textLen);



#ifdef XML_DTD
  if (entity->is_param) {
    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
    result = doProlog(parser, internalEncoding, textStart, textEnd, tok, 
                      next, &next, XML_FALSE);
  }
  else
#endif /* XML_DTD */
    result = doContent(parser, openEntity->startTagLevel, internalEncoding, 
                       textStart, textEnd, &next, XML_FALSE);  

  if (result != XML_ERROR_NONE)
    return result;
  else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
    entity->processed = (int)(next - (char *)entity->textPtr);
    return result;
  }
  else {
    entity->open = XML_FALSE;
    openInternalEntities = openEntity->next;
    /* put openEntity back in list of free instances */
    openEntity->next = freeInternalEntities;
    freeInternalEntities = openEntity;
  }

#ifdef XML_DTD
  if (entity->is_param) {
    int tok;
    processor = prologProcessor;
    tok = XmlPrologTok(encoding, s, end, &next);
    return doProlog(parser, encoding, s, end, tok, next, nextPtr, 
                    (XML_Bool)!ps_finalBuffer);
  }
  else
#endif /* XML_DTD */
  {
    processor = contentProcessor;
    /* see externalEntityContentProcessor vs contentProcessor */
    return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
                     nextPtr, (XML_Bool)!ps_finalBuffer); 
  }  
}

static enum XML_Error PTRCALL
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, XML_Bool isCdata,
                    const char *ptr, const char *end,
                    STRING_POOL *pool)
{
................................................................................
}

static enum XML_Error
appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
                     const char *ptr, const char *end,
                     STRING_POOL *pool)
{
  DTD * const dtd = _dtd;  /* save one level of indirection */
  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:
................................................................................
                                              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);
        /* First, determine if a check for an existing declaration is needed;
           if yes, check that the entity exists, and that it is internal.
        */
        if (pool == &dtd->pool)  /* are we called from prolog? */
          checkEntityDecl =
#ifdef XML_DTD
              prologState.documentEntity &&
#endif /* XML_DTD */
              (dtd->standalone
               ? !openInternalEntities
               : !dtd->hasParamEntityRefs);
        else /* if (pool == &tempPool): we are called from content */
          checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
        if (checkEntityDecl) {
          if (!entity)
            return XML_ERROR_UNDEFINED_ENTITY;
          else if (!entity->is_internal)
            return XML_ERROR_ENTITY_DECLARED_IN_PE;
        }
        else if (!entity) {
          /* Cannot report skipped entity here - see comments on
             skippedEntityHandler.
          if (skippedEntityHandler)
            skippedEntityHandler(handlerArg, name, 0);
          */
          /* Cannot call the default handler because this would be
             out of sync with the call to the startElementHandler.
          if ((pool == &tempPool) && defaultHandler)
            reportDefault(parser, enc, ptr, next);
          */
          break;
        }
        if (entity->open) {
          if (enc == encoding)

















            eventPtr = ptr;

          return XML_ERROR_RECURSIVE_ENTITY_REF;
        }
        if (entity->notation) {
          if (enc == encoding)
            eventPtr = ptr;
          return XML_ERROR_BINARY_ENTITY_REF;
        }
        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 = XML_TRUE;
          result = appendAttributeValue(parser, internalEncoding, isCdata,
                                        (char *)entity->textPtr,
                                        (char *)textEnd, pool);
          entity->open = XML_FALSE;
          if (result)
            return result;
        }
      }
      break;
    default:











      if (enc == encoding)
        eventPtr = ptr;
      return XML_ERROR_UNEXPECTED_STATE;

    }
    ptr = next;
  }
  /* not reached */
}

static enum XML_Error
storeEntityValue(XML_Parser parser,
                 const ENCODING *enc,
                 const char *entityTextPtr,
                 const char *entityTextEnd)
{
  DTD * const dtd = _dtd;  /* save one level of indirection */
  STRING_POOL *pool = &(dtd->entityValuePool);
  enum XML_Error result = XML_ERROR_NONE;
#ifdef XML_DTD
  int oldInEntityValue = prologState.inEntityValue;
  prologState.inEntityValue = 1;
#endif /* XML_DTD */
  /* never return Null for the value argument in EntityDeclHandler,
     since this would indicate an external entity; therefore we
     have to make sure that entityValuePool.start is not null */
  if (!pool->blocks) {
    if (!poolGrow(pool))
      return XML_ERROR_NO_MEMORY;
................................................................................

  for (;;) {
    const char *next;
    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
    switch (tok) {
    case XML_TOK_PARAM_ENTITY_REF:
#ifdef XML_DTD
      if (isParamEntity || enc != encoding) {
        const XML_Char *name;
        ENTITY *entity;
        name = poolStoreString(&tempPool, enc,
                               entityTextPtr + enc->minBytesPerChar,
                               next - enc->minBytesPerChar);
        if (!name) {
          result = XML_ERROR_NO_MEMORY;
          goto endEntityValue;
        }
        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
        poolDiscard(&tempPool);
        if (!entity) {
          /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
          /* cannot report skipped entity here - see comments on
             skippedEntityHandler
          if (skippedEntityHandler)
            skippedEntityHandler(handlerArg, name, 0);
          */
          dtd->keepProcessing = dtd->standalone;
          goto endEntityValue;
        }
        if (entity->open) {
          if (enc == encoding)
            eventPtr = entityTextPtr;
          result = XML_ERROR_RECURSIVE_ENTITY_REF;
          goto endEntityValue;
        }
        if (entity->systemId) {
          if (externalEntityRefHandler) {
            dtd->paramEntityRead = XML_FALSE;
            entity->open = XML_TRUE;
            if (!externalEntityRefHandler(externalEntityRefHandlerArg,
                                          0,
                                          entity->base,
                                          entity->systemId,
                                          entity->publicId)) {
              entity->open = XML_FALSE;
              result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
              goto endEntityValue;
................................................................................
          }
          else
            dtd->keepProcessing = dtd->standalone;
        }
        else {
          entity->open = XML_TRUE;
          result = storeEntityValue(parser,
                                    internalEncoding,
                                    (char *)entity->textPtr,
                                    (char *)(entity->textPtr
                                             + entity->textLen));
          entity->open = XML_FALSE;
          if (result)
            goto endEntityValue;
        }
        break;
      }
#endif /* XML_DTD */
      /* In the internal subset, PE references are not legal
         within markup declarations, e.g entity values in this case. */
      eventPtr = entityTextPtr;
      result = XML_ERROR_PARAM_ENTITY_REF;
      goto endEntityValue;
    case XML_TOK_NONE:
      result = XML_ERROR_NONE;
      goto endEntityValue;
    case XML_TOK_ENTITY_REF:
    case XML_TOK_DATA_CHARS:
................................................................................
      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;
          result = XML_ERROR_BAD_CHAR_REF;
          goto endEntityValue;
        }
        n = XmlEncode(n, (ICHAR *)buf);
        if (!n) {
          if (enc == encoding)
            eventPtr = entityTextPtr;
          result = XML_ERROR_BAD_CHAR_REF;
          goto endEntityValue;
        }




        for (i = 0; i < n; i++) {
          if (pool->end == pool->ptr && !poolGrow(pool)) {
            result = XML_ERROR_NO_MEMORY;
            goto endEntityValue;
          }
          *(pool->ptr)++ = buf[i];
        }
      }
      break;
    case XML_TOK_PARTIAL:
      if (enc == encoding)
        eventPtr = entityTextPtr;
      result = XML_ERROR_INVALID_TOKEN;
      goto endEntityValue;
    case XML_TOK_INVALID:
      if (enc == encoding)
        eventPtr = next;
      result = XML_ERROR_INVALID_TOKEN;
      goto endEntityValue;
    default:







      if (enc == encoding)
        eventPtr = entityTextPtr;
      result = XML_ERROR_UNEXPECTED_STATE;
      goto endEntityValue;

    }
    entityTextPtr = next;
  }
endEntityValue:
#ifdef XML_DTD
  prologState.inEntityValue = oldInEntityValue;
#endif /* XML_DTD */
  return result;
}

static void FASTCALL
normalizeLines(XML_Char *s)
{
................................................................................
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, (int)(dataPtr - (ICHAR *)dataBuf));

      *eventPP = s;
    } while (s != end);

  }
  else
    defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
}


static int
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
                XML_Bool isId, const XML_Char *value, XML_Parser parser)
{
................................................................................
        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 = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
                            * sizeof(DEFAULT_ATTRIBUTE));
      if (!type->defaultAtts)

        return 0;

    }
    else {
      DEFAULT_ATTRIBUTE *temp;
      int count = type->allocDefaultAtts * 2;
      temp = (DEFAULT_ATTRIBUTE *)
        REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
      if (temp == NULL)
        return 0;
      type->allocDefaultAtts = count;
      type->defaultAtts = temp;
    }
  }
  att = type->defaultAtts + type->nDefaultAtts;
................................................................................
  type->nDefaultAtts += 1;
  return 1;
}

static int
setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
{
  DTD * const dtd = _dtd;  /* save one level of indirection */
  const XML_Char *name;
  for (name = elementType->name; *name; name++) {
    if (*name == XML_T(ASCII_COLON)) {
      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);
................................................................................
  return 1;
}

static ATTRIBUTE_ID *
getAttributeId(XML_Parser parser, const ENCODING *enc,
               const char *start, const char *end)
{
  DTD * const dtd = _dtd;  /* save one level of indirection */
  ATTRIBUTE_ID *id;
  const XML_Char *name;
  if (!poolAppendChar(&dtd->pool, XML_T('\0')))
    return NULL;
  name = poolStoreString(&dtd->pool, enc, start, end);
  if (!name)
    return NULL;
  /* skip quotation mark - its storage will be re-used (like in name[-1]) */
  ++name;
  id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
  if (!id)
    return NULL;
  if (id->name != name)
    poolDiscard(&dtd->pool);
  else {
    poolFinish(&dtd->pool);
    if (!ns)
      ;
    else if (name[0] == XML_T(ASCII_x)
        && name[1] == XML_T(ASCII_m)
        && name[2] == XML_T(ASCII_l)
        && name[3] == XML_T(ASCII_n)
        && name[4] == XML_T(ASCII_s)
        && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
      if (name[5] == XML_T('\0'))
        id->prefix = &dtd->defaultPrefix;
      else
        id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
      id->xmlns = XML_TRUE;
    }
    else {
      int i;
      for (i = 0; name[i]; i++) {
        /* attributes without prefix are *not* in the default namespace */
        if (name[i] == XML_T(ASCII_COLON)) {
................................................................................
          int j;
          for (j = 0; j < i; j++) {
            if (!poolAppendChar(&dtd->pool, name[j]))
              return NULL;
          }
          if (!poolAppendChar(&dtd->pool, XML_T('\0')))
            return NULL;
          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;
        }
      }
................................................................................
}

#define CONTEXT_SEP XML_T(ASCII_FF)

static const XML_Char *
getContext(XML_Parser parser)
{
  DTD * const dtd = _dtd;  /* save one level of indirection */
  HASH_TABLE_ITER iter;
  XML_Bool needSep = XML_FALSE;

  if (dtd->defaultPrefix.binding) {
    int i;
    int len;
    if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
      return NULL;
    len = dtd->defaultPrefix.binding->uriLen;
    if (namespaceSeparator)
      len--;
    for (i = 0; i < len; i++)
      if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))



















        return NULL;


    needSep = XML_TRUE;
  }

  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 NULL;
    for (s = prefix->name; *s; s++)
      if (!poolAppendChar(&tempPool, *s))
        return NULL;
    if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
      return NULL;
    len = prefix->binding->uriLen;
    if (namespaceSeparator)
      len--;
    for (i = 0; i < len; i++)
      if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
        return NULL;
    needSep = XML_TRUE;
  }


  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 NULL;
    for (s = e->name; *s; s++)
      if (!poolAppendChar(&tempPool, *s))
        return 0;
    needSep = XML_TRUE;
  }

  if (!poolAppendChar(&tempPool, XML_T('\0')))
    return NULL;
  return tempPool.start;
}

static XML_Bool
setContext(XML_Parser parser, const XML_Char *context)
{
  DTD * const dtd = _dtd;  /* save one level of indirection */
  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 XML_FALSE;
      e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
      if (e)
        e->open = XML_TRUE;
      if (*s != XML_T('\0'))
        s++;
      context = s;
      poolDiscard(&tempPool);
    }
    else if (*s == XML_T(ASCII_EQUALS)) {
      PREFIX *prefix;
      if (poolLength(&tempPool) == 0)
        prefix = &dtd->defaultPrefix;
      else {
        if (!poolAppendChar(&tempPool, XML_T('\0')))
          return XML_FALSE;
        prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
                                  sizeof(PREFIX));
        if (!prefix)
          return XML_FALSE;
        if (prefix->name == poolStart(&tempPool)) {
          prefix->name = poolCopyString(&dtd->pool, prefix->name);
          if (!prefix->name)
            return XML_FALSE;
        }
        poolDiscard(&tempPool);
      }
      for (context = s + 1;
           *context != CONTEXT_SEP && *context != XML_T('\0');
           context++)
        if (!poolAppendChar(&tempPool, *context))
          return XML_FALSE;
      if (!poolAppendChar(&tempPool, XML_T('\0')))
        return XML_FALSE;
      if (addBinding(parser, prefix, NULL, poolStart(&tempPool),
                     &inheritedBindings) != XML_ERROR_NONE)
        return XML_FALSE;
      poolDiscard(&tempPool);
      if (*context != XML_T('\0'))
        ++context;
      s = context;
    }
    else {
      if (!poolAppendChar(&tempPool, *s))
        return XML_FALSE;
      s++;
    }
  }
  return XML_TRUE;
}

................................................................................
  ms->free_fcn(p);
}

/* 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, const XML_Memory_Handling_Suite *ms)
{
  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. */

................................................................................
    /* 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));
................................................................................
    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 *)
          ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
      if (!newE->defaultAtts) {
        ms->free_fcn(newE);
        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 = NULL;
    }
  }

  /* 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;
  newDtd->paramEntityRead = oldDtd->paramEntityRead;
#endif /* XML_DTD */

  newDtd->keepProcessing = oldDtd->keepProcessing;
................................................................................
  newDtd->scaffLevel = oldDtd->scaffLevel;
  newDtd->scaffIndex = oldDtd->scaffIndex;

  return 1;
}  /* End dtdCopy */

static int

copyEntityTable(HASH_TABLE *newTable,
                STRING_POOL *newPool,
                const HASH_TABLE *oldTable)
{
  HASH_TABLE_ITER iter;
  const XML_Char *cachedOldBase = NULL;
  const XML_Char *cachedNewBase = NULL;

................................................................................
    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;
................................................................................
keyeq(KEY s1, KEY s2)
{
  for (; *s1 == *s2; s1++, s2++)
    if (*s1 == 0)
      return XML_TRUE;
  return XML_FALSE;
}

static unsigned long FASTCALL
hash(KEY s)
{
  unsigned long h = 0;
  while (*s)
    h = CHAR_HASH(h, *s++);
  return h;




















}

static NAMED *
lookup(HASH_TABLE *table, KEY name, size_t createSize)
{
  size_t i;
  if (table->size == 0) {
    size_t tsize;
    if (!createSize)
      return NULL;
    table->power = INIT_POWER;
................................................................................
    tsize = table->size * sizeof(NAMED *);
    table->v = (NAMED **)table->mem->malloc_fcn(tsize);
    if (!table->v) {
      table->size = 0;
      return NULL;
    }
    memset(table->v, 0, tsize);
    i = hash(name) & ((unsigned long)table->size - 1);
  }
  else {
    unsigned long h = hash(name);
    unsigned long mask = (unsigned long)table->size - 1;
    unsigned char step = 0;
    i = h & mask;
    while (table->v[i]) {
      if (keyeq(name, table->v[i]->name))
        return table->v[i];
      if (!step)
................................................................................
      size_t tsize = newSize * sizeof(NAMED *);
      NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
      if (!newV)
        return NULL;
      memset(newV, 0, tsize);
      for (i = 0; i < table->size; i++)
        if (table->v[i]) {
          unsigned long newHash = hash(table->v[i]->name);
          size_t j = newHash & newMask;
          step = 0;
          while (newV[j]) {
            if (!step)
              step = PROBE_STEP(newHash, newMask, newPower);
            j < step ? (j += newSize - step) : (j -= step);
          }
................................................................................
static XML_Char *
poolAppend(STRING_POOL *pool, const ENCODING *enc,
           const char *ptr, const char *end)
{
  if (!pool->ptr && !poolGrow(pool))
    return NULL;
  for (;;) {
    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
    if (ptr == end)
      break;
    if (!poolGrow(pool))
      return NULL;
  }
  return 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 NULL;

  for (; n > 0; --n, s++) {
    if (!poolAppendChar(pool, *s))
      return NULL;
  }
  s = pool->start;
  poolFinish(pool);
  return s;
................................................................................
  if (!poolAppend(pool, enc, ptr, end))
    return NULL;
  if (pool->ptr == pool->end && !poolGrow(pool))
    return NULL;
  *(pool->ptr)++ = 0;
  return pool->start;
}






























static XML_Bool FASTCALL
poolGrow(STRING_POOL *pool)
{
  if (pool->freeBlocks) {
    if (pool->start == 0) {
      pool->blocks = pool->freeBlocks;
................................................................................
      pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
      pool->start = pool->blocks->s;
      pool->end = pool->start + pool->blocks->size;
      return XML_TRUE;
    }
  }
  if (pool->blocks && pool->start == pool->blocks->s) {

    int blockSize = (int)(pool->end - pool->start)*2;




















    pool->blocks = (BLOCK *)
      pool->mem->realloc_fcn(pool->blocks,
                             (offsetof(BLOCK, s)
                              + blockSize * sizeof(XML_Char)));
    if (pool->blocks == NULL)
      return XML_FALSE;

    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 = (int)(pool->end - pool->start);















    if (blockSize < INIT_BLOCK_SIZE)
      blockSize = INIT_BLOCK_SIZE;
    else




      blockSize *= 2;






    tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
                                        + blockSize * sizeof(XML_Char));
    if (!tem)
      return XML_FALSE;
    tem->size = blockSize;
    tem->next = pool->blocks;
    pool->blocks = tem;
    if (pool->ptr != pool->start)
      memcpy(tem->s, pool->start,
................................................................................
  }
  return XML_TRUE;
}

static int FASTCALL
nextScaffoldPart(XML_Parser parser)
{
  DTD * const dtd = _dtd;  /* save one level of indirection */
  CONTENT_SCAFFOLD * me;
  int next;

  if (!dtd->scaffIndex) {
    dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
    if (!dtd->scaffIndex)
      return -1;
    dtd->scaffIndex[0] = 0;
  }

  if (dtd->scaffCount >= dtd->scaffSize) {
    CONTENT_SCAFFOLD *temp;
    if (dtd->scaffold) {
      temp = (CONTENT_SCAFFOLD *)
        REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
      if (temp == NULL)
        return -1;
      dtd->scaffSize *= 2;
    }
    else {
      temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
                                        * sizeof(CONTENT_SCAFFOLD));
      if (temp == NULL)
        return -1;
      dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
    }
    dtd->scaffold = temp;
  }
................................................................................
static void
build_node(XML_Parser parser,
           int src_node,
           XML_Content *dest,
           XML_Content **contpos,
           XML_Char **strpos)
{
  DTD * const dtd = _dtd;  /* save one level of indirection */
  dest->type = dtd->scaffold[src_node].type;
  dest->quant = dtd->scaffold[src_node].quant;
  if (dest->type == XML_CTYPE_NAME) {
    const XML_Char *src;
    dest->name = *strpos;
    src = dtd->scaffold[src_node].name;
    for (;;) {
................................................................................
    dest->name = NULL;
  }
}

static XML_Content *
build_model (XML_Parser parser)
{
  DTD * const dtd = _dtd;  /* save one level of indirection */
  XML_Content *ret;
  XML_Content *cpos;
  XML_Char * str;
  int allocsize = (dtd->scaffCount * sizeof(XML_Content)
                   + (dtd->contentStringLen * sizeof(XML_Char)));

  ret = (XML_Content *)MALLOC(allocsize);
  if (!ret)
    return NULL;

  str =  (XML_Char *) (&ret[dtd->scaffCount]);
  cpos = &ret[1];

  build_node(parser, 0, ret, &cpos, &str);
................................................................................

static ELEMENT_TYPE *
getElementType(XML_Parser parser,
               const ENCODING *enc,
               const char *ptr,
               const char *end)
{
  DTD * const dtd = _dtd;  /* save one level of indirection */
  const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
  ELEMENT_TYPE *ret;

  if (!name)
    return NULL;
  ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
  if (!ret)
    return NULL;
  if (ret->name != name)
    poolDiscard(&dtd->pool);
  else {
    poolFinish(&dtd->pool);
    if (!setElementTypePrefix(parser, ret))
      return NULL;
  }
  return ret;
}























>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>




>
>
>
>
>
>
>
>
>
>
>
>
>



|

<
<
<
<
<
<


|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|

<
>
|
<
<
<
<
<
<







 







|
|


|



|










>
>







|







 







|




>
|

>
|
<

|







 







>
>
>
>
>
>





>







 







|









|







 







>
>
>













>


|
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<

<
>
>
>
|
|
|
|
|
<
>
|
|
|
>
>
>
>
>
|







 







|
|

|
|
|
|


>
>
>
>
>
>
>
>
|
|
<
>
>
>
>
|


|


|

|
|
|
<
>
>
>
>
|




|
|
|

|
|

|
|

|
|
|

|
|
|

>
>
|
|


|





|
|
|


|








|
|
|
|
<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|

>


|






|
|








>
>
>
>
|

|
<
>



|


|

|
|



|
|

|
|
|
|
|
|
>
>

|
<
>





>
>




|

>
>
>
>

>
|

<
>
>
|












|
|
|
|
|
<
|
|
<
|
<
|
|
<
|
|
<
|
<
|
|
<
|
|
<
|
|
|
|
|

|
|
|
|

|
|

|
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>









<
>

|









|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|

|

|
|
|
>
|

|
|


|




|



|



|


|
|
|













|
|










|
|



|

|
|



|

|

|
|



|

|
|



|


|
|
|
|
>




|

|

|
|
>
>
>
|
|
|
|
|
|
|
|





>
|





>
>


<
>

|









>
>

<
>

|





>
>
|
|

|





>
>

|


|


|






>
|
>





>
>
|





>
|
>

>
>
>
>
>
>
>
>
>
>






>
>
|
|





>
|





>
|






>
|






>
|






>
|







>
>
|
|





>
|





>
|






>
>
|
|






>
>
|
|







>
>
|
|





>
|





>
|






>
|






>
|







>
>
|
|





>
|





>
|






>
|






>
|





>
>

|

|






>
|







>
>
|
|






>
|






>
|






>
|





>
|






>
>

<
>


|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
>
>
>
>
>

|


|

>
>
>
>
>

|



|


|
|





|

|
|

|
>
>
>
>
>
>
>
>
>
>
>
>
|

>
|

|





|
|



|


|
>
>
>
>
>
>
>
|
|
|

<
>

|
|
|



|





<

|
|

>
>
>



|


|
|
|
|
|
|
>

|
<
<
<
<
<
<
>
|


<
>
>

|

|
<
>
|
|
<
>
|







 







|
>
>

|


|

>
>
>
>
>

|


|
|
|
|
|
|

<
>

|
|
|



|



|


|






|
|






|
>
>
>
>
>
>

|


|




|
<
<

>
>
|
>
>
>
>
|
>
>




|

|
|
|
|
|


|
|
|




|



|
>
|
>
>
>
>
|

|


|

|
|


<
>
|
|
<
<
>
>


|
<
>


|
<
>
|

|
<
>


>
>

|





|
>
>


|


|


|




|
|



|


|









>
>
|
|


|

<
>

|
|
|



|



|

|
|






|
|






>
>







|
>
>





|
|
>
>






|
|
>
>







|
|
|
>
>
>
>
|

>
>
>
>







|
|
>
>
|

|





|
|
>
>
|

|





>
|





>
>
|





>
>
|





>
|





>
>
|
|

|
|
|

<
>






<
<
>
>
>
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
>
|
>
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
|
>
>
|
>
|
>
|
<
<
<
>
>
>
>







 







|
>
>
>







 







|




|











|







 







|
|







 







|










|







|






|



|


|



|


|











|
|
|








|
|










|





|





|
|









|
|







 







|



|
|
|


|
|







 







|

|

|

|
|



|









|







 







|
|
|








|












|
|
|









|
|
|
|







|






|





|

|










|
|
|


|


|

|





|
|




|







|



|





|













|
|
|
|

|











|



|

|
>

>
|
|
|


|
|

|


|

|
<
<
<
<
<
<
|
<
|
<
|
>

>


|




|
|
|
|







|
|




|








|
|




|

|



|
|

|
|


|








|

|

|






|

|

|





|
|













|
|

|





|









|

|
|
|
|


|



|

|
|





|





|

|



|
|

|
|
|





|



|












>
>
>
>
>
>
>
|


>


<
>
|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|













|




|



|





|
|
|

>
>
>
|
<
>
|
>

>
|
>
>
>
>
>
>
>
>

|


|

>
>
>
>

|
<
>
|


>
>
>
>
>
>
>
>





|
|




|







 







|
|


|
|



|
|


|







 







|



|




|







 







|
|
>

<
>


|
|
|
|
|
|
>
>

>
|
|

|



|

|







|
>
>
>
>
>
>

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




<


|

<

>
>
>


>
>
>

<
|

<


>
>

|




|

|
|
|






|




|
|


|





|
|



|
|
|







 







|







 







|












|




|


|


|





|







 







|




|




|
|


|





|







 







|













|

|
|

|






|


|


|

|






|
|




|






|
|













|
|



|
|



|







 







|
|

|


|
|










|
|


|
|

|



|




|

|

|




|



|
|

|
|
|





|



|







 







>
>
>
>
>
>
>


>



|







 







|
|



|







 







|
|

|


>
>
>
>
>
>
>
>
>
>
>
|
|
>







|



|







 







>
>
>
>
>
>
>


>












>
|



|

|



|





|

|

|













|


|


|











|

|
|


|

|
|


|


|


|
|

|



|

|
|
|

>
>
>
>
>
>
|
>
|


|





|
|




|

|





|







|







|


|
|




|

|




|
|
|







 







|







 







|

|
|



|













|

|
|
|

|







 







|






|
|
|
|
<
>
>

<
|
<

|









|



>
>
>
>
>
>
>
>

|












|

|







 







|


|
|
|










|





|







 







|
|
|







 







|







 







|





|
|
|


|
|







 







>
>
>



|







|
|













|






|




|
|
|

|
|


|


|
|
|
|
|









|






|
|
>


|



|
>


|
|
|
<
>

|
|
>








|







|

|
>
>
>




|
|
|
|


|
|



|


|
|
>


|
>
>
>
>
>
|
>
|
|

<
>






|
|
|





|



|


|
|








|


|
|




|

|







|
|











|


|
|



|
|

|
|
|


|
|


|
|


|


|


|


|


|


|

|




|

|







|

|

|






|
|


|
|
|
|

|
|

|
|


|
|

|









|








|
|

|
|
|
|

|
|

|
|


|
|


|









|
|
|

|

|
|
|
|
|
|











|


|
|


|

|




|
|
|



|

|
|




|
|
>


|

|




|
|


|

|

|
>
>
>




|

|
|
|

|
|
|





|
|
|


|

|
|
|
|
|
|


|

|
|

|
|
|
|







|






|

|

|

|



|
|



|
|





|









|

|

|

|



|
|



|
|





|


|



|
|
|
|
|

|






|
|






|
|




|

|





|
|
|

|


|


|

|
|
|

|


|





|










|






|






|
|
|
|
>

>
|

|
|






|
|
>

|
|
>
|







|




|

|
|



|


|





|


|





|









|





|

|



|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>




|
|








|







|


|







 







|
|






|
|
|











|
|










|










|







 







|







 







|









|







 







|



|



|



|



|




|


|
|







 







|
|


|
|



|
|
|








|
|


|



|



|


|





|







|
|
|







 







|
|
|


|





|
|

|





>
>



|
|


|

|



|

|



|

|
|







 







|






>
>



|
|




|
|



|





|

|
|





|
|
|
|




|

|
|
|




|
|
|

|







 







|







|
|


|
|







|
|







|
|
|
|
<
>
>
>
>
>







 







|




|
|






|


|

|









|
|
|



|





|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>



|
|



|
|
|





|









>
>
>
>
>
>
>
>
>
>
>
|
|

>












|



|
|







 







|


|






|
|



|
|
|





|
|




|


|







 







|












|







 







|
|




|
|
|
|
|
<
>
>
>
>










|
|



|
|



>
>
>
>
>
>
>
|
|


>





|







 







|
|





|


|
|





|
|








|
|



|






|
|








>


|
|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>


|
|

<
>

<
>


|







 







|

|
>

>





|







 







|











|







 







|









|






|










|







 







|

>
>







 







|






|


|

|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>











|
>
>
>
>
>
>
|
>
|


|

|


|


|













|


|




|

|





|





|

|





|



|


|

|



|




|




|

|

|
|

|





|







 







|







 







|







 







|









|







 







|







<





|


|



|













>
|





>
|







 







>
|







 







|







 








|
|

|
|
<
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|







 







|


|







 







|







 







|
|







 







|
>
>
>
>
>
>
>
>
>
>
>
|
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
<
|

>

|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
>
>
>
>

>
>
>
>
>
>
|
<







 







|




|









|





|







 







|







 







|






|







 







|





|











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57






58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
184
185
186
187
188
189
190
191
192
193

194
195






196
197
198
199
200
201
202
...
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
...
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482

483
484
485
486
487
488
489
490
491
...
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
...
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
...
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650





































































































651
652
653
654
655
656
657
...
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894



895

896
897
898
899
900
901
902
903

904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
...
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967

968
969
970
971
972
973
974
975
976
977
978
979
980
981
982

983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039

1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129

1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156

1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178

1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198

1199
1200

1201

1202
1203

1204
1205

1206

1207
1208

1209
1210

1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286

1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452

1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467

1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777

1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886

1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900

1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922






1923
1924
1925
1926

1927
1928
1929
1930
1931
1932

1933
1934
1935

1936
1937
1938
1939
1940
1941
1942
1943
1944
....
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982

1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029


2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082

2083
2084
2085


2086
2087
2088
2089
2090

2091
2092
2093
2094

2095
2096
2097
2098

2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152

2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303

2304
2305
2306
2307
2308
2309
2310


2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396



2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
....
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
....
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
....
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
....
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
....
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
....
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
....
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908






2909

2910

2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104

3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
....
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191

3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217

3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
....
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
....
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
....
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341

3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401

3402
3403
3404
3405

3406
3407
3408
3409
3410
3411
3412
3413
3414
3415

3416
3417

3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
....
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
....
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
....
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
....
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
....
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
....
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
....
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
....
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
....
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
....
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
....
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
....
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150

4151
4152
4153

4154

4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
....
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
....
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
....
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
....
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
....
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429

4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490

4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
....
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
....
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
....
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
....
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
....
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
....
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
....
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
....
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547

5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
....
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
....
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
....
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
....
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823

5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
....
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980

5981
5982

5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
....
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
....
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
....
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
....
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
....
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
....
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
....
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
....
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
....
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491

6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
....
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
....
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
....
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630

6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
....
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
....
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
....
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
....
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
....
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
....
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985


6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026

7027
7028
7029
7030
7031
7032
7033
....
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
....
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
....
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
....
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
/* 4b74aa710b4ed5ce464b0ce544852cb47bf905c85a49c7bae2749f5885cb966d (2.2.5+)
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

#if !defined(_GNU_SOURCE)
# define _GNU_SOURCE 1                  /* syscall prototype */
#endif

#include <stddef.h>
#include <string.h>                     /* memset(), memcpy() */
#include <assert.h>
#include <limits.h>                     /* UINT_MAX */
#include <stdio.h>                      /* fprintf */
#include <stdlib.h>                     /* getenv */

#ifdef _WIN32
#define getpid GetCurrentProcessId
#else
#include <sys/time.h>                   /* gettimeofday() */
#include <sys/types.h>                  /* getpid() */
#include <unistd.h>                     /* getpid() */
#include <fcntl.h>                      /* O_RDONLY */
#include <errno.h>
#endif

#define XML_BUILDING_EXPAT 1

#ifdef _WIN32
#include "winconfig.h"






#elif defined(HAVE_EXPAT_CONFIG_H)
#include <expat_config.h>
#endif /* ndef _WIN32 */

#include "ascii.h"
#include "expat.h"
#include "siphash.h"

#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
# if defined(HAVE_GETRANDOM)
#  include <sys/random.h>    /* getrandom */
# else
#  include <unistd.h>        /* syscall */
#  include <sys/syscall.h>   /* SYS_getrandom */
# endif
# if ! defined(GRND_NONBLOCK)
#  define GRND_NONBLOCK  0x0001
# endif  /* defined(GRND_NONBLOCK) */
#endif  /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */

#if defined(HAVE_LIBBSD) \
    && (defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_ARC4RANDOM))
# include <bsd/stdlib.h>
#endif

#if defined(_WIN32) && !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
# define LOAD_LIBRARY_SEARCH_SYSTEM32  0x00000800
#endif

#if !defined(HAVE_GETRANDOM) && !defined(HAVE_SYSCALL_GETRANDOM) \
    && !defined(HAVE_ARC4RANDOM_BUF) && !defined(HAVE_ARC4RANDOM) \
    && !defined(XML_DEV_URANDOM) \
    && !defined(_WIN32) \
    && !defined(XML_POOR_ENTROPY)
# error  \
    You do not have support for any sources of high quality entropy \
    enabled.  For end user security, that is probably not what you want. \
    \
    Your options include: \
      * Linux + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
      * Linux + glibc <2.25 (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
      * BSD / macOS >=10.7 (arc4random_buf): HAVE_ARC4RANDOM_BUF, \
      * BSD / macOS <10.7 (arc4random): HAVE_ARC4RANDOM, \
      * libbsd (arc4random_buf): HAVE_ARC4RANDOM_BUF + HAVE_LIBBSD, \
      * libbsd (arc4random): HAVE_ARC4RANDOM + HAVE_LIBBSD, \
      * Linux / BSD / macOS (/dev/urandom): XML_DEV_URANDOM \
      * Windows (RtlGenRandom): _WIN32. \
    \
    If insist on not using any of these, bypass this error by defining \
    XML_POOR_ENTROPY; you have been warned. \
    \
    If you have reasons to patch this detection code away or need changes \
    to the build system, please open a bug.  Thank you!
#endif


#ifdef XML_UNICODE
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
#define XmlConvert XmlUtf16Convert
#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
#define XmlEncode XmlUtf16Encode
................................................................................
  NAMED **v;
  unsigned char power;
  size_t size;
  size_t used;
  const XML_Memory_Handling_Suite *mem;
} HASH_TABLE;

static size_t
keylen(KEY s);


static void
copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key);







/* For probing (after a collision) we need a step size relative prime
   to the hash table size, which is a power of 2. We use double-hashing,
   since we can calculate a second hash value cheaply by taking those bits
   of the first hash value that were discarded (masked out) when the table
   index was calculated: index = hash & mask, where mask = table->size - 1.
   We limit the maximum step size to table->size / 4 (mask >> 2) and make
................................................................................
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
static enum XML_Error
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
               const char *s, const char *next);
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,
         XML_Bool haveMore);
static enum XML_Error
processInternalEntity(XML_Parser parser, ENTITY *entity,
                      XML_Bool betweenDecl);
static enum XML_Error
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
          const char *start, const char *end, const char **endPtr,
          XML_Bool haveMore);
static enum XML_Error
doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
               const char *end, const char **nextPtr, XML_Bool haveMore);
#ifdef XML_DTD
static enum XML_Error
doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
                const char *end, const char **nextPtr, XML_Bool haveMore);
#endif /* XML_DTD */

static void
freeBindings(XML_Parser parser, BINDING *bindings);
static enum XML_Error
storeAtts(XML_Parser parser, const ENCODING *, const char *s,
          TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
static enum XML_Error
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
           const XML_Char *uri, BINDING **bindingsPtr);
static int
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
                XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
static enum XML_Error
storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
                    const char *, const char *, STRING_POOL *);
static enum XML_Error
appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
                     const char *, const char *, STRING_POOL *);
................................................................................
static const XML_Char * getContext(XML_Parser parser);
static XML_Bool
setContext(XML_Parser parser, const XML_Char *context);

static void FASTCALL normalizePublicId(XML_Char *s);

static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms);
/* do not call if m_parentParser != NULL */
static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms);
static void
dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms);
static int
dtdCopy(XML_Parser oldParser,
        DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms);
static int
copyEntityTable(XML_Parser oldParser,
                HASH_TABLE *, STRING_POOL *, const HASH_TABLE *);

static NAMED *
lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize);
static void FASTCALL
hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
static void FASTCALL hashTableClear(HASH_TABLE *);
static void FASTCALL hashTableDestroy(HASH_TABLE *);
static void FASTCALL
hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
................................................................................

static int FASTCALL nextScaffoldPart(XML_Parser parser);
static XML_Content * build_model(XML_Parser parser);
static ELEMENT_TYPE *
getElementType(XML_Parser parser, const ENCODING *enc,
               const char *ptr, const char *end);

static XML_Char *copyString(const XML_Char *s,
                            const XML_Memory_Handling_Suite *memsuite);

static unsigned long generate_hash_secret_salt(XML_Parser parser);
static XML_Bool startParsing(XML_Parser parser);

static XML_Parser
parserCreate(const XML_Char *encodingName,
             const XML_Memory_Handling_Suite *memsuite,
             const XML_Char *nameSep,
             DTD *dtd);

static void
parserInit(XML_Parser parser, const XML_Char *encodingName);

#define poolStart(pool) ((pool)->start)
#define poolEnd(pool) ((pool)->ptr)
#define poolLength(pool) ((pool)->ptr - (pool)->start)
#define poolChop(pool) ((void)--(pool->ptr))
................................................................................
#define poolFinish(pool) ((pool)->start = (pool)->ptr)
#define poolAppendChar(pool, c) \
  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
   ? 0 \
   : ((*((pool)->ptr)++ = c), 1))

struct XML_ParserStruct {
  /* The first member must be m_userData so that the XML_GetUserData
     macro works. */
  void *m_userData;
  void *m_handlerArg;
  char *m_buffer;
  const XML_Memory_Handling_Suite m_mem;
  /* first character to be parsed */
  const char *m_bufferPtr;
  /* past last character to be parsed */
  char *m_bufferEnd;
  /* allocated end of m_buffer */
  const char *m_bufferLim;
  XML_Index m_parseEndByteIndex;
  const char *m_parseEndPtr;
  XML_Char *m_dataBuf;
  XML_Char *m_dataBufEnd;
  XML_StartElementHandler m_startElementHandler;
  XML_EndElementHandler m_endElementHandler;
................................................................................
  int m_attsSize;
  int m_nSpecifiedAtts;
  int m_idAttIndex;
  ATTRIBUTE *m_atts;
  NS_ATT *m_nsAtts;
  unsigned long m_nsAttsVersion;
  unsigned char m_nsAttsPower;
#ifdef XML_ATTR_INFO
  XML_AttrInfo *m_attInfo;
#endif
  POSITION m_position;
  STRING_POOL m_tempPool;
  STRING_POOL m_temp2Pool;
  char *m_groupConnector;
  unsigned int m_groupSize;
  XML_Char m_namespaceSeparator;
  XML_Parser m_parentParser;
  XML_ParsingStatus m_parsingStatus;
#ifdef XML_DTD
  XML_Bool m_isParamEntity;
  XML_Bool m_useForeignDTD;
  enum XML_ParamEntityParsing m_paramEntityParsing;
#endif
  unsigned long m_hash_secret_salt;
};

#define MALLOC(parser, s)      (parser->m_mem.malloc_fcn((s)))
#define REALLOC(parser, p, s)  (parser->m_mem.realloc_fcn((p),(s)))
#define FREE(parser, p)        (parser->m_mem.free_fcn((p)))







































































































XML_Parser XMLCALL
XML_ParserCreate(const XML_Char *encodingName)
{
  return XML_ParserCreate_MM(encodingName, NULL, NULL);
}

................................................................................
  XML_Char tmp[2];
  *tmp = nsSep;
  return XML_ParserCreate_MM(encodingName, NULL, tmp);
}

static const XML_Char implicitContext[] = {
  ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
  ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
  ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
  ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
  ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
  ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
};


/* To avoid warnings about unused functions: */
#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)

#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)

/* Obtain entropy on Linux 3.17+ */
static int
writeRandomBytes_getrandom_nonblock(void * target, size_t count) {
  int success = 0;  /* full count bytes written? */
  size_t bytesWrittenTotal = 0;
  const unsigned int getrandomFlags = GRND_NONBLOCK;

  do {
    void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
    const size_t bytesToWrite = count - bytesWrittenTotal;

    const int bytesWrittenMore =
#if defined(HAVE_GETRANDOM)
        getrandom(currentTarget, bytesToWrite, getrandomFlags);
#else
        syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
#endif

    if (bytesWrittenMore > 0) {
      bytesWrittenTotal += bytesWrittenMore;
      if (bytesWrittenTotal >= count)
        success = 1;
    }
  } while (! success && (errno == EINTR));

  return success;
}

#endif  /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */


#if ! defined(_WIN32) && defined(XML_DEV_URANDOM)

/* Extract entropy from /dev/urandom */
static int
writeRandomBytes_dev_urandom(void * target, size_t count) {
  int success = 0;  /* full count bytes written? */
  size_t bytesWrittenTotal = 0;

  const int fd = open("/dev/urandom", O_RDONLY);
  if (fd < 0) {
    return 0;
  }

  do {
    void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
    const size_t bytesToWrite = count - bytesWrittenTotal;

    const ssize_t bytesWrittenMore = read(fd, currentTarget, bytesToWrite);

    if (bytesWrittenMore > 0) {
      bytesWrittenTotal += bytesWrittenMore;
      if (bytesWrittenTotal >= count)
        success = 1;
    }
  } while (! success && (errno == EINTR));

  close(fd);
  return success;
}

#endif  /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */

#endif  /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */


#if defined(HAVE_ARC4RANDOM)

static void
writeRandomBytes_arc4random(void * target, size_t count) {
  size_t bytesWrittenTotal = 0;

  while (bytesWrittenTotal < count) {
    const uint32_t random32 = arc4random();
    size_t i = 0;

    for (; (i < sizeof(random32)) && (bytesWrittenTotal < count);
        i++, bytesWrittenTotal++) {
      const uint8_t random8 = (uint8_t)(random32 >> (i * 8));
      ((uint8_t *)target)[bytesWrittenTotal] = random8;
    }
  }
}

#endif  /* defined(HAVE_ARC4RANDOM) */


#ifdef _WIN32

typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
HMODULE _Expat_LoadLibrary(LPCTSTR filename);  /* see loadlibrary.c */

/* Obtain entropy on Windows XP / Windows Server 2003 and later.
 * Hint on RtlGenRandom and the following article from libsodium.
 *
 * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI
 * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/
 */
static int
writeRandomBytes_RtlGenRandom(void * target, size_t count) {
  int success = 0;  /* full count bytes written? */
  const HMODULE advapi32 = _Expat_LoadLibrary(TEXT("ADVAPI32.DLL"));

  if (advapi32) {
    const RTLGENRANDOM_FUNC RtlGenRandom
        = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036");
    if (RtlGenRandom) {
      if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) {
        success = 1;
      }
    }
    FreeLibrary(advapi32);
  }

  return success;
}

#endif /* _WIN32 */


#if ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM)

static unsigned long
gather_time_entropy(void)
{
#ifdef _WIN32
  FILETIME ft;
  GetSystemTimeAsFileTime(&ft); /* never fails */
  return ft.dwHighDateTime ^ ft.dwLowDateTime;
#else
  struct timeval tv;
  int gettimeofday_res;

  gettimeofday_res = gettimeofday(&tv, NULL);

#if defined(NDEBUG)
  (void)gettimeofday_res;
#else
  assert (gettimeofday_res == 0);
#endif  /* defined(NDEBUG) */

  /* Microseconds time is <20 bits entropy */
  return tv.tv_usec;
#endif
}

#endif  /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */


static unsigned long
ENTROPY_DEBUG(const char * label, unsigned long entropy) {
  const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
  if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
    fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n",
        label,
        (int)sizeof(entropy) * 2, entropy,
        (unsigned long)sizeof(entropy));
  }
  return entropy;
}

static unsigned long
generate_hash_secret_salt(XML_Parser parser)
{
  unsigned long entropy;
  (void)parser;

  /* "Failproof" high quality providers: */
#if defined(HAVE_ARC4RANDOM_BUF)
  arc4random_buf(&entropy, sizeof(entropy));
  return ENTROPY_DEBUG("arc4random_buf", entropy);
#elif defined(HAVE_ARC4RANDOM)
  writeRandomBytes_arc4random((void *)&entropy, sizeof(entropy));
  return ENTROPY_DEBUG("arc4random", entropy);
#else
  /* Try high quality providers first .. */
#ifdef _WIN32
  if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) {
    return ENTROPY_DEBUG("RtlGenRandom", entropy);
  }
#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
  if (writeRandomBytes_getrandom_nonblock((void *)&entropy, sizeof(entropy))) {
    return ENTROPY_DEBUG("getrandom", entropy);
  }
#endif
#if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
  if (writeRandomBytes_dev_urandom((void *)&entropy, sizeof(entropy))) {
    return ENTROPY_DEBUG("/dev/urandom", entropy);
  }
#endif  /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
  /* .. and self-made low quality for backup: */

  /* Process ID is 0 bits entropy if attacker has local access */
  entropy = gather_time_entropy() ^ getpid();

  /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
  if (sizeof(unsigned long) == 4) {
    return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
  } else {
    return ENTROPY_DEBUG("fallback(8)",
        entropy * (unsigned long)2305843009213693951ULL);
  }
#endif
}

static unsigned long
get_hash_secret_salt(XML_Parser parser) {
  if (parser->m_parentParser != NULL)
    return get_hash_secret_salt(parser->m_parentParser);
  return parser->m_hash_secret_salt;
}

static XML_Bool  /* only valid for root parser */
startParsing(XML_Parser parser)



{

    /* hash functions must be initialized before setContext() is called */
    if (parser->m_hash_secret_salt == 0)
      parser->m_hash_secret_salt = generate_hash_secret_salt(parser);
    if (parser->m_ns) {
      /* implicit context only set for root parser, since child
         parsers (i.e. external entity parsers) will inherit it
      */
      return setContext(parser, implicitContext);

    }
    return XML_TRUE;
}

XML_Parser XMLCALL
XML_ParserCreate_MM(const XML_Char *encodingName,
                    const XML_Memory_Handling_Suite *memsuite,
                    const XML_Char *nameSep)
{
  return parserCreate(encodingName, memsuite, nameSep, NULL);
}

static XML_Parser
parserCreate(const XML_Char *encodingName,
             const XML_Memory_Handling_Suite *memsuite,
             const XML_Char *nameSep,
             DTD *dtd)
................................................................................
      mtemp->free_fcn = free;
    }
  }

  if (!parser)
    return parser;

  parser->m_buffer = NULL;
  parser->m_bufferLim = NULL;

  parser->m_attsSize = INIT_ATTS_SIZE;
  parser->m_atts = (ATTRIBUTE *)MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE));
  if (parser->m_atts == NULL) {
    FREE(parser, parser);
    return NULL;
  }
#ifdef XML_ATTR_INFO
  parser->m_attInfo = (XML_AttrInfo*)MALLOC(parser, parser->m_attsSize * sizeof(XML_AttrInfo));
  if (parser->m_attInfo == NULL) {
    FREE(parser, parser->m_atts);
    FREE(parser, parser);
    return NULL;
  }
#endif
  parser->m_dataBuf = (XML_Char *)MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char));
  if (parser->m_dataBuf == NULL) {

    FREE(parser, parser->m_atts);
#ifdef XML_ATTR_INFO
    FREE(parser, parser->m_attInfo);
#endif
    FREE(parser, parser);
    return NULL;
  }
  parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE;

  if (dtd)
    parser->m_dtd = dtd;
  else {
    parser->m_dtd = dtdCreate(&parser->m_mem);
    if (parser->m_dtd == NULL) {
      FREE(parser, parser->m_dataBuf);

      FREE(parser, parser->m_atts);
#ifdef XML_ATTR_INFO
      FREE(parser, parser->m_attInfo);
#endif
      FREE(parser, parser);
      return NULL;
    }
  }

  parser->m_freeBindingList = NULL;
  parser->m_freeTagList = NULL;
  parser->m_freeInternalEntities = NULL;

  parser->m_groupSize = 0;
  parser->m_groupConnector = NULL;

  parser->m_unknownEncodingHandler = NULL;
  parser->m_unknownEncodingHandlerData = NULL;

  parser->m_namespaceSeparator = ASCII_EXCL;
  parser->m_ns = XML_FALSE;
  parser->m_ns_triplets = XML_FALSE;

  parser->m_nsAtts = NULL;
  parser->m_nsAttsVersion = 0;
  parser->m_nsAttsPower = 0;

  parser->m_protocolEncodingName = NULL;

  poolInit(&parser->m_tempPool, &(parser->m_mem));
  poolInit(&parser->m_temp2Pool, &(parser->m_mem));
  parserInit(parser, encodingName);

  if (encodingName && !parser->m_protocolEncodingName) {
    XML_ParserFree(parser);
    return NULL;
  }

  if (nameSep) {
    parser->m_ns = XML_TRUE;
    parser->m_internalEncoding = XmlGetInternalEncodingNS();
    parser->m_namespaceSeparator = *nameSep;
  }
  else {
    parser->m_internalEncoding = XmlGetInternalEncoding();
  }

  return parser;
}

static void
parserInit(XML_Parser parser, const XML_Char *encodingName)
{
  parser->m_processor = prologInitProcessor;
  XmlPrologStateInit(&parser->m_prologState);
  if (encodingName != NULL) {
    parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));

  }
  parser->m_curBase = NULL;
  XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
  parser->m_userData = NULL;
  parser->m_handlerArg = NULL;
  parser->m_startElementHandler = NULL;
  parser->m_endElementHandler = NULL;
  parser->m_characterDataHandler = NULL;
  parser->m_processingInstructionHandler = NULL;
  parser->m_commentHandler = NULL;
  parser->m_startCdataSectionHandler = NULL;
  parser->m_endCdataSectionHandler = NULL;
  parser->m_defaultHandler = NULL;
  parser->m_startDoctypeDeclHandler = NULL;
  parser->m_endDoctypeDeclHandler = NULL;
  parser->m_unparsedEntityDeclHandler = NULL;
  parser->m_notationDeclHandler = NULL;
  parser->m_startNamespaceDeclHandler = NULL;
  parser->m_endNamespaceDeclHandler = NULL;
  parser->m_notStandaloneHandler = NULL;
  parser->m_externalEntityRefHandler = NULL;
  parser->m_externalEntityRefHandlerArg = parser;
  parser->m_skippedEntityHandler = NULL;
  parser->m_elementDeclHandler = NULL;
  parser->m_attlistDeclHandler = NULL;
  parser->m_entityDeclHandler = NULL;
  parser->m_xmlDeclHandler = NULL;
  parser->m_bufferPtr = parser->m_buffer;
  parser->m_bufferEnd = parser->m_buffer;
  parser->m_parseEndByteIndex = 0;
  parser->m_parseEndPtr = NULL;
  parser->m_declElementType = NULL;
  parser->m_declAttributeId = NULL;
  parser->m_declEntity = NULL;
  parser->m_doctypeName = NULL;
  parser->m_doctypeSysid = NULL;
  parser->m_doctypePubid = NULL;
  parser->m_declAttributeType = NULL;
  parser->m_declNotationName = NULL;
  parser->m_declNotationPublicId = NULL;
  parser->m_declAttributeIsCdata = XML_FALSE;
  parser->m_declAttributeIsId = XML_FALSE;
  memset(&parser->m_position, 0, sizeof(POSITION));
  parser->m_errorCode = XML_ERROR_NONE;
  parser->m_eventPtr = NULL;
  parser->m_eventEndPtr = NULL;
  parser->m_positionPtr = NULL;
  parser->m_openInternalEntities = NULL;
  parser->m_defaultExpandInternalEntities = XML_TRUE;
  parser->m_tagLevel = 0;
  parser->m_tagStack = NULL;
  parser->m_inheritedBindings = NULL;
  parser->m_nSpecifiedAtts = 0;
  parser->m_unknownEncodingMem = NULL;
  parser->m_unknownEncodingRelease = NULL;
  parser->m_unknownEncodingData = NULL;
  parser->m_parentParser = NULL;
  parser->m_parsingStatus.parsing = XML_INITIALIZED;
#ifdef XML_DTD
  parser->m_isParamEntity = XML_FALSE;
  parser->m_useForeignDTD = XML_FALSE;
  parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
#endif
  parser->m_hash_secret_salt = 0;
}

/* moves list of bindings to m_freeBindingList */
static void FASTCALL
moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
{
  while (bindings) {
    BINDING *b = bindings;
    bindings = bindings->nextTagBinding;
    b->nextTagBinding = parser->m_freeBindingList;
    parser->m_freeBindingList = b;
  }
}

XML_Bool XMLCALL
XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
{
  TAG *tStk;
  OPEN_INTERNAL_ENTITY *openEntityList;

  if (parser == NULL)
      return XML_FALSE;

  if (parser->m_parentParser)
    return XML_FALSE;
  /* move m_tagStack to m_freeTagList */

  tStk = parser->m_tagStack;
  while (tStk) {
    TAG *tag = tStk;
    tStk = tStk->parent;
    tag->parent = parser->m_freeTagList;
    moveToFreeBindingList(parser, tag->bindings);
    tag->bindings = NULL;
    parser->m_freeTagList = tag;
  }
  /* move m_openInternalEntities to m_freeInternalEntities */
  openEntityList = parser->m_openInternalEntities;
  while (openEntityList) {
    OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
    openEntityList = openEntity->next;
    openEntity->next = parser->m_freeInternalEntities;
    parser->m_freeInternalEntities = openEntity;
  }
  moveToFreeBindingList(parser, parser->m_inheritedBindings);
  FREE(parser, parser->m_unknownEncodingMem);
  if (parser->m_unknownEncodingRelease)
    parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
  poolClear(&parser->m_tempPool);
  poolClear(&parser->m_temp2Pool);
  FREE(parser, (void *)parser->m_protocolEncodingName);
  parser->m_protocolEncodingName = NULL;
  parserInit(parser, encodingName);
  dtdReset(parser->m_dtd, &parser->m_mem);

  return XML_TRUE;
}

enum XML_Status XMLCALL
XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
{
  if (parser == NULL)
      return XML_STATUS_ERROR;
  /* Block after XML_Parse()/XML_ParseBuffer() has been called.
     XXX There's no way for the caller to determine which of the
     XXX possible error cases caused the XML_STATUS_ERROR return.
  */
  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
    return XML_STATUS_ERROR;

  /* Get rid of any previous encoding name */
  FREE(parser, (void *)parser->m_protocolEncodingName);

  if (encodingName == NULL)
    /* No new encoding name */
    parser->m_protocolEncodingName = NULL;
  else {

    /* Copy the new encoding name into allocated memory */
    parser->m_protocolEncodingName = copyString(encodingName, &(parser->m_mem));
    if (!parser->m_protocolEncodingName)
      return XML_STATUS_ERROR;
  }
  return XML_STATUS_OK;
}

XML_Parser XMLCALL
XML_ExternalEntityParserCreate(XML_Parser oldParser,
                               const XML_Char *context,
                               const XML_Char *encodingName)
{
  XML_Parser parser = oldParser;
  DTD *newDtd = NULL;
  DTD *oldDtd;
  XML_StartElementHandler oldStartElementHandler;
  XML_EndElementHandler oldEndElementHandler;
  XML_CharacterDataHandler oldCharacterDataHandler;
  XML_ProcessingInstructionHandler oldProcessingInstructionHandler;

  XML_CommentHandler oldCommentHandler;
  XML_StartCdataSectionHandler oldStartCdataSectionHandler;

  XML_EndCdataSectionHandler oldEndCdataSectionHandler;

  XML_DefaultHandler oldDefaultHandler;
  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;

  XML_NotationDeclHandler oldNotationDeclHandler;
  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;

  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;

  XML_NotStandaloneHandler oldNotStandaloneHandler;
  XML_ExternalEntityRefHandler oldExternalEntityRefHandler;

  XML_SkippedEntityHandler oldSkippedEntityHandler;
  XML_UnknownEncodingHandler oldUnknownEncodingHandler;

  XML_ElementDeclHandler oldElementDeclHandler;
  XML_AttlistDeclHandler oldAttlistDeclHandler;
  XML_EntityDeclHandler oldEntityDeclHandler;
  XML_XmlDeclHandler oldXmlDeclHandler;
  ELEMENT_TYPE * oldDeclElementType;

  void *oldUserData;
  void *oldHandlerArg;
  XML_Bool oldDefaultExpandInternalEntities;
  XML_Parser oldExternalEntityRefHandlerArg;
#ifdef XML_DTD
  enum XML_ParamEntityParsing oldParamEntityParsing;
  int oldInEntityValue;
#endif
  XML_Bool oldns_triplets;
  /* Note that the new parser shares the same hash secret as the old
     parser, so that dtdCopy and copyEntityTable can lookup values
     from hash tables associated with either parser without us having
     to worry which hash secrets each table has.
  */
  unsigned long oldhash_secret_salt;

  /* Validate the oldParser parameter before we pull everything out of it */
  if (oldParser == NULL)
    return NULL;

  /* Stash the original parser contents on the stack */
  oldDtd = parser->m_dtd;
  oldStartElementHandler = parser->m_startElementHandler;
  oldEndElementHandler = parser->m_endElementHandler;
  oldCharacterDataHandler = parser->m_characterDataHandler;
  oldProcessingInstructionHandler = parser->m_processingInstructionHandler;
  oldCommentHandler = parser->m_commentHandler;
  oldStartCdataSectionHandler = parser->m_startCdataSectionHandler;
  oldEndCdataSectionHandler = parser->m_endCdataSectionHandler;
  oldDefaultHandler = parser->m_defaultHandler;
  oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler;
  oldNotationDeclHandler = parser->m_notationDeclHandler;
  oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler;
  oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler;
  oldNotStandaloneHandler = parser->m_notStandaloneHandler;
  oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
  oldSkippedEntityHandler = parser->m_skippedEntityHandler;
  oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
  oldElementDeclHandler = parser->m_elementDeclHandler;
  oldAttlistDeclHandler = parser->m_attlistDeclHandler;
  oldEntityDeclHandler = parser->m_entityDeclHandler;
  oldXmlDeclHandler = parser->m_xmlDeclHandler;
  oldDeclElementType = parser->m_declElementType;

  oldUserData = parser->m_userData;
  oldHandlerArg = parser->m_handlerArg;
  oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities;
  oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg;
#ifdef XML_DTD
  oldParamEntityParsing = parser->m_paramEntityParsing;
  oldInEntityValue = parser->m_prologState.inEntityValue;
#endif
  oldns_triplets = parser->m_ns_triplets;
  /* Note that the new parser shares the same hash secret as the old
     parser, so that dtdCopy and copyEntityTable can lookup values
     from hash tables associated with either parser without us having
     to worry which hash secrets each table has.
  */
  oldhash_secret_salt = parser->m_hash_secret_salt;

#ifdef XML_DTD
  if (!context)
    newDtd = oldDtd;
#endif /* XML_DTD */

  /* Note that the magical uses of the pre-processor to make field
     access look more like C++ require that `parser' be overwritten
     here.  This makes this function more painful to follow than it
     would be otherwise.
  */

  if (parser->m_ns) {
    XML_Char tmp[2];
    *tmp = parser->m_namespaceSeparator;
    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
  }
  else {
    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
  }

  if (!parser)
    return NULL;

  parser->m_startElementHandler = oldStartElementHandler;
  parser->m_endElementHandler = oldEndElementHandler;
  parser->m_characterDataHandler = oldCharacterDataHandler;
  parser->m_processingInstructionHandler = oldProcessingInstructionHandler;
  parser->m_commentHandler = oldCommentHandler;
  parser->m_startCdataSectionHandler = oldStartCdataSectionHandler;
  parser->m_endCdataSectionHandler = oldEndCdataSectionHandler;
  parser->m_defaultHandler = oldDefaultHandler;
  parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
  parser->m_notationDeclHandler = oldNotationDeclHandler;
  parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
  parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
  parser->m_notStandaloneHandler = oldNotStandaloneHandler;
  parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
  parser->m_skippedEntityHandler = oldSkippedEntityHandler;
  parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
  parser->m_elementDeclHandler = oldElementDeclHandler;
  parser->m_attlistDeclHandler = oldAttlistDeclHandler;
  parser->m_entityDeclHandler = oldEntityDeclHandler;
  parser->m_xmlDeclHandler = oldXmlDeclHandler;
  parser->m_declElementType = oldDeclElementType;
  parser->m_userData = oldUserData;
  if (oldUserData == oldHandlerArg)
    parser->m_handlerArg = parser->m_userData;
  else
    parser->m_handlerArg = parser;
  if (oldExternalEntityRefHandlerArg != oldParser)
    parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
  parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
  parser->m_ns_triplets = oldns_triplets;
  parser->m_hash_secret_salt = oldhash_secret_salt;
  parser->m_parentParser = oldParser;
#ifdef XML_DTD
  parser->m_paramEntityParsing = oldParamEntityParsing;
  parser->m_prologState.inEntityValue = oldInEntityValue;
  if (context) {
#endif /* XML_DTD */
    if (!dtdCopy(oldParser, parser->m_dtd, oldDtd, &parser->m_mem)
      || !setContext(parser, context)) {
      XML_ParserFree(parser);
      return NULL;
    }
    parser->m_processor = externalEntityInitProcessor;
#ifdef XML_DTD
  }
  else {
    /* The DTD instance referenced by parser->m_dtd is shared between the document's
       root parser and external PE parsers, therefore one does not need to
       call setContext. In addition, one also *must* not call setContext,
       because this would overwrite existing prefix->binding pointers in
       parser->m_dtd with ones that get destroyed with the external PE parser.
       This would leave those prefixes with dangling pointers.
    */
    parser->m_isParamEntity = XML_TRUE;
    XmlPrologStateInitExternalEntity(&parser->m_prologState);
    parser->m_processor = externalParEntInitProcessor;
  }
#endif /* XML_DTD */
  return parser;
}

static void FASTCALL
destroyBindings(BINDING *bindings, XML_Parser parser)
{
  for (;;) {
    BINDING *b = bindings;
    if (!b)
      break;
    bindings = b->nextTagBinding;
    FREE(parser, b->uri);
    FREE(parser, b);
  }
}

void XMLCALL
XML_ParserFree(XML_Parser parser)
{
  TAG *tagList;
  OPEN_INTERNAL_ENTITY *entityList;
  if (parser == NULL)
    return;
  /* free m_tagStack and m_freeTagList */
  tagList = parser->m_tagStack;
  for (;;) {
    TAG *p;
    if (tagList == NULL) {
      if (parser->m_freeTagList == NULL)
        break;
      tagList = parser->m_freeTagList;
      parser->m_freeTagList = NULL;
    }
    p = tagList;
    tagList = tagList->parent;
    FREE(parser, p->buf);
    destroyBindings(p->bindings, parser);
    FREE(parser, p);
  }
  /* free m_openInternalEntities and m_freeInternalEntities */
  entityList = parser->m_openInternalEntities;
  for (;;) {
    OPEN_INTERNAL_ENTITY *openEntity;
    if (entityList == NULL) {
      if (parser->m_freeInternalEntities == NULL)
        break;
      entityList = parser->m_freeInternalEntities;
      parser->m_freeInternalEntities = NULL;
    }
    openEntity = entityList;
    entityList = entityList->next;
    FREE(parser, openEntity);
  }

  destroyBindings(parser->m_freeBindingList, parser);
  destroyBindings(parser->m_inheritedBindings, parser);
  poolDestroy(&parser->m_tempPool);
  poolDestroy(&parser->m_temp2Pool);
  FREE(parser, (void *)parser->m_protocolEncodingName);
#ifdef XML_DTD
  /* external parameter entity parsers share the DTD structure
     parser->m_dtd with the root parser, so we must not destroy it
  */
  if (!parser->m_isParamEntity && parser->m_dtd)
#else
  if (parser->m_dtd)
#endif /* XML_DTD */
    dtdDestroy(parser->m_dtd, (XML_Bool)!parser->m_parentParser, &parser->m_mem);
  FREE(parser, (void *)parser->m_atts);
#ifdef XML_ATTR_INFO
  FREE(parser, (void *)parser->m_attInfo);
#endif
  FREE(parser, parser->m_groupConnector);
  FREE(parser, parser->m_buffer);
  FREE(parser, parser->m_dataBuf);
  FREE(parser, parser->m_nsAtts);
  FREE(parser, parser->m_unknownEncodingMem);
  if (parser->m_unknownEncodingRelease)
    parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
  FREE(parser, parser);
}

void XMLCALL
XML_UseParserAsHandlerArg(XML_Parser parser)
{
  if (parser != NULL)
    parser->m_handlerArg = parser;
}

enum XML_Error XMLCALL
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
{
  if (parser == NULL)
    return XML_ERROR_INVALID_ARGUMENT;
#ifdef XML_DTD
  /* block after XML_Parse()/XML_ParseBuffer() has been called */

  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
  parser->m_useForeignDTD = useDTD;
  return XML_ERROR_NONE;
#else
  return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
#endif
}

void XMLCALL
XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
{
  if (parser == NULL)
    return;
  /* block after XML_Parse()/XML_ParseBuffer() has been called */

  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
    return;
  parser->m_ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
}

void XMLCALL
XML_SetUserData(XML_Parser parser, void *p)
{
  if (parser == NULL)
    return;
  if (parser->m_handlerArg == parser->m_userData)
    parser->m_handlerArg = parser->m_userData = p;
  else
    parser->m_userData = p;
}

enum XML_Status XMLCALL
XML_SetBase(XML_Parser parser, const XML_Char *p)
{
  if (parser == NULL)
    return XML_STATUS_ERROR;
  if (p) {
    p = poolCopyString(&parser->m_dtd->pool, p);
    if (!p)
      return XML_STATUS_ERROR;
    parser->m_curBase = p;
  }
  else
    parser->m_curBase = NULL;
  return XML_STATUS_OK;
}

const XML_Char * XMLCALL
XML_GetBase(XML_Parser parser)
{
  if (parser == NULL)
    return NULL;
  return parser->m_curBase;
}

int XMLCALL
XML_GetSpecifiedAttributeCount(XML_Parser parser)
{
  if (parser == NULL)
    return -1;
  return parser->m_nSpecifiedAtts;
}

int XMLCALL
XML_GetIdAttributeIndex(XML_Parser parser)
{
  if (parser == NULL)
    return -1;
  return parser->m_idAttIndex;
}

#ifdef XML_ATTR_INFO
const XML_AttrInfo * XMLCALL
XML_GetAttributeInfo(XML_Parser parser)
{
  if (parser == NULL)
    return NULL;
  return parser->m_attInfo;
}
#endif

void XMLCALL
XML_SetElementHandler(XML_Parser parser,
                      XML_StartElementHandler start,
                      XML_EndElementHandler end)
{
  if (parser == NULL)
    return;
  parser->m_startElementHandler = start;
  parser->m_endElementHandler = end;
}

void XMLCALL
XML_SetStartElementHandler(XML_Parser parser,
                           XML_StartElementHandler start) {
  if (parser != NULL)
    parser->m_startElementHandler = start;
}

void XMLCALL
XML_SetEndElementHandler(XML_Parser parser,
                         XML_EndElementHandler end) {
  if (parser != NULL)
    parser->m_endElementHandler = end;
}

void XMLCALL
XML_SetCharacterDataHandler(XML_Parser parser,
                            XML_CharacterDataHandler handler)
{
  if (parser != NULL)
    parser->m_characterDataHandler = handler;
}

void XMLCALL
XML_SetProcessingInstructionHandler(XML_Parser parser,
                                    XML_ProcessingInstructionHandler handler)
{
  if (parser != NULL)
    parser->m_processingInstructionHandler = handler;
}

void XMLCALL
XML_SetCommentHandler(XML_Parser parser,
                      XML_CommentHandler handler)
{
  if (parser != NULL)
    parser->m_commentHandler = handler;
}

void XMLCALL
XML_SetCdataSectionHandler(XML_Parser parser,
                           XML_StartCdataSectionHandler start,
                           XML_EndCdataSectionHandler end)
{
  if (parser == NULL)
    return;
  parser->m_startCdataSectionHandler = start;
  parser->m_endCdataSectionHandler = end;
}

void XMLCALL
XML_SetStartCdataSectionHandler(XML_Parser parser,
                                XML_StartCdataSectionHandler start) {
  if (parser != NULL)
    parser->m_startCdataSectionHandler = start;
}

void XMLCALL
XML_SetEndCdataSectionHandler(XML_Parser parser,
                              XML_EndCdataSectionHandler end) {
  if (parser != NULL)
    parser->m_endCdataSectionHandler = end;
}

void XMLCALL
XML_SetDefaultHandler(XML_Parser parser,
                      XML_DefaultHandler handler)
{
  if (parser == NULL)
    return;
  parser->m_defaultHandler = handler;
  parser->m_defaultExpandInternalEntities = XML_FALSE;
}

void XMLCALL
XML_SetDefaultHandlerExpand(XML_Parser parser,
                            XML_DefaultHandler handler)
{
  if (parser == NULL)
    return;
  parser->m_defaultHandler = handler;
  parser->m_defaultExpandInternalEntities = XML_TRUE;
}

void XMLCALL
XML_SetDoctypeDeclHandler(XML_Parser parser,
                          XML_StartDoctypeDeclHandler start,
                          XML_EndDoctypeDeclHandler end)
{
  if (parser == NULL)
    return;
  parser->m_startDoctypeDeclHandler = start;
  parser->m_endDoctypeDeclHandler = end;
}

void XMLCALL
XML_SetStartDoctypeDeclHandler(XML_Parser parser,
                               XML_StartDoctypeDeclHandler start) {
  if (parser != NULL)
    parser->m_startDoctypeDeclHandler = start;
}

void XMLCALL
XML_SetEndDoctypeDeclHandler(XML_Parser parser,
                             XML_EndDoctypeDeclHandler end) {
  if (parser != NULL)
    parser->m_endDoctypeDeclHandler = end;
}

void XMLCALL
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
                                 XML_UnparsedEntityDeclHandler handler)
{
  if (parser != NULL)
    parser->m_unparsedEntityDeclHandler = handler;
}

void XMLCALL
XML_SetNotationDeclHandler(XML_Parser parser,
                           XML_NotationDeclHandler handler)
{
  if (parser != NULL)
    parser->m_notationDeclHandler = handler;
}

void XMLCALL
XML_SetNamespaceDeclHandler(XML_Parser parser,
                            XML_StartNamespaceDeclHandler start,
                            XML_EndNamespaceDeclHandler end)
{
  if (parser == NULL)
    return;
  parser->m_startNamespaceDeclHandler = start;
  parser->m_endNamespaceDeclHandler = end;
}

void XMLCALL
XML_SetStartNamespaceDeclHandler(XML_Parser parser,
                                 XML_StartNamespaceDeclHandler start) {
  if (parser != NULL)
    parser->m_startNamespaceDeclHandler = start;
}

void XMLCALL
XML_SetEndNamespaceDeclHandler(XML_Parser parser,
                               XML_EndNamespaceDeclHandler end) {
  if (parser != NULL)
    parser->m_endNamespaceDeclHandler = end;
}

void XMLCALL
XML_SetNotStandaloneHandler(XML_Parser parser,
                            XML_NotStandaloneHandler handler)
{
  if (parser != NULL)
    parser->m_notStandaloneHandler = handler;
}

void XMLCALL
XML_SetExternalEntityRefHandler(XML_Parser parser,
                                XML_ExternalEntityRefHandler handler)
{
  if (parser != NULL)
    parser->m_externalEntityRefHandler = handler;
}

void XMLCALL
XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
{
  if (parser == NULL)
    return;
  if (arg)
    parser->m_externalEntityRefHandlerArg = (XML_Parser)arg;
  else
    parser->m_externalEntityRefHandlerArg = parser;
}

void XMLCALL
XML_SetSkippedEntityHandler(XML_Parser parser,
                            XML_SkippedEntityHandler handler)
{
  if (parser != NULL)
    parser->m_skippedEntityHandler = handler;
}

void XMLCALL
XML_SetUnknownEncodingHandler(XML_Parser parser,
                              XML_UnknownEncodingHandler handler,
                              void *data)
{
  if (parser == NULL)
    return;
  parser->m_unknownEncodingHandler = handler;
  parser->m_unknownEncodingHandlerData = data;
}

void XMLCALL
XML_SetElementDeclHandler(XML_Parser parser,
                          XML_ElementDeclHandler eldecl)
{
  if (parser != NULL)
    parser->m_elementDeclHandler = eldecl;
}

void XMLCALL
XML_SetAttlistDeclHandler(XML_Parser parser,
                          XML_AttlistDeclHandler attdecl)
{
  if (parser != NULL)
    parser->m_attlistDeclHandler = attdecl;
}

void XMLCALL
XML_SetEntityDeclHandler(XML_Parser parser,
                         XML_EntityDeclHandler handler)
{
  if (parser != NULL)
    parser->m_entityDeclHandler = handler;
}

void XMLCALL
XML_SetXmlDeclHandler(XML_Parser parser,
                      XML_XmlDeclHandler handler) {
  if (parser != NULL)
    parser->m_xmlDeclHandler = handler;
}

int XMLCALL
XML_SetParamEntityParsing(XML_Parser parser,
                          enum XML_ParamEntityParsing peParsing)
{
  if (parser == NULL)
    return 0;
  /* block after XML_Parse()/XML_ParseBuffer() has been called */

  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
    return 0;
#ifdef XML_DTD
  parser->m_paramEntityParsing = peParsing;
  return 1;
#else
  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
#endif
}

int XMLCALL
XML_SetHashSalt(XML_Parser parser,
                unsigned long hash_salt)
{
  if (parser == NULL)
    return 0;
  if (parser->m_parentParser)
    return XML_SetHashSalt(parser->m_parentParser, hash_salt);
  /* block after XML_Parse()/XML_ParseBuffer() has been called */
  if (parser->m_parsingStatus.parsing == XML_PARSING || parser->m_parsingStatus.parsing == XML_SUSPENDED)
    return 0;
  parser->m_hash_secret_salt = hash_salt;
  return 1;
}

enum XML_Status XMLCALL
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
{
  if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
    if (parser != NULL)
      parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
    return XML_STATUS_ERROR;
  }
  switch (parser->m_parsingStatus.parsing) {
  case XML_SUSPENDED:
    parser->m_errorCode = XML_ERROR_SUSPENDED;
    return XML_STATUS_ERROR;
  case XML_FINISHED:
    parser->m_errorCode = XML_ERROR_FINISHED;
    return XML_STATUS_ERROR;
  case XML_INITIALIZED:
    if (parser->m_parentParser == NULL && !startParsing(parser)) {
      parser->m_errorCode = XML_ERROR_NO_MEMORY;
      return XML_STATUS_ERROR;
    }
  default:
    parser->m_parsingStatus.parsing = XML_PARSING;
  }

  if (len == 0) {
    parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
    if (!isFinal)
      return XML_STATUS_OK;
    parser->m_positionPtr = parser->m_bufferPtr;
    parser->m_parseEndPtr = parser->m_bufferEnd;

    /* If data are left over from last buffer, and we now know that these
       data are the final chunk of input, then we have to check them again
       to detect errors based on that fact.
    */
    parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);

    if (parser->m_errorCode == XML_ERROR_NONE) {
      switch (parser->m_parsingStatus.parsing) {
      case XML_SUSPENDED:
        /* It is hard to be certain, but it seems that this case
         * cannot occur.  This code is cleaning up a previous parse
         * with no new data (since len == 0).  Changing the parsing
         * state requires getting to execute a handler function, and
         * there doesn't seem to be an opportunity for that while in
         * this circumstance.
         *
         * Given the uncertainty, we retain the code but exclude it
         * from coverage tests.
         *
         * LCOV_EXCL_START
         */
        XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position);
        parser->m_positionPtr = parser->m_bufferPtr;
        return XML_STATUS_SUSPENDED;
        /* LCOV_EXCL_STOP */
      case XML_INITIALIZED:
      case XML_PARSING:
        parser->m_parsingStatus.parsing = XML_FINISHED;
        /* fall through */
      default:
        return XML_STATUS_OK;
      }
    }
    parser->m_eventEndPtr = parser->m_eventPtr;
    parser->m_processor = errorProcessor;
    return XML_STATUS_ERROR;
  }
#ifndef XML_CONTEXT_BYTES
  else if (parser->m_bufferPtr == parser->m_bufferEnd) {
    const char *end;
    int nLeftOver;
    enum XML_Status result;
    /* Detect overflow (a+b > MAX <==> b > MAX-a) */
    if (len > ((XML_Size)-1) / 2 - parser->m_parseEndByteIndex) {
       parser->m_errorCode = XML_ERROR_NO_MEMORY;
       parser->m_eventPtr = parser->m_eventEndPtr = NULL;
       parser->m_processor = errorProcessor;
       return XML_STATUS_ERROR;
    }
    parser->m_parseEndByteIndex += len;
    parser->m_positionPtr = s;
    parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;


    parser->m_errorCode = parser->m_processor(parser, s, parser->m_parseEndPtr = s + len, &end);

    if (parser->m_errorCode != XML_ERROR_NONE) {
      parser->m_eventEndPtr = parser->m_eventPtr;
      parser->m_processor = errorProcessor;
      return XML_STATUS_ERROR;
    }
    else {
      switch (parser->m_parsingStatus.parsing) {
      case XML_SUSPENDED:
        result = XML_STATUS_SUSPENDED;
        break;
      case XML_INITIALIZED:
      case XML_PARSING:

        if (isFinal) {
          parser->m_parsingStatus.parsing = XML_FINISHED;
          return XML_STATUS_OK;
        }
      /* fall through */
      default:
        result = XML_STATUS_OK;
      }
    }

    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end, &parser->m_position);
    nLeftOver = s + len - end;
    if (nLeftOver) {
      if (parser->m_buffer == NULL || nLeftOver > parser->m_bufferLim - parser->m_buffer) {
        /* avoid _signed_ integer overflow */
        char *temp = NULL;
        const int bytesToAllocate = (int)((unsigned)len * 2U);
        if (bytesToAllocate > 0) {
          temp = (char *)REALLOC(parser, parser->m_buffer, bytesToAllocate);
        }
        if (temp == NULL) {
          parser->m_errorCode = XML_ERROR_NO_MEMORY;






          parser->m_eventPtr = parser->m_eventEndPtr = NULL;
          parser->m_processor = errorProcessor;
          return XML_STATUS_ERROR;
        }

        parser->m_buffer = temp;
        parser->m_bufferLim = parser->m_buffer + bytesToAllocate;
      }
      memcpy(parser->m_buffer, end, nLeftOver);
    }
    parser->m_bufferPtr = parser->m_buffer;

    parser->m_bufferEnd = parser->m_buffer + nLeftOver;
    parser->m_positionPtr = parser->m_bufferPtr;
    parser->m_parseEndPtr = parser->m_bufferEnd;

    parser->m_eventPtr = parser->m_bufferPtr;
    parser->m_eventEndPtr = parser->m_bufferPtr;
    return result;
  }
#endif  /* not defined XML_CONTEXT_BYTES */
  else {
    void *buff = XML_GetBuffer(parser, len);
    if (buff == NULL)
      return XML_STATUS_ERROR;
................................................................................

enum XML_Status XMLCALL
XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
{
  const char *start;
  enum XML_Status result = XML_STATUS_OK;

  if (parser == NULL)
    return XML_STATUS_ERROR;
  switch (parser->m_parsingStatus.parsing) {
  case XML_SUSPENDED:
    parser->m_errorCode = XML_ERROR_SUSPENDED;
    return XML_STATUS_ERROR;
  case XML_FINISHED:
    parser->m_errorCode = XML_ERROR_FINISHED;
    return XML_STATUS_ERROR;
  case XML_INITIALIZED:
    if (parser->m_parentParser == NULL && !startParsing(parser)) {
      parser->m_errorCode = XML_ERROR_NO_MEMORY;
      return XML_STATUS_ERROR;
    }
  default:
    parser->m_parsingStatus.parsing = XML_PARSING;
  }

  start = parser->m_bufferPtr;
  parser->m_positionPtr = start;
  parser->m_bufferEnd += len;
  parser->m_parseEndPtr = parser->m_bufferEnd;
  parser->m_parseEndByteIndex += len;
  parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;


  parser->m_errorCode = parser->m_processor(parser, start, parser->m_parseEndPtr, &parser->m_bufferPtr);

  if (parser->m_errorCode != XML_ERROR_NONE) {
    parser->m_eventEndPtr = parser->m_eventPtr;
    parser->m_processor = errorProcessor;
    return XML_STATUS_ERROR;
  }
  else {
    switch (parser->m_parsingStatus.parsing) {
    case XML_SUSPENDED:
      result = XML_STATUS_SUSPENDED;
      break;
    case XML_INITIALIZED:
    case XML_PARSING:
      if (isFinal) {
        parser->m_parsingStatus.parsing = XML_FINISHED;
        return result;
      }
    default: ;  /* should not happen */
    }
  }

  XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position);
  parser->m_positionPtr = parser->m_bufferPtr;
  return result;
}

void * XMLCALL
XML_GetBuffer(XML_Parser parser, int len)
{
  if (parser == NULL)
    return NULL;
  if (len < 0) {
    parser->m_errorCode = XML_ERROR_NO_MEMORY;
    return NULL;
  }
  switch (parser->m_parsingStatus.parsing) {
  case XML_SUSPENDED:
    parser->m_errorCode = XML_ERROR_SUSPENDED;
    return NULL;
  case XML_FINISHED:
    parser->m_errorCode = XML_ERROR_FINISHED;
    return NULL;
  default: ;
  }

  if (len > parser->m_bufferLim - parser->m_bufferEnd) {


#ifdef XML_CONTEXT_BYTES
    int keep;
#endif  /* defined XML_CONTEXT_BYTES */
    /* Do not invoke signed arithmetic overflow: */
    int neededSize = (int) ((unsigned)len + (unsigned)(parser->m_bufferEnd - parser->m_bufferPtr));
    if (neededSize < 0) {
      parser->m_errorCode = XML_ERROR_NO_MEMORY;
      return NULL;
    }
#ifdef XML_CONTEXT_BYTES
    keep = (int)(parser->m_bufferPtr - parser->m_buffer);
    if (keep > XML_CONTEXT_BYTES)
      keep = XML_CONTEXT_BYTES;
    neededSize += keep;
#endif  /* defined XML_CONTEXT_BYTES */
    if (neededSize  <= parser->m_bufferLim - parser->m_buffer) {
#ifdef XML_CONTEXT_BYTES
      if (keep < parser->m_bufferPtr - parser->m_buffer) {
        int offset = (int)(parser->m_bufferPtr - parser->m_buffer) - keep;
        memmove(parser->m_buffer, &parser->m_buffer[offset], parser->m_bufferEnd - parser->m_bufferPtr + keep);
        parser->m_bufferEnd -= offset;
        parser->m_bufferPtr -= offset;
      }
#else
      memmove(parser->m_buffer, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr);
      parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr);
      parser->m_bufferPtr = parser->m_buffer;
#endif  /* not defined XML_CONTEXT_BYTES */
    }
    else {
      char *newBuf;
      int bufferSize = (int)(parser->m_bufferLim - parser->m_bufferPtr);
      if (bufferSize == 0)
        bufferSize = INIT_BUFFER_SIZE;
      do {
        /* Do not invoke signed arithmetic overflow: */
        bufferSize = (int) (2U * (unsigned) bufferSize);
      } while (bufferSize < neededSize && bufferSize > 0);
      if (bufferSize <= 0) {
        parser->m_errorCode = XML_ERROR_NO_MEMORY;
        return NULL;
      }
      newBuf = (char *)MALLOC(parser, bufferSize);
      if (newBuf == 0) {
        parser->m_errorCode = XML_ERROR_NO_MEMORY;
        return NULL;
      }
      parser->m_bufferLim = newBuf + bufferSize;
#ifdef XML_CONTEXT_BYTES
      if (parser->m_bufferPtr) {
        int keep = (int)(parser->m_bufferPtr - parser->m_buffer);
        if (keep > XML_CONTEXT_BYTES)
          keep = XML_CONTEXT_BYTES;

        memcpy(newBuf, &parser->m_bufferPtr[-keep], parser->m_bufferEnd - parser->m_bufferPtr + keep);
        FREE(parser, parser->m_buffer);
        parser->m_buffer = newBuf;


        parser->m_bufferEnd = parser->m_buffer + (parser->m_bufferEnd - parser->m_bufferPtr) + keep;
        parser->m_bufferPtr = parser->m_buffer + keep;
      }
      else {
        parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr);

        parser->m_bufferPtr = parser->m_buffer = newBuf;
      }
#else
      if (parser->m_bufferPtr) {

        memcpy(newBuf, parser->m_bufferPtr, parser->m_bufferEnd - parser->m_bufferPtr);
        FREE(parser, parser->m_buffer);
      }
      parser->m_bufferEnd = newBuf + (parser->m_bufferEnd - parser->m_bufferPtr);

      parser->m_bufferPtr = parser->m_buffer = newBuf;
#endif  /* not defined XML_CONTEXT_BYTES */
    }
    parser->m_eventPtr = parser->m_eventEndPtr = NULL;
    parser->m_positionPtr = NULL;
  }
  return parser->m_bufferEnd;
}

enum XML_Status XMLCALL
XML_StopParser(XML_Parser parser, XML_Bool resumable)
{
  if (parser == NULL)
    return XML_STATUS_ERROR;
  switch (parser->m_parsingStatus.parsing) {
  case XML_SUSPENDED:
    if (resumable) {
      parser->m_errorCode = XML_ERROR_SUSPENDED;
      return XML_STATUS_ERROR;
    }
    parser->m_parsingStatus.parsing = XML_FINISHED;
    break;
  case XML_FINISHED:
    parser->m_errorCode = XML_ERROR_FINISHED;
    return XML_STATUS_ERROR;
  default:
    if (resumable) {
#ifdef XML_DTD
      if (parser->m_isParamEntity) {
        parser->m_errorCode = XML_ERROR_SUSPEND_PE;
        return XML_STATUS_ERROR;
      }
#endif
      parser->m_parsingStatus.parsing = XML_SUSPENDED;
    }
    else
      parser->m_parsingStatus.parsing = XML_FINISHED;
  }
  return XML_STATUS_OK;
}

enum XML_Status XMLCALL
XML_ResumeParser(XML_Parser parser)
{
  enum XML_Status result = XML_STATUS_OK;

  if (parser == NULL)
    return XML_STATUS_ERROR;
  if (parser->m_parsingStatus.parsing != XML_SUSPENDED) {
    parser->m_errorCode = XML_ERROR_NOT_SUSPENDED;
    return XML_STATUS_ERROR;
  }
  parser->m_parsingStatus.parsing = XML_PARSING;


  parser->m_errorCode = parser->m_processor(parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);

  if (parser->m_errorCode != XML_ERROR_NONE) {
    parser->m_eventEndPtr = parser->m_eventPtr;
    parser->m_processor = errorProcessor;
    return XML_STATUS_ERROR;
  }
  else {
    switch (parser->m_parsingStatus.parsing) {
    case XML_SUSPENDED:
      result = XML_STATUS_SUSPENDED;
      break;
    case XML_INITIALIZED:
    case XML_PARSING:
      if (parser->m_parsingStatus.finalBuffer) {
        parser->m_parsingStatus.parsing = XML_FINISHED;
        return result;
      }
    default: ;
    }
  }

  XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_bufferPtr, &parser->m_position);
  parser->m_positionPtr = parser->m_bufferPtr;
  return result;
}

void XMLCALL
XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
{
  if (parser == NULL)
    return;
  assert(status != NULL);
  *status = parser->m_parsingStatus;
}

enum XML_Error XMLCALL
XML_GetErrorCode(XML_Parser parser)
{
  if (parser == NULL)
    return XML_ERROR_INVALID_ARGUMENT;
  return parser->m_errorCode;
}

XML_Index XMLCALL
XML_GetCurrentByteIndex(XML_Parser parser)
{
  if (parser == NULL)
    return -1;
  if (parser->m_eventPtr)
    return (XML_Index)(parser->m_parseEndByteIndex - (parser->m_parseEndPtr - parser->m_eventPtr));
  return -1;
}

int XMLCALL
XML_GetCurrentByteCount(XML_Parser parser)
{
  if (parser == NULL)
    return 0;
  if (parser->m_eventEndPtr && parser->m_eventPtr)
    return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
  return 0;
}

const char * XMLCALL
XML_GetInputContext(XML_Parser parser, int *offset, int *size)
{
#ifdef XML_CONTEXT_BYTES
  if (parser == NULL)
    return NULL;
  if (parser->m_eventPtr && parser->m_buffer) {
    if (offset != NULL)
      *offset = (int)(parser->m_eventPtr - parser->m_buffer);
    if (size != NULL)
      *size   = (int)(parser->m_bufferEnd - parser->m_buffer);
    return parser->m_buffer;
  }
#else
  (void)parser;
  (void)offset;
  (void)size;
#endif /* defined XML_CONTEXT_BYTES */
  return (char *) 0;
}

XML_Size XMLCALL
XML_GetCurrentLineNumber(XML_Parser parser)
{
  if (parser == NULL)
    return 0;
  if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position);
    parser->m_positionPtr = parser->m_eventPtr;
  }
  return parser->m_position.lineNumber + 1;
}

XML_Size XMLCALL
XML_GetCurrentColumnNumber(XML_Parser parser)
{
  if (parser == NULL)
    return 0;
  if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
    XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, parser->m_eventPtr, &parser->m_position);
    parser->m_positionPtr = parser->m_eventPtr;
  }
  return parser->m_position.columnNumber;
}

void XMLCALL
XML_FreeContentModel(XML_Parser parser, XML_Content *model)
{
  if (parser != NULL)
    FREE(parser, model);
}

void * XMLCALL
XML_MemMalloc(XML_Parser parser, size_t size)
{
  if (parser == NULL)
    return NULL;
  return MALLOC(parser, size);
}

void * XMLCALL
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
{
  if (parser == NULL)
    return NULL;
  return REALLOC(parser, ptr, size);
}

void XMLCALL
XML_MemFree(XML_Parser parser, void *ptr)
{
  if (parser != NULL)
    FREE(parser, ptr);
}

void XMLCALL
XML_DefaultCurrent(XML_Parser parser)
{
  if (parser == NULL)
    return;
  if (parser->m_defaultHandler) {
    if (parser->m_openInternalEntities)
      reportDefault(parser,
                    parser->m_internalEncoding,
                    parser->m_openInternalEntities->internalEventPtr,
                    parser->m_openInternalEntities->internalEventEndPtr);
    else

      reportDefault(parser, parser->m_encoding, parser->m_eventPtr, parser->m_eventEndPtr);
  }
}

const XML_LChar * XMLCALL
XML_ErrorString(enum XML_Error code)
{


  switch (code) {
  case XML_ERROR_NONE:
    return NULL;
  case XML_ERROR_NO_MEMORY:
    return XML_L("out of memory");
  case XML_ERROR_SYNTAX:
    return XML_L("syntax error");
  case XML_ERROR_NO_ELEMENTS:
    return XML_L("no element found");
  case XML_ERROR_INVALID_TOKEN:
    return XML_L("not well-formed (invalid token)");
  case XML_ERROR_UNCLOSED_TOKEN:
    return XML_L("unclosed token");
  case XML_ERROR_PARTIAL_CHAR:
    return XML_L("partial character");
  case XML_ERROR_TAG_MISMATCH:
    return XML_L("mismatched tag");
  case XML_ERROR_DUPLICATE_ATTRIBUTE:
    return XML_L("duplicate attribute");
  case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
    return XML_L("junk after document element");
  case XML_ERROR_PARAM_ENTITY_REF:
    return XML_L("illegal parameter entity reference");
  case XML_ERROR_UNDEFINED_ENTITY:
    return XML_L("undefined entity");
  case XML_ERROR_RECURSIVE_ENTITY_REF:
    return XML_L("recursive entity reference");
  case XML_ERROR_ASYNC_ENTITY:
    return XML_L("asynchronous entity");
  case XML_ERROR_BAD_CHAR_REF:
    return XML_L("reference to invalid character number");
  case XML_ERROR_BINARY_ENTITY_REF:
    return XML_L("reference to binary entity");
  case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
    return XML_L("reference to external entity in attribute");
  case XML_ERROR_MISPLACED_XML_PI:
    return XML_L("XML or text declaration not at start of entity");
  case XML_ERROR_UNKNOWN_ENCODING:
    return XML_L("unknown encoding");
  case XML_ERROR_INCORRECT_ENCODING:
    return XML_L("encoding specified in XML declaration is incorrect");
  case XML_ERROR_UNCLOSED_CDATA_SECTION:
    return XML_L("unclosed CDATA section");
  case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
    return XML_L("error in processing external entity reference");
  case XML_ERROR_NOT_STANDALONE:
    return XML_L("document is not standalone");
  case XML_ERROR_UNEXPECTED_STATE:
    return XML_L("unexpected parser state - please send a bug report");
  case XML_ERROR_ENTITY_DECLARED_IN_PE:
    return XML_L("entity declared in parameter entity");
  case XML_ERROR_FEATURE_REQUIRES_XML_DTD:
    return XML_L("requested feature requires XML_DTD support in Expat");
  case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:
    return XML_L("cannot change setting once parsing has begun");
  /* Added in 1.95.7. */
  case XML_ERROR_UNBOUND_PREFIX:
    return XML_L("unbound prefix");
  /* Added in 1.95.8. */
  case XML_ERROR_UNDECLARING_PREFIX:
    return XML_L("must not undeclare prefix");
  case XML_ERROR_INCOMPLETE_PE:
    return XML_L("incomplete markup in parameter entity");
  case XML_ERROR_XML_DECL:
    return XML_L("XML declaration not well-formed");
  case XML_ERROR_TEXT_DECL:
    return XML_L("text declaration not well-formed");
  case XML_ERROR_PUBLICID:
    return XML_L("illegal character(s) in public id");
  case XML_ERROR_SUSPENDED:
    return XML_L("parser suspended");
  case XML_ERROR_NOT_SUSPENDED:
    return XML_L("parser not suspended");
  case XML_ERROR_ABORTED:
    return XML_L("parsing aborted");
  case XML_ERROR_FINISHED:
    return XML_L("parsing finished");
  case XML_ERROR_SUSPEND_PE:
    return XML_L("cannot suspend in external parameter entity");
  /* Added in 2.0.0. */
  case XML_ERROR_RESERVED_PREFIX_XML:
    return XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name");
  case XML_ERROR_RESERVED_PREFIX_XMLNS:
    return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
  case XML_ERROR_RESERVED_NAMESPACE_URI:
    return XML_L("prefix must not be bound to one of the reserved namespace names");



  /* Added in 2.2.5. */
  case XML_ERROR_INVALID_ARGUMENT:  /* Constant added in 2.2.1, already */
    return XML_L("invalid argument");
  }
  return NULL;
}

const XML_LChar * XMLCALL
XML_ExpatVersion(void) {

  /* V1 is used to string-ize the version number. However, it would
................................................................................
    {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0},
#endif
#ifdef XML_NS
    {XML_FEATURE_NS,               XML_L("XML_NS"), 0},
#endif
#ifdef XML_LARGE_SIZE
    {XML_FEATURE_LARGE_SIZE,       XML_L("XML_LARGE_SIZE"), 0},
#endif
#ifdef XML_ATTR_INFO
    {XML_FEATURE_ATTR_INFO,        XML_L("XML_ATTR_INFO"), 0},
#endif
    {XML_FEATURE_END,              NULL, 0}
  };

  return features;
}

/* Initially tag->rawName always points into the parse buffer;
................................................................................
   for those TAG instances opened while the current parse buffer was
   processed, and not yet closed, we need to store tag->rawName in a more
   permanent location, since the parse buffer is about to be discarded.
*/
static XML_Bool
storeRawNames(XML_Parser parser)
{
  TAG *tag = parser->m_tagStack;
  while (tag) {
    int bufSize;
    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
    char *rawNameBuf = tag->buf + nameLen;
    /* Stop if already stored.  Since m_tagStack is a stack, we can stop
       at the first entry that has already been copied; everything
       below it in the stack is already been accounted for in a
       previous call to this function.
    */
    if (tag->rawName == rawNameBuf)
      break;
    /* For re-use purposes we need to ensure that the
       size of tag->buf is a multiple of sizeof(XML_Char).
    */
    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
    if (bufSize > tag->bufEnd - tag->buf) {
      char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
      if (temp == NULL)
        return XML_FALSE;
      /* if tag->name.str points to tag->buf (only when namespace
         processing is off) then we have to update it
      */
      if (tag->name.str == (XML_Char *)tag->buf)
        tag->name.str = (XML_Char *)temp;
................................................................................

static enum XML_Error PTRCALL
contentProcessor(XML_Parser parser,
                 const char *start,
                 const char *end,
                 const char **endPtr)
{
  enum XML_Error result = doContent(parser, 0, parser->m_encoding, start, end,
                                    endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  if (result == XML_ERROR_NONE) {
    if (!storeRawNames(parser))
      return XML_ERROR_NO_MEMORY;
  }
  return result;
}

................................................................................
                            const char *start,
                            const char *end,
                            const char **endPtr)
{
  enum XML_Error result = initializeEncoding(parser);
  if (result != XML_ERROR_NONE)
    return result;
  parser->m_processor = externalEntityInitProcessor2;
  return externalEntityInitProcessor2(parser, start, end, endPtr);
}

static enum XML_Error PTRCALL
externalEntityInitProcessor2(XML_Parser parser,
                             const char *start,
                             const char *end,
                             const char **endPtr)
{
  const char *next = start; /* XmlContentTok doesn't always set the last arg */
  int tok = XmlContentTok(parser->m_encoding, start, end, &next);
  switch (tok) {
  case XML_TOK_BOM:
    /* If we are at the end of the buffer, this would cause the next stage,
       i.e. externalEntityInitProcessor3, to pass control directly to
       doContent (by detecting XML_TOK_NONE) without processing any xml text
       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
    */
    if (next == end && !parser->m_parsingStatus.finalBuffer) {
      *endPtr = next;
      return XML_ERROR_NONE;
    }
    start = next;
    break;
  case XML_TOK_PARTIAL:
    if (!parser->m_parsingStatus.finalBuffer) {
      *endPtr = start;
      return XML_ERROR_NONE;
    }
    parser->m_eventPtr = start;
    return XML_ERROR_UNCLOSED_TOKEN;
  case XML_TOK_PARTIAL_CHAR:
    if (!parser->m_parsingStatus.finalBuffer) {
      *endPtr = start;
      return XML_ERROR_NONE;
    }
    parser->m_eventPtr = start;
    return XML_ERROR_PARTIAL_CHAR;
  }
  parser->m_processor = externalEntityInitProcessor3;
  return externalEntityInitProcessor3(parser, start, end, endPtr);
}

static enum XML_Error PTRCALL
externalEntityInitProcessor3(XML_Parser parser,
                             const char *start,
                             const char *end,
                             const char **endPtr)
{
  int tok;
  const char *next = start; /* XmlContentTok doesn't always set the last arg */
  parser->m_eventPtr = start;
  tok = XmlContentTok(parser->m_encoding, start, end, &next);
  parser->m_eventEndPtr = next;

  switch (tok) {
  case XML_TOK_XML_DECL:
    {
      enum XML_Error result;
      result = processXmlDecl(parser, 1, start, next);
      if (result != XML_ERROR_NONE)
        return result;
      switch (parser->m_parsingStatus.parsing) {
      case XML_SUSPENDED:
        *endPtr = next;
        return XML_ERROR_NONE;
      case XML_FINISHED:
        return XML_ERROR_ABORTED;
      default:
        start = next;
      }
    }
    break;
  case XML_TOK_PARTIAL:
    if (!parser->m_parsingStatus.finalBuffer) {
      *endPtr = start;
      return XML_ERROR_NONE;
    }
    return XML_ERROR_UNCLOSED_TOKEN;
  case XML_TOK_PARTIAL_CHAR:
    if (!parser->m_parsingStatus.finalBuffer) {
      *endPtr = start;
      return XML_ERROR_NONE;
    }
    return XML_ERROR_PARTIAL_CHAR;
  }
  parser->m_processor = externalEntityContentProcessor;
  parser->m_tagLevel = 1;
  return externalEntityContentProcessor(parser, start, end, endPtr);
}

static enum XML_Error PTRCALL
externalEntityContentProcessor(XML_Parser parser,
                               const char *start,
                               const char *end,
                               const char **endPtr)
{
  enum XML_Error result = doContent(parser, 1, parser->m_encoding, start, end,
                                    endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  if (result == XML_ERROR_NONE) {
    if (!storeRawNames(parser))
      return XML_ERROR_NO_MEMORY;
  }
  return result;
}

................................................................................
          const ENCODING *enc,
          const char *s,
          const char *end,
          const char **nextPtr,
          XML_Bool haveMore)
{
  /* save one level of indirection */
  DTD * const dtd = parser->m_dtd;

  const char **eventPP;
  const char **eventEndPP;
  if (enc == parser->m_encoding) {
    eventPP = &parser->m_eventPtr;
    eventEndPP = &parser->m_eventEndPtr;
  }
  else {
    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
    eventEndPP = &(parser->m_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 (haveMore) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      *eventEndPP = end;
      if (parser->m_characterDataHandler) {
        XML_Char c = 0xA;
        parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
      }
      else if (parser->m_defaultHandler)
        reportDefault(parser, enc, s, end);
      /* We are at the end of the final buffer, should we check for
         XML_SUSPENDED, XML_FINISHED?
      */
      if (startTagLevel == 0)
        return XML_ERROR_NO_ELEMENTS;
      if (parser->m_tagLevel != startTagLevel)
        return XML_ERROR_ASYNC_ENTITY;
      *nextPtr = end;
      return XML_ERROR_NONE;
    case XML_TOK_NONE:
      if (haveMore) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      if (startTagLevel > 0) {
        if (parser->m_tagLevel != startTagLevel)
          return XML_ERROR_ASYNC_ENTITY;
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      return XML_ERROR_NO_ELEMENTS;
    case XML_TOK_INVALID:
      *eventPP = next;
................................................................................
      {
        const XML_Char *name;
        ENTITY *entity;
        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
                                              s + enc->minBytesPerChar,
                                              next - enc->minBytesPerChar);
        if (ch) {
          if (parser->m_characterDataHandler)
            parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
          else if (parser->m_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(parser, &dtd->generalEntities, name, 0);
        poolDiscard(&dtd->pool);
        /* First, determine if a check for an existing declaration is needed;
           if yes, check that the entity exists, and that it is internal,
           otherwise call the skipped entity or default handler.
        */
        if (!dtd->hasParamEntityRefs || dtd->standalone) {
          if (!entity)
            return XML_ERROR_UNDEFINED_ENTITY;
          else if (!entity->is_internal)
            return XML_ERROR_ENTITY_DECLARED_IN_PE;
        }
        else if (!entity) {
          if (parser->m_skippedEntityHandler)
            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
          else if (parser->m_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->textPtr) {
          enum XML_Error result;
          if (!parser->m_defaultExpandInternalEntities) {
            if (parser->m_skippedEntityHandler)
              parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name, 0);
            else if (parser->m_defaultHandler)
              reportDefault(parser, enc, s, next);
            break;
          }
          result = processInternalEntity(parser, entity, XML_FALSE);
          if (result != XML_ERROR_NONE)
            return result;
        }
        else if (parser->m_externalEntityRefHandler) {
          const XML_Char *context;
          entity->open = XML_TRUE;
          context = getContext(parser);
          entity->open = XML_FALSE;
          if (!context)
            return XML_ERROR_NO_MEMORY;
          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
                                        context,
                                        entity->base,
                                        entity->systemId,
                                        entity->publicId))
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
          poolDiscard(&parser->m_tempPool);
        }
        else if (parser->m_defaultHandler)
          reportDefault(parser, enc, s, next);
        break;
      }
    case XML_TOK_START_TAG_NO_ATTS:
      /* fall through */
    case XML_TOK_START_TAG_WITH_ATTS:
      {
        TAG *tag;
        enum XML_Error result;
        XML_Char *toPtr;
        if (parser->m_freeTagList) {
          tag = parser->m_freeTagList;
          parser->m_freeTagList = parser->m_freeTagList->parent;
        }
        else {
          tag = (TAG *)MALLOC(parser, sizeof(TAG));
          if (!tag)
            return XML_ERROR_NO_MEMORY;
          tag->buf = (char *)MALLOC(parser, INIT_TAG_BUF_SIZE);
          if (!tag->buf) {
            FREE(parser, tag);
            return XML_ERROR_NO_MEMORY;
          }
          tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
        }
        tag->bindings = NULL;
        tag->parent = parser->m_tagStack;
        parser->m_tagStack = tag;
        tag->name.localPart = NULL;
        tag->name.prefix = NULL;
        tag->rawName = s + enc->minBytesPerChar;
        tag->rawNameLength = XmlNameLength(enc, tag->rawName);
        ++parser->m_tagLevel;
        {
          const char *rawNameEnd = tag->rawName + tag->rawNameLength;
          const char *fromPtr = tag->rawName;
          toPtr = (XML_Char *)tag->buf;
          for (;;) {
            int bufSize;
            int convLen;
            const enum XML_Convert_Result convert_res = XmlConvert(enc,
                       &fromPtr, rawNameEnd,
                       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
            convLen = (int)(toPtr - (XML_Char *)tag->buf);
            if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
              tag->name.strLen = convLen;
              break;
            }
            bufSize = (int)(tag->bufEnd - tag->buf) << 1;
            {
              char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
              if (temp == NULL)
                return XML_ERROR_NO_MEMORY;
              tag->buf = temp;
              tag->bufEnd = temp + bufSize;
              toPtr = (XML_Char *)temp + convLen;
            }
          }
        }
        tag->name.str = (XML_Char *)tag->buf;
        *toPtr = XML_T('\0');
        result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
        if (result)
          return result;
        if (parser->m_startElementHandler)
          parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
                              (const XML_Char **)parser->m_atts);
        else if (parser->m_defaultHandler)
          reportDefault(parser, enc, s, next);
        poolClear(&parser->m_tempPool);
        break;
      }
    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
      /* fall through */
    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
      {
        const char *rawName = s + enc->minBytesPerChar;
        enum XML_Error result;
        BINDING *bindings = NULL;
        XML_Bool noElmHandlers = XML_TRUE;
        TAG_NAME name;
        name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
                                   rawName + XmlNameLength(enc, rawName));
        if (!name.str)
          return XML_ERROR_NO_MEMORY;
        poolFinish(&parser->m_tempPool);
        result = storeAtts(parser, enc, s, &name, &bindings);
        if (result != XML_ERROR_NONE) {
          freeBindings(parser, bindings);
          return result;
        }
        poolFinish(&parser->m_tempPool);
        if (parser->m_startElementHandler) {
          parser->m_startElementHandler(parser->m_handlerArg, name.str, (const XML_Char **)parser->m_atts);
          noElmHandlers = XML_FALSE;
        }
        if (parser->m_endElementHandler) {
          if (parser->m_startElementHandler)
            *eventPP = *eventEndPP;
          parser->m_endElementHandler(parser->m_handlerArg, name.str);
          noElmHandlers = XML_FALSE;
        }
        if (noElmHandlers && parser->m_defaultHandler)
          reportDefault(parser, enc, s, next);
        poolClear(&parser->m_tempPool);






        freeBindings(parser, bindings);

      }

      if ((parser->m_tagLevel == 0) &&
          !((parser->m_parsingStatus.parsing == XML_FINISHED) || (parser->m_parsingStatus.parsing == XML_SUSPENDED))) {
        return epilogProcessor(parser, next, end, nextPtr);
      }
      break;
    case XML_TOK_END_TAG:
      if (parser->m_tagLevel == startTagLevel)
        return XML_ERROR_ASYNC_ENTITY;
      else {
        int len;
        const char *rawName;
        TAG *tag = parser->m_tagStack;
        parser->m_tagStack = tag->parent;
        tag->parent = parser->m_freeTagList;
        parser->m_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;
        }
        --parser->m_tagLevel;
        if (parser->m_endElementHandler) {
          const XML_Char *localPart;
          const XML_Char *prefix;
          XML_Char *uri;
          localPart = tag->name.localPart;
          if (parser->m_ns && localPart) {
            /* localPart and prefix may have been overwritten in
               tag->name.str, since this points to the binding->uri
               buffer which gets re-used; so we have to add them again
            */
            uri = (XML_Char *)tag->name.str + tag->name.uriLen;
            /* don't need to check for space - already done in storeAtts() */
            while (*localPart) *uri++ = *localPart++;
            prefix = (XML_Char *)tag->name.prefix;
            if (parser->m_ns_triplets && prefix) {
              *uri++ = parser->m_namespaceSeparator;
              while (*prefix) *uri++ = *prefix++;
             }
            *uri = XML_T('\0');
          }
          parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
        }
        else if (parser->m_defaultHandler)
          reportDefault(parser, enc, s, next);
        while (tag->bindings) {
          BINDING *b = tag->bindings;
          if (parser->m_endNamespaceDeclHandler)
            parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
          tag->bindings = tag->bindings->nextTagBinding;
          b->nextTagBinding = parser->m_freeBindingList;
          parser->m_freeBindingList = b;
          b->prefix->binding = b->prevPrefixBinding;
        }
        if (parser->m_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 (parser->m_characterDataHandler) {
          XML_Char buf[XML_ENCODE_MAX];
          parser->m_characterDataHandler(parser->m_handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
        }
        else if (parser->m_defaultHandler)
          reportDefault(parser, enc, s, next);
      }
      break;
    case XML_TOK_XML_DECL:
      return XML_ERROR_MISPLACED_XML_PI;
    case XML_TOK_DATA_NEWLINE:
      if (parser->m_characterDataHandler) {
        XML_Char c = 0xA;
        parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
      }
      else if (parser->m_defaultHandler)
        reportDefault(parser, enc, s, next);
      break;
    case XML_TOK_CDATA_SECT_OPEN:
      {
        enum XML_Error result;
        if (parser->m_startCdataSectionHandler)
          parser->m_startCdataSectionHandler(parser->m_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 (parser->m_characterDataHandler)
          parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0);
#endif
        else if (parser->m_defaultHandler)
          reportDefault(parser, enc, s, next);
        result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore);
        if (result != XML_ERROR_NONE)
          return result;
        else if (!next) {
          parser->m_processor = cdataSectionProcessor;
          return result;
        }
      }
      break;
    case XML_TOK_TRAILING_RSQB:
      if (haveMore) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      if (parser->m_characterDataHandler) {
        if (MUST_CONVERT(enc, s)) {
          ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
          parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
                               (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
        }
        else
          parser->m_characterDataHandler(parser->m_handlerArg,
                               (XML_Char *)s,
                               (int)((XML_Char *)end - (XML_Char *)s));
      }
      else if (parser->m_defaultHandler)
        reportDefault(parser, enc, s, end);
      /* We are at the end of the final buffer, should we check for
         XML_SUSPENDED, XML_FINISHED?
      */
      if (startTagLevel == 0) {
        *eventPP = end;
        return XML_ERROR_NO_ELEMENTS;
      }
      if (parser->m_tagLevel != startTagLevel) {
        *eventPP = end;
        return XML_ERROR_ASYNC_ENTITY;
      }
      *nextPtr = end;
      return XML_ERROR_NONE;
    case XML_TOK_DATA_CHARS:
      {
        XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
        if (charDataHandler) {
          if (MUST_CONVERT(enc, s)) {
            for (;;) {
              ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
              *eventEndPP = s;
              charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
                              (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
                break;
              *eventPP = s;
            }
          }
          else
            charDataHandler(parser->m_handlerArg,
                            (XML_Char *)s,
                            (int)((XML_Char *)next - (XML_Char *)s));
        }
        else if (parser->m_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:
      /* All of the tokens produced by XmlContentTok() have their own
       * explicit cases, so this default is not strictly necessary.
       * However it is a useful safety net, so we retain the code and
       * simply exclude it from the coverage tests.
       *
       * LCOV_EXCL_START
       */
      if (parser->m_defaultHandler)
        reportDefault(parser, enc, s, next);
      break;
      /* LCOV_EXCL_STOP */
    }
    *eventPP = s = next;

    switch (parser->m_parsingStatus.parsing) {
    case XML_SUSPENDED:
      *nextPtr = next;
      return XML_ERROR_NONE;
    case XML_FINISHED:
      return XML_ERROR_ABORTED;
    default: ;
    }
  }
  /* not reached */
}

/* This function does not call free() on the allocated memory, merely
 * moving it to the parser's m_freeBindingList where it can be freed or
 * reused as appropriate.
 */
static void
freeBindings(XML_Parser parser, BINDING *bindings)
{
  while (bindings) {
    BINDING *b = bindings;

    /* m_startNamespaceDeclHandler will have been called for this
     * binding in addBindings(), so call the end handler now.
     */
    if (parser->m_endNamespaceDeclHandler)
        parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);

    bindings = bindings->nextTagBinding;
    b->nextTagBinding = parser->m_freeBindingList;
    parser->m_freeBindingList = b;
    b->prefix->binding = b->prevPrefixBinding;
  }
}

/* Precondition: all arguments must be non-NULL;
   Purpose:
   - normalize attributes
   - check attributes for well-formedness
   - generate namespace aware attribute names (URI, prefix)
   - build list of attributes for startElementHandler
................................................................................
   - generate namespace aware element name (URI, prefix)
*/
static enum XML_Error
storeAtts(XML_Parser parser, const ENCODING *enc,
          const char *attStr, TAG_NAME *tagNamePtr,
          BINDING **bindingsPtr)
{
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  ELEMENT_TYPE *elementType;
  int nDefaultAtts;
  const XML_Char **appAtts;   /* the attribute list for the application */
  int attIndex = 0;
  int prefixLen;
  int i;
  int n;
  XML_Char *uri;
  int nPrefixes = 0;
  BINDING *binding;
  const XML_Char *localPart;

  /* lookup the element type name */
  elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
  if (!elementType) {
    const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
    if (!name)
      return XML_ERROR_NO_MEMORY;
    elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
                                         sizeof(ELEMENT_TYPE));
    if (!elementType)
      return XML_ERROR_NO_MEMORY;
    if (parser->m_ns && !setElementTypePrefix(parser, elementType))
      return XML_ERROR_NO_MEMORY;
  }
  nDefaultAtts = elementType->nDefaultAtts;

  /* get the attributes from the tokenizer */
  n = XmlGetAttributes(enc, attStr, parser->m_attsSize, parser->m_atts);
  if (n + nDefaultAtts > parser->m_attsSize) {
    int oldAttsSize = parser->m_attsSize;
    ATTRIBUTE *temp;
#ifdef XML_ATTR_INFO
    XML_AttrInfo *temp2;
#endif
    parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;

    temp = (ATTRIBUTE *)REALLOC(parser, (void *)parser->m_atts, parser->m_attsSize * sizeof(ATTRIBUTE));
    if (temp == NULL) {
      parser->m_attsSize = oldAttsSize;
      return XML_ERROR_NO_MEMORY;
    }
    parser->m_atts = temp;
#ifdef XML_ATTR_INFO
    temp2 = (XML_AttrInfo *)REALLOC(parser, (void *)parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo));
    if (temp2 == NULL) {
      parser->m_attsSize = oldAttsSize;
      return XML_ERROR_NO_MEMORY;
    }
    parser->m_attInfo = temp2;
#endif
    if (n > oldAttsSize)
      XmlGetAttributes(enc, attStr, n, parser->m_atts);
  }

  appAtts = (const XML_Char **)parser->m_atts;
  for (i = 0; i < n; i++) {
    ATTRIBUTE *currAtt = &parser->m_atts[i];
#ifdef XML_ATTR_INFO
    XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
#endif
    /* add the name and value to the attribute list */
    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, currAtt->name,

                                         currAtt->name
                                         + XmlNameLength(enc, currAtt->name));
    if (!attId)
      return XML_ERROR_NO_MEMORY;
#ifdef XML_ATTR_INFO
    currAttInfo->nameStart = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->name);
    currAttInfo->nameEnd = currAttInfo->nameStart +
                           XmlNameLength(enc, currAtt->name);
    currAttInfo->valueStart = parser->m_parseEndByteIndex -
                            (parser->m_parseEndPtr - currAtt->valuePtr);
    currAttInfo->valueEnd = parser->m_parseEndByteIndex - (parser->m_parseEndPtr - currAtt->valueEnd);
#endif
    /* Detect duplicate attributes by their QNames. This does not work when
       namespace processing is turned on and different prefixes for the same
       namespace are used. For this case we have a check further down.
    */
    if ((attId->name)[-1]) {
      if (enc == parser->m_encoding)
        parser->m_eventPtr = parser->m_atts[i].name;
      return XML_ERROR_DUPLICATE_ATTRIBUTE;
    }
    (attId->name)[-1] = 1;
    appAtts[attIndex++] = attId->name;
    if (!parser->m_atts[i].normalized) {
      enum XML_Error result;
      XML_Bool isCdata = XML_TRUE;

      /* figure out whether declared as other than CDATA */
      if (attId->maybeTokenized) {
        int j;
        for (j = 0; j < nDefaultAtts; j++) {
................................................................................
            break;
          }
        }
      }

      /* normalize the attribute value */
      result = storeAttributeValue(parser, enc, isCdata,
                                   parser->m_atts[i].valuePtr, parser->m_atts[i].valueEnd,
                                   &parser->m_tempPool);
      if (result)
        return result;
      appAtts[attIndex] = poolStart(&parser->m_tempPool);
      poolFinish(&parser->m_tempPool);
    }
    else {
      /* the value did not need normalizing */
      appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc, parser->m_atts[i].valuePtr,
                                          parser->m_atts[i].valueEnd);
      if (appAtts[attIndex] == 0)
        return XML_ERROR_NO_MEMORY;
      poolFinish(&parser->m_tempPool);
    }
    /* handle prefixed attribute names */
    if (attId->prefix) {
      if (attId->xmlns) {
        /* deal with namespace declarations here */
        enum XML_Error result = addBinding(parser, attId->prefix, attId,
                                           appAtts[attIndex], bindingsPtr);
................................................................................
      }
    }
    else
      attIndex++;
  }

  /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
  parser->m_nSpecifiedAtts = attIndex;
  if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
    for (i = 0; i < attIndex; i += 2)
      if (appAtts[i] == elementType->idAtt->name) {
        parser->m_idAttIndex = i;
        break;
      }
  }
  else
    parser->m_idAttIndex = -1;

  /* do attribute defaulting */
  for (i = 0; i < nDefaultAtts; i++) {
    const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
    if (!(da->id->name)[-1] && da->value) {
      if (da->id->prefix) {
        if (da->id->xmlns) {
................................................................................
  appAtts[attIndex] = 0;

  /* expand prefixed attribute names, check for duplicates,
     and clear flags that say whether attributes were specified */
  i = 0;
  if (nPrefixes) {
    int j;  /* hash table index */
    unsigned long version = parser->m_nsAttsVersion;
    int nsAttsSize = (int)1 << parser->m_nsAttsPower;
    unsigned char oldNsAttsPower = parser->m_nsAttsPower;
    /* size of hash table must be at least 2 * (# of prefixed attributes) */

    if ((nPrefixes << 1) >> parser->m_nsAttsPower) {  /* true for m_nsAttsPower = 0 */
      NS_ATT *temp;
      /* hash table size must also be a power of 2 and >= 8 */
      while (nPrefixes >> parser->m_nsAttsPower++);
      if (parser->m_nsAttsPower < 3)
        parser->m_nsAttsPower = 3;
      nsAttsSize = (int)1 << parser->m_nsAttsPower;
      temp = (NS_ATT *)REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT));
      if (!temp) {
        /* Restore actual size of memory in m_nsAtts */
        parser->m_nsAttsPower = oldNsAttsPower;
        return XML_ERROR_NO_MEMORY;
      }
      parser->m_nsAtts = temp;
      version = 0;  /* force re-initialization of m_nsAtts hash table */
    }
    /* using a version flag saves us from initializing m_nsAtts every time */
    if (!version) {  /* initialize version flags when version wraps around */
      version = INIT_ATTS_VERSION;
      for (j = nsAttsSize; j != 0; )
        parser->m_nsAtts[--j].version = version;
    }
    parser->m_nsAttsVersion = --version;

    /* expand prefixed names and check for duplicates */
    for (; i < attIndex; i += 2) {
      const XML_Char *s = appAtts[i];
      if (s[-1] == 2) {  /* prefixed */
        ATTRIBUTE_ID *id;
        const BINDING *b;
        unsigned long uriHash;
        struct siphash sip_state;
        struct sipkey sip_key;

        copy_salt_to_sipkey(parser, &sip_key);
        sip24_init(&sip_state, &sip_key);

        ((XML_Char *)s)[-1] = 0;  /* clear flag */
        id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
        if (!id || !id->prefix) {
          /* This code is walking through the appAtts array, dealing
           * with (in this case) a prefixed attribute name.  To be in
           * the array, the attribute must have already been bound, so
           * has to have passed through the hash table lookup once
           * already.  That implies that an entry for it already
           * exists, so the lookup above will return a pointer to
           * already allocated memory.  There is no opportunaity for
           * the allocator to fail, so the condition above cannot be
           * fulfilled.
           *
           * Since it is difficult to be certain that the above
           * analysis is complete, we retain the test and merely
           * remove the code from coverage tests.
           */
          return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
        }
        b = id->prefix->binding;
        if (!b)
          return XML_ERROR_UNBOUND_PREFIX;


        for (j = 0; j < b->uriLen; j++) {
          const XML_Char c = b->uri[j];
          if (!poolAppendChar(&parser->m_tempPool, c))
            return XML_ERROR_NO_MEMORY;

        }

        sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));

        while (*s++ != XML_T(ASCII_COLON))
          ;

        sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));

        do {  /* copies null terminator */

          if (!poolAppendChar(&parser->m_tempPool, *s))
            return XML_ERROR_NO_MEMORY;

        } while (*s++);

        uriHash = (unsigned long)sip24_final(&sip_state);

        { /* Check hash table for duplicate of expanded name (uriName).
             Derived from code in lookup(parser, HASH_TABLE *table, ...).
          */
          unsigned char step = 0;
          unsigned long mask = nsAttsSize - 1;
          j = uriHash & mask;  /* index into hash table */
          while (parser->m_nsAtts[j].version == version) {
            /* for speed we compare stored hash values first */
            if (uriHash == parser->m_nsAtts[j].hash) {
              const XML_Char *s1 = poolStart(&parser->m_tempPool);
              const XML_Char *s2 = parser->m_nsAtts[j].uriName;
              /* s1 is null terminated, but not s2 */
              for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
              if (*s1 == 0)
                return XML_ERROR_DUPLICATE_ATTRIBUTE;
            }
            if (!step)
              step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower);
            j < step ? (j += nsAttsSize - step) : (j -= step);
          }
        }

        if (parser->m_ns_triplets) {  /* append namespace separator and prefix */
          parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
          s = b->prefix->name;
          do {
            if (!poolAppendChar(&parser->m_tempPool, *s))
              return XML_ERROR_NO_MEMORY;
          } while (*s++);
        }

        /* store expanded name in attribute list */
        s = poolStart(&parser->m_tempPool);
        poolFinish(&parser->m_tempPool);
        appAtts[i] = s;

        /* fill empty slot with new version, uriName and hash value */
        parser->m_nsAtts[j].version = version;
        parser->m_nsAtts[j].hash = uriHash;
        parser->m_nsAtts[j].uriName = s;

        if (!--nPrefixes) {
          i += 2;
          break;
        }
      }
      else  /* not prefixed */
................................................................................
  }
  /* clear flags for the remaining attributes */
  for (; i < attIndex; i += 2)
    ((XML_Char *)(appAtts[i]))[-1] = 0;
  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
    binding->attId->name[-1] = 0;

  if (!parser->m_ns)
    return XML_ERROR_NONE;

  /* expand the element type name */
  if (elementType->prefix) {
    binding = elementType->prefix->binding;
    if (!binding)
      return XML_ERROR_UNBOUND_PREFIX;
................................................................................
  else if (dtd->defaultPrefix.binding) {
    binding = dtd->defaultPrefix.binding;
    localPart = tagNamePtr->str;
  }
  else
    return XML_ERROR_NONE;
  prefixLen = 0;
  if (parser->m_ns_triplets && binding->prefix->name) {
    for (; binding->prefix->name[prefixLen++];)
      ;  /* prefixLen includes null terminator */
  }
  tagNamePtr->localPart = localPart;
  tagNamePtr->uriLen = binding->uriLen;
  tagNamePtr->prefix = binding->prefix->name;
  tagNamePtr->prefixLen = prefixLen;
  for (i = 0; localPart[i++];)
    ;  /* i includes null terminator */
  n = i + binding->uriLen + prefixLen;
  if (n > binding->uriAlloc) {
    TAG *p;
    uri = (XML_Char *)MALLOC(parser, (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 = parser->m_tagStack; p; p = p->parent)
      if (p->name.str == binding->uri)
        p->name.str = uri;
    FREE(parser, binding->uri);
    binding->uri = uri;
  }
  /* if m_namespaceSeparator != '\0' then uri includes it already */
  uri = binding->uri + binding->uriLen;
  memcpy(uri, localPart, i * sizeof(XML_Char));
  /* we always have a namespace separator between localPart and prefix */
  if (prefixLen) {
    uri += i - 1;
    *uri = parser->m_namespaceSeparator;  /* replace null terminator */
    memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
  }
  tagNamePtr->str = binding->uri;
  return XML_ERROR_NONE;
}

/* addBinding() overwrites the value of prefix->binding without checking.
................................................................................
static enum XML_Error
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
           const XML_Char *uri, BINDING **bindingsPtr)
{
  static const XML_Char xmlNamespace[] = {
    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,
    ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH,
    ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c,
    ASCII_e, '\0'
  };
  static const int xmlLen =
    (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
  static const XML_Char xmlnsNamespace[] = {
    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
    ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
    ASCII_SLASH, '\0'
  };
  static const int xmlnsLen =
    (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;

  XML_Bool mustBeXML = XML_FALSE;
  XML_Bool isXML = XML_TRUE;
  XML_Bool isXMLNS = XML_TRUE;

  BINDING *b;
  int len;

  /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
  if (*uri == XML_T('\0') && prefix->name)
    return XML_ERROR_UNDECLARING_PREFIX;

................................................................................
      mustBeXML = XML_TRUE;
  }

  for (len = 0; uri[len]; len++) {
    if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
      isXML = XML_FALSE;

    if (!mustBeXML && isXMLNS
        && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
      isXMLNS = XML_FALSE;
  }
  isXML = isXML && len == xmlLen;
  isXMLNS = isXMLNS && len == xmlnsLen;

  if (mustBeXML != isXML)
    return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
                     : XML_ERROR_RESERVED_NAMESPACE_URI;

  if (isXMLNS)
    return XML_ERROR_RESERVED_NAMESPACE_URI;

  if (parser->m_namespaceSeparator)
    len++;
  if (parser->m_freeBindingList) {
    b = parser->m_freeBindingList;
    if (len > b->uriAlloc) {
      XML_Char *temp = (XML_Char *)REALLOC(parser, b->uri,
                          sizeof(XML_Char) * (len + EXPAND_SPARE));
      if (temp == NULL)
        return XML_ERROR_NO_MEMORY;
      b->uri = temp;
      b->uriAlloc = len + EXPAND_SPARE;
    }
    parser->m_freeBindingList = b->nextTagBinding;
  }
  else {
    b = (BINDING *)MALLOC(parser, sizeof(BINDING));
    if (!b)
      return XML_ERROR_NO_MEMORY;
    b->uri = (XML_Char *)MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE));
    if (!b->uri) {
      FREE(parser, b);
      return XML_ERROR_NO_MEMORY;
    }
    b->uriAlloc = len + EXPAND_SPARE;
  }
  b->uriLen = len;
  memcpy(b->uri, uri, len * sizeof(XML_Char));
  if (parser->m_namespaceSeparator)
    b->uri[len - 1] = parser->m_namespaceSeparator;
  b->prefix = prefix;
  b->attId = attId;
  b->prevPrefixBinding = prefix->binding;
  /* NULL binding when default namespace undeclared */
  if (*uri == XML_T('\0') && prefix == &parser->m_dtd->defaultPrefix)
    prefix->binding = NULL;
  else
    prefix->binding = b;
  b->nextTagBinding = *bindingsPtr;
  *bindingsPtr = b;
  /* if attId == NULL then we are not starting a namespace scope */
  if (attId && parser->m_startNamespaceDeclHandler)
    parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
                              prefix->binding ? uri : 0);
  return XML_ERROR_NONE;
}

/* 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 PTRCALL
cdataSectionProcessor(XML_Parser parser,
                      const char *start,
                      const char *end,
                      const char **endPtr)
{
  enum XML_Error result = doCdataSection(parser, parser->m_encoding, &start, end,
                                         endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  if (result != XML_ERROR_NONE)
    return result;
  if (start) {
    if (parser->m_parentParser) {  /* we are parsing an external entity */
      parser->m_processor = externalEntityContentProcessor;
      return externalEntityContentProcessor(parser, start, end, endPtr);
    }
    else {
      parser->m_processor = contentProcessor;
      return contentProcessor(parser, start, end, endPtr);
    }
  }
  return result;
}

/* startPtr gets set to non-null if the section is closed, and to null if
................................................................................
               const char *end,
               const char **nextPtr,
               XML_Bool haveMore)
{
  const char *s = *startPtr;
  const char **eventPP;
  const char **eventEndPP;
  if (enc == parser->m_encoding) {
    eventPP = &parser->m_eventPtr;
    *eventPP = s;
    eventEndPP = &parser->m_eventEndPtr;
  }
  else {
    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
  }
  *eventPP = s;
  *startPtr = NULL;

  for (;;) {
    const char *next;
    int tok = XmlCdataSectionTok(enc, s, end, &next);
    *eventEndPP = next;
    switch (tok) {
    case XML_TOK_CDATA_SECT_CLOSE:
      if (parser->m_endCdataSectionHandler)
        parser->m_endCdataSectionHandler(parser->m_handlerArg);
#if 0
      /* see comment under XML_TOK_CDATA_SECT_OPEN */
      else if (parser->m_characterDataHandler)
        parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf, 0);
#endif
      else if (parser->m_defaultHandler)
        reportDefault(parser, enc, s, next);
      *startPtr = next;
      *nextPtr = next;
      if (parser->m_parsingStatus.parsing == XML_FINISHED)
        return XML_ERROR_ABORTED;
      else
        return XML_ERROR_NONE;
    case XML_TOK_DATA_NEWLINE:
      if (parser->m_characterDataHandler) {
        XML_Char c = 0xA;
        parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
      }
      else if (parser->m_defaultHandler)
        reportDefault(parser, enc, s, next);
      break;
    case XML_TOK_DATA_CHARS:
      {
        XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
        if (charDataHandler) {
          if (MUST_CONVERT(enc, s)) {
            for (;;) {
              ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
              const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
              *eventEndPP = next;
              charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
                              (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
              if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
                break;
              *eventPP = s;
            }
          }
          else
            charDataHandler(parser->m_handlerArg,
                            (XML_Char *)s,
                            (int)((XML_Char *)next - (XML_Char *)s));
        }
        else if (parser->m_defaultHandler)
          reportDefault(parser, enc, s, next);
      }
      break;
    case XML_TOK_INVALID:
      *eventPP = next;
      return XML_ERROR_INVALID_TOKEN;
    case XML_TOK_PARTIAL_CHAR:
................................................................................
    case XML_TOK_NONE:
      if (haveMore) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      return XML_ERROR_UNCLOSED_CDATA_SECTION;
    default:
      /* Every token returned by XmlCdataSectionTok() has its own
       * explicit case, so this default case will never be executed.
       * We retain it as a safety net and exclude it from the coverage
       * statistics.
       *
       * LCOV_EXCL_START
      */
      *eventPP = next;
      return XML_ERROR_UNEXPECTED_STATE;
      /* LCOV_EXCL_STOP */
    }

    *eventPP = s = next;
    switch (parser->m_parsingStatus.parsing) {
    case XML_SUSPENDED:
      *nextPtr = next;
      return XML_ERROR_NONE;
    case XML_FINISHED:
      return XML_ERROR_ABORTED;
    default: ;
    }
................................................................................
*/
static enum XML_Error PTRCALL
ignoreSectionProcessor(XML_Parser parser,
                       const char *start,
                       const char *end,
                       const char **endPtr)
{
  enum XML_Error result = doIgnoreSection(parser, parser->m_encoding, &start, end,
                                          endPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  if (result != XML_ERROR_NONE)
    return result;
  if (start) {
    parser->m_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.
................................................................................
                XML_Bool haveMore)
{
  const char *next;
  int tok;
  const char *s = *startPtr;
  const char **eventPP;
  const char **eventEndPP;
  if (enc == parser->m_encoding) {
    eventPP = &parser->m_eventPtr;
    *eventPP = s;
    eventEndPP = &parser->m_eventEndPtr;
  }
  else {
    /* It's not entirely clear, but it seems the following two lines
     * of code cannot be executed.  The only occasions on which 'enc'
     * is not 'encoding' are when this function is called
     * from the internal entity processing, and IGNORE sections are an
     * error in internal entities.
     *
     * Since it really isn't clear that this is true, we keep the code
     * and just remove it from our coverage tests.
     *
     * LCOV_EXCL_START
     */
    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
    /* LCOV_EXCL_STOP */
  }
  *eventPP = s;
  *startPtr = NULL;
  tok = XmlIgnoreSectionTok(enc, s, end, &next);
  *eventEndPP = next;
  switch (tok) {
  case XML_TOK_IGNORE_SECT:
    if (parser->m_defaultHandler)
      reportDefault(parser, enc, s, next);
    *startPtr = next;
    *nextPtr = next;
    if (parser->m_parsingStatus.parsing == XML_FINISHED)
      return XML_ERROR_ABORTED;
    else
      return XML_ERROR_NONE;
  case XML_TOK_INVALID:
    *eventPP = next;
    return XML_ERROR_INVALID_TOKEN;
  case XML_TOK_PARTIAL_CHAR:
................................................................................
  case XML_TOK_NONE:
    if (haveMore) {
      *nextPtr = s;
      return XML_ERROR_NONE;
    }
    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
  default:
    /* All of the tokens that XmlIgnoreSectionTok() returns have
     * explicit cases to handle them, so this default case is never
     * executed.  We keep it as a safety net anyway, and remove it
     * from our test coverage statistics.
     *
     * LCOV_EXCL_START
     */
    *eventPP = next;
    return XML_ERROR_UNEXPECTED_STATE;
    /* LCOV_EXCL_STOP */
  }
  /* not reached */
}

#endif /* XML_DTD */

static enum XML_Error
initializeEncoding(XML_Parser parser)
{
  const char *s;
#ifdef XML_UNICODE
  char encodingBuf[128];
  /* See comments abount `protoclEncodingName` in parserInit() */
  if (!parser->m_protocolEncodingName)
    s = NULL;
  else {
    int i;
    for (i = 0; parser->m_protocolEncodingName[i]; i++) {
      if (i == sizeof(encodingBuf) - 1
          || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) {
        encodingBuf[0] = '\0';
        break;
      }
      encodingBuf[i] = (char)parser->m_protocolEncodingName[i];
    }
    encodingBuf[i] = '\0';
    s = encodingBuf;
  }
#else
  s = parser->m_protocolEncodingName;
#endif
  if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(&parser->m_initEncoding, &parser->m_encoding, s))
    return XML_ERROR_NONE;
  return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
}

static enum XML_Error
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
               const char *s, const char *next)
{
  const char *encodingName = NULL;
  const XML_Char *storedEncName = NULL;
  const ENCODING *newEncoding = NULL;
  const char *version = NULL;
  const char *versionend;
  const XML_Char *storedversion = NULL;
  int standalone = -1;
  if (!(parser->m_ns
        ? XmlParseXmlDeclNS
        : XmlParseXmlDecl)(isGeneralTextEntity,
                           parser->m_encoding,
                           s,
                           next,
                           &parser->m_eventPtr,
                           &version,
                           &versionend,
                           &encodingName,
                           &newEncoding,
                           &standalone)) {
    if (isGeneralTextEntity)
      return XML_ERROR_TEXT_DECL;
    else
      return XML_ERROR_XML_DECL;
  }
  if (!isGeneralTextEntity && standalone == 1) {
    parser->m_dtd->standalone = XML_TRUE;
#ifdef XML_DTD
    if (parser->m_paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
      parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
#endif /* XML_DTD */
  }
  if (parser->m_xmlDeclHandler) {
    if (encodingName != NULL) {
      storedEncName = poolStoreString(&parser->m_temp2Pool,
                                      parser->m_encoding,
                                      encodingName,
                                      encodingName
                                      + XmlNameLength(parser->m_encoding, encodingName));
      if (!storedEncName)
              return XML_ERROR_NO_MEMORY;
      poolFinish(&parser->m_temp2Pool);
    }
    if (version) {
      storedversion = poolStoreString(&parser->m_temp2Pool,
                                      parser->m_encoding,
                                      version,
                                      versionend - parser->m_encoding->minBytesPerChar);
      if (!storedversion)
        return XML_ERROR_NO_MEMORY;
    }
    parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName, standalone);
  }
  else if (parser->m_defaultHandler)
    reportDefault(parser, parser->m_encoding, s, next);
  if (parser->m_protocolEncodingName == NULL) {
    if (newEncoding) {
      /* Check that the specified encoding does not conflict with what
       * the parser has already deduced.  Do we have the same number
       * of bytes in the smallest representation of a character?  If
       * this is UTF-16, is it the same endianness?
       */
      if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
          || (newEncoding->minBytesPerChar == 2 &&
              newEncoding != parser->m_encoding)) {
        parser->m_eventPtr = encodingName;
        return XML_ERROR_INCORRECT_ENCODING;
      }
      parser->m_encoding = newEncoding;
    }
    else if (encodingName) {
      enum XML_Error result;
      if (!storedEncName) {
        storedEncName = poolStoreString(
          &parser->m_temp2Pool, parser->m_encoding, encodingName,
          encodingName + XmlNameLength(parser->m_encoding, encodingName));
        if (!storedEncName)
          return XML_ERROR_NO_MEMORY;
      }
      result = handleUnknownEncoding(parser, storedEncName);
      poolClear(&parser->m_temp2Pool);
      if (result == XML_ERROR_UNKNOWN_ENCODING)
        parser->m_eventPtr = encodingName;
      return result;
    }
  }

  if (storedEncName || storedversion)
    poolClear(&parser->m_temp2Pool);

  return XML_ERROR_NONE;
}

static enum XML_Error
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
{
  if (parser->m_unknownEncodingHandler) {
    XML_Encoding info;
    int i;
    for (i = 0; i < 256; i++)
      info.map[i] = -1;
    info.convert = NULL;
    info.data = NULL;
    info.release = NULL;
    if (parser->m_unknownEncodingHandler(parser->m_unknownEncodingHandlerData, encodingName,
                               &info)) {
      ENCODING *enc;
      parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding());
      if (!parser->m_unknownEncodingMem) {
        if (info.release)
          info.release(info.data);
        return XML_ERROR_NO_MEMORY;
      }
      enc = (parser->m_ns
             ? XmlInitUnknownEncodingNS
             : XmlInitUnknownEncoding)(parser->m_unknownEncodingMem,
                                       info.map,
                                       info.convert,
                                       info.data);
      if (enc) {
        parser->m_unknownEncodingData = info.data;
        parser->m_unknownEncodingRelease = info.release;
        parser->m_encoding = enc;
        return XML_ERROR_NONE;
      }
    }
    if (info.release != NULL)
      info.release(info.data);
  }
  return XML_ERROR_UNKNOWN_ENCODING;
................................................................................
                    const char *s,
                    const char *end,
                    const char **nextPtr)
{
  enum XML_Error result = initializeEncoding(parser);
  if (result != XML_ERROR_NONE)
    return result;
  parser->m_processor = prologProcessor;
  return prologProcessor(parser, s, end, nextPtr);
}

#ifdef XML_DTD

static enum XML_Error PTRCALL
externalParEntInitProcessor(XML_Parser parser,
................................................................................
{
  enum XML_Error result = initializeEncoding(parser);
  if (result != XML_ERROR_NONE)
    return result;

  /* we know now that XML_Parse(Buffer) has been called,
     so we consider the external parameter entity read */
  parser->m_dtd->paramEntityRead = XML_TRUE;

  if (parser->m_prologState.inEntityValue) {
    parser->m_processor = entityValueInitProcessor;
    return entityValueInitProcessor(parser, s, end, nextPtr);
  }
  else {
    parser->m_processor = externalParEntProcessor;
    return externalParEntProcessor(parser, s, end, nextPtr);
  }
}

static enum XML_Error PTRCALL
entityValueInitProcessor(XML_Parser parser,
                         const char *s,
                         const char *end,
                         const char **nextPtr)
{
  int tok;
  const char *start = s;
  const char *next = start;
  parser->m_eventPtr = start;

  for (;;) {
    tok = XmlPrologTok(parser->m_encoding, start, end, &next);
    parser->m_eventEndPtr = next;
    if (tok <= 0) {
      if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      switch (tok) {
      case XML_TOK_INVALID:
        return XML_ERROR_INVALID_TOKEN;
      case XML_TOK_PARTIAL:
................................................................................
      case XML_TOK_PARTIAL_CHAR:
        return XML_ERROR_PARTIAL_CHAR;
      case XML_TOK_NONE:   /* start == end */
      default:
        break;
      }
      /* found end of entity value - can store it now */
      return storeEntityValue(parser, parser->m_encoding, s, end);
    }
    else if (tok == XML_TOK_XML_DECL) {
      enum XML_Error result;
      result = processXmlDecl(parser, 0, start, next);
      if (result != XML_ERROR_NONE)
        return result;
      /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED.  For that
       * to happen, a parameter entity parsing handler must have
       * attempted to suspend the parser, which fails and raises an
       * error.  The parser can be aborted, but can't be suspended.

       */
      if (parser->m_parsingStatus.parsing == XML_FINISHED)
        return XML_ERROR_ABORTED;

      *nextPtr = next;

      /* stop scanning for text declaration - we found one */
      parser->m_processor = entityValueProcessor;
      return entityValueProcessor(parser, next, end, nextPtr);
    }
    /* If we are at the end of the buffer, this would cause XmlPrologTok to
       return XML_TOK_NONE on the next call, which would then cause the
       function to exit with *nextPtr set to s - that is what we want for other
       tokens, but not for the BOM - we would rather like to skip it;
       then, when this routine is entered the next time, XmlPrologTok will
       return XML_TOK_INVALID, since the BOM is still in the buffer
    */
    else if (tok == XML_TOK_BOM && next == end && !parser->m_parsingStatus.finalBuffer) {
      *nextPtr = next;
      return XML_ERROR_NONE;
    }
    /* If we get this token, we have the start of what might be a
       normal tag, but not a declaration (i.e. it doesn't begin with
       "<!").  In a DTD context, that isn't legal.
    */
    else if (tok == XML_TOK_INSTANCE_START) {
      *nextPtr = next;
      return XML_ERROR_SYNTAX;
    }
    start = next;
    parser->m_eventPtr = start;
  }
}

static enum XML_Error PTRCALL
externalParEntProcessor(XML_Parser parser,
                        const char *s,
                        const char *end,
                        const char **nextPtr)
{
  const char *next = s;
  int tok;

  tok = XmlPrologTok(parser->m_encoding, s, end, &next);
  if (tok <= 0) {
    if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
      *nextPtr = s;
      return XML_ERROR_NONE;
    }
    switch (tok) {
    case XML_TOK_INVALID:
      return XML_ERROR_INVALID_TOKEN;
    case XML_TOK_PARTIAL:
................................................................................
  }
  /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
     However, when parsing an external subset, doProlog will not accept a BOM
     as valid, and report a syntax error, so we have to skip the BOM
  */
  else if (tok == XML_TOK_BOM) {
    s = next;
    tok = XmlPrologTok(parser->m_encoding, s, end, &next);
  }

  parser->m_processor = prologProcessor;
  return doProlog(parser, parser->m_encoding, s, end, tok, next,
                  nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
}

static enum XML_Error PTRCALL
entityValueProcessor(XML_Parser parser,
                     const char *s,
                     const char *end,
                     const char **nextPtr)
{
  const char *start = s;
  const char *next = s;
  const ENCODING *enc = parser->m_encoding;
  int tok;

  for (;;) {
    tok = XmlPrologTok(enc, start, end, &next);
    if (tok <= 0) {
      if (!parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      switch (tok) {
      case XML_TOK_INVALID:
        return XML_ERROR_INVALID_TOKEN;
      case XML_TOK_PARTIAL:
................................................................................
static enum XML_Error PTRCALL
prologProcessor(XML_Parser parser,
                const char *s,
                const char *end,
                const char **nextPtr)
{
  const char *next = s;
  int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
  return doProlog(parser, parser->m_encoding, s, end, tok, next,
                  nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
}

static enum XML_Error
doProlog(XML_Parser parser,
         const ENCODING *enc,
         const char *s,
         const char *end,
................................................................................
         const char *next,
         const char **nextPtr,
         XML_Bool haveMore)
{
#ifdef XML_DTD
  static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' };
#endif /* XML_DTD */
  static const XML_Char atypeCDATA[] =
      { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
  static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' };
  static const XML_Char atypeIDREF[] =
      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
  static const XML_Char atypeIDREFS[] =
      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
  static const XML_Char atypeENTITY[] =
................................................................................
      ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
  static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T,
      ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' };
  static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' };
  static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' };

  /* save one level of indirection */
  DTD * const dtd = parser->m_dtd;

  const char **eventPP;
  const char **eventEndPP;
  enum XML_Content_Quant quant;

  if (enc == parser->m_encoding) {
    eventPP = &parser->m_eventPtr;
    eventEndPP = &parser->m_eventEndPtr;
  }
  else {
    eventPP = &(parser->m_openInternalEntities->internalEventPtr);
    eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
  }

  for (;;) {
    int role;
    XML_Bool handleDefault = XML_TRUE;
    *eventPP = s;
    *eventEndPP = next;
................................................................................
      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_PROLOG_S:
        tok = -tok;
        break;
      case XML_TOK_NONE:
#ifdef XML_DTD
        /* for internal PE NOT referenced between declarations */
        if (enc != parser->m_encoding && !parser->m_openInternalEntities->betweenDecl) {
          *nextPtr = s;
          return XML_ERROR_NONE;
        }
        /* WFC: PE Between Declarations - must check that PE contains
           complete markup, not only for external PEs, but also for
           internal PEs if the reference occurs between declarations.
        */
        if (parser->m_isParamEntity || enc != parser->m_encoding) {
          if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc)
              == XML_ROLE_ERROR)
            return XML_ERROR_INCOMPLETE_PE;
          *nextPtr = s;
          return XML_ERROR_NONE;
        }
#endif /* XML_DTD */
        return XML_ERROR_NO_ELEMENTS;
      default:
        tok = -tok;
        next = end;
        break;
      }
    }
    role = XmlTokenRole(&parser->m_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 = parser->m_encoding;
        handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_DOCTYPE_NAME:
      if (parser->m_startDoctypeDeclHandler) {
        parser->m_doctypeName = poolStoreString(&parser->m_tempPool, enc, s, next);
        if (!parser->m_doctypeName)
          return XML_ERROR_NO_MEMORY;
        poolFinish(&parser->m_tempPool);
        parser->m_doctypePubid = NULL;
        handleDefault = XML_FALSE;
      }
      parser->m_doctypeSysid = NULL; /* always initialize to NULL */
      break;
    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
      if (parser->m_startDoctypeDeclHandler) {
        parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
                                parser->m_doctypePubid, 1);
        parser->m_doctypeName = NULL;
        poolClear(&parser->m_tempPool);
        handleDefault = XML_FALSE;
      }
      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 = parser->m_encoding;
        handleDefault = XML_FALSE;
      }
      break;
#endif /* XML_DTD */
    case XML_ROLE_DOCTYPE_PUBLIC_ID:
#ifdef XML_DTD
      parser->m_useForeignDTD = XML_FALSE;
      parser->m_declEntity = (ENTITY *)lookup(parser,
                                    &dtd->paramEntities,
                                    externalSubsetName,
                                    sizeof(ENTITY));
      if (!parser->m_declEntity)
        return XML_ERROR_NO_MEMORY;
#endif /* XML_DTD */
      dtd->hasParamEntityRefs = XML_TRUE;
      if (parser->m_startDoctypeDeclHandler) {
        XML_Char *pubId;
        if (!XmlIsPublicId(enc, s, next, eventPP))
          return XML_ERROR_PUBLICID;
        pubId = poolStoreString(&parser->m_tempPool, enc,
                                s + enc->minBytesPerChar,
                                next - enc->minBytesPerChar);

        if (!pubId)
          return XML_ERROR_NO_MEMORY;
        normalizePublicId(pubId);
        poolFinish(&parser->m_tempPool);
        parser->m_doctypePubid = pubId;
        handleDefault = XML_FALSE;
        goto alreadyChecked;
      }
      /* fall through */
    case XML_ROLE_ENTITY_PUBLIC_ID:
      if (!XmlIsPublicId(enc, s, next, eventPP))
        return XML_ERROR_PUBLICID;
    alreadyChecked:
      if (dtd->keepProcessing && parser->m_declEntity) {
        XML_Char *tem = poolStoreString(&dtd->pool,
                                        enc,
                                        s + enc->minBytesPerChar,
                                        next - enc->minBytesPerChar);
        if (!tem)
          return XML_ERROR_NO_MEMORY;
        normalizePublicId(tem);
        parser->m_declEntity->publicId = tem;
        poolFinish(&dtd->pool);
        /* Don't suppress the default handler if we fell through from
         * the XML_ROLE_DOCTYPE_PUBLIC_ID case.
         */
        if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID)
          handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_DOCTYPE_CLOSE:
      if (parser->m_doctypeName) {
        parser->m_startDoctypeDeclHandler(parser->m_handlerArg, parser->m_doctypeName,
                                parser->m_doctypeSysid, parser->m_doctypePubid, 0);
        poolClear(&parser->m_tempPool);
        handleDefault = XML_FALSE;
      }
      /* parser->m_doctypeSysid will be non-NULL in the case of a previous
         XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler
         was not set, indicating an external subset
      */
#ifdef XML_DTD
      if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
        dtd->hasParamEntityRefs = XML_TRUE;
        if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) {
          ENTITY *entity = (ENTITY *)lookup(parser,
                                            &dtd->paramEntities,
                                            externalSubsetName,
                                            sizeof(ENTITY));
          if (!entity) {
            /* The external subset name "#" will have already been
             * inserted into the hash table at the start of the
             * external entity parsing, so no allocation will happen
             * and lookup() cannot fail.
             */
            return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
          }
          if (parser->m_useForeignDTD)
            entity->base = parser->m_curBase;
          dtd->paramEntityRead = XML_FALSE;

          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
                                        0,
                                        entity->base,
                                        entity->systemId,
                                        entity->publicId))
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
          if (dtd->paramEntityRead) {
            if (!dtd->standalone &&
                parser->m_notStandaloneHandler &&
                !parser->m_notStandaloneHandler(parser->m_handlerArg))
              return XML_ERROR_NOT_STANDALONE;
          }
          /* if we didn't read the foreign DTD then this means that there
             is no external subset and we must reset dtd->hasParamEntityRefs
          */
          else if (!parser->m_doctypeSysid)
            dtd->hasParamEntityRefs = hadParamEntityRefs;
          /* end of DTD - no need to update dtd->keepProcessing */
        }
        parser->m_useForeignDTD = XML_FALSE;
      }
#endif /* XML_DTD */
      if (parser->m_endDoctypeDeclHandler) {
        parser->m_endDoctypeDeclHandler(parser->m_handlerArg);
        handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_INSTANCE_START:
#ifdef XML_DTD
      /* if there is no DOCTYPE declaration then now is the
         last chance to read the foreign DTD
      */
      if (parser->m_useForeignDTD) {
        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
        dtd->hasParamEntityRefs = XML_TRUE;
        if (parser->m_paramEntityParsing && parser->m_externalEntityRefHandler) {
          ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
                                            externalSubsetName,
                                            sizeof(ENTITY));
          if (!entity)
            return XML_ERROR_NO_MEMORY;
          entity->base = parser->m_curBase;
          dtd->paramEntityRead = XML_FALSE;
          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
                                        0,
                                        entity->base,
                                        entity->systemId,
                                        entity->publicId))
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
          if (dtd->paramEntityRead) {
            if (!dtd->standalone &&
                parser->m_notStandaloneHandler &&
                !parser->m_notStandaloneHandler(parser->m_handlerArg))
              return XML_ERROR_NOT_STANDALONE;
          }
          /* if we didn't read the foreign DTD then this means that there
             is no external subset and we must reset dtd->hasParamEntityRefs
          */
          else
            dtd->hasParamEntityRefs = hadParamEntityRefs;
          /* end of DTD - no need to update dtd->keepProcessing */
        }
      }
#endif /* XML_DTD */
      parser->m_processor = contentProcessor;
      return contentProcessor(parser, s, end, nextPtr);
    case XML_ROLE_ATTLIST_ELEMENT_NAME:
      parser->m_declElementType = getElementType(parser, enc, s, next);
      if (!parser->m_declElementType)
        return XML_ERROR_NO_MEMORY;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_NAME:
      parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
      if (!parser->m_declAttributeId)
        return XML_ERROR_NO_MEMORY;
      parser->m_declAttributeIsCdata = XML_FALSE;
      parser->m_declAttributeType = NULL;
      parser->m_declAttributeIsId = XML_FALSE;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
      parser->m_declAttributeIsCdata = XML_TRUE;
      parser->m_declAttributeType = atypeCDATA;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_ID:
      parser->m_declAttributeIsId = XML_TRUE;
      parser->m_declAttributeType = atypeID;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
      parser->m_declAttributeType = atypeIDREF;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
      parser->m_declAttributeType = atypeIDREFS;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
      parser->m_declAttributeType = atypeENTITY;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
      parser->m_declAttributeType = atypeENTITIES;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
      parser->m_declAttributeType = atypeNMTOKEN;
      goto checkAttListDeclHandler;
    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
      parser->m_declAttributeType = atypeNMTOKENS;
    checkAttListDeclHandler:
      if (dtd->keepProcessing && parser->m_attlistDeclHandler)
        handleDefault = XML_FALSE;
      break;
    case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
      if (dtd->keepProcessing && parser->m_attlistDeclHandler) {
        const XML_Char *prefix;
        if (parser->m_declAttributeType) {
          prefix = enumValueSep;
        }
        else {
          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
                    ? notationPrefix
                    : enumValueStart);
        }
        if (!poolAppendString(&parser->m_tempPool, prefix))
          return XML_ERROR_NO_MEMORY;
        if (!poolAppend(&parser->m_tempPool, enc, s, next))
          return XML_ERROR_NO_MEMORY;
        parser->m_declAttributeType = parser->m_tempPool.start;
        handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
      if (dtd->keepProcessing) {
        if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId,
                             parser->m_declAttributeIsCdata, parser->m_declAttributeIsId,
                             0, parser))
          return XML_ERROR_NO_MEMORY;
        if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
          if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
              || (*parser->m_declAttributeType == XML_T(ASCII_N)
                  && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
            /* Enumerated or Notation type */
            if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
                || !poolAppendChar(&parser->m_tempPool, XML_T('\0')))
              return XML_ERROR_NO_MEMORY;
            parser->m_declAttributeType = parser->m_tempPool.start;
            poolFinish(&parser->m_tempPool);
          }
          *eventEndPP = s;
          parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name,
                             parser->m_declAttributeId->name, parser->m_declAttributeType,
                             0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
          poolClear(&parser->m_tempPool);
          handleDefault = XML_FALSE;
        }
      }
      break;
    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
      if (dtd->keepProcessing) {
        const XML_Char *attVal;
        enum XML_Error result =
          storeAttributeValue(parser, enc, parser->m_declAttributeIsCdata,
                              s + enc->minBytesPerChar,
                              next - enc->minBytesPerChar,
                              &dtd->pool);
        if (result)
          return result;
        attVal = poolStart(&dtd->pool);
        poolFinish(&dtd->pool);
        /* ID attributes aren't allowed to have a default */
        if (!defineAttribute(parser->m_declElementType, parser->m_declAttributeId,
                             parser->m_declAttributeIsCdata, XML_FALSE, attVal, parser))
          return XML_ERROR_NO_MEMORY;
        if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
          if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)
              || (*parser->m_declAttributeType == XML_T(ASCII_N)
                  && parser->m_declAttributeType[1] == XML_T(ASCII_O))) {
            /* Enumerated or Notation type */
            if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN))
                || !poolAppendChar(&parser->m_tempPool, XML_T('\0')))
              return XML_ERROR_NO_MEMORY;
            parser->m_declAttributeType = parser->m_tempPool.start;
            poolFinish(&parser->m_tempPool);
          }
          *eventEndPP = s;
          parser->m_attlistDeclHandler(parser->m_handlerArg, parser->m_declElementType->name,
                             parser->m_declAttributeId->name, parser->m_declAttributeType,
                             attVal,
                             role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
          poolClear(&parser->m_tempPool);
          handleDefault = XML_FALSE;
        }
      }
      break;
    case XML_ROLE_ENTITY_VALUE:
      if (dtd->keepProcessing) {
        enum XML_Error result = storeEntityValue(parser, enc,
                                            s + enc->minBytesPerChar,
                                            next - enc->minBytesPerChar);
        if (parser->m_declEntity) {
          parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool);
          parser->m_declEntity->textLen = (int)(poolLength(&dtd->entityValuePool));
          poolFinish(&dtd->entityValuePool);
          if (parser->m_entityDeclHandler) {
            *eventEndPP = s;
            parser->m_entityDeclHandler(parser->m_handlerArg,
                              parser->m_declEntity->name,
                              parser->m_declEntity->is_param,
                              parser->m_declEntity->textPtr,
                              parser->m_declEntity->textLen,
                              parser->m_curBase, 0, 0, 0);
            handleDefault = XML_FALSE;
          }
        }
        else
          poolDiscard(&dtd->entityValuePool);
        if (result != XML_ERROR_NONE)
          return result;
      }
      break;
    case XML_ROLE_DOCTYPE_SYSTEM_ID:
#ifdef XML_DTD
      parser->m_useForeignDTD = XML_FALSE;
#endif /* XML_DTD */
      dtd->hasParamEntityRefs = XML_TRUE;
      if (parser->m_startDoctypeDeclHandler) {
        parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc,
                                       s + enc->minBytesPerChar,
                                       next - enc->minBytesPerChar);
        if (parser->m_doctypeSysid == NULL)
          return XML_ERROR_NO_MEMORY;
        poolFinish(&parser->m_tempPool);
        handleDefault = XML_FALSE;
      }
#ifdef XML_DTD
      else
        /* use externalSubsetName to make parser->m_doctypeSysid non-NULL
           for the case where no parser->m_startDoctypeDeclHandler is set */
        parser->m_doctypeSysid = externalSubsetName;
#endif /* XML_DTD */
      if (!dtd->standalone
#ifdef XML_DTD
          && !parser->m_paramEntityParsing
#endif /* XML_DTD */
          && parser->m_notStandaloneHandler
          && !parser->m_notStandaloneHandler(parser->m_handlerArg))
        return XML_ERROR_NOT_STANDALONE;
#ifndef XML_DTD
      break;
#else /* XML_DTD */
      if (!parser->m_declEntity) {
        parser->m_declEntity = (ENTITY *)lookup(parser,
                                      &dtd->paramEntities,
                                      externalSubsetName,
                                      sizeof(ENTITY));
        if (!parser->m_declEntity)
          return XML_ERROR_NO_MEMORY;
        parser->m_declEntity->publicId = NULL;
      }
      /* fall through */
#endif /* XML_DTD */
    case XML_ROLE_ENTITY_SYSTEM_ID:
      if (dtd->keepProcessing && parser->m_declEntity) {
        parser->m_declEntity->systemId = poolStoreString(&dtd->pool, enc,
                                               s + enc->minBytesPerChar,
                                               next - enc->minBytesPerChar);
        if (!parser->m_declEntity->systemId)
          return XML_ERROR_NO_MEMORY;
        parser->m_declEntity->base = parser->m_curBase;
        poolFinish(&dtd->pool);
        /* Don't suppress the default handler if we fell through from
         * the XML_ROLE_DOCTYPE_SYSTEM_ID case.
         */
        if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID)
          handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_ENTITY_COMPLETE:
      if (dtd->keepProcessing && parser->m_declEntity && parser->m_entityDeclHandler) {
        *eventEndPP = s;
        parser->m_entityDeclHandler(parser->m_handlerArg,
                          parser->m_declEntity->name,
                          parser->m_declEntity->is_param,
                          0,0,
                          parser->m_declEntity->base,
                          parser->m_declEntity->systemId,
                          parser->m_declEntity->publicId,
                          0);
        handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_ENTITY_NOTATION_NAME:
      if (dtd->keepProcessing && parser->m_declEntity) {
        parser->m_declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
        if (!parser->m_declEntity->notation)
          return XML_ERROR_NO_MEMORY;
        poolFinish(&dtd->pool);
        if (parser->m_unparsedEntityDeclHandler) {
          *eventEndPP = s;
          parser->m_unparsedEntityDeclHandler(parser->m_handlerArg,
                                    parser->m_declEntity->name,
                                    parser->m_declEntity->base,
                                    parser->m_declEntity->systemId,
                                    parser->m_declEntity->publicId,
                                    parser->m_declEntity->notation);
          handleDefault = XML_FALSE;
        }
        else if (parser->m_entityDeclHandler) {
          *eventEndPP = s;
          parser->m_entityDeclHandler(parser->m_handlerArg,
                            parser->m_declEntity->name,
                            0,0,0,
                            parser->m_declEntity->base,
                            parser->m_declEntity->systemId,
                            parser->m_declEntity->publicId,
                            parser->m_declEntity->notation);
          handleDefault = XML_FALSE;
        }
      }
      break;
    case XML_ROLE_GENERAL_ENTITY_NAME:
      {
        if (XmlPredefinedEntityName(enc, s, next)) {
          parser->m_declEntity = NULL;
          break;
        }
        if (dtd->keepProcessing) {
          const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
          if (!name)
            return XML_ERROR_NO_MEMORY;
          parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities, name,
                                        sizeof(ENTITY));
          if (!parser->m_declEntity)
            return XML_ERROR_NO_MEMORY;
          if (parser->m_declEntity->name != name) {
            poolDiscard(&dtd->pool);
            parser->m_declEntity = NULL;
          }
          else {
            poolFinish(&dtd->pool);
            parser->m_declEntity->publicId = NULL;
            parser->m_declEntity->is_param = XML_FALSE;
            /* if we have a parent parser or are reading an internal parameter
               entity, then the entity declaration is not considered "internal"
            */
            parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities);
            if (parser->m_entityDeclHandler)
              handleDefault = XML_FALSE;
          }
        }
        else {
          poolDiscard(&dtd->pool);
          parser->m_declEntity = NULL;
        }
      }
      break;
    case XML_ROLE_PARAM_ENTITY_NAME:
#ifdef XML_DTD
      if (dtd->keepProcessing) {
        const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
        if (!name)
          return XML_ERROR_NO_MEMORY;
        parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
                                           name, sizeof(ENTITY));
        if (!parser->m_declEntity)
          return XML_ERROR_NO_MEMORY;
        if (parser->m_declEntity->name != name) {
          poolDiscard(&dtd->pool);
          parser->m_declEntity = NULL;
        }
        else {
          poolFinish(&dtd->pool);
          parser->m_declEntity->publicId = NULL;
          parser->m_declEntity->is_param = XML_TRUE;
          /* if we have a parent parser or are reading an internal parameter
             entity, then the entity declaration is not considered "internal"
          */
          parser->m_declEntity->is_internal = !(parser->m_parentParser || parser->m_openInternalEntities);
          if (parser->m_entityDeclHandler)
            handleDefault = XML_FALSE;
        }
      }
      else {
        poolDiscard(&dtd->pool);
        parser->m_declEntity = NULL;
      }
#else /* not XML_DTD */
      parser->m_declEntity = NULL;
#endif /* XML_DTD */
      break;
    case XML_ROLE_NOTATION_NAME:
      parser->m_declNotationPublicId = NULL;
      parser->m_declNotationName = NULL;
      if (parser->m_notationDeclHandler) {
        parser->m_declNotationName = poolStoreString(&parser->m_tempPool, enc, s, next);
        if (!parser->m_declNotationName)
          return XML_ERROR_NO_MEMORY;
        poolFinish(&parser->m_tempPool);
        handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_NOTATION_PUBLIC_ID:
      if (!XmlIsPublicId(enc, s, next, eventPP))
        return XML_ERROR_PUBLICID;
      if (parser->m_declNotationName) {  /* means m_notationDeclHandler != NULL */
        XML_Char *tem = poolStoreString(&parser->m_tempPool,
                                        enc,
                                        s + enc->minBytesPerChar,
                                        next - enc->minBytesPerChar);
        if (!tem)
          return XML_ERROR_NO_MEMORY;
        normalizePublicId(tem);
        parser->m_declNotationPublicId = tem;
        poolFinish(&parser->m_tempPool);
        handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_NOTATION_SYSTEM_ID:
      if (parser->m_declNotationName && parser->m_notationDeclHandler) {
        const XML_Char *systemId
          = poolStoreString(&parser->m_tempPool, enc,
                            s + enc->minBytesPerChar,
                            next - enc->minBytesPerChar);
        if (!systemId)
          return XML_ERROR_NO_MEMORY;
        *eventEndPP = s;
        parser->m_notationDeclHandler(parser->m_handlerArg,
                            parser->m_declNotationName,
                            parser->m_curBase,
                            systemId,
                            parser->m_declNotationPublicId);
        handleDefault = XML_FALSE;
      }
      poolClear(&parser->m_tempPool);
      break;
    case XML_ROLE_NOTATION_NO_SYSTEM_ID:
      if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) {
        *eventEndPP = s;
        parser->m_notationDeclHandler(parser->m_handlerArg,
                            parser->m_declNotationName,
                            parser->m_curBase,
                            0,
                            parser->m_declNotationPublicId);
        handleDefault = XML_FALSE;
      }
      poolClear(&parser->m_tempPool);
      break;
    case XML_ROLE_ERROR:
      switch (tok) {
      case XML_TOK_PARAM_ENTITY_REF:
        /* PE references in internal subset are
           not allowed within declarations. */
        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 (parser->m_defaultHandler)
          reportDefault(parser, enc, s, next);
        handleDefault = XML_FALSE;
        result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
        if (result != XML_ERROR_NONE)
          return result;
        else if (!next) {
          parser->m_processor = ignoreSectionProcessor;
          return result;
        }
      }
      break;
#endif /* XML_DTD */
    case XML_ROLE_GROUP_OPEN:
      if (parser->m_prologState.level >= parser->m_groupSize) {
        if (parser->m_groupSize) {
          char *temp = (char *)REALLOC(parser, parser->m_groupConnector, parser->m_groupSize *= 2);
          if (temp == NULL) {
            parser->m_groupSize /= 2;
            return XML_ERROR_NO_MEMORY;
          }
          parser->m_groupConnector = temp;
          if (dtd->scaffIndex) {
            int *temp = (int *)REALLOC(parser, dtd->scaffIndex,
                          parser->m_groupSize * sizeof(int));
            if (temp == NULL)
              return XML_ERROR_NO_MEMORY;
            dtd->scaffIndex = temp;
          }
        }
        else {
          parser->m_groupConnector = (char *)MALLOC(parser, parser->m_groupSize = 32);
          if (!parser->m_groupConnector) {
            parser->m_groupSize = 0;
            return XML_ERROR_NO_MEMORY;
          }
        }
      }
      parser->m_groupConnector[parser->m_prologState.level] = 0;
      if (dtd->in_eldecl) {
        int myindex = nextScaffoldPart(parser);
        if (myindex < 0)
          return XML_ERROR_NO_MEMORY;
        dtd->scaffIndex[dtd->scaffLevel] = myindex;
        dtd->scaffLevel++;
        dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
        if (parser->m_elementDeclHandler)
          handleDefault = XML_FALSE;
      }
      break;
    case XML_ROLE_GROUP_SEQUENCE:
      if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE)
        return XML_ERROR_SYNTAX;
      parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA;
      if (dtd->in_eldecl && parser->m_elementDeclHandler)
        handleDefault = XML_FALSE;
      break;
    case XML_ROLE_GROUP_CHOICE:
      if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA)
        return XML_ERROR_SYNTAX;
      if (dtd->in_eldecl
          && !parser->m_groupConnector[parser->m_prologState.level]
          && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
              != XML_CTYPE_MIXED)
          ) {
        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
            = XML_CTYPE_CHOICE;
        if (parser->m_elementDeclHandler)
          handleDefault = XML_FALSE;
      }
      parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE;
      break;
    case XML_ROLE_PARAM_ENTITY_REF:
#ifdef XML_DTD
    case XML_ROLE_INNER_PARAM_ENTITY_REF:
      dtd->hasParamEntityRefs = XML_TRUE;
      if (!parser->m_paramEntityParsing)
        dtd->keepProcessing = dtd->standalone;
      else {
        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(parser, &dtd->paramEntities, name, 0);
        poolDiscard(&dtd->pool);
        /* first, determine if a check for an existing declaration is needed;
           if yes, check that the entity exists, and that it is internal,
           otherwise call the skipped entity handler
        */
        if (parser->m_prologState.documentEntity &&
            (dtd->standalone
             ? !parser->m_openInternalEntities
             : !dtd->hasParamEntityRefs)) {
          if (!entity)
            return XML_ERROR_UNDEFINED_ENTITY;
          else if (!entity->is_internal) {
            /* It's hard to exhaustively search the code to be sure,
             * but there doesn't seem to be a way of executing the
             * following line.  There are two cases:
             *
             * If 'standalone' is false, the DTD must have no
             * parameter entities or we wouldn't have passed the outer
             * 'if' statement.  That measn the only entity in the hash
             * table is the external subset name "#" which cannot be
             * given as a parameter entity name in XML syntax, so the
             * lookup must have returned NULL and we don't even reach
             * the test for an internal entity.
             *
             * If 'standalone' is true, it does not seem to be
             * possible to create entities taking this code path that
             * are not internal entities, so fail the test above.
             *
             * Because this analysis is very uncertain, the code is
             * being left in place and merely removed from the
             * coverage test statistics.
             */
            return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
          }
        }
        else if (!entity) {
          dtd->keepProcessing = dtd->standalone;
          /* cannot report skipped entities in declarations */
          if ((role == XML_ROLE_PARAM_ENTITY_REF) && parser->m_skippedEntityHandler) {
            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1);
            handleDefault = XML_FALSE;
          }
          break;
        }
        if (entity->open)
          return XML_ERROR_RECURSIVE_ENTITY_REF;
        if (entity->textPtr) {
          enum XML_Error result;
          XML_Bool betweenDecl =
            (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE);
          result = processInternalEntity(parser, entity, betweenDecl);
          if (result != XML_ERROR_NONE)
            return result;
          handleDefault = XML_FALSE;
          break;
        }
        if (parser->m_externalEntityRefHandler) {
          dtd->paramEntityRead = XML_FALSE;
          entity->open = XML_TRUE;
          if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
                                        0,
                                        entity->base,
                                        entity->systemId,
                                        entity->publicId)) {
            entity->open = XML_FALSE;
            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
          }
................................................................................
        else {
          dtd->keepProcessing = dtd->standalone;
          break;
        }
      }
#endif /* XML_DTD */
      if (!dtd->standalone &&
          parser->m_notStandaloneHandler &&
          !parser->m_notStandaloneHandler(parser->m_handlerArg))
        return XML_ERROR_NOT_STANDALONE;
      break;

    /* Element declaration stuff */

    case XML_ROLE_ELEMENT_NAME:
      if (parser->m_elementDeclHandler) {
        parser->m_declElementType = getElementType(parser, enc, s, next);
        if (!parser->m_declElementType)
          return XML_ERROR_NO_MEMORY;
        dtd->scaffLevel = 0;
        dtd->scaffCount = 0;
        dtd->in_eldecl = XML_TRUE;
        handleDefault = XML_FALSE;
      }
      break;

    case XML_ROLE_CONTENT_ANY:
    case XML_ROLE_CONTENT_EMPTY:
      if (dtd->in_eldecl) {
        if (parser->m_elementDeclHandler) {
          XML_Content * content = (XML_Content *) MALLOC(parser, sizeof(XML_Content));
          if (!content)
            return XML_ERROR_NO_MEMORY;
          content->quant = XML_CQUANT_NONE;
          content->name = NULL;
          content->numchildren = 0;
          content->children = NULL;
          content->type = ((role == XML_ROLE_CONTENT_ANY) ?
                           XML_CTYPE_ANY :
                           XML_CTYPE_EMPTY);
          *eventEndPP = s;
          parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, content);
          handleDefault = XML_FALSE;
        }
        dtd->in_eldecl = XML_FALSE;
      }
      break;

    case XML_ROLE_CONTENT_PCDATA:
      if (dtd->in_eldecl) {
        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
            = XML_CTYPE_MIXED;
        if (parser->m_elementDeclHandler)
          handleDefault = XML_FALSE;
      }
      break;

    case XML_ROLE_CONTENT_ELEMENT:
      quant = XML_CQUANT_NONE;
      goto elementContent;
................................................................................
        if (!el)
          return XML_ERROR_NO_MEMORY;
        name = el->name;
        dtd->scaffold[myindex].name = name;
        nameLen = 0;
        for (; name[nameLen++]; );
        dtd->contentStringLen +=  nameLen;
        if (parser->m_elementDeclHandler)
          handleDefault = XML_FALSE;
      }
      break;

    case XML_ROLE_GROUP_CLOSE:
      quant = XML_CQUANT_NONE;
      goto closeGroup;
................................................................................
    case XML_ROLE_GROUP_CLOSE_REP:
      quant = XML_CQUANT_REP;
      goto closeGroup;
    case XML_ROLE_GROUP_CLOSE_PLUS:
      quant = XML_CQUANT_PLUS;
    closeGroup:
      if (dtd->in_eldecl) {
        if (parser->m_elementDeclHandler)
          handleDefault = XML_FALSE;
        dtd->scaffLevel--;
        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
        if (dtd->scaffLevel == 0) {
          if (!handleDefault) {
            XML_Content *model = build_model(parser);
            if (!model)
              return XML_ERROR_NO_MEMORY;
            *eventEndPP = s;
            parser->m_elementDeclHandler(parser->m_handlerArg, parser->m_declElementType->name, model);
          }
          dtd->in_eldecl = XML_FALSE;
          dtd->contentStringLen = 0;
        }
      }
      break;
      /* End element declaration stuff */
................................................................................
      switch (tok) {
      case XML_TOK_BOM:
        handleDefault = XML_FALSE;
        break;
      }
      break;
    case XML_ROLE_DOCTYPE_NONE:
      if (parser->m_startDoctypeDeclHandler)
        handleDefault = XML_FALSE;
      break;
    case XML_ROLE_ENTITY_NONE:
      if (dtd->keepProcessing && parser->m_entityDeclHandler)
        handleDefault = XML_FALSE;
      break;
    case XML_ROLE_NOTATION_NONE:
      if (parser->m_notationDeclHandler)
        handleDefault = XML_FALSE;
      break;
    case XML_ROLE_ATTLIST_NONE:
      if (dtd->keepProcessing && parser->m_attlistDeclHandler)
        handleDefault = XML_FALSE;
      break;
    case XML_ROLE_ELEMENT_NONE:
      if (parser->m_elementDeclHandler)
        handleDefault = XML_FALSE;
      break;
    } /* end of big switch */

    if (handleDefault && parser->m_defaultHandler)
      reportDefault(parser, enc, s, next);

    switch (parser->m_parsingStatus.parsing) {
    case XML_SUSPENDED:
      *nextPtr = next;
      return XML_ERROR_NONE;
    case XML_FINISHED:
      return XML_ERROR_ABORTED;
    default:
      s = next;
      tok = XmlPrologTok(enc, s, end, &next);
................................................................................

static enum XML_Error PTRCALL
epilogProcessor(XML_Parser parser,
                const char *s,
                const char *end,
                const char **nextPtr)
{
  parser->m_processor = epilogProcessor;
  parser->m_eventPtr = s;
  for (;;) {
    const char *next = NULL;
    int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
    parser->m_eventEndPtr = next;
    switch (tok) {
    /* report partial linebreak - it might be the last token */
    case -XML_TOK_PROLOG_S:
      if (parser->m_defaultHandler) {
        reportDefault(parser, parser->m_encoding, s, next);
        if (parser->m_parsingStatus.parsing == XML_FINISHED)
          return XML_ERROR_ABORTED;
      }
      *nextPtr = next;
      return XML_ERROR_NONE;
    case XML_TOK_NONE:
      *nextPtr = s;
      return XML_ERROR_NONE;
    case XML_TOK_PROLOG_S:
      if (parser->m_defaultHandler)
        reportDefault(parser, parser->m_encoding, s, next);
      break;
    case XML_TOK_PI:
      if (!reportProcessingInstruction(parser, parser->m_encoding, s, next))
        return XML_ERROR_NO_MEMORY;
      break;
    case XML_TOK_COMMENT:
      if (!reportComment(parser, parser->m_encoding, s, next))
        return XML_ERROR_NO_MEMORY;
      break;
    case XML_TOK_INVALID:
      parser->m_eventPtr = next;
      return XML_ERROR_INVALID_TOKEN;
    case XML_TOK_PARTIAL:
      if (!parser->m_parsingStatus.finalBuffer) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      return XML_ERROR_UNCLOSED_TOKEN;
    case XML_TOK_PARTIAL_CHAR:
      if (!parser->m_parsingStatus.finalBuffer) {
        *nextPtr = s;
        return XML_ERROR_NONE;
      }
      return XML_ERROR_PARTIAL_CHAR;
    default:
      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
    }
    parser->m_eventPtr = s = next;
    switch (parser->m_parsingStatus.parsing) {
    case XML_SUSPENDED:
      *nextPtr = next;
      return XML_ERROR_NONE;
    case XML_FINISHED:
      return XML_ERROR_ABORTED;
    default: ;
    }
  }
................................................................................
                      XML_Bool betweenDecl)
{
  const char *textStart, *textEnd;
  const char *next;
  enum XML_Error result;
  OPEN_INTERNAL_ENTITY *openEntity;

  if (parser->m_freeInternalEntities) {
    openEntity = parser->m_freeInternalEntities;
    parser->m_freeInternalEntities = openEntity->next;
  }
  else {
    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY));
    if (!openEntity)
      return XML_ERROR_NO_MEMORY;
  }
  entity->open = XML_TRUE;
  entity->processed = 0;
  openEntity->next = parser->m_openInternalEntities;
  parser->m_openInternalEntities = openEntity;
  openEntity->entity = entity;
  openEntity->startTagLevel = parser->m_tagLevel;
  openEntity->betweenDecl = betweenDecl;
  openEntity->internalEventPtr = NULL;
  openEntity->internalEventEndPtr = NULL;
  textStart = (char *)entity->textPtr;
  textEnd = (char *)(entity->textPtr + entity->textLen);
  /* Set a safe default value in case 'next' does not get set */
  next = textStart;

#ifdef XML_DTD
  if (entity->is_param) {
    int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok,
                      next, &next, XML_FALSE);
  }
  else
#endif /* XML_DTD */
    result = doContent(parser, parser->m_tagLevel, parser->m_internalEncoding, textStart,
                       textEnd, &next, XML_FALSE);

  if (result == XML_ERROR_NONE) {
    if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
      entity->processed = (int)(next - textStart);
      parser->m_processor = internalEntityProcessor;
    }
    else {
      entity->open = XML_FALSE;
      parser->m_openInternalEntities = openEntity->next;
      /* put openEntity back in list of free instances */
      openEntity->next = parser->m_freeInternalEntities;
      parser->m_freeInternalEntities = openEntity;
    }
  }
  return result;
}

static enum XML_Error PTRCALL
internalEntityProcessor(XML_Parser parser,
................................................................................
                        const char *end,
                        const char **nextPtr)
{
  ENTITY *entity;
  const char *textStart, *textEnd;
  const char *next;
  enum XML_Error result;
  OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
  if (!openEntity)
    return XML_ERROR_UNEXPECTED_STATE;

  entity = openEntity->entity;
  textStart = ((char *)entity->textPtr) + entity->processed;
  textEnd = (char *)(entity->textPtr + entity->textLen);
  /* Set a safe default value in case 'next' does not get set */
  next = textStart;

#ifdef XML_DTD
  if (entity->is_param) {
    int tok = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next);
    result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd, tok,
                      next, &next, XML_FALSE);
  }
  else
#endif /* XML_DTD */
    result = doContent(parser, openEntity->startTagLevel, parser->m_internalEncoding,
                       textStart, textEnd, &next, XML_FALSE);

  if (result != XML_ERROR_NONE)
    return result;
  else if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
    entity->processed = (int)(next - (char *)entity->textPtr);
    return result;
  }
  else {
    entity->open = XML_FALSE;
    parser->m_openInternalEntities = openEntity->next;
    /* put openEntity back in list of free instances */
    openEntity->next = parser->m_freeInternalEntities;
    parser->m_freeInternalEntities = openEntity;
  }

#ifdef XML_DTD
  if (entity->is_param) {
    int tok;
    parser->m_processor = prologProcessor;
    tok = XmlPrologTok(parser->m_encoding, s, end, &next);
    return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
                    (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  }
  else
#endif /* XML_DTD */
  {
    parser->m_processor = contentProcessor;
    /* see externalEntityContentProcessor vs contentProcessor */
    return doContent(parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, s, end,
                     nextPtr, (XML_Bool)!parser->m_parsingStatus.finalBuffer);
  }
}

static enum XML_Error PTRCALL
errorProcessor(XML_Parser parser,
               const char *UNUSED_P(s),
               const char *UNUSED_P(end),
               const char **UNUSED_P(nextPtr))
{
  return parser->m_errorCode;
}

static enum XML_Error
storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
                    const char *ptr, const char *end,
                    STRING_POOL *pool)
{
................................................................................
}

static enum XML_Error
appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
                     const char *ptr, const char *end,
                     STRING_POOL *pool)
{
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  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 == parser->m_encoding)
        parser->m_eventPtr = next;
      return XML_ERROR_INVALID_TOKEN;
    case XML_TOK_PARTIAL:
      if (enc == parser->m_encoding)
        parser->m_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 == parser->m_encoding)
            parser->m_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);
        /* The XmlEncode() functions can never return 0 here.  That
         * error return happens if the code point passed in is either
         * negative or greater than or equal to 0x110000.  The
         * XmlCharRefNumber() functions will all return a number

         * strictly less than 0x110000 or a negative value if an error
         * occurred.  The negative value is intercepted above, so
         * XmlEncode() is never passed a value it might return an
         * error for.
         */
        for (i = 0; i < n; i++) {
          if (!poolAppendChar(pool, buf[i]))
            return XML_ERROR_NO_MEMORY;
        }
      }
      break;
    case XML_TOK_DATA_CHARS:
................................................................................
                                              ptr + enc->minBytesPerChar,
                                              next - enc->minBytesPerChar);
        if (ch) {
          if (!poolAppendChar(pool, ch))
                return XML_ERROR_NO_MEMORY;
          break;
        }
        name = poolStoreString(&parser->m_temp2Pool, enc,
                               ptr + enc->minBytesPerChar,
                               next - enc->minBytesPerChar);
        if (!name)
          return XML_ERROR_NO_MEMORY;
        entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
        poolDiscard(&parser->m_temp2Pool);
        /* First, determine if a check for an existing declaration is needed;
           if yes, check that the entity exists, and that it is internal.
        */
        if (pool == &dtd->pool)  /* are we called from prolog? */
          checkEntityDecl =
#ifdef XML_DTD
              parser->m_prologState.documentEntity &&
#endif /* XML_DTD */
              (dtd->standalone
               ? !parser->m_openInternalEntities
               : !dtd->hasParamEntityRefs);
        else /* if (pool == &parser->m_tempPool): we are called from content */
          checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
        if (checkEntityDecl) {
          if (!entity)
            return XML_ERROR_UNDEFINED_ENTITY;
          else if (!entity->is_internal)
            return XML_ERROR_ENTITY_DECLARED_IN_PE;
        }
        else if (!entity) {
          /* Cannot report skipped entity here - see comments on
             parser->m_skippedEntityHandler.
          if (parser->m_skippedEntityHandler)
            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
          */
          /* Cannot call the default handler because this would be
             out of sync with the call to the startElementHandler.
          if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
            reportDefault(parser, enc, ptr, next);
          */
          break;
        }
        if (entity->open) {
          if (enc == parser->m_encoding) {
            /* It does not appear that this line can be executed.
             *
             * The "if (entity->open)" check catches recursive entity
             * definitions.  In order to be called with an open
             * entity, it must have gone through this code before and
             * been through the recursive call to
             * appendAttributeValue() some lines below.  That call
             * sets the local encoding ("enc") to the parser's
             * internal encoding (internal_utf8 or internal_utf16),
             * which can never be the same as the principle encoding.
             * It doesn't appear there is another code path that gets
             * here with entity->open being TRUE.
             *
             * Since it is not certain that this logic is watertight,
             * we keep the line and merely exclude it from coverage
             * tests.
             */
            parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
          }
          return XML_ERROR_RECURSIVE_ENTITY_REF;
        }
        if (entity->notation) {
          if (enc == parser->m_encoding)
            parser->m_eventPtr = ptr;
          return XML_ERROR_BINARY_ENTITY_REF;
        }
        if (!entity->textPtr) {
          if (enc == parser->m_encoding)
            parser->m_eventPtr = ptr;
          return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
        }
        else {
          enum XML_Error result;
          const XML_Char *textEnd = entity->textPtr + entity->textLen;
          entity->open = XML_TRUE;
          result = appendAttributeValue(parser, parser->m_internalEncoding, isCdata,
                                        (char *)entity->textPtr,
                                        (char *)textEnd, pool);
          entity->open = XML_FALSE;
          if (result)
            return result;
        }
      }
      break;
    default:
      /* The only token returned by XmlAttributeValueTok() that does
       * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
       * Getting that would require an entity name to contain an
       * incomplete XML character (e.g. \xE2\x82); however previous
       * tokenisers will have already recognised and rejected such
       * names before XmlAttributeValueTok() gets a look-in.  This
       * default case should be retained as a safety net, but the code
       * excluded from coverage tests.
       *
       * LCOV_EXCL_START
       */
      if (enc == parser->m_encoding)
        parser->m_eventPtr = ptr;
      return XML_ERROR_UNEXPECTED_STATE;
      /* LCOV_EXCL_STOP */
    }
    ptr = next;
  }
  /* not reached */
}

static enum XML_Error
storeEntityValue(XML_Parser parser,
                 const ENCODING *enc,
                 const char *entityTextPtr,
                 const char *entityTextEnd)
{
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  STRING_POOL *pool = &(dtd->entityValuePool);
  enum XML_Error result = XML_ERROR_NONE;
#ifdef XML_DTD
  int oldInEntityValue = parser->m_prologState.inEntityValue;
  parser->m_prologState.inEntityValue = 1;
#endif /* XML_DTD */
  /* never return Null for the value argument in EntityDeclHandler,
     since this would indicate an external entity; therefore we
     have to make sure that entityValuePool.start is not null */
  if (!pool->blocks) {
    if (!poolGrow(pool))
      return XML_ERROR_NO_MEMORY;
................................................................................

  for (;;) {
    const char *next;
    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
    switch (tok) {
    case XML_TOK_PARAM_ENTITY_REF:
#ifdef XML_DTD
      if (parser->m_isParamEntity || enc != parser->m_encoding) {
        const XML_Char *name;
        ENTITY *entity;
        name = poolStoreString(&parser->m_tempPool, enc,
                               entityTextPtr + enc->minBytesPerChar,
                               next - enc->minBytesPerChar);
        if (!name) {
          result = XML_ERROR_NO_MEMORY;
          goto endEntityValue;
        }
        entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
        poolDiscard(&parser->m_tempPool);
        if (!entity) {
          /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
          /* cannot report skipped entity here - see comments on
             parser->m_skippedEntityHandler
          if (parser->m_skippedEntityHandler)
            parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
          */
          dtd->keepProcessing = dtd->standalone;
          goto endEntityValue;
        }
        if (entity->open) {
          if (enc == parser->m_encoding)
            parser->m_eventPtr = entityTextPtr;
          result = XML_ERROR_RECURSIVE_ENTITY_REF;
          goto endEntityValue;
        }
        if (entity->systemId) {
          if (parser->m_externalEntityRefHandler) {
            dtd->paramEntityRead = XML_FALSE;
            entity->open = XML_TRUE;
            if (!parser->m_externalEntityRefHandler(parser->m_externalEntityRefHandlerArg,
                                          0,
                                          entity->base,
                                          entity->systemId,
                                          entity->publicId)) {
              entity->open = XML_FALSE;
              result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
              goto endEntityValue;
................................................................................
          }
          else
            dtd->keepProcessing = dtd->standalone;
        }
        else {
          entity->open = XML_TRUE;
          result = storeEntityValue(parser,
                                    parser->m_internalEncoding,
                                    (char *)entity->textPtr,
                                    (char *)(entity->textPtr
                                             + entity->textLen));
          entity->open = XML_FALSE;
          if (result)
            goto endEntityValue;
        }
        break;
      }
#endif /* XML_DTD */
      /* In the internal subset, PE references are not legal
         within markup declarations, e.g entity values in this case. */
      parser->m_eventPtr = entityTextPtr;
      result = XML_ERROR_PARAM_ENTITY_REF;
      goto endEntityValue;
    case XML_TOK_NONE:
      result = XML_ERROR_NONE;
      goto endEntityValue;
    case XML_TOK_ENTITY_REF:
    case XML_TOK_DATA_CHARS:
................................................................................
      break;
    case XML_TOK_CHAR_REF:
      {
        XML_Char buf[XML_ENCODE_MAX];
        int i;
        int n = XmlCharRefNumber(enc, entityTextPtr);
        if (n < 0) {
          if (enc == parser->m_encoding)
            parser->m_eventPtr = entityTextPtr;
          result = XML_ERROR_BAD_CHAR_REF;
          goto endEntityValue;
        }
        n = XmlEncode(n, (ICHAR *)buf);
        /* The XmlEncode() functions can never return 0 here.  That
         * error return happens if the code point passed in is either
         * negative or greater than or equal to 0x110000.  The
         * XmlCharRefNumber() functions will all return a number
         * strictly less than 0x110000 or a negative value if an error

         * occurred.  The negative value is intercepted above, so
         * XmlEncode() is never passed a value it might return an
         * error for.
         */
        for (i = 0; i < n; i++) {
          if (pool->end == pool->ptr && !poolGrow(pool)) {
            result = XML_ERROR_NO_MEMORY;
            goto endEntityValue;
          }
          *(pool->ptr)++ = buf[i];
        }
      }
      break;
    case XML_TOK_PARTIAL:
      if (enc == parser->m_encoding)
        parser->m_eventPtr = entityTextPtr;
      result = XML_ERROR_INVALID_TOKEN;
      goto endEntityValue;
    case XML_TOK_INVALID:
      if (enc == parser->m_encoding)
        parser->m_eventPtr = next;
      result = XML_ERROR_INVALID_TOKEN;
      goto endEntityValue;
    default:
      /* This default case should be unnecessary -- all the tokens
       * that XmlEntityValueTok() can return have their own explicit
       * cases -- but should be retained for safety.  We do however
       * exclude it from the coverage statistics.
       *
       * LCOV_EXCL_START
       */
      if (enc == parser->m_encoding)
        parser->m_eventPtr = entityTextPtr;
      result = XML_ERROR_UNEXPECTED_STATE;
      goto endEntityValue;
      /* LCOV_EXCL_STOP */
    }
    entityTextPtr = next;
  }
endEntityValue:
#ifdef XML_DTD
  parser->m_prologState.inEntityValue = oldInEntityValue;
#endif /* XML_DTD */
  return result;
}

static void FASTCALL
normalizeLines(XML_Char *s)
{
................................................................................
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 (!parser->m_processingInstructionHandler) {
    if (parser->m_defaultHandler)
      reportDefault(parser, enc, start, end);
    return 1;
  }
  start += enc->minBytesPerChar * 2;
  tem = start + XmlNameLength(enc, start);
  target = poolStoreString(&parser->m_tempPool, enc, start, tem);
  if (!target)
    return 0;
  poolFinish(&parser->m_tempPool);
  data = poolStoreString(&parser->m_tempPool, enc,
                        XmlSkipS(enc, tem),
                        end - enc->minBytesPerChar*2);
  if (!data)
    return 0;
  normalizeLines(data);
  parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
  poolClear(&parser->m_tempPool);
  return 1;
}

static int
reportComment(XML_Parser parser, const ENCODING *enc,
              const char *start, const char *end)
{
  XML_Char *data;
  if (!parser->m_commentHandler) {
    if (parser->m_defaultHandler)
      reportDefault(parser, enc, start, end);
    return 1;
  }
  data = poolStoreString(&parser->m_tempPool,
                         enc,
                         start + enc->minBytesPerChar * 4,
                         end - enc->minBytesPerChar * 3);
  if (!data)
    return 0;
  normalizeLines(data);
  parser->m_commentHandler(parser->m_handlerArg, data);
  poolClear(&parser->m_tempPool);
  return 1;
}

static void
reportDefault(XML_Parser parser, const ENCODING *enc,
              const char *s, const char *end)
{
  if (MUST_CONVERT(enc, s)) {
    enum XML_Convert_Result convert_res;
    const char **eventPP;
    const char **eventEndPP;
    if (enc == parser->m_encoding) {
      eventPP = &parser->m_eventPtr;
      eventEndPP = &parser->m_eventEndPtr;
    }
    else {
      /* To get here, two things must be true; the parser must be
       * using a character encoding that is not the same as the
       * encoding passed in, and the encoding passed in must need
       * conversion to the internal format (UTF-8 unless XML_UNICODE
       * is defined).  The only occasions on which the encoding passed
       * in is not the same as the parser's encoding are when it is
       * the internal encoding (e.g. a previously defined parameter
       * entity, already converted to internal format).  This by
       * definition doesn't need conversion, so the whole branch never
       * gets executed.
       *
       * For safety's sake we don't delete these lines and merely
       * exclude them from coverage statistics.
       *
       * LCOV_EXCL_START
       */
      eventPP = &(parser->m_openInternalEntities->internalEventPtr);
      eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
      /* LCOV_EXCL_STOP */
    }
    do {
      ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
      convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd);
      *eventEndPP = s;

      parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf, (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
      *eventPP = s;

    } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
  }
  else
    parser->m_defaultHandler(parser->m_handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
}


static int
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
                XML_Bool isId, const XML_Char *value, XML_Parser parser)
{
................................................................................
        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 = (DEFAULT_ATTRIBUTE *)MALLOC(parser, type->allocDefaultAtts
                            * sizeof(DEFAULT_ATTRIBUTE));
      if (!type->defaultAtts) {
        type->allocDefaultAtts = 0;
        return 0;
      }
    }
    else {
      DEFAULT_ATTRIBUTE *temp;
      int count = type->allocDefaultAtts * 2;
      temp = (DEFAULT_ATTRIBUTE *)
        REALLOC(parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
      if (temp == NULL)
        return 0;
      type->allocDefaultAtts = count;
      type->defaultAtts = temp;
    }
  }
  att = type->defaultAtts + type->nDefaultAtts;
................................................................................
  type->nDefaultAtts += 1;
  return 1;
}

static int
setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
{
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  const XML_Char *name;
  for (name = elementType->name; *name; name++) {
    if (*name == XML_T(ASCII_COLON)) {
      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(parser, &dtd->prefixes, poolStart(&dtd->pool),
                                sizeof(PREFIX));
      if (!prefix)
        return 0;
      if (prefix->name == poolStart(&dtd->pool))
        poolFinish(&dtd->pool);
      else
        poolDiscard(&dtd->pool);
................................................................................
  return 1;
}

static ATTRIBUTE_ID *
getAttributeId(XML_Parser parser, const ENCODING *enc,
               const char *start, const char *end)
{
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  ATTRIBUTE_ID *id;
  const XML_Char *name;
  if (!poolAppendChar(&dtd->pool, XML_T('\0')))
    return NULL;
  name = poolStoreString(&dtd->pool, enc, start, end);
  if (!name)
    return NULL;
  /* skip quotation mark - its storage will be re-used (like in name[-1]) */
  ++name;
  id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
  if (!id)
    return NULL;
  if (id->name != name)
    poolDiscard(&dtd->pool);
  else {
    poolFinish(&dtd->pool);
    if (!parser->m_ns)
      ;
    else if (name[0] == XML_T(ASCII_x)
        && name[1] == XML_T(ASCII_m)
        && name[2] == XML_T(ASCII_l)
        && name[3] == XML_T(ASCII_n)
        && name[4] == XML_T(ASCII_s)
        && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
      if (name[5] == XML_T('\0'))
        id->prefix = &dtd->defaultPrefix;
      else
        id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
      id->xmlns = XML_TRUE;
    }
    else {
      int i;
      for (i = 0; name[i]; i++) {
        /* attributes without prefix are *not* in the default namespace */
        if (name[i] == XML_T(ASCII_COLON)) {
................................................................................
          int j;
          for (j = 0; j < i; j++) {
            if (!poolAppendChar(&dtd->pool, name[j]))
              return NULL;
          }
          if (!poolAppendChar(&dtd->pool, XML_T('\0')))
            return NULL;
          id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
                                        sizeof(PREFIX));
          if (!id->prefix)
            return NULL;
          if (id->prefix->name == poolStart(&dtd->pool))
            poolFinish(&dtd->pool);
          else
            poolDiscard(&dtd->pool);
          break;
        }
      }
................................................................................
}

#define CONTEXT_SEP XML_T(ASCII_FF)

static const XML_Char *
getContext(XML_Parser parser)
{
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  HASH_TABLE_ITER iter;
  XML_Bool needSep = XML_FALSE;

  if (dtd->defaultPrefix.binding) {
    int i;
    int len;
    if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
      return NULL;
    len = dtd->defaultPrefix.binding->uriLen;
    if (parser->m_namespaceSeparator)
      len--;
    for (i = 0; i < len; i++) {
      if (!poolAppendChar(&parser->m_tempPool, dtd->defaultPrefix.binding->uri[i])) {
        /* Because of memory caching, I don't believe this line can be
         * executed.
         *
         * This is part of a loop copying the default prefix binding
         * URI into the parser's temporary string pool.  Previously,
         * that URI was copied into the same string pool, with a
         * terminating NUL character, as part of setContext().  When
         * the pool was cleared, that leaves a block definitely big
         * enough to hold the URI on the free block list of the pool.
         * The URI copy in getContext() therefore cannot run out of
         * memory.
         *
         * If the pool is used between the setContext() and
         * getContext() calls, the worst it can do is leave a bigger
         * block on the front of the free list.  Given that this is
         * all somewhat inobvious and program logic can be changed, we
         * don't delete the line but we do exclude it from the test
         * coverage statistics.
         */
        return NULL; /* LCOV_EXCL_LINE */
      }
    }
    needSep = XML_TRUE;
  }

  hashTableIterInit(&iter, &(dtd->prefixes));
  for (;;) {
    int i;
    int len;
    const XML_Char *s;
    PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
    if (!prefix)
      break;
    if (!prefix->binding) {
      /* This test appears to be (justifiable) paranoia.  There does
       * not seem to be a way of injecting a prefix without a binding
       * that doesn't get errored long before this function is called.
       * The test should remain for safety's sake, so we instead
       * exclude the following line from the coverage statistics.
       */
      continue; /* LCOV_EXCL_LINE */
    }
    if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
      return NULL;
    for (s = prefix->name; *s; s++)
      if (!poolAppendChar(&parser->m_tempPool, *s))
        return NULL;
    if (!poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)))
      return NULL;
    len = prefix->binding->uriLen;
    if (parser->m_namespaceSeparator)
      len--;
    for (i = 0; i < len; i++)
      if (!poolAppendChar(&parser->m_tempPool, prefix->binding->uri[i]))
        return NULL;
    needSep = XML_TRUE;
  }


  hashTableIterInit(&iter, &(dtd->generalEntities));
  for (;;) {
    const XML_Char *s;
    ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
    if (!e)
      break;
    if (!e->open)
      continue;
    if (needSep && !poolAppendChar(&parser->m_tempPool, CONTEXT_SEP))
      return NULL;
    for (s = e->name; *s; s++)
      if (!poolAppendChar(&parser->m_tempPool, *s))
        return 0;
    needSep = XML_TRUE;
  }

  if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
    return NULL;
  return parser->m_tempPool.start;
}

static XML_Bool
setContext(XML_Parser parser, const XML_Char *context)
{
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  const XML_Char *s = context;

  while (*context != XML_T('\0')) {
    if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
      ENTITY *e;
      if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
        return XML_FALSE;
      e = (ENTITY *)lookup(parser, &dtd->generalEntities, poolStart(&parser->m_tempPool), 0);
      if (e)
        e->open = XML_TRUE;
      if (*s != XML_T('\0'))
        s++;
      context = s;
      poolDiscard(&parser->m_tempPool);
    }
    else if (*s == XML_T(ASCII_EQUALS)) {
      PREFIX *prefix;
      if (poolLength(&parser->m_tempPool) == 0)
        prefix = &dtd->defaultPrefix;
      else {
        if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
          return XML_FALSE;
        prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&parser->m_tempPool),
                                  sizeof(PREFIX));
        if (!prefix)
          return XML_FALSE;
        if (prefix->name == poolStart(&parser->m_tempPool)) {
          prefix->name = poolCopyString(&dtd->pool, prefix->name);
          if (!prefix->name)
            return XML_FALSE;
        }
        poolDiscard(&parser->m_tempPool);
      }
      for (context = s + 1;
           *context != CONTEXT_SEP && *context != XML_T('\0');
           context++)
        if (!poolAppendChar(&parser->m_tempPool, *context))
          return XML_FALSE;
      if (!poolAppendChar(&parser->m_tempPool, XML_T('\0')))
        return XML_FALSE;
      if (addBinding(parser, prefix, NULL, poolStart(&parser->m_tempPool),
                     &parser->m_inheritedBindings) != XML_ERROR_NONE)
        return XML_FALSE;
      poolDiscard(&parser->m_tempPool);
      if (*context != XML_T('\0'))
        ++context;
      s = context;
    }
    else {
      if (!poolAppendChar(&parser->m_tempPool, *s))
        return XML_FALSE;
      s++;
    }
  }
  return XML_TRUE;
}

................................................................................
  ms->free_fcn(p);
}

/* 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(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms)
{
  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(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
      return 0;
  }

  hashTableIterInit(&iter, &(oldDtd->attributeIds));

  /* Copy the attribute id table. */

................................................................................
    /* 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(oldParser, &(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(oldParser, &(newDtd->prefixes),
                                        oldA->prefix->name, 0);
    }
  }

  /* Copy the element type table. */

  hashTableIterInit(&iter, &(oldDtd->elementTypes));
................................................................................
    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(oldParser, &(newDtd->elementTypes), name,
                                  sizeof(ELEMENT_TYPE));
    if (!newE)
      return 0;
    if (oldE->nDefaultAtts) {
      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
          ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
      if (!newE->defaultAtts) {

        return 0;
      }
    }
    if (oldE->idAtt)
      newE->idAtt = (ATTRIBUTE_ID *)
          lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
    newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
    if (oldE->prefix)
      newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
                                      oldE->prefix->name, 0);
    for (i = 0; i < newE->nDefaultAtts; i++) {
      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
          lookup(oldParser, &(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 = NULL;
    }
  }

  /* Copy the entity tables. */
  if (!copyEntityTable(oldParser,
                       &(newDtd->generalEntities),
                       &(newDtd->pool),
                       &(oldDtd->generalEntities)))
      return 0;

#ifdef XML_DTD
  if (!copyEntityTable(oldParser,
                       &(newDtd->paramEntities),
                       &(newDtd->pool),
                       &(oldDtd->paramEntities)))
      return 0;
  newDtd->paramEntityRead = oldDtd->paramEntityRead;
#endif /* XML_DTD */

  newDtd->keepProcessing = oldDtd->keepProcessing;
................................................................................
  newDtd->scaffLevel = oldDtd->scaffLevel;
  newDtd->scaffIndex = oldDtd->scaffIndex;

  return 1;
}  /* End dtdCopy */

static int
copyEntityTable(XML_Parser oldParser,
                HASH_TABLE *newTable,
                STRING_POOL *newPool,
                const HASH_TABLE *oldTable)
{
  HASH_TABLE_ITER iter;
  const XML_Char *cachedOldBase = NULL;
  const XML_Char *cachedNewBase = NULL;

................................................................................
    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(oldParser, 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;
................................................................................
keyeq(KEY s1, KEY s2)
{
  for (; *s1 == *s2; s1++, s2++)
    if (*s1 == 0)
      return XML_TRUE;
  return XML_FALSE;
}

static size_t
keylen(KEY s)
{
  size_t len = 0;
  for (; *s; s++, len++);

  return len;
}

static void
copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key)
{
  key->k[0] = 0;
  key->k[1] = get_hash_secret_salt(parser);
}

static unsigned long FASTCALL
hash(XML_Parser parser, KEY s)
{
  struct siphash state;
  struct sipkey key;
  (void)sip_tobin;
  (void)sip24_valid;
  copy_salt_to_sipkey(parser, &key);
  sip24_init(&state, &key);
  sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
  return (unsigned long)sip24_final(&state);
}

static NAMED *
lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
{
  size_t i;
  if (table->size == 0) {
    size_t tsize;
    if (!createSize)
      return NULL;
    table->power = INIT_POWER;
................................................................................
    tsize = table->size * sizeof(NAMED *);
    table->v = (NAMED **)table->mem->malloc_fcn(tsize);
    if (!table->v) {
      table->size = 0;
      return NULL;
    }
    memset(table->v, 0, tsize);
    i = hash(parser, name) & ((unsigned long)table->size - 1);
  }
  else {
    unsigned long h = hash(parser, name);
    unsigned long mask = (unsigned long)table->size - 1;
    unsigned char step = 0;
    i = h & mask;
    while (table->v[i]) {
      if (keyeq(name, table->v[i]->name))
        return table->v[i];
      if (!step)
................................................................................
      size_t tsize = newSize * sizeof(NAMED *);
      NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize);
      if (!newV)
        return NULL;
      memset(newV, 0, tsize);
      for (i = 0; i < table->size; i++)
        if (table->v[i]) {
          unsigned long newHash = hash(parser, table->v[i]->name);
          size_t j = newHash & newMask;
          step = 0;
          while (newV[j]) {
            if (!step)
              step = PROBE_STEP(newHash, newMask, newPower);
            j < step ? (j += newSize - step) : (j -= step);
          }
................................................................................
static XML_Char *
poolAppend(STRING_POOL *pool, const ENCODING *enc,
           const char *ptr, const char *end)
{
  if (!pool->ptr && !poolGrow(pool))
    return NULL;
  for (;;) {
    const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
    if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
      break;
    if (!poolGrow(pool))
      return NULL;
  }
  return 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)) {
    /* The following line is unreachable given the current usage of
     * poolCopyStringN().  Currently it is called from exactly one
     * place to copy the text of a simple general entity.  By that
     * point, the name of the entity is already stored in the pool, so
     * pool->ptr cannot be NULL.
     *
     * If poolCopyStringN() is used elsewhere as it well might be,
     * this line may well become executable again.  Regardless, this
     * sort of check shouldn't be removed lightly, so we just exclude
     * it from the coverage statistics.
     */
    return NULL; /* LCOV_EXCL_LINE */
  }
  for (; n > 0; --n, s++) {
    if (!poolAppendChar(pool, *s))
      return NULL;
  }
  s = pool->start;
  poolFinish(pool);
  return s;
................................................................................
  if (!poolAppend(pool, enc, ptr, end))
    return NULL;
  if (pool->ptr == pool->end && !poolGrow(pool))
    return NULL;
  *(pool->ptr)++ = 0;
  return pool->start;
}

static size_t
poolBytesToAllocateFor(int blockSize)
{
  /* Unprotected math would be:
  ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
  **
  ** Detect overflow, avoiding _signed_ overflow undefined behavior
  ** For a + b * c we check b * c in isolation first, so that addition of a
  ** on top has no chance of making us accept a small non-negative number
  */
  const size_t stretch = sizeof(XML_Char);  /* can be 4 bytes */

  if (blockSize <= 0)
    return 0;

  if (blockSize > (int)(INT_MAX / stretch))
    return 0;

  {
    const int stretchedBlockSize = blockSize * (int)stretch;
    const int bytesToAllocate = (int)(
        offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
    if (bytesToAllocate < 0)
      return 0;

    return (size_t)bytesToAllocate;
  }
}

static XML_Bool FASTCALL
poolGrow(STRING_POOL *pool)
{
  if (pool->freeBlocks) {
    if (pool->start == 0) {
      pool->blocks = pool->freeBlocks;
................................................................................
      pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
      pool->start = pool->blocks->s;
      pool->end = pool->start + pool->blocks->size;
      return XML_TRUE;
    }
  }
  if (pool->blocks && pool->start == pool->blocks->s) {
    BLOCK *temp;
    int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
    size_t bytesToAllocate;

    /* NOTE: Needs to be calculated prior to calling `realloc`
             to avoid dangling pointers: */
    const ptrdiff_t offsetInsideBlock = pool->ptr - pool->start;

    if (blockSize < 0) {
      /* This condition traps a situation where either more than
       * INT_MAX/2 bytes have already been allocated.  This isn't
       * readily testable, since it is unlikely that an average
       * machine will have that much memory, so we exclude it from the
       * coverage statistics.
       */
      return XML_FALSE; /* LCOV_EXCL_LINE */
    }

    bytesToAllocate = poolBytesToAllocateFor(blockSize);
    if (bytesToAllocate == 0)
      return XML_FALSE;

    temp = (BLOCK *)
      pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate);


    if (temp == NULL)
      return XML_FALSE;
    pool->blocks = temp;
    pool->blocks->size = blockSize;
    pool->ptr = pool->blocks->s + offsetInsideBlock;
    pool->start = pool->blocks->s;
    pool->end = pool->start + blockSize;
  }
  else {
    BLOCK *tem;
    int blockSize = (int)(pool->end - pool->start);
    size_t bytesToAllocate;

    if (blockSize < 0) {
      /* This condition traps a situation where either more than
       * INT_MAX bytes have already been allocated (which is prevented
       * by various pieces of program logic, not least this one, never
       * mind the unlikelihood of actually having that much memory) or
       * the pool control fields have been corrupted (which could
       * conceivably happen in an extremely buggy user handler
       * function).  Either way it isn't readily testable, so we
       * exclude it from the coverage statistics.
       */
      return XML_FALSE;  /* LCOV_EXCL_LINE */
    }

    if (blockSize < INIT_BLOCK_SIZE)
      blockSize = INIT_BLOCK_SIZE;
    else {
      /* Detect overflow, avoiding _signed_ overflow undefined behavior */
      if ((int)((unsigned)blockSize * 2U) < 0) {
        return XML_FALSE;
      }
      blockSize *= 2;
    }

    bytesToAllocate = poolBytesToAllocateFor(blockSize);
    if (bytesToAllocate == 0)
      return XML_FALSE;

    tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);

    if (!tem)
      return XML_FALSE;
    tem->size = blockSize;
    tem->next = pool->blocks;
    pool->blocks = tem;
    if (pool->ptr != pool->start)
      memcpy(tem->s, pool->start,
................................................................................
  }
  return XML_TRUE;
}

static int FASTCALL
nextScaffoldPart(XML_Parser parser)
{
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  CONTENT_SCAFFOLD * me;
  int next;

  if (!dtd->scaffIndex) {
    dtd->scaffIndex = (int *)MALLOC(parser, parser->m_groupSize * sizeof(int));
    if (!dtd->scaffIndex)
      return -1;
    dtd->scaffIndex[0] = 0;
  }

  if (dtd->scaffCount >= dtd->scaffSize) {
    CONTENT_SCAFFOLD *temp;
    if (dtd->scaffold) {
      temp = (CONTENT_SCAFFOLD *)
        REALLOC(parser, dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
      if (temp == NULL)
        return -1;
      dtd->scaffSize *= 2;
    }
    else {
      temp = (CONTENT_SCAFFOLD *)MALLOC(parser, INIT_SCAFFOLD_ELEMENTS
                                        * sizeof(CONTENT_SCAFFOLD));
      if (temp == NULL)
        return -1;
      dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
    }
    dtd->scaffold = temp;
  }
................................................................................
static void
build_node(XML_Parser parser,
           int src_node,
           XML_Content *dest,
           XML_Content **contpos,
           XML_Char **strpos)
{
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  dest->type = dtd->scaffold[src_node].type;
  dest->quant = dtd->scaffold[src_node].quant;
  if (dest->type == XML_CTYPE_NAME) {
    const XML_Char *src;
    dest->name = *strpos;
    src = dtd->scaffold[src_node].name;
    for (;;) {
................................................................................
    dest->name = NULL;
  }
}

static XML_Content *
build_model (XML_Parser parser)
{
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  XML_Content *ret;
  XML_Content *cpos;
  XML_Char * str;
  int allocsize = (dtd->scaffCount * sizeof(XML_Content)
                   + (dtd->contentStringLen * sizeof(XML_Char)));

  ret = (XML_Content *)MALLOC(parser, allocsize);
  if (!ret)
    return NULL;

  str =  (XML_Char *) (&ret[dtd->scaffCount]);
  cpos = &ret[1];

  build_node(parser, 0, ret, &cpos, &str);
................................................................................

static ELEMENT_TYPE *
getElementType(XML_Parser parser,
               const ENCODING *enc,
               const char *ptr,
               const char *end)
{
  DTD * const dtd = parser->m_dtd;  /* save one level of indirection */
  const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
  ELEMENT_TYPE *ret;

  if (!name)
    return NULL;
  ret = (ELEMENT_TYPE *) lookup(parser, &dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
  if (!ret)
    return NULL;
  if (ret->name != name)
    poolDiscard(&dtd->pool);
  else {
    poolFinish(&dtd->pool);
    if (!setElementTypePrefix(parser, ret))
      return NULL;
  }
  return ret;
}

static XML_Char *
copyString(const XML_Char *s,
           const XML_Memory_Handling_Suite *memsuite)
{
    int charsRequired = 0;
    XML_Char *result;

    /* First determine how long the string is */
    while (s[charsRequired] != 0) {
      charsRequired++;
    }
    /* Include the terminator */
    charsRequired++;

    /* Now allocate space for the copy */
    result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
    if (result == NULL)
        return NULL;
    /* Copy the original into place */
    memcpy(result, s, charsRequired * sizeof(XML_Char));
    return result;
}

Changes to expat/xmlrole.c.









1
2





















3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
172
173
174
175
176
177
178







179
180
181
182
183
184
185
186
...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
...
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
...
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
...
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
...
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
...
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
...
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
...
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
...
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
...
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
...
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
...
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
...
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
...
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
...
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
...
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
...
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
...
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
...
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
...
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
...
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
...
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
...
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
...
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
...
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
....
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
....
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
....
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
....
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
....
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
....
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
....
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
....
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293




















1294
1295
1296

1297
1298
1299
1300
1301
1302

1303
1304
1305
1306
1307
1308
1309








/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
   See the file COPYING for copying permission.





















*/

#include <stddef.h>

#ifdef COMPILED_FROM_DSP
#include "winconfig.h"
#elif defined(MACOS_CLASSIC)
#include "macconfig.h"
#elif defined(__amigaos4__)
#include "amigaconfig.h"
#elif defined(__WATCOMC__)
#include "watcomconfig.h"
#else
#ifdef HAVE_EXPAT_CONFIG_H
#include <expat_config.h>
#endif
#endif /* ndef COMPILED_FROM_DSP */

#include "expat_external.h"
#include "internal.h"
#include "xmlrole.h"
#include "ascii.h"

/* Doesn't check:
................................................................................
  case XML_TOK_PROLOG_S:
    return XML_ROLE_NONE;
  case XML_TOK_PI:
    return XML_ROLE_PI;
  case XML_TOK_COMMENT:
    return XML_ROLE_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 common(state, tok);
}

static int PTRCALL
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:
    return XML_ROLE_PI;
  case XML_TOK_COMMENT:
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_DOCTYPE_NONE;
  case XML_TOK_NAME:
  case XML_TOK_PREFIXED_NAME:
    state->handler = doctype1;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_DOCTYPE_NONE;
  case XML_TOK_LITERAL:
    state->handler = doctype3;
    return XML_ROLE_DOCTYPE_PUBLIC_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_DOCTYPE_NONE;
  case XML_TOK_LITERAL:
    state->handler = doctype4;
    return XML_ROLE_DOCTYPE_SYSTEM_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_DOCTYPE_NONE;
  case XML_TOK_OPEN_BRACKET:
    state->handler = internalSubset;
    return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_DOCTYPE_NONE;
  case XML_TOK_DECL_CLOSE:
    state->handler = prolog2;
    return XML_ROLE_DOCTYPE_CLOSE;
................................................................................
}

#endif /* XML_DTD */

static int PTRCALL
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_ENTITY_NONE;
  case XML_TOK_PERCENT:
    state->handler = entity1;
    return XML_ROLE_ENTITY_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ENTITY_NONE;
  case XML_TOK_NAME:
    state->handler = entity7;
    return XML_ROLE_PARAM_ENTITY_NAME;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ENTITY_NONE;
  case XML_TOK_LITERAL:
    state->handler = entity4;
    return XML_ROLE_ENTITY_PUBLIC_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ENTITY_NONE;
  case XML_TOK_LITERAL:
    state->handler = entity5;
    return XML_ROLE_ENTITY_SYSTEM_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ENTITY_NONE;
  case XML_TOK_NAME:
    state->handler = declClose;
    state->role_none = XML_ROLE_ENTITY_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ENTITY_NONE;
  case XML_TOK_LITERAL:
    state->handler = entity9;
    return XML_ROLE_ENTITY_PUBLIC_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ENTITY_NONE;
  case XML_TOK_LITERAL:
    state->handler = entity10;
    return XML_ROLE_ENTITY_SYSTEM_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
entity10(PROLOG_STATE *state,
         int tok,
         const char *ptr,
         const char *end,
         const ENCODING *enc)
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ENTITY_NONE;
  case XML_TOK_DECL_CLOSE:
    setTopLevel(state);
    return XML_ROLE_ENTITY_COMPLETE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_NOTATION_NONE;
  case XML_TOK_NAME:
    state->handler = notation1;
    return XML_ROLE_NOTATION_NAME;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_NOTATION_NONE;
  case XML_TOK_LITERAL:
    state->handler = notation4;
    return XML_ROLE_NOTATION_PUBLIC_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_NOTATION_NONE;
  case XML_TOK_LITERAL:
    state->handler = declClose;
    state->role_none = XML_ROLE_NOTATION_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_NOTATION_NONE;
  case XML_TOK_LITERAL:
    state->handler = declClose;
    state->role_none = XML_ROLE_NOTATION_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ATTLIST_NONE;
  case XML_TOK_NAME:
  case XML_TOK_PREFIXED_NAME:
    state->handler = attlist1;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ATTLIST_NONE;
  case XML_TOK_DECL_CLOSE:
    setTopLevel(state);
    return XML_ROLE_ATTLIST_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ATTLIST_NONE;
  case XML_TOK_NMTOKEN:
  case XML_TOK_NAME:
  case XML_TOK_PREFIXED_NAME:
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ATTLIST_NONE;
  case XML_TOK_CLOSE_PAREN:
    state->handler = attlist8;
    return XML_ROLE_ATTLIST_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ATTLIST_NONE;
  case XML_TOK_OPEN_PAREN:
    state->handler = attlist6;
    return XML_ROLE_ATTLIST_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ATTLIST_NONE;
  case XML_TOK_NAME:
    state->handler = attlist7;
    return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ATTLIST_NONE;
  case XML_TOK_CLOSE_PAREN:
    state->handler = attlist8;
    return XML_ROLE_ATTLIST_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ATTLIST_NONE;
  case XML_TOK_LITERAL:
    state->handler = attlist1;
    return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ELEMENT_NONE;
  case XML_TOK_NAME:
  case XML_TOK_PREFIXED_NAME:
    state->handler = element1;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ELEMENT_NONE;
  case XML_TOK_CLOSE_PAREN:
    state->handler = declClose;
    state->role_none = XML_ROLE_ELEMENT_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ELEMENT_NONE;
  case XML_TOK_NAME:
  case XML_TOK_PREFIXED_NAME:
    state->handler = element5;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ELEMENT_NONE;
  case XML_TOK_CLOSE_PAREN_ASTERISK:
    state->handler = declClose;
    state->role_none = XML_ROLE_ELEMENT_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ELEMENT_NONE;
  case XML_TOK_OPEN_PAREN:
    state->level += 1;
    return XML_ROLE_GROUP_OPEN;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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_ELEMENT_NONE;
  case XML_TOK_CLOSE_PAREN:
    state->level -= 1;
    if (state->level == 0) {
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
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 common(state, tok);
}

static int PTRCALL
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;
................................................................................
}

#endif /* XML_DTD */

static int PTRCALL
declClose(PROLOG_STATE *state,
          int tok,
          const char *ptr,
          const char *end,
          const ENCODING *enc)
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return state->role_none;
  case XML_TOK_DECL_CLOSE:
    setTopLevel(state);
    return state->role_none;
  }
  return common(state, tok);
}





















static int PTRCALL
error(PROLOG_STATE *state,
      int tok,

      const char *ptr,
      const char *end,
      const ENCODING *enc)
{
  return XML_ROLE_NONE;
}


static int FASTCALL
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;
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|

<
<
<
<
<
<




|







 







>
>
>
>
>
>
>
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
<
>
|
|
|



>







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36






37
38
39
40
41
42
43
44
45
46
47
48
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
...
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
...
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
...
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
...
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
...
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
...
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
...
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
...
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
...
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
...
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
...
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
...
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
...
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
...
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
...
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
...
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
...
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
...
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
...
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
...
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
...
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
...
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
...
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
....
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
....
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
....
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
....
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
....
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
....
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
....
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
....
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
....
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344

1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

#include <stddef.h>

#ifdef _WIN32
#include "winconfig.h"






#else
#ifdef HAVE_EXPAT_CONFIG_H
#include <expat_config.h>
#endif
#endif /* ndef _WIN32 */

#include "expat_external.h"
#include "internal.h"
#include "xmlrole.h"
#include "ascii.h"

/* Doesn't check:
................................................................................
  case XML_TOK_PROLOG_S:
    return XML_ROLE_NONE;
  case XML_TOK_PI:
    return XML_ROLE_PI;
  case XML_TOK_COMMENT:
    return XML_ROLE_COMMENT;
  case XML_TOK_BOM:
    /* This case can never arise.  To reach this role function, the
     * parse must have passed through prolog0 and therefore have had
     * some form of input, even if only a space.  At that point, a
     * byte order mark is no longer a valid character (though
     * technically it should be interpreted as a non-breaking space),
     * so will be rejected by the tokenizing stages.
     */
    return XML_ROLE_NONE; /* LCOV_EXCL_LINE */
  case XML_TOK_DECL_OPEN:
    if (!XmlNameMatchesAscii(enc,
                             ptr + 2 * MIN_BYTES_PER_CHAR(enc),
                             end,
                             KW_DOCTYPE))
      break;
    state->handler = doctype0;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
prolog2(PROLOG_STATE *state,
        int tok,
        const char *UNUSED_P(ptr),
        const char *UNUSED_P(end),
        const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_NONE;
  case XML_TOK_PI:
    return XML_ROLE_PI;
  case XML_TOK_COMMENT:
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
doctype0(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_DOCTYPE_NONE;
  case XML_TOK_NAME:
  case XML_TOK_PREFIXED_NAME:
    state->handler = doctype1;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
doctype2(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_DOCTYPE_NONE;
  case XML_TOK_LITERAL:
    state->handler = doctype3;
    return XML_ROLE_DOCTYPE_PUBLIC_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
doctype3(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_DOCTYPE_NONE;
  case XML_TOK_LITERAL:
    state->handler = doctype4;
    return XML_ROLE_DOCTYPE_SYSTEM_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
doctype4(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_DOCTYPE_NONE;
  case XML_TOK_OPEN_BRACKET:
    state->handler = internalSubset;
    return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
doctype5(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_DOCTYPE_NONE;
  case XML_TOK_DECL_CLOSE:
    state->handler = prolog2;
    return XML_ROLE_DOCTYPE_CLOSE;
................................................................................
}

#endif /* XML_DTD */

static int PTRCALL
entity0(PROLOG_STATE *state,
        int tok,
        const char *UNUSED_P(ptr),
        const char *UNUSED_P(end),
        const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ENTITY_NONE;
  case XML_TOK_PERCENT:
    state->handler = entity1;
    return XML_ROLE_ENTITY_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
entity1(PROLOG_STATE *state,
        int tok,
        const char *UNUSED_P(ptr),
        const char *UNUSED_P(end),
        const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ENTITY_NONE;
  case XML_TOK_NAME:
    state->handler = entity7;
    return XML_ROLE_PARAM_ENTITY_NAME;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
entity3(PROLOG_STATE *state,
        int tok,
        const char *UNUSED_P(ptr),
        const char *UNUSED_P(end),
        const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ENTITY_NONE;
  case XML_TOK_LITERAL:
    state->handler = entity4;
    return XML_ROLE_ENTITY_PUBLIC_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
entity4(PROLOG_STATE *state,
        int tok,
        const char *UNUSED_P(ptr),
        const char *UNUSED_P(end),
        const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ENTITY_NONE;
  case XML_TOK_LITERAL:
    state->handler = entity5;
    return XML_ROLE_ENTITY_SYSTEM_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
entity6(PROLOG_STATE *state,
        int tok,
        const char *UNUSED_P(ptr),
        const char *UNUSED_P(end),
        const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ENTITY_NONE;
  case XML_TOK_NAME:
    state->handler = declClose;
    state->role_none = XML_ROLE_ENTITY_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
entity8(PROLOG_STATE *state,
        int tok,
        const char *UNUSED_P(ptr),
        const char *UNUSED_P(end),
        const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ENTITY_NONE;
  case XML_TOK_LITERAL:
    state->handler = entity9;
    return XML_ROLE_ENTITY_PUBLIC_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
entity9(PROLOG_STATE *state,
        int tok,
        const char *UNUSED_P(ptr),
        const char *UNUSED_P(end),
        const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ENTITY_NONE;
  case XML_TOK_LITERAL:
    state->handler = entity10;
    return XML_ROLE_ENTITY_SYSTEM_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
entity10(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ENTITY_NONE;
  case XML_TOK_DECL_CLOSE:
    setTopLevel(state);
    return XML_ROLE_ENTITY_COMPLETE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
notation0(PROLOG_STATE *state,
          int tok,
          const char *UNUSED_P(ptr),
          const char *UNUSED_P(end),
          const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_NOTATION_NONE;
  case XML_TOK_NAME:
    state->handler = notation1;
    return XML_ROLE_NOTATION_NAME;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
notation2(PROLOG_STATE *state,
          int tok,
          const char *UNUSED_P(ptr),
          const char *UNUSED_P(end),
          const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_NOTATION_NONE;
  case XML_TOK_LITERAL:
    state->handler = notation4;
    return XML_ROLE_NOTATION_PUBLIC_ID;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
notation3(PROLOG_STATE *state,
          int tok,
          const char *UNUSED_P(ptr),
          const char *UNUSED_P(end),
          const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_NOTATION_NONE;
  case XML_TOK_LITERAL:
    state->handler = declClose;
    state->role_none = XML_ROLE_NOTATION_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
notation4(PROLOG_STATE *state,
          int tok,
          const char *UNUSED_P(ptr),
          const char *UNUSED_P(end),
          const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_NOTATION_NONE;
  case XML_TOK_LITERAL:
    state->handler = declClose;
    state->role_none = XML_ROLE_NOTATION_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
attlist0(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ATTLIST_NONE;
  case XML_TOK_NAME:
  case XML_TOK_PREFIXED_NAME:
    state->handler = attlist1;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
attlist1(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ATTLIST_NONE;
  case XML_TOK_DECL_CLOSE:
    setTopLevel(state);
    return XML_ROLE_ATTLIST_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
attlist3(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ATTLIST_NONE;
  case XML_TOK_NMTOKEN:
  case XML_TOK_NAME:
  case XML_TOK_PREFIXED_NAME:
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
attlist4(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ATTLIST_NONE;
  case XML_TOK_CLOSE_PAREN:
    state->handler = attlist8;
    return XML_ROLE_ATTLIST_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
attlist5(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ATTLIST_NONE;
  case XML_TOK_OPEN_PAREN:
    state->handler = attlist6;
    return XML_ROLE_ATTLIST_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
attlist6(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ATTLIST_NONE;
  case XML_TOK_NAME:
    state->handler = attlist7;
    return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
attlist7(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ATTLIST_NONE;
  case XML_TOK_CLOSE_PAREN:
    state->handler = attlist8;
    return XML_ROLE_ATTLIST_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
attlist9(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ATTLIST_NONE;
  case XML_TOK_LITERAL:
    state->handler = attlist1;
    return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
element0(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ELEMENT_NONE;
  case XML_TOK_NAME:
  case XML_TOK_PREFIXED_NAME:
    state->handler = element1;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
element3(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ELEMENT_NONE;
  case XML_TOK_CLOSE_PAREN:
    state->handler = declClose;
    state->role_none = XML_ROLE_ELEMENT_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
element4(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ELEMENT_NONE;
  case XML_TOK_NAME:
  case XML_TOK_PREFIXED_NAME:
    state->handler = element5;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
element5(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ELEMENT_NONE;
  case XML_TOK_CLOSE_PAREN_ASTERISK:
    state->handler = declClose;
    state->role_none = XML_ROLE_ELEMENT_NONE;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
element6(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ELEMENT_NONE;
  case XML_TOK_OPEN_PAREN:
    state->level += 1;
    return XML_ROLE_GROUP_OPEN;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
element7(PROLOG_STATE *state,
         int tok,
         const char *UNUSED_P(ptr),
         const char *UNUSED_P(end),
         const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_ELEMENT_NONE;
  case XML_TOK_CLOSE_PAREN:
    state->level -= 1;
    if (state->level == 0) {
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
condSect1(PROLOG_STATE *state,
          int tok,
          const char *UNUSED_P(ptr),
          const char *UNUSED_P(end),
          const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return XML_ROLE_NONE;
  case XML_TOK_OPEN_BRACKET:
    state->handler = externalSubset1;
    state->includeLevel += 1;
................................................................................
  }
  return common(state, tok);
}

static int PTRCALL
condSect2(PROLOG_STATE *state,
          int tok,
          const char *UNUSED_P(ptr),
          const char *UNUSED_P(end),
          const ENCODING *UNUSED_P(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;
................................................................................
}

#endif /* XML_DTD */

static int PTRCALL
declClose(PROLOG_STATE *state,
          int tok,
          const char *UNUSED_P(ptr),
          const char *UNUSED_P(end),
          const ENCODING *UNUSED_P(enc))
{
  switch (tok) {
  case XML_TOK_PROLOG_S:
    return state->role_none;
  case XML_TOK_DECL_CLOSE:
    setTopLevel(state);
    return state->role_none;
  }
  return common(state, tok);
}

/* This function will only be invoked if the internal logic of the
 * parser has broken down.  It is used in two cases:
 *
 * 1: When the XML prolog has been finished.  At this point the
 * processor (the parser level above these role handlers) should
 * switch from prologProcessor to contentProcessor and reinitialise
 * the handler function.
 *
 * 2: When an error has been detected (via common() below).  At this
 * point again the processor should be switched to errorProcessor,
 * which will never call a handler.
 *
 * The result of this is that error() can only be called if the
 * processor switch failed to happen, which is an internal error and
 * therefore we shouldn't be able to provoke it simply by using the
 * library.  It is a necessary backstop, however, so we merely exclude
 * it from the coverage statistics.
 *
 * LCOV_EXCL_START
 */
static int PTRCALL
error(PROLOG_STATE *UNUSED_P(state),

      int UNUSED_P(tok),
      const char *UNUSED_P(ptr),
      const char *UNUSED_P(end),
      const ENCODING *UNUSED_P(enc))
{
  return XML_ROLE_NONE;
}
/* LCOV_EXCL_STOP */

static int FASTCALL
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;

Changes to expat/xmlrole.h.









1
2





















3
4
5
6
7
8
9








/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
   See the file COPYING for copying permission.





















*/

#ifndef XmlRole_INCLUDED
#define XmlRole_INCLUDED 1

#ifdef __VMS
/*      0        1         2         3      0        1         2         3
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

#ifndef XmlRole_INCLUDED
#define XmlRole_INCLUDED 1

#ifdef __VMS
/*      0        1         2         3      0        1         2         3

Changes to expat/xmltok.c.









1
2





















3
4
5

6










7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
...
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
...
218
219
220
221
222
223
224











225
226
227
228
229
230
231
...
314
315
316
317
318
319
320
321



































322
323
324
325
326
327
328



329



330
331
332

333
334
335













336
337

338
339
340









341
342
343
344

345
346
347

348
349




350
351
352
353




354
355
356
357
358
359
360
361

362





363
364
365
366
367
368
369
...
370
371
372
373
374
375
376


377
378
379

380
381
382
383
384
385
386
...
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459





460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492





493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
...
532
533
534
535
536
537
538
539
540
541
542
543
544

545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583




584
585
586
587
588
589
590
...
592
593
594
595
596
597
598




599
600
601
602
603
604
605
606


607
608
609
610
611



612




613
614
615
616
617
618
619
...
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
...
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
...
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
...
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
...
924
925
926
927
928
929
930




931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
....
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
....
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
....
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342





1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
....
1364
1365
1366
1367
1368
1369
1370



1371
1372
1373
1374
1375
1376
1377
....
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
....
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651








/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
   See the file COPYING for copying permission.





















*/

#include <stddef.h>












#ifdef COMPILED_FROM_DSP
#include "winconfig.h"
#elif defined(MACOS_CLASSIC)
#include "macconfig.h"
#elif defined(__amigaos4__)
#include "amigaconfig.h"
#elif defined(__WATCOMC__)
#include "watcomconfig.h"
#else
#ifdef HAVE_EXPAT_CONFIG_H
#include <expat_config.h>
#endif
#endif /* ndef COMPILED_FROM_DSP */

#include "expat_external.h"
#include "internal.h"
#include "xmltok.h"
#include "nametab.h"

#ifdef XML_DTD
................................................................................
#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))
................................................................................
    (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
    : \
    ((p)[1] & 0x80) == 0 \
    || \
    ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))

static int PTRFASTCALL
isNever(const ENCODING *enc, const char *p)
{
  return 0;
}

static int PTRFASTCALL
utf8_isName2(const ENCODING *enc, const char *p)
{
  return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
}

static int PTRFASTCALL
utf8_isName3(const ENCODING *enc, const char *p)
{
  return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
}

#define utf8_isName4 isNever

static int PTRFASTCALL
utf8_isNmstrt2(const ENCODING *enc, const char *p)
{
  return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
}

static int PTRFASTCALL
utf8_isNmstrt3(const ENCODING *enc, const char *p)
{
  return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
}

#define utf8_isNmstrt4 isNever

static int PTRFASTCALL
utf8_isInvalid2(const ENCODING *enc, const char *p)
{
  return UTF8_INVALID2((const unsigned char *)p);
}

static int PTRFASTCALL
utf8_isInvalid3(const ENCODING *enc, const char *p)
{
  return UTF8_INVALID3((const unsigned char *)p);
}

static int PTRFASTCALL
utf8_isInvalid4(const ENCODING *enc, const char *p)
{
  return UTF8_INVALID4((const unsigned char *)p);
}

struct normal_encoding {
  ENCODING enc;
  unsigned char type[256];
................................................................................
 E ## isNmstrt2, \
 E ## isNmstrt3, \
 E ## isNmstrt4, \
 E ## isInvalid2, \
 E ## isInvalid3, \
 E ## isInvalid4












static int FASTCALL checkCharRefNumber(int);

#include "xmltok_impl.h"
#include "ascii.h"

#ifdef XML_MIN_SIZE
#define sb_isNameMin isNever
................................................................................
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 PTRCALL



































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 PTRCALL









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++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
      from += 2;
      break;
    case BT_LEAD3:




      *to++ = (unsigned short)(((from[0] & 0xf) << 12)
                               | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
      from += 3;
      break;
    case BT_LEAD4:
      {
        unsigned long n;
        if (to + 1 == toLim)

          goto after;





        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;
    }
  }


after:
  *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 "iasciitab.h"
#undef BT_COLON
#include "utf8tab.h"
  },
  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
};

static void PTRCALL
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)++ = (char)((c >> 6) | UTF8_cval2);
      *(*toP)++ = (char)((c & 0x3f) | 0x80);
      (*fromP)++;
    }
    else {
      if (*toP == toLim)
        break;
      *(*toP)++ = *(*fromP)++;
    }
  }
}

static void PTRCALL
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 PTRCALL
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 PTRFASTCALL
unicode_byte_type(char hi, char lo)
{
  switch ((unsigned char)hi) {
  case 0xD8: case 0xD9: case 0xDA: case 0xDB:
................................................................................
    }
    break;
  }
  return BT_NONASCII;
}

#define DEFINE_UTF16_TO_UTF8(E) \
static void  PTRCALL \
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) \
................................................................................
                   | (lo2 >> 6) \
                   | 0x80); \
      *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
      break; \
    } \
  } \
  *fromP = from; \




}

#define DEFINE_UTF16_TO_UTF16(E) \
static void  PTRCALL \
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])

................................................................................
    0
#endif
  },
  {
#include "asciitab.h"
#include "latin1tab.h"
  },
  STANDARD_VTABLE(little2_)
};

#endif

static const struct normal_encoding little2_encoding = {
  { VTABLE, 2, 0,
#if BYTEORDER == 1234
................................................................................
  },
  {
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "latin1tab.h"
  },
  STANDARD_VTABLE(little2_)
};

#if BYTEORDER != 4321

#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 \
................................................................................
  0
#endif
  },
  {
#include "asciitab.h"
#include "latin1tab.h"
  },
  STANDARD_VTABLE(big2_)
};

#endif

static const struct normal_encoding big2_encoding = {
  { VTABLE, 2, 0,
#if BYTEORDER == 4321
................................................................................
  },
  {
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "latin1tab.h"
  },
  STANDARD_VTABLE(big2_)
};

#if BYTEORDER != 1234

#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 FASTCALL
................................................................................
{
  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 PTRCALL
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)
................................................................................
    /* 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] = (char)(c | UTF8_cval1);
    return 1;
  }
  if (c < min3) {
    buf[0] = (char)((c >> 6) | UTF8_cval2);
    buf[1] = (char)((c & 0x3f) | 0x80);
................................................................................
  if (c < 0x110000) {
    buf[0] = (char)((c >> 18) | UTF8_cval4);
    buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);
    buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);
    buf[3] = (char)((c & 0x3f) | 0x80);
    return 4;
  }
  return 0;
}

int FASTCALL
XmlUtf16Encode(int charNum, unsigned short *buf)
{
  if (charNum < 0)
    return 0;
................................................................................
unknown_isInvalid(const ENCODING *enc, const char *p)
{
  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
  int c = uenc->convert(uenc->userData, p);
  return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
}

static void PTRCALL
unknown_toUtf8(const ENCODING *enc,
               const char **fromP, const char *fromLim,
               char **toP, const char *toLim)
{
  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
  char buf[XML_UTF8_ENCODE_MAX];
  for (;;) {
    const char *utf8;
    int n;
    if (*fromP == fromLim)
      break;
    utf8 = uenc->utf8[(unsigned char)**fromP];
    n = *utf8++;
    if (n == 0) {
      int c = uenc->convert(uenc->userData, *fromP);
      n = XmlUtf8Encode(c, buf);
      if (n > toLim - *toP)
        break;
      utf8 = buf;
      *fromP += (AS_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 PTRCALL
unknown_toUtf16(const ENCODING *enc,
                const char **fromP, const char *fromLim,
                unsigned short **toP, const unsigned short *toLim)
{
  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
  while (*fromP != fromLim && *toP != toLim) {
    unsigned short c = uenc->utf16[(unsigned char)**fromP];
    if (c == 0) {
      c = (unsigned short)
          uenc->convert(uenc->userData, *fromP);
      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
                 - (BT_LEAD2 - 2));
    }
    else
      (*fromP)++;
    *(*toP)++ = c;
  }





}

ENCODING *
XmlInitUnknownEncoding(void *mem,
                       int *table,
                       CONVERTER convert, 
                       void *userData)
{
  int i;
  struct unknown_encoding *e = (struct unknown_encoding *)mem;
  for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
    ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
  for (i = 0; i < 128; i++)
................................................................................
      /* 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] = (unsigned char)(BT_LEAD2 - (c + 2));
      e->utf8[i][0] = 0;
      e->utf16[i] = 0;
    }
    else if (c < 0x80) {
      if (latin1_encoding.type[c] != BT_OTHER
................................................................................
         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)
................................................................................

#undef NS
#undef ns

ENCODING *
XmlInitUnknownEncodingNS(void *mem,
                         int *table,
                         CONVERTER convert, 
                         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 */
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>

>
>
>
>
>
>
>
>
>
>
|

<
<
<
<
<
<




|







 







<












|









|












|







 







|





|





|







|





|







|





|





|







 







>
>
>
>
>
>
>
>
>
>
>







 







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|



<
<
<
>
>
>
|
>
>
>
|
<
<
>

<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
|

<
>
>
>
>
>
>
>
>
>




>


<
>


>
>
>
>




>
>
>
>







|
>

>
>
>
>
>







 







>
>



>







 







|
|






|



|






|





|
|



|

>
>
>
>
>










|












|


|
|



|

>
>
>
>
>










|












|







 







|
|



|
>
|









|









|







|









|
>
>
>
>







 







>
>
>
>



|
|



>
>


|

<
>
>
>

>
>
>
>







 







|







 







|












|












|







 







|







 







|












|












|







 







>
>
>
>
|









|







 







|







 







|







 







|










|






|






|


|
|
<



|





|











>
>
>
>
>





|







 







>
>
>







 







|







 







|









1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47






48
49
50
51
52
53
54
55
56
57
58
59
..
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
...
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
...
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403



404
405
406
407
408
409
410
411


412
413


414
415
416
417
418
419
420
421
422
423
424
425
426
427

428
429
430

431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
...
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
...
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
...
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
...
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748

749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
...
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
...
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
....
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
....
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
....
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
....
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
....
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
....
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468

1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
....
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
....
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
....
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

#include <stddef.h>
#include <string.h>  /* memcpy */

#if defined(_MSC_VER) && (_MSC_VER <= 1700)
  /* for vs2012/11.0/1700 and earlier Visual Studio compilers */
# define bool   int
# define false  0
# define true   1
#else
# include <stdbool.h>
#endif


#ifdef _WIN32
#include "winconfig.h"






#else
#ifdef HAVE_EXPAT_CONFIG_H
#include <expat_config.h>
#endif
#endif /* ndef _WIN32 */

#include "expat_external.h"
#include "internal.h"
#include "xmltok.h"
#include "nametab.h"

#ifdef XML_DTD
................................................................................
#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(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)] & (1u << ((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)] \
         & (1u << (((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)] \
         & (1u << (((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))
................................................................................
    (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
    : \
    ((p)[1] & 0x80) == 0 \
    || \
    ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))

static int PTRFASTCALL
isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p))
{
  return 0;
}

static int PTRFASTCALL
utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p)
{
  return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
}

static int PTRFASTCALL
utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p)
{
  return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
}

#define utf8_isName4 isNever

static int PTRFASTCALL
utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p)
{
  return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
}

static int PTRFASTCALL
utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p)
{
  return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
}

#define utf8_isNmstrt4 isNever

static int PTRFASTCALL
utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p)
{
  return UTF8_INVALID2((const unsigned char *)p);
}

static int PTRFASTCALL
utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p)
{
  return UTF8_INVALID3((const unsigned char *)p);
}

static int PTRFASTCALL
utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p)
{
  return UTF8_INVALID4((const unsigned char *)p);
}

struct normal_encoding {
  ENCODING enc;
  unsigned char type[256];
................................................................................
 E ## isNmstrt2, \
 E ## isNmstrt3, \
 E ## isNmstrt4, \
 E ## isInvalid2, \
 E ## isInvalid3, \
 E ## isInvalid4

#define NULL_VTABLE \
 /* isName2 */ NULL, \
 /* isName3 */ NULL, \
 /* isName4 */ NULL, \
 /* isNmstrt2 */ NULL, \
 /* isNmstrt3 */ NULL, \
 /* isNmstrt4 */ NULL, \
 /* isInvalid2 */ NULL, \
 /* isInvalid3 */ NULL, \
 /* isInvalid4 */ NULL

static int FASTCALL checkCharRefNumber(int);

#include "xmltok_impl.h"
#include "ascii.h"

#ifdef XML_MIN_SIZE
#define sb_isNameMin isNever
................................................................................
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
};

void
_INTERNAL_trim_to_complete_utf8_characters(const char * from, const char ** fromLimRef)
{
  const char * fromLim = *fromLimRef;
  size_t walked = 0;
  for (; fromLim > from; fromLim--, walked++) {
    const unsigned char prev = (unsigned char)fromLim[-1];
    if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */
      if (walked + 1 >= 4) {
        fromLim += 4 - 1;
        break;
      } else {
        walked = 0;
      }
    } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */
      if (walked + 1 >= 3) {
        fromLim += 3 - 1;
        break;
      } else {
        walked = 0;
      }
    } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */
      if (walked + 1 >= 2) {
        fromLim += 2 - 1;
        break;
      } else {
        walked = 0;
      }
    } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */
      break;
    }
  }
  *fromLimRef = fromLim;
}

static enum XML_Convert_Result PTRCALL
utf8_toUtf8(const ENCODING *UNUSED_P(enc),
            const char **fromP, const char *fromLim,
            char **toP, const char *toLim)
{



  bool input_incomplete = false;
  bool output_exhausted = false;

  /* Avoid copying partial characters (due to limited space). */
  const ptrdiff_t bytesAvailable = fromLim - *fromP;
  const ptrdiff_t bytesStorable = toLim - *toP;
  if (bytesAvailable > bytesStorable) {
    fromLim = *fromP + bytesStorable;


    output_exhausted = true;
  }



  /* Avoid copying partial characters (from incomplete input). */
  {
    const char * const fromLimBefore = fromLim;
    _INTERNAL_trim_to_complete_utf8_characters(*fromP, &fromLim);
    if (fromLim < fromLimBefore) {
      input_incomplete = true;
    }
  }

  {
    const ptrdiff_t bytesToCopy = fromLim - *fromP;
    memcpy(*toP, *fromP, bytesToCopy);
    *fromP += bytesToCopy;

    *toP += bytesToCopy;
  }


  if (output_exhausted)  /* needs to go first */
    return XML_CONVERT_OUTPUT_EXHAUSTED;
  else if (input_incomplete)
    return XML_CONVERT_INPUT_INCOMPLETE;
  else
    return XML_CONVERT_COMPLETED;
}

static enum XML_Convert_Result PTRCALL
utf8_toUtf16(const ENCODING *enc,
             const char **fromP, const char *fromLim,
             unsigned short **toP, const unsigned short *toLim)
{
  enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
  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:
      if (fromLim - from < 2) {
        res = XML_CONVERT_INPUT_INCOMPLETE;
        goto after;
      }
      *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
      from += 2;
      break;
    case BT_LEAD3:
      if (fromLim - from < 3) {
        res = XML_CONVERT_INPUT_INCOMPLETE;
        goto after;
      }
      *to++ = (unsigned short)(((from[0] & 0xf) << 12)
                               | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
      from += 3;
      break;
    case BT_LEAD4:
      {
        unsigned long n;
        if (toLim - to < 2) {
          res = XML_CONVERT_OUTPUT_EXHAUSTED;
          goto after;
        }
        if (fromLim - from < 4) {
          res = XML_CONVERT_INPUT_INCOMPLETE;
          goto after;
        }
        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;
    }
  }
  if (from < fromLim)
    res = XML_CONVERT_OUTPUT_EXHAUSTED;
after:
  *fromP = from;
  *toP = to;
  return res;
}

#ifdef XML_NS
static const struct normal_encoding utf8_encoding_ns = {
  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
  {
#include "asciitab.h"
................................................................................
#include "iasciitab.h"
#undef BT_COLON
#include "utf8tab.h"
  },
  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
};

static enum XML_Convert_Result PTRCALL
latin1_toUtf8(const ENCODING *UNUSED_P(enc),
              const char **fromP, const char *fromLim,
              char **toP, const char *toLim)
{
  for (;;) {
    unsigned char c;
    if (*fromP == fromLim)
      return XML_CONVERT_COMPLETED;
    c = (unsigned char)**fromP;
    if (c & 0x80) {
      if (toLim - *toP < 2)
        return XML_CONVERT_OUTPUT_EXHAUSTED;
      *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
      *(*toP)++ = (char)((c & 0x3f) | 0x80);
      (*fromP)++;
    }
    else {
      if (*toP == toLim)
        return XML_CONVERT_OUTPUT_EXHAUSTED;
      *(*toP)++ = *(*fromP)++;
    }
  }
}

static enum XML_Convert_Result PTRCALL
latin1_toUtf16(const ENCODING *UNUSED_P(enc),
               const char **fromP, const char *fromLim,
               unsigned short **toP, const unsigned short *toLim)
{
  while (*fromP < fromLim && *toP < toLim)
    *(*toP)++ = (unsigned char)*(*fromP)++;

  if ((*toP == toLim) && (*fromP < fromLim))
    return XML_CONVERT_OUTPUT_EXHAUSTED;
  else
    return XML_CONVERT_COMPLETED;
}

#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_) NULL_VTABLE
};

#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_) NULL_VTABLE
};

static enum XML_Convert_Result PTRCALL
ascii_toUtf8(const ENCODING *UNUSED_P(enc),
             const char **fromP, const char *fromLim,
             char **toP, const char *toLim)
{
  while (*fromP < fromLim && *toP < toLim)
    *(*toP)++ = *(*fromP)++;

  if ((*toP == toLim) && (*fromP < fromLim))
    return XML_CONVERT_OUTPUT_EXHAUSTED;
  else
    return XML_CONVERT_COMPLETED;
}

#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_) NULL_VTABLE
};

#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_) NULL_VTABLE
};

static int PTRFASTCALL
unicode_byte_type(char hi, char lo)
{
  switch ((unsigned char)hi) {
  case 0xD8: case 0xD9: case 0xDA: case 0xDB:
................................................................................
    }
    break;
  }
  return BT_NONASCII;
}

#define DEFINE_UTF16_TO_UTF8(E) \
static enum XML_Convert_Result  PTRCALL \
E ## toUtf8(const ENCODING *UNUSED_P(enc), \
            const char **fromP, const char *fromLim, \
            char **toP, const char *toLim) \
{ \
  const char *from = *fromP; \
  fromLim = from + (((fromLim - from) >> 1) << 1);  /* shrink to even */ \
  for (; 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 XML_CONVERT_OUTPUT_EXHAUSTED; \
        } \
        *(*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 XML_CONVERT_OUTPUT_EXHAUSTED; \
      } \
      *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \
      *(*toP)++ = ((lo & 0x3f) | 0x80); \
      break; \
    default: \
      if (toLim -  *toP < 3)  { \
        *fromP = from; \
        return XML_CONVERT_OUTPUT_EXHAUSTED; \
      } \
      /* 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 XML_CONVERT_OUTPUT_EXHAUSTED; \
      } \
      if (fromLim - from < 4) { \
        *fromP = from; \
        return XML_CONVERT_INPUT_INCOMPLETE; \
      } \
      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) \
................................................................................
                   | (lo2 >> 6) \
                   | 0x80); \
      *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
      break; \
    } \
  } \
  *fromP = from; \
  if (from < fromLim) \
    return XML_CONVERT_INPUT_INCOMPLETE; \
  else \
    return XML_CONVERT_COMPLETED; \
}

#define DEFINE_UTF16_TO_UTF16(E) \
static enum XML_Convert_Result  PTRCALL \
E ## toUtf16(const ENCODING *UNUSED_P(enc), \
             const char **fromP, const char *fromLim, \
             unsigned short **toP, const unsigned short *toLim) \
{ \
  enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
  fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1);  /* shrink to even */ \
  /* Avoid copying first half only of surrogate */ \
  if (fromLim - *fromP > ((toLim - *toP) << 1) \
      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
    fromLim -= 2; \

    res = XML_CONVERT_INPUT_INCOMPLETE; \
  } \
  for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \
    *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
  if ((*toP == toLim) && (*fromP < fromLim)) \
    return XML_CONVERT_OUTPUT_EXHAUSTED; \
  else \
    return res; \
}

#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])

................................................................................
    0
#endif
  },
  {
#include "asciitab.h"
#include "latin1tab.h"
  },
  STANDARD_VTABLE(little2_) NULL_VTABLE
};

#endif

static const struct normal_encoding little2_encoding = {
  { VTABLE, 2, 0,
#if BYTEORDER == 1234
................................................................................
  },
  {
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "latin1tab.h"
  },
  STANDARD_VTABLE(little2_) NULL_VTABLE
};

#if BYTEORDER != 4321

#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_) NULL_VTABLE
};

#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_) NULL_VTABLE
};

#endif


#define BIG2_BYTE_TYPE(enc, p) \
 ((p)[0] == 0 \
................................................................................
  0
#endif
  },
  {
#include "asciitab.h"
#include "latin1tab.h"
  },
  STANDARD_VTABLE(big2_) NULL_VTABLE
};

#endif

static const struct normal_encoding big2_encoding = {
  { VTABLE, 2, 0,
#if BYTEORDER == 4321
................................................................................
  },
  {
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "latin1tab.h"
  },
  STANDARD_VTABLE(big2_) NULL_VTABLE
};

#if BYTEORDER != 1234

#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_) NULL_VTABLE
};

#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_) NULL_VTABLE
};

#endif

#undef PREFIX

static int FASTCALL
................................................................................
{
  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)
      /* The following line will never get executed.  streqci() is
       * only called from two places, both of which guarantee to put
       * upper-case strings into s2.
       */
      c2 += ASCII_A - ASCII_a; /* LCOV_EXCL_LINE */
    if (c1 != c2)
      return 0;
    if (!c1)
      break;
  }
  return 1;
}

static void PTRCALL
initUpdatePosition(const ENCODING *UNUSED_P(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)
................................................................................
    /* minN is minimum legal resulting value for N byte sequence */
    min2 = 0x80,
    min3 = 0x800,
    min4 = 0x10000
  };

  if (c < 0)
    return 0; /* LCOV_EXCL_LINE: this case is always eliminated beforehand */
  if (c < min2) {
    buf[0] = (char)(c | UTF8_cval1);
    return 1;
  }
  if (c < min3) {
    buf[0] = (char)((c >> 6) | UTF8_cval2);
    buf[1] = (char)((c & 0x3f) | 0x80);
................................................................................
  if (c < 0x110000) {
    buf[0] = (char)((c >> 18) | UTF8_cval4);
    buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);
    buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);
    buf[3] = (char)((c & 0x3f) | 0x80);
    return 4;
  }
  return 0; /* LCOV_EXCL_LINE: this case too is eliminated before calling */
}

int FASTCALL
XmlUtf16Encode(int charNum, unsigned short *buf)
{
  if (charNum < 0)
    return 0;
................................................................................
unknown_isInvalid(const ENCODING *enc, const char *p)
{
  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
  int c = uenc->convert(uenc->userData, p);
  return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
}

static enum XML_Convert_Result PTRCALL
unknown_toUtf8(const ENCODING *enc,
               const char **fromP, const char *fromLim,
               char **toP, const char *toLim)
{
  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
  char buf[XML_UTF8_ENCODE_MAX];
  for (;;) {
    const char *utf8;
    int n;
    if (*fromP == fromLim)
      return XML_CONVERT_COMPLETED;
    utf8 = uenc->utf8[(unsigned char)**fromP];
    n = *utf8++;
    if (n == 0) {
      int c = uenc->convert(uenc->userData, *fromP);
      n = XmlUtf8Encode(c, buf);
      if (n > toLim - *toP)
        return XML_CONVERT_OUTPUT_EXHAUSTED;
      utf8 = buf;
      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
                 - (BT_LEAD2 - 2));
    }
    else {
      if (n > toLim - *toP)
        return XML_CONVERT_OUTPUT_EXHAUSTED;
      (*fromP)++;
    }
    memcpy(*toP, utf8, n);
    *toP += n;

  }
}

static enum XML_Convert_Result PTRCALL
unknown_toUtf16(const ENCODING *enc,
                const char **fromP, const char *fromLim,
                unsigned short **toP, const unsigned short *toLim)
{
  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
  while (*fromP < fromLim && *toP < toLim) {
    unsigned short c = uenc->utf16[(unsigned char)**fromP];
    if (c == 0) {
      c = (unsigned short)
          uenc->convert(uenc->userData, *fromP);
      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
                 - (BT_LEAD2 - 2));
    }
    else
      (*fromP)++;
    *(*toP)++ = c;
  }

  if ((*toP == toLim) && (*fromP < fromLim))
    return XML_CONVERT_OUTPUT_EXHAUSTED;
  else
    return XML_CONVERT_COMPLETED;
}

ENCODING *
XmlInitUnknownEncoding(void *mem,
                       int *table,
                       CONVERTER convert,
                       void *userData)
{
  int i;
  struct unknown_encoding *e = (struct unknown_encoding *)mem;
  for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
    ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
  for (i = 0; i < 128; i++)
................................................................................
      /* 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;
      /* Multi-byte sequences need a converter function */
      if (!convert)
        return 0;
      e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
      e->utf8[i][0] = 0;
      e->utf16[i] = 0;
    }
    else if (c < 0x80) {
      if (latin1_encoding.type[c] != BT_OTHER
................................................................................
         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)
................................................................................

#undef NS
#undef ns

ENCODING *
XmlInitUnknownEncodingNS(void *mem,
                         int *table,
                         CONVERTER convert,
                         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 */

Changes to expat/xmltok.h.









1
2





















3
4
5
6
7
8
9
...
125
126
127
128
129
130
131






132
133
134
135
136
137
138
139
140
141
142
143
144
145
...
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237








/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
   See the file COPYING for copying permission.





















*/

#ifndef XmlTok_INCLUDED
#define XmlTok_INCLUDED 1

#ifdef __cplusplus
extern "C" {
................................................................................
struct encoding;
typedef struct encoding ENCODING;

typedef int (PTRCALL *SCANNER)(const ENCODING *,
                               const char *,
                               const char *,
                               const char **);







struct encoding {
  SCANNER scanners[XML_N_STATES];
  SCANNER literalScanners[XML_N_LITERAL_TYPES];
  int (PTRCALL *sameName)(const ENCODING *,
                          const char *,
                          const char *);
  int (PTRCALL *nameMatchesAscii)(const ENCODING *,
                                  const char *,
                                  const char *,
                                  const char *);
  int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
  const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
  int (PTRCALL *getAtts)(const ENCODING *enc,
................................................................................
                                 const char *ptr,
                                 const char *end,
                                 POSITION *);
  int (PTRCALL *isPublicId)(const ENCODING *enc,
                            const char *ptr,
                            const char *end,
                            const char **badPtr);
  void (PTRCALL *utf8Convert)(const ENCODING *enc,
                              const char **fromP,
                              const char *fromLim,
                              char **toP,
                              const char *toLim);
  void (PTRCALL *utf16Convert)(const ENCODING *enc,
                               const char **fromP,
                               const char *fromLim,
                               unsigned short **toP,
                               const unsigned short *toLim);
  int minBytesPerChar;
  char isUtf8;
  char isUtf16;
................................................................................

#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) \
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>




<
<
<







 







|




|







 







<
<







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
...
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169



170
171
172
173
174
175
176
...
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
253
254
255
256
257
258
259


260
261
262
263
264
265
266
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

#ifndef XmlTok_INCLUDED
#define XmlTok_INCLUDED 1

#ifdef __cplusplus
extern "C" {
................................................................................
struct encoding;
typedef struct encoding ENCODING;

typedef int (PTRCALL *SCANNER)(const ENCODING *,
                               const char *,
                               const char *,
                               const char **);

enum XML_Convert_Result {
  XML_CONVERT_COMPLETED = 0,
  XML_CONVERT_INPUT_INCOMPLETE = 1,
  XML_CONVERT_OUTPUT_EXHAUSTED = 2  /* and therefore potentially input remaining as well */
};

struct encoding {
  SCANNER scanners[XML_N_STATES];
  SCANNER literalScanners[XML_N_LITERAL_TYPES];



  int (PTRCALL *nameMatchesAscii)(const ENCODING *,
                                  const char *,
                                  const char *,
                                  const char *);
  int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
  const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
  int (PTRCALL *getAtts)(const ENCODING *enc,
................................................................................
                                 const char *ptr,
                                 const char *end,
                                 POSITION *);
  int (PTRCALL *isPublicId)(const ENCODING *enc,
                            const char *ptr,
                            const char *end,
                            const char **badPtr);
  enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc,
                              const char **fromP,
                              const char *fromLim,
                              char **toP,
                              const char *toLim);
  enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc,
                               const char **fromP,
                               const char *fromLim,
                               unsigned short **toP,
                               const unsigned short *toLim);
  int minBytesPerChar;
  char isUtf8;
  char isUtf16;
................................................................................

#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 XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
  (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))

#define XmlNameLength(enc, ptr) \
  (((enc)->nameLength)(enc, ptr))

#define XmlSkipS(enc, ptr) \

Changes to expat/xmltok_impl.c.









1
2





















3
4
5
6
7
8
9
10
11
12
..
82
83
84
85
86
87
88


















89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
...
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
...
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
...
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
...
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
...
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
...
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
...
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
...
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
...
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
...
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
...
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
...
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
...
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
...
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
...
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
...
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
...
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
...
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
...
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
...
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
...
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
....
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
....
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
....
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
....
1200
1201
1202
1203
1204
1205
1206
1207
1208








1209
1210

1211
1212
1213
1214
1215
1216
1217
....
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
....
1258
1259
1260
1261
1262
1263
1264
1265
1266








1267
1268

1269
1270
1271
1272
1273
1274
1275
....
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
....
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
....
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
....
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
....
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
....
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690






1691

1692
1693
1694
1695
1696
1697
1698
....
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
....
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770








/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
   See the file COPYING for copying permission.





















*/

/* This file is included! */
#ifdef XML_TOK_IMPL_C

#ifndef IS_INVALID_CHAR
#define IS_INVALID_CHAR(enc, ptr, n) (0)
#endif

#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
................................................................................
  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 PTRCALL
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;
        }
................................................................................

/* ptr points to character following "<!" */

static int PTRCALL
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 */
................................................................................
      return XML_TOK_INVALID;
    }
  }
  return XML_TOK_PARTIAL;
}

static int PTRCALL
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)) {
................................................................................

static int PTRCALL
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);
................................................................................
      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 PTRCALL
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 PTRCALL
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) {
    size_t n = end - ptr;
    if (n & (MINBPC(enc) - 1)) {
      n &= ~(MINBPC(enc) - 1);
      if (n == 0)
        return XML_TOK_PARTIAL;
      end = ptr + n;
    }
  }
  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 points to character following "</" */

static int PTRCALL
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:
................................................................................

/* ptr points to character following "&#X" */

static int PTRCALL
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;
................................................................................

/* ptr points to character following "&#" */

static int PTRCALL
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:
................................................................................

/* ptr points to character following "&" */

static int PTRCALL
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;
................................................................................
static int PTRCALL
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:
................................................................................
      {
        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:
................................................................................
            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:
            {
................................................................................
            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;
................................................................................
        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:
................................................................................
static int PTRCALL
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;
  }
#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:
................................................................................
    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:
................................................................................
  return XML_TOK_PARTIAL;
}

static int PTRCALL
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) {
    size_t n = end - ptr;
    if (n & (MINBPC(enc) - 1)) {
      n &= ~(MINBPC(enc) - 1);
      if (n == 0)
        return XML_TOK_PARTIAL;
................................................................................
  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;
         }
................................................................................

/* ptr points to character following "%" */

static int PTRCALL
PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
                    const char **nextTokPtr)
{
  if (ptr == end)
    return -XML_TOK_PERCENT;
  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_PARTIAL;
}

static int PTRCALL
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:
................................................................................
}

static int PTRCALL
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:
................................................................................
}

static int PTRCALL
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) {
    size_t n = end - ptr;
    if (n & (MINBPC(enc) - 1)) {
      n &= ~(MINBPC(enc) - 1);
      if (n == 0)
        return XML_TOK_PARTIAL;
................................................................................
  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:
................................................................................
      /* indicate that this might be part of a CR/LF pair */
      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)
................................................................................
    *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);
................................................................................
      break;
    }
    /* 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;
        }
................................................................................
}

static int PTRCALL
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 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;
................................................................................
}

static int PTRCALL
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 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;
................................................................................
  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;
................................................................................

static int PTRCALL
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:
................................................................................
      break;
    }
  }
  /* not reached */
}

static int PTRFASTCALL
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);
................................................................................
        return -1;
    }
  }
  return checkCharRefNumber(result);
}

static int PTRCALL
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:
................................................................................
      break;
    }
  }
  return 0;
}

static int PTRCALL
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 PTRCALL
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 PTRFASTCALL
................................................................................

static void PTRCALL
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
................................................................................
      pos->columnNumber = (XML_Size)-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 = (XML_Size)-1;
      break;
    default:
      ptr += MINBPC(enc);
      break;
    }
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|





|



|
|

|
|







 







|
<







 







|


|
<







 







|







 







|
<






|








|




|
<







 







|
<







 







|






|
<







 







|













|
<



|
<








|
<












|







 







|
<






|



|







 







|








|







 







|









|







 







|
<








|







 







|










|
<













|
<







 







|
<







 







|
<







 







|
<







 







|
<











|
<







 







|
<



|
|







 







|










|
<











|







 







|
<







 







|







 







|










|




|












|












|




|







 







|
<









|







 







|
<






|







 







|








|







 







|







 







|
<







 







|







 







|


|
<












|







 







|












|
<







 







|

>
>
>
>
>
>
>
>

<
>







 







|







 







|

>
>
>
>
>
>
>
>

<
>







 







|







 







|



|
|

|
|







|
|

|
|







 







|







 







|







 







|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|



<
>
>
>
>
>
>
|
>







 







|







 







|







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
...
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
...
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
...
187
188
189
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
...
264
265
266
267
268
269
270
271

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

293
294
295
296
297
298
299
...
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332

333
334
335
336
337
338
339
...
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361

362
363
364
365

366
367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
...
415
416
417
418
419
420
421
422

423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
...
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
...
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
...
527
528
529
530
531
532
533
534

535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
...
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577

578
579
580
581
582
583
584
585
586
587
588
589
590
591

592
593
594
595
596
597
598
...
607
608
609
610
611
612
613
614

615
616
617
618
619
620
621
...
625
626
627
628
629
630
631
632

633
634
635
636
637
638
639
...
650
651
652
653
654
655
656
657

658
659
660
661
662
663
664
...
667
668
669
670
671
672
673
674

675
676
677
678
679
680
681
682
683
684
685
686

687
688
689
690
691
692
693
...
711
712
713
714
715
716
717
718

719
720
721
722
723
724
725
726
727
728
729
730
...
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756

757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
...
786
787
788
789
790
791
792
793

794
795
796
797
798
799
800
...
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
...
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
...
904
905
906
907
908
909
910
911

912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
...
932
933
934
935
936
937
938
939

940
941
942
943
944
945
946
947
948
949
950
951
952
953
...
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
...
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
....
1010
1011
1012
1013
1014
1015
1016
1017

1018
1019
1020
1021
1022
1023
1024
....
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
....
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075

1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
....
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177

1178
1179
1180
1181
1182
1183
1184
....
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236

1237
1238
1239
1240
1241
1242
1243
1244
....
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
....
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302

1303
1304
1305
1306
1307
1308
1309
1310
....
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
....
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
....
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
....
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
....
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
....
1650
1651
1652
1653
1654
1655
1656
































































1657
1658
1659
1660

1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
....
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
....
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
/* This file is included!
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/


#ifdef XML_TOK_IMPL_C

#ifndef IS_INVALID_CHAR
#define IS_INVALID_CHAR(enc, ptr, n) (0)
#endif

#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
................................................................................
  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


#define HAS_CHARS(enc, ptr, end, count) \
    (end - ptr >= count * MINBPC(enc))

#define HAS_CHAR(enc, ptr, end) \
    HAS_CHARS(enc, ptr, end, 1)

#define REQUIRE_CHARS(enc, ptr, end, count) \
    { \
      if (! HAS_CHARS(enc, ptr, end, count)) { \
        return XML_TOK_PARTIAL; \
      } \
    }

#define REQUIRE_CHAR(enc, ptr, end) \
    REQUIRE_CHARS(enc, ptr, end, 1)


/* ptr points to character following "<!-" */

static int PTRCALL
PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
                    const char *end, const char **nextTokPtr)
{
  if (HAS_CHAR(enc, ptr, end)) {
    if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
      *nextTokPtr = ptr;
      return XML_TOK_INVALID;
    }
    ptr += MINBPC(enc);
    while (HAS_CHAR(enc, ptr, end)) {
      switch (BYTE_TYPE(enc, ptr)) {
      INVALID_CASES(ptr, nextTokPtr)
      case BT_MINUS:
        ptr += MINBPC(enc);
        REQUIRE_CHAR(enc, ptr, end);
        if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
          ptr += MINBPC(enc);
          REQUIRE_CHAR(enc, ptr, end);
          if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
            *nextTokPtr = ptr;
            return XML_TOK_INVALID;
          }
          *nextTokPtr = ptr + MINBPC(enc);
          return XML_TOK_COMMENT;
        }
................................................................................

/* ptr points to character following "<!" */

static int PTRCALL
PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
                 const char *end, const char **nextTokPtr)
{
  REQUIRE_CHAR(enc, ptr, end);

  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 (HAS_CHAR(enc, ptr, end)) {
    switch (BYTE_TYPE(enc, ptr)) {
    case BT_PERCNT:
      REQUIRE_CHARS(enc, ptr, end, 2);

      /* 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 */
................................................................................
      return XML_TOK_INVALID;
    }
  }
  return XML_TOK_PARTIAL;
}

static int PTRCALL
PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(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)) {
................................................................................

static int PTRCALL
PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
               const char *end, const char **nextTokPtr)
{
  int tok;
  const char *target = ptr;
  REQUIRE_CHAR(enc, ptr, end);

  switch (BYTE_TYPE(enc, ptr)) {
  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  default:
    *nextTokPtr = ptr;
    return XML_TOK_INVALID;
  }
  while (HAS_CHAR(enc, 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 (HAS_CHAR(enc, ptr, end)) {
        switch (BYTE_TYPE(enc, ptr)) {
        INVALID_CASES(ptr, nextTokPtr)
        case BT_QUEST:
          ptr += MINBPC(enc);
          REQUIRE_CHAR(enc, ptr, end);

          if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
            *nextTokPtr = ptr + MINBPC(enc);
            return tok;
          }
          break;
        default:
          ptr += MINBPC(enc);
................................................................................
      return XML_TOK_PARTIAL;
    case BT_QUEST:
      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
        *nextTokPtr = ptr;
        return XML_TOK_INVALID;
      }
      ptr += MINBPC(enc);
      REQUIRE_CHAR(enc, ptr, end);

      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 PTRCALL
PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(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[ */
  REQUIRE_CHARS(enc, ptr, end, 6);

  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 PTRCALL
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) {
    size_t n = end - ptr;
    if (n & (MINBPC(enc) - 1)) {
      n &= ~(MINBPC(enc) - 1);
      if (n == 0)
        return XML_TOK_PARTIAL;
      end = ptr + n;
    }
  }
  switch (BYTE_TYPE(enc, ptr)) {
  case BT_RSQB:
    ptr += MINBPC(enc);
    REQUIRE_CHAR(enc, ptr, end);

    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
      break;
    ptr += MINBPC(enc);
    REQUIRE_CHAR(enc, ptr, end);

    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);
    REQUIRE_CHAR(enc, ptr, end);

    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 (HAS_CHAR(enc, 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 points to character following "</" */

static int PTRCALL
PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
                   const char *end, const char **nextTokPtr)
{
  REQUIRE_CHAR(enc, ptr, end);

  switch (BYTE_TYPE(enc, ptr)) {
  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  default:
    *nextTokPtr = ptr;
    return XML_TOK_INVALID;
  }
  while (HAS_CHAR(enc, 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); HAS_CHAR(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:
................................................................................

/* ptr points to character following "&#X" */

static int PTRCALL
PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
                       const char *end, const char **nextTokPtr)
{
  if (HAS_CHAR(enc, 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); HAS_CHAR(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;
................................................................................

/* ptr points to character following "&#" */

static int PTRCALL
PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
                    const char *end, const char **nextTokPtr)
{
  if (HAS_CHAR(enc, 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); HAS_CHAR(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:
................................................................................

/* ptr points to character following "&" */

static int PTRCALL
PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
                const char **nextTokPtr)
{
  REQUIRE_CHAR(enc, ptr, end);

  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 (HAS_CHAR(enc, 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;
................................................................................
static int PTRCALL
PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
                 const char **nextTokPtr)
{
#ifdef XML_NS
  int hadColon = 0;
#endif
  while (HAS_CHAR(enc, 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);
      REQUIRE_CHAR(enc, ptr, end);

      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);
        REQUIRE_CHAR(enc, ptr, end);

        t = BYTE_TYPE(enc, ptr);
        if (t == BT_EQUALS)
          break;
        switch (t) {
        case BT_S:
        case BT_LF:
        case BT_CR:
................................................................................
      {
        int open;
#ifdef XML_NS
        hadColon = 0;
#endif
        for (;;) {
          ptr += MINBPC(enc);
          REQUIRE_CHAR(enc, ptr, end);

          open = BYTE_TYPE(enc, ptr);
          if (open == BT_QUOT || open == BT_APOS)
            break;
          switch (open) {
          case BT_S:
          case BT_LF:
          case BT_CR:
................................................................................
            return XML_TOK_INVALID;
          }
        }
        ptr += MINBPC(enc);
        /* in attribute value */
        for (;;) {
          int t;
          REQUIRE_CHAR(enc, ptr, end);

          t = BYTE_TYPE(enc, ptr);
          if (t == open)
            break;
          switch (t) {
          INVALID_CASES(ptr, nextTokPtr)
          case BT_AMP:
            {
................................................................................
            return XML_TOK_INVALID;
          default:
            ptr += MINBPC(enc);
            break;
          }
        }
        ptr += MINBPC(enc);
        REQUIRE_CHAR(enc, ptr, end);

        switch (BYTE_TYPE(enc, ptr)) {
        case BT_S:
        case BT_CR:
        case BT_LF:
          break;
        case BT_SOL:
          goto sol;
................................................................................
        default:
          *nextTokPtr = ptr;
          return XML_TOK_INVALID;
        }
        /* ptr points to closing quote */
        for (;;) {
          ptr += MINBPC(enc);
          REQUIRE_CHAR(enc, ptr, end);

          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);
            REQUIRE_CHAR(enc, ptr, end);

            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:
................................................................................
static int PTRCALL
PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
               const char **nextTokPtr)
{
#ifdef XML_NS
  int hadColon;
#endif
  REQUIRE_CHAR(enc, ptr, end);

  switch (BYTE_TYPE(enc, ptr)) {
  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  case BT_EXCL:
    ptr += MINBPC(enc);
    REQUIRE_CHAR(enc, ptr, end);
    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;
  }
#ifdef XML_NS
  hadColon = 0;
#endif
  /* we have a start-tag */
  while (HAS_CHAR(enc, 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);
      REQUIRE_CHAR(enc, ptr, end);

      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 (HAS_CHAR(enc, 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:
................................................................................
    case BT_GT:
    gt:
      *nextTokPtr = ptr + MINBPC(enc);
      return XML_TOK_START_TAG_NO_ATTS;
    case BT_SOL:
    sol:
      ptr += MINBPC(enc);
      REQUIRE_CHAR(enc, ptr, end);

      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:
................................................................................
  return XML_TOK_PARTIAL;
}

static int PTRCALL
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) {
    size_t n = end - ptr;
    if (n & (MINBPC(enc) - 1)) {
      n &= ~(MINBPC(enc) - 1);
      if (n == 0)
        return XML_TOK_PARTIAL;
................................................................................
  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 (! HAS_CHAR(enc, 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 (! HAS_CHAR(enc, ptr, end))
      return XML_TOK_TRAILING_RSQB;
    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
      break;
    ptr += MINBPC(enc);
    if (! HAS_CHAR(enc, 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 (HAS_CHAR(enc, 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 (HAS_CHARS(enc, ptr, end, 2)) {
         if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
           ptr += MINBPC(enc);
           break;
         }
         if (HAS_CHARS(enc, ptr, end, 3)) {
           if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
             ptr += MINBPC(enc);
             break;
           }
           *nextTokPtr = ptr + 2*MINBPC(enc);
           return XML_TOK_INVALID;
         }
................................................................................

/* ptr points to character following "%" */

static int PTRCALL
PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
                    const char **nextTokPtr)
{
  REQUIRE_CHAR(enc, ptr, end);

  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 (HAS_CHAR(enc, 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_PARTIAL;
}

static int PTRCALL
PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
                      const char **nextTokPtr)
{
  REQUIRE_CHAR(enc, ptr, end);

  switch (BYTE_TYPE(enc, ptr)) {
  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
  default:
    *nextTokPtr = ptr;
    return XML_TOK_INVALID;
  }
  while (HAS_CHAR(enc, 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:
................................................................................
}

static int PTRCALL
PREFIX(scanLit)(int open, const ENCODING *enc,
                const char *ptr, const char *end,
                const char **nextTokPtr)
{
  while (HAS_CHAR(enc, 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 (! HAS_CHAR(enc, 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:
................................................................................
}

static int PTRCALL
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) {
    size_t n = end - ptr;
    if (n & (MINBPC(enc) - 1)) {
      n &= ~(MINBPC(enc) - 1);
      if (n == 0)
        return XML_TOK_PARTIAL;
................................................................................
  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);
      REQUIRE_CHAR(enc, ptr, end);

      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:
................................................................................
      /* indicate that this might be part of a CR/LF pair */
      return -XML_TOK_PROLOG_S;
    }
    /* fall through */
  case BT_S: case BT_LF:
    for (;;) {
      ptr += MINBPC(enc);
      if (! HAS_CHAR(enc, 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)
................................................................................
    *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 (! HAS_CHAR(enc, ptr, end))
      return -XML_TOK_CLOSE_BRACKET;
    if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
      REQUIRE_CHARS(enc, ptr, end, 2);

      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 (! HAS_CHAR(enc, 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);
................................................................................
      break;
    }
    /* fall through */
  default:
    *nextTokPtr = ptr;
    return XML_TOK_INVALID;
  }
  while (HAS_CHAR(enc, 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:
        REQUIRE_CHAR(enc, ptr, end);

        tok = XML_TOK_PREFIXED_NAME;
        switch (BYTE_TYPE(enc, ptr)) {
        CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
        default:
          tok = XML_TOK_NMTOKEN;
          break;
        }
................................................................................
}

static int PTRCALL
PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
                          const char *end, const char **nextTokPtr)
{
  const char *start;
  if (ptr >= end)
    return XML_TOK_NONE;
  else if (! HAS_CHAR(enc, ptr, end)) {
    /* This line cannot be executed.  The incoming data has already
     * been tokenized once, so incomplete characters like this have
     * already been eliminated from the input.  Retaining the paranoia
     * check is still valuable, however.
     */
    return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */
  }
  start = ptr;

  while (HAS_CHAR(enc, 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 XML_TOK_DATA_NEWLINE;
      }
      *nextTokPtr = ptr;
      return XML_TOK_DATA_CHARS;
    case BT_CR:
      if (ptr == start) {
        ptr += MINBPC(enc);
        if (! HAS_CHAR(enc, 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;
................................................................................
}

static int PTRCALL
PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
                       const char *end, const char **nextTokPtr)
{
  const char *start;
  if (ptr >= end)
    return XML_TOK_NONE;
  else if (! HAS_CHAR(enc, ptr, end)) {
    /* This line cannot be executed.  The incoming data has already
     * been tokenized once, so incomplete characters like this have
     * already been eliminated from the input.  Retaining the paranoia
     * check is still valuable, however.
     */
    return XML_TOK_PARTIAL; /* LCOV_EXCL_LINE */
  }
  start = ptr;

  while (HAS_CHAR(enc, 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 XML_TOK_DATA_NEWLINE;
      }
      *nextTokPtr = ptr;
      return XML_TOK_DATA_CHARS;
    case BT_CR:
      if (ptr == start) {
        ptr += MINBPC(enc);
        if (! HAS_CHAR(enc, 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;
................................................................................
  if (MINBPC(enc) > 1) {
    size_t n = end - ptr;
    if (n & (MINBPC(enc) - 1)) {
      n &= ~(MINBPC(enc) - 1);
      end = ptr + n;
    }
  }
  while (HAS_CHAR(enc, ptr, end)) {
    switch (BYTE_TYPE(enc, ptr)) {
    INVALID_CASES(ptr, nextTokPtr)
    case BT_LT:
      ptr += MINBPC(enc);
      REQUIRE_CHAR(enc, ptr, end);
      if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
        ptr += MINBPC(enc);
        REQUIRE_CHAR(enc, ptr, end);
        if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
          ++level;
          ptr += MINBPC(enc);
        }
      }
      break;
    case BT_RSQB:
      ptr += MINBPC(enc);
      REQUIRE_CHAR(enc, ptr, end);
      if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
        ptr += MINBPC(enc);
        REQUIRE_CHAR(enc, ptr, end);
        if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
          ptr += MINBPC(enc);
          if (level == 0) {
            *nextTokPtr = ptr;
            return XML_TOK_IGNORE_SECT;
          }
          --level;
................................................................................

static int PTRCALL
PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
                   const char **badPtr)
{
  ptr += MINBPC(enc);
  end -= MINBPC(enc);
  for (; HAS_CHAR(enc, 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:
................................................................................
      break;
    }
  }
  /* not reached */
}

static int PTRFASTCALL
PREFIX(charRefNumber)(const ENCODING *UNUSED_P(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);
................................................................................
        return -1;
    }
  }
  return checkCharRefNumber(result);
}

static int PTRCALL
PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(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:
................................................................................
      break;
    }
  }
  return 0;
}

static int PTRCALL
































































PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1,
                         const char *end1, const char *ptr2)
{
  for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {

    if (end1 - ptr1 < MINBPC(enc)) {
      /* This line cannot be executed.  THe incoming data has already
       * been tokenized once, so imcomplete characters like this have
       * already been eliminated from the input.  Retaining the
       * paranoia check is still valuable, however.
       */
      return 0; /* LCOV_EXCL_LINE */
    }
    if (!CHAR_MATCHES(enc, ptr1, *ptr2))
      return 0;
  }
  return ptr1 == end1;
}

static int PTRFASTCALL
................................................................................

static void PTRCALL
PREFIX(updatePosition)(const ENCODING *enc,
                       const char *ptr,
                       const char *end,
                       POSITION *pos)
{
  while (HAS_CHAR(enc, 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
................................................................................
      pos->columnNumber = (XML_Size)-1;
      pos->lineNumber++;
      ptr += MINBPC(enc);
      break;
    case BT_CR:
      pos->lineNumber++;
      ptr += MINBPC(enc);
      if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF)
        ptr += MINBPC(enc);
      pos->columnNumber = (XML_Size)-1;
      break;
    default:
      ptr += MINBPC(enc);
      break;
    }

Changes to expat/xmltok_impl.h.

1







2
3





















4
5
6
7
8
9
10
/*







Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.





















*/

enum {
  BT_NONXML,
  BT_MALFORM,
  BT_LT,
  BT_AMP,

>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/

enum {
  BT_NONXML,
  BT_MALFORM,
  BT_LT,
  BT_AMP,

Changes to expat/xmltok_ns.c.









1
2





















3
4
5
6
7
8
9
10
11
12








/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
   See the file COPYING for copying permission.





















*/

/* This file is included! */
#ifdef XML_TOK_NS_C

const ENCODING *
NS(XmlGetUtf8InternalEncoding)(void)
{
  return &ns(internal_utf8_encoding).enc;
}
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<







1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
/* This file is included!
                            __  __            _
                         ___\ \/ /_ __   __ _| |_
                        / _ \\  /| '_ \ / _` | __|
                       |  __//  \| |_) | (_| | |_
                        \___/_/\_\ .__/ \__,_|\__|
                                 |_| XML parser

   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd

   Copyright (c) 2000-2017 Expat development team
   Licensed under the MIT license:

   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.
*/


#ifdef XML_TOK_NS_C

const ENCODING *
NS(XmlGetUtf8InternalEncoding)(void)
{
  return &ns(internal_utf8_encoding).enc;
}

Changes to extensions/example/Makefile.in.

3
4
5
6
7
8
9
10
11
12
13
14
15



16


17
18



19
20
21
22

23
24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41


42
43
44
45
46
47
48
49
50
51
52
53
54
55

56
57
58
59
60
61

62
63
64
65


66
67
68


69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91


92
93
94
95
96
97
98
99
100
101
102
103
104
105


106
107
108

109
110
111

112
113
114
115
116

117
118
119
120
121
122
123
124

125
126

127
128
129
130
131
132
133
134


135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153


154
155
156
157
158
159

160
161





162
163
164


165
166

167





168

169

170

171
172
173

174
175
176
177


178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
...
193
194
195
196
197
198
199
200
201
202
203






204




205
206
207
208
209
210
211
212
213
214

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249










250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
...
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329




330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
...
370
371
372
373
374
375
376
377
378
379
380
381
382
383





384
385

386
387
388
389
390
391
392
393
394
395
396
397

398
399
400
401




402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432

433
434
435
436
437
438
439
440
441
442
443
#	This file is a Makefile for Sample TEA Extension.  If it has the name
#	"Makefile.in" then it is a template for a Makefile;  to generate the
#	actual Makefile, run "./configure", which is a configuration script
#	generated by the "autoconf" program (constructs like "@foo@" will get
#	replaced in the actual Makefile.
#
# Copyright (c) 1999 Scriptics Corporation.
# Copyright (c) 2002 ActiveState SRL.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id$






#========================================================================
# Edit the following few lines when writing a new extension



#========================================================================

#========================================================================
# Enumerate the names of the source files included in this package.

# This will be used when a dist target is added to the Makefile.
# EXTRA_SOURCES will be replaced by WIN_SOURCES or UNIX_SOURCES, as is
# appropriate for your platform.  It is not important to specify the
# directory, as long as it is the $(srcdir) or in the generic, win or
# unix subdirectory.
#========================================================================

EXAMPLE_SOURCES    = example.c

WIN_SOURCES	= 
UNIX_SOURCES    =


#========================================================================
# Identify the object files.  This replaces .c with .$(OBJEXT) for all
# the named source files.   These objects are created and linked into the
# final library.  In these do not correspond directly to the source files
# above, you will need to enumerate the object files here.
# Normally we would use $(OBJEXT), but certain make executables won't do
# the extra macro in a macro conversion properly.


#
# "sample_LIB_FILE" refers to the library (dynamic or static as per
# configuration options) composed of the named objects.
#========================================================================

example_OBJECTS		= $(EXAMPLE_SOURCES:.c=.@OBJEXT@)
example_LIB_FILE	= @example_LIB_FILE@

#========================================================================
# RUNTIME_SOURCES identifies Tcl runtime files that are associated with
# this package that need to be installed, if any.
#========================================================================

#RUNTIME_SOURCES = example.tcl


#========================================================================
# This is a list of header files to be installed
#========================================================================

GENERIC_HDRS	= 


#========================================================================
# Add additional lines to handle any additional AC_SUBST cases that
# have been added to the configure script.


#========================================================================

# nothing so far



#========================================================================
# Nothing of the variables below this line need to be changed.  Please
# check the TARGETS section below to make sure the make targets are
# correct.
#========================================================================

#========================================================================
# The variable "$(PACKAGE)_LIB_FILE" is the parameterized name of the
# library that we are building.
#========================================================================

lib_BINARIES	= $($(PACKAGE)_LIB_FILE) $($(PACKAGE)stub_LIB_FILE)
BINARIES	= $(lib_BINARIES)

SHELL		= @SHELL@

srcdir		= @srcdir@
prefix		= @prefix@
exec_prefix	= @exec_prefix@

bindir		= @bindir@
libdir		= @libdir@


datadir		= @datadir@
mandir		= @mandir@
includedir	= @includedir@

DESTDIR		=

PKG_DIR		= $(PACKAGE)$(VERSION)
pkgdatadir	= $(datadir)/$(PKG_DIR)
pkglibdir	= $(libdir)/$(PKG_DIR)
pkgincludedir	= $(includedir)/$(PKG_DIR)

top_builddir	= .

INSTALL		= @INSTALL@


INSTALL_PROGRAM	= @INSTALL_PROGRAM@
INSTALL_DATA	= @INSTALL_DATA@
INSTALL_SCRIPT	= @INSTALL_SCRIPT@


PACKAGE		= @PACKAGE@
VERSION		= @VERSION@

CC		= @CC@
CFLAGS_DEBUG	= @CFLAGS_DEBUG@
CFLAGS_DEFAULT	= @CFLAGS_DEFAULT@
CFLAGS_OPTIMIZE	= @CFLAGS_OPTIMIZE@
CLEANFILES	= @CLEANFILES@

EXEEXT		= @EXEEXT@
LDFLAGS_DEBUG	= @LDFLAGS_DEBUG@
LDFLAGS_DEFAULT	= @LDFLAGS_DEFAULT@
LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@
MAKE_LIB	= @MAKE_LIB@
MAKE_STUB_LIB	= @MAKE_STUB_LIB@
MAKE_SHARED_LIB	= @MAKE_SHARED_LIB@
MAKE_STATIC_LIB	= @MAKE_STATIC_LIB@

OBJEXT		= @OBJEXT@
RANLIB		= @RANLIB@

SHLIB_CFLAGS	= @SHLIB_CFLAGS@
SHLIB_LD	= @SHLIB_LD@
SHLIB_LDFLAGS	= @SHLIB_LDFLAGS@
SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
STLIB_LD	= @STLIB_LD@
TCL_DEFS	= @TCL_DEFS@
TCL_BIN_DIR	= @TCL_BIN_DIR@
TCL_SRC_DIR	= @TCL_SRC_DIR@



# This is necessary for packages that use private Tcl headers
#TCL_TOP_DIR_NATIVE	= @TCL_TOP_DIR_NATIVE@

#========================================================================
# This is needed so we can link the custom shell
#========================================================================

TCL_LIBS	= @TCL_LIBS@
TCL_LIB_SPEC	= @TCL_LIB_SPEC@

#========================================================================
# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
# package without installing.  The other environment variables allow us
# to test against an uninstalled Tcl.  Add special env vars that you
# require for testing here (like TCLX_LIBRARY).
#========================================================================

EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR)


TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
		  LD_LIBRARY_PATH="$(EXTRA_PATH):$(LD_LIBRARY_PATH)" \
		  LIBPATH="$(EXTRA_PATH):${LIBPATH}" \
		  SHLIB_PATH="$(EXTRA_PATH):${SHLIB_PATH}" \
		  PATH="$(EXTRA_PATH):$(PATH)" \
		  TCLLIBPATH="$(top_builddir)"

TCLSH_PROG	= @TCLSH_PROG@
TCLSH		= $(TCLSH_ENV) $(TCLSH_PROG)





SHARED_BUILD	= @SHARED_BUILD@

INCLUDES	= @TCL_INCLUDES@ @EXAMPLE_INCLUDES@



EXTRA_CFLAGS	= $(MEM_DEBUG_FLAGS) @EXTRA_CFLAGS@







DEFS		= $(TCL_DEFS) @DEFS@ $(EXTRA_CFLAGS)



CONFIG_CLEAN_FILES = Makefile


CPPFLAGS	= @CPPFLAGS@
LIBS		= @LIBS@ @TDOM_BUILD_STUB_LIB_SPEC@

AR		= ar

CFLAGS		= @CFLAGS@ -DUSE_TDOM_STUBS=1
COMPILE		= $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)



#========================================================================
# Start of user-definable TARGETS section
#========================================================================

#========================================================================
# TEA TARGETS.  Please note that the "libraries:" target refers to platform
# independent files, and the "binaries:" target inclues executable programs and
# platform-dependent libraries.  Modify these targets so that they install
# the various pieces of your package.  The make and install rules
# for the BINARIES that you specified above have already been done.
#========================================================================

all: binaries libraries doc

................................................................................
#========================================================================
# The binaries target builds executable programs, Windows .dll's, unix
# shared/static libraries, and any other platform-dependent files.
# The list of targets to build for "binaries:" is specified at the top
# of the Makefile, in the "BINARIES" variable.
#========================================================================

binaries: $(BINARIES) pkgIndex.tcl-hand

libraries:







doc:





install: all install-binaries

install-binaries: binaries install-lib-binaries
	@if test "x$(SHARED_BUILD)" = "x1"; then \
	    $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
	fi

#========================================================================
# This rule installs platform-independent files, such as header files.

#========================================================================

install-libraries: libraries
	@mkdir -p $(DESTDIR)$(includedir)
	@echo "Installing header files in $(DESTDIR)$(includedir)"
	@if test "x$(GENERIC_HDRS)" != "x"; then \
	  for i in $(GENERIC_HDRS) ; do \
	    echo " $(INSTALL_DATA) $$i" ; \
	      $(INSTALL_DATA) $$i $(DESTDIR)$(includedir) ; \
	  done;
	fi

#========================================================================
# Install documentation.  Unix manpages should go in the $(mandir)
# directory.
#========================================================================

install-doc: doc
	@mkdir -p $(DESTDIR)$(mandir)/mann
	@echo "Installing documentation in $(DESTDIR)$(mandir)"
	@for i in $(srcdir)/doc/*.n; do \
	  echo " $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann/`basename $$i`"; \
	    rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
	      $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
	done

test: binaries libraries
	$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)

shell: binaries libraries
	@$(TCLSH) $(SCRIPT)

gdb:
	$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)











depend:

#========================================================================
# $($(PACKAGE)_LIB_FILE) should be listed as part of the BINARIES variable
# mentioned above.  That will ensure that this target is built when you
# run "make binaries".
#
# The $($(PACKAGE)_OBJECTS) objects are created and linked into the final
# library.  In most cases these object files will correspond to the
# source files above.
#========================================================================

$($(PACKAGE)stub_LIB_FILE): $($(PACKAGE)stub_OBJECTS)
	-rm -f $($(PACKAGE)stub_LIB_FILE)
	${MAKE_STUB_LIB}
	$(RANLIB) $($(PACKAGE)stub_LIB_FILE)

$($(PACKAGE)_LIB_FILE): $($(PACKAGE)_OBJECTS)
	-rm -f $($(PACKAGE)_LIB_FILE)
	${MAKE_LIB}
	$(RANLIB) $($(PACKAGE)_LIB_FILE)

#========================================================================
# We need to enumerate the list of .c to .o lines here.
#
# In the following lines, $(srcdir) refers to the toplevel directory
# containing your extension.  If your sources are in a subdirectory,
# you will have to modify the paths to reflect this:
................................................................................
# 	$(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
#
# Setting the VPATH variable to a list of paths will cause the makefile
# to look into these paths when resolving .c to .obj dependencies.
# As necessary, add $(srcdir):$(srcdir)/compat:....
#========================================================================

VPATH = $(srcdir)/generic:$(srcdir)/expat:$(srcdir)/unix:$(srcdir)/win

.c.$(OBJEXT):
	$(COMPILE) -c `@CYGPATH@ $<` -o $@

#========================================================================
# Create the pkgIndex.tcl file.
# It is usually easiest to let Tcl do this for you with pkg_mkIndex, but
# you may find that you need to customize the package.  If so, either
# modify the -hand version, or create a pkgIndex.tcl.in file and have
# the configure script output the pkgIndex.tcl by editing configure.in.
#========================================================================

# pkgIndex.tcl:
# 	@(echo pkg_mkIndex . $($(PACKAGE)_LIB_FILE) \; exit; ) | $(TCLSH)

pkgIndex.tcl-hand:
	@(echo 'package ifneeded $(PACKAGE) $(VERSION) \
        "load [file join $$dir $($(PACKAGE)_LIB_FILE)]"'\
	) > pkgIndex.tcl

#========================================================================
# Distribution creation
# You may need to tweak this target to make it work correctly.
#========================================================================

#COMPRESS	= tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
COMPRESS	= gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT	= /tmp/dist
DIST_DIR	= $(DIST_ROOT)/$(PKG_DIR)

dist-clean:
	rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*

dist: dist-clean
	mkdir -p $(DIST_DIR)
	cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
	  $(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
	  $(DIST_DIR)/
	chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
	chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in

	cp -p $(srcdir)/*.[ch] $(DIST_DIR)/





	mkdir $(DIST_DIR)/tclconfig
	cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
	  $(DIST_DIR)/tclconfig/
	chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
	chmod +x $(DIST_DIR)/tclconfig/install-sh

	list='doc generic tests unix win expat lib apps encodings xe'; \
	for p in $$list; do \
	  if test -d $(srcdir)/$$p ; then \
	    mkdir $(DIST_DIR)/$$p; \
	    cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
	  fi; \
	done

	(cd $(DIST_ROOT); $(COMPRESS);)

#========================================================================
# End of user-definable section
#========================================================================

#========================================================================
# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
# variable in configure.in
#========================================================================

clean:  
	-test -z "$(BINARIES)" || rm -f $(BINARIES)
	-rm -f *.$(OBJEXT) core *.core
	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)

distclean: clean
	-rm -f *.tab.c
	-rm -f $(CONFIG_CLEAN_FILES)
................................................................................
# Library files go into the lib directory.
# In addition, this will generate the pkgIndex.tcl
# file in the install location (assuming it can find a usable tclsh shell)
#
# You should not have to modify this target.
#========================================================================

install-lib-binaries:
	@echo "Installing library files in $(pkglibdir)"
	@mkdir -p $(DESTDIR)$(pkglibdir)
	@list='$(lib_BINARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \





	    echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
	    $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \

	    ext=`echo $$p|sed -e "s/.*\.//"`; \
	    if test "x$$ext" = "xdll"; then \
		lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
		if test -f $$lib; then \
		    echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
	            $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
		fi; \
	    fi; \
	  fi; \
	done
	@list='$(RUNTIME_SOURCES)'; for p in $$list; do \
	  if test -f $(srcdir)/lib/$$p; then \

	    echo " $(INSTALL_DATA) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
	    $(INSTALL_DATA) $(srcdir)/lib/$$p $(DESTDIR)$(pkglibdir)/$$p; \
	  fi; \
	done





#========================================================================
# Install binary executables (e.g. .exe files and dependent .dll files)
# This is for files that must go in the bin directory (located next to
# wish and tclsh), like dependent .dll files on Windows.
#
# You should not have to modify this target, except to define bin_BINARIES
# above if necessary.
#========================================================================

# install-bin-binaries:
# 	@echo "Installing executables in $(DESTDIR)$(bindir)"
# 	@mkdir -p $(DESTDIR)$(bindir)
# 	@list='$(bin_BINARIES)'; for p in $$list; do \
# 	  if test -f $$p; then \
# 	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
# 	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
# 	  fi; \
# 	done

.SUFFIXES: .c .$(OBJEXT)

Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
	cd $(top_builddir) \
	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status

uninstall-binaries:
	list='$(lib_BINARIES)'; for p in $$list; do \
	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \
	done
	list='$(RUNTIME_SOURCES)'; for p in $$list; do \

	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \
	done
	list='$(bin_BINARIES)'; for p in $$list; do \
	  rm -f $(DESTDIR)$(bindir)/$$p; \
	done

.PHONY: all binaries clean depend distclean doc install libraries test

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:







|



|
|
>
>
>

>
>

<
>
>
>



|
>

<
|
|
<


<
<
|
<
>

<
<
<
<
<
<
<
>
>
|
<
<

<
<
<
<
<
|



<
>


|


<
>


<
<
>
>


<
>
>

<
<
<
<
<
<
<
<
<
<
<
|










>
>


<



|






|
>
>
|
|
|
>

|
<
>

<

<
<
>

<

<

<


>


>


<


|


>
>

<
|
<
<
<
<
<
|
<









>
>
|
<
<
|

|
>

|
>
>
>
>
>


<
>
>

<
>

>
>
>
>
>
|
>

>
|
>


<
>
|
<
|

>
>







|







 







|



>
>
>
>
>
>

>
>
>
>

|

|
<
<
<



>



|

|
|
<
|
|
<







|

|
|
<
|











>
>
>
>
>
>
>
>
>
>



|



|




|
|
|
|

|
|
|
|







 







|

|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|









|
|



|
>
>
>
>



|



|

|
|
|
|













|







 







|
<
|


|
|
>
>
>
>
>
|
|
>










|
|
>
|
|


>
>
>
>










|
<
|
|
|
|
|
|
|
<
<









|
>











3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31

32
33

34
35


36

37
38







39
40
41


42





43
44
45
46

47
48
49
50
51
52

53
54
55


56
57
58
59

60
61
62











63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98

99


100
101

102

103

104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119

120





121

122
123
124
125
126
127
128
129
130
131
132
133


134
135
136
137
138
139
140
141
142
143
144
145
146

147
148
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211



212
213
214
215
216
217
218
219
220
221
222

223
224

225
226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
...
288
289
290
291
292
293
294
295
296
297
298
299
















300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
...
366
367
368
369
370
371
372
373

374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418

419
420
421
422
423
424
425


426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
#	This file is a Makefile for Sample TEA Extension.  If it has the name
#	"Makefile.in" then it is a template for a Makefile;  to generate the
#	actual Makefile, run "./configure", which is a configuration script
#	generated by the "autoconf" program (constructs like "@foo@" will get
#	replaced in the actual Makefile.
#
# Copyright (c) 1999 Scriptics Corporation.
# Copyright (c) 2002-2005 ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

#========================================================================
# Add additional lines to handle any additional AC_SUBST cases that
# have been added in a customized configure script.
#========================================================================

#SAMPLE_NEW_VAR	= @SAMPLE_NEW_VAR@

#========================================================================

# Nothing of the variables below this line should need to be changed.
# Please check the TARGETS section below to make sure the make targets
# are correct.
#========================================================================

#========================================================================
# The names of the source files is defined in the configure script.
# The object files are used for linking into the final library.
# This will be used when a dist target is added to the Makefile.

# It is not important to specify the directory, as long as it is the
# $(srcdir) or in the generic, win or unix subdirectory.

#========================================================================



PKG_SOURCES	= @PKG_SOURCES@

PKG_OBJECTS	= @PKG_OBJECTS@








PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@



#========================================================================





# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
# this package that need to be installed, if any.
#========================================================================


PKG_TCL_SOURCES = @PKG_TCL_SOURCES@

#========================================================================
# This is a list of public header files to be installed, if any.
#========================================================================


PKG_HEADERS	= @PKG_HEADERS@

#========================================================================


# "PKG_LIB_FILE" refers to the library (dynamic or static as per
# configuration options) composed of the named objects.
#========================================================================


PKG_LIB_FILE	= @PKG_LIB_FILE@
PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@












lib_BINARIES	= $(PKG_LIB_FILE)
BINARIES	= $(lib_BINARIES)

SHELL		= @SHELL@

srcdir		= @srcdir@
prefix		= @prefix@
exec_prefix	= @exec_prefix@

bindir		= @bindir@
libdir		= @libdir@
includedir	= @includedir@
datarootdir	= @datarootdir@
datadir		= @datadir@
mandir		= @mandir@


DESTDIR		=

PKG_DIR		= $(PACKAGE_NAME)$(PACKAGE_VERSION)
pkgdatadir	= $(datadir)/$(PKG_DIR)
pkglibdir	= $(libdir)/$(PKG_DIR)
pkgincludedir	= $(includedir)/$(PKG_DIR)

top_builddir	= .

INSTALL_OPTIONS =
INSTALL		= $(SHELL) $(srcdir)/tclconfig/install-sh -c ${INSTALL_OPTIONS}
INSTALL_DATA_DIR = ${INSTALL} -d -m 755
INSTALL_PROGRAM	= ${INSTALL} -m 555
INSTALL_DATA	= ${INSTALL} -m 444
INSTALL_SCRIPT	= ${INSTALL_PROGRAM}
INSTALL_LIBRARY	= ${INSTALL_DATA}

PACKAGE_NAME	= @PACKAGE_NAME@

PACKAGE_VERSION	= @PACKAGE_VERSION@
CC		= @CC@

CFLAGS_DEFAULT	= @CFLAGS_DEFAULT@


CFLAGS_WARNING	= @CFLAGS_WARNING@
EXEEXT		= @EXEEXT@

LDFLAGS_DEFAULT	= @LDFLAGS_DEFAULT@

MAKE_LIB	= @MAKE_LIB@

MAKE_SHARED_LIB	= @MAKE_SHARED_LIB@
MAKE_STATIC_LIB	= @MAKE_STATIC_LIB@
MAKE_STUB_LIB	= @MAKE_STUB_LIB@
OBJEXT		= @OBJEXT@
RANLIB		= @RANLIB@
RANLIB_STUB	= @RANLIB_STUB@
SHLIB_CFLAGS	= @SHLIB_CFLAGS@
SHLIB_LD	= @SHLIB_LD@

SHLIB_LD_LIBS	= @SHLIB_LD_LIBS@
STLIB_LD	= @STLIB_LD@
#TCL_DEFS	= @TCL_DEFS@
TCL_BIN_DIR	= @TCL_BIN_DIR@
TCL_SRC_DIR	= @TCL_SRC_DIR@
#TK_BIN_DIR	= @TK_BIN_DIR@
#TK_SRC_DIR	= @TK_SRC_DIR@


# Not used, but retained for reference of what libs Tcl required





#TCL_LIBS	= @TCL_LIBS@


#========================================================================
# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
# package without installing.  The other environment variables allow us
# to test against an uninstalled Tcl.  Add special env vars that you
# require for testing here (like TCLX_LIBRARY).
#========================================================================

EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR)
#EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
TCLLIBPATH	= $(top_builddir)
TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`


PKG_ENV		= @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
		  PATH="$(EXTRA_PATH):$(PATH)" \
		  TCLLIBPATH="$(TCLLIBPATH)"

TCLSH_PROG	= @TCLSH_PROG@
TCLSH		= $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)

#WISH_ENV	= TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
#WISH_PROG	= @WISH_PROG@
#WISH		= $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)

SHARED_BUILD	= @SHARED_BUILD@


INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@
#INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@


PKG_CFLAGS	= @PKG_CFLAGS@

# TCL_DEFS is not strictly need here, but if you remove it, then you
# must make sure that configure.in checks for the necessary components
# that your library may use.  TCL_DEFS can actually be a problem if
# you do not compile with a similar machine setup as the Tcl core was
# compiled with.
#DEFS		= $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
DEFS		= @DEFS@ $(PKG_CFLAGS)

# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
CLEANFILES	= @CLEANFILES@

CPPFLAGS	= @CPPFLAGS@

LIBS		= @PKG_LIBS@ @LIBS@
AR		= @AR@

CFLAGS		= @CFLAGS@
COMPILE		= $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)

.SUFFIXES: .c .$(OBJEXT)

#========================================================================
# Start of user-definable TARGETS section
#========================================================================

#========================================================================
# TEA TARGETS.  Please note that the "libraries:" target refers to platform
# independent files, and the "binaries:" target includes executable programs and
# platform-dependent libraries.  Modify these targets so that they install
# the various pieces of your package.  The make and install rules
# for the BINARIES that you specified above have already been done.
#========================================================================

all: binaries libraries doc

................................................................................
#========================================================================
# The binaries target builds executable programs, Windows .dll's, unix
# shared/static libraries, and any other platform-dependent files.
# The list of targets to build for "binaries:" is specified at the top
# of the Makefile, in the "BINARIES" variable.
#========================================================================

binaries: $(BINARIES)

libraries:

#========================================================================
# Your doc target should differentiate from doc builds (by the developer)
# and doc installs (see install-doc), which just install the docs on the
# end user machine when building from source.
#========================================================================

doc:
	@echo "If you have documentation to create, place the commands to"
	@echo "build the docs in the 'doc:' target.  For example:"
	@echo "        xml2nroff sample.xml > sample.n"
	@echo "        xml2html sample.xml > sample.html"

install: all install-binaries install-libraries install-doc

install-binaries: binaries install-lib-binaries install-bin-binaries




#========================================================================
# This rule installs platform-independent files, such as header files.
# The list=...; for p in $$list handles the empty list case x-platform.
#========================================================================

install-libraries: libraries
	@$(INSTALL_DATA_DIR) $(DESTDIR)$(includedir)
	@echo "Installing header files in $(DESTDIR)$(includedir)"
	@list='$(PKG_HEADERS)'; for i in $$list; do \
	    echo "Installing $(srcdir)/$$i" ; \

	    $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
	done;


#========================================================================
# Install documentation.  Unix manpages should go in the $(mandir)
# directory.
#========================================================================

install-doc: doc
	@$(INSTALL_DATA_DIR) $(DESTDIR)$(mandir)/mann
	@echo "Installing documentation in $(DESTDIR)$(mandir)"
	@list='$(srcdir)/doc/*.n'; for i in $$list; do \
	    echo "Installing $$i"; \

	    $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
	done

test: binaries libraries
	$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)

shell: binaries libraries
	@$(TCLSH) $(SCRIPT)

gdb:
	$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)

VALGRINDARGS =	--tool=memcheck --num-callers=8 --leak-resolution=high \
		--leak-check=yes --show-reachable=yes -v

valgrind: binaries libraries
	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) \
		`@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)

valgrindshell: binaries libraries
	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)

depend:

#========================================================================
# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
# mentioned above.  That will ensure that this target is built when you
# run "make binaries".
#
# The $(PKG_OBJECTS) objects are created and linked into the final
# library.  In most cases these object files will correspond to the
# source files above.
#========================================================================

$(PKG_LIB_FILE): $(PKG_OBJECTS)
	-rm -f $(PKG_LIB_FILE)
	${MAKE_LIB}
	$(RANLIB) $(PKG_LIB_FILE)

$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
	-rm -f $(PKG_STUB_LIB_FILE)
	${MAKE_STUB_LIB}
	$(RANLIB_STUB) $(PKG_STUB_LIB_FILE)

#========================================================================
# We need to enumerate the list of .c to .o lines here.
#
# In the following lines, $(srcdir) refers to the toplevel directory
# containing your extension.  If your sources are in a subdirectory,
# you will have to modify the paths to reflect this:
................................................................................
# 	$(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
#
# Setting the VPATH variable to a list of paths will cause the makefile
# to look into these paths when resolving .c to .obj dependencies.
# As necessary, add $(srcdir):$(srcdir)/compat:....
#========================================================================

VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macosx

.c.@OBJEXT@:
	$(COMPILE) -c `@CYGPATH@ $<` -o $@

















#========================================================================
# Distribution creation
# You may need to tweak this target to make it work correctly.
#========================================================================

#COMPRESS	= tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
COMPRESS	= tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT	= /tmp/dist
DIST_DIR	= $(DIST_ROOT)/$(PKG_DIR)

dist-clean:
	rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*

dist: dist-clean
	mkdir -p $(DIST_DIR)
	cp -p $(srcdir)/ChangeLog $(srcdir)/README* $(srcdir)/license* \
		$(srcdir)/aclocal.m4 $(srcdir)/configure $(srcdir)/*.in \
		$(DIST_DIR)/
	chmod 664 $(DIST_DIR)/Makefile.in $(DIST_DIR)/aclocal.m4
	chmod 775 $(DIST_DIR)/configure $(DIST_DIR)/configure.in

	for i in $(srcdir)/*.[ch]; do \
	    if [ -f $$i ]; then \
		cp -p $$i $(DIST_DIR)/ ; \
	    fi; \
	done;

	mkdir $(DIST_DIR)/tclconfig
	cp $(srcdir)/tclconfig/install-sh $(srcdir)/tclconfig/tcl.m4 \
		$(DIST_DIR)/tclconfig/
	chmod 664 $(DIST_DIR)/tclconfig/tcl.m4
	chmod +x $(DIST_DIR)/tclconfig/install-sh

	list='demos doc generic library mac tests unix win'; \
	for p in $$list; do \
	    if test -d $(srcdir)/$$p ; then \
		mkdir $(DIST_DIR)/$$p; \
		cp -p $(srcdir)/$$p/*.* $(DIST_DIR)/$$p/; \
	    fi; \
	done

	(cd $(DIST_ROOT); $(COMPRESS);)

#========================================================================
# End of user-definable section
#========================================================================

#========================================================================
# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
# variable in configure.in
#========================================================================

clean:
	-test -z "$(BINARIES)" || rm -f $(BINARIES)
	-rm -f *.$(OBJEXT) core *.core
	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)

distclean: clean
	-rm -f *.tab.c
	-rm -f $(CONFIG_CLEAN_FILES)
................................................................................
# Library files go into the lib directory.
# In addition, this will generate the pkgIndex.tcl
# file in the install location (assuming it can find a usable tclsh shell)
#
# You should not have to modify this target.
#========================================================================

install-lib-binaries: binaries

	@$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir)
	@list='$(lib_BINARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
	    $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
	    stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
	    if test "x$$stub" = "xstub"; then \
		echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
		$(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
	    else \
		echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
		$(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
	    fi; \
	    ext=`echo $$p|sed -e "s/.*\.//"`; \
	    if test "x$$ext" = "xdll"; then \
		lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
		if test -f $$lib; then \
		    echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
	            $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \
		fi; \
	    fi; \
	  fi; \
	done
	@list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
	  if test -f $(srcdir)/$$p; then \
	    destp=`basename $$p`; \
	    echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
	    $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkglibdir)/$$destp; \
	  fi; \
	done
	@if test "x$(SHARED_BUILD)" = "x1"; then \
	    echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
	    $(INSTALL_DATA) pkgIndex.tcl $(DESTDIR)$(pkglibdir); \
	fi

#========================================================================
# Install binary executables (e.g. .exe files and dependent .dll files)
# This is for files that must go in the bin directory (located next to
# wish and tclsh), like dependent .dll files on Windows.
#
# You should not have to modify this target, except to define bin_BINARIES
# above if necessary.
#========================================================================

install-bin-binaries: binaries

	@$(INSTALL_DATA_DIR) $(DESTDIR)$(bindir)
	@list='$(bin_BINARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
	  fi; \
	done



Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
	cd $(top_builddir) \
	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status

uninstall-binaries:
	list='$(lib_BINARIES)'; for p in $$list; do \
	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \
	done
	list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
	  p=`basename $$p`; \
	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \
	done
	list='$(bin_BINARIES)'; for p in $$list; do \
	  rm -f $(DESTDIR)$(bindir)/$$p; \
	done

.PHONY: all binaries clean depend distclean doc install libraries test

# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

Changes to extensions/example/configure.

more than 10,000 changes

Changes to extensions/example/configure.in.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52


53


54
55
56

57
58
59
60

61
62
63


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
..
92
93
94
95
96
97
98
99
100
101
102
103


















































104
105
106
107
108
109
110
...
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#!/bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tcl installation
dnl	to configure the system for the local environment.
#
# RCS: @(#) $Id$

#-----------------------------------------------------------------------
# Sample configure.in for Tcl Extensions.  The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
# __CHANGE__
# This very first macro is used to verify that the configure script can 
# find the sources.  The argument to AC_INIT should be a unique filename
# for this package, and can be a relative path, such as:
#
# AC_INIT(generic/tcl.h)
#-----------------------------------------------------------------------

AC_INIT(example.c)

AC_CONFIG_AUX_DIR(../../tclconfig)
CONFIGDIR=${srcdir}/../../tclconfig
AC_SUBST(CONFIGDIR)

#----------------------------------------------------------------------
# __CHANGE__
# Set your package name and version numbers here.  The NODOT_VERSION is
# required for constructing the library name on systems that don't like
# dots in library names (Windows).  The VERSION variable is used on the
# other systems.
#----------------------------------------------------------------------

PACKAGE=example

MAJOR_VERSION=1
MINOR_VERSION=0
PATCHLEVEL=0

VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${PATCHLEVEL}
NODOT_VERSION=${MAJOR_VERSION}${MINOR_VERSION}${PATCHLEVEL}

AC_SUBST(PACKAGE)
AC_SUBST(VERSION)

# This package name must be replaced statically for AC_SUBST to work
AC_SUBST(example_LIB_FILE)

#--------------------------------------------------------------------
# We put this here so that you can compile with -DVERSION="1.2" to


# encode the package version directly into the source files.


#--------------------------------------------------------------------

eval AC_DEFINE_UNQUOTED(VERSION, "${VERSION}")


#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows".

#--------------------------------------------------------------------

TEA_INIT



#--------------------------------------------------------------------
# Load the tclConfig.sh file
#--------------------------------------------------------------------

TEA_PATH_TCLCONFIG
TEA_LOAD_TCLCONFIG

#--------------------------------------------------------------------
# Load the tdomConfig.sh file
#--------------------------------------------------------------------
if test "${TEA_PLATFORM}" = "windows" ; then
    TDOM_BIN_DIR=../../win
else
    TDOM_BIN_DIR=../../unix
fi
TDOM_LOAD_CONFIG

#--------------------------------------------------------------------
# Load the tkConfig.sh file if necessary (Tk extension)
#--------------------------------------------------------------------

#TEA_PATH_TKCONFIG
#TEA_LOAD_TKCONFIG

................................................................................
#-----------------------------------------------------------------------

TEA_PREFIX

#-----------------------------------------------------------------------
# Standard compiler checks.
# This sets up CC by using the CC env var, or looks for gcc otherwise.
# This also calls AC_PROG_CC, AC_PROG_INSTALL and a few others to create
# the basic setup necessary to compile executables.
#-----------------------------------------------------------------------

TEA_SETUP_COMPILER



















































#--------------------------------------------------------------------
# __CHANGE__
# Choose which headers you need.  Extension authors should try very
# hard to only rely on the Tcl public header files.  Internal headers
# contain private data structures and are subject to change without
# notice.
................................................................................
#--------------------------------------------------------------------

TEA_PUBLIC_TCL_HEADERS
#TEA_PRIVATE_TCL_HEADERS

#TEA_PUBLIC_TK_HEADERS
#TEA_PRIVATE_TK_HEADERS


#--------------------------------------------------------------------
# __CHANGE__
# A few miscellaneous platform-specific items:
#
# Define a special symbol for Windows (BUILD_sample in this case) so
# that we create the export library with the dll.  See sha1.h on how
# to use this.
#
# Windows creates a few extra files that need to be cleaned up.
# You can add more files to clean if your extension creates any extra
# files.
#
# Define any extra compiler flags in the PACKAGE_CFLAGS variable.
# These will be appended to the current set of compiler flags for
# your system.
#--------------------------------------------------------------------

if test "${TEA_PLATFORM}" = "windows" ; then
    AC_DEFINE(BUILD_example)
    CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
    EXTRA_SOURCES='$(WIN_SOURCES)'
else
    CLEANFILES="pkgIndex.tcl"
    EXTRA_SOURCES='$(UNIX_SOURCES)'
fi
AC_SUBST(CLEANFILES)
AC_SUBST(EXTRA_SOURCES)

#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.

#--------------------------------------------------------------------

TEA_ENABLE_THREADS

#--------------------------------------------------------------------
# The statement below defines a collection of symbols related to
# building as a shared library instead of a static library.
................................................................................

#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols option.
#--------------------------------------------------------------------

TEA_ENABLE_SYMBOLS

if test "${SHARED_BUILD}" = "1" ; then
    CFLAGS='${CFLAGS_DEFAULT} ${CFLAGS_WARNING} ${SHLIB_CFLAGS}'
else
    CFLAGS='${CFLAGS_DEFAULT} ${CFLAGS_WARNING}'
fi
AC_SUBST(SHARED_BUILD)

#--------------------------------------------------------------------
# Everyone should be linking against the Tcl stub library.  If you
# can't for some reason, remove this definition.  If you aren't using
# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
# link against the non-stubbed Tcl library.  Add Tk too if necessary.
#--------------------------------------------------------------------

AC_DEFINE(USE_TCL_STUBS)
#AC_DEFINE(USE_TK_STUBS)

#--------------------------------------------------------------------
# This macro generates a line to use when building a library.  It
# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
# and TEA_LOAD_TCLCONFIG macros above.
# For tDOM we always build both, static and shared libraries
#--------------------------------------------------------------------

TEA_MAKE_LIB

#--------------------------------------------------------------------
# __CHANGE__
# Add platform libs to LIBS or SHLIB_LD_LIBS as necessary.
#--------------------------------------------------------------------


#LIBS="${LIBS} --lsuperfly"

#--------------------------------------------------------------------
# Find tclsh so that we can run pkg_mkIndex to generate the pkgIndex.tcl
# file during the install process.  Don't run the TCLSH_PROG through
# ${CYGPATH} because it's being used directly by make.
# Require that we use a tclsh shell version 8.2 or later since earlier
# versions have bugs in the pkg_mkIndex routine.
# Add WISH as well if this is a Tk extension.
#--------------------------------------------------------------------

TEA_PROG_TCLSH
#TEA_PROG_WISH

#--------------------------------------------------------------------
# Add some private include directories
#--------------------------------------------------------------------

EXAMPLE_INCLUDES="-I${srcdir}/../../generic -I${srcdir}/../../expat"
AC_SUBST(EXAMPLE_INCLUDES)

#--------------------------------------------------------------------
# Finally, substitute all of the various values into the Makefile.
# You may alternatively have a special pkgIndex.tcl.in or other files
# which require substituting th AC variables in.  Include these here.
#--------------------------------------------------------------------

AC_OUTPUT([Makefile])




<
<








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>
|
>
>
|

<
>



|
>


|
>
>








<
<
<
<
<
<
<
<
<
<







 







|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

>







 







<
<
<
<
<
<
<







|
|





<





|
|
|
<
>
|
<
<
<
<
<
<
<
<





<
<
<
<
<
<
<






|
1
2
3
4


5
6
7
8
9
10
11
12















13




14

















15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40










41
42
43
44
45
46
47
..
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
121
122
123
124
125
126
127
128
129
130




























131
132
133
134
135
136
137
138
139
...
151
152
153
154
155
156
157







158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179

180
181








182
183
184
185
186







187
188
189
190
191
192
193
#!/bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tcl installation
dnl	to configure the system for the local environment.



#-----------------------------------------------------------------------
# Sample configure.in for Tcl Extensions.  The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
# __CHANGE__















# Set your package name and version numbers here.




#

















# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided.  These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
# This will also define a special symbol for Windows (BUILD_sample in
# this case) so that we create the export library with the dll.
#-----------------------------------------------------------------------


AC_INIT([example], [1.0])

#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------

TEA_INIT([3.10])

AC_CONFIG_AUX_DIR(../../tclconfig)

#--------------------------------------------------------------------
# Load the tclConfig.sh file
#--------------------------------------------------------------------

TEA_PATH_TCLCONFIG
TEA_LOAD_TCLCONFIG











#--------------------------------------------------------------------
# Load the tkConfig.sh file if necessary (Tk extension)
#--------------------------------------------------------------------

#TEA_PATH_TKCONFIG
#TEA_LOAD_TKCONFIG

................................................................................
#-----------------------------------------------------------------------

TEA_PREFIX

#-----------------------------------------------------------------------
# Standard compiler checks.
# This sets up CC by using the CC env var, or looks for gcc otherwise.
# This also calls AC_PROG_CC and a few others to create the basic setup
# necessary to compile executables.
#-----------------------------------------------------------------------

TEA_SETUP_COMPILER

#--------------------------------------------------------------------
# Load the tdomConfig.sh file
#--------------------------------------------------------------------

TDOM_PATH_CONFIG
TDOM_LOAD_CONFIG

#-----------------------------------------------------------------------
# __CHANGE__
# Specify the C source files to compile in TEA_ADD_SOURCES,
# public headers that need to be installed in TEA_ADD_HEADERS,
# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
# and PKG_TCL_SOURCES.
#-----------------------------------------------------------------------

TEA_ADD_SOURCES([example.c])
TEA_ADD_HEADERS([])
TEA_ADD_INCLUDES([-I${srcdir}/../../generic -I${srcdir}/../../expat])
TEA_ADD_LIBS([${TDOM_STUB_LIB_SPEC}])
TEA_ADD_CFLAGS([-DUSE_TDOM_STUBS=1])
TEA_ADD_STUB_SOURCES([])
TEA_ADD_TCL_SOURCES([])

#--------------------------------------------------------------------
# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
#
# A few miscellaneous platform-specific items:
# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------

#CLEANFILES="$CLEANFILES pkgIndex.tcl"
if test "${TEA_PLATFORM}" = "windows" ; then
    # Ensure no empty if clauses
    :
    #TEA_ADD_SOURCES([win/winFile.c])
    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
else
    # Ensure no empty else clauses
    :
    #TEA_ADD_SOURCES([unix/unixFile.c])
    #TEA_ADD_LIBS([-lsuperfly])
fi

#--------------------------------------------------------------------
# __CHANGE__
# Choose which headers you need.  Extension authors should try very
# hard to only rely on the Tcl public header files.  Internal headers
# contain private data structures and are subject to change without
# notice.
................................................................................
#--------------------------------------------------------------------

TEA_PUBLIC_TCL_HEADERS
#TEA_PRIVATE_TCL_HEADERS

#TEA_PUBLIC_TK_HEADERS
#TEA_PRIVATE_TK_HEADERS
#TEA_PATH_X

#--------------------------------------------------------------------




























# Check whether --enable-threads or --disable-threads was given.
# This auto-enables if Tcl was compiled threaded.
#--------------------------------------------------------------------

TEA_ENABLE_THREADS

#--------------------------------------------------------------------
# The statement below defines a collection of symbols related to
# building as a shared library instead of a static library.
................................................................................

#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols option.
#--------------------------------------------------------------------

TEA_ENABLE_SYMBOLS








#--------------------------------------------------------------------
# Everyone should be linking against the Tcl stub library.  If you
# can't for some reason, remove this definition.  If you aren't using
# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
# link against the non-stubbed Tcl library.  Add Tk too if necessary.
#--------------------------------------------------------------------

AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
#AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])

#--------------------------------------------------------------------
# This macro generates a line to use when building a library.  It
# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
# and TEA_LOAD_TCLCONFIG macros above.

#--------------------------------------------------------------------

TEA_MAKE_LIB

#--------------------------------------------------------------------
# Determine the name of the tclsh and/or wish executables in the
# Tcl and Tk build directories or the location they were installed
# into. These paths are used to support running test cases only,

# the Makefile should not be making use of these paths to generate
# a pkgIndex.tcl file or anything else at extension build time.








#--------------------------------------------------------------------

TEA_PROG_TCLSH
#TEA_PROG_WISH








#--------------------------------------------------------------------
# Finally, substitute all of the various values into the Makefile.
# You may alternatively have a special pkgIndex.tcl.in or other files
# which require substituting th AC variables in.  Include these here.
#--------------------------------------------------------------------

AC_OUTPUT([Makefile pkgIndex.tcl])

Changes to extensions/example/example.c.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
...
231
232
233
234
235
236
237










238
239
240

241
242

#include <tcl.h>
#include <string.h>
#include <expat.h>
#include <tclexpat.h>

/*
 * Beginning with 8.4, Tcl API is CONST'ified
 */
#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION <= 3)
# define CONST84
#endif



typedef struct simpleCounter 
{
    int elementCounter;
} simpleCounter;

static char example_usage[] = 
................................................................................
int
TclExampleObjCmd(dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *CONST objv[];
{
    char          *method;
    CHandlerSet   *handlerSet;
    int            methodIndex, result;
    simpleCounter *counter;
    

    static CONST84 char *exampleMethods[] = {
        "enable", "getresult", "remove",
................................................................................
    }

    if (!CheckExpatParserObj (interp, objv[1])) {
        Tcl_SetResult (interp, "First argument has to be a expat parser object", NULL);
        return TCL_ERROR;
    }

    method = Tcl_GetStringFromObj (objv[2], NULL);
    if (Tcl_GetIndexFromObj (interp, objv[2], exampleMethods, "method", 0,
                             &methodIndex) != TCL_OK)
    {
        Tcl_SetResult (interp, example_usage, NULL);
        return TCL_ERROR;
    }

................................................................................
 *----------------------------------------------------------------------------
 */

int
Example_Init (interp)
    Tcl_Interp *interp;
{










    Tcl_PkgRequire (interp, "expat", "2.0", 0);
    Tcl_CreateObjCommand (interp, "example", TclExampleObjCmd, NULL, NULL );
    Tcl_PkgProvide (interp, "example", "1.0");

}


|

<
<








>







 







<







 







<







 







>
>
>
>
>
>
>
>
>
>
|


>


1
2
3


4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
130
131
132
133
134
135
136

137
138
139
140
141
142
143
...
153
154
155
156
157
158
159

160
161
162
163
164
165
166
...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

#include <tdom.h>
#include <string.h>



/*
 * Beginning with 8.4, Tcl API is CONST'ified
 */
#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION <= 3)
# define CONST84
#endif

extern char *Tdom_InitStubs (Tcl_Interp *interp, char *version, int exact);

typedef struct simpleCounter 
{
    int elementCounter;
} simpleCounter;

static char example_usage[] = 
................................................................................
int
TclExampleObjCmd(dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *CONST objv[];
{

    CHandlerSet   *handlerSet;
    int            methodIndex, result;
    simpleCounter *counter;
    

    static CONST84 char *exampleMethods[] = {
        "enable", "getresult", "remove",
................................................................................
    }

    if (!CheckExpatParserObj (interp, objv[1])) {
        Tcl_SetResult (interp, "First argument has to be a expat parser object", NULL);
        return TCL_ERROR;
    }


    if (Tcl_GetIndexFromObj (interp, objv[2], exampleMethods, "method", 0,
                             &methodIndex) != TCL_OK)
    {
        Tcl_SetResult (interp, example_usage, NULL);
        return TCL_ERROR;
    }

................................................................................
 *----------------------------------------------------------------------------
 */

int
Example_Init (interp)
    Tcl_Interp *interp;
{
#ifdef USE_TCL_STUBS
    if (Tcl_InitStubs(interp, "8", 0) == NULL) {
        return TCL_ERROR;
    }
#endif
#ifdef USE_TDOM_STUBS
    if (Tdom_InitStubs(interp, "0.8", 0) == NULL) {
        return TCL_ERROR;
    }
#endif
    Tcl_PkgRequire (interp, "tdom", "0.8.0", 0);
    Tcl_CreateObjCommand (interp, "example", TclExampleObjCmd, NULL, NULL );
    Tcl_PkgProvide (interp, "example", "1.0");
    return TCL_OK;
}

Changes to extensions/example/exampletest.tcl.

1
2
3
4
5
6
7
8
9
10
11
#!tclsh

load ../../unix/libtdom0.7.5.so
load ./libexample1.0.0.so

set counter1 0
set counter2 0

proc eh1 {args} {
    global counter1



|
|







1
2
3
4
5
6
7
8
9
10
11
#!tclsh

load ../../unix/libtdom0.8.3.so
load ./libexample1.0.so

set counter1 0
set counter2 0

proc eh1 {args} {
    global counter1

Changes to extensions/tdomhtml/configure.

1
2
3
4



5
6

7
8



9
10
11








































































































































































































































































































































































































































































































































































12
13







14


































































15




16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35







36
37
38
39

40
41
42
43
44
45

46
47
48

49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92



93
94
95
96
97
98







99
100

101
102
103
104
105
106












107










108
109

110
111
112
113
114
115







116
117


118
119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191






192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217





218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
...
280
281
282
283
284
285
286
287










288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

341

342
343
344

345
346


347
348


349
350

351
352
353

354
355
356
357

358
359









360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

380
381










382
383
384
385
386
387
388
389





390
391
392
393
394
395
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411

412


413
414
415
416
417
418
419
420

421
422
423
424
425



426
427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
443
444
445
446


447
448
449
450


451
452
453
454

455











456
457
458
459
460
461
462























463
464
465
466
467
468
469
470
471
472


















































































































































473
474




475












476
477
478














































































































































































































































479


480






481
482

483
484

485
486
487


488

489

490




491
492
493
494




495
496




497

498
499
500
501





























































502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521

522
523
524
525
526
527
528
529
530
531
532
533
534




535
536
537
538
539
540

541
542






543
544
545
546
547
548
549
...
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
...
615
616
617
618
619
620
621

622
623
624

625
626
627


628
629

630
631
632

633



634
635
636





637
638
639
640
641
642


643
644
645
646




647









648
649

650
651
652

653
654

655
656


657
658
659
660
661
662
663
664
665
666
667
668

669
670
671
672
673
674
675
676
677
678
679
680
681
682
...
779
780
781
782
783
784
785
786

787
788
789

790
791
792
793
794
795
796
797
798
799
800
801




802

803
804
805

806
807

















808
809
810
811
812
813
814
815

816
817
818
819

820










821
822
823







824
825

826


827



828

829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050





























































































































































































































































































































































































































































































































































































































































































































































































































































































#! /bin/sh

# Guess values for system-dependent variables and create Makefiles.
# Generated automatically using autoconf version 2.13 



# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#

# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.




# Defaults:
ac_help=








































































































































































































































































































































































































































































































































































ac_default_prefix=/usr/local
# Any additions from configure.in:










































































# Initialize some variables set by options.




# The variables have the same names as the options, with
# dashes changed to underlines.
build=NONE
cache_file=./config.cache
exec_prefix=NONE
host=NONE
no_create=
nonopt=NONE
no_recursion=
prefix=NONE
program_prefix=NONE
program_suffix=NONE
program_transform_name=s,x,x,
silent=
site=
srcdir=
target=NONE
verbose=
x_includes=NONE
x_libraries=NONE







bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datadir='${prefix}/share'

sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'

infodir='${prefix}/info'
mandir='${prefix}/man'


# Initialize some other variables.
subdirs=
MFLAGS= MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}
# Maximum number of lines to put in a shell here document.
ac_max_here_lines=12

ac_prev=

for ac_option
do

  # If the previous option needs an argument, assign it.
  if test -n "$ac_prev"; then
    eval "$ac_prev=\$ac_option"
    ac_prev=
    continue
  fi

  case "$ac_option" in
  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
  *) ac_optarg= ;;

  esac

  # Accept the important Cygnus configure options, so we can diagnose typos.

  case "$ac_option" in



  -bindir | --bindir | --bindi | --bind | --bin | --bi)
    ac_prev=bindir ;;
  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
    bindir="$ac_optarg" ;;

  -build | --build | --buil | --bui | --bu)
    ac_prev=build ;;
  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
    build="$ac_optarg" ;;

  -cache-file | --cache-file | --cache-fil | --cache-fi \
  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
    ac_prev=cache_file ;;
  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
    cache_file="$ac_optarg" ;;




  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
    ac_prev=datadir ;;
  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
  | --da=*)
    datadir="$ac_optarg" ;;








  -disable-* | --disable-*)
    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`

    # Reject names that are not valid shell variable names.
    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
    fi
    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
    eval "enable_${ac_feature}=no" ;;























  -enable-* | --enable-*)
    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`

    # Reject names that are not valid shell variable names.
    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
    fi
    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
    case "$ac_option" in







      *=*) ;;
      *) ac_optarg=yes ;;


    esac
    eval "enable_${ac_feature}='$ac_optarg'" ;;


  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
  | --exec | --exe | --ex)
    ac_prev=exec_prefix ;;
  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
  | --exec=* | --exe=* | --ex=*)
    exec_prefix="$ac_optarg" ;;

  -gas | --gas | --ga | --g)
    # Obsolete; use --with-gas.
    with_gas=yes ;;

  -help | --help | --hel | --he)
    # Omit some internal or obsolete options to make the list less imposing.
    # This message is too long to be a string in the A/UX 3.1 sh.
    cat << EOF
Usage: configure [options] [host]
Options: [defaults in brackets after descriptions]
Configuration:
  --cache-file=FILE       cache test results in FILE
  --help                  print this message
  --no-create             do not create output files
  --quiet, --silent       do not print \`checking...' messages
  --version               print the version of autoconf that created configure
Directory and file names:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [$ac_default_prefix]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [same as prefix]
  --bindir=DIR            user executables in DIR [EPREFIX/bin]
  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
  --datadir=DIR           read-only architecture-independent data in DIR
                          [PREFIX/share]
  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
                          [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
  --includedir=DIR        C header files in DIR [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
  --infodir=DIR           info documentation in DIR [PREFIX/info]
  --mandir=DIR            man documentation in DIR [PREFIX/man]
  --srcdir=DIR            find the sources in DIR [configure dir or ..]
  --program-prefix=PREFIX prepend PREFIX to installed program names
  --program-suffix=SUFFIX append SUFFIX to installed program names
  --program-transform-name=PROGRAM
                          run sed PROGRAM on installed program names
EOF
    cat << EOF
Host type:
  --build=BUILD           configure for building on BUILD [BUILD=HOST]
  --host=HOST             configure for HOST [guessed]
  --target=TARGET         configure for TARGET [TARGET=HOST]
Features and packages:
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --x-includes=DIR        X include files are in DIR
  --x-libraries=DIR       X library files are in DIR
EOF
    if test -n "$ac_help"; then
      echo "--enable and --with options recognized:$ac_help"
    fi
    exit 0 ;;

  -host | --host | --hos | --ho)
    ac_prev=host ;;
  -host=* | --host=* | --hos=* | --ho=*)






    host="$ac_optarg" ;;

  -includedir | --includedir | --includedi | --included | --include \
  | --includ | --inclu | --incl | --inc)
    ac_prev=includedir ;;
  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
  | --includ=* | --inclu=* | --incl=* | --inc=*)
    includedir="$ac_optarg" ;;

  -infodir | --infodir | --infodi | --infod | --info | --inf)
    ac_prev=infodir ;;
  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
    infodir="$ac_optarg" ;;

  -libdir | --libdir | --libdi | --libd)
    ac_prev=libdir ;;
  -libdir=* | --libdir=* | --libdi=* | --libd=*)
    libdir="$ac_optarg" ;;

  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
  | --libexe | --libex | --libe)
    ac_prev=libexecdir ;;
  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
  | --libexe=* | --libex=* | --libe=*)
    libexecdir="$ac_optarg" ;;






  -localstatedir | --localstatedir | --localstatedi | --localstated \
  | --localstate | --localstat | --localsta | --localst \
  | --locals | --local | --loca | --loc | --lo)
    ac_prev=localstatedir ;;
  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
    localstatedir="$ac_optarg" ;;

  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
    ac_prev=mandir ;;
  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
    mandir="$ac_optarg" ;;

  -nfp | --nfp | --nf)
    # Obsolete; use --without-fp.
    with_fp=no ;;

  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
  | --no-cr | --no-c)
    no_create=yes ;;

  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
    no_recursion=yes ;;

  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
  | --oldin | --oldi | --old | --ol | --o)
    ac_prev=oldincludedir ;;
  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
    oldincludedir="$ac_optarg" ;;

  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
    ac_prev=prefix ;;
  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
    prefix="$ac_optarg" ;;

  -program-prefix | --program-prefix | --program-prefi | --program-pref \
  | --program-pre | --program-pr | --program-p)
    ac_prev=program_prefix ;;
  -program-prefix=* | --program-prefix=* | --program-prefi=* \
  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
    program_prefix="$ac_optarg" ;;

  -program-suffix | --program-suffix | --program-suffi | --program-suff \
  | --program-suf | --program-su | --program-s)
    ac_prev=program_suffix ;;
  -program-suffix=* | --program-suffix=* | --program-suffi=* \
  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
    program_suffix="$ac_optarg" ;;

  -program-transform-name | --program-transform-name \
  | --program-transform-nam | --program-transform-na \
  | --program-transform-n | --program-transform- \
  | --program-transform | --program-transfor \
  | --program-transfo | --program-transf \
  | --program-trans | --program-tran \
................................................................................
  -program-transform-name=* | --program-transform-name=* \
  | --program-transform-nam=* | --program-transform-na=* \
  | --program-transform-n=* | --program-transform-=* \
  | --program-transform=* | --program-transfor=* \
  | --program-transfo=* | --program-transf=* \
  | --program-trans=* | --program-tran=* \
  | --progr-tra=* | --program-tr=* | --program-t=*)
    program_transform_name="$ac_optarg" ;;











  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil)
    silent=yes ;;

  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
    ac_prev=sbindir ;;
  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
  | --sbi=* | --sb=*)
    sbindir="$ac_optarg" ;;

  -sharedstatedir | --sharedstatedir | --sharedstatedi \
  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
  | --sharedst | --shareds | --shared | --share | --shar \
  | --sha | --sh)
    ac_prev=sharedstatedir ;;
  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
  | --sha=* | --sh=*)
    sharedstatedir="$ac_optarg" ;;

  -site | --site | --sit)
    ac_prev=site ;;
  -site=* | --site=* | --sit=*)
    site="$ac_optarg" ;;

  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
    ac_prev=srcdir ;;
  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
    srcdir="$ac_optarg" ;;

  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
  | --syscon | --sysco | --sysc | --sys | --sy)
    ac_prev=sysconfdir ;;
  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
    sysconfdir="$ac_optarg" ;;

  -target | --target | --targe | --targ | --tar | --ta | --t)
    ac_prev=target ;;
  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
    target="$ac_optarg" ;;

  -v | -verbose | --verbose | --verbos | --verbo | --verb)
    verbose=yes ;;

  -version | --version | --versio | --versi | --vers)
    echo "configure generated by autoconf version 2.13"
    exit 0 ;;

  -with-* | --with-*)
    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`

    # Reject names that are not valid shell variable names.

    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
    fi

    ac_package=`echo $ac_package| sed 's/-/_/g'`
    case "$ac_option" in


      *=*) ;;
      *) ac_optarg=yes ;;


    esac
    eval "with_${ac_package}='$ac_optarg'" ;;


  -without-* | --without-*)
    ac_package=`echo $ac_option|sed -e 's/-*without-//'`

    # Reject names that are not valid shell variable names.
    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
    fi

    ac_package=`echo $ac_package| sed 's/-/_/g'`
    eval "with_${ac_package}=no" ;;










  --x)
    # Obsolete; use --with-x.
    with_x=yes ;;

  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
  | --x-incl | --x-inc | --x-in | --x-i)
    ac_prev=x_includes ;;
  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
    x_includes="$ac_optarg" ;;

  -x-libraries | --x-libraries | --x-librarie | --x-librari \
  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
    ac_prev=x_libraries ;;
  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
    x_libraries="$ac_optarg" ;;

  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }

    ;;











  *)
    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
      echo "configure: warning: $ac_option: invalid host type" 1>&2
    fi
    if test "x$nonopt" != xNONE; then
      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
    fi
    nonopt="$ac_option"





    ;;

  esac
done

if test -n "$ac_prev"; then
  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }

fi

trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15

# File descriptor usage:
# 0 standard input
# 1 file creation
# 2 errors and warnings
# 3 some systems may open it to /dev/tty
# 4 used on the Kubota Titan
# 6 checking for... messages and results
# 5 compiler messages saved in config.log
if test "$silent" = yes; then
  exec 6>/dev/null
else

  exec 6>&1


fi
exec 5>./config.log

echo "\
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
" 1>&5


# Strip out --no-create and --no-recursion so they do not pile up.
# Also quote any args containing shell metacharacters.
ac_configure_args=
for ac_arg
do



  case "$ac_arg" in
  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
  | --no-cr | --no-c) ;;
  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
  esac

done

# NLS nuisances.
# Only set these to C if already set.  These must not be set unconditionally
# because not all systems understand e.g. LANG=C (notably SCO).
# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
# Non-C LC_CTYPE values break the ctype check.
if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi



# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
# AIX cpp loses on an empty file, so make sure it contains at least a newline.
echo > confdefs.h



# A filename unique to this package, relative to the directory that
# configure is in, which we can look for to find out if srcdir is correct.
ac_unique_file=tdomhtml.tcl













# Find the source files, if location was not specified.
if test -z "$srcdir"; then
  ac_srcdir_defaulted=yes
  # Try the directory containing this script, then its parent.
  ac_prog=$0
  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.























  srcdir=$ac_confdir
  if test ! -r $srcdir/$ac_unique_file; then
    srcdir=..
  fi
else
  ac_srcdir_defaulted=no
fi
if test ! -r $srcdir/$ac_unique_file; then
  if test "$ac_srcdir_defaulted" = yes; then
    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }


















































































































































  else
    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }




  fi












fi
srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`















































































































































































































































# Prefer explicitly selected file to automatically selected ones.


if test -z "$CONFIG_SITE"; then






  if test "x$prefix" != xNONE; then
    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"

  else
    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"

  fi
fi
for ac_site_file in $CONFIG_SITE; do


  if test -r "$ac_site_file"; then

    echo "loading site script $ac_site_file"

    . "$ac_site_file"




  fi
done

if test -r "$cache_file"; then




  echo "loading cache $cache_file"
  . $cache_file




else

  echo "creating cache $cache_file"
  > $cache_file
fi






























































ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross

ac_exeext=
ac_objext=o
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
    ac_n= ac_c='
' ac_t='	'
  else
    ac_n=-n ac_c= ac_t=
  fi
else
  ac_n= ac_c='\c' ac_t=
fi




ac_aux_dir=
for ac_dir in ../../tclconfig $srcdir/../../tclconfig; do
  if test -f $ac_dir/install-sh; then
    ac_aux_dir=$ac_dir
    ac_install_sh="$ac_aux_dir/install-sh -c"
    break
  elif test -f $ac_dir/install.sh; then
    ac_aux_dir=$ac_dir
    ac_install_sh="$ac_aux_dir/install.sh -c"
    break




  fi
done
if test -z "$ac_aux_dir"; then
  { echo "configure: error: can not find install-sh or install.sh in ../../tclconfig $srcdir/../../tclconfig" 1>&2; exit 1; }
fi
ac_config_guess=$ac_aux_dir/config.guess

ac_config_sub=$ac_aux_dir/config.sub
ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.







CONFIGDIR=${srcdir}/../../tclconfig


#----------------------------------------------------------------------
# __CHANGE__
# Set your package name and version numbers here.  The NODOT_VERSION is
................................................................................


#--------------------------------------------------------------------
# We put this here so that you can compile with -DVERSION="1.2" to
# encode the package version directly into the source files.
#--------------------------------------------------------------------

eval cat >> confdefs.h <<EOF
#define VERSION "${VERSION}"
EOF


#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows".
#--------------------------------------------------------------------

................................................................................
# Find a good install program.  We prefer a C program (faster),
# so one script is as good as another.  But avoid the broken or
# incompatible versions:
# SysV /etc/install, /usr/sbin/install
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install

# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"

# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:628: checking for a BSD compatible install" >&5


if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then

  echo $ac_n "(cached) $ac_c" 1>&6
else
    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS=":"

  for ac_dir in $PATH; do



    # Account for people who put trailing slashes in PATH elements.
    case "$ac_dir/" in
    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;





    *)
      # OSF1 and SCO ODT 3.0 have their own names for install.
      # Don't use installbsd from OSF since it installs stuff as root
      # by default.
      for ac_prog in ginstall scoinst install; do
        if test -f $ac_dir/$ac_prog; then


	  if test $ac_prog = install &&
            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
	    # AIX install.  It has an incompatible calling convention.
	    :




	  else









	    ac_cv_path_install="$ac_dir/$ac_prog -c"
	    break 2

	  fi
	fi
      done

      ;;
    esac

  done
  IFS="$ac_save_IFS"



fi
  if test "${ac_cv_path_install+set}" = set; then
    INSTALL="$ac_cv_path_install"
  else
    # As a last resort, use the slow shell script.  We don't cache a
    # path for INSTALL within a source directory, because that will
    # break other packages using the cache if that directory is
    # removed, or if the path is relative.
    INSTALL="$ac_install_sh"
  fi
fi

echo "$ac_t""$INSTALL" 1>&6

# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'

test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'

test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'


#--------------------------------------------------------------------
# __CHANGE__
# Choose which headers you need.  Extension authors should try very
................................................................................

#--------------------------------------------------------------------
# Finally, substitute all of the various values into the Makefile.
# You may alternatively have a special pkgIndex.tcl.in or other files
# which require substituting th AC variables in.  Include these here.
#--------------------------------------------------------------------

trap '' 1 2 15

cat > confcache <<\EOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure

# scripts and configure runs.  It is not useful on other systems.
# If it contains results you don't want to keep, you may remove or edit it.
#
# By default, configure uses ./config.cache as the cache file,
# creating it if it does not exist already.  You can give configure
# the --cache-file=FILE option to use a different cache file; that is
# what configure does when it calls configure scripts in
# subdirectories, so they share the cache.
# Giving --cache-file=/dev/null disables caching, for debugging configure.
# config.status only pays attention to the cache file if you give it the
# --recheck option to rerun configure.
#




EOF

# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, don't put newlines in cache variables' values.

# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.

















(set) 2>&1 |
  case `(ac_space=' '; set | grep ac_space) 2>&1` in
  *ac_space=\ *)
    # `set' does not quote correctly, so add quotes (double-quote substitution
    # turns \\\\ into \\, and sed turns \\ into \).
    sed -n \
      -e "s/'/'\\\\''/g" \
      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"

    ;;
  *)
    # `set' quotes correctly as required by POSIX, so do not add quotes.
    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'

    ;;










  esac >> confcache
if cmp -s $cache_file confcache; then
  :







else
  if test -w $cache_file; then

    echo "updating cache $cache_file"


    cat confcache > $cache_file



  else

    echo "not updating unwritable cache $cache_file"
  fi
fi
rm -f confcache

trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15

test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'

# Any assignment to VPATH causes Sun make to only execute
# the first set of double-colon rules, so remove it if not needed.
# If there is a colon in the path, we need to keep it.
if test "x$srcdir" = x.; then
  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
fi

trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15

# Transform confdefs.h into DEFS.
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
cat > conftest.defs <<\EOF
s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
s%[ 	`~#$^&*(){}\\|;'"<>?]%\\&%g
s%\[%\\&%g
s%\]%\\&%g
s%\$%$$%g
EOF
DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
rm -f conftest.defs


# Without the "./", some shells look in PATH for config.status.
: ${CONFIG_STATUS=./config.status}

echo creating $CONFIG_STATUS
rm -f $CONFIG_STATUS
cat > $CONFIG_STATUS <<EOF
#! /bin/sh
# Generated automatically by configure.
# Run this file to recreate the current configuration.
# This directory was configured as follows,
# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
#
# $0 $ac_configure_args
#
# Compiler output produced by configure, useful for debugging
# configure, is in ./config.log if it exists.

ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
for ac_option
do
  case "\$ac_option" in
  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
    echo "$CONFIG_STATUS generated by autoconf version 2.13"
    exit 0 ;;
  -help | --help | --hel | --he | --h)
    echo "\$ac_cs_usage"; exit 0 ;;
  *) echo "\$ac_cs_usage"; exit 1 ;;
  esac
done

ac_given_srcdir=$srcdir
ac_given_INSTALL="$INSTALL"

trap 'rm -fr `echo "Makefile pkgIndex.tcl" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS <<EOF

# Protect against being on the right side of a sed subst in config.status.
sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
 s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
$ac_vpsub
$extrasub
s%@SHELL@%$SHELL%g
s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g
s%@FFLAGS@%$FFLAGS%g
s%@DEFS@%$DEFS%g
s%@LDFLAGS@%$LDFLAGS%g
s%@LIBS@%$LIBS%g
s%@exec_prefix@%$exec_prefix%g
s%@prefix@%$prefix%g
s%@program_transform_name@%$program_transform_name%g
s%@bindir@%$bindir%g
s%@sbindir@%$sbindir%g
s%@libexecdir@%$libexecdir%g
s%@datadir@%$datadir%g
s%@sysconfdir@%$sysconfdir%g
s%@sharedstatedir@%$sharedstatedir%g
s%@localstatedir@%$localstatedir%g
s%@libdir@%$libdir%g
s%@includedir@%$includedir%g
s%@oldincludedir@%$oldincludedir%g
s%@infodir@%$infodir%g
s%@mandir@%$mandir%g
s%@CONFIGDIR@%$CONFIGDIR%g
s%@PACKAGE@%$PACKAGE%g
s%@VERSION@%$VERSION%g
s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
s%@INSTALL_DATA@%$INSTALL_DATA%g
s%@CLEANFILES@%$CLEANFILES%g
s%@EXTRA_SOURCES@%$EXTRA_SOURCES%g

CEOF
EOF

cat >> $CONFIG_STATUS <<\EOF

# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
ac_file=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_cmds # Line after last line for current file.
ac_more_lines=:
ac_sed_cmds=""
while $ac_more_lines; do
  if test $ac_beg -gt 1; then
    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
  else
    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
  fi
  if test ! -s conftest.s$ac_file; then
    ac_more_lines=false
    rm -f conftest.s$ac_file
  else
    if test -z "$ac_sed_cmds"; then
      ac_sed_cmds="sed -f conftest.s$ac_file"
    else
      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
    fi
    ac_file=`expr $ac_file + 1`
    ac_beg=$ac_end
    ac_end=`expr $ac_end + $ac_max_sed_cmds`
  fi
done
if test -z "$ac_sed_cmds"; then
  ac_sed_cmds=cat
fi
EOF

cat >> $CONFIG_STATUS <<EOF

CONFIG_FILES=\${CONFIG_FILES-"Makefile pkgIndex.tcl"}
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
  case "$ac_file" in
  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
  *) ac_file_in="${ac_file}.in" ;;
  esac

  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.

  # Remove last slash and all that follows it.  Not all systems have dirname.
  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
    # The file is in a subdirectory.
    test ! -d "$ac_dir" && mkdir "$ac_dir"
    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
    # A "../" for each directory in $ac_dir_suffix.
    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
  else
    ac_dir_suffix= ac_dots=
  fi

  case "$ac_given_srcdir" in
  .)  srcdir=.
      if test -z "$ac_dots"; then top_srcdir=.
      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
  *) # Relative path.
    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
    top_srcdir="$ac_dots$ac_given_srcdir" ;;
  esac

  case "$ac_given_INSTALL" in
  [/$]*) INSTALL="$ac_given_INSTALL" ;;
  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
  esac

  echo creating "$ac_file"
  rm -f "$ac_file"
  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
  case "$ac_file" in
  *Makefile*) ac_comsub="1i\\
# $configure_input" ;;
  *) ac_comsub= ;;
  esac

  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
  sed -e "$ac_comsub
s%@configure_input@%$configure_input%g
s%@srcdir@%$srcdir%g
s%@top_srcdir@%$top_srcdir%g
s%@INSTALL@%$INSTALL%g
" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
fi; done
rm -f conftest.s*

EOF
cat >> $CONFIG_STATUS <<EOF

EOF
cat >> $CONFIG_STATUS <<\EOF

exit 0
EOF
chmod +x $CONFIG_STATUS
rm -fr confdefs* $ac_clean_files
test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1































































































































































































































































































































































































































































































































































































































































































































































































































































































<

<
>
>
>
|

>


>
>
>

<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>


<
|

<

<








<



>
>
>
>
>
>
>



|
>



<


>
|
|
<
>
|
|
|
|
|
<


>


<


|




|
|
|
>




|
>
>




|


|

|






|

>
>
>
|

|
<
|

>
>
>
>
>
>
>

<
>

<
<
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>

<
>

<
<
<
<
<
>
>
>
>
>
>
>
|
<
>
>

<
>








|





|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


|

>
>
>
>
>
>
|






|




|




|






|

>
>
>
>
>

|
<


|
<
|




|






|













|




|






|






|







 







|
>
>
>
>
>
>
>
>
>
>









|










|




|




|






|


|

|




|
|
<


<
>

>
|
|
<
>
|
<
>
>
|
<
>
>

<
>


<
>

<
<
<
>
|
|
>
>
>
>
>
>
>
>
>










|






|

|
>


>
>
>
>
>
>
>
>
>
>

<
<
<
<
<
<
<
>
>
>
>
>






|
>


<
<
<
<
<
<
<
<
<
<
|
|
<
>
|
>
>

<

<
|
|
|
<
>
|
<
<
<

>
>
>
|
|
|
|
|
|
|
|

>


<
|
|
|
|
|
|
<
<

>
>
|
|
|
|
>
>

<
<
|
>

>
>
>
>
>
>
>
>
>
>
>



|
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|





|
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>

<

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
|
|
>
|
|
>
|
<
|
>
>
|
>
|
>
|
>
>
>
>




>
>
>
>
|
|
>
>
>
>

>
|
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<

|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>




|
|



|



>
>
>
>



|

<
>
|
|
>
>
>
>
>
>







 







|

|







 







>



>

<
|
>
>

<
>
|

<
>
|
>
>
>

<
<
>
>
>
>
>
|
|
|
|
|
<
>
>

|


>
>
>
>

>
>
>
>
>
>
>
>
>
|
|
>



>
|
|
>

|
>
>



|

|
|

|
|


>
|





|







 







|
>
|


>
|
|

<
<
<
<
<
<
|
|

>
>
>
>
|
>


<
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
<
>
|
|
|
<
>
|
>
>
>
>
>
>
>
>
>
>
|
<
<
>
>
>
>
>
>
>
|
|
>
|
>
>
|
>
>
>

>
|




<
<




|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1

2

3
4
5
6
7
8
9
10
11
12
13
14


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567

568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648

649
650

651

652
653
654
655
656
657
658
659

660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677

678
679
680
681
682

683
684
685
686
687
688

689
690
691
692
693

694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735

736
737
738
739
740
741
742
743
744
745

746
747





748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771

772
773





774
775
776
777
778
779
780
781

782
783
784

785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
















































806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848

849
850
851

852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
...
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973

974
975

976
977
978
979
980

981
982

983
984
985

986
987
988

989
990
991

992
993



994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039







1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054










1055
1056

1057
1058
1059
1060
1061

1062

1063
1064
1065

1066
1067



1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083

1084
1085
1086
1087
1088
1089


1090
1091
1092
1093
1094
1095
1096
1097
1098
1099


1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117



1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149

1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296

1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314

1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570

1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664

1665
1666
1667















1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690

1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
....
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
....
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784

1785
1786
1787
1788

1789
1790
1791

1792
1793
1794
1795
1796
1797


1798
1799
1800
1801
1802
1803
1804
1805
1806
1807

1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
....
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980






1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991

1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018

2019
2020
2021
2022

2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035


2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059


2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
#! /bin/sh

# Guess values for system-dependent variables and create Makefiles.

# Generated by GNU Autoconf 2.69.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##



# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '${1+"$@"}'='"$@"'
  setopt NO_GLOB_SUBST
else
  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac
fi


as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='print -r --'
  as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
else
  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
    as_echo_n='/usr/ucb/echo -n'
  else
    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
    as_echo_n_body='eval
      arg=$1;
      case $arg in #(
      *"$as_nl"*)
	expr "X$arg" : "X\\(.*\\)$as_nl";
	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
      esac;
      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
    '
    export as_echo_n_body
    as_echo_n='sh -c $as_echo_n_body as_echo'
  fi
  export as_echo_body
  as_echo='sh -c $as_echo_body as_echo'
fi

# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi


# IFS
# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" ""	$as_nl"

# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
  *[\\/]* ) as_myself=$0 ;;
  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
  done
IFS=$as_save_IFS

     ;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
  as_myself=$0
fi
if test ! -f "$as_myself"; then
  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi

# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH

# Use a proper internal environment variable to ensure we don't fall
  # into an infinite loop, continuously re-executing ourselves.
  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
    _as_can_reexec=no; export _as_can_reexec;
    # We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
  *v*x* | *x*v* ) as_opts=-vx ;;
  *v* ) as_opts=-v ;;
  *x* ) as_opts=-x ;;
  * ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
as_fn_exit 255
  fi
  # We don't want this to propagate to other subprocesses.
          { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '\${1+\"\$@\"}'='\"\$@\"'
  setopt NO_GLOB_SUBST
else
  case \`(set -o) 2>/dev/null\` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac
fi
"
  as_required="as_fn_return () { (exit \$1); }
as_fn_success () { as_fn_return 0; }
as_fn_failure () { as_fn_return 1; }
as_fn_ret_success () { return 0; }
as_fn_ret_failure () { return 1; }

exitcode=0
as_fn_success || { exitcode=1; echo as_fn_success failed.; }
as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :

else
  exitcode=1; echo positional parameters were not saved.
fi
test x\$exitcode = x0 || exit 1
test -x / || exit 1"
  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
  if (eval "$as_required") 2>/dev/null; then :
  as_have_required=yes
else
  as_have_required=no
fi
  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :

else
  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
as_found=false
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
  as_found=:
  case $as_dir in #(
	 /*)
	   for as_base in sh bash ksh sh5; do
	     # Try only shells that exist, to save several forks.
	     as_shell=$as_dir/$as_base
	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
  CONFIG_SHELL=$as_shell as_have_required=yes
		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
  break 2
fi
fi
	   done;;
       esac
  as_found=false
done
$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
  CONFIG_SHELL=$SHELL as_have_required=yes
fi; }
IFS=$as_save_IFS


      if test "x$CONFIG_SHELL" != x; then :
  export CONFIG_SHELL
             # We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
  *v*x* | *x*v* ) as_opts=-vx ;;
  *v* ) as_opts=-v ;;
  *x* ) as_opts=-x ;;
  * ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
exit 255
fi

    if test x$as_have_required = xno; then :
  $as_echo "$0: This script requires a shell more modern than all"
  $as_echo "$0: the shells that I found on your system."
  if test x${ZSH_VERSION+set} = xset ; then
    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
  else
    $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
$0: including any error possibly output before this
$0: message. Then install a modern shell, or manually run
$0: the script under such a shell if you do have one."
  fi
  exit 1
fi
fi
fi
SHELL=${CONFIG_SHELL-/bin/sh}
export SHELL
# Unset more variables known to interfere with behavior of common tools.
CLICOLOR_FORCE= GREP_OPTIONS=
unset CLICOLOR_FORCE GREP_OPTIONS

## --------------------- ##
## M4sh Shell Functions. ##
## --------------------- ##
# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
  { eval $1=; unset $1;}
}
as_unset=as_fn_unset

# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
  return $1
} # as_fn_set_status

# as_fn_exit STATUS
# -----------------
# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
as_fn_exit ()
{
  set +e
  as_fn_set_status $1
  exit $1
} # as_fn_exit

# as_fn_mkdir_p
# -------------
# Create "$as_dir" as a directory, including parents if necessary.
as_fn_mkdir_p ()
{

  case $as_dir in #(
  -*) as_dir=./$as_dir;;
  esac
  test -d "$as_dir" || eval $as_mkdir_p || {
    as_dirs=
    while :; do
      case $as_dir in #(
      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
      *) as_qdir=$as_dir;;
      esac
      as_dirs="'$as_qdir' $as_dirs"
      as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_dir" : 'X\(//\)[^/]' \| \
	 X"$as_dir" : 'X\(//\)$' \| \
	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\).*/{
	    s//\1/
	    q
	  }
	  s/.*/./; q'`
      test -d "$as_dir" && break
    done
    test -z "$as_dirs" || eval "mkdir $as_dirs"
  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"


} # as_fn_mkdir_p

# as_fn_executable_p FILE
# -----------------------
# Test if FILE is an executable regular file.
as_fn_executable_p ()
{
  test -f "$1" && test -x "$1"
} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
  eval 'as_fn_append ()
  {
    eval $1+=\$2
  }'
else
  as_fn_append ()
  {
    eval $1=\$$1\$2
  }
fi # as_fn_append

# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else
  as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  }
fi # as_fn_arith


# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
  as_status=$1; test $as_status -eq 0 && as_status=1
  if test "$4"; then
    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  $as_echo "$as_me: error: $2" >&2
  as_fn_exit $as_status
} # as_fn_error

if expr a : '\(a\)' >/dev/null 2>&1 &&
   test "X`expr 00001 : '.*\(...\)'`" = X001; then
  as_expr=expr
else
  as_expr=false
fi

if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
  as_basename=basename
else
  as_basename=false
fi

if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
  as_dirname=dirname
else
  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\).*/{
	    s//\1/
	    q
	  }
	  s/.*/./; q'`

# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits


  as_lineno_1=$LINENO as_lineno_1a=$LINENO
  as_lineno_2=$LINENO as_lineno_2a=$LINENO
  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
  sed -n '
    p
    /[$]LINENO/=
  ' <$as_myself |
    sed '
      s/[$]LINENO.*/&-/
      t lineno
      b
      :lineno
      N
      :loop
      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
      t loop
      s/-\n.*//
    ' >$as_me.lineno &&
  chmod +x "$as_me.lineno" ||
    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }

  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
  # already done that, so ensure we don't try to do so again and fall
  # in an infinite loop.  This has already happened in practice.
  _as_can_reexec=no; export _as_can_reexec
  # Don't try to exec as it changes $[0], causing all sort of problems
  # (the dirname of $[0] is not the place where we might find the
  # original and so on.  Autoconf is especially sensitive to this).
  . "./$as_me.lineno"
  # Exit status is that of the last command.
  exit
}

ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
  case `echo 'xy\c'` in
  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;
  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
       ECHO_T='	';;
  esac;;
*)
  ECHO_N='-n';;
esac

rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  rm -f conf$$.dir/conf$$.file
else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
fi
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
    # In both cases, we have to default to `cp -pR'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
  fi
else
  as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null

if mkdir -p . 2>/dev/null; then
  as_mkdir_p='mkdir -p "$as_dir"'
else
  test -d ./-p && rmdir ./-p
  as_mkdir_p=false
fi

as_test_x='test -x'
as_executable_p=as_fn_executable_p

# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"

# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"


test -n "$DJDIR" || exec 7<&0 </dev/null
exec 6>&1

# Name of the host.
# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
# so uname gets run too.
ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`

#
# Initializations.
#
ac_default_prefix=/usr/local

ac_clean_files=
ac_config_libobj_dir=.
LIBOBJS=
cross_compiling=no
subdirs=
MFLAGS=
MAKEFLAGS=

# Identity of this package.
PACKAGE_NAME=
PACKAGE_TARNAME=
PACKAGE_VERSION=
PACKAGE_STRING=
PACKAGE_BUGREPORT=
PACKAGE_URL=

ac_unique_file="tdomhtml.tcl"
ac_subst_vars='LTLIBOBJS
LIBOBJS
EXTRA_SOURCES
CLEANFILES
INSTALL_DATA
INSTALL_SCRIPT
INSTALL_PROGRAM
VERSION
PACKAGE
CONFIGDIR
target_alias
host_alias
build_alias
LIBS
ECHO_T
ECHO_N
ECHO_C
DEFS
mandir
localedir
libdir
psdir
pdfdir
dvidir
htmldir
infodir
docdir
oldincludedir
includedir
localstatedir
sharedstatedir
sysconfdir
datadir
datarootdir
libexecdir
sbindir
bindir
program_transform_name
prefix
exec_prefix
PACKAGE_URL
PACKAGE_BUGREPORT
PACKAGE_STRING
PACKAGE_VERSION
PACKAGE_TARNAME
PACKAGE_NAME
PATH_SEPARATOR
SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
'
      ac_precious_vars='build_alias
host_alias
target_alias'


# Initialize some variables set by options.
ac_init_help=
ac_init_version=false
ac_unrecognized_opts=
ac_unrecognized_sep=
# The variables have the same names as the options, with
# dashes changed to underlines.

cache_file=/dev/null
exec_prefix=NONE

no_create=

no_recursion=
prefix=NONE
program_prefix=NONE
program_suffix=NONE
program_transform_name=s,x,x,
silent=
site=
srcdir=

verbose=
x_includes=NONE
x_libraries=NONE

# Installation directory options.
# These are left unexpanded so users can "make install exec_prefix=/foo"
# and all the variables that are supposed to be based on exec_prefix
# by default will actually change.
# Use braces instead of parens because sh, perl, etc. also accept them.
# (The list follows the same order as the GNU Coding Standards.)
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datarootdir='${prefix}/share'
datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'

includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE}'
infodir='${datarootdir}/info'
htmldir='${docdir}'

dvidir='${docdir}'
pdfdir='${docdir}'
psdir='${docdir}'
libdir='${exec_prefix}/lib'
localedir='${datarootdir}/locale'
mandir='${datarootdir}/man'


ac_prev=
ac_dashdash=
for ac_option
do

  # If the previous option needs an argument, assign it.
  if test -n "$ac_prev"; then
    eval $ac_prev=\$ac_option
    ac_prev=
    continue
  fi

  case $ac_option in
  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
  *=)   ac_optarg= ;;
  *)    ac_optarg=yes ;;
  esac

  # Accept the important Cygnus configure options, so we can diagnose typos.

  case $ac_dashdash$ac_option in
  --)
    ac_dashdash=yes ;;

  -bindir | --bindir | --bindi | --bind | --bin | --bi)
    ac_prev=bindir ;;
  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
    bindir=$ac_optarg ;;

  -build | --build | --buil | --bui | --bu)
    ac_prev=build_alias ;;
  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
    build_alias=$ac_optarg ;;

  -cache-file | --cache-file | --cache-fil | --cache-fi \
  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
    ac_prev=cache_file ;;
  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
    cache_file=$ac_optarg ;;

  --config-cache | -C)
    cache_file=config.cache ;;

  -datadir | --datadir | --datadi | --datad)
    ac_prev=datadir ;;
  -datadir=* | --datadir=* | --datadi=* | --datad=*)

    datadir=$ac_optarg ;;

  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
  | --dataroo | --dataro | --datar)
    ac_prev=datarootdir ;;
  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
    datarootdir=$ac_optarg ;;

  -disable-* | --disable-*)

    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
    # Reject names that are not valid shell variable names.





    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"enable_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
    eval enable_$ac_useropt=no ;;

  -docdir | --docdir | --docdi | --doc | --do)
    ac_prev=docdir ;;
  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
    docdir=$ac_optarg ;;

  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
    ac_prev=dvidir ;;
  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
    dvidir=$ac_optarg ;;

  -enable-* | --enable-*)

    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
    # Reject names that are not valid shell variable names.





    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid feature name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"enable_$ac_useropt"
"*) ;;

      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac

    eval enable_$ac_useropt=\$ac_optarg ;;

  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
  | --exec | --exe | --ex)
    ac_prev=exec_prefix ;;
  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
  | --exec=* | --exe=* | --ex=*)
    exec_prefix=$ac_optarg ;;

  -gas | --gas | --ga | --g)
    # Obsolete; use --with-gas.
    with_gas=yes ;;

  -help | --help | --hel | --he | -h)
    ac_init_help=long ;;
  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
    ac_init_help=recursive ;;
  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
    ac_init_help=short ;;

















































  -host | --host | --hos | --ho)
    ac_prev=host_alias ;;
  -host=* | --host=* | --hos=* | --ho=*)
    host_alias=$ac_optarg ;;

  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
    ac_prev=htmldir ;;
  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
  | --ht=*)
    htmldir=$ac_optarg ;;

  -includedir | --includedir | --includedi | --included | --include \
  | --includ | --inclu | --incl | --inc)
    ac_prev=includedir ;;
  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
  | --includ=* | --inclu=* | --incl=* | --inc=*)
    includedir=$ac_optarg ;;

  -infodir | --infodir | --infodi | --infod | --info | --inf)
    ac_prev=infodir ;;
  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
    infodir=$ac_optarg ;;

  -libdir | --libdir | --libdi | --libd)
    ac_prev=libdir ;;
  -libdir=* | --libdir=* | --libdi=* | --libd=*)
    libdir=$ac_optarg ;;

  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
  | --libexe | --libex | --libe)
    ac_prev=libexecdir ;;
  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
  | --libexe=* | --libex=* | --libe=*)
    libexecdir=$ac_optarg ;;

  -localedir | --localedir | --localedi | --localed | --locale)
    ac_prev=localedir ;;
  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
    localedir=$ac_optarg ;;

  -localstatedir | --localstatedir | --localstatedi | --localstated \
  | --localstate | --localstat | --localsta | --localst | --locals)

    ac_prev=localstatedir ;;
  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)

    localstatedir=$ac_optarg ;;

  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
    ac_prev=mandir ;;
  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
    mandir=$ac_optarg ;;

  -nfp | --nfp | --nf)
    # Obsolete; use --without-fp.
    with_fp=no ;;

  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
  | --no-cr | --no-c | -n)
    no_create=yes ;;

  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
    no_recursion=yes ;;

  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
  | --oldin | --oldi | --old | --ol | --o)
    ac_prev=oldincludedir ;;
  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
    oldincludedir=$ac_optarg ;;

  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
    ac_prev=prefix ;;
  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
    prefix=$ac_optarg ;;

  -program-prefix | --program-prefix | --program-prefi | --program-pref \
  | --program-pre | --program-pr | --program-p)
    ac_prev=program_prefix ;;
  -program-prefix=* | --program-prefix=* | --program-prefi=* \
  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
    program_prefix=$ac_optarg ;;

  -program-suffix | --program-suffix | --program-suffi | --program-suff \
  | --program-suf | --program-su | --program-s)
    ac_prev=program_suffix ;;
  -program-suffix=* | --program-suffix=* | --program-suffi=* \
  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
    program_suffix=$ac_optarg ;;

  -program-transform-name | --program-transform-name \
  | --program-transform-nam | --program-transform-na \
  | --program-transform-n | --program-transform- \
  | --program-transform | --program-transfor \
  | --program-transfo | --program-transf \
  | --program-trans | --program-tran \
................................................................................
  -program-transform-name=* | --program-transform-name=* \
  | --program-transform-nam=* | --program-transform-na=* \
  | --program-transform-n=* | --program-transform-=* \
  | --program-transform=* | --program-transfor=* \
  | --program-transfo=* | --program-transf=* \
  | --program-trans=* | --program-tran=* \
  | --progr-tra=* | --program-tr=* | --program-t=*)
    program_transform_name=$ac_optarg ;;

  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
    ac_prev=pdfdir ;;
  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
    pdfdir=$ac_optarg ;;

  -psdir | --psdir | --psdi | --psd | --ps)
    ac_prev=psdir ;;
  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
    psdir=$ac_optarg ;;

  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil)
    silent=yes ;;

  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
    ac_prev=sbindir ;;
  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
  | --sbi=* | --sb=*)
    sbindir=$ac_optarg ;;

  -sharedstatedir | --sharedstatedir | --sharedstatedi \
  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
  | --sharedst | --shareds | --shared | --share | --shar \
  | --sha | --sh)
    ac_prev=sharedstatedir ;;
  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
  | --sha=* | --sh=*)
    sharedstatedir=$ac_optarg ;;

  -site | --site | --sit)
    ac_prev=site ;;
  -site=* | --site=* | --sit=*)
    site=$ac_optarg ;;

  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
    ac_prev=srcdir ;;
  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
    srcdir=$ac_optarg ;;

  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
  | --syscon | --sysco | --sysc | --sys | --sy)
    ac_prev=sysconfdir ;;
  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
    sysconfdir=$ac_optarg ;;

  -target | --target | --targe | --targ | --tar | --ta | --t)
    ac_prev=target_alias ;;
  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
    target_alias=$ac_optarg ;;

  -v | -verbose | --verbose | --verbos | --verbo | --verb)
    verbose=yes ;;

  -version | --version | --versio | --versi | --vers | -V)
    ac_init_version=: ;;


  -with-* | --with-*)

    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
    # Reject names that are not valid shell variable names.
    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: $ac_useropt"
    ac_useropt_orig=$ac_useropt

    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in

      *"
"with_$ac_useropt"
"*) ;;

      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac

    eval with_$ac_useropt=\$ac_optarg ;;

  -without-* | --without-*)

    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
    # Reject names that are not valid shell variable names.



    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
      as_fn_error $? "invalid package name: $ac_useropt"
    ac_useropt_orig=$ac_useropt
    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
    case $ac_user_opts in
      *"
"with_$ac_useropt"
"*) ;;
      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
	 ac_unrecognized_sep=', ';;
    esac
    eval with_$ac_useropt=no ;;

  --x)
    # Obsolete; use --with-x.
    with_x=yes ;;

  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
  | --x-incl | --x-inc | --x-in | --x-i)
    ac_prev=x_includes ;;
  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
    x_includes=$ac_optarg ;;

  -x-libraries | --x-libraries | --x-librarie | --x-librari \
  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
    ac_prev=x_libraries ;;
  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
    x_libraries=$ac_optarg ;;

  -*) as_fn_error $? "unrecognized option: \`$ac_option'
Try \`$0 --help' for more information"
    ;;

  *=*)
    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
    # Reject names that are not valid shell variable names.
    case $ac_envvar in #(
      '' | [0-9]* | *[!_$as_cr_alnum]* )
      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
    esac
    eval $ac_envvar=\$ac_optarg
    export $ac_envvar ;;

  *)







    # FIXME: should be removed in autoconf 3.0.
    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
    ;;

  esac
done

if test -n "$ac_prev"; then
  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
  as_fn_error $? "missing argument to $ac_option"
fi











if test -n "$ac_unrecognized_opts"; then
  case $enable_option_checking in

    no) ;;
    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
  esac
fi



# Check all directory arguments for consistency.
for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
		datadir sysconfdir sharedstatedir localstatedir includedir \

		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
		libdir localedir mandir



do
  eval ac_val=\$$ac_var
  # Remove trailing slashes.
  case $ac_val in
    */ )
      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
      eval $ac_var=\$ac_val;;
  esac
  # Be sure to have absolute directory names.
  case $ac_val in
    [\\/$]* | ?:[\\/]* )  continue;;
    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
  esac
  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
done


# There might be people who depend on the old broken behavior: `$host'
# used to hold the argument of --host etc.
# FIXME: To remove some day.
build=$build_alias
host=$host_alias
target=$target_alias



# FIXME: To remove some day.
if test "x$host_alias" != x; then
  if test "x$build_alias" = x; then
    cross_compiling=maybe
  elif test "x$build_alias" != "x$host_alias"; then
    cross_compiling=yes
  fi
fi



ac_tool_prefix=
test -n "$host_alias" && ac_tool_prefix=$host_alias-

test "$silent" = yes && exec 6>/dev/null


ac_pwd=`pwd` && test -n "$ac_pwd" &&
ac_ls_di=`ls -di .` &&
ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
  as_fn_error $? "working directory cannot be determined"
test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
  as_fn_error $? "pwd does not report name of working directory"


# Find the source files, if location was not specified.
if test -z "$srcdir"; then
  ac_srcdir_defaulted=yes
  # Try the directory containing this script, then the parent directory.



  ac_confdir=`$as_dirname -- "$as_myself" ||
$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_myself" : 'X\(//\)[^/]' \| \
	 X"$as_myself" : 'X\(//\)$' \| \
	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_myself" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\).*/{
	    s//\1/
	    q
	  }
	  s/.*/./; q'`
  srcdir=$ac_confdir
  if test ! -r "$srcdir/$ac_unique_file"; then
    srcdir=..
  fi
else
  ac_srcdir_defaulted=no
fi
if test ! -r "$srcdir/$ac_unique_file"; then
  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."

  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
fi
ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
ac_abs_confdir=`(
	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
	pwd)`
# When building in place, set srcdir=.
if test "$ac_abs_confdir" = "$ac_pwd"; then
  srcdir=.
fi
# Remove unnecessary trailing slashes from srcdir.
# Double slashes in file names in object file debugging info
# mess up M-x gdb in Emacs.
case $srcdir in
*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
esac
for ac_var in $ac_precious_vars; do
  eval ac_env_${ac_var}_set=\${${ac_var}+set}
  eval ac_env_${ac_var}_value=\$${ac_var}
  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
  eval ac_cv_env_${ac_var}_value=\$${ac_var}
done

#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures this package to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print \`checking ...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for \`--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or \`..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [$ac_default_prefix]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, \`make install' will install all the files in
\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
an installation prefix other than \`$ac_default_prefix' using \`--prefix',
for instance \`--prefix=\$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]
  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR            man documentation [DATAROOTDIR/man]
  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
  --htmldir=DIR           html documentation [DOCDIR]
  --dvidir=DIR            dvi documentation [DOCDIR]
  --pdfdir=DIR            pdf documentation [DOCDIR]
  --psdir=DIR             ps documentation [DOCDIR]
_ACEOF

  cat <<\_ACEOF
_ACEOF
fi

if test -n "$ac_init_help"; then

  cat <<\_ACEOF

Report bugs to the package provider.
_ACEOF
ac_status=$?
fi

if test "$ac_init_help" = "recursive"; then
  # If there are subdirs, report their specific --help.
  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
    test -d "$ac_dir" ||
      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
      continue
    ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
  # A ".." for each directory in $ac_dir_suffix.
  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
  case $ac_top_builddir_sub in
  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
  esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
# for backward compatibility:
ac_top_builddir=$ac_top_build_prefix

case $srcdir in
  .)  # We are building in place.
    ac_srcdir=.
    ac_top_srcdir=$ac_top_builddir_sub
    ac_abs_top_srcdir=$ac_pwd ;;
  [\\/]* | ?:[\\/]* )  # Absolute name.
    ac_srcdir=$srcdir$ac_dir_suffix;
    ac_top_srcdir=$srcdir
    ac_abs_top_srcdir=$srcdir ;;
  *) # Relative name.
    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
    ac_top_srcdir=$ac_top_build_prefix$srcdir
    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix

    cd "$ac_dir" || { ac_status=$?; continue; }
    # Check for guested configure.
    if test -f "$ac_srcdir/configure.gnu"; then
      echo &&
      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
    elif test -f "$ac_srcdir/configure"; then
      echo &&
      $SHELL "$ac_srcdir/configure" --help=recursive
    else

      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
    fi || ac_status=$?
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
configure
generated by GNU Autoconf 2.69

Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
fi


## ------------------------ ##
## Autoconf initialization. ##
## ------------------------ ##
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by $as_me, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
cat <<_ASUNAME
## --------- ##
## Platform. ##
## --------- ##

hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`

/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`

/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`

_ASUNAME

as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    $as_echo "PATH: $as_dir"
  done
IFS=$as_save_IFS

} >&5

cat >&5 <<_ACEOF


## ----------- ##
## Core tests. ##
## ----------- ##

_ACEOF


# Keep a trace of the command line.
# Strip out --no-create and --no-recursion so they do not pile up.
# Strip out --silent because we don't want to record it for future runs.
# Also quote any args containing shell meta-characters.
# Make two passes to allow for proper duplicate-argument suppression.
ac_configure_args=
ac_configure_args0=
ac_configure_args1=
ac_must_keep_next=false
for ac_pass in 1 2
do
  for ac_arg
  do
    case $ac_arg in
    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
    | -silent | --silent | --silen | --sile | --sil)
      continue ;;
    *\'*)
      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
    esac
    case $ac_pass in
    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
    2)
      as_fn_append ac_configure_args1 " '$ac_arg'"
      if test $ac_must_keep_next = true; then
	ac_must_keep_next=false # Got value, back to normal.
      else
	case $ac_arg in
	  *=* | --config-cache | -C | -disable-* | --disable-* \
	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
	  | -with-* | --with-* | -without-* | --without-* | --x)
	    case "$ac_configure_args0 " in
	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
	    esac
	    ;;
	  -* ) ac_must_keep_next=true ;;
	esac
      fi
      as_fn_append ac_configure_args " '$ac_arg'"
      ;;
    esac
  done
done
{ ac_configure_args0=; unset ac_configure_args0;}
{ ac_configure_args1=; unset ac_configure_args1;}

# When interrupted or exit'd, cleanup temporary files, and complete
# config.log.  We remove comments because anyway the quotes in there
# would cause problems or look ugly.
# WARNING: Use '\'' to represent an apostrophe within the trap.
# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
trap 'exit_status=$?
  # Save into config.log some information that might help in debugging.
  {
    echo

    $as_echo "## ---------------- ##
## Cache variables. ##
## ---------------- ##"
    echo
    # The following way of writing the cache mishandles newlines in values,
(
  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
    eval ac_val=\$$ac_var
    case $ac_val in #(
    *${as_nl}*)
      case $ac_var in #(
      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      esac
      case $ac_var in #(
      _ | IFS | as_nl) ;; #(
      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
      *) { eval $ac_var=; unset $ac_var;} ;;
      esac ;;
    esac
  done
  (set) 2>&1 |
    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
    *${as_nl}ac_space=\ *)
      sed -n \
	"s/'\''/'\''\\\\'\'''\''/g;
	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
      ;; #(
    *)
      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
)
    echo

    $as_echo "## ----------------- ##
## Output variables. ##
## ----------------- ##"
    echo
    for ac_var in $ac_subst_vars
    do
      eval ac_val=\$$ac_var
      case $ac_val in
      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
      esac
      $as_echo "$ac_var='\''$ac_val'\''"
    done | sort
    echo

    if test -n "$ac_subst_files"; then
      $as_echo "## ------------------- ##
## File substitutions. ##
## ------------------- ##"
      echo
      for ac_var in $ac_subst_files
      do
	eval ac_val=\$$ac_var
	case $ac_val in
	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
	esac
	$as_echo "$ac_var='\''$ac_val'\''"
      done | sort
      echo
    fi

    if test -s confdefs.h; then
      $as_echo "## ----------- ##
## confdefs.h. ##
## ----------- ##"
      echo
      cat confdefs.h
      echo
    fi
    test "$ac_signal" != 0 &&
      $as_echo "$as_me: caught signal $ac_signal"
    $as_echo "$as_me: exit $exit_status"
  } >&5
  rm -f core *.core core.conftest.* &&
    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
    exit $exit_status
' 0
for ac_signal in 1 2 13 15; do
  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
done
ac_signal=0

# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -f -r conftest* confdefs.h

$as_echo "/* confdefs.h */" > confdefs.h

# Predefined preprocessor variables.

cat >>confdefs.h <<_ACEOF
#define PACKAGE_NAME "$PACKAGE_NAME"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_VERSION "$PACKAGE_VERSION"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_STRING "$PACKAGE_STRING"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
_ACEOF

cat >>confdefs.h <<_ACEOF
#define PACKAGE_URL "$PACKAGE_URL"
_ACEOF


# Let the site file select an alternate cache file if it wants to.
# Prefer an explicitly selected file to automatically selected ones.
ac_site_file1=NONE
ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
  # We do not want a PATH search for config.site.
  case $CONFIG_SITE in #((
    -*)  ac_site_file1=./$CONFIG_SITE;;
    */*) ac_site_file1=$CONFIG_SITE;;
    *)   ac_site_file1=./$CONFIG_SITE;;
  esac
elif test "x$prefix" != xNONE; then
  ac_site_file1=$prefix/share/config.site
  ac_site_file2=$prefix/etc/config.site
else
  ac_site_file1=$ac_default_prefix/share/config.site
  ac_site_file2=$ac_default_prefix/etc/config.site
fi

for ac_site_file in "$ac_site_file1" "$ac_site_file2"
do
  test "x$ac_site_file" = xNONE && continue
  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
$as_echo "$as_me: loading site script $ac_site_file" >&6;}
    sed 's/^/| /' "$ac_site_file" >&5
    . "$ac_site_file" \
      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "failed to load site script $ac_site_file
See \`config.log' for more details" "$LINENO" 5; }
  fi
done

if test -r "$cache_file"; then
  # Some versions of bash will fail to source /dev/null (special files
  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
$as_echo "$as_me: loading cache $cache_file" >&6;}
    case $cache_file in
      [\\/]* | ?:[\\/]* ) . "$cache_file";;
      *)                      . "./$cache_file";;
    esac
  fi
else
  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
$as_echo "$as_me: creating cache $cache_file" >&6;}
  >$cache_file
fi

# Check that the precious variables saved in the cache have kept the same
# value.
ac_cache_corrupted=false
for ac_var in $ac_precious_vars; do
  eval ac_old_set=\$ac_cv_env_${ac_var}_set
  eval ac_new_set=\$ac_env_${ac_var}_set
  eval ac_old_val=\$ac_cv_env_${ac_var}_value
  eval ac_new_val=\$ac_env_${ac_var}_value
  case $ac_old_set,$ac_new_set in
    set,)
      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
      ac_cache_corrupted=: ;;
    ,set)
      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
      ac_cache_corrupted=: ;;
    ,);;
    *)
      if test "x$ac_old_val" != "x$ac_new_val"; then
	# differences in whitespace do not lead to failure.
	ac_old_val_w=`echo x $ac_old_val`
	ac_new_val_w=`echo x $ac_new_val`
	if test "$ac_old_val_w" != "$ac_new_val_w"; then
	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
	  ac_cache_corrupted=:
	else
	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
	  eval $ac_var=\$ac_old_val
	fi
	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
      fi;;
  esac
  # Pass precious variables to config.status.
  if test "$ac_new_set" = set; then
    case $ac_new_val in
    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
    *) ac_arg=$ac_var=$ac_new_val ;;
    esac
    case " $ac_configure_args " in
      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
    esac
  fi
done
if $ac_cache_corrupted; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
fi
## -------------------- ##
## Main body of script. ##
## -------------------- ##

ac_ext=c

ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'















ac_compiler_gnu=$ac_cv_c_compiler_gnu



ac_aux_dir=
for ac_dir in ../../tclconfig "$srcdir"/../../tclconfig; do
  if test -f "$ac_dir/install-sh"; then
    ac_aux_dir=$ac_dir
    ac_install_sh="$ac_aux_dir/install-sh -c"
    break
  elif test -f "$ac_dir/install.sh"; then
    ac_aux_dir=$ac_dir
    ac_install_sh="$ac_aux_dir/install.sh -c"
    break
  elif test -f "$ac_dir/shtool"; then
    ac_aux_dir=$ac_dir
    ac_install_sh="$ac_aux_dir/shtool install -c"
    break
  fi
done
if test -z "$ac_aux_dir"; then
  as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../../tclconfig \"$srcdir\"/../../tclconfig" "$LINENO" 5
fi


# These three variables are undocumented and unsupported,
# and are intended to be withdrawn in a future Autoconf release.
# They can cause serious problems if a builder's source tree is in a directory
# whose full name contains unusual characters.
ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.


CONFIGDIR=${srcdir}/../../tclconfig


#----------------------------------------------------------------------
# __CHANGE__
# Set your package name and version numbers here.  The NODOT_VERSION is
................................................................................


#--------------------------------------------------------------------
# We put this here so that you can compile with -DVERSION="1.2" to
# encode the package version directly into the source files.
#--------------------------------------------------------------------

eval cat >>confdefs.h <<_ACEOF
#define VERSION "${VERSION}"
_ACEOF


#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows".
#--------------------------------------------------------------------

................................................................................
# Find a good install program.  We prefer a C program (faster),
# so one script is as good as another.  But avoid the broken or
# incompatible versions:
# SysV /etc/install, /usr/sbin/install
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install
# AmigaOS /C/install, which installs bootblocks on floppy discs
# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# OS/2's system install, which has a completely different semantic
# ./install, which can be erroneously created by make from ./install.sh.

# Reject install programs that cannot install multiple files.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
$as_echo_n "checking for a BSD-compatible install... " >&6; }
if test -z "$INSTALL"; then

if ${ac_cv_path_install+:} false; then :
  $as_echo_n "(cached) " >&6
else

  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    # Account for people who put trailing slashes in PATH elements.


case $as_dir/ in #((
  ./ | .// | /[cC]/* | \
  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
  /usr/ucb/* ) ;;
  *)
    # OSF1 and SCO ODT 3.0 have their own names for install.
    # Don't use installbsd from OSF since it installs stuff as root
    # by default.
    for ac_prog in ginstall scoinst install; do

      for ac_exec_ext in '' $ac_executable_extensions; do
	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
	  if test $ac_prog = install &&
	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
	    # AIX install.  It has an incompatible calling convention.
	    :
	  elif test $ac_prog = install &&
	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
	    # program-specific install script used by HP pwplus--don't use.
	    :
	  else
	    rm -rf conftest.one conftest.two conftest.dir
	    echo one > conftest.one
	    echo two > conftest.two
	    mkdir conftest.dir
	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
	      test -s conftest.one && test -s conftest.two &&
	      test -s conftest.dir/conftest.one &&
	      test -s conftest.dir/conftest.two
	    then
	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
	      break 3
	    fi
	  fi
	fi
      done
    done
    ;;
esac

  done
IFS=$as_save_IFS

rm -rf conftest.one conftest.two conftest.dir

fi
  if test "${ac_cv_path_install+set}" = set; then
    INSTALL=$ac_cv_path_install
  else
    # As a last resort, use the slow shell script.  Don't cache a
    # value for INSTALL within a source directory, because that will
    # break other packages using the cache if that directory is
    # removed, or if the value is a relative name.
    INSTALL=$ac_install_sh
  fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
$as_echo "$INSTALL" >&6; }

# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'

test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'

test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'


#--------------------------------------------------------------------
# __CHANGE__
# Choose which headers you need.  Extension authors should try very
................................................................................

#--------------------------------------------------------------------
# Finally, substitute all of the various values into the Makefile.
# You may alternatively have a special pkgIndex.tcl.in or other files
# which require substituting th AC variables in.  Include these here.
#--------------------------------------------------------------------

ac_config_files="$ac_config_files Makefile pkgIndex.tcl"

cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems.  If it contains results you don't
# want to keep, you may remove or edit it.
#






# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
# `ac_cv_env_foo' variables (set or unset) will be overridden when
# loading this file, other *unset* `ac_cv_foo' will be assigned the
# following values.

_ACEOF

# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.

# So, we kill variables containing newlines.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(
  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
    eval ac_val=\$$ac_var
    case $ac_val in #(
    *${as_nl}*)
      case $ac_var in #(
      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      esac
      case $ac_var in #(
      _ | IFS | as_nl) ;; #(
      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
      *) { eval $ac_var=; unset $ac_var;} ;;
      esac ;;
    esac
  done

  (set) 2>&1 |
    case $as_nl`(ac_space=' '; set) 2>&1` in #(
    *${as_nl}ac_space=\ *)
      # `set' does not quote correctly, so add quotes: double-quote
      # substitution turns \\\\ into \\, and sed turns \\ into \.
      sed -n \
	"s/'/'\\\\''/g;

	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
      ;; #(
    *)
      # `set' quotes correctly as required by POSIX, so do not add quotes.

      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
      ;;
    esac |
    sort
) |
  sed '
     /^ac_cv_env_/b end
     t clear
     :clear
     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
     t end
     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
     :end' >>confcache


if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
  if test -w "$cache_file"; then
    if test "x$cache_file" != "x/dev/null"; then
      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
$as_echo "$as_me: updating cache $cache_file" >&6;}
      if test ! -f "$cache_file" || test -h "$cache_file"; then
	cat confcache >"$cache_file"
      else
        case $cache_file in #(
        */* | ?:*)
	  mv -f confcache "$cache_file"$$ &&
	  mv -f "$cache_file"$$ "$cache_file" ;; #(
        *)
	  mv -f confcache "$cache_file" ;;
	esac
      fi
    fi
  else
    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
  fi
fi
rm -f confcache



test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'

# Transform confdefs.h into DEFS.
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
#
# If the first sed substitution is executed (which looks for macros that
# take arguments), then branch to the quote section.  Otherwise,
# look for a macro that doesn't take arguments.
ac_script='
:mline
/\\$/{
 N
 s,\\\n,,
 b mline
}
t clear
:clear
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
t quote
s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
t quote
b any
:quote
s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
s/\[/\\&/g
s/\]/\\&/g
s/\$/$$/g
H
:any
${
	g
	s/^\n//
	s/\n/ /g
	p
}
'
DEFS=`sed -n "$ac_script" confdefs.h`


ac_libobjs=
ac_ltlibobjs=
U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
  # 1. Remove the extension, and $U if already installed.
  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
  #    will be set to the directory where LIBOBJS objects are built.
  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
done
LIBOBJS=$ac_libobjs

LTLIBOBJS=$ac_ltlibobjs



: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
as_write_fail=0
cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
#! $SHELL
# Generated by $as_me.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.

debug=false
ac_cs_recheck=false
ac_cs_silent=false

SHELL=\${CONFIG_SHELL-$SHELL}
export SHELL
_ASEOF
cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##

# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
  emulate sh
  NULLCMD=:
  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
  # is contrary to our usage.  Disable this feature.
  alias -g '${1+"$@"}'='"$@"'
  setopt NO_GLOB_SUBST
else
  case `(set -o) 2>/dev/null` in #(
  *posix*) :
    set -o posix ;; #(
  *) :
     ;;
esac
fi


as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='print -r --'
  as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
  as_echo='printf %s\n'
  as_echo_n='printf %s'
else
  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
    as_echo_n='/usr/ucb/echo -n'
  else
    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
    as_echo_n_body='eval
      arg=$1;
      case $arg in #(
      *"$as_nl"*)
	expr "X$arg" : "X\\(.*\\)$as_nl";
	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
      esac;
      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
    '
    export as_echo_n_body
    as_echo_n='sh -c $as_echo_n_body as_echo'
  fi
  export as_echo_body
  as_echo='sh -c $as_echo_body as_echo'
fi

# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
  PATH_SEPARATOR=:
  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
      PATH_SEPARATOR=';'
  }
fi


# IFS
# We need space, tab and new line, in precisely that order.  Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" ""	$as_nl"

# Find who we are.  Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
  *[\\/]* ) as_myself=$0 ;;
  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
  IFS=$as_save_IFS
  test -z "$as_dir" && as_dir=.
    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
  done
IFS=$as_save_IFS

     ;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
  as_myself=$0
fi
if test ! -f "$as_myself"; then
  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
  exit 1
fi

# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there.  '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '

# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE

# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH


# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
  as_status=$1; test $as_status -eq 0 && as_status=1
  if test "$4"; then
    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
  fi
  $as_echo "$as_me: error: $2" >&2
  as_fn_exit $as_status
} # as_fn_error


# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
  return $1
} # as_fn_set_status

# as_fn_exit STATUS
# -----------------
# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
as_fn_exit ()
{
  set +e
  as_fn_set_status $1
  exit $1
} # as_fn_exit

# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
  { eval $1=; unset $1;}
}
as_unset=as_fn_unset
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
  eval 'as_fn_append ()
  {
    eval $1+=\$2
  }'
else
  as_fn_append ()
  {
    eval $1=\$$1\$2
  }
fi # as_fn_append

# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
  eval 'as_fn_arith ()
  {
    as_val=$(( $* ))
  }'
else
  as_fn_arith ()
  {
    as_val=`expr "$@" || test $? -eq 1`
  }
fi # as_fn_arith


if expr a : '\(a\)' >/dev/null 2>&1 &&
   test "X`expr 00001 : '.*\(...\)'`" = X001; then
  as_expr=expr
else
  as_expr=false
fi

if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
  as_basename=basename
else
  as_basename=false
fi

if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
  as_dirname=dirname
else
  as_dirname=false
fi

as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
	 X"$0" : 'X\(//\)$' \| \
	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
    sed '/^.*\/\([^/][^/]*\)\/*$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\/\)$/{
	    s//\1/
	    q
	  }
	  /^X\/\(\/\).*/{
	    s//\1/
	    q
	  }
	  s/.*/./; q'`

# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits

ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
  case `echo 'xy\c'` in
  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
  xy)  ECHO_C='\c';;
  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
       ECHO_T='	';;
  esac;;
*)
  ECHO_N='-n';;
esac

rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
  rm -f conf$$.dir/conf$$.file
else
  rm -f conf$$.dir
  mkdir conf$$.dir 2>/dev/null
fi
if (echo >conf$$.file) 2>/dev/null; then
  if ln -s conf$$.file conf$$ 2>/dev/null; then
    as_ln_s='ln -s'
    # ... but there are two gotchas:
    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
    # In both cases, we have to default to `cp -pR'.
    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
      as_ln_s='cp -pR'
  elif ln conf$$.file conf$$ 2>/dev/null; then
    as_ln_s=ln
  else
    as_ln_s='cp -pR'
  fi
else
  as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null


# as_fn_mkdir_p
# -------------
# Create "$as_dir" as a directory, including parents if necessary.
as_fn_mkdir_p ()
{

  case $as_dir in #(
  -*) as_dir=./$as_dir;;
  esac
  test -d "$as_dir" || eval $as_mkdir_p || {
    as_dirs=
    while :; do
      case $as_dir in #(
      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
      *) as_qdir=$as_dir;;
      esac
      as_dirs="'$as_qdir' $as_dirs"
      as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$as_dir" : 'X\(//\)[^/]' \| \
	 X"$as_dir" : 'X\(//\)$' \| \
	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_dir" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\).*/{
	    s//\1/
	    q
	  }
	  s/.*/./; q'`
      test -d "$as_dir" && break
    done
    test -z "$as_dirs" || eval "mkdir $as_dirs"
  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"


} # as_fn_mkdir_p
if mkdir -p . 2>/dev/null; then
  as_mkdir_p='mkdir -p "$as_dir"'
else
  test -d ./-p && rmdir ./-p
  as_mkdir_p=false
fi


# as_fn_executable_p FILE
# -----------------------
# Test if FILE is an executable regular file.
as_fn_executable_p ()
{
  test -f "$1" && test -x "$1"
} # as_fn_executable_p
as_test_x='test -x'
as_executable_p=as_fn_executable_p

# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"

# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"


exec 6>&1
## ----------------------------------- ##
## Main body of $CONFIG_STATUS script. ##
## ----------------------------------- ##
_ASEOF
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by $as_me, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@

on `(hostname || uname -n) 2>/dev/null | sed 1q`
"

_ACEOF

case $ac_config_files in *"
"*) set x $ac_config_files; shift; ac_config_files=$*;;
esac



cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
# Files that config.status was made for.
config_files="$ac_config_files"

_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
ac_cs_usage="\
\`$as_me' instantiates files and other configuration actions
from templates according to the current configuration.  Unless the files
and actions are specified as TAGs, all are instantiated by default.

Usage: $0 [OPTION]... [TAG]...

  -h, --help       print this help, then exit
  -V, --version    print version number and configuration settings, then exit
      --config     print configuration, then exit
  -q, --quiet, --silent
                   do not print progress messages
  -d, --debug      don't remove temporary files
      --recheck    update $as_me by reconfiguring in the same conditions
      --file=FILE[:TEMPLATE]
                   instantiate the configuration file FILE

Configuration files:
$config_files

Report bugs to the package provider."

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
config.status
configured by $0, generated by GNU Autoconf 2.69,
  with options \\"\$ac_cs_config\\"

Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

ac_pwd='$ac_pwd'
srcdir='$srcdir'
INSTALL='$INSTALL'
test -n "\$AWK" || AWK=awk
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# The default lists apply if the user does not specify any file.
ac_need_defaults=:
while test $# != 0
do
  case $1 in
  --*=?*)
    ac_option=`expr "X$1" : 'X\([^=]*\)='`
    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
    ac_shift=:
    ;;
  --*=)
    ac_option=`expr "X$1" : 'X\([^=]*\)='`
    ac_optarg=
    ac_shift=:
    ;;
  *)
    ac_option=$1
    ac_optarg=$2
    ac_shift=shift
    ;;
  esac

  case $ac_option in
  # Handling of the options.
  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
    ac_cs_recheck=: ;;
  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
    $as_echo "$ac_cs_version"; exit ;;
  --config | --confi | --conf | --con | --co | --c )
    $as_echo "$ac_cs_config"; exit ;;
  --debug | --debu | --deb | --de | --d | -d )
    debug=: ;;
  --file | --fil | --fi | --f )
    $ac_shift
    case $ac_optarg in
    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
    '') as_fn_error $? "missing file argument" ;;
    esac
    as_fn_append CONFIG_FILES " '$ac_optarg'"
    ac_need_defaults=false;;
  --he | --h |  --help | --hel | -h )
    $as_echo "$ac_cs_usage"; exit ;;
  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil | --si | --s)
    ac_cs_silent=: ;;

  # This is an error.
  -*) as_fn_error $? "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;

  *) as_fn_append ac_config_targets " $1"
     ac_need_defaults=false ;;

  esac
  shift
done

ac_configure_extra_args=

if $ac_cs_silent; then
  exec 6>/dev/null
  ac_configure_extra_args="$ac_configure_extra_args --silent"
fi

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
  shift
  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
  CONFIG_SHELL='$SHELL'
  export CONFIG_SHELL
  exec "\$@"
fi

_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
exec 5>>config.log
{
  echo
  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
  $as_echo "$ac_log"
} >&5

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1

# Handling of arguments.
for ac_config_target in $ac_config_targets
do
  case $ac_config_target in
    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
    "pkgIndex.tcl") CONFIG_FILES="$CONFIG_FILES pkgIndex.tcl" ;;

  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
  esac
done


# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used.  Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
fi

# Have a temporary directory for convenience.  Make it in the build tree
# simply because there is no reason against having it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Hook for its removal unless debugging.
# Note that there is a small window in which the directory will not be cleaned:
# after its creation but before its name has been assigned to `$tmp'.
$debug ||
{
  tmp= ac_tmp=
  trap 'exit_status=$?
  : "${ac_tmp:=$tmp}"
  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0
  trap 'as_fn_exit 1' 1 2 13 15
}
# Create a (secure) tmp directory for tmp files.

{
  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
  test -d "$tmp"
}  ||
{
  tmp=./conf$$-$RANDOM
  (umask 077 && mkdir "$tmp")
} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
ac_tmp=$tmp

# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
# This happens for instance with `./config.status config.h'.
if test -n "$CONFIG_FILES"; then


ac_cr=`echo X | tr X '\015'`
# On cygwin, bash can eat \r inside `` if the user requested igncr.
# But we know of no other shell where ac_cr would be empty at this
# point, so we can use a bashism as a fallback.
if test "x$ac_cr" = x; then
  eval ac_cr=\$\'\\r\'
fi
ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
  ac_cs_awk_cr='\\r'
else
  ac_cs_awk_cr=$ac_cr
fi

echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
_ACEOF


{
  echo "cat >conf$$subs.awk <<_ACEOF" &&
  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
  echo "_ACEOF"
} >conf$$subs.sh ||
  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
  . ./conf$$subs.sh ||
    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5

  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
  if test $ac_delim_n = $ac_delim_num; then
    break
  elif $ac_last_try; then
    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
  else
    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
  fi
done
rm -f conf$$subs.sh

cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
_ACEOF
sed -n '
h
s/^/S["/; s/!.*/"]=/
p
g
s/^[^!]*!//
:repl
t repl
s/'"$ac_delim"'$//
t delim
:nl
h
s/\(.\{148\}\)..*/\1/
t more1
s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
p
n
b repl
:more1
s/["\\]/\\&/g; s/^/"/; s/$/"\\/
p
g
s/.\{148\}//
t nl
:delim
h
s/\(.\{148\}\)..*/\1/
t more2
s/["\\]/\\&/g; s/^/"/; s/$/"/
p
b
:more2
s/["\\]/\\&/g; s/^/"/; s/$/"\\/
p
g
s/.\{148\}//
t delim
' <conf$$subs.awk | sed '
/^[^""]/{
  N
  s/\n//
}
' >>$CONFIG_STATUS || ac_write_fail=1
rm -f conf$$subs.awk
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACAWK
cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
  for (key in S) S_is_set[key] = 1
  FS = ""

}
{
  line = $ 0
  nfields = split(line, field, "@")
  substed = 0
  len = length(field[1])
  for (i = 2; i < nfields; i++) {
    key = field[i]
    keylen = length(key)
    if (S_is_set[key]) {
      value = S[key]
      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
      len += length(value) + length(field[++i])
      substed = 1
    } else
      len += 1 + keylen
  }

  print line
}

_ACAWK
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
else
  cat
fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
_ACEOF

# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
# trailing colons and then remove the whole line if VPATH becomes empty
# (actually we leave an empty line to preserve line numbers).
if test "x$srcdir" = x.; then
  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
h
s///
s/^/:/
s/[	 ]*$/:/
s/:\$(srcdir):/:/g
s/:\${srcdir}:/:/g
s/:@srcdir@:/:/g
s/^:*//
s/:*$//
x
s/\(=[	 ]*\).*/\1/
G
s/\n//
s/^[^=]*=[	 ]*$//
}'
fi

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
fi # test -n "$CONFIG_FILES"


eval set X "  :F $CONFIG_FILES      "
shift
for ac_tag
do
  case $ac_tag in
  :[FHLC]) ac_mode=$ac_tag; continue;;
  esac
  case $ac_mode$ac_tag in
  :[FHL]*:*);;
  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
  :[FH]-) ac_tag=-:-;;
  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
  esac
  ac_save_IFS=$IFS
  IFS=:
  set x $ac_tag
  IFS=$ac_save_IFS
  shift
  ac_file=$1
  shift

  case $ac_mode in
  :L) ac_source=$1;;
  :[FH])
    ac_file_inputs=
    for ac_f
    do
      case $ac_f in
      -) ac_f="$ac_tmp/stdin";;
      *) # Look for the file first in the build tree, then in the source tree
	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
	 # because $ac_f cannot contain `:'.
	 test -f "$ac_f" ||
	   case $ac_f in
	   [\\/$]*) false;;
	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
	   esac ||
	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
      esac
      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
      as_fn_append ac_file_inputs " '$ac_f'"
    done

    # Let's still pretend it is `configure' which instantiates (i.e., don't
    # use $as_me), people would be surprised to read:
    #    /* config.h.  Generated by config.status.  */
    configure_input='Generated from '`
	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
	`' by configure.'
    if test x"$ac_file" != x-; then
      configure_input="$ac_file.  $configure_input"
      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
$as_echo "$as_me: creating $ac_file" >&6;}
    fi
    # Neutralize special characters interpreted by sed in replacement strings.
    case $configure_input in #(
    *\&* | *\|* | *\\* )
       ac_sed_conf_input=`$as_echo "$configure_input" |
       sed 's/[\\\\&|]/\\\\&/g'`;; #(
    *) ac_sed_conf_input=$configure_input;;
    esac

    case $ac_tag in
    *:-:* | *:-) cat >"$ac_tmp/stdin" \
      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
    esac
    ;;
  esac

  ac_dir=`$as_dirname -- "$ac_file" ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	 X"$ac_file" : 'X\(//\)[^/]' \| \
	 X"$ac_file" : 'X\(//\)$' \| \
	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$ac_file" |
    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)[^/].*/{
	    s//\1/
	    q
	  }
	  /^X\(\/\/\)$/{
	    s//\1/
	    q
	  }
	  /^X\(\/\).*/{
	    s//\1/
	    q
	  }
	  s/.*/./; q'`
  as_dir="$ac_dir"; as_fn_mkdir_p
  ac_builddir=.

case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
  # A ".." for each directory in $ac_dir_suffix.
  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
  case $ac_top_builddir_sub in
  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
  esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
# for backward compatibility:
ac_top_builddir=$ac_top_build_prefix

case $srcdir in
  .)  # We are building in place.
    ac_srcdir=.
    ac_top_srcdir=$ac_top_builddir_sub
    ac_abs_top_srcdir=$ac_pwd ;;
  [\\/]* | ?:[\\/]* )  # Absolute name.
    ac_srcdir=$srcdir$ac_dir_suffix;
    ac_top_srcdir=$srcdir
    ac_abs_top_srcdir=$srcdir ;;
  *) # Relative name.
    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
    ac_top_srcdir=$ac_top_build_prefix$srcdir
    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix


  case $ac_mode in
  :F)
  #
  # CONFIG_FILE
  #

  case $INSTALL in
  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
  esac
_ACEOF

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# If the template does not know about datarootdir, expand it.
# FIXME: This hack should be removed a few years after 2.60.
ac_datarootdir_hack=; ac_datarootdir_seen=
ac_sed_dataroot='
/datarootdir/ {
  p
  q
}
/@datadir@/p
/@docdir@/p
/@infodir@/p
/@localedir@/p
/@mandir@/p'
case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
*datarootdir*) ac_datarootdir_seen=yes;;
*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
  ac_datarootdir_hack='
  s&@datadir@&$datadir&g
  s&@docdir@&$docdir&g
  s&@infodir@&$infodir&g
  s&@localedir@&$localedir&g
  s&@mandir@&$mandir&g
  s&\\\${datarootdir}&$datarootdir&g' ;;
esac
_ACEOF

# Neutralize VPATH when `$srcdir' = `.'.
# Shell code in configure.ac might set extrasub.
# FIXME: do we really want to maintain this feature?
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_sed_extra="$ac_vpsub
$extrasub
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
:t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
s|@configure_input@|$ac_sed_conf_input|;t t
s&@top_builddir@&$ac_top_builddir_sub&;t t
s&@top_build_prefix@&$ac_top_build_prefix&;t t
s&@srcdir@&$ac_srcdir&;t t
s&@abs_srcdir@&$ac_abs_srcdir&;t t
s&@top_srcdir@&$ac_top_srcdir&;t t
s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
s&@builddir@&$ac_builddir&;t t
s&@abs_builddir@&$ac_abs_builddir&;t t
s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
s&@INSTALL@&$ac_INSTALL&;t t
$ac_datarootdir_hack
"
eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5

test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
      "$ac_tmp/out"`; test -z "$ac_out"; } &&
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined.  Please make sure it is defined" >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined.  Please make sure it is defined" >&2;}

  rm -f "$ac_tmp/stdin"
  case $ac_file in
  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
  esac \
  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
 ;;



  esac

done # for ac_tag


as_fn_exit 0
_ACEOF
ac_clean_files=$ac_clean_files_save

test $ac_write_fail = 0 ||
  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5


# configure is writing to config.log, and then calls config.status.
# config.status does its own redirection, appending to config.log.
# Unfortunately, on DOS this fails, as config.log is still kept open
# by configure, so config.status won't be able to write to it; its
# output is simply discarded.  So we exec the FD to /dev/null,
# effectively closing config.log, so it can be properly (re)opened and
# appended to by config.status.  When coming back to configure, we
# need to make the FD available again.
if test "$no_create" != yes; then
  ac_cs_success=:
  ac_config_status_args=
  test "$silent" = yes &&
    ac_config_status_args="$ac_config_status_args --quiet"
  exec 5>/dev/null
  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
  exec 5>>config.log
  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
  # would make configure fail if this is the last instruction.
  $ac_cs_success || as_fn_exit 1
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi

Changes to extensions/tdomhtml/configure.in.

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tcl installation
dnl	to configure the system for the local environment.
#
# RCS: @(#) $Id$

#-----------------------------------------------------------------------
# Sample configure.in for Tcl Extensions.  The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------




<
<







1
2
3
4


5
6
7
8
9
10
11
#!/bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tcl installation
dnl	to configure the system for the local environment.



#-----------------------------------------------------------------------
# Sample configure.in for Tcl Extensions.  The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------

Changes to extensions/tdomhtml/tdomhtml.tcl.

170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
    }

    foreach nodecmd $elementNodeCmd {
        dom createNodeCmd elementNode $nodecmd
    }

    #
    # Miscelaneous commands. Not part of HTML specs but needed 
    # for generation of special DOM nodes.
    #

    variable textNodeCmd t
    dom createNodeCmd textNode $textNodeCmd

    variable commentNodeCmd c







|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
    }

    foreach nodecmd $elementNodeCmd {
        dom createNodeCmd elementNode $nodecmd
    }

    #
    # Miscellaneous commands. Not part of HTML specs but needed 
    # for generation of special DOM nodes.
    #

    variable textNodeCmd t
    dom createNodeCmd textNode $textNodeCmd

    variable commentNodeCmd c

Added extensions/tdomhtml/win/makefile.vc.













































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Simple makefile for pure Tcl package

PROJECT    = tdomhtml
DOTVERSION = 0.1.0
VERSION    = $(DOTVERSION:.=)

CPY	= echo y | xcopy /i >NUL

!ifndef INSTALLDIR
### Assume the normal default.
_INSTALLDIR	= C:\Program Files\Tcl\lib
!else
### Fix the path separators.
_INSTALLDIR	= $(INSTALLDIR:/=\)\lib
!endif


PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)

all:
	@echo This is a pure Tcl package. Just run 'make /f makefile.vc install INSTALLDIR=path\to\tcl\root'

install: install-libraries

install-libraries:
	@if not exist $(SCRIPT_INSTALL_DIR)\nul mkdir $(SCRIPT_INSTALL_DIR)
	@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
        $(CPY) ..\tdomhtml.tcl "$(SCRIPT_INSTALL_DIR)" >NUL
        @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
        @type << >"$(SCRIPT_INSTALL_DIR)\pkgIndex.tcl"
    package ifneeded tdomhtml $(DOTVERSION) "set _V_ $(DOTVERSION); source [list [file join $$dir tdomhtml.tcl]]"
<<

install-docs:
#	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
#	@if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)"

Changes to extensions/tnc/Makefile.in.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
69
70
71
72
73
74
75


76
77
78
79
80
81
82
83
84
85
86
87
88
89


90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
...
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
...
153
154
155
156
157
158
159

160

161
162
163
164
165
166


167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
...
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240










241
242
243
244
245
246
247
...
272
273
274
275
276
277
278
279
280
281
282










283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
...
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
#	replaced in the actual Makefile.
#
# Copyright (c) 1999 Scriptics Corporation.
# Copyright (c) 2002-2005 ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id$

#========================================================================
# Add additional lines to handle any additional AC_SUBST cases that
# have been added in a customized configure script.
#========================================================================

#SAMPLE_NEW_VAR	= @SAMPLE_NEW_VAR@
................................................................................

srcdir		= @srcdir@
prefix		= @prefix@
exec_prefix	= @exec_prefix@

bindir		= @bindir@
libdir		= @libdir@


datadir		= @datadir@
mandir		= @mandir@
includedir	= @includedir@

DESTDIR		=

PKG_DIR		= $(PACKAGE_NAME)$(PACKAGE_VERSION)
pkgdatadir	= $(datadir)/$(PKG_DIR)
pkglibdir	= $(libdir)/$(PKG_DIR)
pkgincludedir	= $(includedir)/$(PKG_DIR)

top_builddir	= .

INSTALL		= @INSTALL@


INSTALL_PROGRAM	= @INSTALL_PROGRAM@
INSTALL_DATA	= @INSTALL_DATA@
INSTALL_SCRIPT	= @INSTALL_SCRIPT@


PACKAGE_NAME	= @PACKAGE_NAME@
PACKAGE_VERSION	= @PACKAGE_VERSION@
CC		= @CC@
CFLAGS_DEFAULT	= @CFLAGS_DEFAULT@
CFLAGS_WARNING	= @CFLAGS_WARNING@
CLEANFILES	= @CLEANFILES@
EXEEXT		= @EXEEXT@
LDFLAGS_DEFAULT	= @LDFLAGS_DEFAULT@
MAKE_LIB	= @MAKE_LIB@
MAKE_SHARED_LIB	= @MAKE_SHARED_LIB@
MAKE_STATIC_LIB	= @MAKE_STATIC_LIB@
MAKE_STUB_LIB	= @MAKE_STUB_LIB@
OBJEXT		= @OBJEXT@
................................................................................
# to test against an uninstalled Tcl.  Add special env vars that you
# require for testing here (like TCLX_LIBRARY).
#========================================================================

EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR)
#EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
TCLLIBPATH	= $(top_builddir)
TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
		  @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
		  PATH="$(EXTRA_PATH):$(PATH)" \
		  TCLLIBPATH="$(TCLLIBPATH)"
#		  TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`

TCLSH_PROG	= @TCLSH_PROG@
TCLSH   	= $(TCLSH_ENV) $(TCLSH_PROG)


#WISH_PROG	= @WISH_PROG@
#WISH   	= $(TCLSH_ENV) $(WISH_PROG)


SHARED_BUILD	= @SHARED_BUILD@

INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@
#INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@

PKG_CFLAGS	= @PKG_CFLAGS@
................................................................................
# must make sure that configure.in checks for the necessary components
# that your library may use.  TCL_DEFS can actually be a problem if
# you do not compile with a similar machine setup as the Tcl core was
# compiled with.
#DEFS		= $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
DEFS		= @DEFS@ $(PKG_CFLAGS)


CONFIG_CLEAN_FILES = Makefile


CPPFLAGS	= @CPPFLAGS@
LIBS		= @PKG_LIBS@ @LIBS@
AR		= @AR@
CFLAGS		= @CFLAGS@
COMPILE		= $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)



#========================================================================
# Start of user-definable TARGETS section
#========================================================================

#========================================================================
# TEA TARGETS.  Please note that the "libraries:" target refers to platform
# independent files, and the "binaries:" target inclues executable programs and
# platform-dependent libraries.  Modify these targets so that they install
# the various pieces of your package.  The make and install rules
# for the BINARIES that you specified above have already been done.
#========================================================================

all: binaries libraries doc

#========================================================================
# The binaries target builds executable programs, Windows .dll's, unix
# shared/static libraries, and any other platform-dependent files.
# The list of targets to build for "binaries:" is specified at the top
# of the Makefile, in the "BINARIES" variable.
#========================================================================

binaries: $(BINARIES)

libraries:


#========================================================================
# Your doc target should differentiate from doc builds (by the developer)
# and doc installs (see install-doc), which just install the docs on the
# end user machine when building from source.
#========================================================================

................................................................................

#========================================================================
# This rule installs platform-independent files, such as header files.
# The list=...; for p in $$list handles the empty list case x-platform.
#========================================================================

install-libraries: libraries
	@mkdir -p $(DESTDIR)$(includedir)
	@echo "Installing header files in $(DESTDIR)$(includedir)"
	@list='$(PKG_HEADERS)'; for i in $$list; do \
	    echo "Installing $(srcdir)/$$i" ; \
	    $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(includedir) ; \
	done;

#========================================================================
# Install documentation.  Unix manpages should go in the $(mandir)
# directory.
#========================================================================

install-doc: doc
	@mkdir -p $(DESTDIR)$(mandir)/mann
	@echo "Installing documentation in $(DESTDIR)$(mandir)"
	@list='$(srcdir)/doc/*.n'; for i in $$list; do \
	    echo "Installing $$i"; \
	    rm -f $(DESTDIR)$(mandir)/mann/`basename $$i`; \
	    $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
	done

test: binaries libraries
	$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)

shell: binaries libraries
	@$(TCLSH) $(SCRIPT)

gdb:
	$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)











depend:

#========================================================================
# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
# mentioned above.  That will ensure that this target is built when you
# run "make binaries".
................................................................................
# 	$(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
#
# Setting the VPATH variable to a list of paths will cause the makefile
# to look into these paths when resolving .c to .obj dependencies.
# As necessary, add $(srcdir):$(srcdir)/compat:....
#========================================================================

VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win

.c.@OBJEXT@:
	$(COMPILE) -c `@CYGPATH@ $<` -o $@











#========================================================================
# Distribution creation
# You may need to tweak this target to make it work correctly.
#========================================================================

#COMPRESS	= tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
COMPRESS	= gtar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT	= /tmp/dist
DIST_DIR	= $(DIST_ROOT)/$(PKG_DIR)

dist-clean:
	rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*

dist: dist-clean
................................................................................
#========================================================================

#========================================================================
# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
# variable in configure.in
#========================================================================

clean:  
	-test -z "$(BINARIES)" || rm -f $(BINARIES)
	-rm -f *.$(OBJEXT) core *.core
	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)

distclean: clean
	-rm -f *.tab.c
	-rm -f $(CONFIG_CLEAN_FILES)
................................................................................
# In addition, this will generate the pkgIndex.tcl
# file in the install location (assuming it can find a usable tclsh shell)
#
# You should not have to modify this target.
#========================================================================

install-lib-binaries: binaries
	@mkdir -p $(DESTDIR)$(pkglibdir)
	@list='$(lib_BINARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkglibdir)/$$p; \
	    stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
	    if test "x$$stub" = "xstub"; then \
		echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
		$(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
	    else \
		echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
		$(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
................................................................................
# wish and tclsh), like dependent .dll files on Windows.
#
# You should not have to modify this target, except to define bin_BINARIES
# above if necessary.
#========================================================================

install-bin-binaries: binaries
	@mkdir -p $(DESTDIR)$(bindir)
	@list='$(bin_BINARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
	  fi; \
	done

.SUFFIXES: .c .$(OBJEXT)

Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
	cd $(top_builddir) \
	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status

uninstall-binaries:
	list='$(lib_BINARIES)'; for p in $$list; do \
	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \







<
<







 







>
>


<










|
>
>
|
|
|
>






<







 







|
|


<


|

>

|
<







 







>
|
>






>
>







|





|








|


<







 







|
<
<
<
<
<







|



<











>
>
>
>
>
>
>
>
>
>







 







|



>
>
>
>
>
>
>
>
>
>







|







 







|







 







|


|
|







 







|







<
<







7
8
9
10
11
12
13


14
15
16
17
18
19
20
..
67
68
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
...
126
127
128
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143

144
145
146
147
148
149
150
...
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
...
208
209
210
211
212
213
214
215





216
217
218
219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
...
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
...
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
...
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427


428
429
430
431
432
433
434
#	replaced in the actual Makefile.
#
# Copyright (c) 1999 Scriptics Corporation.
# Copyright (c) 2002-2005 ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.



#========================================================================
# Add additional lines to handle any additional AC_SUBST cases that
# have been added in a customized configure script.
#========================================================================

#SAMPLE_NEW_VAR	= @SAMPLE_NEW_VAR@
................................................................................

srcdir		= @srcdir@
prefix		= @prefix@
exec_prefix	= @exec_prefix@

bindir		= @bindir@
libdir		= @libdir@
includedir	= @includedir@
datarootdir	= @datarootdir@
datadir		= @datadir@
mandir		= @mandir@


DESTDIR		=

PKG_DIR		= $(PACKAGE_NAME)$(PACKAGE_VERSION)
pkgdatadir	= $(datadir)/$(PKG_DIR)
pkglibdir	= $(libdir)/$(PKG_DIR)
pkgincludedir	= $(includedir)/$(PKG_DIR)

top_builddir	= .

INSTALL_OPTIONS =
INSTALL		= $(SHELL) $(srcdir)/../../tclconfig/install-sh -c ${INSTALL_OPTIONS}
INSTALL_DATA_DIR = ${INSTALL} -d -m 755
INSTALL_PROGRAM	= ${INSTALL} -m 555
INSTALL_DATA	= ${INSTALL} -m 444
INSTALL_SCRIPT	= ${INSTALL_PROGRAM}
INSTALL_LIBRARY	= ${INSTALL_DATA}

PACKAGE_NAME	= @PACKAGE_NAME@
PACKAGE_VERSION	= @PACKAGE_VERSION@
CC		= @CC@
CFLAGS_DEFAULT	= @CFLAGS_DEFAULT@
CFLAGS_WARNING	= @CFLAGS_WARNING@

EXEEXT		= @EXEEXT@
LDFLAGS_DEFAULT	= @LDFLAGS_DEFAULT@
MAKE_LIB	= @MAKE_LIB@
MAKE_SHARED_LIB	= @MAKE_SHARED_LIB@
MAKE_STATIC_LIB	= @MAKE_STATIC_LIB@
MAKE_STUB_LIB	= @MAKE_STUB_LIB@
OBJEXT		= @OBJEXT@
................................................................................
# to test against an uninstalled Tcl.  Add special env vars that you
# require for testing here (like TCLX_LIBRARY).
#========================================================================

EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR)
#EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
TCLLIBPATH	= $(top_builddir)
TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
PKG_ENV		= @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
		  PATH="$(EXTRA_PATH):$(PATH)" \
		  TCLLIBPATH="$(TCLLIBPATH)"


TCLSH_PROG	= @TCLSH_PROG@
TCLSH		= $(PKG_ENV) $(TCLSH_ENV) $(TCLSH_PROG)

#WISH_ENV	= TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
#WISH_PROG	= @WISH_PROG@
#WISH		= $(PKG_ENV) $(TCLSH_ENV) $(WISH_ENV) $(WISH_PROG)


SHARED_BUILD	= @SHARED_BUILD@

INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@
#INCLUDES	= @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@

PKG_CFLAGS	= @PKG_CFLAGS@
................................................................................
# must make sure that configure.in checks for the necessary components
# that your library may use.  TCL_DEFS can actually be a problem if
# you do not compile with a similar machine setup as the Tcl core was
# compiled with.
#DEFS		= $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
DEFS		= @DEFS@ $(PKG_CFLAGS)

# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
CLEANFILES	= @CLEANFILES@

CPPFLAGS	= @CPPFLAGS@
LIBS		= @PKG_LIBS@ @LIBS@
AR		= @AR@
CFLAGS		= @CFLAGS@
COMPILE		= $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)

.SUFFIXES: .c .$(OBJEXT)

#========================================================================
# Start of user-definable TARGETS section
#========================================================================

#========================================================================
# TEA TARGETS.  Please note that the "libraries:" target refers to platform
# independent files, and the "binaries:" target includes executable programs and
# platform-dependent libraries.  Modify these targets so that they install
# the various pieces of your package.  The make and install rules
# for the BINARIES that you specified above have already been done.
#========================================================================

all: binaries libraries

#========================================================================
# The binaries target builds executable programs, Windows .dll's, unix
# shared/static libraries, and any other platform-dependent files.
# The list of targets to build for "binaries:" is specified at the top
# of the Makefile, in the "BINARIES" variable.
#========================================================================

binaries: $(BINARIES) pkgIndex.tcl-hand

libraries:


#========================================================================
# Your doc target should differentiate from doc builds (by the developer)
# and doc installs (see install-doc), which just install the docs on the
# end user machine when building from source.
#========================================================================

................................................................................

#========================================================================
# This rule installs platform-independent files, such as header files.
# The list=...; for p in $$list handles the empty list case x-platform.
#========================================================================

install-libraries: libraries
	@$(INSTALL_DATA_DIR) $(DESTDIR)$(includedir)






#========================================================================
# Install documentation.  Unix manpages should go in the $(mandir)
# directory.
#========================================================================

install-doc: doc
	@$(INSTALL_DATA_DIR) $(DESTDIR)$(mandir)/mann
	@echo "Installing documentation in $(DESTDIR)$(mandir)"
	@list='$(srcdir)/doc/*.n'; for i in $$list; do \
	    echo "Installing $$i"; \

	    $(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/mann ; \
	done

test: binaries libraries
	$(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)

shell: binaries libraries
	@$(TCLSH) $(SCRIPT)

gdb:
	$(TCLSH_ENV) gdb $(TCLSH_PROG) $(SCRIPT)

VALGRINDARGS =	--tool=memcheck --num-callers=8 --leak-resolution=high \
		--leak-check=yes --show-reachable=yes -v

valgrind: binaries libraries
	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) \
		`@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)

valgrindshell: binaries libraries
	$(TCLSH_ENV) valgrind $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)

depend:

#========================================================================
# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
# mentioned above.  That will ensure that this target is built when you
# run "make binaries".
................................................................................
# 	$(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
#
# Setting the VPATH variable to a list of paths will cause the makefile
# to look into these paths when resolving .c to .obj dependencies.
# As necessary, add $(srcdir):$(srcdir)/compat:....
#========================================================================

VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macosx

.c.@OBJEXT@:
	$(COMPILE) -c `@CYGPATH@ $<` -o $@

#========================================================================
# Create the pkgIndex.tcl file.
#========================================================================

pkgIndex.tcl-hand:
	@(echo 'package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
	"package require tdom;\
	 load [list [file join $$dir $(PKG_LIB_FILE)]];"'\
	) > pkgIndex.tcl

#========================================================================
# Distribution creation
# You may need to tweak this target to make it work correctly.
#========================================================================

#COMPRESS	= tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
COMPRESS	= tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT	= /tmp/dist
DIST_DIR	= $(DIST_ROOT)/$(PKG_DIR)

dist-clean:
	rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*

dist: dist-clean
................................................................................
#========================================================================

#========================================================================
# Don't modify the file to clean here.  Instead, set the "CLEANFILES"
# variable in configure.in
#========================================================================

clean:
	-test -z "$(BINARIES)" || rm -f $(BINARIES)
	-rm -f *.$(OBJEXT) core *.core
	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)

distclean: clean
	-rm -f *.tab.c
	-rm -f $(CONFIG_CLEAN_FILES)
................................................................................
# In addition, this will generate the pkgIndex.tcl
# file in the install location (assuming it can find a usable tclsh shell)
#
# You should not have to modify this target.
#========================================================================

install-lib-binaries: binaries
	@$(INSTALL_DATA_DIR) $(DESTDIR)$(pkglibdir)
	@list='$(lib_BINARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
	    $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p; \
	    stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \
	    if test "x$$stub" = "xstub"; then \
		echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \
		$(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \
	    else \
		echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \
		$(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \
................................................................................
# wish and tclsh), like dependent .dll files on Windows.
#
# You should not have to modify this target, except to define bin_BINARIES
# above if necessary.
#========================================================================

install-bin-binaries: binaries
	@$(INSTALL_DATA_DIR) $(DESTDIR)$(bindir)
	@list='$(bin_BINARIES)'; for p in $$list; do \
	  if test -f $$p; then \
	    echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
	    $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
	  fi; \
	done



Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
	cd $(top_builddir) \
	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status

uninstall-binaries:
	list='$(lib_BINARIES)'; for p in $$list; do \
	  rm -f $(DESTDIR)$(pkglibdir)/$$p; \

Changes to extensions/tnc/configure.

more than 10,000 changes

Changes to extensions/tnc/configure.in.

1
2
3
4
5
6
7
8
9
10
11
12
13
..
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tcl installation
dnl	to configure the system for the local environment.
#
# RCS: @(#) $Id$

#-----------------------------------------------------------------------
# Sample configure.in for Tcl Extensions.  The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
................................................................................

#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------

TEA_INIT([3.6])

AC_CONFIG_AUX_DIR(../../tclconfig)

#--------------------------------------------------------------------
# Load the tclConfig.sh file
#--------------------------------------------------------------------

................................................................................
# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
# and PKG_TCL_SOURCES.
#-----------------------------------------------------------------------

TEA_ADD_SOURCES([tnc.c])
TEA_ADD_HEADERS([])
TEA_ADD_INCLUDES([-I${srcdir}/../../generic -I${srcdir}/../../expat])

TEA_ADD_CFLAGS([-DUSE_TDOM_STUBS=1])
TEA_ADD_STUB_SOURCES([])
TEA_ADD_TCL_SOURCES([])

# See https://sourceforge.net/tracker/index.php?func=detail&aid=1636345&group_id=10894&atid=110894
if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
    TEA_ADD_LIBS([\"`${CYGPATH} ${TDOM_STUB_LIB_PATH}`\"])
else
    TEA_ADD_LIBS([${TDOM_STUB_LIB_SPEC}])
fi

#--------------------------------------------------------------------
# __CHANGE__
# A few miscellaneous platform-specific items:
#
# Define a special symbol for Windows (BUILD_sample in this case) so
# that we create the export library with the dll.
#
................................................................................
# You can add more files to clean if your extension creates any extra
# files.
#
# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------

if test "${TEA_PLATFORM}" = "windows" ; then
    AC_DEFINE(BUILD_tnc, 1, [Build windows export dll])
    CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
    #TEA_ADD_SOURCES([win/winFile.c])
    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
else
    CLEANFILES="pkgIndex.tcl"
    #TEA_ADD_SOURCES([unix/unixFile.c])
    #TEA_ADD_LIBS([-lsuperfly])




<
<







 







|







 







>




<
<
<
<
<
<
<







 







|







1
2
3
4


5
6
7
8
9
10
11
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
..
75
76
77
78
79
80
81
82
83
84
85
86







87
88
89
90
91
92
93
..
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/bin/bash -norc
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tcl installation
dnl	to configure the system for the local environment.



#-----------------------------------------------------------------------
# Sample configure.in for Tcl Extensions.  The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
................................................................................

#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------

TEA_INIT([3.10])

AC_CONFIG_AUX_DIR(../../tclconfig)

#--------------------------------------------------------------------
# Load the tclConfig.sh file
#--------------------------------------------------------------------

................................................................................
# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
# and PKG_TCL_SOURCES.
#-----------------------------------------------------------------------

TEA_ADD_SOURCES([tnc.c])
TEA_ADD_HEADERS([])
TEA_ADD_INCLUDES([-I${srcdir}/../../generic -I${srcdir}/../../expat])
TEA_ADD_LIBS([${TDOM_STUB_LIB_SPEC}])
TEA_ADD_CFLAGS([-DUSE_TDOM_STUBS=1])
TEA_ADD_STUB_SOURCES([])
TEA_ADD_TCL_SOURCES([])








#--------------------------------------------------------------------
# __CHANGE__
# A few miscellaneous platform-specific items:
#
# Define a special symbol for Windows (BUILD_sample in this case) so
# that we create the export library with the dll.
#
................................................................................
# You can add more files to clean if your extension creates any extra
# files.
#
# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------

if test "${TEA_PLATFORM}" = "windows" ; then
    #AC_DEFINE(BUILD_tnc, 1, [Build windows export dll])
    CLEANFILES="pkgIndex.tcl *.lib *.dll *.exp *.ilk *.pdb vc*.pch"
    #TEA_ADD_SOURCES([win/winFile.c])
    #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
else
    CLEANFILES="pkgIndex.tcl"
    #TEA_ADD_SOURCES([unix/unixFile.c])
    #TEA_ADD_LIBS([-lsuperfly])

Changes to extensions/tnc/install-sh.

1

2

3
4
5



6
7






























8
9
10
11

12

13
14
15
16
17





18
19
20

21
22
23

24
25
26





27
28
29
30

















31
32
33
34

35
36


37
38


39
40


































41
42







43
44
45
46









47
48
49
50
51
52




53
54
55
56

57





58
59

60
61





62
63

64
65
66
67











































68
69

70
71
72








73



74




75
76
77
78












79
80
81
82
83

84
85
86
87





88
89
90




















91
92






























































93
94

















95








96
97




98
99



































































100

101
102


103
104


105
106
107
108
109
110
111



112





















113

114











115
116




117

118



119












#!/bin/sh



#
# install - install a program, script, or datafile
# This comes from X11R5; it is not part of GNU.



#
# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $






























#
# This script is compatible with the BSD install script, but was written
# from scratch.
#




# set DOITPROG to echo to test this script

# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"







# put in absolute paths if you don't have them in your path; or use env. vars.


mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"

chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"





stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"

instcmd="$mvprog"

















chmodcmd=""
chowncmd=""
chgrpcmd=""
stripcmd=""

rmcmd="$rmprog -f"
mvcmd="$mvprog"


src=""
dst=""



while [ x"$1" != x ]; do


































    case $1 in
	-c) instcmd="$cpprog"







	    shift
	    continue;;

	-m) chmodcmd="$chmodprog $2"









	    shift
	    shift
	    continue;;

	-o) chowncmd="$chownprog $2"
	    shift




	    shift
	    continue;;

	-g) chgrpcmd="$chgrpprog $2"

	    shift





	    shift
	    continue;;


	-s) stripcmd="$stripprog"





	    shift
	    continue;;


	*)  if [ x"$src" = x ]
	    then
		src=$1











































	    else
		dst=$1

	    fi
	    shift
	    continue;;








    esac



done





if [ x"$src" = x ]
then
	echo "install:  no input file specified"












	exit 1
fi

if [ x"$dst" = x ]
then

	echo "install:  no destination specified"
	exit 1
fi







# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic





















if [ -d $dst ]






























































then
	dst="$dst"/`basename $src`

















fi









# Make a temp file name in the proper directory.





dstdir=`dirname $dst`



































































dsttmp=$dstdir/#inst.$$#


# Move or copy the file name to the temp name



$doit $instcmd $src $dsttmp



# and set any options; do chmod last to preserve setuid bits

if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi

























# Now rename the file to the real destination.













$doit $rmcmd $dst
$doit $mvcmd $dsttmp $dst










exit 0













>

>
|
<
<
>
>
>

<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
>
|
>




|
>
>
>
>
>

<
|
>

<
<
>
|
|
<
>
>
>
>
>
|
<

<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
<
>

<
>
>
|
|
>
>

<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
|
<

<
>
>
>
>
>
>
>
>
>
|
<
<

|
|
>
>
>
>
|
<

<
>
|
>
>
>
>
>
|
<
>

<
>
>
>
>
>
|
<
>

<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
|
<
<
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>

<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
|
|

<
<
>
|
|
|

>
>
>
>
>

|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>

<
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>

<
>
>

<
>
>

|
|
<
<
<
<
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>

>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
|
>

>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5


6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60


61
62
63

64
65
66
67
68
69

70

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89


90
91

92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141

142

143
144
145
146
147
148
149
150
151
152


153
154
155
156
157
158
159
160

161

162
163
164
165
166
167
168
169

170
171

172
173
174
175
176
177

178
179



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

224
225


226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258


259
260
261
262
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385
386

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456

457
458
459

460
461
462
463
464




465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
#!/bin/sh
# install - install a program, script, or datafile

scriptversion=2011-04-20.01; # UTC



# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#

# Copyright (C) 1994 X Consortium
#
# 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
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.

nl='
'
IFS=" ""	$nl"

# set DOITPROG to echo to test this script

# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
  doit_exec=exec
else
  doit_exec=$doit
fi


# Put in absolute file names if you don't have them in your path;
# or use environment vars.



chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}

cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}



posix_glob='?'
initialize_posix_glob='
  test "$posix_glob" != "?" || {
    if (set -f) 2>/dev/null; then
      posix_glob=
    else
      posix_glob=:
    fi
  }
'

posix_mkdir=

# Desired mode of installed file.
mode=0755

chgrpcmd=
chmodcmd=$chmodprog
chowncmd=


mvcmd=$mvprog
rmcmd="$rmprog -f"

stripcmd=

src=
dst=
dir_arg=
dst_arg=


copy_on_change=false
no_target_directory=

usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
   or: $0 [OPTION]... SRCFILES... DIRECTORY
   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
   or: $0 [OPTION]... -d DIRECTORIES...

In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.

Options:
     --help     display this help and exit.
     --version  display version info and exit.

  -c            (ignored)
  -C            install only if different (preserve the last data modification time)
  -d            create directories instead of installing files.
  -g GROUP      $chgrpprog installed files to GROUP.
  -m MODE       $chmodprog installed files to MODE.
  -o USER       $chownprog installed files to USER.
  -s            $stripprog installed files.
  -S            $stripprog installed files.
  -t DIRECTORY  install into DIRECTORY.
  -T            report an error if DSTFILE is a directory.

Environment variables override the default commands:
  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
  RMPROG STRIPPROG
"

while test $# -ne 0; do
  case $1 in

    -c) ;;

    -C) copy_on_change=true;;

    -d) dir_arg=true;;

    -g) chgrpcmd="$chgrpprog $2"
	shift;;



    --help) echo "$usage"; exit $?;;

    -m) mode=$2
	case $mode in
	  *' '* | *'	'* | *'
'*	  | *'*'* | *'?'* | *'['*)
	    echo "$0: invalid mode: $mode" >&2
	    exit 1;;
	esac
	shift;;



    -o) chowncmd="$chownprog $2"
	shift;;

    -s) stripcmd=$stripprog;;

    -S) stripcmd="$stripprog $2"
	shift;;



    -t) dst_arg=$2
	shift;;

    -T) no_target_directory=true;;

    --version) echo "$0 $scriptversion"; exit $?;;

    --)	shift

	break;;


    -*)	echo "$0: invalid option: $1" >&2
	exit 1;;

    *)  break;;
  esac
  shift

done




if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
  # When -d is used, all remaining arguments are directories to create.
  # When -t is used, the destination is already specified.
  # Otherwise, the last argument is the destination.  Remove it from $@.
  for arg
  do
    if test -n "$dst_arg"; then
      # $@ is not empty: it contains at least $arg.
      set fnord "$@" "$dst_arg"
      shift # fnord
    fi
    shift # arg
    dst_arg=$arg
  done
fi

if test $# -eq 0; then
  if test -z "$dir_arg"; then
    echo "$0: no input file specified." >&2
    exit 1
  fi
  # It's OK to call `install-sh -d' without argument.
  # This can happen when creating conditional directories.
  exit 0
fi

if test -z "$dir_arg"; then
  do_exit='(exit $ret); exit $ret'
  trap "ret=129; $do_exit" 1
  trap "ret=130; $do_exit" 2
  trap "ret=141; $do_exit" 13
  trap "ret=143; $do_exit" 15

  # Set umask so as not to create temps with too-generous modes.
  # However, 'strip' requires both read and write access to temps.
  case $mode in
    # Optimize common cases.
    *644) cp_umask=133;;
    *755) cp_umask=22;;

    *[0-7])
      if test -z "$stripcmd"; then
	u_plus_rw=
      else

	u_plus_rw='% 200'
      fi


      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
    *)
      if test -z "$stripcmd"; then
	u_plus_rw=
      else
	u_plus_rw=,u+rw
      fi
      cp_umask=$mode$u_plus_rw;;
  esac
fi

for src
do
  # Protect names starting with `-'.
  case $src in
    -*) src=./$src;;
  esac




  if test -n "$dir_arg"; then
    dst=$src
    dstdir=$dst
    test -d "$dstdir"
    dstdir_status=$?
  else

    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
    # might cause directories to be created, which would be especially bad
    # if $src (and thus $dsttmp) contains '*'.
    if test ! -f "$src" && test ! -d "$src"; then
      echo "$0: $src does not exist." >&2
      exit 1
    fi



    if test -z "$dst_arg"; then
      echo "$0: no destination specified." >&2
      exit 1
    fi

    dst=$dst_arg
    # Protect names starting with `-'.
    case $dst in
      -*) dst=./$dst;;
    esac

    # If destination is a directory, append the input filename; won't work

    # if double slashes aren't ignored.
    if test -d "$dst"; then
      if test -n "$no_target_directory"; then
	echo "$0: $dst_arg: Is a directory" >&2
	exit 1
      fi
      dstdir=$dst
      dst=$dstdir/`basename "$src"`
      dstdir_status=0
    else
      # Prefer dirname, but fall back on a substitute if dirname fails.
      dstdir=`
	(dirname "$dst") 2>/dev/null ||
	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	     X"$dst" : 'X\(//\)[^/]' \| \
	     X"$dst" : 'X\(//\)$' \| \
	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
	echo X"$dst" |
	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
		   s//\1/
		   q

		 }
		 /^X\(\/\/\)[^/].*/{
		   s//\1/
		   q
		 }
		 /^X\(\/\/\)$/{
		   s//\1/
		   q
		 }
		 /^X\(\/\).*/{
		   s//\1/
		   q
		 }
		 s/.*/./; q'
      `

      test -d "$dstdir"
      dstdir_status=$?
    fi
  fi

  obsolete_mkdir_used=false

  if test $dstdir_status != 0; then
    case $posix_mkdir in
      '')
	# Create intermediate dirs using mode 755 as modified by the umask.
	# This is like FreeBSD 'install' as of 1997-10-28.
	umask=`umask`
	case $stripcmd.$umask in
	  # Optimize common cases.
	  *[2367][2367]) mkdir_umask=$umask;;
	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;

	  *[0-7])
	    mkdir_umask=`expr $umask + 22 \
	      - $umask % 100 % 40 + $umask % 20 \
	      - $umask % 10 % 4 + $umask % 2
	    `;;
	  *) mkdir_umask=$umask,go-w;;
	esac

	# With -d, create the new directory with the user-specified mode.
	# Otherwise, rely on $mkdir_umask.
	if test -n "$dir_arg"; then
	  mkdir_mode=-m$mode
	else
	  mkdir_mode=
	fi

	posix_mkdir=false
	case $umask in
	  *[123567][0-7][0-7])
	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
	    ;;
	  *)
	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0

	    if (umask $mkdir_umask &&
		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
	    then

	      if test -z "$dir_arg" || {
		   # Check for POSIX incompatibilities with -m.
		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
		   # other-writeable bit of parent directory when it shouldn't.
		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
		   case $ls_ld_tmpdir in
		     d????-?r-*) different_mode=700;;
		     d????-?--*) different_mode=755;;
		     *) false;;
		   esac &&
		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
		   }
		 }
	      then posix_mkdir=:
	      fi
	      rmdir "$tmpdir/d" "$tmpdir"
	    else
	      # Remove any dirs left behind by ancient mkdir implementations.
	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
	    fi
	    trap '' 0;;
	esac;;
    esac


    if
      $posix_mkdir && (
	umask $mkdir_umask &&
	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
      )

    then :
    else

      # The umask is ridiculous, or mkdir does not conform to POSIX,
      # or it failed possibly due to a race condition.  Create the
      # directory the slow way, step by step, checking for races as we go.

      case $dstdir in
	/*) prefix='/';;
	-*) prefix='./';;
	*)  prefix='';;
      esac

      eval "$initialize_posix_glob"

      oIFS=$IFS
      IFS=/
      $posix_glob set -f
      set fnord $dstdir
      shift
      $posix_glob set +f
      IFS=$oIFS

      prefixes=

      for d
      do
	test -z "$d" && continue

	prefix=$prefix$d
	if test -d "$prefix"; then
	  prefixes=
	else
	  if $posix_mkdir; then
	    (umask=$mkdir_umask &&
	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
	    # Don't fail if two instances are running concurrently.
	    test -d "$prefix" || exit 1
	  else
	    case $prefix in
	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
	      *) qprefix=$prefix;;
	    esac
	    prefixes="$prefixes '$qprefix'"
	  fi
	fi
	prefix=$prefix/
      done

      if test -n "$prefixes"; then
	# Don't fail if two instances are running concurrently.
	(umask $mkdir_umask &&
	 eval "\$doit_exec \$mkdirprog $prefixes") ||
	  test -d "$dstdir" || exit 1
	obsolete_mkdir_used=true
      fi
    fi
  fi

  if test -n "$dir_arg"; then
    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
  else

    # Make a couple of temp file names in the proper directory.
    dsttmp=$dstdir/_inst.$$_
    rmtmp=$dstdir/_rm.$$_


    # Trap to clean up those temp files at exit.
    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0


    # Copy the file name to the temp name.
    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&

    # and set any options; do chmod last to preserve setuid bits.
    #




    # If any of these fail, we abort the whole thing.  If we want to
    # ignore errors from any of these, just make sure not to ignore
    # errors from the above "$doit $cpprog $src $dsttmp" command.
    #
    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&

    # If -C, don't bother to copy if it wouldn't change the file.
    if $copy_on_change &&
       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&

       eval "$initialize_posix_glob" &&
       $posix_glob set -f &&
       set X $old && old=:$2:$4:$5:$6 &&
       set X $new && new=:$2:$4:$5:$6 &&
       $posix_glob set +f &&

       test "$old" = "$new" &&
       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
    then
      rm -f "$dsttmp"
    else
      # Rename the file to the real destination.
      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||

      # The rename failed, perhaps because mv can't rename something else
      # to itself, or perhaps because mv is so ancient that it does not
      # support -f.
      {
	# Now remove or move aside any old file at destination location.
	# We try this two ways since rm can't unlink itself on some
	# systems and the destination file might be busy for other
	# reasons.  In this case, the final cleanup might fail but the new
	# file should still install successfully.
	{
	  test ! -f "$dst" ||
	  $doit $rmcmd -f "$dst" 2>/dev/null ||
	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
	  } ||
	  { echo "$0: cannot unlink or rename $dst" >&2
	    (exit 1); exit 1
	  }
	} &&

	# Now rename the file to the real destination.
	$doit $mvcmd "$dsttmp" "$dst"
      }
    fi || exit 1

    trap '' 0
  fi
done

# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

Deleted extensions/tnc/makefile.vc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#----------------------------------------------------------------------------
#   This is derivated from the tcl8.3 win makefile and surely not
#   perfect. It works for me. 
#   rolf ade, 2001 (rolf@pointsman.de)
#   
#
#
#   Project directories
#
#   ROOT   = top of source tree
#
#   TOOLS32 = location of VC++ 32-bit development tools.
#
#   INSTALLDIR = where the install- targets should copy the binaries and
#                support files
#
#----------------------------------------------------------------------------

!if "$(MSVCDIR)" == ""
MSG = ^
You'll need to run vcvars32.bat from Developer Studio, first, to setup^
the environment.
!error $(MSG)
!endif


#          VC++ 2.0 header files are broken, so you need to use the
#          ones that come with the developer network CD's, or later
#          versions of VC++.
#
# INSTALLDIR = where the install- targets should copy the binaries and
#          support files
#

# Set this to the appropriate value of /MACHINE: for your platform
MACHINE                = IX86
ROOT           = ..\..
INSTALLDIR     = c:\Progra~1\Tcl

TOOLS32        = $(MSVCDIR)
TOOLS32_rc     = $(MSVCDIR)\..\common\MSDev98

# Uncomment the following line to compile with thread support
#THREADDEFINES = -DTCL_THREADS=1

# Set NODEBUG to 0 to compile with symbols
NODEBUG = 1

# The following defines can be used to control the amount of debugging
# code that is added to the compilation.
#
#      -DTCL_MEM_DEBUG         Enables the debugging memory allocator.
#      -DTCL_COMPILE_DEBUG     Enables byte compilation logging.
#      -DTCL_COMPILE_STATS     Enables byte compilation statistics gathering.
#      -DUSE_TCLALLOC=0        Disables the Tcl memory allocator in favor
#                              of the native malloc implementation.  This is
#
# DEBUGDEFINES = -DTCL_MEM_DEBUG -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
# DEBUGDEFINES = -DUSE_TCLALLOC=0


#-------------------------------------------------------------------------
#
#   Do not modify below this line
#
#-------------------------------------------------------------------------

NAMEPREFIX = libtnc
STUBPREFIX = $(NAMEPREFIX)stub
DOTVERSION = 0.3
PACKAGE_VERSION = \"0.3.0\"
VERSION = \"0.3\"
W32VERSION = 03
TDOMVER = 082

BINROOT         = .
!IF "$(NODEBUG)" == "1"
TMPDIRNAME      =
DBGX            =
!ELSE
TMPDIRNAME      = Debug
DBGX            = d
!ENDIF
TMPDIR          = $(BINROOT)
OUTDIRNAME      = $(TMPDIRNAME)
OUTDIR          = $(TMPDIR)
TOP_DIR         = $(BINROOT)\..

TNCLIB         = $(OUTDIR)\$(NAMEPREFIX)$(W32VERSION)$(DBGX).lib
TNCDLLNAME     = $(NAMEPREFIX)$(W32VERSION)$(DBGX).dll
TNCDLL         = $(OUTDIR)\$(TNCDLLNAME)

# MKDIR           = .\mkd.bat
RM              = del

LIB_INSTALL_DIR        = $(INSTALLDIR)\lib
BIN_INSTALL_DIR        = $(INSTALLDIR)\bin
SCRIPT_INSTALL_DIR     = $(INSTALLDIR)\lib\tcl$(DOTVERSION)
INCLUDE_INSTALL_DIR    = $(INSTALLDIR)\include


TNCOBJS = $(TMPDIR)\tnc.obj

cc32           = "$(TOOLS32)\bin\cl.exe"
link32         = "$(TOOLS32)\bin\link.exe"
rc32           = "$(TOOLS32_rc)\bin\rc.exe"
include32      = -I"$(TOOLS32)\include"
libpath32      = /LIBPATH:"$(TOOLS32)\lib"
tcllibpath     = /LIBPATH:"$(INSTALLDIR)\lib"
tdomlibpath    = /LIBPATH:"$(ROOT)\win\Release"
lib32          = "$(TOOLS32)\bin\lib.exe"

TNCDIR         = $(ROOT)\extensions\tnc
GENERICDIR     = $(ROOT)\generic
EXPATINCDIR    = $(ROOT)\expat
TCLINCDIR      = $(INSTALLDIR)\Include

TCL_INCLUDES   = -I"$(TNCDIR)" -I"$(GENERICDIR)" -I"$(EXPATINCDIR)" -I"$(TCLINCDIR)"
TCL_DEFINES    = $(DEBUGDEFINES) $(THREADDEFINES)

#-------------------------------------------------------------------------
#
#   Compile flags
#
#-------------------------------------------------------------------------

!IF "$(NODEBUG)" == "1"
# This cranks the optimization level to maximize speed
cdebug = -O2 -Gs -GD
!ELSE
!IF "$(MACHINE)" == "IA64"
cdebug = -Od -Zi
!ELSE
cdebug = -Z7 -Od
!ENDIF
!ENDIF

# declarations common to all compiler options
cflags = -c -nologo -Fp$(TMPDIR)\ -YX -DXML_DTD -DXML_NS -DUSE_TCL_STUBS -DUSE_TDOM_STUBS -DVERSION=$(VERSION) -DPACKAGE_VERSION=$(PACKAGE_VERSION)
cvarsdll = -MD$(DBGX)

TCL_CFLAGS     = $(cdebug) $(cflags) $(cvarsdll) $(include32) \
                       $(TCL_INCLUDES) $(TCL_DEFINES)
CON_CFLAGS     = $(cdebug) $(cflags) $(include32) -DCONSOLE

#-------------------------------------------------------------------------
#
#   Link flags
#
#-------------------------------------------------------------------------

!IF "$(NODEBUG)" == "1"
ldebug = /RELEASE
!ELSE
ldebug = -debug:full -debugtype:cv
!ENDIF

# declarations common to all linker options
lflags = /NODEFAULTLIB /NOLOGO /MACHINE:$(MACHINE) $(libpath32) $(tcllibpath) $(tdomlibpath) 

# declarations for use on Intel i386, i486, and Pentium systems
DLLENTRY = @12
dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll


conlflags = $(lflags) -subsystem:console -entry:mainCRTStartup
guilflags = $(lflags) -subsystem:windows -entry:WinMainCRTStartup

libc = libc$(DBGX).lib oldnames.lib
libcdll = msvcrt$(DBGX).lib oldnames.lib

baselibs   = kernel32.lib $(optlibs) advapi32.lib user32.lib tclstub84$(DBGX).lib tdomstub$(TDOMVER).lib 
winlibs     = $(baselibs) gdi32.lib comdlg32.lib winspool.lib


guilibs     = $(libc) $(winlibs)
conlibs     = $(libc) $(baselibs)
guilibsdll  = $(libcdll) $(winlibs)
conlibsdll  = $(libcdll) $(baselibs)

#-------------------------------------------------------------------------
#
#   Project specific targets
#
#-------------------------------------------------------------------------

release:   setup dlls
dlls:      setup $(TNCDLL)
all:       setup dlls $(CAT32)

setup:
#      @$(MKDIR) $(TMPDIR)
#      @$(MKDIR) $(OUTDIR)

$(TNCLIB): $(TNCDLL)

$(TNCDLL): $(TNCOBJS)
       $(link32) $(ldebug) $(dlllflags) \
               -out:$@ $(guilibsdll) @<<
$(TNCOBJS)
<<

#-------------------------------------------------------------------------
#   Implicit rules
#-------------------------------------------------------------------------

{$(TNCDIR)}.c{$(TMPDIR)}.obj:
    $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<

clean:
       -@$(RM) $(OUTDIR)\*.exp 2>nul
       -@$(RM) $(OUTDIR)\*.lib 2>nul
       -@$(RM) $(OUTDIR)\*.dll 2>nul
       -@$(RM) $(TMPDIR)\*.pch 2>nul
       -@$(RM) $(TMPDIR)\*.obj 2>nul
       -@$(RM) $(TMPDIR)\*.ilk 2>nul
       -@$(RM) $(TMPDIR)\*.pdb 2>nul
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































Changes to extensions/tnc/tests/loadtnc.tcl.





1
2
3
4
5
6
7
..
11
12
13
14
15
16
17
18
19
20
21
22
23
24




# loadtnc.tcl --
#
# This file is [source]d by all.tcl and all test files, to ensure, that
# the tcltest package and the lastest tnc build is present.

if {[lsearch [namespace children] ::tcltest] == -1} {
    if {$tcl_version < 8.2} {
................................................................................
    } else {
        package require tcltest
        namespace import ::tcltest::*
    }
}

if {[catch {package present tdom}]} {
    package require tdom 0.7.5
}

if {[catch {package require tnc 0.3}]} {
    load [file join [file dir [info script]] .. libtnc0.3.0.so]
}

>
>
>
>







 







|


|
|


1
2
3
4
5
6
7
8
9
10
11
..
15
16
17
18
19
20
21
22
23
24
25
26
27
28
catch {load ../../../unix/libtdom0.9.1.so}
catch {load ../libtnc0.3.0.so}
catch {load ../../unix/libtdom0.9.1.so}
catch {load libtnc0.3.0.so}
# loadtnc.tcl --
#
# This file is [source]d by all.tcl and all test files, to ensure, that
# the tcltest package and the lastest tnc build is present.

if {[lsearch [namespace children] ::tcltest] == -1} {
    if {$tcl_version < 8.2} {
................................................................................
    } else {
        package require tcltest
        namespace import ::tcltest::*
    }
}

if {[catch {package present tdom}]} {
    package require tdom
}

if {[catch {package require tnc}]} {
    package require tnc
}

Changes to extensions/tnc/tests/tnc.test.

130
131
132
133
134
135
136




















































137
138
139
140
141
142
143
    <!ELEMENT b EMPTY>
]>
<!-- This not well-formed document doesn't have a root element -->}} errMsg]
    $parser free
    set result
} {1}





















































test tnc-3.1 {validate cmd} {
    set parser [expat]
    tnc $parser enable
    set result [catch {$parser parse $xml}]
    set validator [tnc $parser getValidateCmd]
    rename $validator {}
    $parser free







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
    <!ELEMENT b EMPTY>
]>
<!-- This not well-formed document doesn't have a root element -->}} errMsg]
    $parser free
    set result
} {1}

test tnc-2.7 {not valid document} {
    set parser [expat]
    tnc $parser enable
    set result [catch {$parser parse {<!DOCTYPE root [
    <!ELEMENT root (a,b)>
    <!ELEMENT a (#PCDATA)>
    <!ELEMENT b EMPTY>
]>
<root><a>text</a></root>}} errMsg]
    $parser free
    set errMsg
} {Validation error at line 6, character 17: Element can not end here (required element(s) missing).}

proc 2.8-resolver {base systemId publicId} {
    switch $publicId {
        "-//W3C//DTD Specification V2.0//EN" {
            set fd [open [file join [file dir [info script]] \
                              ../../../tests/data/xmlspec-v20.dtd]]
            set xmlspec [read $fd]
            close $fd
            return [list "string" "" $xmlspec]
        }
        default {
            puts stderr "Unexpected systemId '$systemId'"
            return ""
        }
    }
}

test tnc-2.8 {Validate REC-xslt-19991116.xml} {
    set ::tDOM::extRefHandlerDebug 1
    set parser [expat -externalentitycommand 2.8-resolver  \
                    -paramentityparsing always]
    tnc $parser enable
    $parser parsefile [file join [file dir [info script]] \
                           ../../../tests/data/REC-xslt-19991116.xml] 
    $parser free
} {}

test tnc-2.9 {check #PCDATA only element} {
    set parser [expat]
    tnc $parser enable
    set result [catch {$parser parse {<!DOCTYPE root [
    <!ELEMENT root (a,b)>
    <!ELEMENT a (#PCDATA)>
    <!ELEMENT b EMPTY>
]>
<root><a>text<b/>text</a><b/></root>}} errMsg]
    $parser free
    set errMsg
} {Validation error at line 6, character 13: Element is not allowed here.}

test tnc-3.1 {validate cmd} {
    set parser [expat]
    tnc $parser enable
    set result [catch {$parser parse $xml}]
    set validator [tnc $parser getValidateCmd]
    rename $validator {}
    $parser free

Changes to extensions/tnc/tnc.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
..
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
..
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
...
266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
...
340
341
342
343
344
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
...
373
374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
...
405
406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
...
481
482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
...
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
...
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575

576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
...
631
632
633
634
635
636
637
638
639
640
641
642
643

644
645
646
647
648
649
650
...
670
671
672
673
674
675
676
677
678
679
680

681
682
683
684
685
686
687
...
727
728
729
730
731
732
733
734
735
736
737
738
739
740

741
742
743
744
745
746
747
....
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155

1156
1157
1158
1159
1160
1161
1162
....
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
....
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
....
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
....
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
....
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
....
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525

1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
....
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779

1780
1781
1782
1783
1784
1785
1786
....
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
....
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
....
1932
1933
1934
1935
1936
1937
1938
1939
1940

1941
1942
1943
1944
1945
1946
1947
....
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
....
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085

2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
....
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
....
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
....
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171

2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
....
2206
2207
2208
2209
2210
2211
2212
2213
2214

2215
2216
2217
2218
2219
2220
2221
....
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
....
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
....
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
....
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
....
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
....
2566
2567
2568
2569
2570
2571
2572
2573
2574

2575
2576
2577
2578
2579
2580
2581
....
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663

2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
....
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
....
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
....
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756

2757
2758
2759
2760
2761
2762
2763
....
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
....
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
....
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
....
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981

   Copyright (c) 2001-2003 Rolf Ade */

#include <tdom.h>
#include <string.h>
#include <stdlib.h>

/*
 * Beginning with 8.4, Tcl API is CONST'ified
 */
#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION <= 3)
# define CONST84
#endif

#ifndef TCL_THREADS
# define TDomThreaded(x)
#else
# define TDomThreaded(x) x
#endif

/* The inital stack sizes must be at least 1 */
#define TNC_INITCONTENTSTACKSIZE 512

/*----------------------------------------------------------------------------
|   local globals
|
\---------------------------------------------------------------------------*/
/* Counter to generate unique validateCmd names */
................................................................................
    int           alreadymatched;
} TNC_ContentStack;


typedef struct TNC_data
{
    char             *doctypeName;            /* From DOCTYPE declaration */
    int               ignoreWhiteCDATAs;      /* Flag: white space allowed in 
                                                 current content model? */
    int               ignorePCDATA;           /* Flag: currently mixed content
                                                 model? */
    Tcl_HashTable    *tagNames;               /* Hash table of all ELEMENT
                                                 declarations of the DTD.
                                                 Element name is the key.
                                                 While parsing, entry points
................................................................................
                                                 the elemAttInfo pointer of
                                                 the current element here for
                                                 DOM validation, to avoid two
                                                 element name lookups. */
    int               elemContentsRewriten;   /* Signals, if the tagNames
                                                 entries point to
                                                 TNC_Contents */
    int               status;                 /* While used with expat obj:
                                                 1 after successful parsed
                                                 DTD, 0 otherwise.
                                                 For validateCmd used for
                                                 error report during
                                                 validation: 0 OK, 1 validation
                                                 error. */
    int               idCheck;                /* Flag: check IDREF resolution*/
................................................................................
    TNC_ERROR_UNKNOWN_ELEMENT,
    TNC_ERROR_EMPTY_ELEMENT,
    TNC_ERROR_DISALLOWED_PCDATA,
    TNC_ERROR_DISALLOWED_CDATA,
    TNC_ERROR_NO_DOCTYPE_DECL,
    TNC_ERROR_WRONG_ROOT_ELEMENT,
    TNC_ERROR_NO_ATTRIBUTES,
    TNC_ERROR_UNKOWN_ATTRIBUTE,
    TNC_ERROR_WRONG_FIXED_ATTVALUE,
    TNC_ERROR_MISSING_REQUIRED_ATTRIBUTE,
    TNC_ERROR_MORE_THAN_ONE_ID_ATT,
    TNC_ERROR_ID_ATT_DEFAULT,
    TNC_ERROR_DUPLICATE_ID_VALUE,
    TNC_ERROR_UNKOWN_ID_REFERRED,
    TNC_ERROR_ENTITY_ATTRIBUTE,
    TNC_ERROR_ENTITIES_ATTRIBUTE,
    TNC_ERROR_ATT_ENTITY_DEFAULT_MUST_BE_DECLARED,
    TNC_ERROR_NOTATION_REQUIRED,
    TNC_ERROR_NOTATION_MUST_BE_DECLARED,
    TNC_ERROR_IMPOSSIBLE_DEFAULT,
    TNC_ERROR_ENUM_ATT_WRONG_VALUE,
................................................................................

#define SetBooleanResult(i) Tcl_ResetResult(interp); \
                     Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (i))

extern char *Tdom_InitStubs (Tcl_Interp *interp, char *version, int exact);

static void
signalNotValid (userData, code)
    void        *userData;
    int          code;

{
    TNC_Data *tncdata = (TNC_Data *) userData;
    TclGenExpatInfo *expat;
    char s[1000];

    if (tncdata->expatObj) {
        expat = GetExpatInfo (tncdata->interp, tncdata->expatObj);
................................................................................
                 XML_GetCurrentLineNumber (expat->parser),
                 XML_GetCurrentColumnNumber (expat->parser),
                 TNC_ErrorString (code));
        expat->status = TCL_ERROR;
        expat->result = Tcl_NewStringObj (s, -1);
        Tcl_IncrRefCount (expat->result);
    } else {
        tncdata->status = 1;
        Tcl_SetResult (tncdata->interp, (char *)TNC_ErrorString (code),
                       TCL_VOLATILE);
    }
}

/*
 *----------------------------------------------------------------------------
................................................................................
 * Side effects:
 *	Stores the doctype Name in the TNC_data.
 *
 *----------------------------------------------------------------------------
 */

void
TncStartDoctypeDeclHandler (userData, doctypeName, sysid, pubid, has_internal_subset)
    void       *userData;
    const char *doctypeName;
    const char *sysid;
    const char *pubid;
    int         has_internal_subset;

{
    TNC_Data *tncdata = (TNC_Data *) userData;

#ifdef TNC_DEBUG
    printf ("TncStartDoctypeDeclHandler start\n");
#endif
    tncdata->doctypeName = tdomstrdup (doctypeName);
................................................................................
 * Side effects:
 *	Frees memory.
 *
 *----------------------------------------------------------------------------
 */

static void
TncFreeTncModel (tmodel)
    TNC_Content *tmodel;

{
    unsigned int i;

    if (tmodel->children) {
        for (i = 0; i < tmodel->numchildren; i++) {
            TncFreeTncModel (&tmodel->children[i]);
        }
................................................................................
 * Side effects:
 *	Allocates memory for the TNC_Content models.
 *
 *----------------------------------------------------------------------------
 */

static void
TncRewriteModel (emodel, tmodel, tagNames)
    XML_Content   *emodel;
    TNC_Content   *tmodel;
    Tcl_HashTable *tagNames;

{
    Tcl_HashEntry *entryPtr;
    unsigned int i;

    tmodel->type = emodel->type;
    tmodel->quant = emodel->quant;
    tmodel->numchildren = emodel->numchildren;
................................................................................
 *	Rewrites the XML_Content models to TNC_Content
 *      models.
 *
 *----------------------------------------------------------------------------
 */

void
TncEndDoctypeDeclHandler (userData)
    void *userData;

{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr, *ePtr1;
    Tcl_HashSearch search;
    XML_Content   *emodel;
    TNC_Content   *tmodel = NULL;
    char *elementName;
................................................................................
        if (!Tcl_GetHashValue (entryPtr)) {
            signalNotValid (userData,
                            TNC_ERROR_ATT_ENTITY_DEFAULT_MUST_BE_DECLARED);
            return;
        }
        entryPtr = Tcl_NextHashEntry (&search);
    }
    tncdata->status = 1;
}


/*
 *----------------------------------------------------------------------------
 *
 * TncEntityDeclHandler --
................................................................................
 *	Stores either the name of the entity and
 *      type information in a lookup table.
 *
 *----------------------------------------------------------------------------
 */

void
TncEntityDeclHandler (userData, entityName, is_parameter_entity, value,
                       value_length, base, systemId, publicId, notationName)
    void *userData;
    const char *entityName;
    int is_parameter_entity;
    const char *value;
    int value_length;
    const char *base;
    const char *systemId;
    const char *publicId;
    const char *notationName;

{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr, *entryPtr1;
    int newPtr;
    TNC_EntityInfo *entityInfo;


    /* expat collects entity definitions internaly by himself. So this is
       maybe superfluous, if it possible to access the expat internal
       represention. To study this is left to the reader. */

    if (is_parameter_entity) return;
    entryPtr = Tcl_CreateHashEntry (tncdata->entityDecls, entityName, &newPtr);
    /* multiple declaration of the same entity are allowed; first
       definition wins (rec. 4.2) */
    if (!newPtr) {
        /* Eventually, an attribute declaration with type ENTITY or ENTITIES
           has used this (up to the attribute declaration undeclared) ENTITY
           within his default value. In this case, the hash value have to
           be NULL and the entity must be a unparsed entity. */
        if (!Tcl_GetHashValue (entryPtr)) {
            if (notationName == NULL) {
                signalNotValid (userData,
                                TNC_ERROR_ATT_ENTITY_DEFAULT_MUST_BE_DECLARED);
                return;
            }
................................................................................
            newPtr = 1;
        }
    }
    if (newPtr) {
        entityInfo = (TNC_EntityInfo *) MALLOC (sizeof (TNC_EntityInfo));
        if (notationName != NULL) {
            entityInfo->is_notation = 1;
            entryPtr1 = Tcl_CreateHashEntry (tncdata->notationDecls,
                                             notationName, &newPtr);
            entityInfo->notationName = tdomstrdup (notationName);
        }
        else {
            entityInfo->is_notation = 0;
        }
        Tcl_SetHashValue (entryPtr, entityInfo);
    }
................................................................................
 *	Stores the notationName in the notationDecls table with value
 *      one.
 *
 *----------------------------------------------------------------------------
 */

void
TncNotationDeclHandler (userData, notationName, base, systemId, publicId)
    void       *userData;
    const char *notationName;
    const char *base;
    const char *systemId;
    const char *publicId;

{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr;
    int newPtr;

    entryPtr = Tcl_CreateHashEntry (tncdata->notationDecls,
                                    notationName,
................................................................................
 * Side effects:
 *	Stores the tag name of the element in a lookup table.
 *
 *----------------------------------------------------------------------------
 */

void
TncElementDeclCommand (userData, name, model)
    void *userData;
    const char *name;
    XML_Content *model;

{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr;
    int newPtr;
    unsigned int i, j;

    entryPtr = Tcl_CreateHashEntry (tncdata->tagNames, name, &newPtr);
................................................................................
 * Side effects:
 *	Stores the tag name of the element in a lookup table.
 *
 *----------------------------------------------------------------------------
 */

void
TncAttDeclCommand (userData, elname, attname, att_type, dflt, isrequired)
    void       *userData;
    const char *elname;
    const char *attname;
    const char *att_type;
    const char *dflt;
    int         isrequired;

{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr, *entryPtr1;
    Tcl_HashTable *elemAtts;
    TNC_ElemAttInfo *elemAttInfo;
    TNC_AttDecl *attDecl;
    TNC_EntityInfo *entityInfo;
................................................................................
 *	Eventually pushes data to the contentStack (even in
 *      recurive calls).
 *
 *----------------------------------------------------------------------------
 */

static int
TncProbeElement (nameId, tncdata)
    TNC_NameId *nameId;
    TNC_Data   *tncdata;

{
    TNC_ContentStack *stackelm;
    TNC_Content *activeModel;
    int myStackPtr, zeroMatchPossible, result;
    unsigned int i, seqstartindex;

#ifdef TNC_DEBUG
................................................................................
            if (stackelm->model->quant == XML_CQUANT_NONE ||
                stackelm->model->quant == XML_CQUANT_OPT) {
                /*The child cp's type SEQ or CHOICE keep track by
                  themselve about if they are repeated. Because we are
                  here, they don't.  Since the current cp has already
                  matched and isn't multiple, the current cp as a whole
                  is done.  But no contradiction detected, so return
                  "search futher" */
                return -1;
            }
        }

        /* If one of the alternatives within the CHOICE cp is quant
           REP or OPT, it isn't a contradition to the document structure,
           if the cp doesn't match, even if it is quant
................................................................................
                   have a candidat for "zero match". */
                if (result == -1) {
                    zeroMatchPossible = 1;
                }
                tncdata->contentStackPtr--;
            }
        }
        /* OK, nobody has claimed a match. Question is: try futher or is
           this a document structure error. */
        if (zeroMatchPossible ||
            stackelm->alreadymatched ||
            stackelm->model->quant == XML_CQUANT_REP ||
            stackelm->model->quant == XML_CQUANT_OPT) {
            return -1;
        }
................................................................................
                    break;
                }
            }
        }
        if (!stackelm->alreadymatched) {
            if (zeroMatchPossible) {
                /* The stackelm hasn't matched, but don't have to
                   after all.  Return try futher */
                return -1;
            } else {
                /* No previous match, but at least one child is
                   necessary. Return depends of the quant of the
                   entire seq */
                if (stackelm->model->quant == XML_CQUANT_NONE ||
                    stackelm->model->quant == XML_CQUANT_PLUS) {
................................................................................
                   child later. Error in document structure. */
                return 0;
            } else {
                /* OK, SEQ has matched befor. But after the last match, there
                   where no required (quant NONE or PLUS) childs. */
                if (stackelm->model->quant == XML_CQUANT_NONE ||
                    stackelm->model->quant == XML_CQUANT_OPT) {
                    /* The entire seq isn't multiple. Just look futher. */
                    return -1;
                }
            }
        }
        /* The last untreated case is alreadymatched true,
           zeroMatchPossible (of the rest of the seq childs after the
           last match) true and the entire seq may be
           multiple. Therefore start again with activeChild = 0, to
           see, if the current nameId starts a repeated match of the
           seq.  By the way: zeroMatchPossible still has inital value
           1, therefor no second initaliation is needed */
        for (i = 0; i < seqstartindex; i++) {
            if ((&stackelm->model->children[i])->type == XML_CTYPE_NAME) {
                if ((&stackelm->model->children[i])->nameId == nameId) {
#ifdef TNC_DEBUG
                    printf ("-->matched! child Nr. %d\n",i);
#endif
                    (&tncdata->contentStack[myStackPtr])->activeChild = i;
................................................................................
        }
        /* seq doesn't match again and every seq child from the very first
           up to (not including) the last match aren't required. This last
           fact may be nice to know, but after all since the entire seq have
           matched already ... */
        return -1;
    case XML_CTYPE_NAME:
        /* NAME type dosen't occur at top level of a content model and is
           handled in some "shotcut" way directly in the CHOICE and SEQ cases.
           It's only here to pacify gcc -Wall. */
        printf ("error!!! - in TncProbeElement: XML_CTYPE_NAME shouldn't reached in any case.\n");
    default:
        printf ("error!!! - in TncProbeElement: unknown content type: %d\n",
                stackelm->model->type);
    }
................................................................................
 * Side effects:
 *	Eventually increments the required attributes counter.
 *
 *----------------------------------------------------------------------------
 */

static int
TncProbeAttribute (userData, elemAtts, attrName, attrValue, nrOfreq)
    void *userData;
    Tcl_HashTable *elemAtts;
    char *attrName;
    char *attrValue;
    int *nrOfreq;

{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr;
    TNC_AttDecl *attDecl;
    char *pc, *copy, save;
    int clen, i, start, hnew;
    TNC_EntityInfo *entityInfo;

    entryPtr = Tcl_FindHashEntry (elemAtts, attrName);
    if (!entryPtr) {
        signalNotValid (userData, TNC_ERROR_UNKOWN_ATTRIBUTE);
        return 0;
    }
    /* NOTE: attribute uniqueness per element is a wellformed
               constrain and therefor done by expat. */
    attDecl = (TNC_AttDecl *) Tcl_GetHashValue (entryPtr);
    switch (attDecl->att_type) {
    case TNC_ATTTYPE_CDATA:
................................................................................
 * Side effects:
 *	Eventually signals application error.
 *
 *----------------------------------------------------------------------------
 */

void
TncElementStartCommand (userData, name, atts)
    void *userData;
    const char *name;
    const char **atts;

{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr;
    Tcl_HashTable *elemAtts;
    const char **atPtr;
    TNC_ElemAttInfo *elemAttInfo;
    TNC_Content *model;
................................................................................
#endif

    /* If the document doesn't have a doctype declaration, but the
       user have used the -useForeignDTD 1 feature, the collected
       data out of the provided DTD isn't postprocessed by 
       TncElementStartCommand. We do this now.
       NOTE: Since there wasn't a doctype declaration, there is no
       information avaliable which element is expected to be the
       document element. Eventually it would be desirable, to set
       this somehow. For now, this means, that every valid subtree
       of the given DTD information is accepted.  */
    if (!tncdata->contentStackPtr && !tncdata->elemContentsRewriten) {
        TncEndDoctypeDeclHandler (userData);
        acceptNoDoctype = 1;
    }
................................................................................
        return;
    }
    model = (TNC_Content *) Tcl_GetHashValue (entryPtr);

    switch (model->type) {
    case XML_CTYPE_MIXED:
    case XML_CTYPE_ANY:
        tncdata->ignoreWhiteCDATAs = 1;
        tncdata->ignorePCDATA = 1;
        break;
    case XML_CTYPE_EMPTY:
        tncdata->ignoreWhiteCDATAs = 0;
        break;
    case XML_CTYPE_CHOICE:
    case XML_CTYPE_SEQ:
        tncdata->ignoreWhiteCDATAs = 1;
        tncdata->ignorePCDATA = 0;
        break;
    case XML_CTYPE_NAME:
        break;
    }

    if (tncdata->contentStackPtr) {
................................................................................
 *	Let the contentStackPtr point to the last current content
 *      model before the element had started.
 *
 *----------------------------------------------------------------------------
 */

static int
TncProbeElementEnd (tncdata)
    TNC_Data *tncdata;

{
    TNC_ContentStack stackelm;
    unsigned int i;
    int zeroMatchPossible, seqstartindex;

    stackelm = tncdata->contentStack[tncdata->contentStackPtr - 1];
    switch (stackelm.model->type) {
................................................................................
                    tncdata->contentStackPtr--;
                    return 0;
                }
            }
        }
        return 1;
    case XML_CTYPE_NAME:
        /* NAME type dosen't occur at top level of a content model and is
           handled in some "shotcut" way directly in the CHOICE and SEQ cases.
           It's only here to pacify gcc -Wall. */
        fprintf (stderr, "error!!! - in TncProbeElementEnd: XML_CTYPE_NAME "
                 "shouldn't be reached in any case.\n");
    default:
        fprintf (stderr, "error!!! - in TncProbeElementEnd: unknown content "
                 "type: %d\n", stackelm.model->type);
................................................................................
 * Side effects:
 *	Eventually signals application error.
 *
 *----------------------------------------------------------------------------
 */

void
TncElementEndCommand (userData, name)
    void       *userData;
    const char *name;

{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;

#ifdef TNC_DEBUG
    printf ("TncElementEndCommand start\n");
    printContentStack (tncdata);
#endif
    while (1) {
        if (!TncProbeElementEnd (tncdata, 0)) {
            signalNotValid (userData, TNC_ERROR_ELEMENT_CAN_NOT_END_HERE);
            return;
        }
        if (tncdata->contentStack[tncdata->contentStackPtr - 1].deep == 0) {
            break;
        }
        tncdata->contentStackPtr--;
................................................................................
    printf ("after removing ended element from the stack\n");
    printContentStack (tncdata);
#endif
    if (tncdata->contentStackPtr) {
        switch ((&tncdata->contentStack[tncdata->contentStackPtr - 1])->model->type) {
        case XML_CTYPE_MIXED:
        case XML_CTYPE_ANY:
            tncdata->ignoreWhiteCDATAs = 1;
            tncdata->ignorePCDATA = 1;
            break;
        case XML_CTYPE_EMPTY:
            tncdata->ignoreWhiteCDATAs = 0;
            break;
        case XML_CTYPE_CHOICE:
        case XML_CTYPE_SEQ:
        case XML_CTYPE_NAME:
            tncdata->ignoreWhiteCDATAs = 1;
            tncdata->ignorePCDATA = 0;
            break;
        }
    } else {
        /* This means, the root element is closed,
           therefor the place to check, if every IDREF points
           to a ID. */
................................................................................
                 entryPtr = Tcl_NextHashEntry (&search)) {
#ifdef TNC_DEBUG
                printf ("check id value %s\n",
                        Tcl_GetHashKey (tncdata->ids, entryPtr));
                printf ("value %p\n", Tcl_GetHashValue (entryPtr));
#endif
                if (!Tcl_GetHashValue (entryPtr)) {
                    signalNotValid (userData, TNC_ERROR_UNKOWN_ID_REFERRED);
                return;
                }
            }
        }
    }
}

................................................................................
 * Side effects:
 *	Eventually signals application error.
 *
 *----------------------------------------------------------------------------
 */

void
TncCharacterdataCommand (userData, data, len)
    void       *userData;
    const char *data;
    int         len;

{
    TNC_Data *tncdata = (TNC_Data *) userData;
    int i;
    char *pc;

    if (!tncdata->ignoreWhiteCDATAs && len > 0) {
        signalNotValid (userData, TNC_ERROR_EMPTY_ELEMENT);
        return;
    }
    if (!tncdata->ignorePCDATA) {
        for (i = 0, pc = (char*)data; i < len; i++, pc++) {
            if ( (*pc == ' ')  ||
                 (*pc == '\n') ||
................................................................................
 * Side effects:
 *	Eventually signals application error.
 *
 *----------------------------------------------------------------------------
 */

void
TncStartCdataSectionHandler (userData)
    void *userData;

{
    TNC_Data *tncdata = (TNC_Data *) userData;

    if (!tncdata->ignorePCDATA) {
        signalNotValid (userData, TNC_ERROR_DISALLOWED_CDATA);
    }
}
................................................................................
    )
{
    domNode       *child;

    switch (node->nodeType) {
    case ELEMENT_NODE:
        TncElementStartCommand (tncdata, node->nodeName, NULL);
        if (tncdata->status) return 0;
        if (!validateNodeAttributes (tncdata, tncdata->elemAttInfo, node)) 
            return 0;
        if (node->firstChild) {
            child = node->firstChild;
            while (child) {
                if (!validateTree (tncdata, child)) return 0;
                child = child->nextSibling;
            }
        }
        TncElementEndCommand (tncdata, node->nodeName);
        if (tncdata->status) return 0;
        break;
    case TEXT_NODE:
    case CDATA_SECTION_NODE:
        TncCharacterdataCommand (tncdata, ((domTextNode*)node)->nodeValue, 
                                 ((domTextNode*)node)->valueLength);
        if (tncdata->status) return 0;
        break;
    case COMMENT_NODE:
    case PROCESSING_INSTRUCTION_NODE:
        break;
    default:
        signalNotValid (tncdata, TNC_ERROR_UNKNOWN_NODE_TYPE);
        return 0;
................................................................................
 */

static int
tnc_ValidateObjCmd (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *CONST objv[]
    )
{
    TNC_Data        *tncdata = (TNC_Data*) clientData;
    int              methodIndex, result = 1;
    domNode         *node;
    char            *errMsg = NULL;
    Tcl_HashEntry   *entryPtr;
    TNC_Content     *model;
    
    static CONST84 char *validateMethods[] = {
        "validateTree",   "validateDocument", "validateAttributes",
        "delete",
        NULL
    };
    enum validateMethod {
        m_validateTree, m_validateDocument, m_validateAttributes,
        m_delete
................................................................................
        node = tcldom_getNodeFromName (
            interp, Tcl_GetStringFromObj(objv[2], NULL), &errMsg
            );
        if (!node || (node->nodeType != ELEMENT_NODE)) {
            SetResult ("The validateTree method needs a domNode as argument.");
            return TCL_ERROR;
        }
        tncdata->status = 0;
        tncdata->idCheck = 0;
        if (tncdata->ids->numEntries) {
            Tcl_DeleteHashTable (tncdata->ids);
            Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
        }
        tncdata->contentStackPtr = 0;
        Tcl_ResetResult (interp);
................................................................................
                                    "couldn't save msg in variable", -1);
                    return TCL_ERROR;
                }
            }
            SetBooleanResult (0);
            return TCL_OK;
        }
        tncdata->status = 0;
        tncdata->idCheck = 1;
        if (tncdata->ids->numEntries) {
            Tcl_DeleteHashTable (tncdata->ids);
            Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
        }
        tncdata->contentStackPtr = 0;
        Tcl_ResetResult (interp);
................................................................................
                    return TCL_ERROR;
                }
            }
            SetBooleanResult (0);
            return TCL_OK;
        }
        model = (TNC_Content *) Tcl_GetHashValue (entryPtr);
        tncdata->status = 0;
        tncdata->idCheck = 0;
        if (tncdata->ids->numEntries) {
            Tcl_DeleteHashTable (tncdata->ids);
            Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
        }
        Tcl_ResetResult (interp);
        result = validateNodeAttributes (tncdata, model->attInfo, node);
................................................................................
 *	None.
 *
 * Side effects:
 *	Frees memory.
 *
 *---------------------------------------------------------------------------- */
static void
FreeTncData (tncdata)
    TNC_Data *tncdata;

{
    Tcl_HashEntry *entryPtr, *attentryPtr;
    Tcl_HashSearch search, attsearch;
    TNC_Content *model;
    TNC_ElemAttInfo *elemAttInfo;
    TNC_EntityInfo *entityInfo;
    TNC_AttDecl *attDecl;
................................................................................
 * Side effects:
 *	Resets the "userData" of the C handler set parser extension.
 *
 *----------------------------------------------------------------------------
 */

void
TncResetProc (interp, userData)
    Tcl_Interp *interp;
    void *userData;

{
    TNC_Data *tncdata = (TNC_Data *) userData;

    FreeTncData (tncdata);
    Tcl_InitHashTable (tncdata->tagNames, TCL_STRING_KEYS);
    tncdata->elemContentsRewriten = 0;
    tncdata->status = 0;
    tncdata->idCheck = 1;
    Tcl_InitHashTable (tncdata->attDefsTables, TCL_STRING_KEYS);
    Tcl_InitHashTable (tncdata->entityDecls, TCL_STRING_KEYS);
    Tcl_InitHashTable (tncdata->notationDecls, TCL_STRING_KEYS);
    Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
    tncdata->doctypeName = NULL;
    tncdata->ignoreWhiteCDATAs = 1;
    tncdata->ignorePCDATA = 0;
    tncdata->contentStackPtr = 0;
}

/*
 *----------------------------------------------------------------------------
 *
................................................................................
{
    TNC_Data *tncdata;
    
    tncdata = (TNC_Data *) MALLOC (sizeof (TNC_Data));
    tncdata->tagNames = (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
    Tcl_InitHashTable (tncdata->tagNames, TCL_STRING_KEYS);
    tncdata->elemContentsRewriten = 0;
    tncdata->status = 0;
    tncdata->idCheck = 1;
    tncdata->attDefsTables = 
        (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
    Tcl_InitHashTable (tncdata->attDefsTables, TCL_STRING_KEYS);
    tncdata->entityDecls = 
        (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
    Tcl_InitHashTable (tncdata->entityDecls, TCL_STRING_KEYS);
................................................................................
        (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
    Tcl_InitHashTable (tncdata->notationDecls, TCL_STRING_KEYS);
    tncdata->ids = (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
    Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
    tncdata->doctypeName = NULL;
    tncdata->interp = interp;
    tncdata->expatObj = expatObj;
    tncdata->ignoreWhiteCDATAs = 1;
    tncdata->ignorePCDATA = 0;
    tncdata->contentStack = (TNC_ContentStack *)
        MALLOC (sizeof (TNC_ContentStack) * TNC_INITCONTENTSTACKSIZE);
    tncdata->contentStackSize = TNC_INITCONTENTSTACKSIZE;
    tncdata->contentStackPtr = 0;
    
    return tncdata;
................................................................................
 * Side effects:
 *	C handler set specific userData gets free'd.
 *
 *----------------------------------------------------------------------------
 */

void
TncFreeProc (interp, userData)
    Tcl_Interp *interp;
    void *userData;

{
    TNC_Data *tncdata = (TNC_Data *) userData;

    FreeTncData (tncdata);
    FREE ((char *) tncdata->tagNames);
    FREE ((char *) tncdata->attDefsTables);
    FREE ((char *) tncdata->entityDecls);
................................................................................
 */

int
TclTncObjCmd(dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *CONST objv[];
{
    char          *method, *cmdName, s[20];
    CHandlerSet   *handlerSet;
    int            methodIndex, result;
    TNC_Data      *tncdata;

    static CONST84 char *tncMethods[] = {
        "enable",  "remove", "getValidateCmd",
        NULL
    };
    enum tncMethod {
        m_enable, m_remove, m_getValidateCmd
    };

    if (!CheckExpatParserObj (interp, objv[1])) {
        SetResult ("First argument has to be a expat parser object");
        return TCL_ERROR;
    }

    method = Tcl_GetStringFromObj (objv[2], NULL);
    if (Tcl_GetIndexFromObj (interp, objv[2], tncMethods, "method", 0,
                             &methodIndex) != TCL_OK)
    {
        return TCL_ERROR;
    }

    switch ((enum tncMethod) methodIndex) {
................................................................................
        }
        handlerSet = CHandlerSetGet (interp, objv[1], "tnc");
        if (!handlerSet) {
            SetResult("expat parser obj hasn't a C handler set named \"tnc\"");
            return TCL_ERROR;
        }
        tncdata = (TNC_Data *) handlerSet->userData;
        if (!tncdata->status) {
            SetResult ("No complete and error free DTD data available.");
            return TCL_ERROR;
        }
        /* After we finished, the validator structure is its own command,
           there isn't a parser cmd anymore. */
        tncdata->expatObj = NULL;
        tncdata->status = 0;
        handlerSet->userData = createTncData (interp, objv[1]);
        if (objc == 4) {
            cmdName = Tcl_GetStringFromObj (objv[3], NULL);
        } else {
            FindUniqueCmdName (interp, s);
            cmdName = s;
        }
................................................................................
 *
 * Side effects:
 *	Defines "tnc" enhancement command for expat parser obj
 *
 *----------------------------------------------------------------------------
 */

#if defined(_MSC_VER)
#  undef TCL_STORAGE_CLASS
#  define TCL_STORAGE_CLASS DLLEXPORT
#endif

EXTERN int
Tnc_Init (interp)
    Tcl_Interp *interp;
................................................................................
    }
#endif
#ifdef USE_TDOM_STUBS
    if (Tdom_InitStubs(interp, "0.8", 0) == NULL) {
        return TCL_ERROR;
    }
#endif
    Tcl_PkgRequire (interp, "tdom", "0.8.0", 0);
    Tcl_CreateObjCommand (interp, "tnc", TclTncObjCmd, NULL, NULL );
    Tcl_PkgProvide (interp, "tnc", PACKAGE_VERSION);
    return TCL_OK;
}








<
<
<
<
<
<
<






|







 







|







 







|







 







|





|







 







|
|
|
>







 







|







 







|
|
|
|
|
|
>







 







|
|
>







 







|
|
|
|
>







 







|
|
>







 







|







 







|
<
|
|
|
|
|
|
|
|
|
>


|




|

|








|







 







|
|







 







|
|
|
|
|
|
>







 







|
|
|
|
>







 







|
|
|
|
|
|
|
>







 







|
|
|
>







 







|







 







|







 







|







 







|









|
|







 







|







 







|
|
|
|
|
|
>










|







 







|
|
|
|
>







 







|







 







|



|



|







 







|
|
>







 







|







 







|
|
|
>










|







 







|



|




|







 







|







 







|
|
|
|
>





|







 







|
|
>







 







|










|





|







 







|









|







 







|







 







|







 







|







 







|
|
>







 







|
|
|
>






|






|







 







|







 







|







 







|
|
|
>







 







|

|




|












<







 







|






|







 







|







 







|





5
6
7
8
9
10
11







12
13
14
15
16
17
18
19
20
21
22
23
24
25
..
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
..
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
...
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
...
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
...
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
...
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
...
556
557
558
559
560
561
562
563

564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
...
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
...
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
...
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
...
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
....
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
....
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
....
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
....
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
....
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
....
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
....
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
....
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
....
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
....
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
....
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
....
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
....
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
....
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
....
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
....
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
....
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
....
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
....
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
....
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
....
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
....
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
....
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
....
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
....
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
....
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
....
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
....
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850

2851
2852
2853
2854
2855
2856
2857
....
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
....
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
....
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991

   Copyright (c) 2001-2003 Rolf Ade */

#include <tdom.h>
#include <string.h>
#include <stdlib.h>








#ifndef TCL_THREADS
# define TDomThreaded(x)
#else
# define TDomThreaded(x) x
#endif

/* The initial stack sizes must be at least 1 */
#define TNC_INITCONTENTSTACKSIZE 512

/*----------------------------------------------------------------------------
|   local globals
|
\---------------------------------------------------------------------------*/
/* Counter to generate unique validateCmd names */
................................................................................
    int           alreadymatched;
} TNC_ContentStack;


typedef struct TNC_data
{
    char             *doctypeName;            /* From DOCTYPE declaration */
    int               skipWhiteCDATAs;        /* Flag: white space allowed in 
                                                 current content model? */
    int               ignorePCDATA;           /* Flag: currently mixed content
                                                 model? */
    Tcl_HashTable    *tagNames;               /* Hash table of all ELEMENT
                                                 declarations of the DTD.
                                                 Element name is the key.
                                                 While parsing, entry points
................................................................................
                                                 the elemAttInfo pointer of
                                                 the current element here for
                                                 DOM validation, to avoid two
                                                 element name lookups. */
    int               elemContentsRewriten;   /* Signals, if the tagNames
                                                 entries point to
                                                 TNC_Contents */
    int               dtdstatus;                 /* While used with expat obj:
                                                 1 after successful parsed
                                                 DTD, 0 otherwise.
                                                 For validateCmd used for
                                                 error report during
                                                 validation: 0 OK, 1 validation
                                                 error. */
    int               idCheck;                /* Flag: check IDREF resolution*/
................................................................................
    TNC_ERROR_UNKNOWN_ELEMENT,
    TNC_ERROR_EMPTY_ELEMENT,
    TNC_ERROR_DISALLOWED_PCDATA,
    TNC_ERROR_DISALLOWED_CDATA,
    TNC_ERROR_NO_DOCTYPE_DECL,
    TNC_ERROR_WRONG_ROOT_ELEMENT,
    TNC_ERROR_NO_ATTRIBUTES,
    TNC_ERROR_UNKNOWN_ATTRIBUTE,
    TNC_ERROR_WRONG_FIXED_ATTVALUE,
    TNC_ERROR_MISSING_REQUIRED_ATTRIBUTE,
    TNC_ERROR_MORE_THAN_ONE_ID_ATT,
    TNC_ERROR_ID_ATT_DEFAULT,
    TNC_ERROR_DUPLICATE_ID_VALUE,
    TNC_ERROR_UNKNOWN_ID_REFERRED,
    TNC_ERROR_ENTITY_ATTRIBUTE,
    TNC_ERROR_ENTITIES_ATTRIBUTE,
    TNC_ERROR_ATT_ENTITY_DEFAULT_MUST_BE_DECLARED,
    TNC_ERROR_NOTATION_REQUIRED,
    TNC_ERROR_NOTATION_MUST_BE_DECLARED,
    TNC_ERROR_IMPOSSIBLE_DEFAULT,
    TNC_ERROR_ENUM_ATT_WRONG_VALUE,
................................................................................

#define SetBooleanResult(i) Tcl_ResetResult(interp); \
                     Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (i))

extern char *Tdom_InitStubs (Tcl_Interp *interp, char *version, int exact);

static void
signalNotValid (
    void        *userData,
    int          code
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;
    TclGenExpatInfo *expat;
    char s[1000];

    if (tncdata->expatObj) {
        expat = GetExpatInfo (tncdata->interp, tncdata->expatObj);
................................................................................
                 XML_GetCurrentLineNumber (expat->parser),
                 XML_GetCurrentColumnNumber (expat->parser),
                 TNC_ErrorString (code));
        expat->status = TCL_ERROR;
        expat->result = Tcl_NewStringObj (s, -1);
        Tcl_IncrRefCount (expat->result);
    } else {
        tncdata->dtdstatus = 1;
        Tcl_SetResult (tncdata->interp, (char *)TNC_ErrorString (code),
                       TCL_VOLATILE);
    }
}

/*
 *----------------------------------------------------------------------------
................................................................................
 * Side effects:
 *	Stores the doctype Name in the TNC_data.
 *
 *----------------------------------------------------------------------------
 */

void
TncStartDoctypeDeclHandler (
    void       *userData,
    const char *doctypeName,
    const char *sysid,
    const char *pubid,
    int         has_internal_subset
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;

#ifdef TNC_DEBUG
    printf ("TncStartDoctypeDeclHandler start\n");
#endif
    tncdata->doctypeName = tdomstrdup (doctypeName);
................................................................................
 * Side effects:
 *	Frees memory.
 *
 *----------------------------------------------------------------------------
 */

static void
TncFreeTncModel (
    TNC_Content *tmodel
)
{
    unsigned int i;

    if (tmodel->children) {
        for (i = 0; i < tmodel->numchildren; i++) {
            TncFreeTncModel (&tmodel->children[i]);
        }
................................................................................
 * Side effects:
 *	Allocates memory for the TNC_Content models.
 *
 *----------------------------------------------------------------------------
 */

static void
TncRewriteModel (
    XML_Content   *emodel,
    TNC_Content   *tmodel,
    Tcl_HashTable *tagNames
)
{
    Tcl_HashEntry *entryPtr;
    unsigned int i;

    tmodel->type = emodel->type;
    tmodel->quant = emodel->quant;
    tmodel->numchildren = emodel->numchildren;
................................................................................
 *	Rewrites the XML_Content models to TNC_Content
 *      models.
 *
 *----------------------------------------------------------------------------
 */

void
TncEndDoctypeDeclHandler (
    void *userData
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr, *ePtr1;
    Tcl_HashSearch search;
    XML_Content   *emodel;
    TNC_Content   *tmodel = NULL;
    char *elementName;
................................................................................
        if (!Tcl_GetHashValue (entryPtr)) {
            signalNotValid (userData,
                            TNC_ERROR_ATT_ENTITY_DEFAULT_MUST_BE_DECLARED);
            return;
        }
        entryPtr = Tcl_NextHashEntry (&search);
    }
    tncdata->dtdstatus = 1;
}


/*
 *----------------------------------------------------------------------------
 *
 * TncEntityDeclHandler --
................................................................................
 *	Stores either the name of the entity and
 *      type information in a lookup table.
 *
 *----------------------------------------------------------------------------
 */

void
TncEntityDeclHandler (

    void *userData,
    const char *entityName,
    int is_parameter_entity,
    const char *value,
    int value_length,
    const char *base,
    const char *systemId,
    const char *publicId,
    const char *notationName
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr;
    int newPtr;
    TNC_EntityInfo *entityInfo;


    /* expat collects entity definitions internaly by itself. So this is
       maybe superfluous, if it possible to access the expat internal
       representation. To study this is left to the reader. */

    if (is_parameter_entity) return;
    entryPtr = Tcl_CreateHashEntry (tncdata->entityDecls, entityName, &newPtr);
    /* multiple declaration of the same entity are allowed; first
       definition wins (rec. 4.2) */
    if (!newPtr) {
        /* Eventually, an attribute declaration with type ENTITY or ENTITIES
           has used this (up to the attribute declaration undeclared) ENTITY
           within his default value. In this case, the hash value has to
           be NULL and the entity must be a unparsed entity. */
        if (!Tcl_GetHashValue (entryPtr)) {
            if (notationName == NULL) {
                signalNotValid (userData,
                                TNC_ERROR_ATT_ENTITY_DEFAULT_MUST_BE_DECLARED);
                return;
            }
................................................................................
            newPtr = 1;
        }
    }
    if (newPtr) {
        entityInfo = (TNC_EntityInfo *) MALLOC (sizeof (TNC_EntityInfo));
        if (notationName != NULL) {
            entityInfo->is_notation = 1;
            Tcl_CreateHashEntry (tncdata->notationDecls,
                                 notationName, &newPtr);
            entityInfo->notationName = tdomstrdup (notationName);
        }
        else {
            entityInfo->is_notation = 0;
        }
        Tcl_SetHashValue (entryPtr, entityInfo);
    }
................................................................................
 *	Stores the notationName in the notationDecls table with value
 *      one.
 *
 *----------------------------------------------------------------------------
 */

void
TncNotationDeclHandler (
    void       *userData,
    const char *notationName,
    const char *base,
    const char *systemId,
    const char *publicId
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr;
    int newPtr;

    entryPtr = Tcl_CreateHashEntry (tncdata->notationDecls,
                                    notationName,
................................................................................
 * Side effects:
 *	Stores the tag name of the element in a lookup table.
 *
 *----------------------------------------------------------------------------
 */

void
TncElementDeclCommand (
    void *userData,
    const char *name,
    XML_Content *model
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr;
    int newPtr;
    unsigned int i, j;

    entryPtr = Tcl_CreateHashEntry (tncdata->tagNames, name, &newPtr);
................................................................................
 * Side effects:
 *	Stores the tag name of the element in a lookup table.
 *
 *----------------------------------------------------------------------------
 */

void
TncAttDeclCommand (
    void       *userData,
    const char *elname,
    const char *attname,
    const char *att_type,
    const char *dflt,
    int         isrequired
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr, *entryPtr1;
    Tcl_HashTable *elemAtts;
    TNC_ElemAttInfo *elemAttInfo;
    TNC_AttDecl *attDecl;
    TNC_EntityInfo *entityInfo;
................................................................................
 *	Eventually pushes data to the contentStack (even in
 *      recurive calls).
 *
 *----------------------------------------------------------------------------
 */

static int
TncProbeElement (
    TNC_NameId *nameId,
    TNC_Data   *tncdata
)
{
    TNC_ContentStack *stackelm;
    TNC_Content *activeModel;
    int myStackPtr, zeroMatchPossible, result;
    unsigned int i, seqstartindex;

#ifdef TNC_DEBUG
................................................................................
            if (stackelm->model->quant == XML_CQUANT_NONE ||
                stackelm->model->quant == XML_CQUANT_OPT) {
                /*The child cp's type SEQ or CHOICE keep track by
                  themselve about if they are repeated. Because we are
                  here, they don't.  Since the current cp has already
                  matched and isn't multiple, the current cp as a whole
                  is done.  But no contradiction detected, so return
                  "search further" */
                return -1;
            }
        }

        /* If one of the alternatives within the CHOICE cp is quant
           REP or OPT, it isn't a contradition to the document structure,
           if the cp doesn't match, even if it is quant
................................................................................
                   have a candidat for "zero match". */
                if (result == -1) {
                    zeroMatchPossible = 1;
                }
                tncdata->contentStackPtr--;
            }
        }
        /* OK, nobody has claimed a match. Question is: try further or is
           this a document structure error. */
        if (zeroMatchPossible ||
            stackelm->alreadymatched ||
            stackelm->model->quant == XML_CQUANT_REP ||
            stackelm->model->quant == XML_CQUANT_OPT) {
            return -1;
        }
................................................................................
                    break;
                }
            }
        }
        if (!stackelm->alreadymatched) {
            if (zeroMatchPossible) {
                /* The stackelm hasn't matched, but don't have to
                   after all.  Return try further */
                return -1;
            } else {
                /* No previous match, but at least one child is
                   necessary. Return depends of the quant of the
                   entire seq */
                if (stackelm->model->quant == XML_CQUANT_NONE ||
                    stackelm->model->quant == XML_CQUANT_PLUS) {
................................................................................
                   child later. Error in document structure. */
                return 0;
            } else {
                /* OK, SEQ has matched befor. But after the last match, there
                   where no required (quant NONE or PLUS) childs. */
                if (stackelm->model->quant == XML_CQUANT_NONE ||
                    stackelm->model->quant == XML_CQUANT_OPT) {
                    /* The entire seq isn't multiple. Just look further. */
                    return -1;
                }
            }
        }
        /* The last untreated case is alreadymatched true,
           zeroMatchPossible (of the rest of the seq childs after the
           last match) true and the entire seq may be
           multiple. Therefore start again with activeChild = 0, to
           see, if the current nameId starts a repeated match of the
           seq.  By the way: zeroMatchPossible still has initial value
           1, therefor no second initialiation is needed */
        for (i = 0; i < seqstartindex; i++) {
            if ((&stackelm->model->children[i])->type == XML_CTYPE_NAME) {
                if ((&stackelm->model->children[i])->nameId == nameId) {
#ifdef TNC_DEBUG
                    printf ("-->matched! child Nr. %d\n",i);
#endif
                    (&tncdata->contentStack[myStackPtr])->activeChild = i;
................................................................................
        }
        /* seq doesn't match again and every seq child from the very first
           up to (not including) the last match aren't required. This last
           fact may be nice to know, but after all since the entire seq have
           matched already ... */
        return -1;
    case XML_CTYPE_NAME:
        /* NAME type doesn't occur at top level of a content model and is
           handled in some "shotcut" way directly in the CHOICE and SEQ cases.
           It's only here to pacify gcc -Wall. */
        printf ("error!!! - in TncProbeElement: XML_CTYPE_NAME shouldn't reached in any case.\n");
    default:
        printf ("error!!! - in TncProbeElement: unknown content type: %d\n",
                stackelm->model->type);
    }
................................................................................
 * Side effects:
 *	Eventually increments the required attributes counter.
 *
 *----------------------------------------------------------------------------
 */

static int
TncProbeAttribute (
    void *userData,
    Tcl_HashTable *elemAtts,
    char *attrName,
    char *attrValue,
    int *nrOfreq
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr;
    TNC_AttDecl *attDecl;
    char *pc, *copy, save;
    int clen, i, start, hnew;
    TNC_EntityInfo *entityInfo;

    entryPtr = Tcl_FindHashEntry (elemAtts, attrName);
    if (!entryPtr) {
        signalNotValid (userData, TNC_ERROR_UNKNOWN_ATTRIBUTE);
        return 0;
    }
    /* NOTE: attribute uniqueness per element is a wellformed
               constrain and therefor done by expat. */
    attDecl = (TNC_AttDecl *) Tcl_GetHashValue (entryPtr);
    switch (attDecl->att_type) {
    case TNC_ATTTYPE_CDATA:
................................................................................
 * Side effects:
 *	Eventually signals application error.
 *
 *----------------------------------------------------------------------------
 */

void
TncElementStartCommand (
    void *userData,
    const char *name,
    const char **atts
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr;
    Tcl_HashTable *elemAtts;
    const char **atPtr;
    TNC_ElemAttInfo *elemAttInfo;
    TNC_Content *model;
................................................................................
#endif

    /* If the document doesn't have a doctype declaration, but the
       user have used the -useForeignDTD 1 feature, the collected
       data out of the provided DTD isn't postprocessed by 
       TncElementStartCommand. We do this now.
       NOTE: Since there wasn't a doctype declaration, there is no
       information available which element is expected to be the
       document element. Eventually it would be desirable, to set
       this somehow. For now, this means, that every valid subtree
       of the given DTD information is accepted.  */
    if (!tncdata->contentStackPtr && !tncdata->elemContentsRewriten) {
        TncEndDoctypeDeclHandler (userData);
        acceptNoDoctype = 1;
    }
................................................................................
        return;
    }
    model = (TNC_Content *) Tcl_GetHashValue (entryPtr);

    switch (model->type) {
    case XML_CTYPE_MIXED:
    case XML_CTYPE_ANY:
        tncdata->skipWhiteCDATAs = 1;
        tncdata->ignorePCDATA = 1;
        break;
    case XML_CTYPE_EMPTY:
        tncdata->skipWhiteCDATAs = 0;
        break;
    case XML_CTYPE_CHOICE:
    case XML_CTYPE_SEQ:
        tncdata->skipWhiteCDATAs = 1;
        tncdata->ignorePCDATA = 0;
        break;
    case XML_CTYPE_NAME:
        break;
    }

    if (tncdata->contentStackPtr) {
................................................................................
 *	Let the contentStackPtr point to the last current content
 *      model before the element had started.
 *
 *----------------------------------------------------------------------------
 */

static int
TncProbeElementEnd (
    TNC_Data *tncdata
)
{
    TNC_ContentStack stackelm;
    unsigned int i;
    int zeroMatchPossible, seqstartindex;

    stackelm = tncdata->contentStack[tncdata->contentStackPtr - 1];
    switch (stackelm.model->type) {
................................................................................
                    tncdata->contentStackPtr--;
                    return 0;
                }
            }
        }
        return 1;
    case XML_CTYPE_NAME:
        /* NAME type doesn't occur at top level of a content model and is
           handled in some "shotcut" way directly in the CHOICE and SEQ cases.
           It's only here to pacify gcc -Wall. */
        fprintf (stderr, "error!!! - in TncProbeElementEnd: XML_CTYPE_NAME "
                 "shouldn't be reached in any case.\n");
    default:
        fprintf (stderr, "error!!! - in TncProbeElementEnd: unknown content "
                 "type: %d\n", stackelm.model->type);
................................................................................
 * Side effects:
 *	Eventually signals application error.
 *
 *----------------------------------------------------------------------------
 */

void
TncElementEndCommand (
    void       *userData,
    const char *name
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;

#ifdef TNC_DEBUG
    printf ("TncElementEndCommand start\n");
    printContentStack (tncdata);
#endif
    while (1) {
        if (!TncProbeElementEnd (tncdata)) {
            signalNotValid (userData, TNC_ERROR_ELEMENT_CAN_NOT_END_HERE);
            return;
        }
        if (tncdata->contentStack[tncdata->contentStackPtr - 1].deep == 0) {
            break;
        }
        tncdata->contentStackPtr--;
................................................................................
    printf ("after removing ended element from the stack\n");
    printContentStack (tncdata);
#endif
    if (tncdata->contentStackPtr) {
        switch ((&tncdata->contentStack[tncdata->contentStackPtr - 1])->model->type) {
        case XML_CTYPE_MIXED:
        case XML_CTYPE_ANY:
            tncdata->skipWhiteCDATAs = 1;
            tncdata->ignorePCDATA = 1;
            break;
        case XML_CTYPE_EMPTY:
            tncdata->skipWhiteCDATAs = 0;
            break;
        case XML_CTYPE_CHOICE:
        case XML_CTYPE_SEQ:
        case XML_CTYPE_NAME:
            tncdata->skipWhiteCDATAs = 1;
            tncdata->ignorePCDATA = 0;
            break;
        }
    } else {
        /* This means, the root element is closed,
           therefor the place to check, if every IDREF points
           to a ID. */
................................................................................
                 entryPtr = Tcl_NextHashEntry (&search)) {
#ifdef TNC_DEBUG
                printf ("check id value %s\n",
                        Tcl_GetHashKey (tncdata->ids, entryPtr));
                printf ("value %p\n", Tcl_GetHashValue (entryPtr));
#endif
                if (!Tcl_GetHashValue (entryPtr)) {
                    signalNotValid (userData, TNC_ERROR_UNKNOWN_ID_REFERRED);
                return;
                }
            }
        }
    }
}

................................................................................
 * Side effects:
 *	Eventually signals application error.
 *
 *----------------------------------------------------------------------------
 */

void
TncCharacterdataCommand (
    void       *userData,
    const char *data,
    int         len
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;
    int i;
    char *pc;

    if (!tncdata->skipWhiteCDATAs && len > 0) {
        signalNotValid (userData, TNC_ERROR_EMPTY_ELEMENT);
        return;
    }
    if (!tncdata->ignorePCDATA) {
        for (i = 0, pc = (char*)data; i < len; i++, pc++) {
            if ( (*pc == ' ')  ||
                 (*pc == '\n') ||
................................................................................
 * Side effects:
 *	Eventually signals application error.
 *
 *----------------------------------------------------------------------------
 */

void
TncStartCdataSectionHandler (
    void *userData
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;

    if (!tncdata->ignorePCDATA) {
        signalNotValid (userData, TNC_ERROR_DISALLOWED_CDATA);
    }
}
................................................................................
    )
{
    domNode       *child;

    switch (node->nodeType) {
    case ELEMENT_NODE:
        TncElementStartCommand (tncdata, node->nodeName, NULL);
        if (tncdata->dtdstatus) return 0;
        if (!validateNodeAttributes (tncdata, tncdata->elemAttInfo, node)) 
            return 0;
        if (node->firstChild) {
            child = node->firstChild;
            while (child) {
                if (!validateTree (tncdata, child)) return 0;
                child = child->nextSibling;
            }
        }
        TncElementEndCommand (tncdata, node->nodeName);
        if (tncdata->dtdstatus) return 0;
        break;
    case TEXT_NODE:
    case CDATA_SECTION_NODE:
        TncCharacterdataCommand (tncdata, ((domTextNode*)node)->nodeValue, 
                                 ((domTextNode*)node)->valueLength);
        if (tncdata->dtdstatus) return 0;
        break;
    case COMMENT_NODE:
    case PROCESSING_INSTRUCTION_NODE:
        break;
    default:
        signalNotValid (tncdata, TNC_ERROR_UNKNOWN_NODE_TYPE);
        return 0;
................................................................................
 */

static int
tnc_ValidateObjCmd (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *const objv[]
    )
{
    TNC_Data        *tncdata = (TNC_Data*) clientData;
    int              methodIndex, result = 1;
    domNode         *node;
    char            *errMsg = NULL;
    Tcl_HashEntry   *entryPtr;
    TNC_Content     *model;
    
    static const char *validateMethods[] = {
        "validateTree",   "validateDocument", "validateAttributes",
        "delete",
        NULL
    };
    enum validateMethod {
        m_validateTree, m_validateDocument, m_validateAttributes,
        m_delete
................................................................................
        node = tcldom_getNodeFromName (
            interp, Tcl_GetStringFromObj(objv[2], NULL), &errMsg
            );
        if (!node || (node->nodeType != ELEMENT_NODE)) {
            SetResult ("The validateTree method needs a domNode as argument.");
            return TCL_ERROR;
        }
        tncdata->dtdstatus = 0;
        tncdata->idCheck = 0;
        if (tncdata->ids->numEntries) {
            Tcl_DeleteHashTable (tncdata->ids);
            Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
        }
        tncdata->contentStackPtr = 0;
        Tcl_ResetResult (interp);
................................................................................
                                    "couldn't save msg in variable", -1);
                    return TCL_ERROR;
                }
            }
            SetBooleanResult (0);
            return TCL_OK;
        }
        tncdata->dtdstatus = 0;
        tncdata->idCheck = 1;
        if (tncdata->ids->numEntries) {
            Tcl_DeleteHashTable (tncdata->ids);
            Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
        }
        tncdata->contentStackPtr = 0;
        Tcl_ResetResult (interp);
................................................................................
                    return TCL_ERROR;
                }
            }
            SetBooleanResult (0);
            return TCL_OK;
        }
        model = (TNC_Content *) Tcl_GetHashValue (entryPtr);
        tncdata->dtdstatus = 0;
        tncdata->idCheck = 0;
        if (tncdata->ids->numEntries) {
            Tcl_DeleteHashTable (tncdata->ids);
            Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
        }
        Tcl_ResetResult (interp);
        result = validateNodeAttributes (tncdata, model->attInfo, node);
................................................................................
 *	None.
 *
 * Side effects:
 *	Frees memory.
 *
 *---------------------------------------------------------------------------- */
static void
FreeTncData (
    TNC_Data *tncdata
)
{
    Tcl_HashEntry *entryPtr, *attentryPtr;
    Tcl_HashSearch search, attsearch;
    TNC_Content *model;
    TNC_ElemAttInfo *elemAttInfo;
    TNC_EntityInfo *entityInfo;
    TNC_AttDecl *attDecl;
................................................................................
 * Side effects:
 *	Resets the "userData" of the C handler set parser extension.
 *
 *----------------------------------------------------------------------------
 */

void
TncResetProc (
    Tcl_Interp *interp,
    void *userData
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;

    FreeTncData (tncdata);
    Tcl_InitHashTable (tncdata->tagNames, TCL_STRING_KEYS);
    tncdata->elemContentsRewriten = 0;
    tncdata->dtdstatus = 0;
    tncdata->idCheck = 1;
    Tcl_InitHashTable (tncdata->attDefsTables, TCL_STRING_KEYS);
    Tcl_InitHashTable (tncdata->entityDecls, TCL_STRING_KEYS);
    Tcl_InitHashTable (tncdata->notationDecls, TCL_STRING_KEYS);
    Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
    tncdata->doctypeName = NULL;
    tncdata->skipWhiteCDATAs = 1;
    tncdata->ignorePCDATA = 0;
    tncdata->contentStackPtr = 0;
}

/*
 *----------------------------------------------------------------------------
 *
................................................................................
{
    TNC_Data *tncdata;
    
    tncdata = (TNC_Data *) MALLOC (sizeof (TNC_Data));
    tncdata->tagNames = (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
    Tcl_InitHashTable (tncdata->tagNames, TCL_STRING_KEYS);
    tncdata->elemContentsRewriten = 0;
    tncdata->dtdstatus = 0;
    tncdata->idCheck = 1;
    tncdata->attDefsTables = 
        (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
    Tcl_InitHashTable (tncdata->attDefsTables, TCL_STRING_KEYS);
    tncdata->entityDecls = 
        (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
    Tcl_InitHashTable (tncdata->entityDecls, TCL_STRING_KEYS);
................................................................................
        (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
    Tcl_InitHashTable (tncdata->notationDecls, TCL_STRING_KEYS);
    tncdata->ids = (Tcl_HashTable *) MALLOC (sizeof (Tcl_HashTable));
    Tcl_InitHashTable (tncdata->ids, TCL_STRING_KEYS);
    tncdata->doctypeName = NULL;
    tncdata->interp = interp;
    tncdata->expatObj = expatObj;
    tncdata->skipWhiteCDATAs = 1;
    tncdata->ignorePCDATA = 0;
    tncdata->contentStack = (TNC_ContentStack *)
        MALLOC (sizeof (TNC_ContentStack) * TNC_INITCONTENTSTACKSIZE);
    tncdata->contentStackSize = TNC_INITCONTENTSTACKSIZE;
    tncdata->contentStackPtr = 0;
    
    return tncdata;
................................................................................
 * Side effects:
 *	C handler set specific userData gets free'd.
 *
 *----------------------------------------------------------------------------
 */

void
TncFreeProc (
    Tcl_Interp *interp,
    void *userData
)
{
    TNC_Data *tncdata = (TNC_Data *) userData;

    FreeTncData (tncdata);
    FREE ((char *) tncdata->tagNames);
    FREE ((char *) tncdata->attDefsTables);
    FREE ((char *) tncdata->entityDecls);
................................................................................
 */

int
TclTncObjCmd(dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *const objv[];
{
    char          *cmdName, s[20];
    CHandlerSet   *handlerSet;
    int            methodIndex, result;
    TNC_Data      *tncdata;

    static const char *tncMethods[] = {
        "enable",  "remove", "getValidateCmd",
        NULL
    };
    enum tncMethod {
        m_enable, m_remove, m_getValidateCmd
    };

    if (!CheckExpatParserObj (interp, objv[1])) {
        SetResult ("First argument has to be a expat parser object");
        return TCL_ERROR;
    }


    if (Tcl_GetIndexFromObj (interp, objv[2], tncMethods, "method", 0,
                             &methodIndex) != TCL_OK)
    {
        return TCL_ERROR;
    }

    switch ((enum tncMethod) methodIndex) {
................................................................................
        }
        handlerSet = CHandlerSetGet (interp, objv[1], "tnc");
        if (!handlerSet) {
            SetResult("expat parser obj hasn't a C handler set named \"tnc\"");
            return TCL_ERROR;
        }
        tncdata = (TNC_Data *) handlerSet->userData;
        if (!tncdata->dtdstatus) {
            SetResult ("No complete and error free DTD data available.");
            return TCL_ERROR;
        }
        /* After we finished, the validator structure is its own command,
           there isn't a parser cmd anymore. */
        tncdata->expatObj = NULL;
        tncdata->dtdstatus = 0;
        handlerSet->userData = createTncData (interp, objv[1]);
        if (objc == 4) {
            cmdName = Tcl_GetStringFromObj (objv[3], NULL);
        } else {
            FindUniqueCmdName (interp, s);
            cmdName = s;
        }
................................................................................
 *
 * Side effects:
 *	Defines "tnc" enhancement command for expat parser obj
 *
 *----------------------------------------------------------------------------
 */

#if defined(_MSC_VER) || defined(__MINGW32__) 
#  undef TCL_STORAGE_CLASS
#  define TCL_STORAGE_CLASS DLLEXPORT
#endif

EXTERN int
Tnc_Init (interp)
    Tcl_Interp *interp;
................................................................................
    }
#endif
#ifdef USE_TDOM_STUBS
    if (Tdom_InitStubs(interp, "0.8", 0) == NULL) {
        return TCL_ERROR;
    }
#endif
    Tcl_PkgRequire (interp, "tdom", NULL, 0);
    Tcl_CreateObjCommand (interp, "tnc", TclTncObjCmd, NULL, NULL );
    Tcl_PkgProvide (interp, "tnc", PACKAGE_VERSION);
    return TCL_OK;
}

Added extensions/tnc/win/makefile.vc.











































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#------------------------------------------------------------- -*- makefile -*-
#
# Makefile for tnc
#
# Basic build, test and install
#   nmake /f makefile.vc INSTALLDIR=c:\tcl
#   nmake /f makefile.vc INSTALLDIR=c:\tcl test
#   nmake /f makefile.vc INSTALLDIR=c:\tcl install
#
# For other build options (debug, static etc.),
# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
# detailed documentation.
# 
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
#------------------------------------------------------------------------------


PROJECT = tnc
!include "rules-ext.vc"

PRJ_OBJS = $(TMP_DIR)\tnc.obj

!if [echo TDOM_DOTVERSION = \> versions.vc] \
   || [nmakehlp -V ..\..\..\configure.in ^[tdom^] >> versions.vc]
!error *** Could not figure out tdom version.
!endif
!include versions.vc
TDOMVER             = $(TDOM_DOTVERSION:.=)

# tdom root
TDOMROOT            = ..\..\..

PRJ_DEFINES = -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE \
	-DHAVE_MEMMOVE=1 -DXML_DTD=1 -DXML_NS=1 -DTDOM_NO_UNKNOWN_CMD=1 \
!if !$(STATIC_BUILD)
	-DUSE_TDOM_STUBS
!endif

TDOMLIBPATH    = "$(TDOMROOT)\win\$(BUILDDIRTOP)"

PRJ_INCLUDES = -I$(TDOMROOT)\generic -I$(TDOMROOT)\expat

TNCDIR         = $(TDOMROOT)\extensions\tnc

!if !$(STATIC_BUILD)
PRJ_LIBS  = $(TDOMLIBPATH)\tdomstub$(TDOMVER).lib
!endif

!include "$(_RULESDIR)\targets.vc"
pkgindex: default-pkgindex

Added extensions/tnc/win/nmakehlp.c.





























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
/*
 * ----------------------------------------------------------------------------
 * nmakehlp.c --
 *
 *	This is used to fix limitations within nmake and the environment.
 *
 * Copyright (c) 2002 by David Gravereaux.
 * Copyright (c) 2006 by Pat Thoyts
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * ----------------------------------------------------------------------------
 */

#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#define NO_SHLWAPI_GDI
#define NO_SHLWAPI_STREAM
#define NO_SHLWAPI_REG
#include <shlwapi.h>
#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
#pragma comment (lib, "shlwapi.lib")
#include <stdio.h>
#include <math.h>

/*
 * This library is required for x64 builds with _some_ versions of MSVC
 */
#if defined(_M_IA64) || defined(_M_AMD64)
#if _MSC_VER >= 1400 && _MSC_VER < 1500
#pragma comment(lib, "bufferoverflowU")
#endif
#endif

/* ISO hack for dumb VC++ */
#ifdef _MSC_VER
#define   snprintf	_snprintf
#endif


/* protos */

static int CheckForCompilerFeature(const char *option);
static int CheckForLinkerFeature(const char **options, int count);
static int IsIn(const char *string, const char *substring);
static int SubstituteFile(const char *substs, const char *filename);
static int QualifyPath(const char *path);
static int LocateDependency(const char *keyfile);
static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
static DWORD WINAPI ReadFromPipe(LPVOID args);

/* globals */

#define CHUNK	25
#define STATICBUFFERSIZE    1000
typedef struct {
    HANDLE pipe;
    char buffer[STATICBUFFERSIZE];
} pipeinfo;

pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
 
/*
 * exitcodes: 0 == no, 1 == yes, 2 == error
 */

int
main(
    int argc,
    char *argv[])
{
    char msg[300];
    DWORD dwWritten;
    int chars;
    char *s;

    /*
     * Make sure children (cl.exe and link.exe) are kept quiet.
     */

    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);

    /*
     * Make sure the compiler and linker aren't effected by the outside world.
     */

    SetEnvironmentVariable("CL", "");
    SetEnvironmentVariable("LINK", "");

    if (argc > 1 && *argv[1] == '-') {
	switch (*(argv[1]+1)) {
	case 'c':
	    if (argc != 3) {
		chars = snprintf(msg, sizeof(msg) - 1,
		        "usage: %s -c <compiler option>\n"
			"Tests for whether cl.exe supports an option\n"
			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
			&dwWritten, NULL);
		return 2;
	    }
	    return CheckForCompilerFeature(argv[2]);
	case 'l':
	    if (argc < 3) {
		chars = snprintf(msg, sizeof(msg) - 1,
	       		"usage: %s -l <linker option> ?<mandatory option> ...?\n"
			"Tests for whether link.exe supports an option\n"
			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
			&dwWritten, NULL);
		return 2;
	    }
	    return CheckForLinkerFeature(&argv[2], argc-2);
	case 'f':
	    if (argc == 2) {
		chars = snprintf(msg, sizeof(msg) - 1,
			"usage: %s -f <string> <substring>\n"
			"Find a substring within another\n"
			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
			&dwWritten, NULL);
		return 2;
	    } else if (argc == 3) {
		/*
		 * If the string is blank, there is no match.
		 */

		return 0;
	    } else {
		return IsIn(argv[2], argv[3]);
	    }
	case 's':
	    if (argc == 2) {
		chars = snprintf(msg, sizeof(msg) - 1,
			"usage: %s -s <substitutions file> <file>\n"
			"Perform a set of string map type substutitions on a file\n"
			"exitcodes: 0\n",
			argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
			&dwWritten, NULL);
		return 2;
	    }
	    return SubstituteFile(argv[2], argv[3]);
	case 'V':
	    if (argc != 4) {
		chars = snprintf(msg, sizeof(msg) - 1,
		    "usage: %s -V filename matchstring\n"
		    "Extract a version from a file:\n"
		    "eg: pkgIndex.tcl \"package ifneeded http\"",
		    argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
		    &dwWritten, NULL);
		return 0;
	    }
	    s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
	    if (s && *s) {
		printf("%s\n", s);
		return 0;
	    } else
		return 1; /* Version not found. Return non-0 exit code */

	case 'Q':
	    if (argc != 3) {
		chars = snprintf(msg, sizeof(msg) - 1,
		    "usage: %s -Q path\n"
		    "Emit the fully qualified path\n"
		    "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
		    &dwWritten, NULL);
		return 2;
	    }
	    return QualifyPath(argv[2]);

	case 'L':
	    if (argc != 3) {
		chars = snprintf(msg, sizeof(msg) - 1,
		    "usage: %s -L keypath\n"
		    "Emit the fully qualified path of directory containing keypath\n"
		    "exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
		    &dwWritten, NULL);
		return 2;
	    }
	    return LocateDependency(argv[2]);
	}
    }
    chars = snprintf(msg, sizeof(msg) - 1,
	    "usage: %s -c|-f|-l|-Q|-s|-V ...\n"
	    "This is a little helper app to equalize shell differences between WinNT and\n"
	    "Win9x and get nmake.exe to accomplish its job.\n",
	    argv[0]);
    WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
    return 2;
}
 
static int
CheckForCompilerFeature(
    const char *option)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];
    char cmdline[100];

    hProcess = GetCurrentProcess();

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
    si.hStdInput = INVALID_HANDLE_VALUE;

    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = FALSE;

    /*
     * Create a non-inheritible pipe.
     */

    CreatePipe(&Out.pipe, &h, &sa, 0);

    /*
     * Dupe the write side, make it inheritible, and close the original.
     */

    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Same as above, but for the error side.
     */

    CreatePipe(&Err.pipe, &h, &sa, 0);
    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Base command line.
     */

    lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");

    /*
     * Append our option for testing
     */

    lstrcat(cmdline, option);

    /*
     * Filename to compile, which exists, but is nothing and empty.
     */

    lstrcat(cmdline, " .\\nul");

    ok = CreateProcess(
	    NULL,	    /* Module name. */
	    cmdline,	    /* Command line. */
	    NULL,	    /* Process handle not inheritable. */
	    NULL,	    /* Thread handle not inheritable. */
	    TRUE,	    /* yes, inherit handles. */
	    DETACHED_PROCESS, /* No console for you. */
	    NULL,	    /* Use parent's environment block. */
	    NULL,	    /* Use parent's starting directory. */
	    &si,	    /* Pointer to STARTUPINFO structure. */
	    &pi);	    /* Pointer to PROCESS_INFORMATION structure. */

    if (!ok) {
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.
     */

    CloseHandle(si.hStdOutput);
    CloseHandle(si.hStdError);

    WaitForInputIdle(pi.hProcess, 5000);
    CloseHandle(pi.hThread);

    /*
     * Start the pipe reader threads.
     */

    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);

    /*
     * Block waiting for the process to end.
     */

    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);

    /*
     * Wait for our pipe to get done reading, should it be a little slow.
     */

    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
    CloseHandle(pipeThreads[0]);
    CloseHandle(pipeThreads[1]);

    /*
     * Look for the commandline warning code in both streams.
     *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
     */

    return !(strstr(Out.buffer, "D4002") != NULL
             || strstr(Err.buffer, "D4002") != NULL
             || strstr(Out.buffer, "D9002") != NULL
             || strstr(Err.buffer, "D9002") != NULL
             || strstr(Out.buffer, "D2021") != NULL
             || strstr(Err.buffer, "D2021") != NULL);
}
 
static int
CheckForLinkerFeature(
    const char **options,
    int count)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];
    int i;
    char cmdline[255];

    hProcess = GetCurrentProcess();

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
    si.hStdInput = INVALID_HANDLE_VALUE;

    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    /*
     * Create a non-inheritible pipe.
     */

    CreatePipe(&Out.pipe, &h, &sa, 0);

    /*
     * Dupe the write side, make it inheritible, and close the original.
     */

    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Same as above, but for the error side.
     */

    CreatePipe(&Err.pipe, &h, &sa, 0);
    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Base command line.
     */

    lstrcpy(cmdline, "link.exe -nologo ");

    /*
     * Append our option for testing.
     */

    for (i = 0; i < count; i++) {
	lstrcat(cmdline, " \"");
	lstrcat(cmdline, options[i]);
	lstrcat(cmdline, "\"");
    }

    ok = CreateProcess(
	    NULL,	    /* Module name. */
	    cmdline,	    /* Command line. */
	    NULL,	    /* Process handle not inheritable. */
	    NULL,	    /* Thread handle not inheritable. */
	    TRUE,	    /* yes, inherit handles. */
	    DETACHED_PROCESS, /* No console for you. */
	    NULL,	    /* Use parent's environment block. */
	    NULL,	    /* Use parent's starting directory. */
	    &si,	    /* Pointer to STARTUPINFO structure. */
	    &pi);	    /* Pointer to PROCESS_INFORMATION structure. */

    if (!ok) {
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.
     */

    CloseHandle(si.hStdOutput);
    CloseHandle(si.hStdError);

    WaitForInputIdle(pi.hProcess, 5000);
    CloseHandle(pi.hThread);

    /*
     * Start the pipe reader threads.
     */

    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);

    /*
     * Block waiting for the process to end.
     */

    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);

    /*
     * Wait for our pipe to get done reading, should it be a little slow.
     */

    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
    CloseHandle(pipeThreads[0]);
    CloseHandle(pipeThreads[1]);

    /*
     * Look for the commandline warning code in the stderr stream.
     */

    return !(strstr(Out.buffer, "LNK1117") != NULL ||
	    strstr(Err.buffer, "LNK1117") != NULL ||
	    strstr(Out.buffer, "LNK4044") != NULL ||
	    strstr(Err.buffer, "LNK4044") != NULL ||
	    strstr(Out.buffer, "LNK4224") != NULL ||
	    strstr(Err.buffer, "LNK4224") != NULL);
}
 
static DWORD WINAPI
ReadFromPipe(
    LPVOID args)
{
    pipeinfo *pi = (pipeinfo *) args;
    char *lastBuf = pi->buffer;
    DWORD dwRead;
    BOOL ok;

  again:
    if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
	CloseHandle(pi->pipe);
	return (DWORD)-1;
    }
    ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
    if (!ok || dwRead == 0) {
	CloseHandle(pi->pipe);
	return 0;
    }
    lastBuf += dwRead;
    goto again;

    return 0;  /* makes the compiler happy */
}
 
static int
IsIn(
    const char *string,
    const char *substring)
{
    return (strstr(string, substring) != NULL);
}
 
/*
 * GetVersionFromFile --
 * 	Looks for a match string in a file and then returns the version
 * 	following the match where a version is anything acceptable to
 * 	package provide or package ifneeded.
 */

static const char *
GetVersionFromFile(
    const char *filename,
    const char *match,
    int numdots)
{
    size_t cbBuffer = 100;
    static char szBuffer[100];
    char *szResult = NULL;
    FILE *fp = fopen(filename, "rt");

    if (fp != NULL) {
	/*
	 * Read data until we see our match string.
	 */

	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
	    LPSTR p, q;

	    p = strstr(szBuffer, match);
	    if (p != NULL) {
		/*
		 * Skip to first digit after the match.
		 */

		p += strlen(match);
		while (*p && !isdigit(*p)) {
		    ++p;
		}

		/*
		 * Find ending whitespace.
		 */

		q = p;
		while (*q && (strchr("0123456789.ab", *q)) && ((!strchr(".ab", *q)
			    && (!strchr("ab", q[-1])) || --numdots))) {
		    ++q;
		}

		memcpy(szBuffer, p, q - p);
		szBuffer[q-p] = 0;
		szResult = szBuffer;
		break;
	    }
	}
	fclose(fp);
    }
    return szResult;
}
 
/*
 * List helpers for the SubstituteFile function
 */

typedef struct list_item_t {
    struct list_item_t *nextPtr;
    char * key;
    char * value;
} list_item_t;

/* insert a list item into the list (list may be null) */
static list_item_t *
list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
{
    list_item_t *itemPtr = malloc(sizeof(list_item_t));
    if (itemPtr) {
	itemPtr->key = strdup(key);
	itemPtr->value = strdup(value);
	itemPtr->nextPtr = NULL;

	while(*listPtrPtr) {
	    listPtrPtr = &(*listPtrPtr)->nextPtr;
	}
	*listPtrPtr = itemPtr;
    }
    return itemPtr;
}

static void
list_free(list_item_t **listPtrPtr)
{
    list_item_t *tmpPtr, *listPtr = *listPtrPtr;
    while (listPtr) {
	tmpPtr = listPtr;
	listPtr = listPtr->nextPtr;
	free(tmpPtr->key);
	free(tmpPtr->value);
	free(tmpPtr);
    }
}
 
/*
 * SubstituteFile --
 *	As windows doesn't provide anything useful like sed and it's unreliable
 *	to use the tclsh you are building against (consider x-platform builds -
 *	eg compiling AMD64 target from IX86) we provide a simple substitution
 *	option here to handle autoconf style substitutions.
 *	The substitution file is whitespace and line delimited. The file should
 *	consist of lines matching the regular expression:
 *	  \s*\S+\s+\S*$
 *
 *	Usage is something like:
 *	  nmakehlp -S << $** > $@
 *        @PACKAGE_NAME@ $(PACKAGE_NAME)
 *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
 *        <<
 */

static int
SubstituteFile(
    const char *substitutions,
    const char *filename)
{
    size_t cbBuffer = 1024;
    static char szBuffer[1024], szCopy[1024];
    char *szResult = NULL;
    list_item_t *substPtr = NULL;
    FILE *fp, *sp;

    fp = fopen(filename, "rt");
    if (fp != NULL) {

	/*
	 * Build a list of substutitions from the first filename
	 */

	sp = fopen(substitutions, "rt");
	if (sp != NULL) {
	    while (fgets(szBuffer, cbBuffer, sp) != NULL) {
		unsigned char *ks, *ke, *vs, *ve;
		ks = (unsigned char*)szBuffer;
		while (ks && *ks && isspace(*ks)) ++ks;
		ke = ks;
		while (ke && *ke && !isspace(*ke)) ++ke;
		vs = ke;
		while (vs && *vs && isspace(*vs)) ++vs;
		ve = vs;
		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
		*ke = 0, *ve = 0;
		list_insert(&substPtr, (char*)ks, (char*)vs);
	    }
	    fclose(sp);
	}

	/* debug: dump the list */
#ifdef _DEBUG
	{
	    int n = 0;
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
		fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
	    }
	}
#endif

	/*
	 * Run the substitutions over each line of the input
	 */

	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr) {
		char *m = strstr(szBuffer, p->key);
		if (m) {
		    char *cp, *op, *sp;
		    cp = szCopy;
		    op = szBuffer;
		    while (op != m) *cp++ = *op++;
		    sp = p->value;
		    while (sp && *sp) *cp++ = *sp++;
		    op += strlen(p->key);
		    while (*op) *cp++ = *op++;
		    *cp = 0;
		    memcpy(szBuffer, szCopy, sizeof(szCopy));
		}
	    }
	    printf(szBuffer);
	}

	list_free(&substPtr);
    }
    fclose(fp);
    return 0;
}
 
/*
 * QualifyPath --
 *
 *	This composes the current working directory with a provided path
 *	and returns the fully qualified and normalized path.
 *	Mostly needed to setup paths for testing.
 */

static int
QualifyPath(
    const char *szPath)
{
    char szCwd[MAX_PATH + 1];
    char szTmp[MAX_PATH + 1];
    char *p;
    GetCurrentDirectory(MAX_PATH, szCwd);
    while ((p = strchr(szPath, '/')) && *p)
	*p = '\\';
    PathCombine(szTmp, szCwd, szPath);
    PathCanonicalize(szCwd, szTmp);
    printf("%s\n", szCwd);
    return 0;
}

/*
 * Implements LocateDependency for a single directory. See that command
 * for an explanation.
 * Returns 0 if found after printing the directory.
 * Returns 1 if not found but no errors.
 * Returns 2 on any kind of error
 * Basically, these are used as exit codes for the process.
 */
static int LocateDependencyHelper(const char *dir, const char *keypath)
{
    HANDLE hSearch;
    char path[MAX_PATH+1];
    int dirlen, keylen, ret;
    WIN32_FIND_DATA finfo;

    if (dir == NULL || keypath == NULL)
	return 2; /* Have no real error reporting mechanism into nmake */
    dirlen = strlen(dir);
    if ((dirlen + 3) > sizeof(path))
	return 2;
    strncpy(path, dir, dirlen);
    strncpy(path+dirlen, "\\*", 3);	/* Including terminating \0 */
    keylen = strlen(keypath);

#if 0 /* This function is not available in Visual C++ 6 */
    /*
     * Use numerics 0 -> FindExInfoStandard,
     * 1 -> FindExSearchLimitToDirectories, 
     * as these are not defined in Visual C++ 6
     */
    hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
#else
    hSearch = FindFirstFile(path, &finfo);
#endif
    if (hSearch == INVALID_HANDLE_VALUE)
	return 1; /* Not found */

    /* Loop through all subdirs checking if the keypath is under there */
    ret = 1; /* Assume not found */
    do {
	int sublen;
	/*
	 * We need to check it is a directory despite the 
	 * FindExSearchLimitToDirectories in the above call. See SDK docs
	 */
	if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
	    continue;
	sublen = strlen(finfo.cFileName);
	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
	    continue;		/* Path does not fit, assume not matched */
	strncpy(path+dirlen+1, finfo.cFileName, sublen);
	path[dirlen+1+sublen] = '\\';
	strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
	if (PathFileExists(path)) {
	    /* Found a match, print to stdout */
	    path[dirlen+1+sublen] = '\0';
	    QualifyPath(path);
	    ret = 0;
	    break;
	}
    } while (FindNextFile(hSearch, &finfo));
    FindClose(hSearch);
    return ret;
}

/*
 * LocateDependency --
 *
 *	Locates a dependency for a package.
 *        keypath - a relative path within the package directory
 *          that is used to confirm it is the correct directory.
 *	The search path for the package directory is currently only
 *      the parent and grandparent of the current working directory.
 *      If found, the command prints 
 *         name_DIRPATH=<full path of located directory>
 *      and returns 0. If not found, does not print anything and returns 1.
 */
static int LocateDependency(const char *keypath)
{
    int i, ret;
    static char *paths[] = {"..", "..\\..", "..\\..\\.."};
    
    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
	ret = LocateDependencyHelper(paths[i], keypath);
	if (ret == 0)
	    return ret;
    }
    return ret;
}


/*
 * Local variables:
 *   mode: c
 *   c-basic-offset: 4
 *   fill-column: 78
 *   indent-tabs-mode: t
 *   tab-width: 8
 * End:
 */

Added extensions/tnc/win/rules-ext.vc.













































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# This file should only be included in makefiles for Tcl extensions,
# NOT in the makefile for Tcl itself.

!ifndef _RULES_EXT_VC

# We need to run from the directory the parent makefile is located in.
# nmake does not tell us what makefile was used to invoke it so parent
# makefile has to set the MAKEFILEVC macro or we just make a guess and
# warn if we think that is not the case.
!if "$(MAKEFILEVC)" == ""

!if exist("$(PROJECT).vc")
MAKEFILEVC = $(PROJECT).vc
!elseif exist("makefile.vc")
MAKEFILEVC = makefile.vc
!endif
!endif # "$(MAKEFILEVC)" == ""

!if !exist("$(MAKEFILEVC)")
MSG = ^
You must run nmake from the directory containing the project makefile.^
If you are doing that and getting this message, set the MAKEFILEVC^
macro to the name of the project makefile.
!message WARNING: $(MSG)
!endif

!if "$(PROJECT)" == "tcl"
!error The rules-ext.vc file is not intended for Tcl itself.
!endif

# We extract version numbers using the nmakehlp program. For now use
# the local copy of nmakehlp. Once we locate Tcl, we will use that
# one if it is newer.
!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
!endif

# First locate the Tcl directory that we are working with.
!ifdef TCLDIR

_RULESDIR = $(TCLDIR:/=\)

!else

# If an installation path is specified, that is also the Tcl directory.
# Also Tk never builds against an installed Tcl, it needs Tcl sources
!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
_RULESDIR=$(INSTALLDIR:/=\)
!else
# Locate Tcl sources
!if [echo _RULESDIR = \> nmakehlp.out] \
   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
_RULESDIR = ..\..\tcl
!else
!include nmakehlp.out
!endif

!endif # defined(INSTALLDIR)....

!endif # ifndef TCLDIR

# Now look for the targets.vc file under the Tcl root. Note we check this
# file and not rules.vc because the latter also exists on older systems.
!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
_RULESDIR = $(_RULESDIR)\lib\nmake
!elseif exist("$(_RULESDIR)\win\targets.vc")   # Building against Tcl sources
_RULESDIR = $(_RULESDIR)\win
!else
# If we have not located Tcl's targets file, most likely we are compiling
# against an older version of Tcl and so must use our own support files.
_RULESDIR = .
!endif

!if "$(_RULESDIR)" != "."
# Potentially using Tcl's support files. If this extension has its own
# nmake support files, need to compare the versions and pick newer.

!if exist("rules.vc") # The extension has its own copy

!if [echo TCL_RULES_MAJOR = \> versions.vc] \
   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
!if [echo TCL_RULES_MINOR = \>> versions.vc] \
   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
!endif

!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
   && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
!if [echo OUR_RULES_MINOR = \>> versions.vc] \
   && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
!endif
!include versions.vc
# We have a newer version of the support files, use them
!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
_RULESDIR = .
!endif

!endif # if exist("rules.vc")

!endif # if $(_RULESDIR) != "."

# Let rules.vc know what copy of nmakehlp.c to use.
NMAKEHLPC = $(_RULESDIR)\nmakehlp.c

# Get rid of our internal defines before calling rules.vc
!undef TCL_RULES_MAJOR
!undef TCL_RULES_MINOR
!undef OUR_RULES_MAJOR
!undef OUR_RULES_MINOR

!if exist("$(_RULESDIR)\rules.vc")
!message *** Using $(_RULESDIR)\rules.vc
!include "$(_RULESDIR)\rules.vc"
!else
!error *** Could not locate rules.vc in $(_RULESDIR)
!endif

!endif # _RULES_EXT_VC

Added extensions/tnc/win/rules.vc.

















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
#------------------------------------------------------------- -*- makefile -*-
# rules.vc --
#
# Part of the nmake based build system for Tcl and its extensions.
# This file does all the hard work in terms of parsing build options,
# compiler switches, defining common targets and macros. The Tcl makefile
# directly includes this. Extensions include it via "rules-ext.vc".
#
# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
# detailed documentation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# Copyright (c) 2001-2003 David Gravereaux.
# Copyright (c) 2003-2008 Patrick Thoyts
# Copyright (c) 2017      Ashok P. Nadkarni
#------------------------------------------------------------------------------

!ifndef _RULES_VC
_RULES_VC = 1

# The following macros define the version of the rules.vc nmake build system
# For modifications that are not backward-compatible, you *must* change
# the major version.
RULES_VERSION_MAJOR = 1
RULES_VERSION_MINOR = 1

# The PROJECT macro must be defined by parent makefile.
!if "$(PROJECT)" == ""
!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
!endif

!if "$(PRJ_PACKAGE_TCLNAME)" == ""
PRJ_PACKAGE_TCLNAME = $(PROJECT)
!endif

# Also special case Tcl and Tk to save some typing later
DOING_TCL = 0
DOING_TK  = 0
!if "$(PROJECT)" == "tcl"
DOING_TCL = 1
!elseif "$(PROJECT)" == "tk"
DOING_TK = 1
!endif

!ifndef NEED_TK
# Backwards compatibility
!ifdef PROJECT_REQUIRES_TK
NEED_TK = $(PROJECT_REQUIRES_TK)
!else
NEED_TK = 0
!endif
!endif

!ifndef NEED_TCL_SOURCE
NEED_TCL_SOURCE = 0
!endif

!ifdef NEED_TK_SOURCE
!if $(NEED_TK_SOURCE)
NEED_TK = 1
!endif
!else
NEED_TK_SOURCE = 0
!endif

################################################################
# Nmake is a pretty weak environment in syntax and capabilities
# so this file is necessarily verbose. It's broken down into
# the following parts.
#
# 0. Sanity check that compiler environment is set up and initialize
#    any built-in settings from the parent makefile
# 1. First define the external tools used for compiling, copying etc.
#    as this is independent of everything else.
# 2. Figure out our build structure in terms of the directory, whether
#    we are building Tcl or an extension, etc.
# 3. Determine the compiler and linker versions
# 4. Build the nmakehlp helper application
# 5. Determine the supported compiler options and features
# 6. Parse the OPTS macro value for user-specified build configuration
# 7. Parse the STATS macro value for statistics instrumentation
# 8. Parse the CHECKS macro for additional compilation checks
# 9. Extract Tcl, and possibly Tk, version numbers from the headers
# 10. Based on this selected configuration, construct the output
#     directory and file paths
# 11. Construct the paths where the package is to be installed
# 12. Set up the actual options passed to compiler and linker based
#     on the information gathered above.
# 13. Define some standard build targets and implicit rules. These may
#     be optionally disabled by the parent makefile.
# 14. (For extensions only.) Compare the configuration of the target
#     Tcl and the extensions and warn against discrepancies.
#
# One final note about the macro names used. They are as they are
# for historical reasons. We would like legacy extensions to
# continue to work with this make include file so be wary of
# changing them for consistency or clarity.

# 0. Sanity check compiler environment

# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)

!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
MSG = ^
Visual C++ compiler environment not initialized.
!error $(MSG)
!endif

# We need to run from the directory the parent makefile is located in.
# nmake does not tell us what makefile was used to invoke it so parent
# makefile has to set the MAKEFILEVC macro or we just make a guess and
# warn if we think that is not the case.
!if "$(MAKEFILEVC)" == ""

!if exist("$(PROJECT).vc")
MAKEFILEVC = $(PROJECT).vc
!elseif exist("makefile.vc")
MAKEFILEVC = makefile.vc
!endif
!endif # "$(MAKEFILEVC)" == ""

!if !exist("$(MAKEFILEVC)")
MSG = ^
You must run nmake from the directory containing the project makefile.^
If you are doing that and getting this message, set the MAKEFILEVC^
macro to the name of the project makefile.
!message WARNING: $(MSG)
!endif


################################################################
# 1. Define external programs being used

#----------------------------------------------------------
# Set the proper copy method to avoid overwrite questions
# to the user when copying files and selecting the right
# "delete all" method.
#----------------------------------------------------------

RMDIR	= rmdir /S /Q
CPY	= xcopy /i /y >NUL
CPYDIR  = xcopy /e /i /y >NUL
COPY	= copy /y >NUL
MKDIR   = mkdir

######################################################################
# 2. Figure out our build environment in terms of what we're building.
#
# (a) Tcl itself
# (b) Tk
# (c) a Tcl extension using libraries/includes from an *installed* Tcl
# (d) a Tcl extension using libraries/includes from Tcl source directory
#
# This last is needed because some extensions still need
# some Tcl interfaces that are not publicly exposed.
#
# The fragment will set the following macros:
# ROOT - root of this module sources
# COMPATDIR - source directory that holds compatibility sources
# DOCDIR - source directory containing documentation files
# GENERICDIR - platform-independent source directory
# WINDIR - Windows-specific source directory
# TESTDIR - directory containing test files
# TOOLSDIR - directory containing build tools
# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
#    when building Tcl itself.
# _INSTALLDIR - native form of the installation path. For Tcl
#    this will be the root of the Tcl installation. For extensions
#    this will be the lib directory under the root.
# TCLINSTALL  - set to 1 if _TCLDIR refers to
#    headers and libraries from an installed Tcl, and 0 if built against
#    Tcl sources. Not set when building Tcl itself. Yes, not very well
#    named.
# _TCL_H - native path to the tcl.h file
#
# If Tk is involved, also sets the following
# _TKDIR - native form Tk installation OR Tk source. Not set if building
#    Tk itself.
# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
# _TK_H - native path to the tk.h file

# Root directory for sources and assumed subdirectories
ROOT = $(MAKEDIR)\..
# The following paths CANNOT have spaces in them as they appear on the
# left side of implicit rules.
!ifndef COMPATDIR
COMPATDIR	= $(ROOT)\compat
!endif
!ifndef DOCDIR
DOCDIR		= $(ROOT)\doc
!endif
!ifndef GENERICDIR
GENERICDIR	= $(ROOT)\generic
!endif
!ifndef TOOLSDIR
TOOLSDIR	= $(ROOT)\tools
!endif
!ifndef TESTDIR
TESTDIR	= $(ROOT)\tests
!endif
!ifndef LIBDIR
!if exist("$(ROOT)\library")
LIBDIR          = $(ROOT)\library
!else
LIBDIR          = $(ROOT)\lib
!endif
!endif
!ifndef DEMODIR
!if exist("$(LIBDIR)\demos")
DEMODIR		= $(LIBDIR)\demos
!else
DEMODIR		= $(ROOT)\demos
!endif
!endif # ifndef DEMODIR
# Do NOT enclose WINDIR in a !ifndef because Windows always defines
# WINDIR env var to point to c:\windows!
# TBD - This is a potentially dangerous conflict, rename WINDIR to
# something else
WINDIR		= $(ROOT)\win

!ifndef RCDIR
!if exist("$(WINDIR)\rc")
RCDIR           = $(WINDIR)\rc
!else
RCDIR           = $(WINDIR)
!endif
!endif
RCDIR = $(RCDIR:/=\)

# The target directory where the built packages and binaries will be installed.
# INSTALLDIR is the (optional) path specified by the user.
# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
!ifdef INSTALLDIR
### Fix the path separators.
_INSTALLDIR	= $(INSTALLDIR:/=\)
!else
### Assume the normal default.
_INSTALLDIR	= $(HOMEDRIVE)\Tcl
!endif

!if $(DOING_TCL)

# BEGIN Case 2(a) - Building Tcl itself

# Only need to define _TCL_H
_TCL_H = ..\generic\tcl.h

# END Case 2(a) - Building Tcl itself

!elseif $(DOING_TK)

# BEGIN Case 2(b) - Building Tk

TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
!if "$(TCLDIR)" == ""
!if [echo TCLDIR = \> nmakehlp.out] \
   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
!error *** Could not locate Tcl source directory.
!endif
!include nmakehlp.out
!endif # TCLDIR == ""

_TCLDIR	= $(TCLDIR:/=\)
_TCL_H  = $(_TCLDIR)\generic\tcl.h
!if !exist("$(_TCL_H)")
!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
!endif

_TK_H = ..\generic\tk.h

# END Case 2(b) - Building Tk

!else

# BEGIN Case 2(c) or (d) - Building an extension other than Tk

# If command line has specified Tcl location through TCLDIR, use it
# else default to the INSTALLDIR setting
!if "$(TCLDIR)" != ""

_TCLDIR	= $(TCLDIR:/=\)
!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
TCLINSTALL	= 1
_TCL_H          = $(_TCLDIR)\include\tcl.h
!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
TCLINSTALL	= 0
_TCL_H          = $(_TCLDIR)\generic\tcl.h
!endif

!else  #  # Case 2(c) for extensions with TCLDIR undefined

# Need to locate Tcl depending on whether it needs Tcl source or not.
# If we don't, check the INSTALLDIR for an installed Tcl first

!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)

TCLINSTALL	= 1
TCLDIR          = $(_INSTALLDIR)\..
# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
# later so the \.. accounts for the /lib
_TCLDIR		= $(_INSTALLDIR)\..
_TCL_H          = $(_TCLDIR)\include\tcl.h

!else # exist(...) && ! $(NEED_TCL_SOURCE)

!if [echo _TCLDIR = \> nmakehlp.out] \
   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
!error *** Could not locate Tcl source directory.
!endif
!include nmakehlp.out
TCLINSTALL      = 0
TCLDIR         = $(_TCLDIR)
_TCL_H          = $(_TCLDIR)\generic\tcl.h

!endif # exist(...) && ! $(NEED_TCL_SOURCE)

!endif # TCLDIR

!ifndef _TCL_H
MSG =^
Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
!error $(MSG)
!endif

# Now do the same to locate Tk headers and libs if project requires Tk
!if $(NEED_TK)

!if "$(TKDIR)" != ""

_TKDIR = $(TKDIR:/=\)
!if exist("$(_TKDIR)\include\tk.h")
TKINSTALL      = 1
_TK_H          = $(_TKDIR)\include\tk.h
!elseif exist("$(_TKDIR)\generic\tk.h")
TKINSTALL      = 0
_TK_H          = $(_TKDIR)\generic\tk.h
!endif

!else # TKDIR not defined

# Need to locate Tcl depending on whether it needs Tcl source or not.
# If we don't, check the INSTALLDIR for an installed Tcl first

!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)

TKINSTALL      = 1
# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
# later so the \.. accounts for the /lib
_TKDIR         = $(_INSTALLDIR)\..
_TK_H          = $(_TKDIR)\include\tk.h
TKDIR          = $(_TKDIR)

!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)

!if [echo _TKDIR = \> nmakehlp.out] \
   || [nmakehlp -L generic\tk.h >> nmakehlp.out]
!error *** Could not locate Tk source directory.
!endif
!include nmakehlp.out
TKINSTALL      = 0
TKDIR          = $(_TKDIR)
_TK_H          = $(_TKDIR)\generic\tk.h

!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)

!endif # TKDIR

!ifndef _TK_H
MSG =^
Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
!error $(MSG)
!endif

!endif # NEED_TK

!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
MSG = ^
*** Warning: This extension requires the source distribution of Tcl.^
*** Please set the TCLDIR macro to point to the Tcl sources.
!error $(MSG)
!endif

!if $(NEED_TK_SOURCE)
!if $(TKINSTALL)
MSG = ^
*** Warning: This extension requires the source distribution of Tk.^
*** Please set the TKDIR macro to point to the Tk sources.
!error $(MSG)
!endif
!endif


# If INSTALLDIR set to Tcl installation root dir then reset to the
# lib dir for installing extensions 
!if exist("$(_INSTALLDIR)\include\tcl.h")
_INSTALLDIR=$(_INSTALLDIR)\lib
!endif

# END Case 2(c) or (d) - Building an extension
!endif # if $(DOING_TCL)

################################################################
# 3. Determine compiler version and architecture
# In this section, we figure out the compiler version and the
# architecture for which we are building. This sets the
# following macros:
# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
#     This is also printed by the compiler in dotted form 19.10 etc.
# VCVER - the "marketing version", for example Visual C++ 6 for internal
#     compiler version 1200. This is kept only for legacy reasons as it
#     does not make sense for recent Microsoft compilers. Only used for
#     output directory names.
# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
# MACHINE - same as $(ARCH) - legacy
# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
# CFG_ENCODING - set to an character encoding.
#   TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
#   see where it is used

cc32		= $(CC)   # built-in default.
link32		= link
lib32		= lib
rc32		= $(RC)   # built-in default.

#----------------------------------------------------------------
# Figure out the compiler architecture and version by writing
# the C macros to a file, preprocessing them with the C
# preprocessor and reading back the created file

_HASH=^#
_VC_MANIFEST_EMBED_EXE=
_VC_MANIFEST_EMBED_DLL=
VCVER=0
!if ![echo VCVERSION=_MSC_VER > vercl.x] \
    && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
    && ![echo ARCH=IX86 >> vercl.x] \
    && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
    && ![echo ARCH=AMD64 >> vercl.x] \
    && ![echo $(_HASH)endif >> vercl.x] \
    && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
!include vercl.i
!if $(VCVERSION) < 1900
!if ![echo VCVER= ^\> vercl.vc] \
    && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
!include vercl.vc
!endif
!else
# The simple calculation above does not apply to new Visual Studio releases
# Keep the compiler version in its native form.
VCVER = $(VCVERSION)
!endif
!endif

!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
!endif

#----------------------------------------------------------------
# The MACHINE macro is used by legacy makefiles so set it as well
!ifdef MACHINE
!if "$(MACHINE)" == "x86"
!undef MACHINE
MACHINE = IX86
!elseif "$(MACHINE)" == "x64"
!undef MACHINE
MACHINE = AMD64
!endif
!if "$(MACHINE)" != "$(ARCH)"
!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
!endif
!else
MACHINE=$(ARCH)
!endif

#------------------------------------------------------------
# Figure out the *host* architecture by reading the registry

!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
NATIVE_ARCH=IX86
!else
NATIVE_ARCH=AMD64
!endif

# Since MSVC8 we must deal with manifest resources.
!if $(VCVERSION) >= 1400
_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
!endif

!ifndef CFG_ENCODING
CFG_ENCODING	= \"cp1252\"
!endif

################################################################
# 4. Build the nmakehlp program
# This is a helper app we need to overcome nmake's limiting
# environment. We will call out to it to get various bits of
# information about supported compiler options etc.
#
# Tcl itself will always use the nmakehlp.c program which is
# in its own source. This is the "master" copy and kept updated.
#
# Extensions built against an installed Tcl will use the installed
# copy of Tcl's nmakehlp.c if there is one and their own version
# otherwise. In the latter case, they would also be using their own
# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
# or rules.vc.
#
# Extensions built against Tcl sources will use the one from the Tcl source.
#
# When building an extension using a sufficiently new version of Tcl,
# rules-ext.vc will define NMAKEHLPC appropriately to point to the
# copy of nmakehlp.c to be used.

!ifndef NMAKEHLPC
# Default to the one in the current directory (the extension's own nmakehlp.c)
NMAKEHLPC = nmakehlp.c

!if !$(DOING_TCL)
!if $(TCLINSTALL)
!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
!endif
!else # ! $(TCLINSTALL)
!if exist("$(_TCLDIR)\win\nmakehlp.c")
NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
!endif
!endif # $(TCLINSTALL)
!endif # !$(DOING_TCL)

!endif # NMAKEHLPC

# We always build nmakehlp even if it exists since we do not know
# what source it was built from.
!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
!endif

################################################################
# 5. Test for compiler features
# Visual C++ compiler options have changed over the years. Check
# which options are supported by the compiler in use.
#
# The following macros are set:
# OPTIMIZATIONS - the compiler flags to be used for optimized builds
# DEBUGFLAGS - the compiler flags to be used for debug builds
# LINKERFLAGS - Flags passed to the linker 
#
# Note that these are the compiler settings *available*, not those
# that will be *used*. The latter depends on the OPTS macro settings
# which we have not yet parsed.
#
# Also note that some of the flags in OPTIMIZATIONS are not really
# related to optimization. They are placed there only for legacy reasons
# as some extensions expect them to be included in that macro.

# -Op improves float consistency. Note only needed for older compilers
# Newer compilers do not need or support this option.
!if [nmakehlp -c -Op]
FPOPTS  = -Op
!endif

# Strict floating point semantics - present in newer compilers in lieu of -Op
!if [nmakehlp -c -fp:strict]
FPOPTS  = $(FPOPTS) -fp:strict
!endif

!if "$(MACHINE)" == "IX86"
### test for pentium errata
!if [nmakehlp -c -QI0f]
!message *** Compiler has 'Pentium 0x0f fix'
FPOPTS  = $(FPOPTS) -QI0f
!else
!message *** Compiler does not have 'Pentium 0x0f fix'
!endif
!endif

### test for optimizations
# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
# documentation. Note we do NOT want /Gs as that inserts a _chkstk
# stack probe at *every* function entry, not just those with more than
# a page of stack allocation resulting in a performance hit.  However,
# /O2 documentation is misleading as its stack probes are simply the
# default page size locals allocation probes and not what is implied
# by an explicit /Gs option.

OPTIMIZATIONS = $(FPOPTS)

!if [nmakehlp -c -O2]
OPTIMIZING = 1
OPTIMIZATIONS   = $(OPTIMIZATIONS) -O2
!else
# Legacy, really. All modern compilers support this
!message *** Compiler does not have 'Optimizations'
OPTIMIZING = 0
!endif

# Checks for buffer overflows in local arrays
!if [nmakehlp -c -GS]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
!endif

# Link time optimization. Note that this option (potentially) makes
# generated libraries only usable by the specific VC++ version that
# created it. Requires /LTCG linker option
!if [nmakehlp -c -GL]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
CC_GL_OPT_ENABLED = 1
!else
# In newer compilers -GL and -YX are incompatible.
!if [nmakehlp -c -YX]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
!endif
!endif # [nmakehlp -c -GL]

DEBUGFLAGS     = $(FPOPTS)

# Run time error checks. Not available or valid in a release, non-debug build
# RTC is for modern compilers, -GZ is legacy
!if [nmakehlp -c -RTC1]
DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
!elseif [nmakehlp -c -GZ]
DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
!endif

#----------------------------------------------------------------
# Linker flags

# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
# if the linker supports a specific option. Without these flags link will
# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
# They are not passed through to the actual application / extension
# link rules.
!ifndef LINKER_TESTFLAGS
LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
!endif

LINKERFLAGS     =

# If compiler has enabled link time optimization, linker must too with -ltcg
!ifdef CC_GL_OPT_ENABLED
!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
LINKERFLAGS     = $(LINKERFLAGS) -ltcg
!endif
!endif

########################################################################
# 6. Parse the OPTS macro to work out the requested build configuration.
# Based on this, we will construct the actual switches to be passed to the
# compiler and linker using the macros defined in the previous section.
# The following macros are defined by this section based on OPTS
# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
#                1 -> build as a static library and shell
# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
# DEBUG - 1 -> debug build, 0 -> release builds
# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
# PROFILE - 1 -> generate profiling info, 0 -> no profiling
# PGO     - 1 -> profile based optimization, 0 -> no
# MSVCRT  - 1 -> link to dynamic C runtime even when building static Tcl build
#           0 -> link to static C runtime for static Tcl build.
#           Does not impact shared Tcl builds (STATIC_BUILD == 0)
# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
#           in the Tcl shell. 0 -> keep them as shared libraries
#           Does not impact shared Tcl builds.
# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
#           0 -> Use the non-thread allocator.
# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
#           C runtime, 0 -> use the debug C runtime.
# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
# CONFIG_CHECK - 1 -> check current build configuration against Tcl
#           configuration (ignored for Tcl itself)
# Further, LINKERFLAGS are modified based on above.

# Default values for all the above
STATIC_BUILD	= 0
TCL_THREADS	= 1
DEBUG		= 0
SYMBOLS		= 0
PROFILE		= 0
PGO		= 0
MSVCRT		= 1
TCL_USE_STATIC_PACKAGES	= 0
USE_THREAD_ALLOC = 1
UNCHECKED	= 0
CONFIG_CHECK    = 1
!if $(DOING_TCL)
USE_STUBS       = 0
!else
USE_STUBS       = 1
!endif

# If OPTS is not empty AND does not contain "none" which turns off all OPTS
# set the above macros based on OPTS content
!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]

# OPTS are specified, parse them

!if [nmakehlp -f $(OPTS) "static"]
!message *** Doing static
STATIC_BUILD	= 1
!endif

!if [nmakehlp -f $(OPTS) "nostubs"]
!message *** Not using stubs
USE_STUBS	= 0
!endif

!if [nmakehlp -f $(OPTS) "nomsvcrt"]
!message *** Doing nomsvcrt
MSVCRT		= 0
!else
!if [nmakehlp -f $(OPTS) "msvcrt"]
!message *** Doing msvcrt
MSVCRT		= 1
!else
!if !$(STATIC_BUILD)
MSVCRT		= 1
!else
MSVCRT		= 0
!endif
!endif
!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]

!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
!message *** Doing staticpkg
TCL_USE_STATIC_PACKAGES	= 1
!else
TCL_USE_STATIC_PACKAGES	= 0
!endif

!if [nmakehlp -f $(OPTS) "nothreads"]
!message *** Compile explicitly for non-threaded Tcl
TCL_THREADS	= 0
USE_THREAD_ALLOC= 0
!else
TCL_THREADS	= 1
USE_THREAD_ALLOC= 1
!endif

!if [nmakehlp -f $(OPTS) "symbols"]
!message *** Doing symbols
DEBUG		= 1
!else
DEBUG		= 0
!endif

!if [nmakehlp -f $(OPTS) "pdbs"]
!message *** Doing pdbs
SYMBOLS		= 1
!else
SYMBOLS		= 0
!endif

!if [nmakehlp -f $(OPTS) "profile"]
!message *** Doing profile
PROFILE		= 1
!else
PROFILE		= 0
!endif

!if [nmakehlp -f $(OPTS) "pgi"]
!message *** Doing profile guided optimization instrumentation
PGO		= 1
!elseif [nmakehlp -f $(OPTS) "pgo"]
!message *** Doing profile guided optimization
PGO		= 2
!else
PGO		= 0
!endif

!if [nmakehlp -f $(OPTS) "loimpact"]
!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
!endif

# TBD - should get rid of this option
!if [nmakehlp -f $(OPTS) "thrdalloc"]
!message *** Doing thrdalloc
USE_THREAD_ALLOC = 1
!endif

!if [nmakehlp -f $(OPTS) "tclalloc"]
USE_THREAD_ALLOC = 0
!endif

!if [nmakehlp -f $(OPTS) "unchecked"]
!message *** Doing unchecked
UNCHECKED = 1
!else
UNCHECKED = 0
!endif

!if [nmakehlp -f $(OPTS) "noconfigcheck"]
CONFIG_CHECK = 1
!else
CONFIG_CHECK = 0
!endif

!endif # "$(OPTS)" != ""  && ... parsing of OPTS

# Set linker flags based on above

!if $(PGO) > 1
!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
!else
MSG=^
This compiler does not support profile guided optimization.
!error $(MSG)
!endif
!elseif $(PGO) > 0
!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
!else
MSG=^
This compiler does not support profile guided optimization.
!error $(MSG)
!endif
!endif

################################################################
# 7. Parse the STATS macro to configure code instrumentation
# The following macros are set by this section:
# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
#                 0 -> disables
# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
#                     0 -> disables

# Default both are off
TCL_MEM_DEBUG	    = 0
TCL_COMPILE_DEBUG   = 0

!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]

!if [nmakehlp -f $(STATS) "memdbg"]
!message *** Doing memdbg
TCL_MEM_DEBUG	    = 1
!else
TCL_MEM_DEBUG	    = 0
!endif

!if [nmakehlp -f $(STATS) "compdbg"]
!message *** Doing compdbg
TCL_COMPILE_DEBUG   = 1
!else
TCL_COMPILE_DEBUG   = 0
!endif

!endif

####################################################################
# 8. Parse the CHECKS macro to configure additional compiler checks
# The following macros are set by this section:
# WARNINGS - compiler switches that control the warnings level
# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
#                     0 -> enable deprecated functions

# Defaults - Permit deprecated functions and warning level 3
TCL_NO_DEPRECATED	    = 0
WARNINGS		    = -W3

!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]

!if [nmakehlp -f $(CHECKS) "nodep"]
!message *** Doing nodep check
TCL_NO_DEPRECATED	    = 1
!endif

!if [nmakehlp -f $(CHECKS) "fullwarn"]
!message *** Doing full warnings check
WARNINGS		    = -W4
!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
LINKERFLAGS		    = $(LINKERFLAGS) -warn:3
!endif
!endif

!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
!message *** Doing 64bit portability warnings
WARNINGS		    = $(WARNINGS) -Wp64
!endif

!endif

################################################################
# 9. Extract various version numbers
# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
# respectively. For extensions, versions are extracted from the
# configure.in or configure.ac from the TEA configuration if it
# exists, and unset otherwise.
# Sets the following macros:
# TCL_MAJOR_VERSION
# TCL_MINOR_VERSION
# TCL_PATCH_LEVEL
# TCL_VERSION
# TK_MAJOR_VERSION
# TK_MINOR_VERSION
# TK_PATCH_LEVEL
# TK_VERSION
# DOTVERSION - set as (for example) 2.5
# VERSION - set as (for example 25)
#--------------------------------------------------------------

!if [echo REM = This file is generated from rules.vc > versions.vc]
!endif
!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
!endif
!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
!endif
!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
!endif

!if defined(_TK_H)
!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
!endif
!if [echo TK_MINOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
!endif
!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
!endif
!endif # _TK_H

!include versions.vc

TCL_VERSION	= $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
TCL_DOTVERSION	= $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
!if defined(_TK_H)
TK_VERSION	= $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
TK_DOTVERSION	= $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
!endif

# Set DOTVERSION and VERSION
!if $(DOING_TCL)

DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
VERSION = $(TCL_VERSION)

!elseif $(DOING_TK)

DOTVERSION = $(TK_DOTVERSION)
VERSION = $(TK_VERSION)

!else # Doing a non-Tk extension

# If parent makefile has not defined DOTVERSION, try to get it from TEA
# first from a configure.in file, and then from configure.ac
!ifndef DOTVERSION
!if [echo DOTVERSION = \> versions.vc] \
   || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
!if [echo DOTVERSION = \> versions.vc] \
   || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
!endif
!endif
!include versions.vc
!endif # DOTVERSION
VERSION         = $(DOTVERSION:.=)

!endif # $(DOING_TCL) ... etc.

################################################################
# 10. Construct output directory and file paths
# Figure-out how to name our intermediate and output directories.
# In order to avoid inadvertent mixing of object files built using
# different compilers, build configurations etc.,
#
# Naming convention (suffixes):
#   t = full thread support.
#   s = static library (as opposed to an import library)
#   g = linked to the debug enabled C run-time.
#   x = special static build when it links to the dynamic C run-time.
#
# The following macros are set in this section:
# SUFX - the suffix to use for binaries based on above naming convention
# BUILDDIRTOP - the toplevel default output directory
#      is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
# TMP_DIR - directory where object files are created
# OUT_DIR - directory where output executables are created
# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
# parent makefile (or command line). The default values are
# based on BUILDDIRTOP.
# STUBPREFIX - name of the stubs library for this project
# PRJIMPLIB - output path of the generated project import library
# PRJLIBNAME - name of generated project library
# PRJLIB     - output path of generated project library
# PRJSTUBLIBNAME - name of the generated project stubs library
# PRJSTUBLIB - output path of the generated project stubs library
# RESFILE - output resource file (only if not static build)

SUFX	    = tsgx

!if $(DEBUG)
BUILDDIRTOP = Debug
!else
BUILDDIRTOP = Release
!endif

!if "$(MACHINE)" != "IX86"
BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
!endif
!if $(VCVER) > 6
BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
!endif

!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
SUFX	    = $(SUFX:g=)
!endif

TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX

!if !$(STATIC_BUILD)
TMP_DIRFULL = $(TMP_DIRFULL:Static=)
SUFX	    = $(SUFX:s=)
EXT	    = dll
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!else
TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
EXT	    = lib
!if !$(MSVCRT)
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!endif
!endif

!if !$(TCL_THREADS)
TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
SUFX	    = $(SUFX:t=)
!endif

!ifndef TMP_DIR
TMP_DIR	    = $(TMP_DIRFULL)
!ifndef OUT_DIR
OUT_DIR	    = .\$(BUILDDIRTOP)
!endif
!else
!ifndef OUT_DIR
OUT_DIR	    = $(TMP_DIR)
!endif
!endif

# Relative paths -> absolute
!if [echo OUT_DIR = \> nmakehlp.out] \
   || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
!endif
!if [echo TMP_DIR = \>> nmakehlp.out] \
   || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
!endif
!include nmakehlp.out

# The name of the stubs library for the project being built
STUBPREFIX      = $(PROJECT)stub

# Set up paths to various Tcl executables and libraries needed by extensions
!if $(DOING_TCL)

TCLSHNAME       = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
TCLSH		= $(OUT_DIR)\$(TCLSHNAME)
TCLIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
TCLLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
TCLLIB		= $(OUT_DIR)\$(TCLLIBNAME)

TCLSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
TCLSTUBLIB	= $(OUT_DIR)\$(TCLSTUBLIBNAME)
TCL_INCLUDES    = -I"$(WINDIR)" -I"$(GENERICDIR)"

!else # ! $(DOING_TCL)

!if $(TCLINSTALL) # Building against an installed Tcl

# When building extensions, we need to locate tclsh. Depending on version
# of Tcl we are building against, this may or may not have a "t" suffix.
# Try various possibilities in turn.
TCLSH		= $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
!if !exist("$(TCLSH)") && $(TCL_THREADS)
TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
!endif
!if !exist("$(TCLSH)")
TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
!endif

TCLSTUBLIB	= $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
# When building extensions, may be linking against Tcl that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TCLIMPLIB)")
TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
!endif
TCL_LIBRARY	= $(_TCLDIR)\lib
TCLREGLIB	= $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
TCLDDELIB	= $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
TCLTOOLSDIR	= \must\have\tcl\sources\to\build\this\target
TCL_INCLUDES    = -I"$(_TCLDIR)\include"

!else # Building against Tcl sources

TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
!if !exist($(TCLSH)) && $(TCL_THREADS)
TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
!endif
!if !exist($(TCLSH))
TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
!endif
TCLSTUBLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
# When building extensions, may be linking against Tcl that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TCLIMPLIB)")
TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
!endif
TCL_LIBRARY	= $(_TCLDIR)\library
TCLREGLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
TCLDDELIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
TCLTOOLSDIR	= $(_TCLDIR)\tools
TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"

!endif # TCLINSTALL

tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"

!endif # $(DOING_TCL)

# We need a tclsh that will run on the host machine as part of the build.
# IX86 runs on all architectures.
!ifndef TCLSH_NATIVE
!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
TCLSH_NATIVE	= $(TCLSH)
!else
!error You must explicitly set TCLSH_NATIVE for cross-compilation
!endif
!endif

# Do the same for Tk and Tk extensions that require the Tk libraries
!if $(DOING_TK) || $(NEED_TK)
WISHNAMEPREFIX = wish
WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
TKLIBNAME	= $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
TKSTUBLIBNAME	= tkstub$(TK_VERSION).lib
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX).lib

!if $(DOING_TK)
WISH 		= $(OUT_DIR)\$(WISHNAME)
TKSTUBLIB	= $(OUT_DIR)\$(TKSTUBLIBNAME)
TKIMPLIB	= $(OUT_DIR)\$(TKIMPLIBNAME)
TKLIB		= $(OUT_DIR)\$(TKLIBNAME)
TK_INCLUDES    = -I"$(WINDIR)" -I"$(GENERICDIR)"

!else # effectively NEED_TK

!if $(TKINSTALL) # Building against installed Tk
WISH		= $(_TKDIR)\bin\$(WISHNAME)
TKSTUBLIB	= $(_TKDIR)\lib\$(TKSTUBLIBNAME)
TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
# When building extensions, may be linking against Tk that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TKIMPLIB)")
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
!endif
TK_INCLUDES     = -I"$(_TKDIR)\include"
!else # Building against Tk sources
WISH		= $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
TKSTUBLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
# When building extensions, may be linking against Tk that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TKIMPLIB)")
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
!endif
TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
!endif # TKINSTALL
tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"

!endif # $(DOING_TK)
!endif # $(DOING_TK) || $(NEED_TK)

# Various output paths
PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)

PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)

# If extension parent makefile has not defined a resource definition file,
# we will generate one from standard template.
!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
!ifdef RCFILE
RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
!else
RESFILE = $(TMP_DIR)\$(PROJECT).res
!endif
!endif

###################################################################
# 11. Construct the paths for the installation directories
# The following macros get defined in this section:
# LIB_INSTALL_DIR - where libraries should be installed
# BIN_INSTALL_DIR - where the executables should be installed
# DOC_INSTALL_DIR - where documentation should be installed
# SCRIPT_INSTALL_DIR - where scripts should be installed
# INCLUDE_INSTALL_DIR - where C include files should be installed
# DEMO_INSTALL_DIR - where demos should be installed
# PRJ_INSTALL_DIR - where package will be installed (not set for Tcl and Tk)

!if $(DOING_TCL) || $(DOING_TK)
LIB_INSTALL_DIR		= $(_INSTALLDIR)\lib
BIN_INSTALL_DIR		= $(_INSTALLDIR)\bin
DOC_INSTALL_DIR		= $(_INSTALLDIR)\doc
!if $(DOING_TCL)
SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
!else # DOING_TK
SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
!endif
DEMO_INSTALL_DIR	= $(SCRIPT_INSTALL_DIR)\demos
INCLUDE_INSTALL_DIR	= $(_INSTALLDIR)\include

!else # extension other than Tk

PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
LIB_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
BIN_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
DEMO_INSTALL_DIR	= $(PRJ_INSTALL_DIR)\demos
INCLUDE_INSTALL_DIR	= $(_TCLDIR)\include

!endif

###################################################################
# 12. Set up actual options to be passed to the compiler and linker
# Now we have all the information we need, set up the actual flags and
# options that we will pass to the compiler and linker. The main
# makefile should use these in combination with whatever other flags
# and switches are specific to it.
# The following macros are defined, names are for historical compatibility:
# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
# crt - Compiler switch that selects the appropriate C runtime
# cdebug - Compiler switches related to debug AND optimizations
# cwarn - Compiler switches that set warning levels
# cflags - complete compiler switches (subsumes cdebug and cwarn)
# ldebug - Linker switches controlling debug information and optimization
# lflags - complete linker switches (subsumes ldebug) except subsystem type
# dlllflags - complete linker switches to build DLLs (subsumes lflags)
# conlflags - complete linker switches for console program (subsumes lflags)
# guilflags - complete linker switches for GUI program (subsumes lflags)
# baselibs - minimum Windows libraries required. Parent makefile can
#    define PRJ_LIBS before including rules.rc if additional libs are needed

OPTDEFINES	= -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS

!if $(TCL_MEM_DEBUG)
OPTDEFINES	= $(OPTDEFINES) -DTCL_MEM_DEBUG
!endif
!if $(TCL_COMPILE_DEBUG)
OPTDEFINES	= $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
!endif
!if $(TCL_THREADS)
OPTDEFINES	= $(OPTDEFINES) -DTCL_THREADS=1
!if $(USE_THREAD_ALLOC)
OPTDEFINES	= $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
!endif
!endif
!if $(STATIC_BUILD)
OPTDEFINES	= $(OPTDEFINES) -DSTATIC_BUILD
!endif
!if $(TCL_NO_DEPRECATED)
OPTDEFINES	= $(OPTDEFINES) -DTCL_NO_DEPRECATED
!endif

!if $(USE_STUBS)
# Note we do not define USE_TCL_STUBS even when building Tk since some
# test targets in Tk do not use stubs
!if ! $(DOING_TCL)
USE_STUBS_DEFS  = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
!if $(NEED_TK)
USE_STUBS_DEFS  = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
!endif
!endif
!endif # USE_STUBS

!if !$(DEBUG)
OPTDEFINES	= $(OPTDEFINES) -DNDEBUG
!if $(OPTIMIZING)
OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
!endif
!endif
!if $(PROFILE)
OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_PROFILED
!endif
!if "$(MACHINE)" == "AMD64"
OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_DO64BIT
!endif
!if $(VCVERSION) < 1300
OPTDEFINES	= $(OPTDEFINES) -DNO_STRTOI64
!endif

# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
COMPILERFLAGS  = /D_ATL_XP_TARGETING

# Following is primarily for the benefit of extensions. Tcl 8.5 builds
# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
# an extension, it is advisable (but not mandated) to use the same Windows
# API as the Tcl build. This is accordingly defaulted below. A particular
# extension can override this by pre-defining USE_WIDECHAR_API.
!ifndef USE_WIDECHAR_API
!if $(TCL_VERSION) > 85
USE_WIDECHAR_API = 1
!else
USE_WIDECHAR_API = 0
!endif
!endif

!if $(USE_WIDECHAR_API)
COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE 
!endif

# Like the TEA system only set this non empty for non-Tk extensions
# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
# so we pass both
!if !$(DOING_TCL) && !$(DOING_TK)
PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
               -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
               -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
               -DMODULE_SCOPE=extern 
!endif

# crt picks the C run time based on selected OPTS
!if $(MSVCRT)
!if $(DEBUG) && !$(UNCHECKED)
crt = -MDd
!else
crt = -MD
!endif
!else
!if $(DEBUG) && !$(UNCHECKED)
crt = -MTd
!else
crt = -MT
!endif
!endif

# cdebug includes compiler options for debugging as well as optimization.
!if $(DEBUG)

# In debugging mode, optimizations need to be disabled
cdebug = -Zi -Od $(DEBUGFLAGS)

!else

cdebug = $(OPTIMIZATIONS)
!if $(SYMBOLS)
cdebug = $(cdebug) -Zi
!endif

!endif # $(DEBUG)

# cwarn includes default warning levels.
cwarn = $(WARNINGS)

!if "$(MACHINE)" == "AMD64"
# Disable pointer<->int warnings related to cast between different sizes
# There are a gadzillion of these due to use of ClientData and
# clutter up compiler
# output increasing chance of a real warning getting lost. So disable them.
# Eventually some day, Tcl will be 64-bit clean.
cwarn = $(cwarn) -wd4311 -wd4312
!endif

### Common compiler options that are architecture specific
!if "$(MACHINE)" == "ARM"
carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
!else
carch =
!endif

!if $(DEBUG)
# Turn warnings into errors
cwarn = $(cwarn) -WX
!endif

INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
!if !$(DOING_TCL) && !$(DOING_TK)
INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
!endif

# These flags are defined roughly in the order of the pre-reform
# rules.vc/makefile.vc to help visually compare that the pre- and
# post-reform build logs

# cflags contains generic flags used for building practically all object files
cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)

# appcflags contains $(cflags) and flags for building the application
# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
# flags used for building shared object files The two differ in the
# BUILD_$(PROJECT) macro which should be defined only for the shared
# library *implementation* and not for its caller interface

appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)

# stubscflags contains $(cflags) plus flags used for building a stubs
# library for the package.  Note: -DSTATIC_BUILD is defined in
# $(OPTDEFINES) only if the OPTS configuration indicates a static
# library. However the stubs library is ALWAYS static hence included
# here irrespective of the OPTS setting.
#
# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
# without stating why. Tcl itself compiled stubs libs with this flag.
# so we do not remove it from cflags. -GL may prevent extensions
# compiled with one VC version to fail to link against stubs library
# compiled with another VC version. Check for this and fix accordingly.
stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)

# Link flags 

!if $(DEBUG)
ldebug	= -debug -debugtype:cv
!else
ldebug	= -release -opt:ref -opt:icf,3
!if $(SYMBOLS)
ldebug	= $(ldebug) -debug -debugtype:cv
!endif
!endif

# Note: Profiling is currently only possible with the Visual Studio Enterprise
!if $(PROFILE)
ldebug= $(ldebug) -profile
!endif

### Declarations common to all linker versions 
lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)

!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
lflags	= $(lflags) -nodefaultlib:libucrt.lib
!endif

# Old linkers (Visual C++ 6 in particular) will link for fast loading
# on Win98. Since we do not support Win98 any more, we specify nowin98
# as recommended for NT and later. However, this is only required by
# IX86 on older compilers and only needed if we are not doing a static build.

!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
# Align sections for PE size savings.
lflags	= $(lflags) -opt:nowin98
!endif
!endif

dlllflags = $(lflags) -dll
conlflags = $(lflags) -subsystem:console
guilflags = $(lflags) -subsystem:windows

# Libraries that are required for every image.
# Extensions should define any additional libraries with $(PRJ_LIBS)
winlibs   = kernel32.lib advapi32.lib

!if $(NEED_TK)
winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
!endif

# Avoid 'unresolved external symbol __security_cookie' errors.
# c.f. http://support.microsoft.com/?id=894573
!if "$(MACHINE)" == "AMD64"
!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
winlibs   = $(winlibs) bufferoverflowU.lib
!endif
!endif

baselibs = $(winlibs) $(PRJ_LIBS)

!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
baselibs   = $(baselibs) ucrt.lib
!endif

################################################################
# 13. Define standard commands, common make targets and implicit rules

CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\

LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)

CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
RESCMD  = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
	    $(TCL_INCLUDES) \
	    -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
	    -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
	    -DDOTVERSION=\"$(DOTVERSION)\" \
	    -DVERSION=\"$(VERSION)\" \
	    -DSUFX=\"$(SUFX)\" \
            -DPROJECT=\"$(PROJECT)\" \
            -DPRJLIBNAME=\"$(PRJLIBNAME)\" 

!ifndef DEFAULT_BUILD_TARGET
DEFAULT_BUILD_TARGET = $(PROJECT)
!endif

default-target: $(DEFAULT_BUILD_TARGET)

default-pkgindex:
	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl

default-pkgindex-tea:
	@if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
@PACKAGE_VERSION@    $(DOTVERSION)
@PACKAGE_NAME@       $(PRJ_PACKAGE_TCLNAME)
@PACKAGE_TCLNAME@    $(PRJ_PACKAGE_TCLNAME)
@PKG_LIB_FILE@       $(PRJLIBNAME)
<<


default-install: default-install-binaries default-install-libraries

default-install-binaries: $(PRJLIB)
	@echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
	@$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL

default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
	@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
	@if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
	@echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
	@$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)

default-install-stubs:
	@echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
	@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL

default-install-docs-html:
	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"

default-install-docs-n:
	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"

default-install-demos:
	@echo Installing demos to '$(DEMO_INSTALL_DIR)'
	@if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
	@if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"

default-clean:
	@echo Cleaning $(TMP_DIR)\* ...
	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
	@echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
	@if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
	@echo Cleaning $(WINDIR)\nmhlp-out.txt ...
	@if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
	@echo Cleaning $(WINDIR)\_junk.pch ...
	@if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
	@echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
	@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
	@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
	@echo Cleaning $(WINDIR)\versions.vc, version.vc ...
	@if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
	@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc

default-hose: default-clean
	@echo Hosing $(OUT_DIR)\* ...
	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)

# Only for backward compatibility
default-distclean: default-hose

default-setup:
	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)

!if "$(TESTPAT)" != ""
TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
!endif

default-test: default-setup $(PROJECT)
	@set TCLLIBPATH=$(OUT_DIR:\=/)
	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
	cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)

default-shell: default-setup $(PROJECT)
	@set TCLLIBPATH=$(OUT_DIR:\=/)
	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
	$(DEBUGGER) $(TCLSH)

# Generation of Windows version resource 
!ifdef RCFILE

# Note: don't use $** in below rule because there may be other dependencies
# and only the "master" rc must be passed to the resource compiler
$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
	$(RESCMD) $(RCDIR)\$(PROJECT).rc

!else

# If parent makefile has not defined a resource definition file,
# we will generate one from standard template.
$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc

$(TMP_DIR)\$(PROJECT).rc:
	@$(COPY) << $(TMP_DIR)\$(PROJECT).rc
#include <winver.h>

VS_VERSION_INFO VERSIONINFO
 FILEVERSION	COMMAVERSION
 PRODUCTVERSION	COMMAVERSION
 FILEFLAGSMASK	0x3fL
#ifdef DEBUG
 FILEFLAGS	VS_FF_DEBUG
#else
 FILEFLAGS	0x0L
#endif
 FILEOS		VOS_NT_WINDOWS32
 FILETYPE	VFT_DLL
 FILESUBTYPE	0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription",  "Tcl extension " PROJECT
            VALUE "OriginalFilename", PRJLIBNAME
            VALUE "FileVersion",      DOTVERSION
            VALUE "ProductName",      "Package " PROJECT " for Tcl"
            VALUE "ProductVersion",   DOTVERSION 
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END

<<

!endif # ifdef RCFILE

!ifndef DISABLE_IMPLICIT_RULES
DISABLE_IMPLICIT_RULES = 0
!endif

!if !$(DISABLE_IMPLICIT_RULES)
# Implicit rule definitions - only for building library objects. For stubs and
# main application, the master makefile should define explicit rules.

{$(ROOT)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(WINDIR)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(RCDIR)}.rc{$(TMP_DIR)}.res:
	$(RESCMD) $<

{$(WINDIR)}.rc{$(TMP_DIR)}.res:
	$(RESCMD) $<

{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
	$(RESCMD) $<

.SUFFIXES:
.SUFFIXES:.c .rc

!endif

################################################################
# 14. Sanity check selected options against Tcl build options
# When building an extension, certain configuration options should
# match the ones used when Tcl was built. Here we check and
# warn on a mismatch.
!if ! $(DOING_TCL)

!if $(TCLINSTALL) # Building against an installed Tcl
!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
!endif
!else # ! $(TCLINSTALL) - building against Tcl source
!if exist("$(OUT_DIR)\tcl.nmake")
TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
!endif
!endif # TCLINSTALL

!if $(CONFIG_CHECK)
!ifdef TCLNMAKECONFIG
!include $(TCLNMAKECONFIG)

!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
!endif
!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
!endif
!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
!endif
!endif

!endif # TCLNMAKECONFIG

!endif # ! $(DOING_TCL)


#----------------------------------------------------------
# Display stats being used.
#----------------------------------------------------------

!if !$(DOING_TCL)
!message *** Building against Tcl at '$(_TCLDIR)'
!endif
!if !$(DOING_TK) && $(NEED_TK)
!message *** Building against Tk at '$(_TKDIR)'
!endif
!message *** Intermediate directory will be '$(TMP_DIR)'
!message *** Output directory will be '$(OUT_DIR)'
!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
!message *** Suffix for binaries will be '$(SUFX)'
!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).

!endif # ifdef _RULES_VC

Added extensions/tnc/win/targets.vc.





































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#------------------------------------------------------------- -*- makefile -*-
# targets.vc --
#
# Part of the nmake based build system for Tcl and its extensions.
# This file defines some standard targets for the convenience of extensions
# and can be optionally included by the extension makefile.
# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.

$(PROJECT): setup pkgindex $(PRJLIB)

!ifdef PRJ_STUBOBJS
$(PROJECT): $(PRJSTUBLIB)
$(PRJSTUBLIB): $(PRJ_STUBOBJS)
	$(LIBCMD) $**

$(PRJ_STUBOBJS):
	$(CCSTUBSCMD) %s
!endif # PRJ_STUBOBJS

!ifdef PRJ_MANIFEST
$(PROJECT): $(PRJLIB).manifest
$(PRJLIB).manifest: $(PRJ_MANIFEST)
	@nmakehlp -s << $** >$@
@MACHINE@	  $(MACHINE:IX86=X86)
<<
!endif

!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
!if $(STATIC_BUILD)
       $(LIBCMD) $**
!else
       $(DLLCMD) $**
       $(_VC_MANIFEST_EMBED_DLL)
!endif
       -@del $*.exp
!endif

!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
$(PRJ_OBJS): $(PRJ_HEADERS)
!endif

# If parent makefile has defined stub objects, add their installation
# to the default install
!if "$(PRJ_STUBOBJS)" != ""
default-install: default-install-stubs
!endif

# Unlike the other default targets, these cannot be in rules.vc because
# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
# that the parent makefile will not define until after including rules-ext.vc
!if "$(PRJ_HEADERS_PUBLIC)" != ""
default-install: default-install-headers
default-install-headers:
	@echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
	@for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
!endif

!if "$(DISABLE_STANDARD_TARGETS)" == ""
DISABLE_STANDARD_TARGETS = 0
!endif

!if "$(DISABLE_TARGET_setup)" == ""
DISABLE_TARGET_setup = 0
!endif
!if "$(DISABLE_TARGET_install)" == ""
DISABLE_TARGET_install = 0
!endif
!if "$(DISABLE_TARGET_clean)" == ""
DISABLE_TARGET_clean = 0
!endif
!if "$(DISABLE_TARGET_test)" == ""
DISABLE_TARGET_test = 0
!endif
!if "$(DISABLE_TARGET_shell)" == ""
DISABLE_TARGET_shell = 0
!endif

!if !$(DISABLE_STANDARD_TARGETS)
!if !$(DISABLE_TARGET_setup)
setup: default-setup
!endif
!if !$(DISABLE_TARGET_install)
install: default-install
!endif
!if !$(DISABLE_TARGET_clean)
clean: default-clean
realclean: hose
hose: default-hose
distclean: realclean default-distclean
!endif
!if !$(DISABLE_TARGET_test)
test: default-test
!endif
!if !$(DISABLE_TARGET_shell)
shell: default-shell
!endif
!endif # DISABLE_STANDARD_TARGETS

Changes to generic/dom.c.

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62

63

64
65

66
67
68
69
70
71
72
..
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
...
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
...
146
147
148
149
150
151
152

153
154
155

156

157
158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
...
353
354
355
356
357
358
359

360
361
362
363
364
365





















366
367
368
369
370
371
372
...
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
...
540
541
542
543
544
545
546





547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
...
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
...
795
796
797
798
799
800
801

802
803
804
805

806
807
808
809
810
811
812
...
871
872
873
874
875
876
877
878
879
880

881
882
883
884

885
886
887
888
889
890
891
...
898
899
900
901
902
903
904
905
906
907

908
909
910

911
912
913
914
915
916
917
....
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
....
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078



1079
1080


1081
1082
1083
1084
1085
1086
1087



1088
1089


1090
1091
1092
1093
1094
1095
1096
....
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170






1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225

1226

1227

1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253




1254
1255

1256
1257
1258
1259
1260
1261
1262
1263
1264
....
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
....
1281
1282
1283
1284
1285
1286
1287
1288
1289

1290
1291
1292
1293

1294
1295
1296
1297
1298
1299
1300
....
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328

1329

1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352

1353
1354
1355
1356
1357
1358
1359
....
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380

1381
1382
1383
1384
1385
1386
1387
....
1405
1406
1407
1408
1409
1410
1411






























1412
1413
1414
1415
1416
1417
1418
....
1422
1423
1424
1425
1426
1427
1428
1429
1430

1431
1432
1433
1434
1435
1436
1437
1438
1439
1440

1441
1442
1443
1444
1445
1446
1447
....
1470
1471
1472
1473
1474
1475
1476



1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
....
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
....
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
....
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746

1747
1748
1749
1750
1751



1752
1753
1754
1755
1756
1757
1758
....
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807

1808
1809
1810
1811
1812
1813
1814
....
1862
1863
1864
1865
1866
1867
1868


1869


1870
1871


1872
1873


1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903






1904










1905
1906
1907
1908
1909


1910
1911


1912
1913
1914
1915
1916
1917
1918
1919
1920
1921






1922












1923
1924
1925

1926
1927



1928
1929
1930

1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941

1942
1943
1944
1945
1946
1947
1948
....
1994
1995
1996
1997
1998
1999
2000
2001
2002

2003

2004
2005
2006
2007
2008
2009

2010
2011
2012

2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024





2025
2026
2027
2028
2029
2030
2031
2032
2033
2034

2035

2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046

2047
2048
2049
2050
2051
2052
2053
....
2060
2061
2062
2063
2064
2065
2066


2067


2068
2069









2070
2071
2072
2073
2074

2075


2076
2077
2078
2079
2080
2081
2082
2083
2084
2085

2086
2087
2088
2089
2090
2091
2092
2093
2094
2095









2096
2097
2098
2099
2100

2101


2102
2103
2104
2105
2106
2107
2108
2109
2110
2111









2112
2113
2114
2115
2116
2117

2118


2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
....
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
....
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
....
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
....
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
....
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
....
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
....
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
....
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588

2589
2590
2591
2592
2593
2594
2595
2596
2597
....
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
....
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
....
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
....
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
....
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
....
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
....
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418





4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
....
4464
4465
4466
4467
4468
4469
4470
4471







4472
4473
4474
4475
4476

4477
4478
4479

4480
4481
4482
4483
4484
4485
4486
....
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
....
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
....
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
....
5025
5026
5027
5028
5029
5030
5031

5032
5033
5034

5035

5036
5037
5038
5039
5040
5041
5042
5043
....
5104
5105
5106
5107
5108
5109
5110

5111
5112
5113
5114
5115
5116
5117
5118
5119
....
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
....
5202
5203
5204
5205
5206
5207
5208







5209
5210
5211
5212
5213
5214
5215
....
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232

5233
5234
5235
5236

5237

5238
5239
5240
5241
5242
5243
5244
5245
....
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317


5318
5319
5320
5321
5322
5323
5324
....
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
....
5353
5354
5355
5356
5357
5358
5359




5360
5361
5362
5363
5364
5365
5366


5367
5368
5369
5370
5371





5372










































5373
5374


/*---------------------------------------------------------------------------
|   Includes
|
\--------------------------------------------------------------------------*/
#include <tcl.h>
#include <stdlib.h>
#include <string.h>
#include <dom.h>
#include <domxpath.h>
#include <utf8conv.h>
#include <tclexpat.h>




/*---------------------------------------------------------------------------
|   Defines
|
\--------------------------------------------------------------------------*/

#define DBG(x)

#define TDOM_NS
#define XSLT_NAMESPACE  "http://www.w3.org/1999/XSL/Transform"


#define MutationEvent()
#define MutationEvent2(type,node)
#define MutationEvent3(type,node,relatioNode)

#define MCHK(a)  if ((a)==NULL) { \
                     fprintf(stderr, \
................................................................................
#endif

static int domModuleIsInitialized = 0;
TDomThreaded(static Tcl_Mutex initMutex;)

static char *domException2StringTable [] = {

    "OK - no expection",
    "INDEX_SIZE_ERR",
    "DOMSTRING_SIZE_ERR",
    "HIERARCHY_REQUEST_ERR",
    "WRONG_DOCUMENT_ERR",
    "INVALID_CHARACTER_ERR",
    "NO_DATA_ALLOWED_ERR",
    "NO_MODIFICATION_ALLOWED_ERR",
................................................................................
    "INUSE_ATTRIBUTE_ERR"
};

static char tdom_usage[] =
                "Usage tdom <expat parser obj> <subCommand>, where subCommand can be:\n"
                "           enable             \n"
                "           getdoc             \n"
                "           setResultEncoding  \n"
                "           setStoreLineColumn \n"
                ;


/*---------------------------------------------------------------------------
|   type domActiveNS
|
\--------------------------------------------------------------------------*/
typedef struct _domActiveNS {

    int    depth;
    domNS *namespace;

} domActiveNS;

/*---------------------------------------------------------------------------
|   type domBaseURIstackElem
|
\--------------------------------------------------------------------------*/
typedef struct _domActiveBaseURI {

    int   depth;
................................................................................
typedef struct _domReadInfo {

    XML_Parser        parser;
    domDocument      *document;
    domNode          *currentNode;
    int               depth;
    int               ignoreWhiteSpaces;

    Tcl_DString      *cdata;
    TEncoding        *encoding_8bit;
    int               storeLineColumn;

    int               feedbackAfter;

    int               lastFeedbackPosition;
    Tcl_Interp       *interp;
    int               activeNSsize;
    int               activeNSpos;
    domActiveNS      *activeNS;
    int               baseURIstackSize;
    int               baseURIstackPos;
    domActiveBaseURI *baseURIstack;
    int               insideDTD;


} domReadInfo;

/*----------------------------------------------------------------------------
|   Prototypes
|
\---------------------------------------------------------------------------*/
................................................................................
{
    const char *p;
    int   clen;
    
    p = str;
    while (*p) {
        clen = UTF8_CHAR_LEN(*p);

        if (UTF8_XMLCHAR((unsigned const char *)p,clen))
            p += clen;
        else return 0;
    }
    return 1;
}






















/*---------------------------------------------------------------------------
|   domIsComment
|
\--------------------------------------------------------------------------*/
int
domIsComment (
................................................................................

int
domPrecedes (
    domNode *node,
    domNode *other
    )
{
    domNode *nodeAncestor, *otherAncestor, *otherToplevel;
    domAttrNode *attrN, *attrO;
    
    if (node == other) {
        return 0;
    }
    
    if (node->nodeType == ATTRIBUTE_NODE) {
................................................................................
#ifndef TCL_THREADS
    if (node->ownerDocument->nodeFlags & NEEDS_RENUMBERING) {
        domRenumberTree (node->ownerDocument->rootNode);
        node->ownerDocument->nodeFlags &= ~NEEDS_RENUMBERING;
    }
    return (node->nodeNumber < other->nodeNumber);
# else 





    if (!(node->ownerDocument->nodeFlags & NEEDS_RENUMBERING)) {
        return (node->nodeNumber < other->nodeNumber);
    }
#endif
    
    otherAncestor = other;
    while (otherAncestor->parentNode) {
        otherAncestor = otherAncestor->parentNode;
        if (otherAncestor == node) {
            return 1;
        }
    }
    otherToplevel = otherAncestor;
    
    nodeAncestor = node;
    while (nodeAncestor->parentNode) {
        otherAncestor = other;
        while (otherAncestor->parentNode) {
            if (nodeAncestor->parentNode == otherAncestor->parentNode) {
                nodeAncestor = nodeAncestor->nextSibling;
................................................................................
    return NULL;
}

/*---------------------------------------------------------------------------
|   domIsNamespaceInScope
|
\--------------------------------------------------------------------------*/
static int
domIsNamespaceInScope (
    domActiveNS *NSstack,
    int          NSstackPos,
    const char  *prefix,
    const char  *namespaceURI
)
{
................................................................................
    domNS *ns = NULL;

    DBG(fprintf(stderr, "domNewNamespace '%s' --> '%s' \n", prefix, namespaceURI);)

    ns = domLookupNamespace (doc, prefix, namespaceURI);
    if (ns != NULL) return ns;
    doc->nsptr++;

    if (doc->nsptr > 254) {
        DBG(fprintf (stderr, "maximum number of namespaces exceeded!!!\n");)
        domPanic("domNewNamespace: maximum number of namespaces exceeded!");
    }

    if (doc->nsptr >= doc->nslen) {
        doc->namespaces = (domNS**) REALLOC ((char*) doc->namespaces,
                                             sizeof (domNS*) * 2 * doc->nslen);
        doc->nslen *= 2;
    }
    doc->namespaces[doc->nsptr] = (domNS*)MALLOC (sizeof (domNS));
    ns = doc->namespaces[doc->nsptr];
................................................................................
domNamespaceURI (
    domNode *node
)
{
    domAttrNode *attr;
    domNS       *ns;

    if (!node->namespace) return NULL;
    if (node->nodeType == ATTRIBUTE_NODE) {
        attr = (domAttrNode*)node;

        if (attr->nodeFlags & IS_NS_NODE) return NULL;
        ns = attr->parentNode->ownerDocument->namespaces[attr->namespace-1];
    } else
    if (node->nodeType == ELEMENT_NODE) {

        ns = node->ownerDocument->namespaces[node->namespace-1];
    } else {
        return NULL;
    }
    return ns->uri;
}

................................................................................
domNamespacePrefix (
    domNode *node
)
{
    domAttrNode *attr;
    domNS *ns;

    if (!node->namespace) return NULL;
    if (node->nodeType == ATTRIBUTE_NODE) {
        attr = (domAttrNode*)node;

        ns = attr->parentNode->ownerDocument->namespaces[attr->namespace-1];
    } else
    if (node->nodeType == ELEMENT_NODE) {

        ns = node->ownerDocument->namespaces[node->namespace-1];
    } else {
        return NULL;
    }
    if (ns) return ns->prefix;
    return NULL;
}
................................................................................
 *      Returns the previous node to the given node or NULL, if there
 *      is no previous node. This function is needed in situations,
 *      where the given node may also be an domAttrNode. Namespace
 *      declaring attributes are treated as any other
 *      attributes. Since the domAttrNode struct doesn't has an
 *      element for the previous attribute, we need a function for the
 *      relatively rare cases, the 'previous attribute' is
 *      needed. Remeber, that the XML rec say, that there is no
 *      specific order of the attributes of a node.
 *
 * Results: 
 *      A pointer to the previous node of the given one
 *      or NULL, if there isn't a previous node.
 *
 * Side effects:
................................................................................
{
    domReadInfo   *info = userData;
    domNode       *node, *parentNode;
    domLineColumn *lc;
    domAttrNode   *attrnode, *lastAttr;
    const char   **atPtr, **idAttPtr;
    Tcl_HashEntry *h;
    int            hnew, len, pos, idatt, newNS;
    const char    *xmlns, *localname;
    char           tagPrefix[MAX_PREFIX_LEN];
    char           prefix[MAX_PREFIX_LEN];
    domNS         *ns;
    char           feedbackCmd[24];

    if (info->feedbackAfter) {

        if (info->lastFeedbackPosition
             < XML_GetCurrentByteIndex (info->parser)
        ) {



            sprintf(feedbackCmd, "%s", "::dom::domParseFeedback");
            if (Tcl_Eval(info->interp, feedbackCmd) != TCL_OK) {


                DBG(fprintf(stderr, "%s\n", 
                            Tcl_GetStringResult (info->interp));)
                /* FIXME: We simply ignore script errors in the
                   feedbackCmd, for now. One fine day, expat may provide
                   a way to cancel an already started parse run from
                   inside a handler. Then we should revisit this. */
                /* exit(1) */    



            }
            info->lastFeedbackPosition += info->feedbackAfter;


        }
    }

    DispatchPCDATA (info);
    
    h = Tcl_CreateHashEntry(&HASHTAB(info->document,tdom_tagNames), name,
                            &hnew);
................................................................................


    lastAttr = NULL;
    /*--------------------------------------------------------------
    |   process namespace declarations
    |
    \-------------------------------------------------------------*/
#ifdef TDOM_NS
    for (atPtr = atts; atPtr[0] && atPtr[1]; atPtr += 2) {

        if (strncmp(atPtr[0], "xmlns", 5) == 0) {
            xmlns = atPtr[0];
            newNS = 1;
            if (xmlns[5] == ':') {






                if (domIsNamespaceInScope (info->activeNS, info->activeNSpos,
                                           &(xmlns[6]), atPtr[1])) {
                    ns = domLookupPrefix (info->currentNode, &(xmlns[6]));
                    newNS = 0;
                }
                else {
                    ns = domNewNamespace(info->document, &xmlns[6], atPtr[1]);
                }
            } else {
                ns = domNewNamespace(info->document, "", atPtr[1]);
            }
            if (newNS) {
                /* push active namespace */
                info->activeNSpos++;
                if (info->activeNSpos >= info->activeNSsize) {
                    info->activeNS = (domActiveNS*) REALLOC(
                        (char*)info->activeNS,
                        sizeof(domActiveNS) * 2 * info->activeNSsize);
                    info->activeNSsize = 2 * info->activeNSsize;
                }
                info->activeNS[info->activeNSpos].depth     = info->depth;
                info->activeNS[info->activeNSpos].namespace = ns;
            }

            h = Tcl_CreateHashEntry(&HASHTAB(info->document, tdom_attrNames),
                                    atPtr[0], &hnew);
            attrnode = (domAttrNode*) domAlloc(sizeof(domAttrNode));
            memset(attrnode, 0, sizeof(domAttrNode));
            attrnode->nodeType    = ATTRIBUTE_NODE;
            attrnode->nodeFlags   = IS_NS_NODE;
            attrnode->namespace   = ns->index;
            attrnode->nodeName    = (char *)&(h->key);
            attrnode->parentNode  = node;
            len = strlen(atPtr[1]);
            if (TclOnly8Bits && info->encoding_8bit) {
                tdom_Utf8to8Bit(info->encoding_8bit, atPtr[1], &len);
            }
            attrnode->valueLength = len;
            attrnode->nodeValue   = (char*)MALLOC(len+1);
            strcpy(attrnode->nodeValue, atPtr[1]);
            if (node->firstAttr) {
                lastAttr->nextSibling = attrnode;
            } else {
                node->firstAttr = attrnode;
            }
            lastAttr = attrnode;
        }

    }

    /*----------------------------------------------------------
    |   look for namespace of element
    \---------------------------------------------------------*/
    domSplitQName (name, tagPrefix, &localname);
    for (pos = info->activeNSpos; pos >= 0; pos--) {

        if (  ((tagPrefix[0] == '\0') && (info->activeNS[pos].namespace->prefix[0] == '\0'))

           || ((tagPrefix[0] != '\0') && (info->activeNS[pos].namespace->prefix[0] != '\0')

               && (strcmp(tagPrefix, info->activeNS[pos].namespace->prefix) == 0))
        ) {
            if (info->activeNS[pos].namespace->prefix[0] == '\0'
                && info->activeNS[pos].namespace->uri[0] == '\0'
                && tagPrefix[0] == '\0') {
                /* xml-names rec. 5.2: "The default namespace can be
                   set to the empty string. This has the same effect,
                   within the scope of the declaration, of there being
                   no default namespace." */
                goto elemNSfound;
            }
            node->namespace = info->activeNS[pos].namespace->index;
            DBG(fprintf(stderr, "tag='%s' uri='%s' \n",
                        node->nodeName,
                        info->activeNS[pos].namespace->uri);
            )
            goto elemNSfound;
        }
    }
    if (tagPrefix[0] != '\0') {
        if (strcmp (tagPrefix, "xml")==0) {
            node->namespace = info->document->rootNode->firstAttr->namespace;
        } else {
            /* Since where here, this means, the element has a
               up to now not declared namespace prefix. We probably
               should return this as an error, shouldn't we?*/




        }
    }

 elemNSfound:
#endif

    /*--------------------------------------------------------------
    |   add the attribute nodes
    |
    \-------------------------------------------------------------*/
    if ((idatt = XML_GetIdAttributeIndex (info->parser)) != -1) {
        if (!info->document->ids) {
................................................................................
            info->document->ids = MALLOC (sizeof (Tcl_HashTable));
            Tcl_InitHashTable (info->document->ids, TCL_STRING_KEYS);
        }
        h = Tcl_CreateHashEntry (info->document->ids,
                                 atts[idatt+1],
                                 &hnew);
        /* if hnew isn't 1 this is a validation error. Hm, no clear way
           to report this. And more, xslt and xpath can process not
           valid XML, the spec mentioned this even within the context
           of id(). If some elements share the same ID, the first in
           document order should be used. Doing it this way, this is
           guaranteed for unchanged DOM trees. There are problems, if
           the DOM tree is changed, befor using id() */
        if (hnew) {
            Tcl_SetHashValue (h, node);
................................................................................
        idAttPtr = atts + idatt;
    } else {
        idAttPtr = NULL;
    }
    /* lastAttr already set right, either to NULL above, or to the last
       NS attribute */
    for (atPtr = atts; atPtr[0] && atPtr[1]; atPtr += 2) {

#ifdef TDOM_NS

        if (strncmp(atPtr[0], "xmlns", 5) == 0) {
            continue;
        }
#endif

        h = Tcl_CreateHashEntry(&HASHTAB(info->document, tdom_attrNames),
                                atPtr[0], &hnew);
        attrnode = (domAttrNode*) domAlloc(sizeof(domAttrNode));
        memset(attrnode, 0, sizeof(domAttrNode));
        attrnode->nodeType = ATTRIBUTE_NODE;
        if (atPtr == idAttPtr) {
            attrnode->nodeFlags |= IS_ID_ATTRIBUTE;
................................................................................
        } else {
            attrnode->nodeFlags = 0;
        }
        attrnode->namespace   = 0;
        attrnode->nodeName    = (char *)&(h->key);
        attrnode->parentNode  = node;
        len = strlen(atPtr[1]);
        if (TclOnly8Bits && info->encoding_8bit) {
            tdom_Utf8to8Bit(info->encoding_8bit, atPtr[1], &len);
        }
        attrnode->valueLength = len;
        attrnode->nodeValue   = (char*)MALLOC(len+1);
        strcpy(attrnode->nodeValue, (char *)atPtr[1]);

        if (node->firstAttr) {
            lastAttr->nextSibling = attrnode;
        } else {
            node->firstAttr = attrnode;
        }
        lastAttr = attrnode;

#ifdef TDOM_NS
        /*----------------------------------------------------------
        |   look for attribute namespace
        \---------------------------------------------------------*/
        domSplitQName (attrnode->nodeName, prefix, &localname);
        if (prefix[0] != '\0') {
            for (pos = info->activeNSpos; pos >= 0; pos--) {

                if (  ((prefix[0] == '\0') && (info->activeNS[pos].namespace->prefix[0] == '\0'))

                      || ((prefix[0] != '\0') && (info->activeNS[pos].namespace->prefix[0] != '\0')
                          && (strcmp(prefix, info->activeNS[pos].namespace->prefix) == 0))
                    ) {
                    attrnode->namespace = info->activeNS[pos].namespace->index;
                    DBG(fprintf(stderr, "attr='%s' uri='%s' \n",
                                attrnode->nodeName,
                                info->activeNS[pos].namespace->uri);
                        )
                    goto attrNSfound;
                }
            }
            if (strcmp (prefix, "xml")==0) {
                attrnode->namespace = 
                    info->document->rootNode->firstAttr->namespace;
            } else {
                /* Since where here, this means, the attribute has a
                   up to now not declared namespace prefix. We probably
                   should return this as an error, shouldn't we?*/
            }
        attrNSfound:
            ;
        }
#endif

    }

    info->depth++;
}

/*---------------------------------------------------------------------------
|   endElement
................................................................................
)
{
    domReadInfo  *info = userData;

    DispatchPCDATA (info);
    
    info->depth--;
#ifdef TDOM_NS
    /* pop active namespaces */
    while ( (info->activeNSpos >= 0) &&
            (info->activeNS[info->activeNSpos].depth == info->depth) )
    {
        info->activeNSpos--;
    }
#endif


    if (info->depth != -1) {
        info->currentNode = info->currentNode->parentNode;
    } else {
        info->currentNode = NULL;
    }

................................................................................
{
    domReadInfo   *info = userData;

    Tcl_DStringAppend (info->cdata, s, len);
    return;
    
}































/*---------------------------------------------------------------------------
|   DispatchPCDATA
|
\--------------------------------------------------------------------------*/
static void
DispatchPCDATA (
................................................................................
    domTextNode   *node;
    domNode       *parentNode;
    domLineColumn *lc;
    Tcl_HashEntry *h;
    char          *s;
    int            len, hnew;
    
    s = Tcl_DStringValue (info->cdata);
    len = Tcl_DStringLength (info->cdata);

    if (!len) return;
    
    if (TclOnly8Bits && info->encoding_8bit) {
        tdom_Utf8to8Bit( info->encoding_8bit, s, &len);
    }
    parentNode = info->currentNode;
    if (!parentNode) return;
    
    if (   parentNode->lastChild 
        && parentNode->lastChild->nodeType == TEXT_NODE) {


        /* normalize text node, i.e. there are no adjacent text nodes */
        node = (domTextNode*)parentNode->lastChild;
        node->nodeValue = REALLOC(node->nodeValue, node->valueLength + len);
        memmove(node->nodeValue + node->valueLength, s, len);
        node->valueLength += len;

................................................................................
        if (info->storeLineColumn) {
            node = (domTextNode*) domAlloc(sizeof(domTextNode)
                                            + sizeof(domLineColumn));
        } else {
            node = (domTextNode*) domAlloc(sizeof(domTextNode));
        }
        memset(node, 0, sizeof(domTextNode));



        node->nodeType    = TEXT_NODE;
        node->nodeFlags   = 0;
        node->namespace   = 0;
        node->nodeNumber  = NODE_NO(info->document);
        node->valueLength = len;
        node->nodeValue   = (char*)MALLOC(len);
        memmove(node->nodeValue, s, len);

        node->ownerDocument = info->document;
        node->parentNode = parentNode;
................................................................................
        DBG(fprintf (stderr, "commentHandler: insideDTD, skipping\n");)
        return;
    }

    DispatchPCDATA (info);

    len = strlen(s);
    if (TclOnly8Bits && info->encoding_8bit) {
        tdom_Utf8to8Bit(info->encoding_8bit, s, &len);
    }
    parentNode = info->currentNode;

    if (info->storeLineColumn) {
        node = (domTextNode*) domAlloc(sizeof(domTextNode)
                                        + sizeof(domLineColumn));
    } else {
        node = (domTextNode*) domAlloc(sizeof(domTextNode));
    }
    memset(node, 0, sizeof(domTextNode));
    node->nodeType    = COMMENT_NODE;
    node->nodeFlags   = 0;
    node->namespace   = 0;
    node->nodeNumber  = NODE_NO(info->document);
    node->valueLength = len;
    node->nodeValue   = (char*)MALLOC(len);
    memmove(node->nodeValue, s, len);

    node->ownerDocument = info->document;
    node->parentNode = parentNode;
................................................................................
                                 (char*) node,
                                 &hnew);
        Tcl_SetHashValue (h, tdomstrdup (XML_GetBase (info->parser)));
        node->nodeFlags |= HAS_BASEURI;
    }

    len = strlen(target);
    if (TclOnly8Bits && info->encoding_8bit) {
        tdom_Utf8to8Bit(info->encoding_8bit, target, &len);
    }
    node->targetLength = len;
    node->targetValue  = (char*)MALLOC(len);
    memmove(node->targetValue, target, len);

    len = strlen(data);
    if (TclOnly8Bits && info->encoding_8bit) {
        tdom_Utf8to8Bit(info->encoding_8bit, data, &len);
    }
    node->dataLength = len;
    node->dataValue  = (char*)MALLOC(len);
    memmove(node->dataValue, data, len);

    node->ownerDocument = info->document;
    node->parentNode = parentNode;
    if (parentNode == NULL) {
................................................................................
/*---------------------------------------------------------------------------
|  externalEntityRefHandler
|
\--------------------------------------------------------------------------*/
static int
externalEntityRefHandler (
    XML_Parser  parser,
    CONST char *openEntityNames,
    CONST char *base,
    CONST char *systemId,
    CONST char *publicId
)
{
    domReadInfo   *info = (domReadInfo *) XML_GetUserData (parser);

    Tcl_Obj *cmdPtr, *resultObj, *resultTypeObj, *extbaseObj, *xmlstringObj;
    Tcl_Obj *channelIdObj;
    int result, mode, done, byteIndex, i;

    size_t len;
    int tclLen;
    XML_Parser extparser, oldparser = NULL;
    char buf[4096], *resultType, *extbase, *xmlstring, *channelId, s[50];
    Tcl_Channel chan = (Tcl_Channel) NULL;




    if (info->document->extResolver == NULL) {
        Tcl_AppendResult (info->interp, "Can't read external entity \"",
                          systemId, "\": No -externalentitycommand given",
                          NULL);
        return 0;
    }
................................................................................
                                 Tcl_NewStringObj(publicId, strlen(publicId)));
    } else {
        Tcl_ListObjAppendElement(info->interp, cmdPtr,
                                 Tcl_NewObj());
    }

 
#if TclOnly8Bits
    result = Tcl_GlobalEvalObj(info->interp, cmdPtr);
#else
    result = Tcl_EvalObjEx (info->interp, cmdPtr, 
                            TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);
#endif

    Tcl_DecrRefCount(cmdPtr);

    if (result != TCL_OK) {

        return 0;
    }

    extparser = XML_ExternalEntityParserCreate (parser, openEntityNames, 0);

    resultObj = Tcl_GetObjResult (info->interp);
    Tcl_IncrRefCount (resultObj);
................................................................................
                       NULL);
        return 0;
    }

    oldparser = info->parser;
    info->parser = extparser;
    XML_SetBase (extparser, extbase);





    if (chan == NULL) {
        if (!XML_Parse(extparser, xmlstring, strlen (xmlstring), 1)) {


            Tcl_ResetResult (info->interp);
            sprintf(s, "%ld", XML_GetCurrentLineNumber(extparser));


            Tcl_AppendResult(info->interp, "error \"",
                             XML_ErrorString(XML_GetErrorCode(extparser)),
                             "\" in entity \"", systemId,
                             "\" at line ", s, " character ", NULL);
            sprintf(s, "%ld", XML_GetCurrentColumnNumber(extparser));
            Tcl_AppendResult(info->interp, s, NULL);
            byteIndex = XML_GetCurrentByteIndex(extparser);
            if (byteIndex != -1) {
                Tcl_AppendResult(info->interp, "\n\"", NULL);
                s[1] = '\0';
                for (i=-20; i < 40; i++) {
                    if ((byteIndex+i)>=0) {
                        if (xmlstring[byteIndex+i]) {
                            s[0] = xmlstring[byteIndex+i];
                            Tcl_AppendResult(info->interp, s, NULL);
                            if (i==0) {
                                Tcl_AppendResult(info->interp,
                                                 " <--Error-- ", NULL);
                            }
                        } else {
                            break;
                        }
                    }
                }
                Tcl_AppendResult(info->interp, "\"",NULL);
            } 
            Tcl_DecrRefCount (resultObj);
            XML_ParserFree (extparser);
            info->parser = oldparser;
            return 0;






        }










    } else {
        do {
            len = Tcl_Read (chan, buf, sizeof(buf));
            done = len < sizeof(buf);
            if (!XML_Parse (extparser, buf, len, done)) {


                Tcl_ResetResult (info->interp);
                sprintf(s, "%ld", XML_GetCurrentLineNumber(extparser));


                Tcl_AppendResult(info->interp, "error \"",
                                 XML_ErrorString(XML_GetErrorCode(extparser)),
                                 "\" in entity \"", systemId,
                                 "\" at line ", s, " character ", NULL);
                sprintf(s, "%ld", XML_GetCurrentColumnNumber(extparser));
                Tcl_AppendResult(info->interp, s, NULL);
                Tcl_DecrRefCount (resultObj);
                XML_ParserFree (extparser);
                info->parser = oldparser;
                return 0;






            }












        } while (!done);
    }


    DispatchPCDATA (info);




    XML_ParserFree (extparser);
    info->parser = oldparser;


    Tcl_DecrRefCount (resultObj);
    Tcl_ResetResult (info->interp);
    return 1;

 wrongScriptResult:
    Tcl_DecrRefCount (resultObj);
    Tcl_ResetResult (info->interp);
    XML_ParserFree (extparser);
    if (oldparser) {
        info->parser = oldparser;
    }

    Tcl_AppendResult (info->interp, "The -externalentitycommand script "
                      "has to return a Tcl list with 3 elements.\n"
                      "Syntax: {string|channel|filename <baseurl> <data>}\n",
                      NULL);
    return 0;
}

................................................................................
\--------------------------------------------------------------------------*/
domDocument *
domReadDocument (
    XML_Parser  parser,
    char       *xml,
    int         length,
    int         ignoreWhiteSpaces,
    TEncoding  *encoding_8bit,
    int         storeLineColumn,

    int         feedbackAfter,

    Tcl_Channel channel,
    const char *baseurl,
    char       *extResolver,
    int         useForeignDTD,
    int         paramEntityParsing,
    Tcl_Interp *interp

)
{
    int            done, tclLen;

    size_t         len;
    domReadInfo    info;
    char           buf[8192];
#if !TclOnly8Bits
    Tcl_Obj       *bufObj;
    Tcl_DString    dStr;
    int            useBinary;
    char          *str;
#endif
    domDocument   *doc = domCreateDoc(baseurl, storeLineColumn);

    doc->extResolver = extResolver;






    info.parser               = parser;
    info.document             = doc;
    info.currentNode          = NULL;
    info.depth                = 0;
    info.ignoreWhiteSpaces    = ignoreWhiteSpaces;
    info.cdata                = (Tcl_DString*) MALLOC (sizeof (Tcl_DString));
    Tcl_DStringInit (info.cdata);
    info.encoding_8bit        = encoding_8bit;
    info.storeLineColumn      = storeLineColumn;

    info.feedbackAfter        = feedbackAfter;

    info.lastFeedbackPosition = 0;
    info.interp               = interp;
    info.activeNSpos          = -1;
    info.activeNSsize         = 8;
    info.activeNS             = (domActiveNS*) MALLOC (sizeof(domActiveNS) 
                                                       * info.activeNSsize);
    info.baseURIstackPos      = 0;
    info.baseURIstackSize     = INITIAL_BASEURISTACK_SIZE;
    info.baseURIstack         = (domActiveBaseURI*) 
        MALLOC (sizeof(domActiveBaseURI) * info.baseURIstackSize);
    info.insideDTD            = 0;


    XML_SetUserData(parser, &info);
    XML_SetBase (parser, baseurl);
    /* We must use XML_GetBase(), because XML_SetBase copies the baseURI,
       and we want to compare the pointers */
    info.baseURIstack[0].baseURI = XML_GetBase (parser);
    info.baseURIstack[0].depth = 0;
................................................................................
    if (extResolver) {
        XML_SetExternalEntityRefHandler (parser, externalEntityRefHandler);
    }
    XML_SetParamEntityParsing (parser, 
                             (enum XML_ParamEntityParsing) paramEntityParsing);
    XML_SetDoctypeDeclHandler (parser, startDoctypeDeclHandler,
                               endDoctypeDeclHandler);





    if (channel == NULL) {
        if (!XML_Parse(parser, xml, length, 1)) {









            FREE ( info.activeNS );
            FREE ( info.baseURIstack );
            Tcl_DStringFree (info.cdata);
            FREE ( info.cdata);
            domFreeDocument (doc, NULL, NULL);

            return NULL;


        }
    } else {
#if !TclOnly8Bits
        Tcl_DStringInit (&dStr);
        if (Tcl_GetChannelOption (interp, channel, "-encoding", &dStr) != TCL_OK) {
            FREE ( (char*) info.activeNS );
            FREE ( info.baseURIstack );
            Tcl_DStringFree (info.cdata);
            FREE ( info.cdata);
            domFreeDocument (doc, NULL, NULL);

            return NULL;
        }
        if (strcmp (Tcl_DStringValue (&dStr), "identity")==0 ) useBinary = 1;
        else useBinary = 0;
        Tcl_DStringFree (&dStr);
        if (useBinary) {
            do {
                len = Tcl_Read (channel, buf, sizeof(buf));
                done = len < sizeof(buf);
                if (!XML_Parse (parser, buf, len, done)) {









                    FREE ( info.activeNS );
                    FREE ( info.baseURIstack );
                    Tcl_DStringFree (info.cdata);
                    FREE ( info.cdata);
                    domFreeDocument (doc, NULL, NULL);

                    return NULL;


                }
            } while (!done);
        } else {
            bufObj = Tcl_NewObj();
            Tcl_SetObjLength (bufObj, 6144);
            do {
                len = Tcl_ReadChars (channel, bufObj, 1024, 0);
                done = (len < 1024);
                str = Tcl_GetStringFromObj(bufObj, &tclLen);
                if (!XML_Parse (parser, str, tclLen, done)) {









                    FREE ( info.activeNS );
                    FREE ( info.baseURIstack );
                    Tcl_DStringFree (info.cdata);
                    FREE ( info.cdata);
                    domFreeDocument (doc, NULL, NULL);
                    Tcl_DecrRefCount (bufObj);

                    return NULL;


                }
            } while (!done);
            Tcl_DecrRefCount (bufObj);
        }
#else
        do {
            len = Tcl_Read (channel, buf, sizeof(buf));
            done = len < sizeof(buf);
            if (!XML_Parse (parser, buf, len, done)) {
                FREE ( info.activeNS );
                FREE ( info.baseURIstack );
                domFreeDocument (doc, NULL, NULL);
                Tcl_DStringFree (info.cdata);
                FREE ( info.cdata);
                return NULL;
            }
        } while (!done);
#endif
    }
    FREE ( info.activeNS );
    FREE ( info.baseURIstack );
    Tcl_DStringFree (info.cdata);
    FREE ( info.cdata);

    domSetDocumentElement (doc);
................................................................................
        *column = lc->column;
        return 0;
    } else {
        return -1;
    }
}

#ifdef TDOM_NS
domAttrNode *
domCreateXMLNamespaceNode (
    domNode  *parent
)
{
    Tcl_HashEntry  *h;
    int             hnew;
................................................................................
    attr->namespace     = ns->index;
    attr->nodeName      = (char *)&(h->key);
    attr->parentNode    = parent;
    attr->valueLength   = strlen (XML_NAMESPACE);
    attr->nodeValue     = tdomstrdup (XML_NAMESPACE);
    return attr;
}
#endif /* TDOM_NS */

 
/*
 *----------------------------------------------------------------------
 *
 * domCreateDoc --
 *
................................................................................
 *----------------------------------------------------------------------
 */

domDocument *
domCreateDoc (
    const char * baseURI,
    int          storeLineColumn
    )
{
    Tcl_HashEntry *h;
    int            hnew;
    domNode       *rootNode;
    domDocument   *doc;
    domLineColumn *lc;

................................................................................
    memset(doc, 0, sizeof(domDocument));
    doc->nodeType       = DOCUMENT_NODE;
    doc->documentNumber = DOC_NO(doc);
    doc->nsptr          = -1;
    doc->nslen          =  4;
    doc->namespaces     = (domNS**) MALLOC (sizeof (domNS*) * doc->nslen);
    
    /* We malloc and initialze the baseURIs hash table here to avoid
       cluttering of the code all over the place with checks. */
    doc->baseURIs = MALLOC (sizeof (Tcl_HashTable));
    Tcl_InitHashTable (doc->baseURIs, TCL_ONE_WORD_KEYS);

    TDomThreaded(
        domLocksAttach(doc);
        Tcl_InitHashTable(&doc->tdom_tagNames, TCL_STRING_KEYS);
................................................................................
    rootNode->namespace     = 0;
    h = Tcl_CreateHashEntry(&HASHTAB(doc,tdom_tagNames), "", &hnew);
    rootNode->nodeName      = (char *)&(h->key);
    rootNode->nodeNumber    = NODE_NO(doc);
    rootNode->ownerDocument = doc;
    rootNode->parentNode    = NULL;
    rootNode->firstChild    = rootNode->lastChild = NULL;
#ifdef TDOM_NS
    rootNode->firstAttr     = domCreateXMLNamespaceNode (rootNode);
#endif
    if (storeLineColumn) {
        lc = (domLineColumn*) ( ((char*)rootNode) + sizeof(domNode));
        rootNode->nodeFlags |= HAS_LINE_COLUMN;
        lc->line            = 0;
        lc->column          = 0;
    }
    doc->rootNode = rootNode;
................................................................................

/*---------------------------------------------------------------------------
|   domCreateDocument
|
\--------------------------------------------------------------------------*/
domDocument *
domCreateDocument (
    Tcl_Interp *interp,
    const char *uri,
    char       *documentElementTagName
)
{
    Tcl_HashEntry *h;
    int            hnew;
    domNode       *node;
................................................................................
    const char    *localName;
    domNS         *ns = NULL;

    if (uri) {
        domSplitQName (documentElementTagName, prefix, &localName);
        DBG(fprintf(stderr, 
                    "rootName: -->%s<--, prefix: -->%s<--, localName: -->%s<--\n", 
                    documentElementTagName, prefix, localName);)
        if (prefix[0] != '\0') {
            if (!domIsNCNAME (prefix)) {
                if (interp) {
                    Tcl_SetObjResult(interp, 
                                     Tcl_NewStringObj("invalid prefix name", -1));
                }
                return NULL;
            }
        }
        if (!domIsNCNAME (localName)) {
            if (interp) {
                Tcl_SetObjResult(interp, 
                                 Tcl_NewStringObj("invalid local name", -1));
            }
            return NULL;
        }
    } else {
        if (!domIsNAME (documentElementTagName)) {
            if (interp) {
                Tcl_SetObjResult(interp, 
                                 Tcl_NewStringObj("invalid root element name", -1));
            }
            return NULL;
        }
    }
    doc = domCreateDoc (NULL, 0);

    h = Tcl_CreateHashEntry(&HASHTAB(doc, tdom_tagNames),
                            documentElementTagName, &hnew);
    node = (domNode*) domAlloc(sizeof(domNode));
    memset(node, 0, sizeof(domNode));
................................................................................
    \---------------------------------------------------------------*/
    if (freeCB) {
        freeCB(node, clientData);
    }
    TDomThreaded (    
        if (shared) {
            if (doc->deletedNodes) {
                doc->deletedNodes->nextDeleted = node;
            } else {
                doc->deletedNodes = node;
            }

            node->nodeFlags |= IS_DELETED;
            node->nextDeleted = NULL;
        }
    )
    MutationEvent3(DOMNodeRemoved, childToRemove, node);
    MutationEvent2(DOMSubtreeModified, node);
    domFreeNode(node, freeCB, clientData, 0);

    return OK;
................................................................................
        FREE (Tcl_GetHashValue (entryPtr));
        entryPtr = Tcl_NextHashEntry (&search);
    }
    Tcl_DeleteHashTable (doc->baseURIs);
    FREE (doc->baseURIs);
    
    /*-----------------------------------------------------------
    | delete xpath cache hash table
    \-----------------------------------------------------------*/
    if (doc->xpathCache) {
        entryPtr = Tcl_FirstHashEntry (doc->xpathCache, &search);
        while (entryPtr) {
            xpathFreeAst((ast)Tcl_GetHashValue (entryPtr));
            entryPtr = Tcl_NextHashEntry (&search);
        }
................................................................................
            if (!attr->namespace) {
                if (strcmp (attr->nodeName, localName)==0) break;
            }
        }
        attr = attr->nextSibling;
    }
    if (attr) {
        DBG(fprintf (stderr, "domSetAttributeNS: reseting existing attribute %s ; old value: %s\n", attr->nodeName, attr->nodeValue);)
        if (attr->nodeFlags & IS_ID_ATTRIBUTE) {
            h = Tcl_FindHashEntry (node->ownerDocument->ids, attr->nodeValue);
            if (h) {
                Tcl_DeleteHashEntry (h);
                h = Tcl_CreateHashEntry (node->ownerDocument->ids,
                                         attributeValue, &hnew);
                Tcl_SetHashValue (h, node);
................................................................................
    }

    attr = node->firstAttr;
    while (attr) {
        domSplitQName (attr->nodeName, prefix, &str);
        if (strcmp(localName,str)==0) {
            ns = domGetNamespaceByIndex(node->ownerDocument, attr->namespace);
            if (strcmp(ns->uri, uri)==0) {
                if (previous) {
                    previous->nextSibling = attr->nextSibling;
                } else {
                    attr->parentNode->firstAttr = attr->nextSibling;
                }

                if (attr->nodeFlags & IS_ID_ATTRIBUTE) {
................................................................................
{
    domTextNode   *node;

    node = (domTextNode*) domAlloc(sizeof(domTextNode));
    memset(node, 0, sizeof(domTextNode));
    node->nodeType      = nodeType;
    node->nodeFlags     = 0;
    node->namespace     = 0;
    node->nodeNumber    = NODE_NO(doc);
    node->ownerDocument = doc;
    node->valueLength   = length;
    node->nodeValue     = (char*)MALLOC(length);
    memmove(node->nodeValue, value, length);

    if (doc->fragments) {
................................................................................
    node = (domTextNode*) domAlloc(sizeof(domTextNode));
    memset(node, 0, sizeof(domTextNode));
    node->nodeType      = nodeType;
    node->nodeFlags     = 0;
    if (disableOutputEscaping) {
        node->nodeFlags |= DISABLE_OUTPUT_ESCAPING;
    }
    node->namespace     = 0;
    node->nodeNumber    = NODE_NO(parent->ownerDocument);
    node->ownerDocument = parent->ownerDocument;
    node->valueLength   = length;
    node->nodeValue     = (char*)MALLOC(length);
    memmove(node->nodeValue, value, length);

    if (parent->lastChild) {
................................................................................
/*---------------------------------------------------------------------------
|   domNewElementNode
|
\--------------------------------------------------------------------------*/
domNode *
domNewElementNode(
    domDocument *doc,
    const char  *tagName,
    domNodeType  nodeType		
)
{
    domNode       *node;
    Tcl_HashEntry *h;
    int           hnew;

    h = Tcl_CreateHashEntry(&HASHTAB(doc, tdom_tagNames), tagName, &hnew);
    node = (domNode*) domAlloc(sizeof(domNode));
    memset(node, 0, sizeof(domNode));
    node->nodeType      = nodeType;
    node->nodeFlags     = 0;
    node->namespace     = 0;
    node->nodeNumber    = NODE_NO(doc);
    node->ownerDocument = doc;
    node->nodeName      = (char *)&(h->key);

    if (doc->fragments) {
................................................................................
|   domNewElementNodeNS
|
\--------------------------------------------------------------------------*/
domNode *
domNewElementNodeNS (
    domDocument *doc,
    const char  *tagName,
    const char  *uri,
    domNodeType  nodeType		
)
{
    domNode       *node;
    Tcl_HashEntry *h;
    int            hnew;
    char           prefix[MAX_PREFIX_LEN];
    const char    *localname;
    domNS         *ns;






    h = Tcl_CreateHashEntry(&HASHTAB(doc, tdom_tagNames), tagName, &hnew);
    node = (domNode*) domAlloc(sizeof(domNode));
    memset(node, 0, sizeof(domNode));
    node->nodeType      = nodeType;
    node->nodeFlags     = 0;
    node->namespace     = 0;
    node->nodeNumber    = NODE_NO(doc);
    node->ownerDocument = doc;
    node->nodeName      = (char *)&(h->key);

    domSplitQName (tagName, prefix, &localname);
    ns = domNewNamespace(doc, prefix, uri);
    node->namespace = ns->index;

    if (doc->fragments) {
        node->nextSibling = doc->fragments;
        doc->fragments->previousSibling = node;
        doc->fragments = node;
................................................................................
                                         pinode->ownerDocument,
                                         pinode->targetValue,
                                         pinode->targetLength,
                                         pinode->dataValue,
                                         pinode->dataLength);
    }
    if (node->nodeType != ELEMENT_NODE) {
        domTextNode *tnode = (domTextNode*)node;







        return (domNode*) domNewTextNode(tnode->ownerDocument,
                                         tnode->nodeValue, tnode->valueLength,
					 tnode->nodeType);
    }


    n = domNewElementNode(node->ownerDocument, node->nodeName, node->nodeType);
    n->namespace = node->namespace;



    /*------------------------------------------------------------------
    |   copy attributes (if any)
    \-----------------------------------------------------------------*/
    attr = node->firstAttr;
    while (attr != NULL) {
        nattr = domSetAttribute (n, attr->nodeName, attr->nodeValue );
................................................................................
    \-----------------------------------------------------------------*/
    attr = node->firstAttr;
    while (attr != NULL) {
        if (attr->nodeFlags & IS_NS_NODE) {
            if (copyNS) {
                /* If copyNS is true, then all namespaces in scope
                 * (including the one declared with the node to copy)
                 * are allready copied over. */
                attr = attr->nextSibling;
                continue;
                
            }
            ns = node->ownerDocument->namespaces[attr->namespace-1];
            ns1 = domLookupPrefix (n, ns->prefix);
            if (ns1 && strcmp (ns->uri, ns1->uri)==0) {
................................................................................
    int            attrLen,
    domAddCallback addCallback,
    void         * clientData
)
{
    domNode     *ancestor;
    domAttrNode *attr;
    int          found=0, result;


    ancestor = node->parentNode;
    if (ancestor) {
        found = 0;
        if ((type == ALL_NODES) || (ancestor->nodeType == type)) {
            if ((element == NULL) ||
                ((ancestor->nodeType == ELEMENT_NODE) && (strcmp(ancestor->nodeName,element)==0))
               ) {
                if (attrName == NULL) {
                    *i = (instance<0) ? (*i)-1 : (*i)+1;
                    if (all || (*i == instance)) {
                        result = addCallback (ancestor, clientData);
                        if (result) {
                            return result;
                        }
                        found = 1;
                    }
                } else {
                    attr = ancestor->firstAttr;
                    while (attr) {
                        if ((strcmp(attr->nodeName,attrName)==0) &&
                            ( (strcmp(attrValue,"*")==0) ||
                              ( (attr->valueLength == attrLen) &&
................................................................................
                           ) {
                            *i = (instance<0) ? (*i)-1 : (*i)+1;
                            if (all || (*i == instance)) {
                                result = addCallback (ancestor, clientData);
                                if (result) {
                                    return result;
                                }
                                found = 1;
                            }
                        }
                        attr = attr->nextSibling;
                    }
                }
            }
        }
................................................................................
typedef struct _tdomCmdReadInfo {

    XML_Parser        parser;
    domDocument      *document;
    domNode          *currentNode;
    int               depth;
    int               ignoreWhiteSpaces;

    Tcl_DString      *cdata;
    TEncoding        *encoding_8bit;
    int               storeLineColumn;

    int               feedbackAfter;

    int               lastFeedbackPosition;
    Tcl_Interp       *interp;
    int               activeNSsize;
    int               activeNSpos;
    domActiveNS      *activeNS;
    int               baseURIstackSize;
    int               baseURIstackPos;
    domActiveBaseURI *baseURIstack;
................................................................................
        domFreeDocument (info->document, NULL, NULL);
    }

    info->document          = NULL;
    info->currentNode       = NULL;
    info->depth             = 0;
    info->feedbackAfter     = 0;

    Tcl_DStringSetLength (info->cdata, 0);
    info->lastFeedbackPosition = 0;
    info->interp            = interp;
    info->activeNSpos       = -1;
    info->insideDTD         = 0;
    info->baseURIstackPos   = 0;
    info->tdomStatus        = 0;

}
................................................................................
}

int
TclTdomObjCmd (dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *CONST objv[];
{
    char            *method, *encodingName;
    CHandlerSet     *handlerSet;
    int              methodIndex, result, bool;
    tdomCmdReadInfo *info;
    TclGenExpatInfo *expat;
    Tcl_Obj         *newObjName = NULL;
    TEncoding       *encoding;

    static CONST84 char *tdomMethods[] = {
        "enable", "getdoc",
        "setResultEncoding", "setStoreLineColumn",
        "setExternalEntityResolver", "keepEmpties",
        "remove",
        NULL
    };
    enum tdomMethod {
        m_enable, m_getdoc,
        m_setResultEncoding, m_setStoreLineColumn,
        m_setExternalEntityResolver, m_keepEmpties,
        m_remove
    };

    if (objc < 3 || objc > 4) {
        Tcl_WrongNumArgs (interp, 1, objv, tdom_usage);
        return TCL_ERROR;
    }

    if (!CheckExpatParserObj (interp, objv[1])) {
        Tcl_SetResult (interp, "First argument has to be a expat parser object", NULL);
        return TCL_ERROR;
    }

    method = Tcl_GetString(objv[2]);
    if (Tcl_GetIndexFromObj (interp, objv[2], tdomMethods, "method", 0,
                             &methodIndex) != TCL_OK)
    {
        Tcl_SetResult (interp, tdom_usage, NULL);
        return TCL_ERROR;
    }

................................................................................
    switch ((enum tdomMethod) methodIndex) {

    default:
        Tcl_SetResult (interp, "unknown method", NULL);
        return TCL_ERROR;

    case m_enable:







        handlerSet = CHandlerSetCreate ("tdom");
        handlerSet->ignoreWhiteCDATAs       = 1;
        handlerSet->resetProc               = tdom_resetProc;
        handlerSet->freeProc                = tdom_freeProc;
        handlerSet->parserResetProc         = tdom_parserResetProc;
        handlerSet->initParseProc           = tdom_initParseProc;
        handlerSet->elementstartcommand     = startElement;
................................................................................
/*         handlerSet->datacommand             = characterDataHandler; */
        handlerSet->commentCommand          = commentHandler;
        handlerSet->picommand               = processingInstructionHandler;
        handlerSet->entityDeclCommand       = entityDeclHandler;
        handlerSet->startDoctypeDeclCommand = startDoctypeDeclHandler;
        handlerSet->endDoctypeDeclCommand   = endDoctypeDeclHandler;

        expat = GetExpatInfo (interp, objv[1]);

        info = (tdomCmdReadInfo *) MALLOC (sizeof (tdomCmdReadInfo));
        info->parser            = expat->parser;
        info->document          = NULL;
        info->currentNode       = NULL;
        info->depth             = 0;
        info->ignoreWhiteSpaces = 1;

        info->cdata             = (Tcl_DString*) MALLOC (sizeof (Tcl_DString));
        Tcl_DStringInit (info->cdata);
        info->encoding_8bit     = 0;
        info->storeLineColumn   = 0;

        info->feedbackAfter     = 0;

        info->lastFeedbackPosition = 0;
        info->interp            = interp;
        info->activeNSpos       = -1;
        info->activeNSsize      = 8;
        info->activeNS          = 
            (domActiveNS*) MALLOC(sizeof(domActiveNS) * info->activeNSsize);
        info->baseURIstackPos   = 0;
        info->baseURIstackSize  = INITIAL_BASEURISTACK_SIZE;
................................................................................
        info = CHandlerSetGetUserData (interp, objv[1], "tdom");
        if (!info) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
        expat = GetExpatInfo (interp, objv[1]);
        if (info->tdomStatus != 2 || !expat->finished) {
            Tcl_SetResult (interp, "No DOM tree avaliable.", NULL);
            return TCL_ERROR;
        }
        domSetDocumentElement (info->document);
        result = tcldom_returnDocumentObj (interp, info->document, 0,
                                           newObjName, 0, 0);
        info->document = NULL;
        return result;

    case m_setResultEncoding:
        info = CHandlerSetGetUserData (interp, objv[1], "tdom");
        if (!info) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
        if (info->encoding_8bit == NULL) {
            Tcl_AppendResult (interp, "UTF-8", NULL);
        }
        else {
            Tcl_AppendResult (interp,
                              tdom_GetEncodingName (info->encoding_8bit),
                              NULL);
        }
        if (objc == 4) {
            encodingName = Tcl_GetString(objv[3]);

            if (   (strcmp(encodingName, "UTF-8") == 0)
                 ||(strcmp(encodingName, "UTF8" ) == 0)
                 ||(strcmp(encodingName, "utf-8") == 0)
                 ||(strcmp(encodingName, "utf8" ) == 0)) {

                info->encoding_8bit = NULL;
            } else {
                encoding = tdom_GetEncoding ( encodingName );
                if (encoding == NULL) {
                    Tcl_AppendResult(interp, "encoding not found", NULL);
                    return TCL_ERROR;
                }
                info->encoding_8bit = encoding;
            }
        }
        info->tdomStatus = 1;
        break;
        
    case m_setStoreLineColumn:
        info = CHandlerSetGetUserData (interp, objv[1], "tdom");
        if (!info) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
        Tcl_SetIntObj (Tcl_GetObjResult (interp), info->storeLineColumn);
        if (objc == 4) {
            Tcl_GetBooleanFromObj (interp, objv[3], &bool);


            info->storeLineColumn = bool;
        }
        info->tdomStatus = 1;
        break;
        
    case m_remove:
        result = CHandlerSetRemove (interp, objv[1], "tdom");
................................................................................
            Tcl_SetResult (interp, "expat parser obj hasn't a C handler set named \"tdom\"", NULL);
            return TCL_ERROR;
        }
        break;

    case m_setExternalEntityResolver:
        if (objc != 4) {
            Tcl_SetResult (interp, "You must name a tcl command as external entity resolver for setExternalEntityResolver.", NULL);
            return TCL_ERROR;
        }
        info = CHandlerSetGetUserData (interp, objv[1], "tdom");
        if (!info) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
................................................................................
    case m_keepEmpties:
        if (objc != 4) {
            Tcl_SetResult (interp, "wrong # of args for method keepEmpties.",
                           NULL);
            return TCL_ERROR;
        }
        handlerSet = CHandlerSetGet (interp, objv[1], "tdom");




        info = handlerSet->userData;
        if (!info) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
        Tcl_SetIntObj (Tcl_GetObjResult (interp), info->ignoreWhiteSpaces);
        Tcl_GetBooleanFromObj (interp, objv[3], &bool);


        info->ignoreWhiteSpaces = !bool;
        handlerSet->ignoreWhiteCDATAs = !bool;
        info->tdomStatus = 1;
        break;
    }
















































    return TCL_OK;
}







<
<


<



<
>
|
|

|
>
|
>
|
<
>







 







|







 







<



<
<
<
<
<
<
<
<
<
<
<
<







 







>

<

>

>
|








>







 







>






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







>
>
>
>
>












<







 







|







 







>




>







 







<


>




>







 







<


>



>







 







|







 







|








|
|

>
>
>
|
|
>
>

|
<
<
<
<
<
>
>
>

|
>
>







 







|
|

|
|
|
|
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
<
<
<
|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
>
|
>
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>
>
>
>
|
|
>
|
<







 







|







 







<
<
>
|
|
|
<
>







 







<
<
<











|
|
|
|
|
|
|
>
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
>







 







|
|
|
|
|
|
|
<
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<

>
|

<
<
<


|

|
>







 







>
>
>
|

<







 







<
<
<











<







 







<
<
<





<
<
<







 







|
|
|
|







>





>
>
>







 







<
<
<


<




>







 







>
>

>
>

|
>
>
|

>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>




|
>
>
|

>
>
|
|
|
|
|
|
<
<
<
<
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>



>
|
|
>
>
>


<
>

<
|








>







 







|

>

>


|


|
>


|
>
|
|
|
<
|
|
|
|
<
|

|
>
>
>
>
>








|

>

>
|










>







 







>
>
|
>
>

|
>
>
>
>
>
>
>
>
>





>

>
>


<







>


|






|
>
>
>
>
>
>
>
>
>





>

>
>









|
>
>
>
>
>
>
>
>
>






>

>
>




<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<







 







<







 







|







 







|







 







<

<







 







<







 







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|

|

>

<







 







|







 







|







 







|







 







<







 







<







 







|
<









|







 







|
<








>
>
>
>
>




|






<







 







|
>
>
>
>
>
>
>
|
|
|
|
|
>
|

<
>







 







|







 







|




<











<







 







<







 







>

<

>

>
|







 







>

|







 







|

<





<

|

|

|




|

|












<







 







>
>
>
>
>
>
>







 







<
<






>


<

>

>
|







 







|








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








|
>
>







 







|







 







>
>
>
>






|
>
>




|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


43
44
45
46
47
48
49


50
51

52
53
54

55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
..
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
107
108
109
110
111
112
113

114
115
116












117
118
119
120
121
122
123
...
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
...
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
...
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
...
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574

575
576
577
578
579
580
581
...
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
...
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
...
888
889
890
891
892
893
894

895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
...
916
917
918
919
920
921
922

923
924
925
926
927
928
929
930
931
932
933
934
935
936
....
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
....
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106





1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
....
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234



1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282

1283
1284
1285
1286
1287
1288
1289
1290

1291
1292
1293
1294
1295
1296
1297
....
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
....
1314
1315
1316
1317
1318
1319
1320


1321
1322
1323
1324

1325
1326
1327
1328
1329
1330
1331
1332
....
1333
1334
1335
1336
1337
1338
1339



1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382

1383
1384
1385
1386
1387
1388
1389
1390
....
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410

1411
1412
1413
1414
1415
1416
1417
1418
....
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
....
1483
1484
1485
1486
1487
1488
1489

1490
1491
1492
1493



1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
....
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540

1541
1542
1543
1544
1545
1546
1547
....
1596
1597
1598
1599
1600
1601
1602



1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613

1614
1615
1616
1617
1618
1619
1620
....
1702
1703
1704
1705
1706
1707
1708



1709
1710
1711
1712
1713



1714
1715
1716
1717
1718
1719
1720
....
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
....
1846
1847
1848
1849
1850
1851
1852



1853
1854

1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
....
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959




1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993




1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023

2024
2025

2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
....
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113

2114
2115
2116
2117

2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
....
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197

2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266














2267
2268
2269
2270
2271
2272
2273
....
2335
2336
2337
2338
2339
2340
2341

2342
2343
2344
2345
2346
2347
2348
....
2359
2360
2361
2362
2363
2364
2365

2366
2367
2368
2369
2370
2371
2372
....
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
....
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
....
2431
2432
2433
2434
2435
2436
2437

2438

2439
2440
2441
2442
2443
2444
2445
....
2449
2450
2451
2452
2453
2454
2455

2456
2457
2458
2459
2460
2461
2462
....
2465
2466
2467
2468
2469
2470
2471
2472
























2473
2474
2475
2476
2477
2478
2479
....
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691

2692
2693
2694
2695
2696
2697
2698
....
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
....
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
....
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
....
3913
3914
3915
3916
3917
3918
3919

3920
3921
3922
3923
3924
3925
3926
....
4006
4007
4008
4009
4010
4011
4012

4013
4014
4015
4016
4017
4018
4019
....
4463
4464
4465
4466
4467
4468
4469
4470

4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
....
4500
4501
4502
4503
4504
4505
4506
4507

4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531

4532
4533
4534
4535
4536
4537
4538
....
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587

4588
4589
4590
4591
4592
4593
4594
4595
....
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
....
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076

5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087

5088
5089
5090
5091
5092
5093
5094
....
5098
5099
5100
5101
5102
5103
5104

5105
5106
5107
5108
5109
5110
5111
....
5131
5132
5133
5134
5135
5136
5137
5138
5139

5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
....
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
....
5262
5263
5264
5265
5266
5267
5268
5269
5270

5271
5272
5273
5274
5275

5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300

5301
5302
5303
5304
5305
5306
5307
....
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
....
5331
5332
5333
5334
5335
5336
5337


5338
5339
5340
5341
5342
5343
5344
5345
5346

5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
....
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386



































5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
....
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
....
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507


/*---------------------------------------------------------------------------
|   Includes
|
\--------------------------------------------------------------------------*/
#include <tcl.h>


#include <dom.h>
#include <domxpath.h>

#include <tclexpat.h>



/* #define DEBUG */
/*----------------------------------------------------------------------------
|   Debug Macros
|
\---------------------------------------------------------------------------*/
#ifdef DEBUG
# define DBG(x) x
#else
# define DBG(x) 

#endif

#define MutationEvent()
#define MutationEvent2(type,node)
#define MutationEvent3(type,node,relatioNode)

#define MCHK(a)  if ((a)==NULL) { \
                     fprintf(stderr, \
................................................................................
#endif

static int domModuleIsInitialized = 0;
TDomThreaded(static Tcl_Mutex initMutex;)

static char *domException2StringTable [] = {

    "OK - no exception",
    "INDEX_SIZE_ERR",
    "DOMSTRING_SIZE_ERR",
    "HIERARCHY_REQUEST_ERR",
    "WRONG_DOCUMENT_ERR",
    "INVALID_CHARACTER_ERR",
    "NO_DATA_ALLOWED_ERR",
    "NO_MODIFICATION_ALLOWED_ERR",
................................................................................
    "INUSE_ATTRIBUTE_ERR"
};

static char tdom_usage[] =
                "Usage tdom <expat parser obj> <subCommand>, where subCommand can be:\n"
                "           enable             \n"
                "           getdoc             \n"

                "           setStoreLineColumn \n"
                ;













/*---------------------------------------------------------------------------
|   type domBaseURIstackElem
|
\--------------------------------------------------------------------------*/
typedef struct _domActiveBaseURI {

    int   depth;
................................................................................
typedef struct _domReadInfo {

    XML_Parser        parser;
    domDocument      *document;
    domNode          *currentNode;
    int               depth;
    int               ignoreWhiteSpaces;
    int               cdataSection;
    Tcl_DString      *cdata;

    int               storeLineColumn;
    int               ignorexmlns;
    int               feedbackAfter;
    Tcl_Obj          *feedbackCmd;
    XML_Index         nextFeedbackPosition;
    Tcl_Interp       *interp;
    int               activeNSsize;
    int               activeNSpos;
    domActiveNS      *activeNS;
    int               baseURIstackSize;
    int               baseURIstackPos;
    domActiveBaseURI *baseURIstack;
    int               insideDTD;
    int               status;

} domReadInfo;

/*----------------------------------------------------------------------------
|   Prototypes
|
\---------------------------------------------------------------------------*/
................................................................................
{
    const char *p;
    int   clen;
    
    p = str;
    while (*p) {
        clen = UTF8_CHAR_LEN(*p);
        if (clen > 4) return 0;
        if (UTF8_XMLCHAR((unsigned const char *)p,clen))
            p += clen;
        else return 0;
    }
    return 1;
}

/*---------------------------------------------------------------------------
|   domIsBMPChar 
|
\--------------------------------------------------------------------------*/
int
domIsBMPChar (
    const char *str
    )
{
    const char *p;
    int   clen;
    
    p = str;
    while (*p) {
        clen = UTF8_CHAR_LEN(*p);
        if (clen > 3 || clen == 0) return 0;
        p += clen;
    }
    return 1;
}

/*---------------------------------------------------------------------------
|   domIsComment
|
\--------------------------------------------------------------------------*/
int
domIsComment (
................................................................................

int
domPrecedes (
    domNode *node,
    domNode *other
    )
{
    domNode *nodeAncestor, *otherAncestor;
    domAttrNode *attrN, *attrO;
    
    if (node == other) {
        return 0;
    }
    
    if (node->nodeType == ATTRIBUTE_NODE) {
................................................................................
#ifndef TCL_THREADS
    if (node->ownerDocument->nodeFlags & NEEDS_RENUMBERING) {
        domRenumberTree (node->ownerDocument->rootNode);
        node->ownerDocument->nodeFlags &= ~NEEDS_RENUMBERING;
    }
    return (node->nodeNumber < other->nodeNumber);
# else 
    if (node->ownerDocument->nodeFlags & NEEDS_RENUMBERING
        && node->ownerDocument->refCount <= 1) {
        domRenumberTree (node->ownerDocument->rootNode);
        node->ownerDocument->nodeFlags &= ~NEEDS_RENUMBERING;
    }
    if (!(node->ownerDocument->nodeFlags & NEEDS_RENUMBERING)) {
        return (node->nodeNumber < other->nodeNumber);
    }
#endif
    
    otherAncestor = other;
    while (otherAncestor->parentNode) {
        otherAncestor = otherAncestor->parentNode;
        if (otherAncestor == node) {
            return 1;
        }
    }

    
    nodeAncestor = node;
    while (nodeAncestor->parentNode) {
        otherAncestor = other;
        while (otherAncestor->parentNode) {
            if (nodeAncestor->parentNode == otherAncestor->parentNode) {
                nodeAncestor = nodeAncestor->nextSibling;
................................................................................
    return NULL;
}

/*---------------------------------------------------------------------------
|   domIsNamespaceInScope
|
\--------------------------------------------------------------------------*/
int
domIsNamespaceInScope (
    domActiveNS *NSstack,
    int          NSstackPos,
    const char  *prefix,
    const char  *namespaceURI
)
{
................................................................................
    domNS *ns = NULL;

    DBG(fprintf(stderr, "domNewNamespace '%s' --> '%s' \n", prefix, namespaceURI);)

    ns = domLookupNamespace (doc, prefix, namespaceURI);
    if (ns != NULL) return ns;
    doc->nsptr++;
#ifdef TDOM_LESS_NS
    if (doc->nsptr > 254) {
        DBG(fprintf (stderr, "maximum number of namespaces exceeded!!!\n");)
        domPanic("domNewNamespace: maximum number of namespaces exceeded!");
    }
#endif
    if (doc->nsptr >= doc->nslen) {
        doc->namespaces = (domNS**) REALLOC ((char*) doc->namespaces,
                                             sizeof (domNS*) * 2 * doc->nslen);
        doc->nslen *= 2;
    }
    doc->namespaces[doc->nsptr] = (domNS*)MALLOC (sizeof (domNS));
    ns = doc->namespaces[doc->nsptr];
................................................................................
domNamespaceURI (
    domNode *node
)
{
    domAttrNode *attr;
    domNS       *ns;


    if (node->nodeType == ATTRIBUTE_NODE) {
        attr = (domAttrNode*)node;
        if (!attr->namespace) return NULL;
        if (attr->nodeFlags & IS_NS_NODE) return NULL;
        ns = attr->parentNode->ownerDocument->namespaces[attr->namespace-1];
    } else
    if (node->nodeType == ELEMENT_NODE) {
        if (!node->namespace) return NULL;
        ns = node->ownerDocument->namespaces[node->namespace-1];
    } else {
        return NULL;
    }
    return ns->uri;
}

................................................................................
domNamespacePrefix (
    domNode *node
)
{
    domAttrNode *attr;
    domNS *ns;


    if (node->nodeType == ATTRIBUTE_NODE) {
        attr = (domAttrNode*)node;
        if (!attr->namespace) return NULL;
        ns = attr->parentNode->ownerDocument->namespaces[attr->namespace-1];
    } else
    if (node->nodeType == ELEMENT_NODE) {
        if (!node->namespace) return NULL;
        ns = node->ownerDocument->namespaces[node->namespace-1];
    } else {
        return NULL;
    }
    if (ns) return ns->prefix;
    return NULL;
}
................................................................................
 *      Returns the previous node to the given node or NULL, if there
 *      is no previous node. This function is needed in situations,
 *      where the given node may also be an domAttrNode. Namespace
 *      declaring attributes are treated as any other
 *      attributes. Since the domAttrNode struct doesn't has an
 *      element for the previous attribute, we need a function for the
 *      relatively rare cases, the 'previous attribute' is
 *      needed. Remember, that the XML rec say, that there is no
 *      specific order of the attributes of a node.
 *
 * Results: 
 *      A pointer to the previous node of the given one
 *      or NULL, if there isn't a previous node.
 *
 * Side effects:
................................................................................
{
    domReadInfo   *info = userData;
    domNode       *node, *parentNode;
    domLineColumn *lc;
    domAttrNode   *attrnode, *lastAttr;
    const char   **atPtr, **idAttPtr;
    Tcl_HashEntry *h;
    int            hnew, len, pos, idatt, newNS, result;
    const char    *xmlns, *localname;
    char           tagPrefix[MAX_PREFIX_LEN];
    char           prefix[MAX_PREFIX_LEN];
    domNS         *ns;
    char           feedbackCmd[24];

    if (info->feedbackAfter) {

        if (info->nextFeedbackPosition
             <= XML_GetCurrentByteIndex (info->parser)
        ) {
            if (info->feedbackCmd) {
                result = Tcl_GlobalEvalObj(info->interp, info->feedbackCmd);
            } else {
                sprintf(feedbackCmd, "%s", "::dom::domParseFeedback");
                result = Tcl_Eval(info->interp, feedbackCmd);
            }
            if (result != TCL_OK) {
                DBG(fprintf(stderr, "%s\n", 
                            Tcl_GetStringResult (info->interp)););





                info->status = result;
                XML_StopParser(info->parser, 1);
                return;
            }
            info->nextFeedbackPosition = 
                XML_GetCurrentByteIndex (info->parser) + info->feedbackAfter;
            Tcl_ResetResult (info->interp);
        }
    }

    DispatchPCDATA (info);
    
    h = Tcl_CreateHashEntry(&HASHTAB(info->document,tdom_tagNames), name,
                            &hnew);
................................................................................


    lastAttr = NULL;
    /*--------------------------------------------------------------
    |   process namespace declarations
    |
    \-------------------------------------------------------------*/
    if (!info->ignorexmlns) {
        for (atPtr = atts; atPtr[0] && atPtr[1]; atPtr += 2) {

            if (strncmp(atPtr[0], "xmlns", 5) == 0) {
                xmlns = atPtr[0];
                newNS = 1;
                if (xmlns[5] == ':') {
                    if (atPtr[1][0] == '\0') {
                        Tcl_SetResult (info->interp, "Missing URI in Namespace "
                               "declaration", NULL);
                        XML_StopParser(info->parser, 0);
                        return;
                    }
                    if (domIsNamespaceInScope (info->activeNS, info->activeNSpos,
                                               &(xmlns[6]), atPtr[1])) {
                        ns = domLookupPrefix (info->currentNode, &(xmlns[6]));
                        newNS = 0;
                    }
                    else {
                        ns = domNewNamespace(info->document, &xmlns[6], atPtr[1]);
                    }
                } else {
                    ns = domNewNamespace(info->document, "", atPtr[1]);
                }
                if (newNS) {
                    /* push active namespace */
                    info->activeNSpos++;
                    if (info->activeNSpos >= info->activeNSsize) {
                        info->activeNS = (domActiveNS*) REALLOC(
                            (char*)info->activeNS,
                            sizeof(domActiveNS) * 2 * info->activeNSsize);
                        info->activeNSsize = 2 * info->activeNSsize;
                    }
                    info->activeNS[info->activeNSpos].depth     = info->depth;
                    info->activeNS[info->activeNSpos].namespace = ns;
                }

                h = Tcl_CreateHashEntry(&HASHTAB(info->document, tdom_attrNames),
                                        atPtr[0], &hnew);
                attrnode = (domAttrNode*) domAlloc(sizeof(domAttrNode));
                memset(attrnode, 0, sizeof(domAttrNode));
                attrnode->nodeType    = ATTRIBUTE_NODE;
                attrnode->nodeFlags   = IS_NS_NODE;
                attrnode->namespace   = ns->index;
                attrnode->nodeName    = (char *)&(h->key);
                attrnode->parentNode  = node;
                len = strlen(atPtr[1]);



                attrnode->valueLength = len;
                attrnode->nodeValue   = (char*)MALLOC(len+1);
                strcpy(attrnode->nodeValue, atPtr[1]);
                if (node->firstAttr) {
                    lastAttr->nextSibling = attrnode;
                } else {
                    node->firstAttr = attrnode;
                }
                lastAttr = attrnode;
            }

        }

        /*----------------------------------------------------------
          |   look for namespace of element
          \---------------------------------------------------------*/
        domSplitQName (name, tagPrefix, &localname);
        for (pos = info->activeNSpos; pos >= 0; pos--) {
            if (  ((tagPrefix[0] == '\0')
                   && (info->activeNS[pos].namespace->prefix[0] == '\0'))
                  || ((tagPrefix[0] != '\0') 
                      && (info->activeNS[pos].namespace->prefix[0] != '\0')
                      && (strcmp(tagPrefix, 
                                 info->activeNS[pos].namespace->prefix) == 0))
                ) {
                if (info->activeNS[pos].namespace->prefix[0] == '\0'
                    && info->activeNS[pos].namespace->uri[0] == '\0'
                    && tagPrefix[0] == '\0') {
                    /* xml-names rec. 5.2: "The default namespace can be
                       set to the empty string. This has the same effect,
                       within the scope of the declaration, of there being
                       no default namespace." */
                    goto elemNSfound;
                }
                node->namespace = info->activeNS[pos].namespace->index;
                DBG(fprintf(stderr, "tag='%s' uri='%s' \n",
                            node->nodeName,
                            info->activeNS[pos].namespace->uri);
                    )
                    goto elemNSfound;
            }
        }
        if (tagPrefix[0] != '\0') {
            if (strcmp (tagPrefix, "xml")==0) {
                node->namespace = info->document->rootNode->firstAttr->namespace;
            } else {
                /* Since where here, this means, the element has a
                   up to now not declared namespace prefix. */

                Tcl_SetResult (info->interp, "Namespace prefix is not "
                               "defined", NULL);
                XML_StopParser(info->parser, 0);
                return;
            }
        }
    }
elemNSfound:


    /*--------------------------------------------------------------
    |   add the attribute nodes
    |
    \-------------------------------------------------------------*/
    if ((idatt = XML_GetIdAttributeIndex (info->parser)) != -1) {
        if (!info->document->ids) {
................................................................................
            info->document->ids = MALLOC (sizeof (Tcl_HashTable));
            Tcl_InitHashTable (info->document->ids, TCL_STRING_KEYS);
        }
        h = Tcl_CreateHashEntry (info->document->ids,
                                 atts[idatt+1],
                                 &hnew);
        /* if hnew isn't 1 this is a validation error. Hm, no clear way
           to report this. And more, XSLT and XPath can process not
           valid XML, the spec mentioned this even within the context
           of id(). If some elements share the same ID, the first in
           document order should be used. Doing it this way, this is
           guaranteed for unchanged DOM trees. There are problems, if
           the DOM tree is changed, befor using id() */
        if (hnew) {
            Tcl_SetHashValue (h, node);
................................................................................
        idAttPtr = atts + idatt;
    } else {
        idAttPtr = NULL;
    }
    /* lastAttr already set right, either to NULL above, or to the last
       NS attribute */
    for (atPtr = atts; atPtr[0] && atPtr[1]; atPtr += 2) {


        if (!info->ignorexmlns) {
            if (strncmp(atPtr[0], "xmlns", 5) == 0) {
                continue;
            }

        }
        h = Tcl_CreateHashEntry(&HASHTAB(info->document, tdom_attrNames),
                                atPtr[0], &hnew);
        attrnode = (domAttrNode*) domAlloc(sizeof(domAttrNode));
        memset(attrnode, 0, sizeof(domAttrNode));
        attrnode->nodeType = ATTRIBUTE_NODE;
        if (atPtr == idAttPtr) {
            attrnode->nodeFlags |= IS_ID_ATTRIBUTE;
................................................................................
        } else {
            attrnode->nodeFlags = 0;
        }
        attrnode->namespace   = 0;
        attrnode->nodeName    = (char *)&(h->key);
        attrnode->parentNode  = node;
        len = strlen(atPtr[1]);



        attrnode->valueLength = len;
        attrnode->nodeValue   = (char*)MALLOC(len+1);
        strcpy(attrnode->nodeValue, (char *)atPtr[1]);

        if (node->firstAttr) {
            lastAttr->nextSibling = attrnode;
        } else {
            node->firstAttr = attrnode;
        }
        lastAttr = attrnode;

        if (!info->ignorexmlns) {
            /*----------------------------------------------------------
              |   look for attribute namespace
              \---------------------------------------------------------*/
            domSplitQName (attrnode->nodeName, prefix, &localname);
            if (prefix[0] != '\0') {
                for (pos = info->activeNSpos; pos >= 0; pos--) {
                    if (  ((prefix[0] == '\0') 
                           && (info->activeNS[pos].namespace->prefix[0] == '\0'))
                          || ((prefix[0] != '\0') 
                              && (info->activeNS[pos].namespace->prefix[0] != '\0')
                              && (strcmp(prefix, info->activeNS[pos].namespace->prefix) == 0))
                        ) {
                        attrnode->namespace = info->activeNS[pos].namespace->index;
                        DBG(fprintf(stderr, "attr='%s' uri='%s' \n",
                                    attrnode->nodeName,
                                    info->activeNS[pos].namespace->uri);
                            )
                            goto attrNSfound;
                    }
                }
                if (strcmp (prefix, "xml")==0) {
                    attrnode->namespace = 
                        info->document->rootNode->firstAttr->namespace;
                } else {
                    /* Since where here, this means, the attribute has a
                       up to now not declared namespace prefix. We probably
                       should return this as an error, shouldn't we?*/
                }
            attrNSfound:
                ;
            }

        }
    }

    info->depth++;
}

/*---------------------------------------------------------------------------
|   endElement
................................................................................
)
{
    domReadInfo  *info = userData;

    DispatchPCDATA (info);
    
    info->depth--;
    if (!info->ignorexmlns) {
        /* pop active namespaces */
        while ( (info->activeNSpos >= 0) &&
                (info->activeNS[info->activeNSpos].depth == info->depth) )
        {
            info->activeNSpos--;
        }

    }

    if (info->depth != -1) {
        info->currentNode = info->currentNode->parentNode;
    } else {
        info->currentNode = NULL;
    }

................................................................................
{
    domReadInfo   *info = userData;

    Tcl_DStringAppend (info->cdata, s, len);
    return;
    
}

/*---------------------------------------------------------------------------
|   startCDATA
|
\--------------------------------------------------------------------------*/
static void
startCDATA (
    void        *userData
    )
{
    domReadInfo   *info = userData;

    DispatchPCDATA (info);
    info->cdataSection = 1;
}

/*---------------------------------------------------------------------------
|   endCDATA
|
\--------------------------------------------------------------------------*/
static void
endCDATA (
    void        *userData
    )
{
    domReadInfo   *info = userData;
    
    DispatchPCDATA (info);
    info->cdataSection = 0;
}

/*---------------------------------------------------------------------------
|   DispatchPCDATA
|
\--------------------------------------------------------------------------*/
static void
DispatchPCDATA (
................................................................................
    domTextNode   *node;
    domNode       *parentNode;
    domLineColumn *lc;
    Tcl_HashEntry *h;
    char          *s;
    int            len, hnew;
    

    len = Tcl_DStringLength (info->cdata);
    if (!len && !info->cdataSection) return;
    s = Tcl_DStringValue (info->cdata);
    



    parentNode = info->currentNode;
    if (!parentNode) return;

    if (   parentNode->lastChild 
        && parentNode->lastChild->nodeType == TEXT_NODE
        && !info->cdataSection) {

        /* normalize text node, i.e. there are no adjacent text nodes */
        node = (domTextNode*)parentNode->lastChild;
        node->nodeValue = REALLOC(node->nodeValue, node->valueLength + len);
        memmove(node->nodeValue + node->valueLength, s, len);
        node->valueLength += len;

................................................................................
        if (info->storeLineColumn) {
            node = (domTextNode*) domAlloc(sizeof(domTextNode)
                                            + sizeof(domLineColumn));
        } else {
            node = (domTextNode*) domAlloc(sizeof(domTextNode));
        }
        memset(node, 0, sizeof(domTextNode));
        if (info->cdataSection)
            node->nodeType    = CDATA_SECTION_NODE;
        else 
            node->nodeType    = TEXT_NODE;
        node->nodeFlags   = 0;

        node->nodeNumber  = NODE_NO(info->document);
        node->valueLength = len;
        node->nodeValue   = (char*)MALLOC(len);
        memmove(node->nodeValue, s, len);

        node->ownerDocument = info->document;
        node->parentNode = parentNode;
................................................................................
        DBG(fprintf (stderr, "commentHandler: insideDTD, skipping\n");)
        return;
    }

    DispatchPCDATA (info);

    len = strlen(s);



    parentNode = info->currentNode;

    if (info->storeLineColumn) {
        node = (domTextNode*) domAlloc(sizeof(domTextNode)
                                        + sizeof(domLineColumn));
    } else {
        node = (domTextNode*) domAlloc(sizeof(domTextNode));
    }
    memset(node, 0, sizeof(domTextNode));
    node->nodeType    = COMMENT_NODE;
    node->nodeFlags   = 0;

    node->nodeNumber  = NODE_NO(info->document);
    node->valueLength = len;
    node->nodeValue   = (char*)MALLOC(len);
    memmove(node->nodeValue, s, len);

    node->ownerDocument = info->document;
    node->parentNode = parentNode;
................................................................................
                                 (char*) node,
                                 &hnew);
        Tcl_SetHashValue (h, tdomstrdup (XML_GetBase (info->parser)));
        node->nodeFlags |= HAS_BASEURI;
    }

    len = strlen(target);



    node->targetLength = len;
    node->targetValue  = (char*)MALLOC(len);
    memmove(node->targetValue, target, len);

    len = strlen(data);



    node->dataLength = len;
    node->dataValue  = (char*)MALLOC(len);
    memmove(node->dataValue, data, len);

    node->ownerDocument = info->document;
    node->parentNode = parentNode;
    if (parentNode == NULL) {
................................................................................
/*---------------------------------------------------------------------------
|  externalEntityRefHandler
|
\--------------------------------------------------------------------------*/
static int
externalEntityRefHandler (
    XML_Parser  parser,
    const char *openEntityNames,
    const char *base,
    const char *systemId,
    const char *publicId
)
{
    domReadInfo   *info = (domReadInfo *) XML_GetUserData (parser);

    Tcl_Obj *cmdPtr, *resultObj, *resultTypeObj, *extbaseObj, *xmlstringObj;
    Tcl_Obj *channelIdObj;
    int result, mode, done, byteIndex, i;
    int keepresult = 0;
    size_t len;
    int tclLen;
    XML_Parser extparser, oldparser = NULL;
    char buf[4096], *resultType, *extbase, *xmlstring, *channelId, s[50];
    Tcl_Channel chan = (Tcl_Channel) NULL;
    enum XML_Status status;
    XML_Index storedNextFeedbackPosition;
    const char *interpResult;

    if (info->document->extResolver == NULL) {
        Tcl_AppendResult (info->interp, "Can't read external entity \"",
                          systemId, "\": No -externalentitycommand given",
                          NULL);
        return 0;
    }
................................................................................
                                 Tcl_NewStringObj(publicId, strlen(publicId)));
    } else {
        Tcl_ListObjAppendElement(info->interp, cmdPtr,
                                 Tcl_NewObj());
    }

 



    result = Tcl_EvalObjEx (info->interp, cmdPtr, 
                            TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);


    Tcl_DecrRefCount(cmdPtr);

    if (result != TCL_OK) {
        info->status = result;
        return 0;
    }

    extparser = XML_ExternalEntityParserCreate (parser, openEntityNames, 0);

    resultObj = Tcl_GetObjResult (info->interp);
    Tcl_IncrRefCount (resultObj);
................................................................................
                       NULL);
        return 0;
    }

    oldparser = info->parser;
    info->parser = extparser;
    XML_SetBase (extparser, extbase);
    storedNextFeedbackPosition = info->nextFeedbackPosition;
    info->nextFeedbackPosition = info->feedbackAfter;

    Tcl_ResetResult (info->interp);
    result = 1;
    if (chan == NULL) {
        status = XML_Parse(extparser, xmlstring, strlen (xmlstring), 1);
        switch (status) {
        case XML_STATUS_ERROR:
            interpResult = Tcl_GetStringResult(info->interp);
            sprintf(s, "%ld", XML_GetCurrentLineNumber(extparser));
            if (interpResult[0] == '\0') {
                Tcl_ResetResult (info->interp);
                Tcl_AppendResult(info->interp, "error \"",
                                 XML_ErrorString(XML_GetErrorCode(extparser)),
                                 "\" in entity \"", systemId,
                                 "\" at line ", s, " character ", NULL);
                sprintf(s, "%ld", XML_GetCurrentColumnNumber(extparser));
                Tcl_AppendResult(info->interp, s, NULL);
                byteIndex = XML_GetCurrentByteIndex(extparser);
                if (byteIndex != -1) {
                    Tcl_AppendResult(info->interp, "\n\"", NULL);
                    s[1] = '\0';
                    for (i=-20; i < 40; i++) {
                        if ((byteIndex+i)>=0) {
                            if (xmlstring[byteIndex+i]) {
                                s[0] = xmlstring[byteIndex+i];
                                Tcl_AppendResult(info->interp, s, NULL);
                                if (i==0) {
                                    Tcl_AppendResult(info->interp,
                                                     " <--Error-- ", NULL);
                                }
                            } else {
                                break;
                            }
                        }
                    }
                    Tcl_AppendResult(info->interp, "\"",NULL);
                }




            } else {
                Tcl_AppendResult(info->interp, ", referenced in entity \"",
                                 systemId, 
                                 "\" at line ", s, " character ", NULL);
                sprintf(s, "%ld", XML_GetCurrentColumnNumber(extparser));
                Tcl_AppendResult(info->interp, s, NULL);
            }
            keepresult = 1;
            result = 0;
            break;
        case XML_STATUS_SUSPENDED:
            XML_StopParser (oldparser, 1);
            keepresult = 1;
            break;
        default:
            break;
        }
    } else {
        do {
            len = Tcl_Read (chan, buf, sizeof(buf));
            done = len < sizeof(buf);
            status = XML_Parse (extparser, buf, len, done);
            switch (status) {
            case XML_STATUS_ERROR:
                interpResult = Tcl_GetStringResult(info->interp);
                sprintf(s, "%ld", XML_GetCurrentLineNumber(extparser));
                if (interpResult[0] == '\0') {
                    Tcl_ResetResult (info->interp);
                    Tcl_AppendResult(info->interp, "error \"",
                                     XML_ErrorString(XML_GetErrorCode(extparser)),
                                     "\" in entity \"", systemId,
                                     "\" at line ", s, " character ", NULL);
                    sprintf(s, "%ld", XML_GetCurrentColumnNumber(extparser));
                    Tcl_AppendResult(info->interp, s, NULL);




                } else {
                    Tcl_AppendResult(info->interp, ", referenced in entity \"",
                                     systemId, 
                                     "\" at line ", s, " character ", NULL);
                    sprintf(s, "%ld", XML_GetCurrentColumnNumber(extparser));
                    Tcl_AppendResult(info->interp, s, NULL);
                }
                result = 0;
                keepresult = 1;
                done = 1;
                break;
            case XML_STATUS_SUSPENDED:
                XML_StopParser (oldparser, 1);
                keepresult = 1;
                done = 1;
                break;
            default:
                break;
            }
        } while (!done);
    }

    if (result) {
        DispatchPCDATA (info);
    }
    if (!keepresult) {
        Tcl_ResetResult (info->interp);
    }
    XML_ParserFree (extparser);
    info->parser = oldparser;

    info->nextFeedbackPosition = storedNextFeedbackPosition;
    Tcl_DecrRefCount (resultObj);

    return result;

 wrongScriptResult:
    Tcl_DecrRefCount (resultObj);
    Tcl_ResetResult (info->interp);
    XML_ParserFree (extparser);
    if (oldparser) {
        info->parser = oldparser;
    }
    info->status = TCL_ERROR;
    Tcl_AppendResult (info->interp, "The -externalentitycommand script "
                      "has to return a Tcl list with 3 elements.\n"
                      "Syntax: {string|channel|filename <baseurl> <data>}\n",
                      NULL);
    return 0;
}

................................................................................
\--------------------------------------------------------------------------*/
domDocument *
domReadDocument (
    XML_Parser  parser,
    char       *xml,
    int         length,
    int         ignoreWhiteSpaces,
    int         keepCDATA,
    int         storeLineColumn,
    int         ignorexmlns,
    int         feedbackAfter,
    Tcl_Obj    *feedbackCmd,
    Tcl_Channel channel,
    const char *baseurl,
    Tcl_Obj    *extResolver,
    int         useForeignDTD,
    int         paramEntityParsing,
    Tcl_Interp *interp,
    int        *resultcode
)
{
    int             done, tclLen;
    enum XML_Status status;
    size_t          len;
    domReadInfo     info;
    char            buf[8192];

    Tcl_Obj        *bufObj;
    Tcl_DString     dStr;
    int             useBinary;
    char           *str;

    domDocument    *doc = domCreateDoc(baseurl, storeLineColumn);

    if (extResolver) {
        doc->extResolver = tdomstrdup (Tcl_GetString (extResolver));
    }
    if (ignorexmlns) {
        doc->nodeFlags |= IGNORE_XMLNS;
    }

    info.parser               = parser;
    info.document             = doc;
    info.currentNode          = NULL;
    info.depth                = 0;
    info.ignoreWhiteSpaces    = ignoreWhiteSpaces;
    info.cdata                = (Tcl_DString*) MALLOC (sizeof (Tcl_DString));
    Tcl_DStringInit (info.cdata);
    info.cdataSection         = 0;
    info.storeLineColumn      = storeLineColumn;
    info.ignorexmlns          = ignorexmlns;
    info.feedbackAfter        = feedbackAfter;
    info.feedbackCmd          = feedbackCmd;
    info.nextFeedbackPosition = feedbackAfter;
    info.interp               = interp;
    info.activeNSpos          = -1;
    info.activeNSsize         = 8;
    info.activeNS             = (domActiveNS*) MALLOC (sizeof(domActiveNS) 
                                                       * info.activeNSsize);
    info.baseURIstackPos      = 0;
    info.baseURIstackSize     = INITIAL_BASEURISTACK_SIZE;
    info.baseURIstack         = (domActiveBaseURI*) 
        MALLOC (sizeof(domActiveBaseURI) * info.baseURIstackSize);
    info.insideDTD            = 0;
    info.status               = 0;

    XML_SetUserData(parser, &info);
    XML_SetBase (parser, baseurl);
    /* We must use XML_GetBase(), because XML_SetBase copies the baseURI,
       and we want to compare the pointers */
    info.baseURIstack[0].baseURI = XML_GetBase (parser);
    info.baseURIstack[0].depth = 0;
................................................................................
    if (extResolver) {
        XML_SetExternalEntityRefHandler (parser, externalEntityRefHandler);
    }
    XML_SetParamEntityParsing (parser, 
                             (enum XML_ParamEntityParsing) paramEntityParsing);
    XML_SetDoctypeDeclHandler (parser, startDoctypeDeclHandler,
                               endDoctypeDeclHandler);
    if (keepCDATA) {
        XML_SetCdataSectionHandler(parser, startCDATA, endCDATA);
    }
    

    if (channel == NULL) {
        status = XML_Parse(parser, xml, length, 1);
        switch (status) {
        case XML_STATUS_SUSPENDED:
            DBG(fprintf(stderr, "XML_STATUS_SUSPENDED\n");)
            if (info.status == TCL_BREAK) {
                Tcl_ResetResult(interp);
            }
            /* fall throu */
        case XML_STATUS_ERROR:
            DBG(fprintf(stderr, "XML_STATUS_ERROR\n");)
            FREE ( info.activeNS );
            FREE ( info.baseURIstack );
            Tcl_DStringFree (info.cdata);
            FREE ( info.cdata);
            domFreeDocument (doc, NULL, NULL);
            *resultcode = info.status;
            return NULL;
        case XML_STATUS_OK:
            break;
        }
    } else {

        Tcl_DStringInit (&dStr);
        if (Tcl_GetChannelOption (interp, channel, "-encoding", &dStr) != TCL_OK) {
            FREE ( (char*) info.activeNS );
            FREE ( info.baseURIstack );
            Tcl_DStringFree (info.cdata);
            FREE ( info.cdata);
            domFreeDocument (doc, NULL, NULL);
            *resultcode = info.status;
            return NULL;
        }
        if (strcmp (Tcl_DStringValue (&dStr), "utf-8")==0 ) useBinary = 1;
        else useBinary = 0;
        Tcl_DStringFree (&dStr);
        if (useBinary) {
            do {
                len = Tcl_Read (channel, buf, sizeof(buf));
                done = len < sizeof(buf);
                status = XML_Parse (parser, buf, len, done);
                switch (status) {
                case XML_STATUS_SUSPENDED:
                    DBG(fprintf(stderr, "XML_STATUS_SUSPENDED\n"););
                    if (info.status == TCL_BREAK) {
                        Tcl_ResetResult(interp);
                    }
                    /* fall throu */
                case XML_STATUS_ERROR:
                    DBG(fprintf(stderr, "XML_STATUS_ERROR\n");)
                    FREE ( info.activeNS );
                    FREE ( info.baseURIstack );
                    Tcl_DStringFree (info.cdata);
                    FREE ( info.cdata);
                    domFreeDocument (doc, NULL, NULL);
                    *resultcode = info.status;
                    return NULL;
                case XML_STATUS_OK:
                    break;
                }
            } while (!done);
        } else {
            bufObj = Tcl_NewObj();
            Tcl_SetObjLength (bufObj, 6144);
            do {
                len = Tcl_ReadChars (channel, bufObj, 1024, 0);
                done = (len < 1024);
                str = Tcl_GetStringFromObj(bufObj, &tclLen);
                status = XML_Parse (parser, str, tclLen, done);
                switch (status) {
                case XML_STATUS_SUSPENDED:
                    DBG(fprintf(stderr, "XML_STATUS_SUSPENDED\n"););
                    if (info.status == TCL_BREAK) {
                        Tcl_ResetResult(interp);
                    }
                    /* fall throu */
                case XML_STATUS_ERROR:
                    DBG(fprintf(stderr, "XML_STATUS_ERROR\n");)
                    FREE ( info.activeNS );
                    FREE ( info.baseURIstack );
                    Tcl_DStringFree (info.cdata);
                    FREE ( info.cdata);
                    domFreeDocument (doc, NULL, NULL);
                    Tcl_DecrRefCount (bufObj);
                    *resultcode = info.status;
                    return NULL;
                case XML_STATUS_OK:
                    break;
                }
            } while (!done);
            Tcl_DecrRefCount (bufObj);
        }














    }
    FREE ( info.activeNS );
    FREE ( info.baseURIstack );
    Tcl_DStringFree (info.cdata);
    FREE ( info.cdata);

    domSetDocumentElement (doc);
................................................................................
        *column = lc->column;
        return 0;
    } else {
        return -1;
    }
}


domAttrNode *
domCreateXMLNamespaceNode (
    domNode  *parent
)
{
    Tcl_HashEntry  *h;
    int             hnew;
................................................................................
    attr->namespace     = ns->index;
    attr->nodeName      = (char *)&(h->key);
    attr->parentNode    = parent;
    attr->valueLength   = strlen (XML_NAMESPACE);
    attr->nodeValue     = tdomstrdup (XML_NAMESPACE);
    return attr;
}


 
/*
 *----------------------------------------------------------------------
 *
 * domCreateDoc --
 *
................................................................................
 *----------------------------------------------------------------------
 */

domDocument *
domCreateDoc (
    const char * baseURI,
    int          storeLineColumn
)
{
    Tcl_HashEntry *h;
    int            hnew;
    domNode       *rootNode;
    domDocument   *doc;
    domLineColumn *lc;

................................................................................
    memset(doc, 0, sizeof(domDocument));
    doc->nodeType       = DOCUMENT_NODE;
    doc->documentNumber = DOC_NO(doc);
    doc->nsptr          = -1;
    doc->nslen          =  4;
    doc->namespaces     = (domNS**) MALLOC (sizeof (domNS*) * doc->nslen);
    
    /* We malloc and initialize the baseURIs hash table here to avoid
       cluttering of the code all over the place with checks. */
    doc->baseURIs = MALLOC (sizeof (Tcl_HashTable));
    Tcl_InitHashTable (doc->baseURIs, TCL_ONE_WORD_KEYS);

    TDomThreaded(
        domLocksAttach(doc);
        Tcl_InitHashTable(&doc->tdom_tagNames, TCL_STRING_KEYS);
................................................................................
    rootNode->namespace     = 0;
    h = Tcl_CreateHashEntry(&HASHTAB(doc,tdom_tagNames), "", &hnew);
    rootNode->nodeName      = (char *)&(h->key);
    rootNode->nodeNumber    = NODE_NO(doc);
    rootNode->ownerDocument = doc;
    rootNode->parentNode    = NULL;
    rootNode->firstChild    = rootNode->lastChild = NULL;

    rootNode->firstAttr     = domCreateXMLNamespaceNode (rootNode);

    if (storeLineColumn) {
        lc = (domLineColumn*) ( ((char*)rootNode) + sizeof(domNode));
        rootNode->nodeFlags |= HAS_LINE_COLUMN;
        lc->line            = 0;
        lc->column          = 0;
    }
    doc->rootNode = rootNode;
................................................................................

/*---------------------------------------------------------------------------
|   domCreateDocument
|
\--------------------------------------------------------------------------*/
domDocument *
domCreateDocument (

    const char *uri,
    char       *documentElementTagName
)
{
    Tcl_HashEntry *h;
    int            hnew;
    domNode       *node;
................................................................................
    const char    *localName;
    domNS         *ns = NULL;

    if (uri) {
        domSplitQName (documentElementTagName, prefix, &localName);
        DBG(fprintf(stderr, 
                    "rootName: -->%s<--, prefix: -->%s<--, localName: -->%s<--\n", 
                    documentElementTagName, prefix, localName););
























    }
    doc = domCreateDoc (NULL, 0);

    h = Tcl_CreateHashEntry(&HASHTAB(doc, tdom_tagNames),
                            documentElementTagName, &hnew);
    node = (domNode*) domAlloc(sizeof(domNode));
    memset(node, 0, sizeof(domNode));
................................................................................
    \---------------------------------------------------------------*/
    if (freeCB) {
        freeCB(node, clientData);
    }
    TDomThreaded (    
        if (shared) {
            if (doc->deletedNodes) {
                node->nextSibling = doc->deletedNodes;
            } else {
                node->nextSibling = NULL;
            }
            doc->deletedNodes = node;
            node->nodeFlags |= IS_DELETED;

        }
    )
    MutationEvent3(DOMNodeRemoved, childToRemove, node);
    MutationEvent2(DOMSubtreeModified, node);
    domFreeNode(node, freeCB, clientData, 0);

    return OK;
................................................................................
        FREE (Tcl_GetHashValue (entryPtr));
        entryPtr = Tcl_NextHashEntry (&search);
    }
    Tcl_DeleteHashTable (doc->baseURIs);
    FREE (doc->baseURIs);
    
    /*-----------------------------------------------------------
    | delete XPath cache hash table
    \-----------------------------------------------------------*/
    if (doc->xpathCache) {
        entryPtr = Tcl_FirstHashEntry (doc->xpathCache, &search);
        while (entryPtr) {
            xpathFreeAst((ast)Tcl_GetHashValue (entryPtr));
            entryPtr = Tcl_NextHashEntry (&search);
        }
................................................................................
            if (!attr->namespace) {
                if (strcmp (attr->nodeName, localName)==0) break;
            }
        }
        attr = attr->nextSibling;
    }
    if (attr) {
        DBG(fprintf (stderr, "domSetAttributeNS: resetting existing attribute %s ; old value: %s\n", attr->nodeName, attr->nodeValue);)
        if (attr->nodeFlags & IS_ID_ATTRIBUTE) {
            h = Tcl_FindHashEntry (node->ownerDocument->ids, attr->nodeValue);
            if (h) {
                Tcl_DeleteHashEntry (h);
                h = Tcl_CreateHashEntry (node->ownerDocument->ids,
                                         attributeValue, &hnew);
                Tcl_SetHashValue (h, node);
................................................................................
    }

    attr = node->firstAttr;
    while (attr) {
        domSplitQName (attr->nodeName, prefix, &str);
        if (strcmp(localName,str)==0) {
            ns = domGetNamespaceByIndex(node->ownerDocument, attr->namespace);
            if (ns && strcmp(ns->uri, uri)==0) {
                if (previous) {
                    previous->nextSibling = attr->nextSibling;
                } else {
                    attr->parentNode->firstAttr = attr->nextSibling;
                }

                if (attr->nodeFlags & IS_ID_ATTRIBUTE) {
................................................................................
{
    domTextNode   *node;

    node = (domTextNode*) domAlloc(sizeof(domTextNode));
    memset(node, 0, sizeof(domTextNode));
    node->nodeType      = nodeType;
    node->nodeFlags     = 0;

    node->nodeNumber    = NODE_NO(doc);
    node->ownerDocument = doc;
    node->valueLength   = length;
    node->nodeValue     = (char*)MALLOC(length);
    memmove(node->nodeValue, value, length);

    if (doc->fragments) {
................................................................................
    node = (domTextNode*) domAlloc(sizeof(domTextNode));
    memset(node, 0, sizeof(domTextNode));
    node->nodeType      = nodeType;
    node->nodeFlags     = 0;
    if (disableOutputEscaping) {
        node->nodeFlags |= DISABLE_OUTPUT_ESCAPING;
    }

    node->nodeNumber    = NODE_NO(parent->ownerDocument);
    node->ownerDocument = parent->ownerDocument;
    node->valueLength   = length;
    node->nodeValue     = (char*)MALLOC(length);
    memmove(node->nodeValue, value, length);

    if (parent->lastChild) {
................................................................................
/*---------------------------------------------------------------------------
|   domNewElementNode
|
\--------------------------------------------------------------------------*/
domNode *
domNewElementNode(
    domDocument *doc,
    const char  *tagName

)
{
    domNode       *node;
    Tcl_HashEntry *h;
    int           hnew;

    h = Tcl_CreateHashEntry(&HASHTAB(doc, tdom_tagNames), tagName, &hnew);
    node = (domNode*) domAlloc(sizeof(domNode));
    memset(node, 0, sizeof(domNode));
    node->nodeType      = ELEMENT_NODE;
    node->nodeFlags     = 0;
    node->namespace     = 0;
    node->nodeNumber    = NODE_NO(doc);
    node->ownerDocument = doc;
    node->nodeName      = (char *)&(h->key);

    if (doc->fragments) {
................................................................................
|   domNewElementNodeNS
|
\--------------------------------------------------------------------------*/
domNode *
domNewElementNodeNS (
    domDocument *doc,
    const char  *tagName,
    const char  *uri

)
{
    domNode       *node;
    Tcl_HashEntry *h;
    int            hnew;
    char           prefix[MAX_PREFIX_LEN];
    const char    *localname;
    domNS         *ns;

    domSplitQName (tagName, prefix, &localname);
    if (prefix[0] == '\0' && uri[0] == '\0') {
        return NULL;
    }

    h = Tcl_CreateHashEntry(&HASHTAB(doc, tdom_tagNames), tagName, &hnew);
    node = (domNode*) domAlloc(sizeof(domNode));
    memset(node, 0, sizeof(domNode));
    node->nodeType      = ELEMENT_NODE;
    node->nodeFlags     = 0;
    node->namespace     = 0;
    node->nodeNumber    = NODE_NO(doc);
    node->ownerDocument = doc;
    node->nodeName      = (char *)&(h->key);


    ns = domNewNamespace(doc, prefix, uri);
    node->namespace = ns->index;

    if (doc->fragments) {
        node->nextSibling = doc->fragments;
        doc->fragments->previousSibling = node;
        doc->fragments = node;
................................................................................
                                         pinode->ownerDocument,
                                         pinode->targetValue,
                                         pinode->targetLength,
                                         pinode->dataValue,
                                         pinode->dataLength);
    }
    if (node->nodeType != ELEMENT_NODE) {
        domTextNode *t1node, *tnode = (domTextNode*)node;
        if (tnode->info) {
            t1node = domNewTextNode(tnode->ownerDocument,
                                    tnode->nodeValue, tnode->valueLength,
                                    tnode->nodeType);
            t1node->info = tnode->info;
            return (domNode*) t1node;
        } else {
            return (domNode*) domNewTextNode(tnode->ownerDocument,
                                             tnode->nodeValue, tnode->valueLength,
                                             tnode->nodeType);
        }
    }

    n = domNewElementNode(node->ownerDocument, node->nodeName);
    n->namespace = node->namespace;

    n->info = node->info;

    /*------------------------------------------------------------------
    |   copy attributes (if any)
    \-----------------------------------------------------------------*/
    attr = node->firstAttr;
    while (attr != NULL) {
        nattr = domSetAttribute (n, attr->nodeName, attr->nodeValue );
................................................................................
    \-----------------------------------------------------------------*/
    attr = node->firstAttr;
    while (attr != NULL) {
        if (attr->nodeFlags & IS_NS_NODE) {
            if (copyNS) {
                /* If copyNS is true, then all namespaces in scope
                 * (including the one declared with the node to copy)
                 * are already copied over. */
                attr = attr->nextSibling;
                continue;
                
            }
            ns = node->ownerDocument->namespaces[attr->namespace-1];
            ns1 = domLookupPrefix (n, ns->prefix);
            if (ns1 && strcmp (ns->uri, ns1->uri)==0) {
................................................................................
    int            attrLen,
    domAddCallback addCallback,
    void         * clientData
)
{
    domNode     *ancestor;
    domAttrNode *attr;
    int          result;


    ancestor = node->parentNode;
    if (ancestor) {

        if ((type == ALL_NODES) || (ancestor->nodeType == type)) {
            if ((element == NULL) ||
                ((ancestor->nodeType == ELEMENT_NODE) && (strcmp(ancestor->nodeName,element)==0))
               ) {
                if (attrName == NULL) {
                    *i = (instance<0) ? (*i)-1 : (*i)+1;
                    if (all || (*i == instance)) {
                        result = addCallback (ancestor, clientData);
                        if (result) {
                            return result;
                        }

                    }
                } else {
                    attr = ancestor->firstAttr;
                    while (attr) {
                        if ((strcmp(attr->nodeName,attrName)==0) &&
                            ( (strcmp(attrValue,"*")==0) ||
                              ( (attr->valueLength == attrLen) &&
................................................................................
                           ) {
                            *i = (instance<0) ? (*i)-1 : (*i)+1;
                            if (all || (*i == instance)) {
                                result = addCallback (ancestor, clientData);
                                if (result) {
                                    return result;
                                }

                            }
                        }
                        attr = attr->nextSibling;
                    }
                }
            }
        }
................................................................................
typedef struct _tdomCmdReadInfo {

    XML_Parser        parser;
    domDocument      *document;
    domNode          *currentNode;
    int               depth;
    int               ignoreWhiteSpaces;
    int               cdataSection;
    Tcl_DString      *cdata;

    int               storeLineColumn;
    int               ignorexmlns;
    int               feedbackAfter;
    Tcl_Obj          *feedbackCmd;
    int               nextFeedbackPosition;
    Tcl_Interp       *interp;
    int               activeNSsize;
    int               activeNSpos;
    domActiveNS      *activeNS;
    int               baseURIstackSize;
    int               baseURIstackPos;
    domActiveBaseURI *baseURIstack;
................................................................................
        domFreeDocument (info->document, NULL, NULL);
    }

    info->document          = NULL;
    info->currentNode       = NULL;
    info->depth             = 0;
    info->feedbackAfter     = 0;
    info->ignorexmlns       = 0;
    Tcl_DStringSetLength (info->cdata, 0);
    info->nextFeedbackPosition = info->feedbackAfter;
    info->interp            = interp;
    info->activeNSpos       = -1;
    info->insideDTD         = 0;
    info->baseURIstackPos   = 0;
    info->tdomStatus        = 0;

}
................................................................................
}

int
TclTdomObjCmd (dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *const objv[];
{

    CHandlerSet     *handlerSet;
    int              methodIndex, result, bool;
    tdomCmdReadInfo *info;
    TclGenExpatInfo *expat;
    Tcl_Obj         *newObjName = NULL;


    static const char *tdomMethods[] = {
        "enable", "getdoc",
        "setStoreLineColumn",
        "setExternalEntityResolver", "keepEmpties",
        "remove", "ignorexmlns", "keepCDATA",
        NULL
    };
    enum tdomMethod {
        m_enable, m_getdoc,
        m_setStoreLineColumn,
        m_setExternalEntityResolver, m_keepEmpties,
        m_remove, m_ignorexmlns, m_keepCDATA
    };

    if (objc < 3 || objc > 4) {
        Tcl_WrongNumArgs (interp, 1, objv, tdom_usage);
        return TCL_ERROR;
    }

    if (!CheckExpatParserObj (interp, objv[1])) {
        Tcl_SetResult (interp, "First argument has to be a expat parser object", NULL);
        return TCL_ERROR;
    }


    if (Tcl_GetIndexFromObj (interp, objv[2], tdomMethods, "method", 0,
                             &methodIndex) != TCL_OK)
    {
        Tcl_SetResult (interp, tdom_usage, NULL);
        return TCL_ERROR;
    }

................................................................................
    switch ((enum tdomMethod) methodIndex) {

    default:
        Tcl_SetResult (interp, "unknown method", NULL);
        return TCL_ERROR;

    case m_enable:
        expat = GetExpatInfo (interp, objv[1]);
        if (expat->parsingState != 0) {
            Tcl_SetResult (interp, 
                           "Parser is not in init or reset state.", NULL);
            return TCL_ERROR;
        }

        handlerSet = CHandlerSetCreate ("tdom");
        handlerSet->ignoreWhiteCDATAs       = 1;
        handlerSet->resetProc               = tdom_resetProc;
        handlerSet->freeProc                = tdom_freeProc;
        handlerSet->parserResetProc         = tdom_parserResetProc;
        handlerSet->initParseProc           = tdom_initParseProc;
        handlerSet->elementstartcommand     = startElement;
................................................................................
/*         handlerSet->datacommand             = characterDataHandler; */
        handlerSet->commentCommand          = commentHandler;
        handlerSet->picommand               = processingInstructionHandler;
        handlerSet->entityDeclCommand       = entityDeclHandler;
        handlerSet->startDoctypeDeclCommand = startDoctypeDeclHandler;
        handlerSet->endDoctypeDeclCommand   = endDoctypeDeclHandler;



        info = (tdomCmdReadInfo *) MALLOC (sizeof (tdomCmdReadInfo));
        info->parser            = expat->parser;
        info->document          = NULL;
        info->currentNode       = NULL;
        info->depth             = 0;
        info->ignoreWhiteSpaces = 1;
        info->cdataSection      = 0;
        info->cdata             = (Tcl_DString*) MALLOC (sizeof (Tcl_DString));
        Tcl_DStringInit (info->cdata);

        info->storeLineColumn   = 0;
        info->ignorexmlns       = 0;
        info->feedbackAfter     = 0;
        info->feedbackCmd       = NULL;
        info->nextFeedbackPosition = 0;
        info->interp            = interp;
        info->activeNSpos       = -1;
        info->activeNSsize      = 8;
        info->activeNS          = 
            (domActiveNS*) MALLOC(sizeof(domActiveNS) * info->activeNSsize);
        info->baseURIstackPos   = 0;
        info->baseURIstackSize  = INITIAL_BASEURISTACK_SIZE;
................................................................................
        info = CHandlerSetGetUserData (interp, objv[1], "tdom");
        if (!info) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
        expat = GetExpatInfo (interp, objv[1]);
        if (info->tdomStatus != 2 || !expat->finished) {
            Tcl_SetResult (interp, "No DOM tree available.", NULL);
            return TCL_ERROR;
        }
        domSetDocumentElement (info->document);
        result = tcldom_returnDocumentObj (interp, info->document, 0,
                                           newObjName, 0, 0);
        info->document = NULL;
        return result;




































    case m_setStoreLineColumn:
        info = CHandlerSetGetUserData (interp, objv[1], "tdom");
        if (!info) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
        Tcl_SetIntObj (Tcl_GetObjResult (interp), info->storeLineColumn);
        if (objc == 4) {
            if (Tcl_GetBooleanFromObj (interp, objv[3], &bool) != TCL_OK) {
                return TCL_ERROR;
            }
            info->storeLineColumn = bool;
        }
        info->tdomStatus = 1;
        break;
        
    case m_remove:
        result = CHandlerSetRemove (interp, objv[1], "tdom");
................................................................................
            Tcl_SetResult (interp, "expat parser obj hasn't a C handler set named \"tdom\"", NULL);
            return TCL_ERROR;
        }
        break;

    case m_setExternalEntityResolver:
        if (objc != 4) {
            Tcl_SetResult (interp, "You must name a Tcl command as external entity resolver for setExternalEntityResolver.", NULL);
            return TCL_ERROR;
        }
        info = CHandlerSetGetUserData (interp, objv[1], "tdom");
        if (!info) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
................................................................................
    case m_keepEmpties:
        if (objc != 4) {
            Tcl_SetResult (interp, "wrong # of args for method keepEmpties.",
                           NULL);
            return TCL_ERROR;
        }
        handlerSet = CHandlerSetGet (interp, objv[1], "tdom");
        if (!handlerSet) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
        info = handlerSet->userData;
        if (!info) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
        Tcl_SetIntObj (Tcl_GetObjResult (interp), info->ignoreWhiteSpaces);
        if (Tcl_GetBooleanFromObj (interp, objv[3], &bool) != TCL_OK) {
            return TCL_ERROR;
        }
        info->ignoreWhiteSpaces = !bool;
        handlerSet->ignoreWhiteCDATAs = !bool;
        info->tdomStatus = 1;
        break;

    case m_keepCDATA:
        if (objc != 4) {
            Tcl_SetResult (interp, "wrong # of args for method keepCDATA.",
                           NULL);
            return TCL_ERROR;
        }
        handlerSet = CHandlerSetGet (interp, objv[1], "tdom");
        if (!handlerSet) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
        info = handlerSet->userData;
        if (!info) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
        if (Tcl_GetBooleanFromObj (interp, objv[3], &bool) != TCL_OK) {
            return TCL_ERROR;
        }
        if (bool) {
            handlerSet->startCdataSectionCommand = startCDATA;
            handlerSet->endCdataSectionCommand = endCDATA;
        } else {
            handlerSet->startCdataSectionCommand = startCDATA;
            handlerSet->endCdataSectionCommand = endCDATA;
        }
        info->tdomStatus = 1;
        break;
        
    case m_ignorexmlns:
        info = CHandlerSetGetUserData (interp, objv[1], "tdom");
        if (!info) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
        Tcl_SetIntObj (Tcl_GetObjResult (interp), info->ignorexmlns);
        if (objc == 4) {
            if (Tcl_GetBooleanFromObj (interp, objv[3], &bool) != TCL_OK) {
                return TCL_ERROR;
            }
            info->ignorexmlns = bool;
        }
        info->tdomStatus = 1;
        break;
        

    }

    return TCL_OK;
}

Changes to generic/dom.h.

33
34
35
36
37
38
39


40
41
42
43
44
45
46
47
48
49
..
83
84
85
86
87
88
89
90

91
92
93

94
95
96
97
98
99
100
...
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

157
158
159
160
161
162
163
...
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230






231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
...
419
420
421
422
423
424
425



426
427
428
429
430
431
432
...
550
551
552
553
554
555
556










557
558
559
560
561
562
563
...
572
573
574
575
576
577
578

579
580




581
582
583
584
585
586
587



588
589
590
591
592
593
594
595
596
597
598
599
...
611
612
613
614
615
616
617

618
619




620
621
622
623
624
625
626
...
633
634
635
636
637
638
639

640
641




642
643
644
645
646
647
648
649



650
651
652
653
654
655
656
...
657
658
659
660
661
662
663

664
665





666
667
668
669
670
671
672
...
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699

700

701
702
703
704
705
706

707
708
709
710
711
712
713
...
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
...
767
768
769
770
771
772
773


774
775
776
777
778
779
780
...
803
804
805
806
807
808
809

810
811
812
813
814
815
816
|
\--------------------------------------------------------------------------*/

#ifndef __DOM_H__
#define __DOM_H__

#include <tcl.h>


#include <ctype.h>
#include <expat.h>
#include <utf8conv.h>
#include <domalloc.h>

/*
 * tDOM provides it's own memory allocator which is optimized for
 * low heap usage. It uses the native Tcl allocator underneath,
 * though, but it is not very MT-friendly. Therefore, you might
 * use the (normal) Tcl allocator with USE_NORMAL_ALLOCATOR
................................................................................
   };
#  define MEM_SUITE &memsuite
#else
#  define MEM_SUITE NULL
#endif

/*
 * Beginning with 8.4, Tcl API is CONST'ified

 */
#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION <= 3)
# define CONST84

#endif

/*
 * Starting with Tcl 8.2 the Tcl_Panic() is defined properly
 * over the stubs table.
 * Also, we have a proper Tcl_GetString() shortcut afterwards.
 */
................................................................................
# define TDomNotThreaded(x)
# define TDomThreaded(x)    x
# define HASHTAB(doc,tab)   (doc)->tab
# define NODE_NO(doc)       ((doc)->nodeCounter)++
# define DOC_NO(doc)        (unsigned long)(doc)
#endif /* TCL_THREADS */

#define DOC_CMD(s,doc)      sprintf((s), "domDoc%p", (doc))
#define NODE_CMD(s,node)    sprintf((s), "domNode%p", (node))
#define XSLT_CMD(s,doc)     sprintf((s), "XSLTcmd%p", (doc))

#define XML_NAMESPACE "http://www.w3.org/XML/1998/namespace"
#define XMLNS_NAMESPACE "http://www.w3.org/2000/xmlns"

#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0) || TCL_MAJOR_VERSION < 8
#define TclOnly8Bits 1
#else
#define TclOnly8Bits 0
#endif

#define UTF8_1BYTE_CHAR(c) ( 0    == ((c) & 0x80))
#define UTF8_2BYTE_CHAR(c) ( 0xC0 == ((c) & 0xE0))
#define UTF8_3BYTE_CHAR(c) ( 0xE0 == ((c) & 0xF0))
#define UTF8_4BYTE_CHAR(c) ( 0xF0 == ((c) & 0xF8))

#if TclOnly8Bits
#define UTF8_CHAR_LEN(c) 1
#else
#define UTF8_CHAR_LEN(c) \
  UTF8_1BYTE_CHAR((c)) ? 1 : \
   (UTF8_2BYTE_CHAR((c)) ? 2 : \
     (UTF8_3BYTE_CHAR((c)) ? 3 : 0))
#endif


/* The following 2 defines are out of the expat code */

/* 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. */
................................................................................
  ? NCnameStart7Bit[(int)(*(p))] \
  : ((n) == 2 \
    ? UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)(p)) \
    : ((n) == 3 \
      ? UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)(p)) \
      : 0)))

#if TclOnly8Bits 
#  define UTF8_XMLCHAR(p,n) \
 (*(p) < 0x80 ? CharBit[(int)(*(p))] : 1)
#else  
#  define UTF8_XMLCHAR3(p) \
  (*(p) == 0xED  \
   ? ((p)[1] < 0xA0 ? 1 : 0) \
   : (*(p) == 0xEF \
      ? ((p)[1] == 0xBF \
         ? ((p)[2] == 0xBE || (p)[2] == 0xBF ? 0 : 1) \
         : 1) \
      : 1)) \
    






#  define UTF8_XMLCHAR(p, n) \
  ((n) == 1 \
  ? CharBit[(int)(*(p))] \
  : ((n) == 2 \
    ? 1 \
    : ((n) == 3 \
      ? (UTF8_XMLCHAR3(p)) \
      : 0)))
#endif

#include "../expat/nametab.h"

static const unsigned char nameChar7Bit[] = {
/* 0x00 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x08 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x10 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
................................................................................
/* 0x60 */    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 0x68 */    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 0x70 */    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 0x78 */    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
};


#if TclOnly8Bits == 1
#  define isNameStart(x)   (isalpha(*x) || ((*x)=='_') || ((*x)==':'))
#  define isNameChar(x)    (isalnum(*x)  || ((*x)=='_') || ((*x)=='-') || ((*x)=='.') || ((*x)==':'))
#  define isNCNameStart(x) (isalpha(*x) || ((*x)=='_'))
#  define isNCNameChar(x)  (isalnum(*x)  || ((*x)=='_') || ((*x)=='-') || ((*x)=='.'))
#else
#  define isNameStart(x)   UTF8_GET_NAME_START((x),UTF8_CHAR_LEN(*(x)))
#  define isNCNameStart(x) UTF8_GET_NCNAME_START((x),UTF8_CHAR_LEN(*(x)))
#  define isNameChar(x)    UTF8_GET_NAMING_NMTOKEN((x),UTF8_CHAR_LEN(*(x)))
#  define isNCNameChar(x)  UTF8_GET_NAMING_NCNMTOKEN((x),UTF8_CHAR_LEN(*(x)))
#endif

#define IS_XML_WHITESPACE(c)  ((c)==' ' || (c)=='\n' || (c)=='\r' || (c)=='\t')

/*--------------------------------------------------------------------------
|   DOMString
|
\-------------------------------------------------------------------------*/
................................................................................
#define IS_NS_NODE                2

typedef unsigned int domDocFlags;

#define OUTPUT_DEFAULT_INDENT     1
#define NEEDS_RENUMBERING         2
#define DONT_FREE                 4




/*--------------------------------------------------------------------------
|   a index to the namespace records
|
\-------------------------------------------------------------------------*/
typedef unsigned int domNameSpaceIndex;

................................................................................
   int     index;

} domNS;


#define MAX_PREFIX_LEN   80













/*--------------------------------------------------------------------------
|   domLineColumn
|
\-------------------------------------------------------------------------*/
typedef struct domLineColumn {
................................................................................
|   domNode
|
\-------------------------------------------------------------------------*/
typedef struct domNode {

    domNodeType         nodeType  : 8;
    domNodeFlags        nodeFlags : 8;

    domNameSpaceIndex   namespace : 8;
    unsigned int        info      : 8;




    unsigned int        nodeNumber;
    domDocument        *ownerDocument;
    struct domNode     *parentNode;
    struct domNode     *previousSibling;
    struct domNode     *nextSibling;

    domString           nodeName;  /* now the element node specific fields */



    struct domNode     *firstChild;
    struct domNode     *lastChild;
#ifdef TCL_THREADS
    struct domNode     *nextDeleted;
#endif
    struct domAttrNode *firstAttr;

} domNode;

/*--------------------------------------------------------------------------
|   domDeleteInfo
|
................................................................................
|   domTextNode
|
\-------------------------------------------------------------------------*/
typedef struct domTextNode {

    domNodeType         nodeType  : 8;
    domNodeFlags        nodeFlags : 8;

    domNameSpaceIndex   namespace : 8;
    unsigned int        info      : 8;




    unsigned int        nodeNumber;
    domDocument        *ownerDocument;
    struct domNode     *parentNode;
    struct domNode     *previousSibling;
    struct domNode     *nextSibling;

    domString           nodeValue;   /* now the text node specific fields */
................................................................................
|   domProcessingInstructionNode
|
\-------------------------------------------------------------------------*/
typedef struct domProcessingInstructionNode {

    domNodeType         nodeType  : 8;
    domNodeFlags        nodeFlags : 8;

    domNameSpaceIndex   namespace : 8;
    unsigned int        info      : 8;




    unsigned int        nodeNumber;
    domDocument        *ownerDocument;
    struct domNode     *parentNode;
    struct domNode     *previousSibling;
    struct domNode     *nextSibling;

    domString           targetValue;   /* now the pi specific fields */
    int                 targetLength;



    domString           dataValue;
    int                 dataLength;

} domProcessingInstructionNode;


/*--------------------------------------------------------------------------
................................................................................
|   domAttrNode
|
\-------------------------------------------------------------------------*/
typedef struct domAttrNode {

    domNodeType         nodeType  : 8;
    domAttrFlags        nodeFlags : 8;

    domNameSpaceIndex   namespace : 8;
    unsigned int        info      : 8;





    domString           nodeName;
    domString           nodeValue;
    int                 valueLength;
    struct domNode     *parentNode;
    struct domAttrNode *nextSibling;

} domAttrNode;
................................................................................
typedef int  (*domAddCallback)  (domNode * node, void * clientData);
typedef void (*domFreeCallback) (domNode * node, void * clientData);

/*--------------------------------------------------------------------------
|   Function prototypes
|
\-------------------------------------------------------------------------*/
const char *   domException2String (domException expection);


void           domModuleInitialize (void);
domDocument *  domCreateDoc (const char *baseURI, int storeLineColumn);
domDocument *  domCreateDocument (Tcl_Interp *interp, const char *uri,
                                  char *documentElementTagName);
void           domSetDocumentElement (domDocument *doc);

domDocument *  domReadDocument   (XML_Parser parser,
                                  char *xml,
                                  int   length,
                                  int   ignoreWhiteSpaces,
                                  TEncoding *encoding_8bit,
                                  int   storeLineColumn,

                                  int   feedbackAfter,

                                  Tcl_Channel channel,
                                  const char *baseurl,
                                  char *extResolver,
                                  int   useForeignDTD,
                                  int   paramEntityParsing,
                                  Tcl_Interp *interp);


void           domFreeDocument   (domDocument *doc, 
                                  domFreeCallback freeCB, 
                                  void * clientData);

void           domFreeNode       (domNode *node, 
                                  domFreeCallback freeCB, 
................................................................................

domTextNode *  domNewTextNode    (domDocument *doc,
                                  const char  *value,
                                  int          length,
                                  domNodeType  nodeType);

domNode *      domNewElementNode (domDocument *doc,
                                  const char  *tagName,
                                  domNodeType  nodeType);
		
domNode *      domNewElementNodeNS (domDocument *doc,
                                    const char  *tagName,
                                    const char  *uri,
                                    domNodeType  nodeType);

domProcessingInstructionNode * domNewProcessingInstructionNode (
                                  domDocument *doc,
                                  const char  *targetValue,
                                  int          targetLength,
                                  const char  *dataValue,
                                  int          dataLength);
................................................................................
const char *   domNamespaceURI    (domNode *node);
const char *   domGetLocalName    (const char *nodeName);
int            domSplitQName (const char *name, char *prefix,
                              const char **localName);
domNS *        domLookupNamespace (domDocument *doc, const char *prefix, 
                                   const char *namespaceURI);
domNS *        domLookupPrefix  (domNode *node, const char *prefix);


const char *   domLookupPrefixWithMappings (domNode *node, const char *prefix,
                                            char **prefixMappings);
domNS *        domLookupURI     (domNode *node, char *uri);
domNS *        domGetNamespaceByIndex (domDocument *doc, int nsIndex);
domNS *        domNewNamespace (domDocument *doc, const char *prefix,
                                const char *namespaceURI);
int            domGetLineColumn (domNode *node, int *line, int *column);
................................................................................

void           tcldom_tolower (const char *str, char *str_out, int  len);
int            domIsNAME (const char *name);
int            domIsPINAME (const char *name);
int            domIsQNAME (const char *name);
int            domIsNCNAME (const char *name);
int            domIsChar (const char *str);

int            domIsComment (const char *str);
int            domIsCDATA (const char *str);
int            domIsPIValue (const char *str);
void           domCopyTo (domNode *node, domNode *parent, int copyNS);
void           domCopyNS (domNode *from, domNode *to);
domAttrNode *  domCreateXMLNamespaceNode (domNode *parent);
void           domRenumberTree (domNode *node);







>
>


<







 







|
>

|
<
>







 







|
|
|




<
<
<
<
<
<





<
<
<



|
<
>







 







<
<
<
<
|








>
>
>
>
>
>
|






|
|







 







<
<
<
<
<
<
|
|
|
|
<







 







>
>
>







 







>
>
>
>
>
>
>
>
>
>







 







>


>
>
>
>







>
>
>


<
<
<







 







>


>
>
>
>







 







>


>
>
>
>








>
>
>







 







>


>
>
>
>
>







 







|




|







|

>

>


|


|
>







 







|
<



|
<







 







>
>







 







>







33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
..
84
85
86
87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
102
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139






140
141
142
143
144



145
146
147
148

149
150
151
152
153
154
155
156
...
204
205
206
207
208
209
210




211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
...
329
330
331
332
333
334
335






336
337
338
339

340
341
342
343
344
345
346
...
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
...
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
...
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598



599
600
601
602
603
604
605
...
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
...
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
...
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
...
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
...
744
745
746
747
748
749
750
751

752
753
754
755

756
757
758
759
760
761
762
...
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
...
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
|
\--------------------------------------------------------------------------*/

#ifndef __DOM_H__
#define __DOM_H__

#include <tcl.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <expat.h>

#include <domalloc.h>

/*
 * tDOM provides it's own memory allocator which is optimized for
 * low heap usage. It uses the native Tcl allocator underneath,
 * though, but it is not very MT-friendly. Therefore, you might
 * use the (normal) Tcl allocator with USE_NORMAL_ALLOCATOR
................................................................................
   };
#  define MEM_SUITE &memsuite
#else
#  define MEM_SUITE NULL
#endif

/*
 * Beginning with 8.6, interp->errorLine isn't public visible anymore
 * (TIP 330)
 */
#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6)

# define Tcl_GetErrorLine(interp) (interp)->errorLine
#endif

/*
 * Starting with Tcl 8.2 the Tcl_Panic() is defined properly
 * over the stubs table.
 * Also, we have a proper Tcl_GetString() shortcut afterwards.
 */
................................................................................
# define TDomNotThreaded(x)
# define TDomThreaded(x)    x
# define HASHTAB(doc,tab)   (doc)->tab
# define NODE_NO(doc)       ((doc)->nodeCounter)++
# define DOC_NO(doc)        (unsigned long)(doc)
#endif /* TCL_THREADS */

#define DOC_CMD(s,doc)      sprintf((s), "domDoc%p", (void *)(doc))
#define NODE_CMD(s,node)    sprintf((s), "domNode%p", (void *)(node))
#define XSLT_CMD(s,doc)     sprintf((s), "XSLTcmd%p", (void *)(doc))

#define XML_NAMESPACE "http://www.w3.org/XML/1998/namespace"
#define XMLNS_NAMESPACE "http://www.w3.org/2000/xmlns"







#define UTF8_1BYTE_CHAR(c) ( 0    == ((c) & 0x80))
#define UTF8_2BYTE_CHAR(c) ( 0xC0 == ((c) & 0xE0))
#define UTF8_3BYTE_CHAR(c) ( 0xE0 == ((c) & 0xF0))
#define UTF8_4BYTE_CHAR(c) ( 0xF0 == ((c) & 0xF8))




#define UTF8_CHAR_LEN(c) \
  UTF8_1BYTE_CHAR((c)) ? 1 : \
   (UTF8_2BYTE_CHAR((c)) ? 2 : \
     (UTF8_3BYTE_CHAR((c)) ? 3 : \

       (UTF8_4BYTE_CHAR((c)) ? 4 : 0)))

/* The following 2 defines are out of the expat code */

/* 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. */
................................................................................
  ? NCnameStart7Bit[(int)(*(p))] \
  : ((n) == 2 \
    ? UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)(p)) \
    : ((n) == 3 \
      ? UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)(p)) \
      : 0)))





#define UTF8_XMLCHAR3(p) \
  (*(p) == 0xED  \
   ? ((p)[1] < 0xA0 ? 1 : 0) \
   : (*(p) == 0xEF \
      ? ((p)[1] == 0xBF \
         ? ((p)[2] == 0xBE || (p)[2] == 0xBF ? 0 : 1) \
         : 1) \
      : 1)) \
    
/* This definition is lax in the sense, that it accepts every 4 byte
 * utf-8 character beyond #xFFFF as valid, no matter, if Unicode has
 * (so far) defined a character for that encoding point. Additionally,
 * this define does not care about the discouraged characters beyond
 * #xFFFF (but after all, they are only discouraged, not
 * forbidden). */
#define UTF8_XMLCHAR(p, n) \
  ((n) == 1 \
  ? CharBit[(int)(*(p))] \
  : ((n) == 2 \
    ? 1 \
    : ((n) == 3 \
      ? (UTF8_XMLCHAR3(p)) \
      : ((n) == 4 \
        ? 1 : 0))))

#include "../expat/nametab.h"

static const unsigned char nameChar7Bit[] = {
/* 0x00 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x08 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0x10 */    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
................................................................................
/* 0x60 */    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 0x68 */    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 0x70 */    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
/* 0x78 */    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
};








#define isNameStart(x)   UTF8_GET_NAME_START((x),UTF8_CHAR_LEN(*(x)))
#define isNCNameStart(x) UTF8_GET_NCNAME_START((x),UTF8_CHAR_LEN(*(x)))
#define isNameChar(x)    UTF8_GET_NAMING_NMTOKEN((x),UTF8_CHAR_LEN(*(x)))
#define isNCNameChar(x)  UTF8_GET_NAMING_NCNMTOKEN((x),UTF8_CHAR_LEN(*(x)))


#define IS_XML_WHITESPACE(c)  ((c)==' ' || (c)=='\n' || (c)=='\r' || (c)=='\t')

/*--------------------------------------------------------------------------
|   DOMString
|
\-------------------------------------------------------------------------*/
................................................................................
#define IS_NS_NODE                2

typedef unsigned int domDocFlags;

#define OUTPUT_DEFAULT_INDENT     1
#define NEEDS_RENUMBERING         2
#define DONT_FREE                 4
#define IGNORE_XMLNS              8
#define DOCUMENT_CMD             16
#define VAR_TRACE                32

/*--------------------------------------------------------------------------
|   a index to the namespace records
|
\-------------------------------------------------------------------------*/
typedef unsigned int domNameSpaceIndex;

................................................................................
   int     index;

} domNS;


#define MAX_PREFIX_LEN   80

/*---------------------------------------------------------------------------
|   type domActiveNS
|
\--------------------------------------------------------------------------*/
typedef struct _domActiveNS {

    int    depth;
    domNS *namespace;

} domActiveNS;


/*--------------------------------------------------------------------------
|   domLineColumn
|
\-------------------------------------------------------------------------*/
typedef struct domLineColumn {
................................................................................
|   domNode
|
\-------------------------------------------------------------------------*/
typedef struct domNode {

    domNodeType         nodeType  : 8;
    domNodeFlags        nodeFlags : 8;
#ifdef TDOM_LESS_NS
    domNameSpaceIndex   namespace : 8;
    unsigned int        info      : 8;
#else
    unsigned int        dummy     : 8;
    unsigned int        info      : 8;    
#endif
    unsigned int        nodeNumber;
    domDocument        *ownerDocument;
    struct domNode     *parentNode;
    struct domNode     *previousSibling;
    struct domNode     *nextSibling;

    domString           nodeName;  /* now the element node specific fields */
#ifndef TDOM_LESS_NS
    domNameSpaceIndex   namespace;
#endif
    struct domNode     *firstChild;
    struct domNode     *lastChild;



    struct domAttrNode *firstAttr;

} domNode;

/*--------------------------------------------------------------------------
|   domDeleteInfo
|
................................................................................
|   domTextNode
|
\-------------------------------------------------------------------------*/
typedef struct domTextNode {

    domNodeType         nodeType  : 8;
    domNodeFlags        nodeFlags : 8;
#ifdef TDOM_LESS_NS
    domNameSpaceIndex   namespace : 8;
    unsigned int        info      : 8;
#else
    unsigned int        dummy     : 8;
    unsigned int        info      : 8;    
#endif
    unsigned int        nodeNumber;
    domDocument        *ownerDocument;
    struct domNode     *parentNode;
    struct domNode     *previousSibling;
    struct domNode     *nextSibling;

    domString           nodeValue;   /* now the text node specific fields */
................................................................................
|   domProcessingInstructionNode
|
\-------------------------------------------------------------------------*/
typedef struct domProcessingInstructionNode {

    domNodeType         nodeType  : 8;
    domNodeFlags        nodeFlags : 8;
#ifdef TDOM_LESS_NS
    domNameSpaceIndex   namespace : 8;
    unsigned int        info      : 8;
#else
    unsigned int        dummy     : 8;
    unsigned int        info      : 8;    
#endif
    unsigned int        nodeNumber;
    domDocument        *ownerDocument;
    struct domNode     *parentNode;
    struct domNode     *previousSibling;
    struct domNode     *nextSibling;

    domString           targetValue;   /* now the pi specific fields */
    int                 targetLength;
#ifndef TDOM_LESS_NS
    domNameSpaceIndex   namespace;
#endif
    domString           dataValue;
    int                 dataLength;

} domProcessingInstructionNode;


/*--------------------------------------------------------------------------
................................................................................
|   domAttrNode
|
\-------------------------------------------------------------------------*/
typedef struct domAttrNode {

    domNodeType         nodeType  : 8;
    domAttrFlags        nodeFlags : 8;
#ifdef TDOM_LESS_NS
    domNameSpaceIndex   namespace : 8;
    unsigned int        info      : 8;
#else
    unsigned int        dummy     : 8;
    unsigned int        info      : 8;    
    domNameSpaceIndex   namespace;
#endif
    domString           nodeName;
    domString           nodeValue;
    int                 valueLength;
    struct domNode     *parentNode;
    struct domAttrNode *nextSibling;

} domAttrNode;
................................................................................
typedef int  (*domAddCallback)  (domNode * node, void * clientData);
typedef void (*domFreeCallback) (domNode * node, void * clientData);

/*--------------------------------------------------------------------------
|   Function prototypes
|
\-------------------------------------------------------------------------*/
const char *   domException2String (domException exception);


void           domModuleInitialize (void);
domDocument *  domCreateDoc (const char *baseURI, int storeLineColumn);
domDocument *  domCreateDocument (const char *uri,
                                  char *documentElementTagName);
void           domSetDocumentElement (domDocument *doc);

domDocument *  domReadDocument   (XML_Parser parser,
                                  char *xml,
                                  int   length,
                                  int   ignoreWhiteSpaces,
                                  int   keepCDATA,
                                  int   storeLineColumn,
                                  int   ignoreXMLNS,
                                  int   feedbackAfter,
                                  Tcl_Obj *feedbackCmd,
                                  Tcl_Channel channel,
                                  const char *baseurl,
                                  Tcl_Obj *extResolver,
                                  int   useForeignDTD,
                                  int   paramEntityParsing,
                                  Tcl_Interp *interp,
                                  int  *status);

void           domFreeDocument   (domDocument *doc, 
                                  domFreeCallback freeCB, 
                                  void * clientData);

void           domFreeNode       (domNode *node, 
                                  domFreeCallback freeCB, 
................................................................................

domTextNode *  domNewTextNode    (domDocument *doc,
                                  const char  *value,
                                  int          length,
                                  domNodeType  nodeType);

domNode *      domNewElementNode (domDocument *doc,
                                  const char  *tagName);

		
domNode *      domNewElementNodeNS (domDocument *doc,
                                    const char  *tagName,
                                    const char  *uri);


domProcessingInstructionNode * domNewProcessingInstructionNode (
                                  domDocument *doc,
                                  const char  *targetValue,
                                  int          targetLength,
                                  const char  *dataValue,
                                  int          dataLength);
................................................................................
const char *   domNamespaceURI    (domNode *node);
const char *   domGetLocalName    (const char *nodeName);
int            domSplitQName (const char *name, char *prefix,
                              const char **localName);
domNS *        domLookupNamespace (domDocument *doc, const char *prefix, 
                                   const char *namespaceURI);
domNS *        domLookupPrefix  (domNode *node, const char *prefix);
int            domIsNamespaceInScope (domActiveNS *NSstack, int NSstackPos,
                                      const char *prefix, const char *namespaceURI);
const char *   domLookupPrefixWithMappings (domNode *node, const char *prefix,
                                            char **prefixMappings);
domNS *        domLookupURI     (domNode *node, char *uri);
domNS *        domGetNamespaceByIndex (domDocument *doc, int nsIndex);
domNS *        domNewNamespace (domDocument *doc, const char *prefix,
                                const char *namespaceURI);
int            domGetLineColumn (domNode *node, int *line, int *column);
................................................................................

void           tcldom_tolower (const char *str, char *str_out, int  len);
int            domIsNAME (const char *name);
int            domIsPINAME (const char *name);
int            domIsQNAME (const char *name);
int            domIsNCNAME (const char *name);
int            domIsChar (const char *str);
int            domIsBMPChar (const char *str);
int            domIsComment (const char *str);
int            domIsCDATA (const char *str);
int            domIsPIValue (const char *str);
void           domCopyTo (domNode *node, domNode *parent, int copyNS);
void           domCopyNS (domNode *from, domNode *to);
domAttrNode *  domCreateXMLNamespaceNode (domNode *parent);
void           domRenumberTree (domNode *node);

Changes to generic/domalloc.h.

30
31
32
33
34
35
36
37
38
39
40
|
|
|   written by Jochen Loewer
|   October, 2000
|
\--------------------------------------------------------------------------*/

void   domAllocInit();
void * domAlloc(int size);
void   domFree(void *mem);








|



30
31
32
33
34
35
36
37
38
39
40
|
|
|   written by Jochen Loewer
|   October, 2000
|
\--------------------------------------------------------------------------*/

void   domAllocInit(void);
void * domAlloc(int size);
void   domFree(void *mem);

Changes to generic/domhtml.c.

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
...
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
...
591
592
593
594
595
596
597

598
599
600
601
602
603
604
...
613
614
615
616
617
618
619







620
621
622
623
624
625
626
627
628
629







630
631
632
633
634
635

636
637
638







639


640
641
642
643
644
645
646
647
648
649
650
651
652
653

654
655
656
657
658
659
660
...
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
...
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
...
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
...
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
....
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
....
1327
1328
1329
1330
1331
1332
1333

1334
1335
1336
1337
1338
1339
1340
....
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368

1369
1370
1371
1372
1373
1374
1375
....
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
....
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
|
|
|   written by Jochen Loewer
|   October 2000
|
|   ------------------------------------------------------------------------
|
|   A parser for XML.
|
|   Copyright (C) 1998 D. Richard Hipp
|
|   This library is free software; you can redistribute it and/or
|   modify it under the terms of the GNU Library General Public
|   License as published by the Free Software Foundation; either
|   version 2 of the License, or (at your option) any later version.
|
|   This library is distributed in the hope that it will be useful,
|   but WITHOUT ANY WARRANTY; without even the implied warranty of
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
|   Library General Public License for more details.
|
|   You should have received a copy of the GNU Library General Public
|   License along with this library; if not, write to the
|   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|   Boston, MA  02111-1307, USA.
|
|   Author contact information:
|     drh@acm.org
|     http://www.hwaci.com/drh/
|
\---------------------------------------------------------------------------*/



/*----------------------------------------------------------------------------
|   Includes
................................................................................

/*----------------------------------------------------------------------------
|   The size of the hash table.  For best results this should
|   be a prime number which is about the same size as the number of
|   character entity references known to the system.
|
\---------------------------------------------------------------------------*/
#if TclOnly8Bits
#define ER_HASH_SIZE 107
#else
#define ER_HASH_SIZE 257
#endif

/*----------------------------------------------------------------------------
|   The following flag is TRUE if entity reference hash table needs
|   to be initialized.
|
\---------------------------------------------------------------------------*/
static int bErNeedsInit = 1;
................................................................................
\---------------------------------------------------------------------------*/
static Er er_sequences[] = {
    { "amp",       "&",        0 },
    { "lt",        "<",        0 },
    { "gt",        ">",        0 },
    { "apos",      "'",        0 },
    { "quot",      "\"",       0 },
#if TclOnly8Bits
    { "nbsp",      "\240",     0 },
    { "iexcl",     "\241",     0 }, /* inverted exclamation mark  */
    { "cent",      "\242",     0 }, /* cent sign  */
    { "pound",     "\243",     0 }, /* pound sterling sign  */
    { "curren",    "\244",     0 }, /* general currency sign  */
    { "yen",       "\245",     0 }, /* yen sign  */
    { "brvbar",    "\246",     0 }, /* broken (vertical) bar  */
    { "sect",      "\247",     0 }, /* section sign  */
    { "uml",       "\250",     0 }, /* umlaut (dieresis)  */
    { "copy",      "\251",     0 }, /* copyright sign  */
    { "ordf",      "\252",     0 }, /* ordinal indicator, feminine  */
    { "laquo",     "\253",     0 }, /* angle quotation mark, left  */
    { "not",       "\254",     0 }, /* not sign  */
    { "shy",       "\255",     0 }, /* soft hyphen  */
    { "reg",       "\256",     0 }, /* registered sign  */
    { "macr",      "\257",     0 }, /* macron  */
    { "deg",       "\260",     0 }, /* degree sign  */
    { "plusmn",    "\261",     0 }, /* plus-or-minus sign  */
    { "sup2",      "\262",     0 }, /* superscript two  */
    { "sup3",      "\263",     0 }, /* superscript three  */
    { "acute",     "\264",     0 }, /* acute accent  */
    { "micro",     "\265",     0 }, /* micro sign  */
    { "para",      "\266",     0 }, /* pilcrow (paragraph sign)  */
    { "middot",    "\267",     0 }, /* middle dot  */
    { "cedil",     "\270",     0 }, /* cedilla  */
    { "sup1",      "\271",     0 }, /* superscript one  */
    { "ordm",      "\272",     0 }, /* ordinal indicator, masculine  */
    { "raquo",     "\273",     0 }, /* angle quotation mark, right  */
    { "frac14",    "\274",     0 }, /* fraction one-quarter  */
    { "frac12",    "\275",     0 }, /* fraction one-half  */
    { "frac34",    "\276",     0 }, /* fraction three-quarters  */
    { "iquest",    "\277",     0 }, /* inverted question mark  */
    { "Agrave",    "\300",     0 }, /* capital A, grave accent  */
    { "Aacute",    "\301",     0 }, /* capital A, acute accent  */
    { "Acirc",     "\302",     0 }, /* capital A, circumflex accent  */
    { "Atilde",    "\303",     0 }, /* capital A, tilde  */
    { "Auml",      "\304",     0 }, /* capital A, dieresis or umlaut mark  */
    { "Aring",     "\305",     0 }, /* capital A, ring  */
    { "AElig",     "\306",     0 }, /* capital AE diphthong (ligature)  */
    { "Ccedil",    "\307",     0 }, /* capital C, cedilla  */
    { "Egrave",    "\310",     0 }, /* capital E, grave accent  */
    { "Eacute",    "\311",     0 }, /* capital E, acute accent  */
    { "Ecirc",     "\312",     0 }, /* capital E, circumflex accent  */
    { "Euml",      "\313",     0 }, /* capital E, dieresis or umlaut mark  */
    { "Igrave",    "\314",     0 }, /* capital I, grave accent  */
    { "Iacute",    "\315",     0 }, /* capital I, acute accent  */
    { "Icirc",     "\316",     0 }, /* capital I, circumflex accent  */
    { "Iuml",      "\317",     0 }, /* capital I, dieresis or umlaut mark  */
    { "ETH",       "\320",     0 }, /* capital Eth, Icelandic  */
    { "Ntilde",    "\321",     0 }, /* capital N, tilde  */
    { "Ograve",    "\322",     0 }, /* capital O, grave accent  */
    { "Oacute",    "\323",     0 }, /* capital O, acute accent  */
    { "Ocirc",     "\324",     0 }, /* capital O, circumflex accent  */
    { "Otilde",    "\325",     0 }, /* capital O, tilde  */
    { "Ouml",      "\326",     0 }, /* capital O, dieresis or umlaut mark  */
    { "times",     "\327",     0 }, /* multiply sign  */
    { "Oslash",    "\330",     0 }, /* capital O, slash  */
    { "Ugrave",    "\331",     0 }, /* capital U, grave accent  */
    { "Uacute",    "\332",     0 }, /* capital U, acute accent  */
    { "Ucirc",     "\333",     0 }, /* capital U, circumflex accent  */
    { "Uuml",      "\334",     0 }, /* capital U, dieresis or umlaut mark  */
    { "Yacute",    "\335",     0 }, /* capital Y, acute accent  */
    { "THORN",     "\336",     0 }, /* capital THORN, Icelandic  */
    { "szlig",     "\337",     0 }, /* small sharp s, German (sz ligature)  */
    { "agrave",    "\340",     0 }, /* small a, grave accent  */
    { "aacute",    "\341",     0 }, /* small a, acute accent  */
    { "acirc",     "\342",     0 }, /* small a, circumflex accent  */
    { "atilde",    "\343",     0 }, /* small a, tilde  */
    { "auml",      "\344",     0 }, /* small a, dieresis or umlaut mark  */
    { "aring",     "\345",     0 }, /* small a, ring  */
    { "aelig",     "\346",     0 }, /* small ae diphthong (ligature)  */
    { "ccedil",    "\347",     0 }, /* small c, cedilla  */
    { "egrave",    "\350",     0 }, /* small e, grave accent  */
    { "eacute",    "\351",     0 }, /* small e, acute accent  */
    { "ecirc",     "\352",     0 }, /* small e, circumflex accent  */
    { "euml",      "\353",     0 }, /* small e, dieresis or umlaut mark  */
    { "igrave",    "\354",     0 }, /* small i, grave accent  */
    { "iacute",    "\355",     0 }, /* small i, acute accent  */
    { "icirc",     "\356",     0 }, /* small i, circumflex accent  */
    { "iuml",      "\357",     0 }, /* small i, dieresis or umlaut mark  */
    { "eth",       "\360",     0 }, /* small eth, Icelandic  */
    { "ntilde",    "\361",     0 }, /* small n, tilde  */
    { "ograve",    "\362",     0 }, /* small o, grave accent  */
    { "oacute",    "\363",     0 }, /* small o, acute accent  */
    { "ocirc",     "\364",     0 }, /* small o, circumflex accent  */
    { "otilde",    "\365",     0 }, /* small o, tilde  */
    { "ouml",      "\366",     0 }, /* small o, dieresis or umlaut mark  */
    { "divide",    "\367",     0 }, /* divide sign  */
    { "oslash",    "\370",     0 }, /* small o, slash  */
    { "ugrave",    "\371",     0 }, /* small u, grave accent  */
    { "uacute",    "\372",     0 }, /* small u, acute accent  */
    { "ucirc",     "\373",     0 }, /* small u, circumflex accent  */
    { "uuml",      "\374",     0 }, /* small u, dieresis or umlaut mark  */
    { "yacute",    "\375",     0 }, /* small y, acute accent  */
    { "thorn",     "\376",     0 }, /* small thorn, Icelandic  */
    { "yuml",      "\377",     0 }, /* small y, dieresis or umlaut mark  */
#else
    { "nbsp",      "\xC2\xA0",    0 },
    { "iexcl",     "\xC2\xA1",    0 },
    { "cent",      "\xC2\xA2",    0 },
    { "pound",     "\xC2\xA3",    0 },
    { "curren",    "\xC2\xA4",    0 },
    { "yen",       "\xC2\xA5",    0 },
    { "brvbar",    "\xC2\xA6",    0 },
................................................................................
    { "lang",      "\xE2\x8C\xA9",    0 },
    { "rang",      "\xE2\x8C\xAA",    0 },
    { "loz",       "\xE2\x97\x8A",    0 },
    { "spades",    "\xE2\x99\xA0",    0 },
    { "clubs",     "\xE2\x99\xA3",    0 },
    { "hearts",    "\xE2\x99\xA5",    0 },
    { "diams",     "\xE2\x99\xA6",    0 },
#endif
};


/*----------------------------------------------------------------------------
|   ErInit --
|
|       Initialize the entity reference hash table
................................................................................
            bErNeedsInit = 0;
        }
        TDomThreaded(Tcl_MutexUnlock(&initMutex);)
    }

    while (z[from]) {
        if (z[from]=='&') {

            int i = from+1;
            int c;

            if (z[i] == '#') {
                /*---------------------------------------------
                |   convert character reference
                \--------------------------------------------*/
................................................................................
                        if ((c>='A') && (c<='F')) {
                            value += c-'A' + 10;
                        } else
                        if ((c>='a') && (c<='f')) {
                            value += c-'a' + 10;
                        } else {
                            /* error */







                        }
                        i++;
                    }
                } else {
                    while ((c=z[i]) && (c!=';')) {
                        value = value * 10;
                        if ((c>='0') && (c<='9')) {
                            value += c-'0';
                        } else {
                            /* error */







                        }
                        i++;
                    }
                }
                if (z[i]!=';') {
                    /* error */

                }
                from = i+1;
#if TclOnly8Bits







                z[to++] = value;


#else 
                if (value < 0x80) {
                    z[to++] = value;
                } else if (value <= 0x7FF) {
                    z[to++] = (char) ((value >> 6) | 0xC0);
                    z[to++] = (char) ((value | 0x80) & 0xBF);
                } else if (value <= 0xFFFF) {
                    z[to++] = (char) ((value >> 12) | 0xE0);
                    z[to++] = (char) (((value >> 6) | 0x80) & 0xBF);
                    z[to++] = (char) ((value | 0x80) & 0xBF);
                } else {
                    /* error */
                }
#endif

            } else {
                while (z[i] && isalpha((unsigned char)z[i])) {
                   i++;
                }
                c = z[i];
                z[i] = 0;
                h = ErHash(&z[from+1]);
................................................................................
                /*--------------------------------------------------------
                |   allocate new TEXT node
                \-------------------------------------------------------*/
                tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                memset(tnode, 0, sizeof(domTextNode));
                tnode->nodeType    = TEXT_NODE;
                tnode->nodeFlags   = 0;
                tnode->namespace   = 0;
                tnode->ownerDocument = doc;
                tnode->nodeNumber  = NODE_NO(doc);
                tnode->valueLength = (x - start);
                tnode->nodeValue   = (char*)MALLOC((x - start)+1);
                memmove(tnode->nodeValue, start, (x - start));
                *(tnode->nodeValue + (x - start)) = 0;
                DBG(fprintf(stderr, "New text node: '%s'\n", tnode->nodeValue);)
................................................................................
                pnode = parent_node;
                while (pnode != NULL) {
                    DBG(fprintf(stderr, "checking '%s' to top hierarchy: '%s' \n", start+2,pnode->nodeName);)
                    if (!strcmp(start+2,pnode->nodeName)) break;
                    pnode = pnode->parentNode;
                }
                if (pnode == NULL) {
                    /* begining tag was not found the way up the tag hierarchy
                       -> ignore the tag */
                    DBG(fprintf(stderr,"ignoring closing '%s' \n", start+2);)
                    ignore = 1;
                }
            }            
            if (!ignore) {

................................................................................


                        /*---------------------------------------------------------------
                        |   check for tags for which end tag can be omitted
                        \--------------------------------------------------------------*/
                        autoclose = 0;
                        switch (pn[0]) {
                            case 'a': if (!strcmp(pn,"a"))        autoclose = 1; break;
                            case 'b': if (!strcmp(pn,"b"))        autoclose = 1; break;
                            case 'c': if (!strcmp(pn,"colgroup")) autoclose = 1; break;
                            case 'd': if (!strcmp(pn,"dd") ||
                                          !strcmp(pn,"dt") ||
                                          (!strcmp(start+2,"form") && !strcmp(pn,"div"))
                                         )                        autoclose = 1; break;
                            case 'h': if (!strcmp(pn,"head") ||
                                          !strcmp(pn,"html"))     autoclose = 1; break;
                            case 'f': if (!strcmp(pn,"font")||
                                          !strcmp(pn,"form"))     autoclose = 1; break;
                            case 'i': if (!strcmp(pn,"i"))        autoclose = 1; break;
                            case 'l': if (!strcmp(pn,"li"))       autoclose = 1; break;
                            case 'n': if (!strcmp(pn,"noscript")) autoclose = 1; break;
                            case 'o': if (!strcmp(pn,"option"))   autoclose = 1; break;
                            case 'p': if (!strcmp(pn,"p"))        autoclose = 1; break;
                            case 's': if (!strcmp(pn,"span"))     autoclose = 1; break;
                            case 't': if (!strcmp(pn,"tbody") ||
                                          !strcmp(pn,"td")    ||
                                          !strcmp(pn,"tfoot") ||
                                          !strcmp(pn,"thead") ||
                                          !strcmp(pn,"th")    ||
                                          !strcmp(pn,"tr")    ||
                                          !strcmp(pn,"tt"))       autoclose = 1; break;
                            case 'u': if (!strcmp(pn,"ul"))       autoclose = 1; break; /* ext */
                        }
                        /*---------------------------------------------------------------
                        |   check for tags for close inner tags
                        \--------------------------------------------------------------*/
                        switch (start[2]) {
                            case 'b': if (!strcmp(start+2,"body")) autoclose = 1; break;
                        }
................................................................................
                        /*----------------------------------------------------
                        |   allocate new COMMENT node for comments
                        \---------------------------------------------------*/
                        tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                        memset(tnode, 0, sizeof(domTextNode));
                        tnode->nodeType      = COMMENT_NODE;
                        tnode->nodeFlags     = 0;
                        tnode->namespace     = 0;
                        tnode->ownerDocument = doc;
                        tnode->nodeNumber    = NODE_NO(doc);
                        tnode->parentNode    = parent_node;
                        tnode->valueLength   = x - start - 4;
                        tnode->nodeValue     = (char*)MALLOC(tnode->valueLength+1);
                        memmove(tnode->nodeValue, start+4, tnode->valueLength);
                        *(tnode->nodeValue + tnode->valueLength) = 0;
................................................................................
                            /*----------------------------------------------------
                            |   allocate new TEXT node for CDATA section data
                            \---------------------------------------------------*/
                            tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                            memset(tnode, 0, sizeof(domTextNode));
                            tnode->nodeType      = TEXT_NODE;
                            tnode->nodeFlags     = 0;
                            tnode->namespace     = 0;
                            tnode->ownerDocument = doc;
                            tnode->nodeNumber    = NODE_NO(doc);
                            tnode->parentNode    = parent_node;
                            tnode->valueLength   = (x - start);
                            tnode->nodeValue     = (char*)MALLOC((x - start)+1);
                            memmove(tnode->nodeValue, start, (x - start));
                            *(tnode->nodeValue + (x - start)) = 0;
................................................................................
                    h = Tcl_CreateHashEntry (doc->ids, attrnode->nodeValue,
                                             &hnew);
                    /* How to resolve in case of dublicates?  We
                       follow, what the core dom building code does:
                       the first value in document order wins. */
                    if (hnew) {
                        Tcl_SetHashValue (h, node);

                    }
                }
                if (node->firstAttr) {
                    lastAttr->nextSibling = attrnode;
                } else {
                    node->firstAttr = attrnode;
                }
................................................................................
                }
            }

            /*-----------------------------------------------------------
            |   check for empty HTML tags
            \----------------------------------------------------------*/
            switch (node->nodeName[0]) {
                case 'a':  if (!strcmp(node->nodeName,"area"))     hasContent = 0; break;
                case 'b':  if (!strcmp(node->nodeName,"br")     ||
                               !strcmp(node->nodeName,"base")   ||
                               !strcmp(node->nodeName,"basefont")) hasContent = 0; break;
                case 'c':  if (!strcmp(node->nodeName,"col"))      hasContent = 0; break;
                case 'e':  if (!strcmp(node->nodeName,"embed"))    hasContent = 0; break; /*ext*/
                case 'f':  if (!strcmp(node->nodeName,"frame"))    hasContent = 0; break;
                case 'h':  if (!strcmp(node->nodeName,"hr"))       hasContent = 0; break;
                case 'i':  if (!strcmp(node->nodeName,"img")   ||
                               !strcmp(node->nodeName,"input") ||
                               !strcmp(node->nodeName,"isindex"))  hasContent = 0; break;
                case 'l':  if (!strcmp(node->nodeName,"link"))     hasContent = 0; break;
                case 'm':  if (!strcmp(node->nodeName,"meta"))     hasContent = 0; break;
                case 'p':  if (!strcmp(node->nodeName,"param"))    hasContent = 0; break;
                case 's':  if (!strcmp(node->nodeName,"spacer"))   hasContent = 0; break; /*ext*/

            }

            if (*x=='/') {
                hasContent = 0;
                x++;
                if (*x!='>') {
                    RetError("Syntax Error",(x - html - 1) );
................................................................................
                    /*----------------------------------------------------
                    |   allocate new TEXT node for style/script data
                    \---------------------------------------------------*/
                    tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                    memset(tnode, 0, sizeof(domTextNode));
                    tnode->nodeType      = TEXT_NODE;
                    tnode->nodeFlags     = 0;
                    tnode->namespace     = 0;
                    tnode->ownerDocument = doc;
                    tnode->nodeNumber    = NODE_NO(doc);
                    tnode->parentNode    = node;
                    tnode->valueLength   = (x - start);
                    tnode->nodeValue     = (char*)MALLOC((x - start)+1);
                    memmove(tnode->nodeValue, start, (x - start));
                    *(tnode->nodeValue + (x - start)) = 0;
................................................................................
        pn = (char*)node->parentNode->nodeName;
        DBG(fprintf(stderr, "final autoclose '%s'? \n", pn);)
        /*---------------------------------------------------------------
        |   check for tags for which end tag can be omitted
        \--------------------------------------------------------------*/
        autoclose = 0;
        switch (pn[0]) {
            case 'b': if (!strcmp(pn,"body"))     autoclose = 1; break;
            case 'c': if (!strcmp(pn,"colgroup")) autoclose = 1; break;
            case 'd': if (!strcmp(pn,"dd") ||
                          !strcmp(pn,"dt"))       autoclose = 1; break;
            case 'h': if (!strcmp(pn,"head") ||
                          !strcmp(pn,"html"))     autoclose = 1; break;
            case 'l': if (!strcmp(pn,"li"))       autoclose = 1; break;
            case 'o': if (!strcmp(pn,"option"))   autoclose = 1; break;
            case 'p': if (!strcmp(pn,"p"))        autoclose = 1; break;
            case 't': if (!strcmp(pn,"tbody") ||
                          !strcmp(pn,"td")    ||
                          !strcmp(pn,"tfoot") ||
                          !strcmp(pn,"thead") ||
                          !strcmp(pn,"th")    ||
                          !strcmp(pn,"tr"))       autoclose = 1; break;
            case 'u': if (!strcmp(pn,"ul"))       autoclose = 1; break; /* ext */
        }
        if (!autoclose) break;
        DBG(fprintf(stderr, "final autoclosed '%s'! \n", pn);)
        node = node->parentNode;
        parent_node = node->parentNode;
    }
    if (parent_node == NULL) {







|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<
<
<

<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<







 







>







 







>
>
>
>
>
>
>










>
>
>
>
>
>
>






>

<
|
>
>
>
>
>
>
>
|
>
>
|












|
>







 







<







 







|







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







 







<







 







<







 







>







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>







 







<







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







30
31
32
33
34
35
36
37
38
39



















40
41
42
43
44
45
46
..
96
97
98
99
100
101
102



103

104
105
106
107
108
109
110
...
157
158
159
160
161
162
163


































































































164
165
166
167
168
169
170
...
407
408
409
410
411
412
413

414
415
416
417
418
419
420
...
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
...
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530

531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
...
662
663
664
665
666
667
668

669
670
671
672
673
674
675
...
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
...
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
...
869
870
871
872
873
874
875

876
877
878
879
880
881
882
...
948
949
950
951
952
953
954

955
956
957
958
959
960
961
....
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
....
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
....
1315
1316
1317
1318
1319
1320
1321

1322
1323
1324
1325
1326
1327
1328
....
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
|
|
|   written by Jochen Loewer
|   October 2000
|
|   ------------------------------------------------------------------------
|
|   Partly based on a parser for XML (for TMML by R.Hipp 1998). 
|   This source code is released into the public domain by the author.
|   on 2002, December 17.



















|
\---------------------------------------------------------------------------*/



/*----------------------------------------------------------------------------
|   Includes
................................................................................

/*----------------------------------------------------------------------------
|   The size of the hash table.  For best results this should
|   be a prime number which is about the same size as the number of
|   character entity references known to the system.
|
\---------------------------------------------------------------------------*/



#define ER_HASH_SIZE 257


/*----------------------------------------------------------------------------
|   The following flag is TRUE if entity reference hash table needs
|   to be initialized.
|
\---------------------------------------------------------------------------*/
static int bErNeedsInit = 1;
................................................................................
\---------------------------------------------------------------------------*/
static Er er_sequences[] = {
    { "amp",       "&",        0 },
    { "lt",        "<",        0 },
    { "gt",        ">",        0 },
    { "apos",      "'",        0 },
    { "quot",      "\"",       0 },


































































































    { "nbsp",      "\xC2\xA0",    0 },
    { "iexcl",     "\xC2\xA1",    0 },
    { "cent",      "\xC2\xA2",    0 },
    { "pound",     "\xC2\xA3",    0 },
    { "curren",    "\xC2\xA4",    0 },
    { "yen",       "\xC2\xA5",    0 },
    { "brvbar",    "\xC2\xA6",    0 },
................................................................................
    { "lang",      "\xE2\x8C\xA9",    0 },
    { "rang",      "\xE2\x8C\xAA",    0 },
    { "loz",       "\xE2\x97\x8A",    0 },
    { "spades",    "\xE2\x99\xA0",    0 },
    { "clubs",     "\xE2\x99\xA3",    0 },
    { "hearts",    "\xE2\x99\xA5",    0 },
    { "diams",     "\xE2\x99\xA6",    0 },

};


/*----------------------------------------------------------------------------
|   ErInit --
|
|       Initialize the entity reference hash table
................................................................................
            bErNeedsInit = 0;
        }
        TDomThreaded(Tcl_MutexUnlock(&initMutex);)
    }

    while (z[from]) {
        if (z[from]=='&') {
            int isInvalid = 0;
            int i = from+1;
            int c;

            if (z[i] == '#') {
                /*---------------------------------------------
                |   convert character reference
                \--------------------------------------------*/
................................................................................
                        if ((c>='A') && (c<='F')) {
                            value += c-'A' + 10;
                        } else
                        if ((c>='a') && (c<='f')) {
                            value += c-'a' + 10;
                        } else {
                            /* error */
			    isInvalid = 1;
			    break;
                        }
                        if (value > 2097152) {
                            /* error */
			    isInvalid = 1;
			    break;
                        }
                        i++;
                    }
                } else {
                    while ((c=z[i]) && (c!=';')) {
                        value = value * 10;
                        if ((c>='0') && (c<='9')) {
                            value += c-'0';
                        } else {
                            /* error */
  			    isInvalid = 1;
			    break;
                        }
                        if (value > 2097152) {
                            /* error */
			    isInvalid = 1;
			    break;
                        }
                        i++;
                    }
                }
                if (z[i]!=';') {
                    /* error */
		    isInvalid = 1;
                }

		if (isInvalid) {
		    /*
		     * In case the character reference was invalid
		     * it was a false alaram, no valid character
		     * reference, just copy the source chars;
		     */
		    int j;
		    for (j = from; j < i; j++) {
		        z[to++] = z[j];
		    }
		    from = i;
		} else {
                if (value < 0x80) {
                    z[to++] = value;
                } else if (value <= 0x7FF) {
                    z[to++] = (char) ((value >> 6) | 0xC0);
                    z[to++] = (char) ((value | 0x80) & 0xBF);
                } else if (value <= 0xFFFF) {
                    z[to++] = (char) ((value >> 12) | 0xE0);
                    z[to++] = (char) (((value >> 6) | 0x80) & 0xBF);
                    z[to++] = (char) ((value | 0x80) & 0xBF);
                } else {
                    /* error */
                }
		    from = i+1;
		}
            } else {
                while (z[i] && isalpha((unsigned char)z[i])) {
                   i++;
                }
                c = z[i];
                z[i] = 0;
                h = ErHash(&z[from+1]);
................................................................................
                /*--------------------------------------------------------
                |   allocate new TEXT node
                \-------------------------------------------------------*/
                tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                memset(tnode, 0, sizeof(domTextNode));
                tnode->nodeType    = TEXT_NODE;
                tnode->nodeFlags   = 0;

                tnode->ownerDocument = doc;
                tnode->nodeNumber  = NODE_NO(doc);
                tnode->valueLength = (x - start);
                tnode->nodeValue   = (char*)MALLOC((x - start)+1);
                memmove(tnode->nodeValue, start, (x - start));
                *(tnode->nodeValue + (x - start)) = 0;
                DBG(fprintf(stderr, "New text node: '%s'\n", tnode->nodeValue);)
................................................................................
                pnode = parent_node;
                while (pnode != NULL) {
                    DBG(fprintf(stderr, "checking '%s' to top hierarchy: '%s' \n", start+2,pnode->nodeName);)
                    if (!strcmp(start+2,pnode->nodeName)) break;
                    pnode = pnode->parentNode;
                }
                if (pnode == NULL) {
                    /* beginning tag was not found the way up the tag hierarchy
                       -> ignore the tag */
                    DBG(fprintf(stderr,"ignoring closing '%s' \n", start+2);)
                    ignore = 1;
                }
            }            
            if (!ignore) {

................................................................................


                        /*---------------------------------------------------------------
                        |   check for tags for which end tag can be omitted
                        \--------------------------------------------------------------*/
                        autoclose = 0;
                        switch (pn[0]) {
                        case 'a': if (!strcmp(pn,"a"))        {autoclose = 1;} break;
                        case 'b': if (!strcmp(pn,"b"))        {autoclose = 1;} break;
                        case 'c': if (!strcmp(pn,"colgroup")) {autoclose = 1;} break;
                        case 'd': if (!strcmp(pn,"dd") ||
                                      !strcmp(pn,"dt") ||
                                      (!strcmp(start+2,"form") && !strcmp(pn,"div"))
                            )                        {autoclose = 1;}          break;
                        case 'h': if (!strcmp(pn,"head") ||
                                      !strcmp(pn,"html"))     {autoclose = 1;} break;
                        case 'f': if (!strcmp(pn,"font")||
                                      !strcmp(pn,"form"))     {autoclose = 1;} break;
                        case 'i': if (!strcmp(pn,"i"))        {autoclose = 1;} break;
                        case 'l': if (!strcmp(pn,"li"))       {autoclose = 1;} break;
                        case 'n': if (!strcmp(pn,"noscript")) {autoclose = 1;} break;
                        case 'o': if (!strcmp(pn,"option"))   {autoclose = 1;} break;
                        case 'p': if (!strcmp(pn,"p"))        {autoclose = 1;} break;
                        case 's': if (!strcmp(pn,"span"))     {autoclose = 1;} break;
                        case 't': if (!strcmp(pn,"tbody") ||
                                      !strcmp(pn,"td")    ||
                                      !strcmp(pn,"tfoot") ||
                                      !strcmp(pn,"thead") ||
                                      !strcmp(pn,"th")    ||
                                      !strcmp(pn,"tr")    ||
                                      !strcmp(pn,"tt"))       {autoclose = 1;} break;
                        case 'u': if (!strcmp(pn,"ul"))       {autoclose = 1;} break; /* ext */
                        }
                        /*---------------------------------------------------------------
                        |   check for tags for close inner tags
                        \--------------------------------------------------------------*/
                        switch (start[2]) {
                            case 'b': if (!strcmp(start+2,"body")) autoclose = 1; break;
                        }
................................................................................
                        /*----------------------------------------------------
                        |   allocate new COMMENT node for comments
                        \---------------------------------------------------*/
                        tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                        memset(tnode, 0, sizeof(domTextNode));
                        tnode->nodeType      = COMMENT_NODE;
                        tnode->nodeFlags     = 0;

                        tnode->ownerDocument = doc;
                        tnode->nodeNumber    = NODE_NO(doc);
                        tnode->parentNode    = parent_node;
                        tnode->valueLength   = x - start - 4;
                        tnode->nodeValue     = (char*)MALLOC(tnode->valueLength+1);
                        memmove(tnode->nodeValue, start+4, tnode->valueLength);
                        *(tnode->nodeValue + tnode->valueLength) = 0;
................................................................................
                            /*----------------------------------------------------
                            |   allocate new TEXT node for CDATA section data
                            \---------------------------------------------------*/
                            tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                            memset(tnode, 0, sizeof(domTextNode));
                            tnode->nodeType      = TEXT_NODE;
                            tnode->nodeFlags     = 0;

                            tnode->ownerDocument = doc;
                            tnode->nodeNumber    = NODE_NO(doc);
                            tnode->parentNode    = parent_node;
                            tnode->valueLength   = (x - start);
                            tnode->nodeValue     = (char*)MALLOC((x - start)+1);
                            memmove(tnode->nodeValue, start, (x - start));
                            *(tnode->nodeValue + (x - start)) = 0;
................................................................................
                    h = Tcl_CreateHashEntry (doc->ids, attrnode->nodeValue,
                                             &hnew);
                    /* How to resolve in case of dublicates?  We
                       follow, what the core dom building code does:
                       the first value in document order wins. */
                    if (hnew) {
                        Tcl_SetHashValue (h, node);
                        attrnode->nodeFlags |= IS_ID_ATTRIBUTE;
                    }
                }
                if (node->firstAttr) {
                    lastAttr->nextSibling = attrnode;
                } else {
                    node->firstAttr = attrnode;
                }
................................................................................
                }
            }

            /*-----------------------------------------------------------
            |   check for empty HTML tags
            \----------------------------------------------------------*/
            switch (node->nodeName[0]) {
            case 'a':  if (!strcmp(node->nodeName,"area"))     {hasContent = 0;} break;
            case 'b':  if (!strcmp(node->nodeName,"br")     ||
                           !strcmp(node->nodeName,"base")   ||
                           !strcmp(node->nodeName,"basefont")) {hasContent = 0;} break;
            case 'c':  if (!strcmp(node->nodeName,"col"))      {hasContent = 0;} break;
            case 'e':  if (!strcmp(node->nodeName,"embed"))    {hasContent = 0;} break;
            case 'f':  if (!strcmp(node->nodeName,"frame"))    {hasContent = 0;} break;
            case 'h':  if (!strcmp(node->nodeName,"hr"))       {hasContent = 0;} break;
            case 'i':  if (!strcmp(node->nodeName,"img")   ||
                           !strcmp(node->nodeName,"input") ||
                           !strcmp(node->nodeName,"isindex"))  {hasContent = 0;} break;
            case 'l':  if (!strcmp(node->nodeName,"link"))     {hasContent = 0;} break;
            case 'm':  if (!strcmp(node->nodeName,"meta"))     {hasContent = 0;} break;
            case 'p':  if (!strcmp(node->nodeName,"param"))    {hasContent = 0;} break;
            case 's':  if (!strcmp(node->nodeName,"spacer") || 
                           !strcmp(node->nodeName,"source"))   {hasContent = 0;} break; /*html5*/
            }

            if (*x=='/') {
                hasContent = 0;
                x++;
                if (*x!='>') {
                    RetError("Syntax Error",(x - html - 1) );
................................................................................
                    /*----------------------------------------------------
                    |   allocate new TEXT node for style/script data
                    \---------------------------------------------------*/
                    tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                    memset(tnode, 0, sizeof(domTextNode));
                    tnode->nodeType      = TEXT_NODE;
                    tnode->nodeFlags     = 0;

                    tnode->ownerDocument = doc;
                    tnode->nodeNumber    = NODE_NO(doc);
                    tnode->parentNode    = node;
                    tnode->valueLength   = (x - start);
                    tnode->nodeValue     = (char*)MALLOC((x - start)+1);
                    memmove(tnode->nodeValue, start, (x - start));
                    *(tnode->nodeValue + (x - start)) = 0;
................................................................................
        pn = (char*)node->parentNode->nodeName;
        DBG(fprintf(stderr, "final autoclose '%s'? \n", pn);)
        /*---------------------------------------------------------------
        |   check for tags for which end tag can be omitted
        \--------------------------------------------------------------*/
        autoclose = 0;
        switch (pn[0]) {
        case 'b': if (!strcmp(pn,"body"))     {autoclose = 1;} break;
        case 'c': if (!strcmp(pn,"colgroup")) {autoclose = 1;} break;
        case 'd': if (!strcmp(pn,"dd") ||
                      !strcmp(pn,"dt"))       {autoclose = 1;} break;
        case 'h': if (!strcmp(pn,"head") ||
                      !strcmp(pn,"html"))     {autoclose = 1;} break;
        case 'l': if (!strcmp(pn,"li"))       {autoclose = 1;} break;
        case 'o': if (!strcmp(pn,"option"))   {autoclose = 1;} break;
        case 'p': if (!strcmp(pn,"p"))        {autoclose = 1;} break;
        case 't': if (!strcmp(pn,"tbody") ||
                      !strcmp(pn,"td")    ||
                      !strcmp(pn,"tfoot") ||
                      !strcmp(pn,"thead") ||
                      !strcmp(pn,"th")    ||
                      !strcmp(pn,"tr"))       {autoclose = 1;} break;
        case 'u': if (!strcmp(pn,"ul"))       {autoclose = 1;} break; /* ext */
        }
        if (!autoclose) break;
        DBG(fprintf(stderr, "final autoclosed '%s'! \n", pn);)
        node = node->parentNode;
        parent_node = node->parentNode;
    }
    if (parent_node == NULL) {

Added generic/domhtml5.c.













































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
/*----------------------------------------------------------------------------
|   Copyright (c) 2017  Rolf Ade (rolf@pointsman.de)
|-----------------------------------------------------------------------------
|
|
|   The contents of this file are subject to the Mozilla Public License
|   Version 1.1 (the "License"); you may not use this file except in
|   compliance with the License. You may obtain a copy of the License at
|   http://www.mozilla.org/MPL/
|
|   Software distributed under the License is distributed on an "AS IS"
|   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|   License for the specific language governing rights and limitations
|   under the License.
|
|   Contributor(s):
|
|
|   written by Rolf Ade
|   March 2017
|
\---------------------------------------------------------------------------*/

#ifdef TDOM_HAVE_GUMBO

#define MAX_TAG_LEN 201

/*----------------------------------------------------------------------------
|   Includes
|
\---------------------------------------------------------------------------*/
#include <tcl.h>
#include <dom.h>
#include "gumbo.h"
#include <assert.h>

static const char *xhtml = "http://www.w3.org/1999/xhtml";
static const char *svg = "http://www.w3.org/2000/svg";
static const char *mathml = "http://www.w3.org/1998/Math/MathML";
static const char *xlink = "http://www.w3.org/1999/xlink";

#ifdef DEBUG
# define DBG(x) x
#else
# define DBG(x) 
#endif

static void
convertGumboToDom (
    domNode *parent,
    GumboNode *gumboParent,
    int ignoreWhiteSpaces,
    int ignorexmlns
    ) 
{
    int i, j, hnew;
    GumboVector *children = &gumboParent->v.element.children;
    GumboNode *child;
    GumboElement *gumboElm;
    GumboAttribute *gumboAtt;
    const char *tag;
    const char *attValue;
    const char *attUri = NULL;
    char buf[MAX_TAG_LEN];
    domNode *node;
    domNS *ns;
    domNodeType nodeType = ALL_NODES;
    domAttrNode *attr = NULL;
    Tcl_HashEntry *h;
    const char *elmns = NULL;
    
    for (i = 0; i < children->length; ++i) {
        child = (GumboNode*) (children->data[i]);
        switch (child->type) {
        case GUMBO_NODE_DOCUMENT:
            assert(false &&
                   "This gumbo node type can't happen here.");
            break;
        case GUMBO_NODE_ELEMENT:
        case GUMBO_NODE_TEMPLATE:
            gumboElm = &child->v.element;
            tag = gumbo_normalized_tagname(gumboElm->tag);
            if (!domIsNAME(tag)) {
                gumbo_tag_from_original_text(&gumboElm->original_tag);
                if (gumboElm->original_tag.length < MAX_TAG_LEN - 1) {
                    strncpy(&buf[0],
                            gumboElm->original_tag.data,
                            gumboElm->original_tag.length);
                    buf[gumboElm->original_tag.length] = '\0';
                    Tcl_UtfToLower(&buf[0]);
                    if (!domIsNAME(&buf[0])) {
                        DBG(fprintf (stderr, "invalid tag name '%s'\n", tag););
                        continue;
                    }
                    tag = &buf[0];
                } else {
                    /* Just skip this subtree */
                    DBG(fprintf(stderr, "long tag: %d bytes\n", gumboElm->original_tag.length););
                    continue;
                }
            }
            if (!ignorexmlns) {
                switch (gumboElm->tag_namespace) {
                case GUMBO_NAMESPACE_HTML:
                    elmns = xhtml;
                    break;
                case GUMBO_NAMESPACE_SVG:
                    elmns = svg;
                    break;
                case GUMBO_NAMESPACE_MATHML:
                    elmns = mathml;
                    break;
                default:
                    /* do nothing */
                    break;
                }
            }
            if (elmns == NULL) {
                node = domNewElementNode (parent->ownerDocument, tag);
            } else {
                DBG(fprintf (stderr, "namespaced node %s\n", tag););
                node = domNewElementNodeNS (parent->ownerDocument, tag,
                                            elmns);
            }
            domAppendChild(parent, node);
            for (j = 0; j < gumboElm->attributes.length; ++j) {
                gumboAtt = gumboElm->attributes.data[j];
                /* This is to ensure the same behavior as the -html
                 * parser: if there is just the attribute name given
                 * in the source (as 'selected' on a checkbox) then do
                 * it the XHTML style (att value is the att name,
                 * selected="selected"). If there is any value given
                 * in the source, including the empty string, use
                 * that. See gumbo.h for the details why/how this
                 * works.*/
                if (gumboAtt->original_value.data[0] != '"'
                    && gumboAtt->original_value.data[0] != '\'') {
                    attValue = gumboAtt->name;
                } else {
                    attValue = gumboAtt->value;
                }

                if (ignorexmlns) {
                    if (gumboAtt->attr_namespace != GUMBO_ATTR_NAMESPACE_NONE) {
                        if (gumboAtt->original_name.length < MAX_TAG_LEN - 1) {
                            strncpy(&buf[0],
                                    gumboAtt->original_name.data,
                                    gumboAtt->original_name.length);
                            buf[gumboAtt->original_name.length] = '\0';
                            Tcl_UtfToLower(&buf[0]);
                            DBG(fprintf (stderr, "original att name: %s\n",
                                         &buf[0]););
                            if (!domIsNAME(&buf[0])) {
                                DBG(fprintf (stderr, "invalid att name '%s'\n", tag););
                                continue;
                            }
                            domSetAttribute(node, &buf[0], attValue);
                        } else {
                            continue;
                        }
                    } else {
                        attr = domSetAttribute (node, gumboAtt->name, attValue);
                    }
                } else {
                    attUri = NULL;
                    switch (gumboAtt->attr_namespace) {
                    case GUMBO_ATTR_NAMESPACE_XLINK:
                        DBG(fprintf (stderr, "GUMBO_ATTR_NAMESPACE_XLINK\n"););
                        attUri = xlink;
                        break;
                    case GUMBO_ATTR_NAMESPACE_XMLNS:
                        DBG(fprintf (stderr, "GUMBO_ATTR_NAMESPACE_XMLNS\n"););
                        if (attValue[5] == ':') {
                            ns = domLookupPrefix (node, &(attValue[6]));
                        } else {
                            ns = domLookupPrefix (node, "");
                        }
                        DBG(fprintf (stderr, "xmns att name: %s\n att value %s\n",
                                     gumboAtt->name,
                                     attValue););
                        if (ns) {
                            if (strcmp(ns->uri, attValue) == 0) {
                                /* Namespace already in scope. Skip
                                 * this attribute to prevent invalid
                                 * double attributes and unnecessary
                                 * namespace declarations. */
                                DBG(fprintf (stderr, "namespace %s already in scope\n",
                                             attValue););
                                continue;
                            }
                        }
                        if (gumboAtt->original_name.length < MAX_TAG_LEN - 1) {
                            strncpy(&buf[0],
                                    gumboAtt->original_name.data,
                                    gumboAtt->original_name.length);
                            buf[gumboAtt->original_name.length] = '\0';
                            Tcl_UtfToLower(&buf[0]);
                            DBG(fprintf (stderr, "original att name: %s\n",
                                         &buf[0]););
                            if (!domIsNAME(&buf[0])) {
                                DBG(fprintf (stderr, "invalid att name '%s'\n", tag););
                                continue;
                            }
                            domSetAttributeNS(node, &buf[0], attValue, NULL, 1);
                        }
                        continue;
                    case GUMBO_ATTR_NAMESPACE_XML:
                        /* The xml namespace is always in scope, nothing
                         * to do. */
                        continue;
                    default:
                        break;
                    }

                    if (attUri) {
                        if (gumboAtt->original_name.length < MAX_TAG_LEN - 1) {
                            strncpy(&buf[0],
                                    gumboAtt->original_name.data,
                                    gumboAtt->original_name.length);
                            buf[gumboAtt->original_name.length] = '\0';
                            Tcl_UtfToLower(&buf[0]);
                            DBG(fprintf (stderr, "original att name: %s\n",
                                         &buf[0]););
                            if (!domIsNAME(&buf[0])) {
                                DBG(fprintf (stderr, "invalid att name '%s'\n", tag););
                                continue;
                            }
                        } else {
                            continue;
                        }
                        DBG(fprintf (stderr, "name: %s value %s\n", &buf[0], attValue););
                        attr = domSetAttributeNS (node, &buf[0],
                                                  attValue, xlink, 0);
                        DBG(fprintf(stderr, "attr: %p\n", attr););
                    } else {
                        attr = domSetAttribute (node, gumboAtt->name,
                                                attValue);
                    }
                }
                if (attr) {
                    if (strcmp(gumboAtt->name, "id") == 0) {
                        if (!node->ownerDocument->ids) {
                            node->ownerDocument->ids = (Tcl_HashTable *)
                                MALLOC (sizeof (Tcl_HashTable));
                            Tcl_InitHashTable (
                                node->ownerDocument->ids,
                                TCL_STRING_KEYS);
                        }
                        h = Tcl_CreateHashEntry (
                            node->ownerDocument->ids,
                            gumboAtt->value,
                            &hnew);
                        /* How to resolve in case of dublicates?  We
                           follow, what the core dom building code does:
                           the first value in document order wins. */
                        if (hnew) {
                            Tcl_SetHashValue (h, node);
                            attr->nodeFlags |= IS_ID_ATTRIBUTE;
                        }
                    }
                }
            }
            convertGumboToDom(node, child, ignoreWhiteSpaces, ignorexmlns);
            break;
        case GUMBO_NODE_WHITESPACE:
            if (ignoreWhiteSpaces) {
                continue;
            }
            /* fall thru */;
        case GUMBO_NODE_CDATA:
        case GUMBO_NODE_TEXT:
            nodeType = TEXT_NODE
            /* fall thru */;
        case GUMBO_NODE_COMMENT:
            if (nodeType == ALL_NODES) nodeType = COMMENT_NODE;
            node = (domNode*)domNewTextNode(parent->ownerDocument,
                                            child->v.text.text,
                                            strlen(child->v.text.text),
                                            nodeType);
            domAppendChild(parent, node);
            break;
        default:
            assert(false && "unknown node type");
        }
    }
}

domDocument *
HTML_GumboParseDocument (
    char   *html,              /* Complete text of the XML being parsed.  */
    int     ignoreWhiteSpaces,
    int     ignorexmlns
    ) {
    domDocument *doc = domCreateDoc(NULL, 0);
    GumboOutput *output = gumbo_parse(html);
    GumboDocument* doctype = & output->document->v.document;
    /* Generate and populate doctype info. */
    doc->doctype = (domDocInfo *)MALLOC(sizeof(domDocInfo));
    memset(doc->doctype, 0,(sizeof(domDocInfo)));
    doc->doctype->publicId = tdomstrdup(doctype->public_identifier);
    doc->doctype->systemId = tdomstrdup(doctype->system_identifier);
    convertGumboToDom (doc->rootNode, output->document, ignoreWhiteSpaces,
                       ignorexmlns);
    domSetDocumentElement (doc);
    gumbo_destroy_output(&kGumboDefaultOptions, output);    
    return doc;
}
#else
typedef int make_pedantic_compiler_happy;
#endif

Added generic/domhtml5.h.

















>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8

domDocument *
HTML_GumboParseDocument (
    char   *html,              /* Complete text of the XML being parsed.  */
    int     ignoreWhiteSpaces,
    int     ignorexmlns
    );

Added generic/domjson.c.









































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
/*----------------------------------------------------------------------------
|   Copyright (c) 2017  Rolf Ade (rolf@pointsman.de)
|-----------------------------------------------------------------------------
|
|
|   The contents of this file are subject to the Mozilla Public License
|   Version 1.1 (the "License"); you may not use this file except in
|   compliance with the License. You may obtain a copy of the License at
|   http://www.mozilla.org/MPL/
|
|   Software distributed under the License is distributed on an "AS IS"
|   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|   License for the specific language governing rights and limitations
|   under the License.
|
|   Contributor(s):
|
|
|   written by Rolf Ade
|   April 2017
|
\---------------------------------------------------------------------------*/

/* Some parts of the following are inspired, derivated or, for a few
 * smaller pieces, even verbatim copied from the (public domain)
 * sqlite JSON parser
 * (https://www.sqlite.org/src/artifact/312b4ddf4c7399dc) */

#include <dom.h>
#include <domjson.h>
#include <ctype.h>

static const char jsonIsSpace[] = {
  0, 0, 0, 0, 0, 0, 0, 0,     0, 1, 1, 0, 0, 1, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  1, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
};
#define skipspace(x)  while (jsonIsSpace[(unsigned char)json[(x)]]) { (x)++; }

#define rc(i) if (jparse->state != JSON_OK) return (i);

/* The meaning of parse state values */
typedef enum {
    JSON_OK,
    JSON_MAX_NESTING_REACHED,
    JSON_SYNTAX_ERR,
} JSONParseState;

/* Error string constants, indexed by JSONParseState. */
static const char *JSONParseStateStr[] = {
    "OK",
    "Maximum JSON object/array nesting depth exceeded",
    "JSON syntax error",
};

typedef struct {
    JSONParseState state;
    JSONWithin within;
    int  nestingDepth;
    int  maxnesting;
    char *arrItemElm;
    char *buf;
    int len;
} JSONParse;


#define errReturn(i,j) {jparse->state = j; return (i);}
    

/* #define DEBUG */
#ifdef DEBUG
# define DBG(x) x
#else
# define DBG(x) 
#endif

/*
** Return true if z[] begins with 4 (or more) hexadecimal digits
*/
static int jsonIs4Hex(const char *z){
  int i;
  for (i=0; i<4; i++) if (!isxdigit(z[i])) return 0;
  return 1;
}

/* Parse the single JSON string which begins (with the starting '"')
 * at json[i]. Return the index of the closing '"' of the string
 * parsed. */

static int jsonParseString (
    char *json,
    int   i,
    JSONParse *jparse
    )
{
    unsigned char c;
    int clen, j, k, savedStart;
    unsigned int u;
    
    DBG(fprintf(stderr, "jsonParseString start: '%s'\n", &json[i]););
    if (jparse->len) jparse->buf[0] = '\0';
    savedStart = i;

    if (json[i] != '"') {
        errReturn(i,JSON_SYNTAX_ERR);
    }
    i++;
    if (json[i] == '"') {
        return i;
    }
    for(;;) {
        c = json[i];
        DBG(fprintf (stderr, "Looking at '%d'\n", c););
        /* Unescaped control characters are not allowed in JSON
         * strings. */
        if (c <= 0x1f) {
            errReturn(i,JSON_SYNTAX_ERR);
        }
        if (c == '\\') {
            goto unescape;
        }
        if (c == '"') {
            return i;
        }
        if (c == 0xC0 && (unsigned char)json[i+1] == 0x80)
            errReturn(i,JSON_SYNTAX_ERR);
        if ((clen = UTF8_CHAR_LEN(c)) == 0)
            errReturn(i,JSON_SYNTAX_ERR);
        i += clen;
    }
    unescape:
    DBG(fprintf (stderr, "Continue with unescaping ..\n"););
    /* If we here, then i points to the first backslash in the string
     * to parse */
    if (i - savedStart > jparse->len - 200) {
        jparse->buf = REALLOC(jparse->buf, i-savedStart+200);
        jparse->len = i-savedStart+200;
    }
    memcpy (jparse->buf, &json[savedStart+1], i-savedStart);
    j = i-savedStart-1;
    for(;;) {
        c = json[i];
        DBG(fprintf (stderr, "Looking at '%c'\n", c););
        /* Unescaped control characters are not allowed in JSON
         * strings. */
        if (c <= 0x1f) errReturn(i,JSON_SYNTAX_ERR);
        if (jparse->len - j < 8) {
            jparse->buf = REALLOC (jparse->buf, jparse->len * 2);
            jparse->len *= 2;
        }
        if (c == '\\') {
            c = json[i+1];
            if (c == 'u' && jsonIs4Hex(&json[i+2])) {
                u = 0;
                for (k = 2; k < 6; k++) {
                    c = json[i+k];
                    if (c <= '9') u = u*16 + c - '0';
                    else if (c <= 'F') u = u*16 + c - 'A' + 10;
                    else u = u*16 + c - 'a' + 10;
                }
                if (u <= 0x7f) {
                    if (u == 0) {
                        jparse->buf[j++] = (char)0xC0;
                        jparse->buf[j++] = (char)0x80;
                        clen = 2;
                    } else {
                        jparse->buf[j++] = (char)u;
                        clen = 1;
                    }
                } else if (u <= 0x7ff) {
                    jparse->buf[j++] = (char)(0xc0 | (u>>6));
                    jparse->buf[j++] = 0x80 | (u&0x3f);
                    clen = 2;
                } else {
                    jparse->buf[j++] = (char)(0xe0 | (u>>12));
                    jparse->buf[j++] = 0x80 | ((u>>6)&0x3f);
                    jparse->buf[j++] = 0x80 | (u&0x3f);
                    clen = 3;
                }
                i += 6;
            } else {
                if (c == '\\') {
                    c = '\\';
                } else if (c == '"') {
                    c = '"';
                } else if (c == '/') {
                    c = '/';
                } else if (c == 'b') {
                    c = '\b';
                } else if (c == 'f') {
                    c = '\f';
                } else if (c == 'n') {
                    c = '\n';
                } else if (c == 'r') {
                    c = '\r';
                } else if (c == 't') {
                    c = '\t';
                } else {
                    errReturn(i+1,JSON_SYNTAX_ERR);
                }
                jparse->buf[j++] = c;
                i += 2;
            }
            continue;
        }
        if (c == '"') {
            jparse->buf[j] = '\0';
            return i;
        }
        if ((clen = UTF8_CHAR_LEN(json[i])) == 0)
            errReturn(i,JSON_SYNTAX_ERR);
        for (k = 0; k < clen; k++) {
            jparse->buf[j++] = json[i+k];
        }
        i += clen;
    }
}

/* Parse a single JSON value which begins at json[i]. Return the index
 * of the first character past the end of the value parsed. */

static int jsonParseValue(
    domNode   *parent,
    char      *json,
    int        i,
    JSONParse *jparse
    )
{
    char c, save;
    int j;
    domNode *node;
    domTextNode *newTextNode;
    JSONWithin savedWithin = jparse->within;
    
    DBG(fprintf(stderr, "jsonParseValue start: '%s'\n", &json[i]););
    if (jparse->len) jparse->buf[0] = 0;
    skipspace(i);
    if ((c = json[i]) == '{' ) {
        /* Parse object */
        if (++jparse->nestingDepth > jparse->maxnesting)
            errReturn(i,JSON_MAX_NESTING_REACHED);
        i++;
        if (jparse->within == JSON_ARRAY) {
            node = domNewElementNode (parent->ownerDocument,
                                      JSON_OBJECT_CONTAINER);
            node->info = JSON_OBJECT;
            domAppendChild(parent, node);
            parent = node;
        } else {
            parent->info  = JSON_OBJECT;
        }
        skipspace(i);
        if (json[i] == '}') {
            /* Empty object. */
            jparse->nestingDepth--;
            return i+1;
        }
        jparse->within = JSON_WITHIN_OBJECT;
        for (;;) {
            j = jsonParseString (json, i, jparse);
            rc(j);
            if (jparse->len && jparse->buf[0]) {
                DBG(fprintf(stderr, "New object member '%s'\n", jparse->buf););
                node = domNewElementNode (parent->ownerDocument,
                                          jparse->buf);
                domAppendChild (parent, node);
                jparse->buf[0] = 0;
            } else {
                save = json[j];
                json[j] = '\0';
                DBG(fprintf(stderr, "New object member '%s'\n", jparse->buf););
                DBG(fprintf(stderr, "New object member '%s'\n", &json[i+1]););
                node = domNewElementNode (parent->ownerDocument, &json[i+1]);
                domAppendChild (parent, node);
                json[j] = save;
            }
            i = j+1;
            skipspace(i);
            if (json[i] != ':') errReturn(i,JSON_SYNTAX_ERR);
            i++;
            skipspace(i);
            j = jsonParseValue (node, json, i, jparse);
            rc(j);
            i = j;
            skipspace(i);
            if (json[i] == '}') {
                jparse->nestingDepth--;
                jparse->within = savedWithin;
                return i+1;
            }
            if (json[i] == ',') {
                i++; skipspace(i);
                continue;
            }
            errReturn(i,JSON_SYNTAX_ERR);
        }
    } else if (c == '[') {
        /* Parse array */
        if (++jparse->nestingDepth > jparse->maxnesting)
            errReturn(i,JSON_MAX_NESTING_REACHED);
        i++;
        skipspace(i);
        parent->info = JSON_ARRAY;
        if (jparse->within == JSON_WITHIN_ARRAY) {
            node = domNewElementNode (parent->ownerDocument,
                                      JSON_ARRAY_CONTAINER);
            node->info = JSON_ARRAY;
            domAppendChild(parent, node);
        } else {
            node = parent;
        }
        if (json[i] == ']') {
            /* empty array */
            DBG(fprintf(stderr,"Empty JSON array.\n"););
            jparse->nestingDepth--;
            return i+1;
        }
        jparse->within = JSON_WITHIN_ARRAY;
        for (;;) {
            DBG(fprintf(stderr, "Next array value node '%s'\n", &json[i]););
            skipspace(i);
            i = jsonParseValue (node, json, i, jparse);
            rc(i);
            skipspace(i);
            if (json[i] == ']') {
                jparse->within = savedWithin;
                jparse->nestingDepth--;
                return i+1;
            }
            if (json[i] == ',') {
                i++;
                continue;
            }
            errReturn(i,JSON_SYNTAX_ERR);
        }
    } else if (c == '"') {
        /* Parse string */
        j = jsonParseString (json, i, jparse);
        rc(j);
        if (jparse->len && jparse->buf[0]) {
            DBG(fprintf(stderr, "New unescaped text node '%s'\n", jparse->buf));
            newTextNode = domNewTextNode (parent->ownerDocument,
                                          jparse->buf, strlen(jparse->buf),
                                          TEXT_NODE);
            domAppendChild (parent, (domNode *) newTextNode);
        } else {
            DBG(save = json[j];json[j] = '\0';fprintf(stderr, "New text node '%s'\n", &json[i+1]);json[j] = save;);
            newTextNode = domNewTextNode (parent->ownerDocument,
                                          &json[i+1], j-i-1, TEXT_NODE);
            domAppendChild (parent, (domNode *) newTextNode);
        }
        newTextNode->info = JSON_STRING;
        return j+1;
    } else if (c == 'n'
               && strncmp (json+i, "null", 4) == 0
               && !isalnum(json[i+4])) {
        newTextNode = domNewTextNode (parent->ownerDocument, "null", 4,
                                      TEXT_NODE);
        newTextNode->info = JSON_NULL;
        domAppendChild (parent, (domNode *) newTextNode);
        return i+4;
    } else if (c == 't'
               && strncmp (json+i, "true", 4) == 0
               && !isalnum(json[i+4])) {
        newTextNode = domNewTextNode (parent->ownerDocument, "true", 4,
                                      TEXT_NODE);
        newTextNode->info = JSON_TRUE;
        domAppendChild (parent, (domNode *) newTextNode);
        return i+4;
    } else if (c == 'f'
               && strncmp (json+i, "false", 5) == 0
               && !isalnum(json[i+5])) {
        newTextNode = domNewTextNode (parent->ownerDocument, "false", 5,
                                      TEXT_NODE);
        newTextNode->info = JSON_FALSE;
        domAppendChild (parent, (domNode *) newTextNode);
        return i+5;
    } else if (c == '-' || (c>='0' && c<='9')) {
        /* Parse number */
        int seenDP = 0;
        int seenE = 0;
        if (c<='0') {
            j = (c == '-' ? i+1 : i);
            if (json[j] == '0' && json[j+1] >= '0' && json[j+1] <= '9')
                errReturn(j+1,JSON_SYNTAX_ERR);
        }
        j = i+1;
        for (;; j++) {
            c = json[j];
            if (c >= '0' && c <= '9') continue;
            if (c == '.') {
                if (json[j-1] == '-') errReturn(j,JSON_SYNTAX_ERR);
                if (seenDP) errReturn(j,JSON_SYNTAX_ERR);
                seenDP = 1;
                continue;
            }
            if (c == 'e' || c == 'E') {
                if (json[j-1] < '0') errReturn(j,JSON_SYNTAX_ERR);
                if (seenE) errReturn(j,JSON_SYNTAX_ERR);
                seenDP = seenE = 1;
                c = json[j+1];
                if (c == '+' || c == '-') {
                    j++;
                    c = json[j+1];
                }
                if (c < '0' || c > '9') errReturn(j,JSON_SYNTAX_ERR);
                continue;
            }
            break;
        }
        /* Catches a plain '-' without following digits */
        if( json[j-1]<'0' ) errReturn(j-1,JSON_SYNTAX_ERR);
        DBG(save = json[j];json[j] = '\0';fprintf(stderr, "New text node '%s'\n", &json[i]);json[j] = save;);
        newTextNode = domNewTextNode (parent->ownerDocument, &json[i], j-i,
                                      TEXT_NODE);
        newTextNode->info = JSON_NUMBER;
        domAppendChild(parent, (domNode *) newTextNode);
        return j;
    } else if (c == '\0') {
        return 0;   /* End of input */
    } else {
        errReturn(i,JSON_SYNTAX_ERR);
    }
}


domDocument *
JSON_Parse (
    char *json,    /* Complete text of the json string being parsed */
    char *documentElement, /* name of the root element, may be NULL */
    int   maxnesting,
    char **errStr,
    int  *byteIndex
    )
{
    domDocument *doc = domCreateDoc (NULL, 0);
    domNode *root;
    Tcl_HashEntry *h;
    JSONParse jparse;
    int hnew, pos = 0;

    h = Tcl_CreateHashEntry(&HASHTAB(doc, tdom_tagNames), "item", &hnew);
    jparse.state = JSON_OK;
    jparse.within = JSON_START;
    jparse.nestingDepth = 0;
    jparse.maxnesting = maxnesting;
    jparse.arrItemElm = (char*)&h->key;
    jparse.buf = NULL;
    jparse.len = 0;

    skipspace(pos);
    if (json[pos] == '\0') {
        *byteIndex = pos;
        jparse.state = JSON_SYNTAX_ERR;
        goto reportError;
    }
    if (documentElement) {
        root = domNewElementNode(doc, documentElement);
        domAppendChild(doc->rootNode, root);
    } else {
        root = doc->rootNode;
    }
    *byteIndex = jsonParseValue (root, json, pos, &jparse );
    if (jparse.state != JSON_OK) goto reportError;
    if (*byteIndex > 0) {
        pos = *byteIndex;
        skipspace(pos);
    }
    if (json[pos] != '\0') {
        *byteIndex = pos;
        jparse.state = JSON_SYNTAX_ERR;
        goto reportError;
    }
    if (jparse.len > 0) {
        FREE (jparse.buf);
    }
    domSetDocumentElement (doc);
    return doc;
reportError:
    if (jparse.len > 0) {
        FREE (jparse.buf);
    }
    domFreeDocument (doc, NULL, NULL);
    doc = NULL;
    *errStr = (char *)JSONParseStateStr[jparse.state];
    return doc;
}

Added generic/domjson.h.











































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

#ifndef JSON_MAX_NESTING
# define JSON_MAX_NESTING 2000
#endif

#ifndef JSON_OBJECT_CONTAINER
# define JSON_OBJECT_CONTAINER "objectcontainer"
#endif

#ifndef JSON_ARRAY_CONTAINER
# define JSON_ARRAY_CONTAINER "arraycontainer"
#endif

typedef enum {
    JSON_START,
    JSON_WITHIN_ARRAY,
    JSON_WITHIN_OBJECT
} JSONWithin;

#define JSON_ARRAY 1
#define JSON_OBJECT 2
#define JSON_NULL 3
#define JSON_TRUE 4
#define JSON_FALSE 5
#define JSON_STRING 6
#define JSON_NUMBER 7


domDocument *
JSON_Parse (
    char *json,    /* Complete text of the json string being parsed */
    char *documentElement, /* name of the root element, may be NULL */
    int   maxnesting,
    char **errStr,
    int  *byteIndex
    );

Changes to generic/domxpath.c.

65
66
67
68
69
70
71

72
73
74
75
76
77
78
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
...
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
...
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
...
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
...
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
...
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
...
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
...
890
891
892
893
894
895
896
























897
898
899
900
901
902
903
....
1075
1076
1077
1078
1079
1080
1081



1082



1083
1084
1085
1086
1087
1088
1089
....
1151
1152
1153
1154
1155
1156
1157

1158
1159
1160
1161
1162
1163
1164
....
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
....
1335
1336
1337
1338
1339
1340
1341

1342
1343
1344
1345
1346
1347
1348
....
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
....
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
....
1590
1591
1592
1593
1594
1595
1596

1597
1598
1599
1600
1601
1602
1603
1604
1605
1606

1607
1608
1609
1610
1611
1612
1613
1614

1615
1616
1617
1618

1619
1620
1621
1622
1623
1624
1625
....
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
....
1668
1669
1670
1671
1672
1673
1674

1675
1676
1677
1678
1679
1680
1681
....
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
....
1794
1795
1796
1797
1798
1799
1800

1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812

1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824

1825
1826
1827
1828
1829
1830
1831
1832

1833
1834
1835
1836
1837
1838
1839
....
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
....
1907
1908
1909
1910
1911
1912
1913
1914

1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
....
2141
2142
2143
2144
2145
2146
2147
2148


2149
2150
2151
2152
2153
2154
2155
....
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
....
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
....
2326
2327
2328
2329
2330
2331
2332
2333

2334



2335
2336
2337
2338
2339
2340
2341
....
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425

2426
2427
2428


2429

















2430
2431

2432
2433
2434

2435
2436
2437
2438

2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453







2454

2455


2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
....
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540

2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
....
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
....
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
....
2848
2849
2850
2851
2852
2853
2854

2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
....
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
....
3055
3056
3057
3058
3059
3060
3061



3062


3063
3064
3065
3066
3067
3068
3069
....
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
....
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
....
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
....
3191
3192
3193
3194
3195
3196
3197



3198

3199
3200
3201
3202
3203
3204
3205
....
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
....
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
....
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
....
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
....
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
....
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
....
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
....
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
....
4119
4120
4121
4122
4123
4124
4125
4126
4127

4128
4129
4130
4131
4132

4133
4134
4135
4136
4137
4138

4139
4140
4141
4142
4143
4144
4145
....
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
....
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
....
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
....
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
....
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
....
4701
4702
4703
4704
4705
4706
4707
4708


4709
4710
4711
4712
4713
4714
4715
....
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828

4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839


4840
4841
4842


4843
4844
4845
4846
4847
4848
4849
....
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
....
4882
4883
4884
4885
4886
4887
4888
4889


4890
4891
4892
4893
4894
4895
4896
....
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
....
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249






5250
5251
5252
5253
5254
5255
5256
....
5323
5324
5325
5326
5327
5328
5329
5330

5331
5332
5333
5334
5335
5336
5337
....
5367
5368
5369
5370
5371
5372
5373
5374

5375
5376
5377
5378
5379
5380
5381
....
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
....
5777
5778
5779
5780
5781
5782
5783
5784

5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805

5806
















5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817

5818
5819
5820
5821
5822
5823
5824
....
5860
5861
5862
5863
5864
5865
5866
5867

5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include <math.h>
#include <limits.h>
#include <ctype.h>

#include <dom.h>
#include <domxpath.h>
#include <domxslt.h>


/*----------------------------------------------------------------------------
|   Macros
................................................................................
};


typedef struct {

    Token  token;
    char  *strvalue;
    int    intvalue;
    double realvalue;
    int    pos;

} XPathToken;

typedef XPathToken *XPathTokens;

................................................................................
|   Types for abstract syntax trees
|
\---------------------------------------------------------------------------*/
static char *astType2str[] = {
    "Int", "Real", "Mult", "Div", "Mod", "UnaryMinus", "IsNSElement",
    "IsNode", "IsComment", "IsText", "IsPI", "IsSpecificPI", "IsElement",
    "IsFQElement", "GetVar", "GetFQVar", "Literal", "ExecFunction", "Pred",
    "EvalSteps", "SelectRoot", "CombineSets", "Add", "Substract", "Less",
    "LessOrEq", "Greater", "GreaterOrEq", "Equal", "NotEqual", "And", "Or",
    "IsNSAttr", "IsAttr", "AxisAncestor", "AxisAncestorOrSelf",
    "AxisAttribute", "AxisChild",
    "AxisDescendant", "AxisDescendantOrSelf", "AxisFollowing",
    "AxisFollowingSibling", "AxisNamespace", "AxisParent",
    "AxisPreceding", "AxisPrecedingSilbing", "AxisSelf",
    "GetContextNode", "GetParentNode", "AxisDescendantOrSelfLit",
................................................................................

static int xpathEvalPredicate (ast steps, domNode *exprContext, 
                               xpathResultSet *result, 
                               xpathResultSet *stepResult,
                               xpathCBs *cbs, int *docOrder, char **errMsg);

/*----------------------------------------------------------------------------
|   xpath result set functions
|
\---------------------------------------------------------------------------*/

void xpathRSFree ( xpathResultSet *rs ) {

    if (rs->type == xNodeSetResult) {
        if (!rs->intvalue) {
................................................................................
    int i = 0,l;  char tmp[80];
    switch (rs->type) {
        case EmptyResult:
             fprintf(stderr, "empty result \n");
             break;

        case BoolResult:
             fprintf(stderr, "boolean result: %d \n", rs->intvalue);
             break;

        case IntResult:
             fprintf(stderr, "int result: %d \n", rs->intvalue);
             break;

        case RealResult:
             fprintf(stderr, "real result: %f \n", rs->realvalue);
             break;

        case StringResult:
................................................................................
             break;

        case xNodeSetResult:
             if (!i) fprintf(stderr,"nodeSet result (len %d):\n",rs->nr_nodes);
             for (i=0; i<rs->nr_nodes; i++) {
                 if (rs->nodes[i]->nodeType == ELEMENT_NODE) {
                     fprintf(stderr, "%2d domNode%p %s ",
                             i, rs->nodes[i], rs->nodes[i]->nodeName);
                     if (rs->nodes[i]->firstChild &&
                         rs->nodes[i]->firstChild->nodeType == TEXT_NODE)
                     {
                         l = ((domTextNode*)rs->nodes[i]->firstChild)->valueLength;
                         if (l > 25) l = 25;
                         memcpy(tmp, ((domTextNode*)rs->nodes[i]->firstChild)->nodeValue, l);
                         tmp[l] = '\0';
................................................................................
                 } else
                 if (rs->nodes[i]->nodeType == TEXT_NODE) {
                     l = ((domTextNode*)rs->nodes[i])->valueLength;
                     if (l > 60) l = 60;
                     memcpy(tmp, ((domTextNode*)rs->nodes[i])->nodeValue, l);
                     tmp[l] = '\0';
                     fprintf(stderr, "%2d domNode%p text:'%s' \n",
                             i, rs->nodes[i], tmp);
                 } else
                 if (rs->nodes[i]->nodeType == COMMENT_NODE) {
                     l = ((domTextNode*)rs->nodes[i])->valueLength;
                     memcpy (tmp, "<!--", 4);
                     if (l > 60) l = 60;
                     memcpy(&tmp[4], ((domTextNode*)rs->nodes[i])->nodeValue, l);
                     memcpy(&tmp[4+l], "-->", 3);
                     tmp[7+l] = '\0';
                     fprintf(stderr, "%2d domNode%p text:'%s' \n",
                             i, rs->nodes[i], tmp);
                 } else
                 if (rs->nodes[i]->nodeType == ATTRIBUTE_NODE) {
                     fprintf(stderr, "%2d Attr %s='%*s'\n", i,
                             ((domAttrNode*)rs->nodes[i])->nodeName,
                             ((domAttrNode*)rs->nodes[i])->valueLength,
                             ((domAttrNode*)rs->nodes[i])->nodeValue);
                 }
................................................................................
}
void rsSetInf ( xpathResultSet *rs ) {
    rs->type = InfResult;
}
void rsSetNInf ( xpathResultSet *rs ) {
    rs->type = NInfResult;
}
void rsSetInt ( xpathResultSet *rs, int i) {

    rs->type = IntResult;
    rs->intvalue = i;
}
void rsSetBool ( xpathResultSet *rs, int i) {

    rs->type = BoolResult;
    rs->intvalue = (i ? 1 : 0);
}
void rsSetString ( xpathResultSet *rs, const char *s) {

    rs->type = StringResult;
................................................................................
        t->child->next = New1(EvalSteps, b);
    } else {
        t->child->next = b;
    }
    return t;
}

static ast NewInt( int i ) {
    ast t = NEWCONS;

    t->type      = Int;
    t->strvalue  = NULL;
    t->intvalue  = i;
    t->realvalue = 0.0;

................................................................................
    }
    /*child->next = NULL;*/
    return m;
}
static void freeAst (ast t)
{
    ast tmp;

    while (t) {
        tmp = t->next;
        if (t->strvalue) FREE(t->strvalue);
        if (t->child) freeAst (t->child);
        FREE((char*)t);
        t = tmp;
    }
................................................................................
    int i;

    while (t) {
        for (i=0; i<depth; i++) fprintf(stderr, "   ");
        fprintf(stderr, "%s ", astType2str[t->type]);
        switch (t->type) {

            case Int :        fprintf(stderr, "%d", t->intvalue);   break;
            case Real:        fprintf(stderr, "%f", t->realvalue);  break;
            case IsElement:
            case IsFQElement:
            case IsNSAttr:
            case IsAttr:
            case ExecFunction:
            case Literal:
................................................................................
                           } else {
                               *errMsg = tdomstrdup("Expected variable name");
                               return tokens;
                           }
                       }
                       break;

























            case '.':  if (xpath[i+1] == '.') {
                           token = DOTDOT;
                           i++;
                           break;
                       } else if (!isdigit((unsigned char)xpath[i+1])) {
                           token = DOT;
                           break;
................................................................................
                               i++;
                               while (xpath[i] 
                                      && isdigit((unsigned char)xpath[i])) i++;
                           }
                           save = xpath[i];
                           xpath[i] = '\0';
                           if (token == INTNUMBER) {



                               tokens[l].intvalue = atoi(ps);



                           }
                           tokens[l].realvalue = (double)atof(ps);
                           xpath[i--] = save;
                       } else {
                           sprintf (tmpErr, "Unexpected character '%c' at "
                                    "position %d", xpath[i], i);
                           *errMsg = tdomstrdup (tmpErr);
................................................................................
    } else
    if (LA==NSWC) {
        Consume (NSWC);
        a = NewStr (IsNSElement, STRVAL);
    } else {
        Consume(WCARDNAME);
        a = NewStr (IsElement, STRVAL);

    }
EndProduction


/*-----------------------------------------------------------------
|   AbbreviatedBasis  production
|
................................................................................
        Consume(RPAR);
    } else {
        ErrExpected("$var or (expr) or literal or number or func");
    }
    while (LA==LBRACKET) {
        ast b;
        b = Recurse(Predicate);
        if (!b) return NULL;
        Append( a, New1WithEvalSteps( Pred, b));
    }
EndProduction


/*-----------------------------------------------------------------
|   PathExpr  production
................................................................................
            Consume(SLASH);
            Append(a, Recurse(RelativeLocationPath));

        } else if (LA==SLASHSLASH) {
            ast b;
            Consume(SLASHSLASH);
            b = Recurse(RelativeLocationPath);

            if (b->type == AxisChild) {
                b->type = AxisDescendant;
            } else {
                Append(a, New( AxisDescendantOrSelf ) );
            }
            Append(a, b );
        }
................................................................................
          ||(LA==MINUS)
    ) {
        if (LA==PLUS) {
            Consume(PLUS);
            a = New2( Add, a, Recurse(MultiplicativeExpr));
        } else {
            Consume(MINUS);
            a = New2( Substract, a, Recurse(MultiplicativeExpr));
        }
    }
EndProduction


/*-----------------------------------------------------------------
|   RelationalExpr  production
................................................................................
EndProduction


/*-----------------------------------------------------------------
|   Step  production
|
\----------------------------------------------------------------*/
static int IsStepPredOptimizable (ast a) {
    ast b;
    int left;
    
    /* Must be called with a != NULL */
    DBG (
        fprintf (stderr, "IsStepPredOptimizable:\n");
        printAst (0,a);
    )
    switch (a->type) {
................................................................................
    case Less:
    case LessOrEq:
        b = a->child;
        if (!b) return 0;
        if (b->type != ExecFunction 
            || b->intvalue != f_position) return 0;
        b = b->next;

        if (b->type != Int) return 0;
        if (a->type == Less) return b->intvalue;
        else                 return b->intvalue + 1;
    case Greater:
    case GreaterOrEq:
        b = a->child;
        if (!b) return 0;
        if (b->type != Int) return 0;
        left = b->intvalue;
        b = b->next;

        if (b->type != ExecFunction 
            || b->intvalue != f_position) return 0;
        if (a->type == Greater) return left;
        else                    return left + 1;
    case Equal:
        b = a->child;
        if (!b) return 0;
        if (b->type == Int

            && b->next->type == ExecFunction
            && b->next->intvalue == f_position) return b->intvalue;
        if (b->type == ExecFunction
            && b->intvalue == f_position

            && b->next->type == Int) return b->next->intvalue;
        return 0;
    default: return 0;
    }
}

Production(Step)
................................................................................
        a = Recurse(Basis);
        if (LA==LBRACKET && !a) {
            if (*errMsg == NULL) { ErrExpected("Step"); }
            return NULL;
        }
        while (LA==LBRACKET) {
            b = Recurse (Predicate);
            if (!b) return NULL;
            if (isFirst) {
                a->intvalue = IsStepPredOptimizable (b);
                DBG (fprintf (stderr, "step type %s, intvalue: %d\n", astType2str[a->type], a->intvalue);)
                    isFirst = 0;
            }
            Append( a, New1WithEvalSteps( Pred, b));
        }
................................................................................
        if (LA==SLASH) {
            Consume(SLASH);
            Append(a, Recurse(Step));
        } else {
            ast b;
            Consume(SLASHSLASH);
            b = Recurse(Step);

            if (b->type == AxisChild) {
                b->type = AxisDescendant;
            } else {
                Append(a, New( AxisDescendantOrSelf ) );
            }
            Append(a, b );
        }
................................................................................
        }
        a = a->next;
    }
    return 0;
}

/* Must be called with a != NULL */
static int checkStepPatternPredOptimizability ( ast a , int *max) {
    ast b;

    switch (a->type) {
        case Literal:
        case AxisAncestor:
        case AxisAncestorOrSelf:
        case AxisChild:
................................................................................
            return 1;
        case Less:
        case LessOrEq:
            b = a->child;
            if (b
                && b->type == ExecFunction
                && b->intvalue == f_position

                && b->next->type == Int) {
                if (a->type == Less) *max = b->next->intvalue;
                else *max = b->next->intvalue + 1;
                return 0;
            }
            if (usesPositionInformation(a->child)) return 0;
            return 1;            
        case Greater:
        case GreaterOrEq:
            b = a->child;
            if (b
                && b->type == Int 

                && b->next->type == ExecFunction
                && b->next->intvalue == f_position) {
                if (a->type == Greater) *max = b->intvalue;
                else *max = b->intvalue + 1;
                return 0;
            }
            if (usesPositionInformation(a->child)) return 0;
            return 1;            
        case Equal:
            b = a->child;
            if (b
                && b->type == Int

                && b->next->type == ExecFunction
                && b->next->intvalue == f_position) {
                *max = b->intvalue;
                return 0;
            }
            if (b
                && b->type == ExecFunction 
                && b->intvalue == f_position

                && b->next->type == Int) {
                *max = b->next->intvalue;
                return 0;
            }
            if (usesPositionInformation(a->child)) return 0;
            return 1;
        case NotEqual:
................................................................................
        default: 
            return 0;
    }
    return 1;
}

/* Must be called with a != NULL */
static int IsStepPatternPredOptimizable ( ast a, int *max ) {
    int f;

    *max = 0;
    f = checkStepPatternPredOptimizability(a, max);
    DBG(
        if (f) {
            fprintf(stderr, "\nStepPattern Pred is optimizable:\n");
        } else {
................................................................................
    }
    if (!a) {
        if (*errMsg == NULL) { ErrExpected("StepPattern") }; 
        return NULL;
    }
    {
        ast b = NULL, c = NULL, aCopy = NULL;
        int stepIsOptimizable = 1, isFirst = 1, max, savedmax;

        while (LA==LBRACKET) {
            b = Recurse (Predicate);
            if (!b) return NULL;
            if (stepIsOptimizable) {
                if (!IsStepPatternPredOptimizable(b, &max)) 
                    stepIsOptimizable = 0;
            }
            if (isFirst) {
                savedmax = max;
                c = New1WithEvalSteps( Pred, b);
................................................................................
    DBG(
        fprintf(stderr, "xpathParsePostProcess start:\n");
        printAst (0, t);
        )
    while (t) {
        DBG(printAst (4, t);)
        if (t->type == AxisNamespace) {
            if (t->child->type == IsElement && t->child->strvalue[0] != '*') {


                uri = domLookupPrefixWithMappings (exprContext, 
                                                   t->child->strvalue, 
                                                   prefixMappings);
                if (!uri) {
                    *errMsg = tdomstrdup ("Prefix doesn't resolve");
                    return 0;
                }
................................................................................
                        varParseCB, errMsg);
    if (*errMsg != NULL) {
        if (tokens != NULL) xpathFreeTokens (tokens);
        return XPATH_LEX_ERR;
    }
    DDBG(
        for (i=0; tokens[i].token != EOS; i++) {
            fprintf(stderr, "%3d %-12s %5d %8.3f %5d  %s\n",
                            i,
                            token2str[tokens[i].token-LPAR],
                            tokens[i].intvalue,
                            tokens[i].realvalue,
                            tokens[i].pos,
                            tokens[i].strvalue
            );
................................................................................
        newlen = strlen(xpath);
        *errMsg = (char*)REALLOC(*errMsg, len+newlen+10);
        memmove(*errMsg + len, " for '", 6);
        memmove(*errMsg + len+6, xpath, newlen);
        memmove(*errMsg + len+6+newlen, "' ", 3);

        for (i=0; tokens[i].token != EOS; i++) {
            sprintf(tmp, "%s\n%3s%3d %-12s %5d %8.3f %5d  ",
                         (i==0) ? "\n\nParsed symbols:" : "",
                         (i==l) ? "-->" : "   ",
                          i,
                         token2str[tokens[i].token-LPAR],
                         tokens[i].intvalue,
                         tokens[i].realvalue,
                         tokens[i].pos
................................................................................
    const char *localName, *nodeUri;

    if (!(step->child)) return 1;
    if (step->child->type == IsElement) {
        if (node->nodeType == ELEMENT_NODE) {
            if ((step->child->strvalue[0] == '*') &&
                (step->child->strvalue[1] == '\0') &&
                (node->ownerDocument->rootNode != node)) return 1;

            if (node->namespace) return 0;



            return (strcmp(node->nodeName, step->child->strvalue)==0);
        }
        return 0;
    } else
    if (step->child->type == IsAttr) {
        if (node->nodeType == ATTRIBUTE_NODE) {
            if (node->nodeFlags & IS_NS_NODE) return 0;
................................................................................
|
\---------------------------------------------------------------------------*/
int xpathFuncBoolean (
    xpathResultSet  *rs
)
{
    switch (rs->type) {
        case BoolResult:         return ( rs->intvalue         );
        case IntResult:          return ( rs->intvalue ? 1 : 0 );
        case RealResult:         return ((rs->realvalue != 0.0 ) && !IS_NAN (rs->realvalue));
        case StringResult:       return ( rs->string_len > 0   );
        case xNodeSetResult:     return ( rs->nr_nodes > 0     );
        case InfResult:
        case NInfResult:         return 1;
        /* NaNResult and EmptyResult are 'false' */
        default:                 return 0;
    }
}

static int
xpathIsNumber (
    char *str

    )
{
    int dotseen = 0;


    

















    while (*str && IS_XML_WHITESPACE(*str)) str++;
    if (!*str) return 0;

    if (*str == '-') {
        str++;
        if (!*str) return 0;

    } else if (*str == '.') {
        dotseen = 1;
        str++;
        if (!*str) return 0;

    }
    if (!isdigit((unsigned char)*str)) return 0;
    while (*str) {
        if (isdigit((unsigned char)*str)) {
            str++;
            continue;
        }
        if (*str == '.' && !dotseen) {
            dotseen = 1;
            str++;
            continue;
        }
        break;
    }
    while (*str && IS_XML_WHITESPACE(*str)) str++;







    if (*str) return 0;

    else return 1;


}

/*----------------------------------------------------------------------------
|   xpathFuncNumber
|
\---------------------------------------------------------------------------*/
double xpathFuncNumber (
    xpathResultSet  *rs,
    int             *NaN
)
{
    double d;
    char   tmp[80], *pc, *tailptr;

    *NaN = 0;
    switch (rs->type) {
        case BoolResult:   return (rs->intvalue? 1.0 : 0.0);
        case IntResult:    return rs->intvalue;
        case RealResult:   
            if (IS_NAN(rs->realvalue)) *NaN = 2;
................................................................................
            return -DBL_MAX;
#   else
            /* well, what? */
            return 0.0
#   endif
#endif
        case StringResult:
              if (!xpathIsNumber (rs->string)) {
                  d = strtod ("nan", &tailptr);
                  *NaN = 2;
                  return d;
              }
              strncpy(tmp, rs->string, (rs->string_len<79) ? rs->string_len : 79);
              tmp[(rs->string_len<79) ? rs->string_len : 79] = '\0';
              d = strtod (tmp, &tailptr);
              if (d == 0.0 && tailptr == tmp) {
                  d = strtod ("nan", &tailptr);
                  *NaN = 2;
              } else
              if (IS_NAN(d)) {
                  *NaN = 2;
              } else
              if (tailptr) {
                  while (*tailptr) {
                      switch (*tailptr) {
                      case ' ' :
                      case '\n':
                      case '\r':
                      case '\t': tailptr++; continue;
                      default: break; /*do nothing */
                      }
                      d = strtod ("nan", &tailptr);
                      *NaN = 2;
                      break;
                  }
              }
              return d;
        case xNodeSetResult:
              pc = xpathFuncString(rs);
              if (!xpathIsNumber (pc)) {
                  d = strtod ("nan", &tailptr);
                  *NaN = 2;

                  FREE(pc);
                  return d;
              }
              d = strtod (pc, &tailptr);
              if (d == 0.0 && tailptr == pc) {
                  d = strtod ("nan", &tailptr);
                  *NaN = 2;
              } else
              if (IS_NAN(d)) {
                  *NaN = 2;
              } else
              if (tailptr) {
                  while (*tailptr) {
                      switch (*tailptr) {
                      case ' ' :
                      case '\n':
                      case '\r':
                      case '\t': tailptr++; continue;
                      default: break; /*do nothing */
                      }
                      d = strtod ("nan", &tailptr);
                      *NaN = 2;
                      break;
                  }
              }
              FREE(pc);
              return d;
        default:
              DBG(fprintf(stderr, "funcNumber: default: 0.0\n");)
              d = strtod ("nan", &tailptr);
              *NaN = 2;
              return d;
    }
}
................................................................................
    int          len;

    switch (rs->type) {
        case BoolResult:
            if (rs->intvalue) return (tdomstrdup("true"));
                         else return (tdomstrdup("false"));
        case IntResult:
            sprintf(tmp, "%d", rs->intvalue);
            return (tdomstrdup(tmp));

        case RealResult:
            if (IS_NAN (rs->realvalue)) return tdomstrdup ("NaN");
            else if (IS_INF (rs->realvalue)) {
                if (IS_INF (rs->realvalue) == 1) return tdomstrdup ("Infinity");
                else                             return tdomstrdup ("-Infinity");
................................................................................
    domNode *node
)
{
    int          len;

    return xpathGetStringValue (node, &len);
}

/*----------------------------------------------------------------------------
|   xpathFuncNumberForNode
|
\---------------------------------------------------------------------------*/
double xpathFuncNumberForNode (
    domNode *node,
    int      *NaN
)
{
    char        *pc;
    int          len, rc;
    double       d;

    *NaN = 0;
    pc = xpathGetStringValue (node, &len);
    rc = sscanf (pc,"%lf", &d);
    if (rc != 1) *NaN = 2;
    FREE(pc);
    return d;
}


/*----------------------------------------------------------------------------
|   xpathArity
|
\---------------------------------------------------------------------------*/
static int xpathArity (
    ast step
................................................................................
    domNode         *node;
    domAttrNode     *attr;
    double           leftReal;
    ast              nextStep;
    int              argc, savedDocOrder, from;
    xpathResultSets *args;
    xpathResultSet  *arg;

    Tcl_HashEntry   *entryPtr;
    int              left = 0, useFastAdd;
    double           dRight = 0.0;
    char            *leftStr = NULL, *rightStr = NULL;
    const char      *str;
    Tcl_DString      dStr;
#if TclOnly8Bits
    char            *fStr;
#else
    int              found, j;
    int              lenstr, fromlen, utfCharLen;
    char             utfBuf[TCL_UTF_MAX];
    Tcl_DString      tstr, tfrom, tto, tresult;
    Tcl_UniChar     *ufStr, *upfrom, unichar;
#endif

    if (result->type == EmptyResult) useFastAdd = 1;
    else useFastAdd = 0;


    switch (step->intvalue) {

    case f_position:
        XPATH_ARITYCHECK(step,0,errMsg);
        if (*docOrder) {
            rsSetInt (result, position+1);
................................................................................

        leftStr = xpathFuncString (&leftResult );
        xpathRSFree( &leftResult );
        DBG(fprintf(stderr, "leftStr='%s'\n", leftStr);)
        if      (step->intvalue == f_string)
            rsSetString (result, leftStr);
        else if (step->intvalue == f_stringLength) {
#if TclOnly8Bits            
            rsSetInt (result, strlen(leftStr));
#else
            pto = leftStr;
            len = 0;
            while (*pto) {
                len++;
                i = UTF8_CHAR_LEN (*pto);
                if (!i) {
                    FREE (leftStr);
                    *errMsg = tdomstrdup("Can only handle UTF-8 chars up "
                                         "to 3 bytes length");
                    return XPATH_I18N_ERR;
                }
                pto += i;
            }
            rsSetInt (result, len);
#endif
        }
        else {
            pwhite = 1;
            pfrom = pto = leftStr;
            while (*pfrom) {
                switch (*pfrom) {
                case ' ' : case '\n': case '\r': case '\t':
................................................................................
    case f_false:
        XPATH_ARITYCHECK(step,0,errMsg);
        rsSetBool (result, 0);
        break;

    case f_id:
        XPATH_ARITYCHECK(step,1,errMsg);



        if (!ctxNode->ownerDocument->ids) {


            break;
        }
        xpathRSInit (&leftResult);
        rc = xpathEvalStep( step->child, ctxNode, exprContext, position,
                            nodeList, cbs, &leftResult, docOrder, errMsg);
        if (rc) {
            xpathRSFree( &leftResult );
................................................................................
        if (leftResult.type == EmptyResult) {
            xpathRSFree (&leftResult);
            return XPATH_OK;
        }
        if (leftResult.type == xNodeSetResult) {
            for (i=0; i < leftResult.nr_nodes; i++) {
                leftStr = xpathFuncStringForNode (leftResult.nodes[i]);
                entryPtr = Tcl_FindHashEntry (ctxNode->ownerDocument->ids,
                                              leftStr);
                if (entryPtr) {
                    node = (domNode*) Tcl_GetHashValue (entryPtr);
                    /* Don't report nodes out of the fragment list */
                    if (node->parentNode != NULL ||
                        (node == node->ownerDocument->documentElement)) {
                        rsAddNode (result, node);
                    }
................................................................................
                switch (*pto) {
                case ' ' : case '\n': case '\r': case '\t':
                    if (pwhite) {
                        pto++;
                        continue;
                    }
                    *pto = '\0';
                    entryPtr = Tcl_FindHashEntry (ctxNode->ownerDocument->ids,
                                                  pfrom);
                    if (entryPtr) {
                        node = (domNode*) Tcl_GetHashValue (entryPtr);
                        /* Don't report nodes out of the fragment list */
                        if (node->parentNode != NULL ||
                            (node == node->ownerDocument->documentElement)) {
                            rsAddNode (result, node);
                        }
................................................................................
                        pfrom = pto;
                        pwhite = 0;
                    }
                    pto++;
                }
            }
            if (!pwhite) {
                entryPtr = Tcl_FindHashEntry (ctxNode->ownerDocument->ids,
                                              pfrom);
                if (entryPtr) {
                    node = (domNode*) Tcl_GetHashValue (entryPtr);
                    /* Don't report nodes out of the fragment list */
                    if (node->parentNode != NULL ||
                        (node == node->ownerDocument->documentElement)) {
                        rsAddNode (result, node);
                    }
................................................................................
                            nodeList, cbs, &leftResult, docOrder, errMsg);
        if (rc) {
            xpathRSFree (&leftResult);
            return rc;
        }
        leftStr = xpathFuncString (&leftResult);
        if (ctxNode->nodeType != ELEMENT_NODE) {



            node = ctxNode->parentNode;

        } else {
            node = ctxNode;
        }
        while (node) {
            attr = node->firstAttr;
            while (attr) {
                if (strcmp (attr->nodeName, "xml:lang")!=0) {
................................................................................
                    rsSetString (result, "");
                    return XPATH_OK;
                }
                from = 0;
            }
        } else {
            if (from < 0) from = 0;
#if TclOnly8Bits
            len = strlen(leftStr) - from;
#else
            len = INT_MAX;
#endif
        }

#if TclOnly8Bits
        if (from >= (int) strlen(leftStr)) {
            rsSetString (result, "");
            FREE(leftStr);
            return XPATH_OK;
        } else {
            if ( (len == INT_MAX) || ((from + len) > (int) strlen(leftStr)) ) {
                len =  strlen(leftStr) - from;
            }
        }
        DBG(fprintf(stderr, "substring leftStr='%s' from=%d len=%d \n",
                    leftStr, from, len);
            )

            *(leftStr+from+len) = '\0';
        rsSetString (result, (leftStr+from));
#else 
        pfrom = leftStr;
        while (*pfrom && (from > 0)) {
            i = UTF8_CHAR_LEN (*pfrom);
            if (!i) {
                FREE (leftStr);
                *errMsg = tdomstrdup("Can only handle UTF-8 chars up "
                                     "to 3 bytes length");
                return XPATH_I18N_ERR;
            }
            pfrom += i;
            from--;
        }
        if (len < INT_MAX) {
            pto = pfrom;
            while (*pto && (len > 0)) {
                i = UTF8_CHAR_LEN (*pto);
                if (!i) {
                    FREE (leftStr);
                    *errMsg = tdomstrdup("Can only handle UTF-8 chars up "
                                         "to 3 bytes length");
                    return XPATH_I18N_ERR;
                }
                pto += i;
                len--;
            }
            *pto = '\0';
        }
        rsSetString (result, pfrom);
#endif
        FREE(leftStr);
        break;

    case f_translate:
        XPATH_ARITYCHECK(step,3,errMsg);
        xpathRSInit (&leftResult);
        savedDocOrder = *docOrder;
................................................................................
        CHECK_RC;
        *docOrder = savedDocOrder;
        leftStr    = xpathFuncString( &leftResult    );
        rightStr   = xpathFuncString( &rightResult   );
        replaceStr = xpathFuncString( &replaceResult );


#if TclOnly8Bits
        len = strlen(replaceStr);
        pfrom = pto = leftStr;
        while (*pfrom) {
            fStr = strchr(rightStr, *pfrom);
            if (fStr == NULL) {
                *pto++ = *pfrom;
            } else {
                i = (fStr - rightStr);
                if (i < len) {
                    *pto++ = *(replaceStr+i);
                }
            }
            pfrom++;
        }
        *pto = '\0';
        rsSetString (result, leftStr);
#else
        Tcl_DStringInit (&tstr);
        Tcl_DStringInit (&tfrom);
        Tcl_DStringInit (&tto);
        Tcl_DStringInit (&tresult);

        Tcl_UtfToUniCharDString (leftStr, -1, &tstr);
        Tcl_UtfToUniCharDString (rightStr, -1, &tfrom);
................................................................................
            upfrom++;
        }
        rsSetString (result, Tcl_DStringValue (&tresult));
        Tcl_DStringFree (&tstr);
        Tcl_DStringFree (&tfrom);
        Tcl_DStringFree (&tto);
        Tcl_DStringFree (&tresult);
#endif

        xpathRSFree( &replaceResult );
        xpathRSFree( &rightResult   );
        xpathRSFree( &leftResult    );
        FREE(leftStr); FREE(rightStr); FREE(replaceStr);
        break;

................................................................................
                i = 0;
                attr = node->firstAttr;
                while (attr) {
                    if ((domNode*)attr == leftResult.nodes[0]) break;
                    attr = attr->nextSibling;
                    i++;
                }
                sprintf(tmp,"id%p-%d", node, i);
            } else {
                sprintf(tmp,"id%p", leftResult.nodes[0]);
            }
            rsSetString (result, tmp);
        } else

        if (step->intvalue == f_namespaceUri) {
            if (leftResult.type != xNodeSetResult) {
                *errMsg = tdomstrdup("namespace-uri() requires a node set!");
................................................................................
            while (child && (count < step->intvalue)) {
                DBG(fprintf(stderr, "AxisChild: child '%s' domNode%p \n", 
                            child->nodeName, child);)
                if (xpathNodeTest(child, step)) {
                    DBG(fprintf(stderr, 
                      "AxisChild: after node taking child '%s' domNode%p \n",
                                child->nodeName, child);)
                    rsAddNodeFast( result, child);
                    count++;
                }
                child = child->nextSibling;
            }
        } else {
            while (child) {
                DBG(fprintf(stderr, "AxisChild: child '%s' domNode%p \n",
                            child->nodeName, child);)
                if (xpathNodeTest(child, step)) {
                    DBG(fprintf(stderr,
                      "AxisChild: after node taking child '%s' domNode%p \n",
                                child->nodeName, child);)
                    rsAddNodeFast( result, child);
                }
                child = child->nextSibling;
            }
        }
        DBG( fprintf(stderr,"AxisChild result:\n");
             rsPrint(result);
        )
        break;

    case SlashSlash:
        if (step->intvalue) predLimit = 1;
        else predLimit = 0;
        predLimit = 0;
        xpathRSInit (&tResult);
        node = ctxNode->firstChild;
        while (node) {
            if (node->nodeType == ELEMENT_NODE) {
                rc = xpathEvalStep (step, node, exprContext, position,
                                    nodeList, cbs, result, docOrder, errMsg);
                if (rc) {
                    xpathRSFree (&tResult);
                    return rc;
                }
            }
            if (xpathNodeTest(node, step)) {
                rsAddNodeFast( &tResult, node);
                if (predLimit) {
                    count++;
                    if (count >= step->intvalue) break;
                }
            }
            node = node->nextSibling;
        }
        if (node) {
            node = node->nextSibling;
            while (node) {
                if (node->nodeType == ELEMENT_NODE) {
                    rc = xpathEvalStep (step, node, exprContext, position,
                                        nodeList, cbs, result, docOrder,
                                        errMsg);
                    if (rc) {
                        xpathRSFree (&tResult);
                        return rc;
                    }
                }
                node = node->nextSibling;
            }
        }
        rc = xpathEvalPredicate (step->next, exprContext, result, &tResult,
                                  cbs, docOrder, errMsg);
        xpathRSFree (&tResult);
        CHECK_RC;
        break;

    case AxisDescendant:
................................................................................
            step->type = SlashSlash;
            rc = xpathEvalStep (step, ctxNode, exprContext, position, 
                                nodeList, cbs, result, docOrder, errMsg);
            step->type = savedAstType;
            CHECK_RC;
            break;
        }
        /* whithout following Pred step, // is the same as 
           AxisDescendantOrSelf, fall throu */

    case AxisDescendantLit:
    case AxisDescendantOrSelfLit:
        *docOrder = 1;
        if (step->intvalue
            && (step->type == AxisDescendantLit 
................................................................................
        }
        break;

    case AxisSelf:
        *docOrder = 1;
        DBG(fprintf(stderr, "AxisSelf :: \n");)
        if (xpathNodeTest(ctxNode, step)) {
            checkRsAddNode( result, ctxNode);
        }
        break;

    case GetContextNode:
        checkRsAddNode( result, ctxNode);
        break;

    case AxisAttribute:
        *docOrder = 1;
        DBG(fprintf(stderr, "AxisAttribute %s \n", step->child->strvalue);)
        if (ctxNode->nodeType != ELEMENT_NODE) return XPATH_OK;
        if (step->child->type == IsElement) {
................................................................................
            step->child->type = IsAttr;
        }
        if (step->child->type == IsAttr) {
            if (strcmp(step->child->strvalue, "*")==0) {
                attr = ctxNode->firstAttr;
                while (attr) {
                    if (!(attr->nodeFlags & IS_NS_NODE)) {
                        rsAddNodeFast (result, (domNode *)attr);
                    }
                    attr = attr->nextSibling;
                }
            } else {
                attr = ctxNode->firstAttr;
                while (attr && (attr->nodeFlags & IS_NS_NODE))
                    attr = attr->nextSibling;
                while (attr) {
                    if (xpathNodeTest( (domNode*)attr, step)) {
                        rsAddNodeFast (result, (domNode *)attr);
                    }
                    attr = attr->nextSibling;
                }
            }
        } else
        if (step->child->type == IsNSAttr) {
            attr = ctxNode->firstAttr;
            while (attr && (attr->nodeFlags & IS_NS_NODE))
                attr = attr->nextSibling;
            while (attr) {
                if (xpathNodeTest ( (domNode*)attr, step)) {
                    rsAddNodeFast (result, (domNode *)attr);
                }
                attr = attr->nextSibling;
            }
        }
        break;

    case AxisParent:
................................................................................
        break;

    case AxisAncestor:
    case AxisAncestorOrSelf:
        *docOrder = 0;
        xpathRSInit (&tResult);
        if (step->type == AxisAncestorOrSelf) {
            if (xpathNodeTest(ctxNode, step))
                rsAddNodeFast(&tResult, ctxNode);

        }
        if (ctxNode->nodeType == ATTRIBUTE_NODE) {
            ctxNode = ((domAttrNode *)ctxNode)->parentNode;
            if (xpathNodeTest(ctxNode, step))
                rsAddNodeFast(&tResult, ctxNode);

        }
        startingNode = ctxNode;
        while (ctxNode->parentNode) {
            ctxNode = ctxNode->parentNode;
            if (xpathNodeTest(ctxNode, step))
                rsAddNodeFast(&tResult, ctxNode);

        }
        if (startingNode != ctxNode->ownerDocument->rootNode) {
            if (xpathNodeTest (ctxNode->ownerDocument->rootNode, step)) {
                rsAddNodeFast (&tResult, ctxNode->ownerDocument->rootNode);
            }
        }
        for (i = tResult.nr_nodes - 1; i >= 0;  i--) {
................................................................................
                rc = 0;
                for (i = 0; i < result->nr_nodes; i++) {
                    if (strcmp (attr->nodeName, ((domAttrNode*)result->nodes[i])->nodeName)==0) {
                        rc = 1; break;
                    }
                }
                if (rc) {attr = attr->nextSibling; continue;}
                rsAddNodeFast (result, (domNode *)attr);
                attr = attr->nextSibling;
            }

            if (node == node->ownerDocument->documentElement) {
                if (ctxNode != ctxNode->ownerDocument->rootNode) {
                    node = ctxNode->ownerDocument->rootNode;
                } else {
................................................................................
        break;

    case Real:
        rsSetReal (result, step->realvalue);
        break;

    case Add:
    case Substract:
    case Mult:
    case Div:
    case Mod:
        xpathRSInit (&leftResult);
        xpathRSInit (&rightResult);

        savedDocOrder = *docOrder;
................................................................................
            dRight = xpathFuncNumber(&rightResult, &NaN1);
        }
        if (NaN || NaN1) {
            if ((NaN == 2) || (NaN1 == 2)) {
                rsSetNaN (result);
            } else {
                switch (step->type) {
                case Substract:
                    NaN1 = -1 * NaN1;
                    /* fall throu */   
                case Add:
                    if (NaN == NaN1) {
                        if (NaN == 1) rsSetInf (result);
                        else          rsSetNInf (result);
                    } else if ((rc = NaN + NaN1) != 0) {
................................................................................
            }
            xpathRSFree (&rightResult);
            xpathRSFree (&leftResult);
            return XPATH_OK;
        }
        switch (step->type) {
        case Add:       rsSetReal (result, dLeft + dRight); break;
        case Substract: rsSetReal (result, dLeft - dRight); break;
        case Mult:      rsSetReal (result, dLeft * dRight); break;
        case Div:
            if (dRight == 0.0) {
                if (dLeft == 0.0) {
                    rsSetNaN (result);
                } else {
                    if (dLeft > 0) {
................................................................................
                    }
                }
            } else {
                rsSetReal (result, dLeft / dRight);
            }
            break;
        case Mod:
            if (dRight == 0.0) {
                rsSetNaN (result);
            } else {
                rsSetInt  (result, ((int)dLeft) % ((int)dRight));
            }
            break;
        default:        break;
        }
................................................................................
                    /* The real value of a node could never be inf/-inf */
                    /* And NaN is always != NaN (and != everything else) */
                    if (step->type == Equal) res = 0;
                    else                     res = 1;
                    break;
                }
                for (i=0; i < pleftResult->nr_nodes; i++) {
                    dLeft = xpathFuncNumberForNode (pleftResult->nodes[i], &NaN);


                    if (NaN) continue;
                    if (step->type == Equal) res = (dLeft == dRight);
                    else                     res = (dLeft != dRight);
                    if (res) break;
                }
                break;
            case NaNResult:
................................................................................
        CHECK_RC;
        *docOrder = savedDocOrder;

        DBG( fprintf(stderr,"right:\n");
             rsPrint(&rightResult);
        )
        res = 0;

        if (   leftResult.type == xNodeSetResult
            || rightResult.type == xNodeSetResult) {
            if (leftResult.type == xNodeSetResult) {
                pleftResult = &leftResult;
                prightResult = &rightResult;
                switchResult = 0;
            } else {
                pleftResult = &rightResult;
                prightResult = &leftResult;
                switchResult = 1;
            }

            switch (prightResult->type) {
            case EmptyResult:
                res = 0;
                break;
            case xNodeSetResult:
                JDBG( fprintf(stderr,"\nleft+right result:\n");
                     rsPrint(pleftResult);
                     rsPrint(prightResult);
                )
                for (i=0; i < pleftResult->nr_nodes; i++) {
                    dLeft = xpathFuncNumberForNode (pleftResult->nodes[i], &NaN);


                    if (NaN) continue;
                    for (j=0; j < prightResult->nr_nodes; j++) {
                        dRight = xpathFuncNumberForNode (prightResult->nodes[j], &NaN);


                        if (NaN)  continue;
                        if (switchResult) {
                            dTmp   = dLeft;
                            dLeft  = dRight;
                            dRight = dTmp;
                        }
                        if      (step->type == Less)     res = (dLeft < dRight);
................................................................................

                        if (res) break;
                    }
                    if (res) break;
                }
                break;
            case BoolResult:
                /* pleftResult is a non-emtpy nodeset, therefor: */
                dLeft = 1.0;
                dRight = xpathFuncNumber (prightResult, &NaN);
                if (NaN) break;
                if      (step->type == Less)     res = (dLeft < dRight);
                else if (step->type == LessOrEq) res = (dLeft <= dRight);
                else if (step->type == Greater)  res = (dLeft >  dRight);
                else                             res = (dLeft >= dRight);
................................................................................
                    if (NaN == 2) break;
#ifdef DBL_MAX                    
                    if (NaN == 1) dRight = DBL_MAX;
                    else          dRight = -DBL_MAX;
#endif
                }
                for (i=0; i < pleftResult->nr_nodes; i++) {
                    dLeft = xpathFuncNumberForNode (pleftResult->nodes[i], &NaN);


                    if (NaN) continue;
                    if (switchResult) {
                        dTmp   = dLeft;
                        dLeft  = dRight;
                        dRight = dTmp;
                    }
                    if      (step->type == Less)     res = (dLeft < dRight);
................................................................................
            rc = xpathEvalStep( step->child, stepResult->nodes[i],
                                exprContext, i, stepResult, cbs, &predResult,
                                docOrder, errMsg);
            CHECK_RC;
            *docOrder = savedDocOrder;
            DBG( fprintf(stderr, "after eval for Predicate: \n"); )
            DBG( rsPrint( &predResult); )

            if (predResult.type == RealResult) {
                predResult.type = IntResult;
                predResult.intvalue = xpathRound(predResult.realvalue);
            }
            if (predResult.type == IntResult) {
                if (predResult.intvalue < 0) {
                    predResult.intvalue = 
................................................................................
    char            ** errMsg,
    xpathResultSet   * result
)
{
    xpathResultSet nodeList;
    int            rc, hnew = 1, docOrder = 1;
    ast            t;
    Tcl_HashEntry *h;

    *errMsg = NULL;
    if (cache) {
        h = Tcl_CreateHashEntry (cache, xpath, &hnew);
    }
    if (hnew) {
        rc = xpathParse(xpath, exprContext, XPATH_EXPR, prefixMappings,
                        parseVarCB, &t, errMsg);
        CHECK_RC;






        if (cache) {
            Tcl_SetHashValue(h, t);
        }
    } else {
        t = (ast)Tcl_GetHashValue(h);
    }
    
................................................................................
                    if (nodeToMatch->nodeType != ELEMENT_NODE) {
                        xpathRSFree (&nodeList); return 0;
                    }
                    if (nodeToMatch == nodeToMatch->ownerDocument->rootNode) {
                        xpathRSFree (&nodeList); return 0;
                    }
                    if ((step->child->strvalue[0] != '*') ||
                        (step->child->strvalue[1] != '\0'))

                    {
                        if (nodeToMatch->namespace) return 0;
                        if (strcmp(nodeToMatch->nodeName, step->child->strvalue)!=0) {
                            xpathRSFree (&nodeList); return 0;
                        }
                    }
                    break;
................................................................................
                if (nodeToMatch->nodeType != ELEMENT_NODE) {
                    xpathRSFree (&nodeList); return 0;
                }
                if (nodeToMatch == nodeToMatch->ownerDocument->rootNode) {
                    xpathRSFree (&nodeList); return 0;
                }
                if ((step->strvalue[0] != '*') ||
                    (step->strvalue[1] != '\0'))

                {
                    if (nodeToMatch->namespace) return 0;
                    if (strcmp(nodeToMatch->nodeName, step->strvalue)!=0) {
                        xpathRSFree (&nodeList); return 0;
                    }
                }
                break;
................................................................................
{
    if (!steps) return 0.0;

    DBG(printAst(0, steps);)

    if (steps->next == NULL) {
        if (steps->type == IsElement) {
            if (strcmp(steps->strvalue, "*")==0) {
                return -0.5;
            } else {
                return 0.0;
            }
        } else
        if (steps->type == IsFQElement) {
            return 0.0;
................................................................................
|   nodeToXPath  -  returns a XPath addressing exactly the given node
|
\---------------------------------------------------------------------------*/
static void nodeToXPath (
    domNode  * node,
    char    ** xpath,
    int      * xpathLen,
    int      * xpathAllocated

)
{
    domNode *parent, *child;
    char    step[200], *nTest;
    int     sameNodes, nodeIndex, len;


    parent = node->parentNode;
    if (parent == NULL) {
        parent = node->ownerDocument->rootNode;
    } else {
        nodeToXPath (parent, xpath, xpathLen, xpathAllocated);
    }

    step[0] = '\0';
    switch (node->nodeType) {

    case ELEMENT_NODE:
        nodeIndex = 0;
        sameNodes = 0;
        child = parent->firstChild;

        while (child) {
















            if (strcmp(child->nodeName, node->nodeName)==0) {
                sameNodes++;
                if (node == child) nodeIndex = sameNodes;
                if ((nodeIndex != 0) && (sameNodes > 2)) break;
            }
            child = child->nextSibling;
        }
        if (sameNodes == 1) {
            sprintf(step, "/%s", node->nodeName);
        } else {
            sprintf(step, "/%s[%d]", node->nodeName, nodeIndex);

        }
        break;

    case TEXT_NODE:
    case COMMENT_NODE:
    case PROCESSING_INSTRUCTION_NODE:
        nodeIndex = 0;
................................................................................


/*----------------------------------------------------------------------------
|   xpathNodeToXPath
|
\---------------------------------------------------------------------------*/
char * xpathNodeToXPath (
    domNode *node

)
{
    char  * xpath;
    int     xpathLen, xpathAllocated;


    xpathAllocated = 100;
    xpathLen       = 0;
    xpath          = MALLOC(xpathAllocated + 1);

    nodeToXPath (node, &xpath, &xpathLen, &xpathAllocated);

    return xpath;

} /* xpathNodeToXPath */








>







 







|







 







|







 







|







 







|



|







 







|







 







|









|







 







|




|







 







|







 







<







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
|
>
>
>







 







>







 







|







 







>







 







|







 







|

|







 







>










>








>




>







 







|







 







>







 







|







 







>












>












>








>







 







|
|







 







|
>


|







 







|
>
>







 







|







 







|







 







|
>
|
>
>
>







 







|











|
<
|
>



>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
|
|
<
>
|

|
<
>

|
|
|
|


|

|




|
>
>
>
>
>
>
>
|
>
|
>
>












|







 







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
<
<
>
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>

|




<
<
<





<
<
<
<
<







 







<
<
<








|





<







 







>
>
>
|
>
>







 







|
<







 







|
<







 







|
<







 







>
>
>
|
>







 







<
<
<

<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|












|








<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<







 







|

|







 







|












|










<
<
<













<
<
<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







 







|




|







 







|









|











|







 







|

>



|

>




|

>







 







|







 







|







 







|







 







|







 







|







 







|
>
>







 







<











>










|
>
>


|
>
>







 







|







 







|
>
>







 







<







 







|








<
>
>
>
>
>
>







 







|
>







 







|
>







 







|







 







|
>











|









>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
>







 







|
>










|





65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
...
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
...
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
...
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
...
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
...
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
...
607
608
609
610
611
612
613

614
615
616
617
618
619
620
...
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
...
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
....
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
....
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
....
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
....
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
....
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
....
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
....
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
....
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
....
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
....
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
....
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
....
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
....
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
....
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
....
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
....
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
....
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
....
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471

2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497

2498
2499
2500

2501
2502
2503
2504

2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
....
2576
2577
2578
2579
2580
2581
2582
2583





























2584
2585



2586
2587
2588

























2589
2590
2591
2592
2593
2594
2595
....
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
....
2760
2761
2762
2763
2764
2765
2766






















2767
2768
2769
2770
2771
2772
2773
....
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860



2861
2862
2863
2864
2865





2866
2867
2868
2869
2870
2871
2872
....
2975
2976
2977
2978
2979
2980
2981



2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995

2996
2997
2998
2999
3000
3001
3002
....
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
....
3068
3069
3070
3071
3072
3073
3074
3075

3076
3077
3078
3079
3080
3081
3082
....
3093
3094
3095
3096
3097
3098
3099
3100

3101
3102
3103
3104
3105
3106
3107
....
3114
3115
3116
3117
3118
3119
3120
3121

3122
3123
3124
3125
3126
3127
3128
....
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
....
3396
3397
3398
3399
3400
3401
3402



3403

3404
3405

















3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433

3434
3435
3436
3437
3438
3439
3440
....
3454
3455
3456
3457
3458
3459
3460


















3461
3462
3463
3464
3465
3466
3467
....
3495
3496
3497
3498
3499
3500
3501

3502
3503
3504
3505
3506
3507
3508
....
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
....
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847



3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860




3861
3862
3863















3864
3865
3866
3867
3868
3869
3870
....
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
....
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
....
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
....
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
....
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
....
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
....
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
....
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
....
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
....
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
....
4746
4747
4748
4749
4750
4751
4752

4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
....
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
....
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
....
4990
4991
4992
4993
4994
4995
4996

4997
4998
4999
5000
5001
5002
5003
....
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189

5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
....
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
....
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
....
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
....
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
....
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include <math.h>
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <dom.h>
#include <domxpath.h>
#include <domxslt.h>


/*----------------------------------------------------------------------------
|   Macros
................................................................................
};


typedef struct {

    Token  token;
    char  *strvalue;
    long   intvalue;
    double realvalue;
    int    pos;

} XPathToken;

typedef XPathToken *XPathTokens;

................................................................................
|   Types for abstract syntax trees
|
\---------------------------------------------------------------------------*/
static char *astType2str[] = {
    "Int", "Real", "Mult", "Div", "Mod", "UnaryMinus", "IsNSElement",
    "IsNode", "IsComment", "IsText", "IsPI", "IsSpecificPI", "IsElement",
    "IsFQElement", "GetVar", "GetFQVar", "Literal", "ExecFunction", "Pred",
    "EvalSteps", "SelectRoot", "CombineSets", "Add", "Subtract", "Less",
    "LessOrEq", "Greater", "GreaterOrEq", "Equal", "NotEqual", "And", "Or",
    "IsNSAttr", "IsAttr", "AxisAncestor", "AxisAncestorOrSelf",
    "AxisAttribute", "AxisChild",
    "AxisDescendant", "AxisDescendantOrSelf", "AxisFollowing",
    "AxisFollowingSibling", "AxisNamespace", "AxisParent",
    "AxisPreceding", "AxisPrecedingSilbing", "AxisSelf",
    "GetContextNode", "GetParentNode", "AxisDescendantOrSelfLit",
................................................................................

static int xpathEvalPredicate (ast steps, domNode *exprContext, 
                               xpathResultSet *result, 
                               xpathResultSet *stepResult,
                               xpathCBs *cbs, int *docOrder, char **errMsg);

/*----------------------------------------------------------------------------
|   XPath result set functions
|
\---------------------------------------------------------------------------*/

void xpathRSFree ( xpathResultSet *rs ) {

    if (rs->type == xNodeSetResult) {
        if (!rs->intvalue) {
................................................................................
    int i = 0,l;  char tmp[80];
    switch (rs->type) {
        case EmptyResult:
             fprintf(stderr, "empty result \n");
             break;

        case BoolResult:
             fprintf(stderr, "boolean result: %ld \n", rs->intvalue);
             break;

        case IntResult:
             fprintf(stderr, "int result: %ld \n", rs->intvalue);
             break;

        case RealResult:
             fprintf(stderr, "real result: %f \n", rs->realvalue);
             break;

        case StringResult:
................................................................................
             break;

        case xNodeSetResult:
             if (!i) fprintf(stderr,"nodeSet result (len %d):\n",rs->nr_nodes);
             for (i=0; i<rs->nr_nodes; i++) {
                 if (rs->nodes[i]->nodeType == ELEMENT_NODE) {
                     fprintf(stderr, "%2d domNode%p %s ",
                             i, (void *)rs->nodes[i], rs->nodes[i]->nodeName);
                     if (rs->nodes[i]->firstChild &&
                         rs->nodes[i]->firstChild->nodeType == TEXT_NODE)
                     {
                         l = ((domTextNode*)rs->nodes[i]->firstChild)->valueLength;
                         if (l > 25) l = 25;
                         memcpy(tmp, ((domTextNode*)rs->nodes[i]->firstChild)->nodeValue, l);
                         tmp[l] = '\0';
................................................................................
                 } else
                 if (rs->nodes[i]->nodeType == TEXT_NODE) {
                     l = ((domTextNode*)rs->nodes[i])->valueLength;
                     if (l > 60) l = 60;
                     memcpy(tmp, ((domTextNode*)rs->nodes[i])->nodeValue, l);
                     tmp[l] = '\0';
                     fprintf(stderr, "%2d domNode%p text:'%s' \n",
                             i,  (void *)rs->nodes[i], tmp);
                 } else
                 if (rs->nodes[i]->nodeType == COMMENT_NODE) {
                     l = ((domTextNode*)rs->nodes[i])->valueLength;
                     memcpy (tmp, "<!--", 4);
                     if (l > 60) l = 60;
                     memcpy(&tmp[4], ((domTextNode*)rs->nodes[i])->nodeValue, l);
                     memcpy(&tmp[4+l], "-->", 3);
                     tmp[7+l] = '\0';
                     fprintf(stderr, "%2d domNode%p text:'%s' \n",
                             i,  (void *)rs->nodes[i], tmp);
                 } else
                 if (rs->nodes[i]->nodeType == ATTRIBUTE_NODE) {
                     fprintf(stderr, "%2d Attr %s='%*s'\n", i,
                             ((domAttrNode*)rs->nodes[i])->nodeName,
                             ((domAttrNode*)rs->nodes[i])->valueLength,
                             ((domAttrNode*)rs->nodes[i])->nodeValue);
                 }
................................................................................
}
void rsSetInf ( xpathResultSet *rs ) {
    rs->type = InfResult;
}
void rsSetNInf ( xpathResultSet *rs ) {
    rs->type = NInfResult;
}
void rsSetInt ( xpathResultSet *rs, long i) {

    rs->type = IntResult;
    rs->intvalue = i;
}
void rsSetBool ( xpathResultSet *rs, long i) {

    rs->type = BoolResult;
    rs->intvalue = (i ? 1 : 0);
}
void rsSetString ( xpathResultSet *rs, const char *s) {

    rs->type = StringResult;
................................................................................
        t->child->next = New1(EvalSteps, b);
    } else {
        t->child->next = b;
    }
    return t;
}

static ast NewInt( long i ) {
    ast t = NEWCONS;

    t->type      = Int;
    t->strvalue  = NULL;
    t->intvalue  = i;
    t->realvalue = 0.0;

................................................................................
    }
    /*child->next = NULL;*/
    return m;
}
static void freeAst (ast t)
{
    ast tmp;

    while (t) {
        tmp = t->next;
        if (t->strvalue) FREE(t->strvalue);
        if (t->child) freeAst (t->child);
        FREE((char*)t);
        t = tmp;
    }
................................................................................
    int i;

    while (t) {
        for (i=0; i<depth; i++) fprintf(stderr, "   ");
        fprintf(stderr, "%s ", astType2str[t->type]);
        switch (t->type) {

            case Int :        fprintf(stderr, "%ld", t->intvalue);   break;
            case Real:        fprintf(stderr, "%f", t->realvalue);  break;
            case IsElement:
            case IsFQElement:
            case IsNSAttr:
            case IsAttr:
            case ExecFunction:
            case Literal:
................................................................................
                           } else {
                               *errMsg = tdomstrdup("Expected variable name");
                               return tokens;
                           }
                       }
                       break;

            case '%':  if (!varParseCB) {
                           *errMsg = tdomstrdup ("Unexpected char '%'");
                           return tokens;
                       }
                       ps = (varParseCB->parseVarCB) (
                                varParseCB->parseVarClientData, &xpath[i],
                                &offset, errMsg
                              );
                       if (ps) {
                           token = WCARDNAME;
                           tokens[l].strvalue = tdomstrdup (ps);
                           /* We kind of misuse the (in case of
                            * WCARDNAME token otherwise not used)
                            * intvalue to mark this WCARDNAME token
                            * to be meant as literal - this is to
                            * distinguish between '*' as wildcard and
                            * as literal element name. */
                           tokens[l].intvalue = 1;
                           i += offset - 1;
                       } else {
                           return tokens;
                       }
                       break;
                
            case '.':  if (xpath[i+1] == '.') {
                           token = DOTDOT;
                           i++;
                           break;
                       } else if (!isdigit((unsigned char)xpath[i+1])) {
                           token = DOT;
                           break;
................................................................................
                               i++;
                               while (xpath[i] 
                                      && isdigit((unsigned char)xpath[i])) i++;
                           }
                           save = xpath[i];
                           xpath[i] = '\0';
                           if (token == INTNUMBER) {
                               errno = 0;
                               tokens[l].intvalue = strtol(ps, NULL, 10);
                               if (errno == ERANGE 
                                   && ( tokens[l].intvalue == LONG_MAX 
                                        || tokens[l].intvalue == LONG_MIN)) {
                                   token = REALNUMBER;
                               }
                           }
                           tokens[l].realvalue = (double)atof(ps);
                           xpath[i--] = save;
                       } else {
                           sprintf (tmpErr, "Unexpected character '%c' at "
                                    "position %d", xpath[i], i);
                           *errMsg = tdomstrdup (tmpErr);
................................................................................
    } else
    if (LA==NSWC) {
        Consume (NSWC);
        a = NewStr (IsNSElement, STRVAL);
    } else {
        Consume(WCARDNAME);
        a = NewStr (IsElement, STRVAL);
        a->intvalue = INTVAL;
    }
EndProduction


/*-----------------------------------------------------------------
|   AbbreviatedBasis  production
|
................................................................................
        Consume(RPAR);
    } else {
        ErrExpected("$var or (expr) or literal or number or func");
    }
    while (LA==LBRACKET) {
        ast b;
        b = Recurse(Predicate);
        if (!b) return a;
        Append( a, New1WithEvalSteps( Pred, b));
    }
EndProduction


/*-----------------------------------------------------------------
|   PathExpr  production
................................................................................
            Consume(SLASH);
            Append(a, Recurse(RelativeLocationPath));

        } else if (LA==SLASHSLASH) {
            ast b;
            Consume(SLASHSLASH);
            b = Recurse(RelativeLocationPath);
            if (!b) return a;
            if (b->type == AxisChild) {
                b->type = AxisDescendant;
            } else {
                Append(a, New( AxisDescendantOrSelf ) );
            }
            Append(a, b );
        }
................................................................................
          ||(LA==MINUS)
    ) {
        if (LA==PLUS) {
            Consume(PLUS);
            a = New2( Add, a, Recurse(MultiplicativeExpr));
        } else {
            Consume(MINUS);
            a = New2( Subtract, a, Recurse(MultiplicativeExpr));
        }
    }
EndProduction


/*-----------------------------------------------------------------
|   RelationalExpr  production
................................................................................
EndProduction


/*-----------------------------------------------------------------
|   Step  production
|
\----------------------------------------------------------------*/
static long IsStepPredOptimizable (ast a) {
    ast b;
    long left;
    
    /* Must be called with a != NULL */
    DBG (
        fprintf (stderr, "IsStepPredOptimizable:\n");
        printAst (0,a);
    )
    switch (a->type) {
................................................................................
    case Less:
    case LessOrEq:
        b = a->child;
        if (!b) return 0;
        if (b->type != ExecFunction 
            || b->intvalue != f_position) return 0;
        b = b->next;
        if (!b) return 0;
        if (b->type != Int) return 0;
        if (a->type == Less) return b->intvalue;
        else                 return b->intvalue + 1;
    case Greater:
    case GreaterOrEq:
        b = a->child;
        if (!b) return 0;
        if (b->type != Int) return 0;
        left = b->intvalue;
        b = b->next;
        if (!b) return 0;
        if (b->type != ExecFunction 
            || b->intvalue != f_position) return 0;
        if (a->type == Greater) return left;
        else                    return left + 1;
    case Equal:
        b = a->child;
        if (!b) return 0;
        if (b->type == Int
            && b->next
            && b->next->type == ExecFunction
            && b->next->intvalue == f_position) return b->intvalue;
        if (b->type == ExecFunction
            && b->intvalue == f_position
            && b->next
            && b->next->type == Int) return b->next->intvalue;
        return 0;
    default: return 0;
    }
}

Production(Step)
................................................................................
        a = Recurse(Basis);
        if (LA==LBRACKET && !a) {
            if (*errMsg == NULL) { ErrExpected("Step"); }
            return NULL;
        }
        while (LA==LBRACKET) {
            b = Recurse (Predicate);
            if (!b) return a;
            if (isFirst) {
                a->intvalue = IsStepPredOptimizable (b);
                DBG (fprintf (stderr, "step type %s, intvalue: %d\n", astType2str[a->type], a->intvalue);)
                    isFirst = 0;
            }
            Append( a, New1WithEvalSteps( Pred, b));
        }
................................................................................
        if (LA==SLASH) {
            Consume(SLASH);
            Append(a, Recurse(Step));
        } else {
            ast b;
            Consume(SLASHSLASH);
            b = Recurse(Step);
            if (!b) return a;
            if (b->type == AxisChild) {
                b->type = AxisDescendant;
            } else {
                Append(a, New( AxisDescendantOrSelf ) );
            }
            Append(a, b );
        }
................................................................................
        }
        a = a->next;
    }
    return 0;
}

/* Must be called with a != NULL */
static int checkStepPatternPredOptimizability ( ast a , long *max) {
    ast b;

    switch (a->type) {
        case Literal:
        case AxisAncestor:
        case AxisAncestorOrSelf:
        case AxisChild:
................................................................................
            return 1;
        case Less:
        case LessOrEq:
            b = a->child;
            if (b
                && b->type == ExecFunction
                && b->intvalue == f_position
                && b->next
                && b->next->type == Int) {
                if (a->type == Less) *max = b->next->intvalue;
                else *max = b->next->intvalue + 1;
                return 0;
            }
            if (usesPositionInformation(a->child)) return 0;
            return 1;            
        case Greater:
        case GreaterOrEq:
            b = a->child;
            if (b
                && b->type == Int 
                && b->next
                && b->next->type == ExecFunction
                && b->next->intvalue == f_position) {
                if (a->type == Greater) *max = b->intvalue;
                else *max = b->intvalue + 1;
                return 0;
            }
            if (usesPositionInformation(a->child)) return 0;
            return 1;            
        case Equal:
            b = a->child;
            if (b
                && b->type == Int
                && b->next
                && b->next->type == ExecFunction
                && b->next->intvalue == f_position) {
                *max = b->intvalue;
                return 0;
            }
            if (b
                && b->type == ExecFunction 
                && b->intvalue == f_position
                && b->next
                && b->next->type == Int) {
                *max = b->next->intvalue;
                return 0;
            }
            if (usesPositionInformation(a->child)) return 0;
            return 1;
        case NotEqual:
................................................................................
        default: 
            return 0;
    }
    return 1;
}

/* Must be called with a != NULL */
static long IsStepPatternPredOptimizable ( ast a, long *max ) {
    long f;

    *max = 0;
    f = checkStepPatternPredOptimizability(a, max);
    DBG(
        if (f) {
            fprintf(stderr, "\nStepPattern Pred is optimizable:\n");
        } else {
................................................................................
    }
    if (!a) {
        if (*errMsg == NULL) { ErrExpected("StepPattern") }; 
        return NULL;
    }
    {
        ast b = NULL, c = NULL, aCopy = NULL;
        int stepIsOptimizable = 1, isFirst = 1;
        long max, savedmax;
        while (LA==LBRACKET) {
            b = Recurse (Predicate);
            if (!b) return a;
            if (stepIsOptimizable) {
                if (!IsStepPatternPredOptimizable(b, &max)) 
                    stepIsOptimizable = 0;
            }
            if (isFirst) {
                savedmax = max;
                c = New1WithEvalSteps( Pred, b);
................................................................................
    DBG(
        fprintf(stderr, "xpathParsePostProcess start:\n");
        printAst (0, t);
        )
    while (t) {
        DBG(printAst (4, t);)
        if (t->type == AxisNamespace) {
            if (t->child->type == IsElement
                && t->child->strvalue[0] != '*'
                && t->child->intvalue == 0) {
                uri = domLookupPrefixWithMappings (exprContext, 
                                                   t->child->strvalue, 
                                                   prefixMappings);
                if (!uri) {
                    *errMsg = tdomstrdup ("Prefix doesn't resolve");
                    return 0;
                }
................................................................................
                        varParseCB, errMsg);
    if (*errMsg != NULL) {
        if (tokens != NULL) xpathFreeTokens (tokens);
        return XPATH_LEX_ERR;
    }
    DDBG(
        for (i=0; tokens[i].token != EOS; i++) {
            fprintf(stderr, "%3d %-12s %5ld %8.3f %5d  %s\n",
                            i,
                            token2str[tokens[i].token-LPAR],
                            tokens[i].intvalue,
                            tokens[i].realvalue,
                            tokens[i].pos,
                            tokens[i].strvalue
            );
................................................................................
        newlen = strlen(xpath);
        *errMsg = (char*)REALLOC(*errMsg, len+newlen+10);
        memmove(*errMsg + len, " for '", 6);
        memmove(*errMsg + len+6, xpath, newlen);
        memmove(*errMsg + len+6+newlen, "' ", 3);

        for (i=0; tokens[i].token != EOS; i++) {
            sprintf(tmp, "%s\n%3s%3d %-12s %5ld %09.3f %5d  ",
                         (i==0) ? "\n\nParsed symbols:" : "",
                         (i==l) ? "-->" : "   ",
                          i,
                         token2str[tokens[i].token-LPAR],
                         tokens[i].intvalue,
                         tokens[i].realvalue,
                         tokens[i].pos
................................................................................
    const char *localName, *nodeUri;

    if (!(step->child)) return 1;
    if (step->child->type == IsElement) {
        if (node->nodeType == ELEMENT_NODE) {
            if ((step->child->strvalue[0] == '*') &&
                (step->child->strvalue[1] == '\0') &&
                (node->ownerDocument->rootNode != node) &&
                (step->child->intvalue == 0)) return 1;
            if (node->namespace
                && (node->ownerDocument->namespaces[node->namespace-1]->prefix[0] != '\0'
                    || node->ownerDocument->namespaces[node->namespace-1]->uri[0] != '\0')
                ) return 0;
            return (strcmp(node->nodeName, step->child->strvalue)==0);
        }
        return 0;
    } else
    if (step->child->type == IsAttr) {
        if (node->nodeType == ATTRIBUTE_NODE) {
            if (node->nodeFlags & IS_NS_NODE) return 0;
................................................................................
|
\---------------------------------------------------------------------------*/
int xpathFuncBoolean (
    xpathResultSet  *rs
)
{
    switch (rs->type) {
        case BoolResult:         return ( rs->intvalue ? 1 : 0 );
        case IntResult:          return ( rs->intvalue ? 1 : 0 );
        case RealResult:         return ((rs->realvalue != 0.0 ) && !IS_NAN (rs->realvalue));
        case StringResult:       return ( rs->string_len > 0   );
        case xNodeSetResult:     return ( rs->nr_nodes > 0     );
        case InfResult:
        case NInfResult:         return 1;
        /* NaNResult and EmptyResult are 'false' */
        default:                 return 0;
    }
}

static double xpathStringToNumber (

    char *str,
    int  *NaN
    )
{
    int dotseen = 0;
    double d;
    char *pc, *tailptr;

    /* 
       Just to use strtod() isn't sufficient for a few reasons:
       - strtod() accepts a leading - or +, but XPath allows only a
         leading -
       - strtod() accepts the string representation of a hexadecimal
         number, but XPath does not
       - strtod() accepts an optional exponent but XPath does not
       - strtod() accepts leading whitespace including \f and \v, but
         XPath doesn't allow this characters. Since this two
         characters are not legal XML characters, they can not be part
         of a DOM tree and therefor there isn't a problem with XPath
         expressions on DOM trees or in XSLT. But on Tcl level it's
         possible, to feed that characters literal into the XPath
         engine.
    */
    *NaN = 0;
    pc = str;
    while (*pc && IS_XML_WHITESPACE(*pc)) pc++;

    if (!*pc) goto returnNaN;
    if (*pc == '-') {
        pc++;

        if (!*pc) goto returnNaN;
    } else if (*pc == '.') {
        dotseen = 1;
        pc++;

        if (!*pc) goto returnNaN;
    }
    if (!isdigit((unsigned char)*pc)) goto returnNaN;
    while (*pc) {
        if (isdigit((unsigned char)*pc)) {
            pc++;
            continue;
        }
        if (*pc == '.' && !dotseen) {
            dotseen = 1;
            pc++;
            continue;
        }
        break;
    }
    while (*pc && IS_XML_WHITESPACE(*pc)) pc++;
    if (*pc) goto returnNaN;

    /* If we are here str is a number string, as XPath expects it. Now
       we just use strtod(), to get the number */
    d = strtod (str, &tailptr);
    if (d == 0.0 && tailptr == str) goto returnNaN;
    else if (IS_NAN(d)) goto returnNaN;
    return d;

    returnNaN:
    *NaN = 2;
    return strtod ("nan", &tailptr);
}

/*----------------------------------------------------------------------------
|   xpathFuncNumber
|
\---------------------------------------------------------------------------*/
double xpathFuncNumber (
    xpathResultSet  *rs,
    int             *NaN
)
{
    double d;
    char  *pc, *tailptr;

    *NaN = 0;
    switch (rs->type) {
        case BoolResult:   return (rs->intvalue? 1.0 : 0.0);
        case IntResult:    return rs->intvalue;
        case RealResult:   
            if (IS_NAN(rs->realvalue)) *NaN = 2;
................................................................................
            return -DBL_MAX;
#   else
            /* well, what? */
            return 0.0
#   endif
#endif
        case StringResult:
            return xpathStringToNumber(rs->string, NaN);





























        case xNodeSetResult:
            pc = xpathFuncString(rs);



            d = xpathStringToNumber(pc, NaN);
            FREE(pc);
            return d;

























        default:
              DBG(fprintf(stderr, "funcNumber: default: 0.0\n");)
              d = strtod ("nan", &tailptr);
              *NaN = 2;
              return d;
    }
}
................................................................................
    int          len;

    switch (rs->type) {
        case BoolResult:
            if (rs->intvalue) return (tdomstrdup("true"));
                         else return (tdomstrdup("false"));
        case IntResult:
            sprintf(tmp, "%ld", rs->intvalue);
            return (tdomstrdup(tmp));

        case RealResult:
            if (IS_NAN (rs->realvalue)) return tdomstrdup ("NaN");
            else if (IS_INF (rs->realvalue)) {
                if (IS_INF (rs->realvalue) == 1) return tdomstrdup ("Infinity");
                else                             return tdomstrdup ("-Infinity");
................................................................................
    domNode *node
)
{
    int          len;

    return xpathGetStringValue (node, &len);
}























/*----------------------------------------------------------------------------
|   xpathArity
|
\---------------------------------------------------------------------------*/
static int xpathArity (
    ast step
................................................................................
    domNode         *node;
    domAttrNode     *attr;
    double           leftReal;
    ast              nextStep;
    int              argc, savedDocOrder, from;
    xpathResultSets *args;
    xpathResultSet  *arg;
    Tcl_HashTable   *ids;
    Tcl_HashEntry   *entryPtr;
    int              left = 0;
    double           dRight = 0.0;
    char            *leftStr = NULL, *rightStr = NULL;
    const char      *str;
    Tcl_DString      dStr;



    int              found, j;
    int              lenstr, fromlen, utfCharLen;
    char             utfBuf[TCL_UTF_MAX];
    Tcl_DString      tstr, tfrom, tto, tresult;
    Tcl_UniChar     *ufStr, *upfrom, unichar;






    switch (step->intvalue) {

    case f_position:
        XPATH_ARITYCHECK(step,0,errMsg);
        if (*docOrder) {
            rsSetInt (result, position+1);
................................................................................

        leftStr = xpathFuncString (&leftResult );
        xpathRSFree( &leftResult );
        DBG(fprintf(stderr, "leftStr='%s'\n", leftStr);)
        if      (step->intvalue == f_string)
            rsSetString (result, leftStr);
        else if (step->intvalue == f_stringLength) {



            pto = leftStr;
            len = 0;
            while (*pto) {
                len++;
                i = UTF8_CHAR_LEN (*pto);
                if (!i) {
                    FREE (leftStr);
                    *errMsg = tdomstrdup("Can only handle UTF-8 chars up "
                                         "to 4 bytes length");
                    return XPATH_I18N_ERR;
                }
                pto += i;
            }
            rsSetInt (result, len);

        }
        else {
            pwhite = 1;
            pfrom = pto = leftStr;
            while (*pfrom) {
                switch (*pfrom) {
                case ' ' : case '\n': case '\r': case '\t':
................................................................................
    case f_false:
        XPATH_ARITYCHECK(step,0,errMsg);
        rsSetBool (result, 0);
        break;

    case f_id:
        XPATH_ARITYCHECK(step,1,errMsg);
        if (ctxNode->nodeType == ATTRIBUTE_NODE) {
            ids = ((domAttrNode*)ctxNode)->parentNode->ownerDocument->ids;
        } else {
            ids = ctxNode->ownerDocument->ids;
        }
        if (!ids) {
            break;
        }
        xpathRSInit (&leftResult);
        rc = xpathEvalStep( step->child, ctxNode, exprContext, position,
                            nodeList, cbs, &leftResult, docOrder, errMsg);
        if (rc) {
            xpathRSFree( &leftResult );
................................................................................
        if (leftResult.type == EmptyResult) {
            xpathRSFree (&leftResult);
            return XPATH_OK;
        }
        if (leftResult.type == xNodeSetResult) {
            for (i=0; i < leftResult.nr_nodes; i++) {
                leftStr = xpathFuncStringForNode (leftResult.nodes[i]);
                entryPtr = Tcl_FindHashEntry (ids, leftStr);

                if (entryPtr) {
                    node = (domNode*) Tcl_GetHashValue (entryPtr);
                    /* Don't report nodes out of the fragment list */
                    if (node->parentNode != NULL ||
                        (node == node->ownerDocument->documentElement)) {
                        rsAddNode (result, node);
                    }
................................................................................
                switch (*pto) {
                case ' ' : case '\n': case '\r': case '\t':
                    if (pwhite) {
                        pto++;
                        continue;
                    }
                    *pto = '\0';
                    entryPtr = Tcl_FindHashEntry (ids, pfrom);

                    if (entryPtr) {
                        node = (domNode*) Tcl_GetHashValue (entryPtr);
                        /* Don't report nodes out of the fragment list */
                        if (node->parentNode != NULL ||
                            (node == node->ownerDocument->documentElement)) {
                            rsAddNode (result, node);
                        }
................................................................................
                        pfrom = pto;
                        pwhite = 0;
                    }
                    pto++;
                }
            }
            if (!pwhite) {
                entryPtr = Tcl_FindHashEntry (ids, pfrom);

                if (entryPtr) {
                    node = (domNode*) Tcl_GetHashValue (entryPtr);
                    /* Don't report nodes out of the fragment list */
                    if (node->parentNode != NULL ||
                        (node == node->ownerDocument->documentElement)) {
                        rsAddNode (result, node);
                    }
................................................................................
                            nodeList, cbs, &leftResult, docOrder, errMsg);
        if (rc) {
            xpathRSFree (&leftResult);
            return rc;
        }
        leftStr = xpathFuncString (&leftResult);
        if (ctxNode->nodeType != ELEMENT_NODE) {
            if (ctxNode->nodeType == ATTRIBUTE_NODE) {
                node = ((domAttrNode*)ctxNode)->parentNode;
            } else {
                node = ctxNode->parentNode;
            }
        } else {
            node = ctxNode;
        }
        while (node) {
            attr = node->firstAttr;
            while (attr) {
                if (strcmp (attr->nodeName, "xml:lang")!=0) {
................................................................................
                    rsSetString (result, "");
                    return XPATH_OK;
                }
                from = 0;
            }
        } else {
            if (from < 0) from = 0;



            len = INT_MAX;

        }


















        pfrom = leftStr;
        while (*pfrom && (from > 0)) {
            i = UTF8_CHAR_LEN (*pfrom);
            if (!i) {
                FREE (leftStr);
                *errMsg = tdomstrdup("Can only handle UTF-8 chars up "
                                     "to 4 bytes length");
                return XPATH_I18N_ERR;
            }
            pfrom += i;
            from--;
        }
        if (len < INT_MAX) {
            pto = pfrom;
            while (*pto && (len > 0)) {
                i = UTF8_CHAR_LEN (*pto);
                if (!i) {
                    FREE (leftStr);
                    *errMsg = tdomstrdup("Can only handle UTF-8 chars up "
                                         "to 4 bytes length");
                    return XPATH_I18N_ERR;
                }
                pto += i;
                len--;
            }
            *pto = '\0';
        }
        rsSetString (result, pfrom);

        FREE(leftStr);
        break;

    case f_translate:
        XPATH_ARITYCHECK(step,3,errMsg);
        xpathRSInit (&leftResult);
        savedDocOrder = *docOrder;
................................................................................
        CHECK_RC;
        *docOrder = savedDocOrder;
        leftStr    = xpathFuncString( &leftResult    );
        rightStr   = xpathFuncString( &rightResult   );
        replaceStr = xpathFuncString( &replaceResult );




















        Tcl_DStringInit (&tstr);
        Tcl_DStringInit (&tfrom);
        Tcl_DStringInit (&tto);
        Tcl_DStringInit (&tresult);

        Tcl_UtfToUniCharDString (leftStr, -1, &tstr);
        Tcl_UtfToUniCharDString (rightStr, -1, &tfrom);
................................................................................
            upfrom++;
        }
        rsSetString (result, Tcl_DStringValue (&tresult));
        Tcl_DStringFree (&tstr);
        Tcl_DStringFree (&tfrom);
        Tcl_DStringFree (&tto);
        Tcl_DStringFree (&tresult);


        xpathRSFree( &replaceResult );
        xpathRSFree( &rightResult   );
        xpathRSFree( &leftResult    );
        FREE(leftStr); FREE(rightStr); FREE(replaceStr);
        break;

................................................................................
                i = 0;
                attr = node->firstAttr;
                while (attr) {
                    if ((domNode*)attr == leftResult.nodes[0]) break;
                    attr = attr->nextSibling;
                    i++;
                }
                sprintf(tmp,"id%p-%d", (void *)node, i);
            } else {
                sprintf(tmp,"id%p", (void *)leftResult.nodes[0]);
            }
            rsSetString (result, tmp);
        } else

        if (step->intvalue == f_namespaceUri) {
            if (leftResult.type != xNodeSetResult) {
                *errMsg = tdomstrdup("namespace-uri() requires a node set!");
................................................................................
            while (child && (count < step->intvalue)) {
                DBG(fprintf(stderr, "AxisChild: child '%s' domNode%p \n", 
                            child->nodeName, child);)
                if (xpathNodeTest(child, step)) {
                    DBG(fprintf(stderr, 
                      "AxisChild: after node taking child '%s' domNode%p \n",
                                child->nodeName, child);)
                    checkRsAddNode( result, child);
                    count++;
                }
                child = child->nextSibling;
            }
        } else {
            while (child) {
                DBG(fprintf(stderr, "AxisChild: child '%s' domNode%p \n",
                            child->nodeName, child);)
                if (xpathNodeTest(child, step)) {
                    DBG(fprintf(stderr,
                      "AxisChild: after node taking child '%s' domNode%p \n",
                                child->nodeName, child);)
                    checkRsAddNode( result, child);
                }
                child = child->nextSibling;
            }
        }
        DBG( fprintf(stderr,"AxisChild result:\n");
             rsPrint(result);
        )
        break;

    case SlashSlash:



        xpathRSInit (&tResult);
        node = ctxNode->firstChild;
        while (node) {
            if (node->nodeType == ELEMENT_NODE) {
                rc = xpathEvalStep (step, node, exprContext, position,
                                    nodeList, cbs, result, docOrder, errMsg);
                if (rc) {
                    xpathRSFree (&tResult);
                    return rc;
                }
            }
            if (xpathNodeTest(node, step)) {
                rsAddNodeFast( &tResult, node);




            }
            node = node->nextSibling;
        }















        rc = xpathEvalPredicate (step->next, exprContext, result, &tResult,
                                  cbs, docOrder, errMsg);
        xpathRSFree (&tResult);
        CHECK_RC;
        break;

    case AxisDescendant:
................................................................................
            step->type = SlashSlash;
            rc = xpathEvalStep (step, ctxNode, exprContext, position, 
                                nodeList, cbs, result, docOrder, errMsg);
            step->type = savedAstType;
            CHECK_RC;
            break;
        }
        /* without following Pred step, // is the same as 
           AxisDescendantOrSelf, fall throu */

    case AxisDescendantLit:
    case AxisDescendantOrSelfLit:
        *docOrder = 1;
        if (step->intvalue
            && (step->type == AxisDescendantLit 
................................................................................
        }
        break;

    case AxisSelf:
        *docOrder = 1;
        DBG(fprintf(stderr, "AxisSelf :: \n");)
        if (xpathNodeTest(ctxNode, step)) {
            rsAddNode( result, ctxNode);
        }
        break;

    case GetContextNode:
        rsAddNode( result, ctxNode);
        break;

    case AxisAttribute:
        *docOrder = 1;
        DBG(fprintf(stderr, "AxisAttribute %s \n", step->child->strvalue);)
        if (ctxNode->nodeType != ELEMENT_NODE) return XPATH_OK;
        if (step->child->type == IsElement) {
................................................................................
            step->child->type = IsAttr;
        }
        if (step->child->type == IsAttr) {
            if (strcmp(step->child->strvalue, "*")==0) {
                attr = ctxNode->firstAttr;
                while (attr) {
                    if (!(attr->nodeFlags & IS_NS_NODE)) {
                        checkRsAddNode (result, (domNode *)attr);
                    }
                    attr = attr->nextSibling;
                }
            } else {
                attr = ctxNode->firstAttr;
                while (attr && (attr->nodeFlags & IS_NS_NODE))
                    attr = attr->nextSibling;
                while (attr) {
                    if (xpathNodeTest( (domNode*)attr, step)) {
                        checkRsAddNode (result, (domNode *)attr);
                    }
                    attr = attr->nextSibling;
                }
            }
        } else
        if (step->child->type == IsNSAttr) {
            attr = ctxNode->firstAttr;
            while (attr && (attr->nodeFlags & IS_NS_NODE))
                attr = attr->nextSibling;
            while (attr) {
                if (xpathNodeTest ( (domNode*)attr, step)) {
                    checkRsAddNode (result, (domNode *)attr);
                }
                attr = attr->nextSibling;
            }
        }
        break;

    case AxisParent:
................................................................................
        break;

    case AxisAncestor:
    case AxisAncestorOrSelf:
        *docOrder = 0;
        xpathRSInit (&tResult);
        if (step->type == AxisAncestorOrSelf) {
            if (xpathNodeTest(ctxNode, step)) {
                rsAddNodeFast(&tResult, ctxNode);
            }
        }
        if (ctxNode->nodeType == ATTRIBUTE_NODE) {
            ctxNode = ((domAttrNode *)ctxNode)->parentNode;
            if (xpathNodeTest(ctxNode, step)) {
                rsAddNodeFast(&tResult, ctxNode);
            }
        }
        startingNode = ctxNode;
        while (ctxNode->parentNode) {
            ctxNode = ctxNode->parentNode;
            if (xpathNodeTest(ctxNode, step)) {
                rsAddNodeFast(&tResult, ctxNode);
            }
        }
        if (startingNode != ctxNode->ownerDocument->rootNode) {
            if (xpathNodeTest (ctxNode->ownerDocument->rootNode, step)) {
                rsAddNodeFast (&tResult, ctxNode->ownerDocument->rootNode);
            }
        }
        for (i = tResult.nr_nodes - 1; i >= 0;  i--) {
................................................................................
                rc = 0;
                for (i = 0; i < result->nr_nodes; i++) {
                    if (strcmp (attr->nodeName, ((domAttrNode*)result->nodes[i])->nodeName)==0) {
                        rc = 1; break;
                    }
                }
                if (rc) {attr = attr->nextSibling; continue;}
                checkRsAddNode (result, (domNode *)attr);
                attr = attr->nextSibling;
            }

            if (node == node->ownerDocument->documentElement) {
                if (ctxNode != ctxNode->ownerDocument->rootNode) {
                    node = ctxNode->ownerDocument->rootNode;
                } else {
................................................................................
        break;

    case Real:
        rsSetReal (result, step->realvalue);
        break;

    case Add:
    case Subtract:
    case Mult:
    case Div:
    case Mod:
        xpathRSInit (&leftResult);
        xpathRSInit (&rightResult);

        savedDocOrder = *docOrder;
................................................................................
            dRight = xpathFuncNumber(&rightResult, &NaN1);
        }
        if (NaN || NaN1) {
            if ((NaN == 2) || (NaN1 == 2)) {
                rsSetNaN (result);
            } else {
                switch (step->type) {
                case Subtract:
                    NaN1 = -1 * NaN1;
                    /* fall throu */   
                case Add:
                    if (NaN == NaN1) {
                        if (NaN == 1) rsSetInf (result);
                        else          rsSetNInf (result);
                    } else if ((rc = NaN + NaN1) != 0) {
................................................................................
            }
            xpathRSFree (&rightResult);
            xpathRSFree (&leftResult);
            return XPATH_OK;
        }
        switch (step->type) {
        case Add:       rsSetReal (result, dLeft + dRight); break;
        case Subtract: rsSetReal (result, dLeft - dRight); break;
        case Mult:      rsSetReal (result, dLeft * dRight); break;
        case Div:
            if (dRight == 0.0) {
                if (dLeft == 0.0) {
                    rsSetNaN (result);
                } else {
                    if (dLeft > 0) {
................................................................................
                    }
                }
            } else {
                rsSetReal (result, dLeft / dRight);
            }
            break;
        case Mod:
            if ((int)dRight == 0) {
                rsSetNaN (result);
            } else {
                rsSetInt  (result, ((int)dLeft) % ((int)dRight));
            }
            break;
        default:        break;
        }
................................................................................
                    /* The real value of a node could never be inf/-inf */
                    /* And NaN is always != NaN (and != everything else) */
                    if (step->type == Equal) res = 0;
                    else                     res = 1;
                    break;
                }
                for (i=0; i < pleftResult->nr_nodes; i++) {
                    leftStr = xpathFuncStringForNode (pleftResult->nodes[i]);
                    dLeft = xpathStringToNumber (leftStr, &NaN);
                    FREE(leftStr);
                    if (NaN) continue;
                    if (step->type == Equal) res = (dLeft == dRight);
                    else                     res = (dLeft != dRight);
                    if (res) break;
                }
                break;
            case NaNResult:
................................................................................
        CHECK_RC;
        *docOrder = savedDocOrder;

        DBG( fprintf(stderr,"right:\n");
             rsPrint(&rightResult);
        )
        res = 0;

        if (   leftResult.type == xNodeSetResult
            || rightResult.type == xNodeSetResult) {
            if (leftResult.type == xNodeSetResult) {
                pleftResult = &leftResult;
                prightResult = &rightResult;
                switchResult = 0;
            } else {
                pleftResult = &rightResult;
                prightResult = &leftResult;
                switchResult = 1;
            }

            switch (prightResult->type) {
            case EmptyResult:
                res = 0;
                break;
            case xNodeSetResult:
                JDBG( fprintf(stderr,"\nleft+right result:\n");
                     rsPrint(pleftResult);
                     rsPrint(prightResult);
                )
                for (i=0; i < pleftResult->nr_nodes; i++) {
                    leftStr = xpathFuncStringForNode (pleftResult->nodes[i]);
                    dLeft = xpathStringToNumber (leftStr, &NaN);
                    FREE(leftStr);
                    if (NaN) continue;
                    for (j=0; j < prightResult->nr_nodes; j++) {
                        rightStr = xpathFuncStringForNode (prightResult->nodes[j]);
                        dRight = xpathStringToNumber (rightStr, &NaN);
                        FREE(rightStr);
                        if (NaN)  continue;
                        if (switchResult) {
                            dTmp   = dLeft;
                            dLeft  = dRight;
                            dRight = dTmp;
                        }
                        if      (step->type == Less)     res = (dLeft < dRight);
................................................................................

                        if (res) break;
                    }
                    if (res) break;
                }
                break;
            case BoolResult:
                /* pleftResult is a non-empty nodeset, therefor: */
                dLeft = 1.0;
                dRight = xpathFuncNumber (prightResult, &NaN);
                if (NaN) break;
                if      (step->type == Less)     res = (dLeft < dRight);
                else if (step->type == LessOrEq) res = (dLeft <= dRight);
                else if (step->type == Greater)  res = (dLeft >  dRight);
                else                             res = (dLeft >= dRight);
................................................................................
                    if (NaN == 2) break;
#ifdef DBL_MAX                    
                    if (NaN == 1) dRight = DBL_MAX;
                    else          dRight = -DBL_MAX;
#endif
                }
                for (i=0; i < pleftResult->nr_nodes; i++) {
                    leftStr = xpathFuncStringForNode (pleftResult->nodes[i]);
                    dLeft = xpathStringToNumber (leftStr, &NaN);
                    FREE (leftStr);
                    if (NaN) continue;
                    if (switchResult) {
                        dTmp   = dLeft;
                        dLeft  = dRight;
                        dRight = dTmp;
                    }
                    if      (step->type == Less)     res = (dLeft < dRight);
................................................................................
            rc = xpathEvalStep( step->child, stepResult->nodes[i],
                                exprContext, i, stepResult, cbs, &predResult,
                                docOrder, errMsg);
            CHECK_RC;
            *docOrder = savedDocOrder;
            DBG( fprintf(stderr, "after eval for Predicate: \n"); )
            DBG( rsPrint( &predResult); )

            if (predResult.type == RealResult) {
                predResult.type = IntResult;
                predResult.intvalue = xpathRound(predResult.realvalue);
            }
            if (predResult.type == IntResult) {
                if (predResult.intvalue < 0) {
                    predResult.intvalue = 
................................................................................
    char            ** errMsg,
    xpathResultSet   * result
)
{
    xpathResultSet nodeList;
    int            rc, hnew = 1, docOrder = 1;
    ast            t;
    Tcl_HashEntry *h = NULL;

    *errMsg = NULL;
    if (cache) {
        h = Tcl_CreateHashEntry (cache, xpath, &hnew);
    }
    if (hnew) {
        rc = xpathParse(xpath, exprContext, XPATH_EXPR, prefixMappings,
                        parseVarCB, &t, errMsg);

        if (rc) {
            if (h != NULL) {
                Tcl_DeleteHashEntry(h);
            }
            return rc;
        }
        if (cache) {
            Tcl_SetHashValue(h, t);
        }
    } else {
        t = (ast)Tcl_GetHashValue(h);
    }
    
................................................................................
                    if (nodeToMatch->nodeType != ELEMENT_NODE) {
                        xpathRSFree (&nodeList); return 0;
                    }
                    if (nodeToMatch == nodeToMatch->ownerDocument->rootNode) {
                        xpathRSFree (&nodeList); return 0;
                    }
                    if ((step->child->strvalue[0] != '*') ||
                        (step->child->strvalue[1] != '\0') ||
                        (step->child->intvalue != 0))
                    {
                        if (nodeToMatch->namespace) return 0;
                        if (strcmp(nodeToMatch->nodeName, step->child->strvalue)!=0) {
                            xpathRSFree (&nodeList); return 0;
                        }
                    }
                    break;
................................................................................
                if (nodeToMatch->nodeType != ELEMENT_NODE) {
                    xpathRSFree (&nodeList); return 0;
                }
                if (nodeToMatch == nodeToMatch->ownerDocument->rootNode) {
                    xpathRSFree (&nodeList); return 0;
                }
                if ((step->strvalue[0] != '*') ||
                    (step->strvalue[1] != '\0') ||
                    (step->intvalue != 0))
                {
                    if (nodeToMatch->namespace) return 0;
                    if (strcmp(nodeToMatch->nodeName, step->strvalue)!=0) {
                        xpathRSFree (&nodeList); return 0;
                    }
                }
                break;
................................................................................
{
    if (!steps) return 0.0;

    DBG(printAst(0, steps);)

    if (steps->next == NULL) {
        if (steps->type == IsElement) {
            if (strcmp(steps->strvalue, "*")==0 && steps->intvalue==0) {
                return -0.5;
            } else {
                return 0.0;
            }
        } else
        if (steps->type == IsFQElement) {
            return 0.0;
................................................................................
|   nodeToXPath  -  returns a XPath addressing exactly the given node
|
\---------------------------------------------------------------------------*/
static void nodeToXPath (
    domNode  * node,
    char    ** xpath,
    int      * xpathLen,
    int      * xpathAllocated,
    int        legacy
)
{
    domNode *parent, *child;
    char    step[200], *nTest;
    int     sameNodes, nodeIndex, len;


    parent = node->parentNode;
    if (parent == NULL) {
        parent = node->ownerDocument->rootNode;
    } else {
        nodeToXPath (parent, xpath, xpathLen, xpathAllocated, legacy);
    }

    step[0] = '\0';
    switch (node->nodeType) {

    case ELEMENT_NODE:
        nodeIndex = 0;
        sameNodes = 0;
        child = parent->firstChild;
        if (node->namespace && !legacy) {
            while (child) {
                if (child->nodeType == ELEMENT_NODE) {
                    sameNodes++;
                    if (node == child) {
                        nodeIndex = sameNodes;
                        if (sameNodes > 1) break;
                    }
                }
                child = child->nextSibling;
            }
            if (sameNodes == 1) {
                sprintf(step, "/*");
            } else {
                sprintf(step, "/*[%d]", nodeIndex);
            }
        } else {
            while (child) {
                if (strcmp(child->nodeName, node->nodeName)==0) {
                    sameNodes++;
                    if (node == child) nodeIndex = sameNodes;
                    if ((nodeIndex != 0) && (sameNodes > 2)) break;
                }
                child = child->nextSibling;
            }
            if (sameNodes == 1) {
                sprintf(step, "/%s", node->nodeName);
            } else {
                sprintf(step, "/%s[%d]", node->nodeName, nodeIndex);
            }
        }
        break;

    case TEXT_NODE:
    case COMMENT_NODE:
    case PROCESSING_INSTRUCTION_NODE:
        nodeIndex = 0;
................................................................................


/*----------------------------------------------------------------------------
|   xpathNodeToXPath
|
\---------------------------------------------------------------------------*/
char * xpathNodeToXPath (
    domNode *node,
    int      legacy
)
{
    char  * xpath;
    int     xpathLen, xpathAllocated;


    xpathAllocated = 100;
    xpathLen       = 0;
    xpath          = MALLOC(xpathAllocated + 1);

    nodeToXPath (node, &xpath, &xpathLen, &xpathAllocated, legacy);

    return xpath;

} /* xpathNodeToXPath */

Changes to generic/domxpath.h.

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
..
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|   Types for abstract syntax trees
|
\---------------------------------------------------------------------------*/
typedef enum {
    Int, Real, Mult, Div, Mod, UnaryMinus, IsNSElement,
    IsNode, IsComment, IsText, IsPI, IsSpecificPI, IsElement,
    IsFQElement, GetVar, GetFQVar, Literal, ExecFunction, Pred,
    EvalSteps, SelectRoot, CombineSets, Add, Substract, Less,
    LessOrEq, Greater, GreaterOrEq, Equal,  NotEqual, And, Or,
    IsNSAttr, IsAttr, AxisAncestor, AxisAncestorOrSelf, 
    AxisAttribute, AxisChild,
    AxisDescendant, AxisDescendantOrSelf, AxisFollowing,
    AxisFollowingSibling, AxisNamespace, AxisParent,
    AxisPreceding, AxisPrecedingSibling, AxisSelf,
    GetContextNode, GetParentNode, AxisDescendantOrSelfLit,
................................................................................


typedef struct astElem {
    astType         type;
    struct astElem *child;
    struct astElem *next;
    char           *strvalue;
    int             intvalue;
    double          realvalue;
} astElem;

typedef astElem *ast;


/*----------------------------------------------------------------------------
................................................................................


typedef struct xpathResultSet {

    xpathResultType type;
    char           *string;
    int             string_len;
    int             intvalue;
    double          realvalue;          
    domNode       **nodes;
    int             nr_nodes;
    int             allocated;

} xpathResultSet;

................................................................................
double xpathFuncNumber   (xpathResultSet *rs, int *NaN);
char * xpathFuncString   (xpathResultSet *rs); 
char * xpathFuncStringForNode (domNode *node);
int    xpathRound        (double r);

char * xpathGetStringValue (domNode *node, int *strLen);

char * xpathNodeToXPath  (domNode *node);
    
void rsSetBool      ( xpathResultSet *rs, int          i    );
void rsSetInt       ( xpathResultSet *rs, int          i    );
void rsSetReal      ( xpathResultSet *rs, double       d    );
void rsSetString    ( xpathResultSet *rs, const char  *s    );
void rsAddNode      ( xpathResultSet *rs, domNode     *node );
void rsAddNodeFast  ( xpathResultSet *rs, domNode     *node );
void rsCopy         ( xpathResultSet *to, xpathResultSet *from );

/* This function is only used for debugging code */
void rsPrint        ( xpathResultSet *rs );

#endif








|







 







|







 







|







 







|

|
|











71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
..
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|   Types for abstract syntax trees
|
\---------------------------------------------------------------------------*/
typedef enum {
    Int, Real, Mult, Div, Mod, UnaryMinus, IsNSElement,
    IsNode, IsComment, IsText, IsPI, IsSpecificPI, IsElement,
    IsFQElement, GetVar, GetFQVar, Literal, ExecFunction, Pred,
    EvalSteps, SelectRoot, CombineSets, Add, Subtract, Less,
    LessOrEq, Greater, GreaterOrEq, Equal,  NotEqual, And, Or,
    IsNSAttr, IsAttr, AxisAncestor, AxisAncestorOrSelf, 
    AxisAttribute, AxisChild,
    AxisDescendant, AxisDescendantOrSelf, AxisFollowing,
    AxisFollowingSibling, AxisNamespace, AxisParent,
    AxisPreceding, AxisPrecedingSibling, AxisSelf,
    GetContextNode, GetParentNode, AxisDescendantOrSelfLit,
................................................................................


typedef struct astElem {
    astType         type;
    struct astElem *child;
    struct astElem *next;
    char           *strvalue;
    long            intvalue;
    double          realvalue;
} astElem;

typedef astElem *ast;


/*----------------------------------------------------------------------------
................................................................................


typedef struct xpathResultSet {

    xpathResultType type;
    char           *string;
    int             string_len;
    long            intvalue;
    double          realvalue;          
    domNode       **nodes;
    int             nr_nodes;
    int             allocated;

} xpathResultSet;

................................................................................
double xpathFuncNumber   (xpathResultSet *rs, int *NaN);
char * xpathFuncString   (xpathResultSet *rs); 
char * xpathFuncStringForNode (domNode *node);
int    xpathRound        (double r);

char * xpathGetStringValue (domNode *node, int *strLen);

char * xpathNodeToXPath  (domNode *node, int legacy);
    
void rsSetBool      ( xpathResultSet *rs, long         i    );
void rsSetInt       ( xpathResultSet *rs, long         i    );
void rsSetReal      ( xpathResultSet *rs, double       d    );
void rsSetString    ( xpathResultSet *rs, const char  *s    );
void rsAddNode      ( xpathResultSet *rs, domNode     *node );
void rsAddNodeFast  ( xpathResultSet *rs, domNode     *node );
void rsCopy         ( xpathResultSet *to, xpathResultSet *from );

/* This function is only used for debugging code */
void rsPrint        ( xpathResultSet *rs );

#endif

Changes to generic/domxslt.c.

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
..
64
65
66
67
68
69
70

71
72
73
74





75
76
77
78
79
80
81
82




83
84
85
86
87
88
89
...
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
...
356
357
358
359
360
361
362


363
364
365
366
367
368
369
...
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
...
530
531
532
533
534
535
536

537
538
539
540
541
542
543
544
...
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
...
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
...
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
...
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
...
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
....
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
....
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
....
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
....
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730

1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
....
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
....
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
....
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
....
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
....
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
....
2943
2944
2945
2946
2947
2948
2949

2950

2951
2952
2953
2954
2955
2956
2957
....
3170
3171
3172
3173
3174
3175
3176
3177


3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
....
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
....
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
....
3279
3280
3281
3282
3283
3284
3285








3286
3287
3288
3289
3290
3291
3292





3293
3294
3295
3296






3297
3298
3299
3300
3301
3302
3303
....
3466
3467
3468
3469
3470
3471
3472
3473


3474
3475
3476
3477
3478
3479
3480
....
3546
3547
3548
3549
3550
3551
3552
3553




3554
3555
3556
3557
3558
3559
3560
....
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
....
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
....
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
....
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
....
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
....
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
....
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
....
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
....
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
....
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831




4832





4833
4834
4835
4836
4837
4838
4839
4840
....
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
....
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
....
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
....
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
....
5456
5457
5458
5459
5460
5461
5462






5463
5464
5465
5466
5467
5468
5469
....
5487
5488
5489
5490
5491
5492
5493

5494
5495
5496
5497
5498
5499
5500
....
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
....
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
....
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
....
5851
5852
5853
5854
5855
5856
5857

5858
5859
5860

5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871





5872
5873
5874
5875
5876
5877
5878
....
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
....
5955
5956
5957
5958
5959
5960
5961
5962

5963
5964
5965
5966
5967
5968



5969
5970
5971
5972
5973
5974
5975
5976
....
6238
6239
6240
6241
6242
6243
6244

6245
6246
6247
6248
6249
6250
6251
....
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
....
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
....
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
....
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
....
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
....
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
....
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
....
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
....
7391
7392
7393
7394
7395
7396
7397

7398
7399
7400
7401
7402
7403
7404
....
7417
7418
7419
7420
7421
7422
7423


7424
7425
7426
7427
7428
7429
7430
7431
....
7594
7595
7596
7597
7598
7599
7600

7601
7602
7603
7604
7605
7606
7607
7608
7609


/*----------------------------------------------------------------------------
|   Includes
|
\---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <limits.h>
#include <ctype.h>
#include <locale.h>
#include <dom.h>
#include <domxpath.h>
#include <domxslt.h>
#include <tcl.h>         /* for hash tables */

/*----------------------------------------------------------------------------
................................................................................
|   Defines
|
\---------------------------------------------------------------------------*/
#define XSLT_NAMESPACE  "http://www.w3.org/1999/XSL/Transform"
#define INITIAL_SIZE_FOR_KEYSETS 10



/*----------------------------------------------------------------------------
|   Macros
|
\---------------------------------------------------------------------------*/





#define DBG(x)              
#define TRACE(x)            DBG(fprintf(stderr,(x)))
#define TRACE1(x,a)         DBG(fprintf(stderr,(x),(a)))
#define TRACE2(x,a,b)       DBG(fprintf(stderr,(x),(a),(b)))
#define TRACE3(x,a,b,c)     DBG(fprintf(stderr,(x),(a),(b),(c)))
#define TRACE4(x,a,b,c,d)   DBG(fprintf(stderr,(x),(a),(b),(c),(d)))
#define TRACE5(x,a,b,c,d,e) DBG(fprintf(stderr,(x),(a),(b),(c),(d),(e)))





#define CHECK_RC            if (rc < 0) return rc
#define CHECK_RC1(x)        if (rc < 0) {FREE((char*)(x)); return rc;}
#define SET_TAG(t,n,s,v)    if (strcmp(n,s)==0) { t->info = v; return v; }
#define SETSCOPESTART       xs->varFramesStack[xs->varFramesStackPtr].stop=1
#define SETPARAMDEF         xs->varFramesStack[xs->varFramesStackPtr].stop=2

#if defined(_MSC_VER)
................................................................................
|
\-------------------------------------------------------------------------*/
typedef struct xsltAttrSet {

    const char * name;
    const char * uri;
    domNode    * content;


    struct xsltAttrSet *next;

} xsltAttrSet;

/*--------------------------------------------------------------------------
|   xsltNodeSet
|
................................................................................

/*--------------------------------------------------------------------------
|   xsltDecimalFormat
|
\-------------------------------------------------------------------------*/
typedef struct xsltDecimalFormat
{
#if TclOnly8Bits
    char   * name;
    char   * uri;
    char     decimalSeparator;
    char     groupingSeparator;
    char   * infinity;
    char     minusSign;
    char   * NaN;
    char     percent;
    char     zeroDigit;
    char     digit;
    char     patternSeparator;
#else 
    char        * name;
    char        * uri;
    Tcl_UniChar   decimalSeparator;
    Tcl_UniChar   groupingSeparator;
    char        * infinity;
    Tcl_UniChar   minusSign;
    char        * NaN;
    Tcl_UniChar   percent;
    Tcl_UniChar   perMille;
    Tcl_UniChar   zeroDigit;
    Tcl_UniChar   digit;
    Tcl_UniChar   patternSeparator;
#endif /* TclOnly8Bits */

    struct xsltDecimalFormat * next;

} xsltDecimalFormat;


/*--------------------------------------------------------------------------
................................................................................
/*--------------------------------------------------------------------------
|   xsltState
|
\-------------------------------------------------------------------------*/
typedef struct {

    xsltTemplate      * templates;


    Tcl_HashTable       namedTemplates;
    Tcl_HashTable       isElementTpls;
    xsltWSInfo          wsInfo;
    domNode           * xmlRootNode;
    domDocInfo          doctype;
    int                 indentOutput;
    domDocument       * resultDoc;
................................................................................

static domDocument * getExternalDocument (Tcl_Interp *interp, xsltState *xs,
                                          domDocument *xsltDoc, 
                                          const char *baseURI,
                                          const char *href, int isStylesheet,
                                          int fixedXMLSource, char **errMsg);


/*----------------------------------------------------------------------------
|   printXML
|
\---------------------------------------------------------------------------*/
static void printXML (domNode *node, int level, int maxlevel) {

    domTextNode *tnode;
................................................................................
            fprintf(stderr, "%s?>\n", tmp);
        }
        node = node->nextSibling;
        n++;
        if (n>8) { fprintf(stderr, "...\n"); return; }
    }
}

        
/*----------------------------------------------------------------------------
|   reportError
|
\---------------------------------------------------------------------------*/
static void
reportError (
    domNode * node,
................................................................................
    domDocument * extDocument;
    int           found;

    DBG(
        fprintf (stderr, "xsltAddExternalDocument: baseURI '%s'\n", baseURI);
        fprintf (stderr, "xsltAddExternalDocument: systemID '%s'\n", str);
    )

    found = 0;
    sdoc = xs->subDocs;
    if (str) {
        while (sdoc) {
            if (!sdoc->isStylesheet
                && sdoc->baseURI 
                && strcmp (sdoc->baseURI, str)==0) {
................................................................................
                break;
            }
            sdoc = sdoc->next;
        }
    }
    if (!found) {
        if (!xs->xsltDoc->extResolver) {
            *errMsg = tdomstrdup("need resolver Script to include Stylesheet! "
                                 "(use \"-externalentitycommand\")");
            return -1;
        }
        extDocument = getExternalDocument (
                         (Tcl_Interp*)xs->orig_funcClientData,
                         xs, xs->xsltDoc, baseURI, str, 0, fixedXMLSource,
                         errMsg);
        if (extDocument) {
................................................................................
        Tcl_SetHashValue (h, format);
        format->formatStr = p = Tcl_GetHashKey (&(xs->formats), h);
    }
    while (*p) {
        clen = UTF8_CHAR_LEN(*p);
        if (!clen) {
            reportError (xs->currentXSLTNode, "xsl:number: UTF-8 form of"
                         " character longer than 3 Byte", errMsg);
            return NULL;
        }
        if (clen > 1) {
            /* hack: skip over multibyte chars - this may be wrong */
            format->prologLen += clen;
            p += clen;
            continue;
................................................................................
    p++;                                         \
    if (*p) {                                    \
        format->tokens[nrOfTokens].sepStart = p; \
    }                                            \
    while (*p) {                                 \
        clen = UTF8_CHAR_LEN(*p);                \
        if (!clen) {                             \
            reportError (xs->currentXSLTNode, "xsl:number: UTF-8 form of character longer than 3 Byte", errMsg); \
            return NULL;                         \
        }                                        \
        if (clen > 1) {                          \
            /* hack: skip over multibyte chars - this may be wrong */ \
            format->tokens[nrOfTokens].sepLen += clen;  \
            p += clen;                           \
            continue;                            \
................................................................................
static void formatValue (
    xsltNumberFormat *f,
    int              *useFormatToken,
    int               value,
    Tcl_DString      *str,
    char             *groupingSeparator,
    long              groupingSize,
    int               addSeperater
)
{
    int         len, fulllen, gslen, upper = 0, e, m, b, i, z, v;
    char        tmp[80], *pt;
    Tcl_DString tmp1;
    static struct { char *digit; char *ldigit; int value; } RomanDigit[] = {
          { "M" , "m" , 1000, },
................................................................................
    default:
        sprintf (tmp, "%d", value);
        break;
    }
    len = strlen (tmp);
    Tcl_DStringAppend (str, tmp, len);
 appendSeperator:
    if (addSeperater) {
        if (f->tokens[*useFormatToken].sepStart) {
            Tcl_DStringAppend (str, f->tokens[*useFormatToken].sepStart,
                               f->tokens[*useFormatToken].sepLen);
            *useFormatToken += 1;
        } else {
            if (*useFormatToken > 0) {
                Tcl_DStringAppend (str, f->tokens[*useFormatToken-1].sepStart,
                                   f->tokens[*useFormatToken-1].sepLen);
            } else {
                /* insert default seperator '.' */
                Tcl_DStringAppend (str, ".", 1);
            }
        }
    }

    return;
}

/*----------------------------------------------------------------------------
|   xsltFormatNumber
|
\---------------------------------------------------------------------------*/
#if TclOnly8Bits
static int xsltFormatNumber (
    double              number,
    char              * formatStr,
    xsltDecimalFormat * df,
    char             ** resultStr,
    int               * resultLen,
    char             ** errMsg
)
{
    char *p, prefix[800], suffix[800], s[2400], n[800], f[800];
    char *negformat = NULL, save = '\0', save1;
    int i, l, zl, g, nHash, nZero, fHash, fZero, gLen, isNeg;
/*      struct lconv *lc = NULL;  */
    char wrongFormat[] = "Unable to interpret format pattern.";

    DBG(fprintf(stderr, "\nformatStr='%s' \n", formatStr);)
    if (number < 0.0) {
        isNeg = 1;
        number *= -1.0;
    } else {
        isNeg = 0;
    }
    p = formatStr;
    while (*p) {
        if (*p == df->patternSeparator) {
            *p = '\0';
            negformat = ++p;
            break;
        }
        p++;
    }
    /* Check for more than one patternSeparator in the formatStr */
    while (*p) {
        if (*p == df->patternSeparator) {
            *errMsg = tdomstrdup(wrongFormat);
            return -1;
        }
        p++;
    }
    p = formatStr;

    i = 0;
    while (*p 
           && (*p!=df->zeroDigit) 
           && (*p!=df->digit) 
           && (*p!=df->groupingSeparator) 
           && (*p!=df->decimalSeparator)) {
        if (i<79) { prefix[i++] = *p; }
        p++;
    }
    prefix[i] = '\0';
    nHash = nZero = fHash = fZero = 0;
    gLen = -2222;
    while (*p) {
             if (*p==df->digit) {
                 if (nZero) {*errMsg = tdomstrdup(wrongFormat); return -1;}
                 nHash++;}
        else if (*p==df->zeroDigit) { nZero++; }
        else if (*p==df->groupingSeparator) { gLen=-1; }
        else break;
        p++; gLen++;
    }
    if (*p && (*p==df->decimalSeparator)) {
        p++;
        while (*p && (*p==df->zeroDigit)) { p++; fZero++; }
        while (*p && (*p==df->digit)) { p++; fHash++; }
    }
    i = 0;
    while (*p) {
        if (i<79) { suffix[i++] = *p; }
        p++;
    }
    suffix[i] = '\0';
    if (save) *p = save;

    if (isNeg && negformat) {
        /* Only prefix and suffix are taken from the second format string */
        p++;
        i = 0;
        while (*p 
               && *p!=df->zeroDigit
               && *p!=df->digit 
               && *p!=df->groupingSeparator 
               && *p!=df->decimalSeparator) {
            if (i<79) { prefix[i++] = *p; }
            p++;
        }
        prefix[i] = '\0';
        while (*p 
               && ((*p==df->zeroDigit) 
                   || (*p==df->digit) 
                   || (*p==df->groupingSeparator) 
                   || (*p==df->decimalSeparator))) p++;
        i = 0;
        while (*p) {
            if (i<79) { suffix[i++] = *p; }
            p++;
        }
        suffix[i] = '\0';
    }

    if (isNeg) {
        if (negformat) {
            if (prefix[0]=='\0' && suffix[0]=='\0') {
                prefix[0] = df->minusSign;
                prefix[1] = '\0';
            }
        } else {
            i = 0;
            save = prefix[0];
            prefix[0] = df->minusSign;
            while (i < 79) {
                i++;
                if (save == '\0') {
                    prefix[i] = save;
                    break;
                }
                save1 = prefix[i];
                prefix[i] = save;
                save = save1;
            }
            if (i == 79) prefix[79] = '\0';
        }
    }
    if (prefix[0]=='\xc2' && prefix[1]=='\xa4') {
/*          lc = localeconv(); */
/*          if (strlen (lc->currency_symbol) > 79 */
/*              || lc->currency_symbol[0] == '\0') { */
            prefix[0] = '$';
            prefix[1] = '\0';
/*          } else { */
/*              strcpy (prefix, lc->currency_symbol); */
/*          } */
    }

    if (suffix[0] == df->percent) {
        number *= 100.0;
    } else 
    if (suffix[0]=='\xe2' && suffix[1]=='\x80' && suffix[2]=='\xb0') {
        number *= 1000.0;
    }
    
    if (fHash + fZero == 0) {
        i = (int) (number+0.5);
    } else {
        i = (int) number;
    }
    DBG(fprintf(stderr,"normal part nZero=%d i=%d glen=%d\n", nZero, i, gLen);)
    /* fill in grouping char */
    if (gLen > 0) {
        if (i < 0.0) {isNeg = 1; i *= -1;}
        else isNeg = 0;
        sprintf(s,"%0*d", nZero, i);
        l = strlen(s);
        /* if (l > (nHash+nZero)) { l = nHash+nZero; } */
        DBG(fprintf(stderr,"s='%s isNeg=%d'\n", s, isNeg);)
        zl = l + ((l-1) / gLen);
        DBG(fprintf(stderr, "l=%d zl=%d \n", l, zl);)
        n[zl--] = '\0';
        p = s + strlen(s) -1;
        g = 0;
        while (zl>=0) {
            g++;
            n[zl--] = *p--;
            if ((g == gLen) && (zl>=1)) {
                n[zl--] = df->groupingSeparator;
                g = 0;
            }
        }
        DBG(fprintf(stderr,"s='%s' --> n='%s'\n", s, n);)

    } else {
        sprintf(n,"%0*d", nZero, i);
        DBG(fprintf(stderr,"n='%s'\n", n);)
    }

    DBG(fprintf(stderr, "number=%f Hash=%d fZero=%d \n", number, fHash, fZero);)
    if ((fHash+fZero) > 0) {
        i = (int) number;
        /* format fraction part */
        if (number >= 0.0) {
            sprintf(f,"%0.*f", fZero+fHash, number -i);
        } else {
            sprintf(f,"%0.*f", fZero+fHash, -1.0 * (number -i) );
        }
        l = strlen(f);
        while (l>0 && fHash>0) {   /* strip not need 0's */
            if (f[l-1] == '0') {
                f[l-1]='\0'; l--; fHash--;
            } else {
                break;
            }
        }
        DBG(fprintf(stderr, "f='%s'\n", f);)
        sprintf(s,"%s%s%c%s%s", prefix, n, df->decimalSeparator, &(f[2]), suffix);
    } else {
        sprintf(s,"%s%s%s", prefix, n, suffix);
    }
    DBG(fprintf(stderr, "returning s='%s' \n\n", s);)
    *resultStr = tdomstrdup(s);
    *resultLen = strlen(s);
    return 0;
}

#else

static int addCurrencySymbol (
    Tcl_UniChar  *p,
    Tcl_UniChar  *result,
    int          *i
)
{
    Tcl_DString dStr;
................................................................................
    int               * resultLen,
    char             ** errMsg
)
{
    Tcl_UniChar prefix1[800], prefix2[800], suffix1[800], suffix2[800];
    Tcl_UniChar save = '\0', save1, t, *prefix, *suffix, n[800], f[800];
    Tcl_UniChar uniCharNull = '\0';
    char stmp[240], ftmp[80];
    char wrongFormat[] = "Unable to interpret format pattern.";
    int i, j, k, l, zl, g, nHash, nZero, fHash, fZero, gLen, isNeg;
    int prefixMinux, percentMul = 0, perMilleMul = 0;
    Tcl_DString  dStr, s;
    Tcl_UniChar *format, *negformat = NULL, *p, *p1;
    DBG(Tcl_DString dbStr;)

................................................................................
    }
    
    if (fHash + fZero == 0) {
        i = (int) (number+0.5);
    } else {
        i = (int) number;
        /* format fraction part */
        DBG(fprintf(stderr, "formating fraction part: '%f', fZero+fHash: '%d'\n",
                    number - i, fZero+fHash);)
        sprintf(ftmp,"%.*f", fZero+fHash, number -i);
        DBG(fprintf(stderr, "raw formated fraction part: '%s'\n", ftmp);)
        if (ftmp[0] == '1') {
            i++;
        }
    }
    
    DBG(fprintf(stderr,"normal part nZero=%d i=%d glen=%d\n", nZero, i, gLen);)
    /* fill in grouping char */
................................................................................
                Tcl_UniCharToUtfDString(
                    (Tcl_UniChar*)Tcl_DStringValue (&s),
                    Tcl_UniCharLen((Tcl_UniChar*)Tcl_DStringValue(&s)), &dStr
                    ));
        Tcl_DStringFree (&dbStr);
    )
    Tcl_DStringSetLength (&dStr, 0);
    *resultStr = tdomstrdup(
        Tcl_UniCharToUtfDString(
            (Tcl_UniChar*)Tcl_DStringValue (&s),
            Tcl_UniCharLen((Tcl_UniChar*)Tcl_DStringValue(&s)), &dStr
            )
        );

    Tcl_DStringFree (&dStr);
    Tcl_DStringFree (&s);
    *resultLen = strlen(*resultStr);
    return 0;

 xsltFormatNumberError:
    Tcl_DStringFree (&dStr);
    Tcl_DStringFree (&s);
    return -1;
}

#endif /* TclOnly8Bits */


static xsltNodeSet *
createXsltNodeSet () 
{
    xsltNodeSet * ns;

    ns = (xsltNodeSet *) MALLOC (sizeof(xsltNodeSet));
    ns->nodes = (domNode**)MALLOC(INITIAL_SIZE_FOR_KEYSETS * sizeof(domNode*));
    ns->allocated = INITIAL_SIZE_FOR_KEYSETS;
    ns->nr_nodes = 0;
................................................................................
            }
            kinfo = kinfo->next;
        }
        if ((node->nodeType == ELEMENT_NODE) && (node->firstAttr)) {
            node = (domNode*) node->firstAttr;
            continue;
        }
        if ((node->nodeType == ATTRIBUTE_NODE)) {
            if (((domAttrNode*)node)->nextSibling) {
                node = (domNode*) ((domAttrNode*)node)->nextSibling;
                continue;
            }
            node = ((domAttrNode*)node)->parentNode;
        }
        if ((node->nodeType == ELEMENT_NODE) && (node->firstChild)) {
................................................................................
    char      * strB,
    double      realA,
    double      realB,
    int       * greater
)
{
    int             rc;
#if TclOnly8Bits == 0
    char           *strAptr, *strBptr;
    int             lenA, lenB, len;
    Tcl_UniChar     unicharA, unicharB;
#endif

    *greater = 0;

    if (typeText) {

#if TclOnly8Bits
        /* TODO: this only works for 7 bit ASCII */
        rc = STRCASECMP(strA, strB);
        if (rc == 0) {
            rc = strcmp (strA, strB);
            if (!upperFirst) {
                rc *= -1;
            }
        }
DBG(   fprintf(stderr, "nodeGreater %d <-- strA='%s' strB='%s'\n", rc, strA, strB);)
#else
        lenA = Tcl_NumUtfChars (strA, -1);
        lenB = Tcl_NumUtfChars (strB, -1);
        len = (lenA < lenB ? lenA : lenB);
        rc = Tcl_UtfNcasecmp (strA, strB, len);
        if (rc == 0) {
            if (lenA > lenB) {
                rc = 1;
................................................................................
                    break;
                }
            }
            if (!upperFirst) {
                rc *= -1;
            }
        }
#endif
        if (asc) *greater = (rc > 0);
            else *greater = (rc < 0);

    } else {
DBG(   fprintf(stderr, "nodeGreater  realA='%f' realB='%f'\n",realA, realB);)
        if (IS_NAN (realA) || IS_NAN (realB)) {
            if (asc) {
................................................................................
            b    [i] = a   [lptr  ];
            posb [i] = posa[lptr  ];
            vstmp[i] = vs  [lptr  ];
            vdtmp[i] = vd  [lptr++];
        }
    }
    memcpy(a,    b,     size*sizeof(domNode*));
    memcpy(posa, posb,  size*sizeof(int*));
    memcpy(vs,   vstmp, size*sizeof(char*));
    memcpy(vd,   vdtmp, size*sizeof(double));
    return 0;
}

static int sortNodeSetFastMerge(
    int         txt,
................................................................................
                        errMsg);
        CHECK_RC;
    } else {
        if (!actionNode->firstChild) {
            xpathRSInit (&rs);
            rsSetString (&rs, "");
        } else {
            fragmentNode = domNewElementNode(xs->resultDoc, "",
                                             ELEMENT_NODE);
            savedLastNode = xs->lastNode;
            xs->lastNode = fragmentNode;
            /* process the children as well */
            xsltPushVarFrame (xs);
            rc = ExecActions(xs, context, currentNode, currentPos,
                             actionNode->firstChild, errMsg);
            xsltPopVarFrame (xs);
................................................................................
            CHECK_RC;
            rc = xsltGetVar (xs, variableName, varURI, result, errMsg);
            CHECK_RC;
            /* remove var out of the varsInProcess list. Should be first
               in the list, shouldn't it? */
            varInProcess = xs->varsInProcess;
            if (varInProcess != &thisVarInProcess) {

                domPanic ("error in top level vars processing");

            }
            xs->varsInProcess = varInProcess->next;
            xs->currentXSLTNode = savedCurrentXSLTNode;
            return XPATH_OK;
        }
    }
    Tcl_DStringInit (&dErrMsg);
................................................................................
            reportError (node, "A template without a \"match\" attribute must"
                         " not have a \"mode\" attribute.", errMsg);
            rc = -1;
        }
        domSplitQName (str, prefix, &localName);
        if (prefix[0] != '\0') {
            ns = domLookupPrefix (node, prefix);
            if (!ns) {


                reportError (node, "The prefix of the \"mode\" attribute value"
                             " isn't bound to a namespace.", errMsg);
                rc = -1;
            }
            tpl->modeURI = ns->uri;
        }
        tpl->mode = localName;
        if (rc < 0) {
            /* If the template has a name attribute, it is already stored in
               in the namedTemplates hash table and will be freed. */
            if (!tpl->name) {
                FREE ((char*)tpl);
................................................................................
    sDoc = xs->subDocs;
    while (sDoc) {
        if (sDoc->doc == node->ownerDocument) break;
        sDoc = sDoc->next;
    }
    tpl->sDoc = sDoc;
    
    TRACE1("compiling XPATH '%s' ...\n", tpl->match);
    if (tpl->match) {
        rc = xpathParse(tpl->match, node, XPATH_TEMPMATCH_PATTERN, NULL, NULL,
                        &(tpl->freeAst), errMsg);
        if (rc < 0) {
            reportError (node, *errMsg, errMsg);
        } else {
            rc = addMatch (xs, node, tpl, prioStr, tpl->freeAst, errMsg);
................................................................................
                /* The template is already stored in the namedTemplates
                   hash table. Therefor we don't free tpl here, but
                   set tpl->match to NULL, which ensures, that the
                   tpl will be freed while the namedTemplates hash table
                   is cleand up. */
                tpl->match = NULL;
            } else {
                free ((char*)tpl);
            }
            return rc;
        }
    }

    return 0;
}
................................................................................
                        if (strcmp (ns->uri, attrSet->uri)==0) {
                            if (strcmp (attrSet->name, localName)==0) rc = 1;
                        }
                    }
                }
            }
            if (rc) {








                str = getAttr (attrSet->content, "use-attribute-sets",
                               a_useAttributeSets);
                if (str) {
                    rc = ExecUseAttributeSets (xs, context, currentNode,
                                               currentPos, attrSet->content,
                                               str, errMsg);
                    CHECK_RC;





                }
                rc = ExecActions(xs, context, currentNode, currentPos,
                                 attrSet->content->firstChild, errMsg);
                CHECK_RC;






            }
            attrSet = attrSet->next;
        }
        *pc = save;
    }
    return 0;
}
................................................................................
    xpathResultSet  * context,
    domNode         * currentNode,
    int               currentPos,
    char           ** errMsg
)
{
    domNode       *child;
    char          *str, *evStr, *select, *lang;


    char         **vs = NULL;
    char           prefix[MAX_PREFIX_LEN];
    const char    *localName;
    double        *vd = NULL;
    int            rc = 0, typeText, ascending, upperFirst, *pos = NULL, i, NaN;
    xpathResultSet rs;

................................................................................
                        FREE(evStr);
                        rc = -1;
                        break;
                    }
                    FREE(evStr);
                }
                /* jcl: TODO */
                lang = getAttr(child, "lang", a_lang);





                TRACE4("sorting with '%s' typeText %d ascending %d nodeSetLen=%d\n",
                       select, typeText, ascending, nodelist->nr_nodes);
                CHECK_RC;
                if (!pos)
                    pos = (int*)MALLOC(sizeof(int) * nodelist->nr_nodes);
                for (i=0; i<nodelist->nr_nodes;i++) pos[i] = i;
................................................................................
        TRACE2("xsltNumber value='%s' format='%s' \n", value, format);
        rc = evalXPath(xs, context, currentNode, currentPos,
                       value, &rs, errMsg);
        if (rc < 0) goto xsltNumberError;
        vVals = 1;
        v[0] = xpathRound(xpathFuncNumber( &rs, &NaN ));
        /* MARK recoverable error */
        /* This is one of the not so satisfying corners of the xslt
         * rec. The rec doesn't say, what to do, if the value isn't a
         * (finit) number. E24 from the erratas doesn't makes things
         * much better - a little bit dubious wording and a not very
         * convincing decision. Well, at least saxon seems to follow
         * the words of E24. I'll postpone this topic. */
        if (NaN) v[0] = 0;
        xpathRSFree( &rs );
................................................................................
    xsltExclExtNS  *eNS;
    xsltNSAlias    *nsAlias;
    Tcl_DString     dStr;
    domProcessingInstructionNode *pi;
    xpathResultSet  rs, nodeList;
    char           *str, *str2, *select, *pc, *nsAT, *out;
    const char     *mode, *modeURI, *localName, *uri, *nsStr;
    char            prefix[MAX_PREFIX_LEN];
    int             rc, b, i, len, terminate, chooseState, disableEsc = 0;
    double          currentPrio, currentPrec;
    Tcl_HashEntry  *h;

    if (actionNode->nodeType == TEXT_NODE) {
        domAppendNewTextNode(xs->lastNode,
                             ((domTextNode*)actionNode)->nodeValue,
................................................................................
                                       Tcl_DStringValue (&dStr));
                Tcl_DStringFree (&dStr);

                if (h) {
                    for (tpl = (xsltTemplate *) Tcl_GetHashValue (h);
                         tpl != NULL;
                         tpl = tpl->next) {
                        if (tpl->precedence > xs->currentTplRule->precedence
                            || tpl == xs->currentTplRule) continue;
                        TRACE3("find element tpl match='%s' mode='%s' name='%s'\n",
                               tpl->match, tpl->mode, tpl->name);
                        TRACE4("tpl has prio='%f' precedence='%f'\n", tpl->prio, tpl->precedence, currentPrio, currentPrec);
                        rc = xpathMatches ( tpl->ast, actionNode, currentNode,
                                            &(xs->cbs), errMsg);
                        if (rc < 0) {
                            TRACE1("xpathMatches had errors '%s' \n", *errMsg);
                            return rc;
................................................................................
                        break;
                    }
                }
            }

            TRACE2("apply-imports: current template precedence='%f' mode='%s'\n", xs->currentTplRule->precedence, xs->currentTplRule->mode);
            for (tpl = xs->templates; tpl != NULL; tpl = tpl->next) {
                TRACE4("find tpl match='%s' mode='%s' modeURI='%s' name='%s'\n",
                       tpl->match, tpl->mode, tpl->modeURI, tpl->name);
                /* exclude those, which don't match the current mode
                   and the currentTplRule */
                if (   ( mode && !tpl->mode)
                       || (!mode &&  tpl->mode)
                       || ( mode &&  tpl->mode && (strcmp(mode,tpl->mode)!=0))
                       || (!modeURI && tpl->modeURI)
................................................................................
                    }
                    Tcl_DStringAppend (&dStr, str2, -1);
                }
            }

            savedLastNode = xs->lastNode;
            xs->lastNode  = domNewElementNode (xs->resultDoc,
                                               "container", ELEMENT_NODE);
            xsltPushVarFrame (xs);
            rc = ExecActions(xs, context, currentNode, currentPos,
                             actionNode->firstChild, errMsg);
            xsltPopVarFrame (xs);
            if (rc < 0) {
                if (out) FREE(out);
                FREE(str2);
................................................................................
                                       Tcl_DStringValue (&dStr));
                Tcl_DStringFree (&dStr);
            } else {
                h = Tcl_FindHashEntry (&(xs->namedTemplates), localName);
            }
            if (!h) {
                reportError (actionNode, "xsl:call-template calls a non"
                             " existend template!", errMsg);
                return -1;
            } 
            tplChoosen = (xsltTemplate *) Tcl_GetHashValue (h);
            xsltPushVarFrame (xs);
            SETPARAMDEF;
            TRACE3("call template %s match='%s' name='%s' \n", localName, 
                   tplChoosen->match, tplChoosen->name);
................................................................................
                reportError (actionNode, "\"choose\" must have at least"
                             " one \"when\" clause", errMsg);
                return -1;
            }
            break;

        case comment:
            fragmentNode = domNewElementNode(xs->resultDoc, "", ELEMENT_NODE);
            savedLastNode = xs->lastNode;
            xs->lastNode = fragmentNode;
            xsltPushVarFrame (xs);
            rc = ExecActions(xs, context, currentNode, currentPos,
                             actionNode->firstChild, errMsg);
            xsltPopVarFrame (xs);
            CHECK_RC;
................................................................................
                                 " nodes other than text nodes.", errMsg);
                    return -1;
                }
                child = child->nextSibling;
            }
            str = xpathGetStringValue (fragmentNode, &len);
            if (!domIsComment (str)) {
                reportError (actionNode, "Invalide comment value", errMsg);
                domDeleteNode (fragmentNode, NULL, NULL);
                FREE(str);
                return -1;
            }
            xs->lastNode = savedLastNode;
            domAppendNewTextNode(xs->lastNode, str, len, COMMENT_NODE, 0);
            domDeleteNode (fragmentNode, NULL, NULL);
................................................................................
            TRACE1(" copyOf select='%s':\n", select);
            DBG(rsPrint(&rs));
            if (rs.type == xNodeSetResult) {
                for (i=0; i<rs.nr_nodes; i++) {
                    if (rs.nodes[i]->nodeType == ATTRIBUTE_NODE) {
                        attr = (domAttrNode*)rs.nodes[i];
                        if (attr ->nodeFlags & IS_NS_NODE) {
                            /* If someone selects explicitely namespace nodes
                               to copy-of with e.g namespace::* (remember: @*
                               doesn't select namespace nodes), we must this
                               handle seperately.*/
                            /* The xmlns:xml namespace node will always
                               be in scope, but never needed to be copied,
                               because the result tree will also always
                               already have it. To suppress, that the result
                               tree gets glutted with xmlns:xml declarations
                               (they would not harm, but ev. irritate some and
                               are unnecessary, we check this here as a 
................................................................................

        case message:
            str  = getAttr(actionNode,"terminate", a_terminate);
            if (!str) terminate = 0;
            else if (strcmp (str, "yes") == 0) terminate = 1;
            else if (strcmp (str, "no")  == 0) terminate = 0;
            else {
                reportError (actionNode, "Value for terminate should equal"
                             " 'yes' or 'no'", errMsg);
                return -1;
            }
            fragmentNode = domNewElementNode(xs->resultDoc, "",
                                             ELEMENT_NODE);
            savedLastNode = xs->lastNode;
            xs->lastNode = fragmentNode;
            xsltPushVarFrame (xs);
            rc = ExecActions(xs, context, currentNode, currentPos,
                             actionNode->firstChild, errMsg);
            xsltPopVarFrame (xs);
            CHECK_RC;

            str2 = xpathGetStringValue(fragmentNode, &len);
            xs->xsltMsgCB (xs->xsltMsgClientData, str2, len, terminate);
            FREE(str2);
            xs->lastNode = savedLastNode;
            domDeleteNode (fragmentNode, NULL, NULL);
            if (terminate) {
                reportError (actionNode, "xsl:message with attribute"
                             " \"terminate\"=\"yes\"", errMsg);
                return -1;
            }




            return 0;






        case namespaceAlias: 
            reportError (actionNode, "xsl:namespaceAlias is only allowed"
                         " at toplevel.", errMsg);
            return -1;

        case number:
            if (actionNode->firstChild) {
................................................................................
                    return -1;
                }
            } else {
                reportError (actionNode, "xsl:processing-instruction:"
                             " missing mandatory attribute \"name\".", errMsg);
                return -1;
            }
            fragmentNode = domNewElementNode(xs->resultDoc, "", ELEMENT_NODE);
            savedLastNode = xs->lastNode;
            xs->lastNode = fragmentNode;
            xsltPushVarFrame (xs);
            rc = ExecActions(xs, context, currentNode, currentPos,
                             actionNode->firstChild, errMsg);
            xsltPopVarFrame (xs);
            CHECK_RC;
................................................................................
                    FREE(str2);
                    return -1;
                }
                child = child->nextSibling;
            }
            str = xpathGetStringValue (fragmentNode, &len);
            if (!domIsPIValue (str)) {
                reportError (actionNode, "Invalide processing instruction "
                             "value", errMsg);
                domDeleteNode (fragmentNode, NULL, NULL);
                FREE(str);
                FREE(str2);
                return -1;
            }
            xs->lastNode = savedLastNode;
................................................................................
                        actionNode->nodeName, domNamespaceURI(actionNode) ););
            xs->lastNode = domAppendLiteralNode (xs->lastNode, actionNode);
            n = actionNode;

            while (n) {
                attr = n->firstAttr;
                while (attr && (attr->nodeFlags & IS_NS_NODE)) {
                    /* xslt namespace isn't copied */
                    /* Well, xslt implementors doesn't seem to agree
                       at which point this rule out of the second paragraph
                       of 7.1.1 must be applied: before or after applying
                       the namespace aliases (or, in other words: is this
                       rule (of not copying the XSLT namespace for lre)
                       considered, at the time, the lre is found in the
                       stylesheet or at the time, the lre is written to the
                       result doc). In deed the rec doesn't clarify this
................................................................................
            || ( modeURI && !tpl->modeURI)
            || ( modeURI && tpl->modeURI && (strcmp(modeURI, tpl->modeURI)!=0))
        ) {
            TRACE("doesn't match mode\n");
            continue; /* doesn't match mode */
        }
        TRACE4("tpl has prio='%f' precedence='%f', currentPrio='%f', currentPrec='%f'\n", tpl->prio, tpl->precedence, currentPrio, currentPrec);
        /* According to xslt rec 5.5: First test precedence */
        if (tpl->precedence < currentPrec) break;
        if (tpl->precedence == currentPrec) {
            if (tpl->prio < currentPrio) break;
            if (tpl->prio == currentPrio
                && domPrecedes (tpl->content, tplChoosen->content))
                break;
        }
................................................................................
    char          ** errMsg
)
{
    domNode  * savedLastNode;
    int        i, rc, needNewVarFrame = 1;

    if (nodeList->type == xNodeSetResult) {






        savedLastNode = xs->lastNode;
        for (i=0; i < nodeList->nr_nodes; i++) {
            if (needNewVarFrame) {
                xsltPushVarFrame (xs);
                SETPARAMDEF;
                rc = setParamVars (xs, context, currentNode, currentPos,
                                   actionNode, errMsg);
................................................................................
                needNewVarFrame = 1;
            } else needNewVarFrame = 0;
        }
        if (!needNewVarFrame) {
            xsltPopVarFrame (xs);
        }
        xs->lastNode = savedLastNode;

    } else {
        TRACE("ApplyTemplates: nodeList not a NodeSetResult !!!\n");
        DBG(rsPrint(nodeList);)
    }
    return 0;
}

................................................................................
    Tcl_HashTable  * HashTable,
    char          ** errMsg
    )
{
    char *pc, *start, save, prefix[MAX_PREFIX_LEN];
    const char *localName;
    int hnew;
    Tcl_HashEntry *h;

    Tcl_DString dStr;
    domNS  *ns;

    Tcl_DStringInit (&dStr);
    pc = qnameList;
    while (*pc) {
................................................................................
            Tcl_DStringAppend (&dStr, prefix, -1);
            Tcl_DStringAppend (&dStr, "'.", 2);
            reportError (node, Tcl_DStringValue (&dStr), errMsg);
            Tcl_DStringFree (&dStr);
            return 0;
        }
        Tcl_DStringAppend (&dStr, localName, -1);
        h = Tcl_CreateHashEntry (HashTable, Tcl_DStringValue (&dStr), &hnew);
        Tcl_DStringSetLength (&dStr, 0);
        *pc = save;
    }
    return 1;
}
        
/*----------------------------------------------------------------------------
................................................................................
    }
    if (d > 1.0) {
        docData->fwCmpProcessing = 1;
    } else {
        if (d != 1.0) {
            reportError (xsltRoot, "Strange \"version\" value.", errMsg);
            return -1;
            docData->fwCmpProcessing = 0;
        }
    }

    str = getAttr (xsltRoot, "exclude-result-prefixes",
                   a_excludeResultPrefixes);
    rc = parseList (docData, xsltRoot, str, 0, errMsg);
    CHECK_RC;
................................................................................
    int          fixedXMLSource,
    char       **errMsg
    )
{
    Tcl_Obj      *cmdPtr, *resultObj, *extbaseObj, *xmlstringObj;
    Tcl_Obj      *channelIdObj, *resultTypeObj;
    int           len, mode, result, storeLineColumn;

    char         *resultType, *extbase, *xmlstring, *channelId, s[20];
    char         *extResolver = NULL;
    CONST84 char *str;

    domDocument  *doc;
    xsltSubDoc   *sdoc;
    XML_Parser    parser;
    Tcl_Channel   chan;
    Tcl_DString   dStr;
    
    if (isStylesheet && (href[0] == '\0')) {
        *errMsg = tdomstrdup("Recursive import/include: stylesheet tries "
                             "to access itself.");
        return NULL;
    }





    cmdPtr = Tcl_NewStringObj (xsltDoc->extResolver, -1);
    Tcl_IncrRefCount (cmdPtr);
    if (baseURI) {
        Tcl_ListObjAppendElement(interp, cmdPtr,
                                 Tcl_NewStringObj (baseURI,
                                                   strlen(baseURI)));
    } else {
................................................................................
    }
    Tcl_ListObjAppendElement (interp, cmdPtr, (href ?
                              Tcl_NewStringObj (href, strlen (href))
                              : Tcl_NewStringObj ("", 0)));
    Tcl_ListObjAppendElement (interp, cmdPtr,
                              Tcl_NewStringObj ("", 0));

#if TclOnly8Bits
    result = Tcl_GlobalEvalObj(interp, cmdPtr);
#else 
    result = Tcl_EvalObjEx (interp, cmdPtr, TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);
#endif    

    Tcl_DecrRefCount (cmdPtr);
    resultObj = Tcl_GetObjResult (interp);
    Tcl_IncrRefCount (resultObj);

    if (result != TCL_OK) {
        goto wrongScriptResult;
................................................................................
        storeLineColumn = 0;
    }

    parser = XML_ParserCreate_MM (NULL, MEM_SUITE, NULL);

    Tcl_ResetResult (interp);
    if (xsltDoc->extResolver) {
        extResolver = tdomstrdup (xsltDoc->extResolver);

    }
    /* keep white space, no fiddling with the encoding (is this
       a good idea?) */
    doc = domReadDocument (parser, xmlstring, len, 0, 0, storeLineColumn, 0,
                           chan, extbase, extResolver, 0, 
                           (int) XML_PARAM_ENTITY_PARSING_ALWAYS, interp);




    if (doc == NULL) {
        DBG(fprintf (stderr, "parse error, str len %d, xmlstring: -->%s<--\n",
                     strlen (xmlstring), xmlstring);)
        Tcl_DStringInit (&dStr);
        Tcl_DStringAppend (&dStr, "Error while processing external entity \"",
                           -1);
        Tcl_DStringAppend (&dStr, href, -1);
................................................................................
                    } else {
                        attrSet = (xsltAttrSet*)MALLOC(sizeof(xsltAttrSet));
                        xs->attrSets = attrSet;
                    }
                    attrSet->next    = NULL;
                    attrSet->content = node;
                    attrSet->name    = localName;

                    if (ns) {
                        attrSet->uri = ns->uri;
                    } else {
                        attrSet->uri = NULL;
                    }
                } else {
                    reportError (node, "xsl:attribute-set: missing mandatory"
................................................................................
                        df = df->next;
                    }
                    if (df == NULL) {
                        df = (xsltDecimalFormat*)MALLOC(sizeof(xsltDecimalFormat));
                        memset (df, 0, sizeof (xsltDecimalFormat));
                        newdf = 1;
                        /* initialize to defaults */
#if TclOnly8Bits
                        df->decimalSeparator  = '.';
                        df->groupingSeparator = ',';
                        df->infinity          = "Infinity";
                        df->minusSign         = '-';
                        df->NaN               = "NaN";
                        df->percent           = '%';
                        df->zeroDigit         = '0';
                        df->digit             = '#';
                        df->patternSeparator  = ';';
#else 
                        df->decimalSeparator  = 46;          
                        df->groupingSeparator = 44;          
                        df->infinity          = "Infinity";  
                        df->minusSign         = 45;          
                        df->NaN               = "NaN";       
                        df->percent           = 37;          
                        df->perMille          = 0x2030;      
                        df->zeroDigit         = 48;          
                        df->digit             = 35;          
                        df->patternSeparator  = 59;
#endif /* TclOnly8Bits */
                        df->name = tdomstrdup(str);
                        if (ns) df->uri = tdomstrdup(ns->uri);
                        else df->uri = NULL;
                        /* prepend into list of decimal format
                           after the default one */
                        df->next = xs->decimalFormats->next;
                        xs->decimalFormats->next = df;
................................................................................
                    }
                } else {
                    /* definitions for default decimal format */
                    df = xs->decimalFormats;
                }
                str = getAttr(node, "decimal-separator",  a_decimalSeparator);
                if (str) {
#if TclOnly8Bits
                    if (str[1] != '\0') {
                        reportError (node, "decimal-separator has to be a"
                                     " single char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    df->decimalSeparator = str[0];
#else
                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "decimal-separator has to be a"
                                     " single char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->decimalSeparator);
#endif /* TclOnly8Bits */
                }
                str = getAttr(node, "grouping-separator", a_groupingSeparator);
                if (str) {
#if TclOnly8Bits
                    if (str[1] != '\0') {
                        reportError (node, "grouping-separator has to be a"
                                     " single char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    df->groupingSeparator = str[0];
#else 
                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "groupingSeparator has to be a"
                                     " single char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->groupingSeparator);
#endif /* TclOnly8Bits */                    
                }
                str = getAttr(node, "infinity",           a_infinity);
                if (str) df->infinity = str;
                str = getAttr(node, "minus-sign",         a_minusSign);
                if (str) {
#if TclOnly8Bits
                    if (str[1] != '\0') {
                        reportError (node, "minus-sign has to be a single"
                                     " char", errMsg);
                        return -1;
                    }
                    df->minusSign = str[0];
#else                     
                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "minus-sign has to be a single"
                                     " char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->minusSign);
#endif /* TclOnly8Bits */         
                }
                str = getAttr(node, "NaN",                a_nan);
                if (str) df->NaN = str;
                str = getAttr(node, "percent",            a_percent);
                if (str) {
#if TclOnly8Bits
                    if (str[1] != '\0') {
                        reportError (node, "percent has to be a single"
                                     " char", errMsg);
                        return -1;
                    }
                    df->percent = str[0];
#else
                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "percent has to be a single"
                                     " char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->percent);                    
#endif /* TclOnly8Bits */
                }
                str = getAttr(node, "per-mille",          a_perMille);
                if (str) {
#if TclOnly8Bits
                    reportError (node, "User defined per-mille sign not"
                                 " supported, sorry.", errMsg);
                    return -1;
#else
                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "per-mille has to be a single"
                                     " char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->perMille);                    
#endif /* TclOnly8Bits */
                }
                str = getAttr(node, "zero-digit",         a_zeroDigit);
                if (str) {
#if TclOnly8Bits                    
                    if (str[1] != '\0') {
                        reportError (node, "zero-digit has to be a single"
                                     " char", errMsg);
                        return -1;
                    }
                    df->zeroDigit = str[0];
#else
                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "zero-digit has to be a single"
                                     " char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->zeroDigit);                    
#endif /* TclOnly8Bits */
                }
                str = getAttr(node, "digit",              a_digit);
                if (str) {
#if TclOnly8Bits
                    if (str[1] != '\0') {
                        reportError (node, "digit has to be a single char",
                                     errMsg);
                        return -1;
                    }
                    df->digit = str[0];
#else 
                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "digit has to be a single char",
                                     errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->digit);
#endif /* TclOnly8Bits */
                }
                str = getAttr(node, "pattern-separator",  a_patternSeparator);
                if (str) {
#if TclOnly8Bits
                    if (str[1] != '\0') {
                        reportError (node, "pattern-separator has to be a"
                                     " single char", errMsg);
                        return -1;
                    }
                    df->patternSeparator = str[0];
#else
                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "pattern-separator has to be a"
                                     " single char", errMsg);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->patternSeparator);
#endif /* TclOnly8Bits */
                }
                break;

            case import:
                if (nonImportElemSeen) {
                    reportError (node, "xsl:import elements must come first",
                                 errMsg);
................................................................................

                keyInfo = (xsltKeyInfo *)MALLOC(sizeof(xsltKeyInfo));
                keyInfo->node = node;
                rc = xpathParse (match, node, XPATH_KEY_MATCH_PATTERN, NULL,
                                 NULL, &(keyInfo->matchAst), errMsg);
                if (rc < 0) {
                    reportError (node, *errMsg, errMsg);
                    free ((char*)keyInfo);
                    return rc;
                }
                keyInfo->use       = use;
                rc = xpathParse (use, node, XPATH_KEY_USE_EXPR, NULL,
                                 NULL, &(keyInfo->useAst), errMsg);
                if (rc < 0) {
                    reportError (node, *errMsg, errMsg);
                    xpathFreeAst (keyInfo->matchAst);
                    free ((char*)keyInfo);
                    return rc;
                }
                domSplitQName (name, prefix, &localName);
                Tcl_DStringInit (&dStr);
                if (prefix[0] != '\0') {
                    ns = domLookupPrefix (node, prefix);
                    if (!ns) {
................................................................................
            entryPtr = Tcl_NextHashEntry(&search)) {
        nf = (xsltNumberFormat *) Tcl_GetHashValue (entryPtr);
        FREE(nf->tokens);
        FREE(nf);
    }
    Tcl_DeleteHashTable(&xs->formats);

    if (&xs->topLevelVars) {
        for (entryPtr = Tcl_FirstHashEntry(&xs->topLevelVars, &search);
             entryPtr != (Tcl_HashEntry*) NULL;
             entryPtr = Tcl_NextHashEntry(&search)) {
            tlv = (xsltTopLevelVar *) Tcl_GetHashValue (entryPtr);
            FREE(tlv);
        }
        Tcl_DeleteHashTable (&xs->topLevelVars);
    }

    /*--- free key definition information ---*/
    for (entryPtr = Tcl_FirstHashEntry (&xs->keyInfos, &search);
         entryPtr != (Tcl_HashEntry*) NULL;
         entryPtr = Tcl_NextHashEntry (&search)) {
        ki = (xsltKeyInfo *) Tcl_GetHashValue (entryPtr);
        while (ki) {
................................................................................
    /* Free the sub documents, which are resolved relative to nodes in
     * the xml source. */
    /* XML documents don't have excludeNS and extensionNS information
       and the already parsed XSLT documents information is
       preserved, therefor we don't touch excludeNS and extensionNS
       information */
    /* This loop works only as coded, because, the first subdoc will
     * always be the primary xslt doc, so xs->subDocs will not
     * change. Crusty stuff, this code. */
    sd = xs->subDocs;
    while (sd)  {
        sdsave = sd;
        sd = sd->next;
        if (sdsave->isStylesheet || sdsave->fixedXMLSource) {
            if (lastSubDoc) {
................................................................................
            if (sdsave->baseURI) FREE(sdsave->baseURI);
            
            FREE(sdsave);
        }
    }
    xs->nsUniqeNr = 0;
    /* In theory, the varFramesStack and varStack pointers should
       be always back to there inital state. But to be sure, we
       re-initialize, just in case of a bizarre error or something. */
    xs->varFramesStackPtr = -1;
    xs->varStackPtr       = -1;
}

/*----------------------------------------------------------------------------
|   xsltCompileStylesheet
................................................................................
    Tcl_InitHashTable ( &(xs->xpaths), TCL_STRING_KEYS);
    Tcl_InitHashTable ( &(xs->pattern), TCL_STRING_KEYS);
    Tcl_InitHashTable ( &(xs->formats), TCL_STRING_KEYS);
    Tcl_InitHashTable ( &(xs->topLevelVars), TCL_STRING_KEYS);
    Tcl_InitHashTable ( &(xs->keyInfos), TCL_STRING_KEYS);
    xs->decimalFormats->name              = NULL;
    xs->decimalFormats->uri               = NULL;
#if TclOnly8Bits
    xs->decimalFormats->decimalSeparator  = '.';
    xs->decimalFormats->groupingSeparator = ',';
    xs->decimalFormats->minusSign         = '-';
    xs->decimalFormats->percent           = '%';
    xs->decimalFormats->zeroDigit         = '0';
    xs->decimalFormats->digit             = '#';
    xs->decimalFormats->patternSeparator  = ';';
#else 
    xs->decimalFormats->decimalSeparator  = 46;          
    xs->decimalFormats->groupingSeparator = 44;          
    xs->decimalFormats->minusSign         = 45;          
    xs->decimalFormats->percent           = 37;          
    xs->decimalFormats->perMille          = 0x2030;          
    xs->decimalFormats->zeroDigit         = 48;          
    xs->decimalFormats->digit             = 35;          
    xs->decimalFormats->patternSeparator  = 59;          
#endif /* TclOnly8Bits */
    xs->decimalFormats->infinity          = "Infinity";
    xs->decimalFormats->NaN               = "NaN";
    xs->decimalFormats->next              = NULL;
    xs->indentOutput = 0;
    memset (&xs->doctype, 0, sizeof (domDocInfo));
    
    node = xsltDoc->documentElement;

    /* add the xslt doc to the doc list */
    sdoc = (xsltSubDoc*)MALLOC(sizeof (xsltSubDoc));
    sdoc->doc = xsltDoc;
    baseURI = findBaseURI (xsltDoc->documentElement);
    if (baseURI) {
        sdoc->baseURI = tdomstrdup (baseURI);
    } else {
        sdoc->baseURI = NULL;
................................................................................
    } else {
        rc = addExclExtNS (sdoc, node, errMsg);
        if (rc < 0) goto error;
        
        StripXSLTSpace (xsltDoc->rootNode);
        precedence = 1.0;
        precedenceLowBound = 0.0;
        rc = 0;
        rc = processTopLevel (xpathFuncClientData, node, xs, precedence, 
                              &precedenceLowBound, errMsg);
        if (rc != 0) goto error;
    }
        
    return xs;

................................................................................
\---------------------------------------------------------------------------*/
int xsltProcess (
    domDocument       * xsltDoc,
    domNode           * xmlNode,
    void              * xsltCmdData,
    char             ** parameters,
    int                 ignoreUndeclaredParameters,

    xpathFuncCallback   funcCB,
    void              * xpathFuncClientData,
    xsltMsgCB           xsltMsgCB,
    void              * xsltMsgClientData,
    char             ** errMsg,
    domDocument      ** resultDoc   
    )
................................................................................
        xs = (xsltState *) xsltCmdData;
    } else {
        xs = (xsltState *) xsltCompileStylesheet (xsltDoc, funcCB,
                                                  xpathFuncClientData,
                                                  1, errMsg);
        if (!xs) return -1;
    }



    if (xmlNode->nodeType == DOCUMENT_NODE) {
        xmlNode = ((domDocument *)xmlNode)->rootNode;
    } else {
        xmlNode = xmlNode->ownerDocument->rootNode;
    }
    DBG(printXML(xmlNode, 0, 1);)

................................................................................
    }
    return 0;

 error:
    xsltPopVarFrame (xs);
    xpathRSFree( &nodeList );
    domFreeDocument (xs->resultDoc, NULL, NULL);

    if (xsltCmdData) {
        xsltResetState (xs);
    } else {
        xsltFreeState (xs);
    }
    return -1;

} /* xsltProcess */








<
<


<







 







>

|


>
>
>
>
>








>
>
>
>







 







>
|







 







<
<
<
<
<
<
<
<
<
<
<
<
<












<







 







>
>







 







|







 







>
|







 







<







 







|
|







 







|







 







|







 







|







 







|









|












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







 







|


|







 







<
|
|
|
|
<
>











<
<
<

|







 







|







 







<



<




<
<
<
<
<
<
<
<
<
<
<
<







 







<







 







|







 







|
<







 







>
|
>







 







|
>
>




<







 







|







 







|







 







>
>
>
>
>
>
>
>






<
>
>
>
>
>



<
>
>
>
>
>
>







 







|
>
>







 







|
>
>
>
>







 







|







 







|







 







|

|







 







|







 







|







 







|







 







|







 







|







 







|


|







 







|
|


|
<









|








>
>
>
>
|
>
>
>
>
>
|







 







|







 







|







 







|
|







 







|







 







>
>
>
>
>
>







 







>







 







<







 







|







 







<







 







>

|
<
>











>
>
>
>
>







 







<
<
<

<







 







|
>



|
|
|
>
>
>
|







 







>







 







<
<
<
<
<
<
<
<
<
<
<










<







 







<
<
<
<
<
<
<
<
<








<



<
<
<
<
<
<
<
<
<








<





<
<
<
<
<
<
<
<








<





<






<








<



<
<
<
<
<








<



<
<
<
<
<
<
<
<








<



<
<
<
<
<
<
<
<








<



<
<
<
<
<
<
<
<







<







 







|








|







 







<
|
|
|
|
|
|
|
<







 







|







 







|







 







<
<
<
<
<
<
<
<
<








<








|







 







<







 







>







 







>
>
|







 







>









45
46
47
48
49
50
51


52
53

54
55
56
57
58
59
60
..
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
...
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
...
297
298
299
300
301
302
303













304
305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
...
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
...
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
...
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
...
745
746
747
748
749
750
751

752
753
754
755
756
757
758
...
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
...
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
...
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
...
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
....
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101















































































































































































































1102
1103
1104
1105
1106
1107
1108
....
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
....
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
....
1507
1508
1509
1510
1511
1512
1513

1514
1515
1516
1517

1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529



1530
1531
1532
1533
1534
1535
1536
1537
1538
....
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
....
2292
2293
2294
2295
2296
2297
2298

2299
2300
2301

2302
2303
2304
2305












2306
2307
2308
2309
2310
2311
2312
....
2325
2326
2327
2328
2329
2330
2331

2332
2333
2334
2335
2336
2337
2338
....
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
....
2520
2521
2522
2523
2524
2525
2526
2527

2528
2529
2530
2531
2532
2533
2534
....
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
....
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954

2955
2956
2957
2958
2959
2960
2961
....
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
....
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
....
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071

3072
3073
3074
3075
3076
3077
3078
3079

3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
....
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
....
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
....
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
....
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
....
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
....
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
....
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
....
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
....
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
....
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
....
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
....
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607

4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
....
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
....
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
....
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
....
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
....
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
....
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
....
5419
5420
5421
5422
5423
5424
5425

5426
5427
5428
5429
5430
5431
5432
....
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
....
5625
5626
5627
5628
5629
5630
5631

5632
5633
5634
5635
5636
5637
5638
....
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668

5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
....
5695
5696
5697
5698
5699
5700
5701



5702

5703
5704
5705
5706
5707
5708
5709
....
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
....
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
....
6101
6102
6103
6104
6105
6106
6107











6108
6109
6110
6111
6112
6113
6114
6115
6116
6117

6118
6119
6120
6121
6122
6123
6124
....
6125
6126
6127
6128
6129
6130
6131









6132
6133
6134
6135
6136
6137
6138
6139

6140
6141
6142









6143
6144
6145
6146
6147
6148
6149
6150

6151
6152
6153
6154
6155








6156
6157
6158
6159
6160
6161
6162
6163

6164
6165
6166
6167
6168

6169
6170
6171
6172
6173
6174

6175
6176
6177
6178
6179
6180
6181
6182

6183
6184
6185





6186
6187
6188
6189
6190
6191
6192
6193

6194
6195
6196








6197
6198
6199
6200
6201
6202
6203
6204

6205
6206
6207








6208
6209
6210
6211
6212
6213
6214
6215

6216
6217
6218








6219
6220
6221
6222
6223
6224
6225

6226
6227
6228
6229
6230
6231
6232
....
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
....
6741
6742
6743
6744
6745
6746
6747

6748
6749
6750
6751
6752
6753
6754

6755
6756
6757
6758
6759
6760
6761
....
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
....
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
....
7010
7011
7012
7013
7014
7015
7016









7017
7018
7019
7020
7021
7022
7023
7024

7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
....
7094
7095
7096
7097
7098
7099
7100

7101
7102
7103
7104
7105
7106
7107
....
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
....
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
....
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338


/*----------------------------------------------------------------------------
|   Includes
|
\---------------------------------------------------------------------------*/
#include <stdio.h>


#include <math.h>
#include <limits.h>

#include <locale.h>
#include <dom.h>
#include <domxpath.h>
#include <domxslt.h>
#include <tcl.h>         /* for hash tables */

/*----------------------------------------------------------------------------
................................................................................
|   Defines
|
\---------------------------------------------------------------------------*/
#define XSLT_NAMESPACE  "http://www.w3.org/1999/XSL/Transform"
#define INITIAL_SIZE_FOR_KEYSETS 10


/* #define DEBUG */
/*----------------------------------------------------------------------------
|   Debug Macros
|
\---------------------------------------------------------------------------*/
#ifdef DEBUG
# define DBG(x) x
#else
# define DBG(x) 
#endif
#define DBG(x)              
#define TRACE(x)            DBG(fprintf(stderr,(x)))
#define TRACE1(x,a)         DBG(fprintf(stderr,(x),(a)))
#define TRACE2(x,a,b)       DBG(fprintf(stderr,(x),(a),(b)))
#define TRACE3(x,a,b,c)     DBG(fprintf(stderr,(x),(a),(b),(c)))
#define TRACE4(x,a,b,c,d)   DBG(fprintf(stderr,(x),(a),(b),(c),(d)))
#define TRACE5(x,a,b,c,d,e) DBG(fprintf(stderr,(x),(a),(b),(c),(d),(e)))

/*----------------------------------------------------------------------------
|   Macros
|
\---------------------------------------------------------------------------*/
#define CHECK_RC            if (rc < 0) return rc
#define CHECK_RC1(x)        if (rc < 0) {FREE((char*)(x)); return rc;}
#define SET_TAG(t,n,s,v)    if (strcmp(n,s)==0) { t->info = v; return v; }
#define SETSCOPESTART       xs->varFramesStack[xs->varFramesStackPtr].stop=1
#define SETPARAMDEF         xs->varFramesStack[xs->varFramesStackPtr].stop=2

#if defined(_MSC_VER)
................................................................................
|
\-------------------------------------------------------------------------*/
typedef struct xsltAttrSet {

    const char * name;
    const char * uri;
    domNode    * content;
    int          inUse;
    
    struct xsltAttrSet *next;

} xsltAttrSet;

/*--------------------------------------------------------------------------
|   xsltNodeSet
|
................................................................................

/*--------------------------------------------------------------------------
|   xsltDecimalFormat
|
\-------------------------------------------------------------------------*/
typedef struct xsltDecimalFormat
{













    char        * name;
    char        * uri;
    Tcl_UniChar   decimalSeparator;
    Tcl_UniChar   groupingSeparator;
    char        * infinity;
    Tcl_UniChar   minusSign;
    char        * NaN;
    Tcl_UniChar   percent;
    Tcl_UniChar   perMille;
    Tcl_UniChar   zeroDigit;
    Tcl_UniChar   digit;
    Tcl_UniChar   patternSeparator;


    struct xsltDecimalFormat * next;

} xsltDecimalFormat;


/*--------------------------------------------------------------------------
................................................................................
/*--------------------------------------------------------------------------
|   xsltState
|
\-------------------------------------------------------------------------*/
typedef struct {

    xsltTemplate      * templates;
    int                 nestedApplyTemplates;
    int                 maxNestedApplyTemplates;
    Tcl_HashTable       namedTemplates;
    Tcl_HashTable       isElementTpls;
    xsltWSInfo          wsInfo;
    domNode           * xmlRootNode;
    domDocInfo          doctype;
    int                 indentOutput;
    domDocument       * resultDoc;
................................................................................

static domDocument * getExternalDocument (Tcl_Interp *interp, xsltState *xs,
                                          domDocument *xsltDoc, 
                                          const char *baseURI,
                                          const char *href, int isStylesheet,
                                          int fixedXMLSource, char **errMsg);

#ifdef DEBUG
/*----------------------------------------------------------------------------
|   printXML
|
\---------------------------------------------------------------------------*/
static void printXML (domNode *node, int level, int maxlevel) {

    domTextNode *tnode;
................................................................................
            fprintf(stderr, "%s?>\n", tmp);
        }
        node = node->nextSibling;
        n++;
        if (n>8) { fprintf(stderr, "...\n"); return; }
    }
}
#endif /* #ifdef DEBUG */

/*----------------------------------------------------------------------------
|   reportError
|
\---------------------------------------------------------------------------*/
static void
reportError (
    domNode * node,
................................................................................
    domDocument * extDocument;
    int           found;

    DBG(
        fprintf (stderr, "xsltAddExternalDocument: baseURI '%s'\n", baseURI);
        fprintf (stderr, "xsltAddExternalDocument: systemID '%s'\n", str);
    )

    found = 0;
    sdoc = xs->subDocs;
    if (str) {
        while (sdoc) {
            if (!sdoc->isStylesheet
                && sdoc->baseURI 
                && strcmp (sdoc->baseURI, str)==0) {
................................................................................
                break;
            }
            sdoc = sdoc->next;
        }
    }
    if (!found) {
        if (!xs->xsltDoc->extResolver) {
            *errMsg = tdomstrdup("Need resolver script for document() calls. "
                                 "(Use \"-externalentitycommand\")");
            return -1;
        }
        extDocument = getExternalDocument (
                         (Tcl_Interp*)xs->orig_funcClientData,
                         xs, xs->xsltDoc, baseURI, str, 0, fixedXMLSource,
                         errMsg);
        if (extDocument) {
................................................................................
        Tcl_SetHashValue (h, format);
        format->formatStr = p = Tcl_GetHashKey (&(xs->formats), h);
    }
    while (*p) {
        clen = UTF8_CHAR_LEN(*p);
        if (!clen) {
            reportError (xs->currentXSLTNode, "xsl:number: UTF-8 form of"
                         " character longer than 4 Byte", errMsg);
            return NULL;
        }
        if (clen > 1) {
            /* hack: skip over multibyte chars - this may be wrong */
            format->prologLen += clen;
            p += clen;
            continue;
................................................................................
    p++;                                         \
    if (*p) {                                    \
        format->tokens[nrOfTokens].sepStart = p; \
    }                                            \
    while (*p) {                                 \
        clen = UTF8_CHAR_LEN(*p);                \
        if (!clen) {                             \
            reportError (xs->currentXSLTNode, "xsl:number: UTF-8 form of character longer than 4 Byte", errMsg); \
            return NULL;                         \
        }                                        \
        if (clen > 1) {                          \
            /* hack: skip over multibyte chars - this may be wrong */ \
            format->tokens[nrOfTokens].sepLen += clen;  \
            p += clen;                           \
            continue;                            \
................................................................................
static void formatValue (
    xsltNumberFormat *f,
    int              *useFormatToken,
    int               value,
    Tcl_DString      *str,
    char             *groupingSeparator,
    long              groupingSize,
    int               addSeparater
)
{
    int         len, fulllen, gslen, upper = 0, e, m, b, i, z, v;
    char        tmp[80], *pt;
    Tcl_DString tmp1;
    static struct { char *digit; char *ldigit; int value; } RomanDigit[] = {
          { "M" , "m" , 1000, },
................................................................................
    default:
        sprintf (tmp, "%d", value);
        break;
    }
    len = strlen (tmp);
    Tcl_DStringAppend (str, tmp, len);
 appendSeperator:
    if (addSeparater) {
        if (f->tokens[*useFormatToken].sepStart) {
            Tcl_DStringAppend (str, f->tokens[*useFormatToken].sepStart,
                               f->tokens[*useFormatToken].sepLen);
            *useFormatToken += 1;
        } else {
            if (*useFormatToken > 0) {
                Tcl_DStringAppend (str, f->tokens[*useFormatToken-1].sepStart,
                                   f->tokens[*useFormatToken-1].sepLen);
            } else {
                /* insert default separator '.' */
                Tcl_DStringAppend (str, ".", 1);
            }
        }
    }

    return;
}

/*----------------------------------------------------------------------------
|   xsltFormatNumber
|
\---------------------------------------------------------------------------*/















































































































































































































static int addCurrencySymbol (
    Tcl_UniChar  *p,
    Tcl_UniChar  *result,
    int          *i
)
{
    Tcl_DString dStr;
................................................................................
    int               * resultLen,
    char             ** errMsg
)
{
    Tcl_UniChar prefix1[800], prefix2[800], suffix1[800], suffix2[800];
    Tcl_UniChar save = '\0', save1, t, *prefix, *suffix, n[800], f[800];
    Tcl_UniChar uniCharNull = '\0';
    char stmp[240], ftmp[80], *tstr;
    char wrongFormat[] = "Unable to interpret format pattern.";
    int i, j, k, l, zl, g, nHash, nZero, fHash, fZero, gLen, isNeg;
    int prefixMinux, percentMul = 0, perMilleMul = 0;
    Tcl_DString  dStr, s;
    Tcl_UniChar *format, *negformat = NULL, *p, *p1;
    DBG(Tcl_DString dbStr;)

................................................................................
    }
    
    if (fHash + fZero == 0) {
        i = (int) (number+0.5);
    } else {
        i = (int) number;
        /* format fraction part */
        DBG(fprintf(stderr, "formatting fraction part: '%f', fZero+fHash: '%d'\n",
                    number - i, fZero+fHash);)
        sprintf(ftmp,"%.*f", fZero+fHash, number -i);
        DBG(fprintf(stderr, "raw formatted fraction part: '%s'\n", ftmp);)
        if (ftmp[0] == '1') {
            i++;
        }
    }
    
    DBG(fprintf(stderr,"normal part nZero=%d i=%d glen=%d\n", nZero, i, gLen);)
    /* fill in grouping char */
................................................................................
                Tcl_UniCharToUtfDString(
                    (Tcl_UniChar*)Tcl_DStringValue (&s),
                    Tcl_UniCharLen((Tcl_UniChar*)Tcl_DStringValue(&s)), &dStr
                    ));
        Tcl_DStringFree (&dbStr);
    )
    Tcl_DStringSetLength (&dStr, 0);

    tstr = Tcl_UniCharToUtfDString(
        (Tcl_UniChar*)Tcl_DStringValue (&s),
        Tcl_UniCharLen((Tcl_UniChar*)Tcl_DStringValue(&s)), &dStr
        );

    *resultStr = tdomstrdup(tstr);
    Tcl_DStringFree (&dStr);
    Tcl_DStringFree (&s);
    *resultLen = strlen(*resultStr);
    return 0;

 xsltFormatNumberError:
    Tcl_DStringFree (&dStr);
    Tcl_DStringFree (&s);
    return -1;
}




static xsltNodeSet *
createXsltNodeSet (void) 
{
    xsltNodeSet * ns;

    ns = (xsltNodeSet *) MALLOC (sizeof(xsltNodeSet));
    ns->nodes = (domNode**)MALLOC(INITIAL_SIZE_FOR_KEYSETS * sizeof(domNode*));
    ns->allocated = INITIAL_SIZE_FOR_KEYSETS;
    ns->nr_nodes = 0;
................................................................................
            }
            kinfo = kinfo->next;
        }
        if ((node->nodeType == ELEMENT_NODE) && (node->firstAttr)) {
            node = (domNode*) node->firstAttr;
            continue;
        }
        if (node->nodeType == ATTRIBUTE_NODE) {
            if (((domAttrNode*)node)->nextSibling) {
                node = (domNode*) ((domAttrNode*)node)->nextSibling;
                continue;
            }
            node = ((domAttrNode*)node)->parentNode;
        }
        if ((node->nodeType == ELEMENT_NODE) && (node->firstChild)) {
................................................................................
    char      * strB,
    double      realA,
    double      realB,
    int       * greater
)
{
    int             rc;

    char           *strAptr, *strBptr;
    int             lenA, lenB, len;
    Tcl_UniChar     unicharA, unicharB;


    *greater = 0;

    if (typeText) {












        lenA = Tcl_NumUtfChars (strA, -1);
        lenB = Tcl_NumUtfChars (strB, -1);
        len = (lenA < lenB ? lenA : lenB);
        rc = Tcl_UtfNcasecmp (strA, strB, len);
        if (rc == 0) {
            if (lenA > lenB) {
                rc = 1;
................................................................................
                    break;
                }
            }
            if (!upperFirst) {
                rc *= -1;
            }
        }

        if (asc) *greater = (rc > 0);
            else *greater = (rc < 0);

    } else {
DBG(   fprintf(stderr, "nodeGreater  realA='%f' realB='%f'\n",realA, realB);)
        if (IS_NAN (realA) || IS_NAN (realB)) {
            if (asc) {
................................................................................
            b    [i] = a   [lptr  ];
            posb [i] = posa[lptr  ];
            vstmp[i] = vs  [lptr  ];
            vdtmp[i] = vd  [lptr++];
        }
    }
    memcpy(a,    b,     size*sizeof(domNode*));
    memcpy(posa, posb,  size*sizeof(int));
    memcpy(vs,   vstmp, size*sizeof(char*));
    memcpy(vd,   vdtmp, size*sizeof(double));
    return 0;
}

static int sortNodeSetFastMerge(
    int         txt,
................................................................................
                        errMsg);
        CHECK_RC;
    } else {
        if (!actionNode->firstChild) {
            xpathRSInit (&rs);
            rsSetString (&rs, "");
        } else {
            fragmentNode = domNewElementNode(xs->resultDoc, "");

            savedLastNode = xs->lastNode;
            xs->lastNode = fragmentNode;
            /* process the children as well */
            xsltPushVarFrame (xs);
            rc = ExecActions(xs, context, currentNode, currentPos,
                             actionNode->firstChild, errMsg);
            xsltPopVarFrame (xs);
................................................................................
            CHECK_RC;
            rc = xsltGetVar (xs, variableName, varURI, result, errMsg);
            CHECK_RC;
            /* remove var out of the varsInProcess list. Should be first
               in the list, shouldn't it? */
            varInProcess = xs->varsInProcess;
            if (varInProcess != &thisVarInProcess) {
                reportError (topLevelVar->node, "Error in top level"
                             " vars processing.", errMsg);
                return XPATH_EVAL_ERR;
            }
            xs->varsInProcess = varInProcess->next;
            xs->currentXSLTNode = savedCurrentXSLTNode;
            return XPATH_OK;
        }
    }
    Tcl_DStringInit (&dErrMsg);
................................................................................
            reportError (node, "A template without a \"match\" attribute must"
                         " not have a \"mode\" attribute.", errMsg);
            rc = -1;
        }
        domSplitQName (str, prefix, &localName);
        if (prefix[0] != '\0') {
            ns = domLookupPrefix (node, prefix);
            if (ns) {
                tpl->modeURI = ns->uri;
            } else {
                reportError (node, "The prefix of the \"mode\" attribute value"
                             " isn't bound to a namespace.", errMsg);
                rc = -1;
            }

        }
        tpl->mode = localName;
        if (rc < 0) {
            /* If the template has a name attribute, it is already stored in
               in the namedTemplates hash table and will be freed. */
            if (!tpl->name) {
                FREE ((char*)tpl);
................................................................................
    sDoc = xs->subDocs;
    while (sDoc) {
        if (sDoc->doc == node->ownerDocument) break;
        sDoc = sDoc->next;
    }
    tpl->sDoc = sDoc;
    
    TRACE1("compiling XPath '%s' ...\n", tpl->match);
    if (tpl->match) {
        rc = xpathParse(tpl->match, node, XPATH_TEMPMATCH_PATTERN, NULL, NULL,
                        &(tpl->freeAst), errMsg);
        if (rc < 0) {
            reportError (node, *errMsg, errMsg);
        } else {
            rc = addMatch (xs, node, tpl, prioStr, tpl->freeAst, errMsg);
................................................................................
                /* The template is already stored in the namedTemplates
                   hash table. Therefor we don't free tpl here, but
                   set tpl->match to NULL, which ensures, that the
                   tpl will be freed while the namedTemplates hash table
                   is cleand up. */
                tpl->match = NULL;
            } else {
                FREE ((char*)tpl);
            }
            return rc;
        }
    }

    return 0;
}
................................................................................
                        if (strcmp (ns->uri, attrSet->uri)==0) {
                            if (strcmp (attrSet->name, localName)==0) rc = 1;
                        }
                    }
                }
            }
            if (rc) {
                if (attrSet->inUse) {
                    attrSet->inUse = 0;
                    *pc = save;
                    reportError(actionNode, "Circular reference "
                                "to attribute set", errMsg);
                    return -1;
                }
                attrSet->inUse = 1;
                str = getAttr (attrSet->content, "use-attribute-sets",
                               a_useAttributeSets);
                if (str) {
                    rc = ExecUseAttributeSets (xs, context, currentNode,
                                               currentPos, attrSet->content,
                                               str, errMsg);

                    if (rc < 0) {
                        attrSet->inUse = 0;
                        *pc = save;
                        return rc;
                    }
                }
                rc = ExecActions(xs, context, currentNode, currentPos,
                                 attrSet->content->firstChild, errMsg);

                attrSet->inUse = 0;
                if (rc < 0) {
                    attrSet->inUse = 0;
                    *pc = save;
                    return rc;
                }
            }
            attrSet = attrSet->next;
        }
        *pc = save;
    }
    return 0;
}
................................................................................
    xpathResultSet  * context,
    domNode         * currentNode,
    int               currentPos,
    char           ** errMsg
)
{
    domNode       *child;
    char          *str, *evStr, *select;
    /* todo */
    /* char       *lang; */
    char         **vs = NULL;
    char           prefix[MAX_PREFIX_LEN];
    const char    *localName;
    double        *vd = NULL;
    int            rc = 0, typeText, ascending, upperFirst, *pos = NULL, i, NaN;
    xpathResultSet rs;

................................................................................
                        FREE(evStr);
                        rc = -1;
                        break;
                    }
                    FREE(evStr);
                }
                /* jcl: TODO */
                /* lang = getAttr(child, "lang", a_lang); */
                /* The getAttr call should be done, to set attr->info
                   to the attribute type for faster checks in further
                   runs */
                getAttr(child, "lang", a_lang);

                TRACE4("sorting with '%s' typeText %d ascending %d nodeSetLen=%d\n",
                       select, typeText, ascending, nodelist->nr_nodes);
                CHECK_RC;
                if (!pos)
                    pos = (int*)MALLOC(sizeof(int) * nodelist->nr_nodes);
                for (i=0; i<nodelist->nr_nodes;i++) pos[i] = i;
................................................................................
        TRACE2("xsltNumber value='%s' format='%s' \n", value, format);
        rc = evalXPath(xs, context, currentNode, currentPos,
                       value, &rs, errMsg);
        if (rc < 0) goto xsltNumberError;
        vVals = 1;
        v[0] = xpathRound(xpathFuncNumber( &rs, &NaN ));
        /* MARK recoverable error */
        /* This is one of the not so satisfying corners of the XSLT
         * rec. The rec doesn't say, what to do, if the value isn't a
         * (finit) number. E24 from the erratas doesn't makes things
         * much better - a little bit dubious wording and a not very
         * convincing decision. Well, at least saxon seems to follow
         * the words of E24. I'll postpone this topic. */
        if (NaN) v[0] = 0;
        xpathRSFree( &rs );
................................................................................
    xsltExclExtNS  *eNS;
    xsltNSAlias    *nsAlias;
    Tcl_DString     dStr;
    domProcessingInstructionNode *pi;
    xpathResultSet  rs, nodeList;
    char           *str, *str2, *select, *pc, *nsAT, *out;
    const char     *mode, *modeURI, *localName, *uri, *nsStr;
    char            prefix[MAX_PREFIX_LEN], tmpErr[200];
    int             rc, b, i, len, terminate, chooseState, disableEsc = 0;
    double          currentPrio, currentPrec;
    Tcl_HashEntry  *h;

    if (actionNode->nodeType == TEXT_NODE) {
        domAppendNewTextNode(xs->lastNode,
                             ((domTextNode*)actionNode)->nodeValue,
................................................................................
                                       Tcl_DStringValue (&dStr));
                Tcl_DStringFree (&dStr);

                if (h) {
                    for (tpl = (xsltTemplate *) Tcl_GetHashValue (h);
                         tpl != NULL;
                         tpl = tpl->next) {
                        if (tpl->precedence >= xs->currentTplRule->precedence
                            || tpl == xs->currentTplRule) continue;
                        TRACE3("testing element tpl match='%s' mode='%s' name='%s'\n",
                               tpl->match, tpl->mode, tpl->name);
                        TRACE4("tpl has prio='%f' precedence='%f'\n", tpl->prio, tpl->precedence, currentPrio, currentPrec);
                        rc = xpathMatches ( tpl->ast, actionNode, currentNode,
                                            &(xs->cbs), errMsg);
                        if (rc < 0) {
                            TRACE1("xpathMatches had errors '%s' \n", *errMsg);
                            return rc;
................................................................................
                        break;
                    }
                }
            }

            TRACE2("apply-imports: current template precedence='%f' mode='%s'\n", xs->currentTplRule->precedence, xs->currentTplRule->mode);
            for (tpl = xs->templates; tpl != NULL; tpl = tpl->next) {
                TRACE4("testing tpl match='%s' mode='%s' modeURI='%s' name='%s'\n",
                       tpl->match, tpl->mode, tpl->modeURI, tpl->name);
                /* exclude those, which don't match the current mode
                   and the currentTplRule */
                if (   ( mode && !tpl->mode)
                       || (!mode &&  tpl->mode)
                       || ( mode &&  tpl->mode && (strcmp(mode,tpl->mode)!=0))
                       || (!modeURI && tpl->modeURI)
................................................................................
                    }
                    Tcl_DStringAppend (&dStr, str2, -1);
                }
            }

            savedLastNode = xs->lastNode;
            xs->lastNode  = domNewElementNode (xs->resultDoc,
                                               "container");
            xsltPushVarFrame (xs);
            rc = ExecActions(xs, context, currentNode, currentPos,
                             actionNode->firstChild, errMsg);
            xsltPopVarFrame (xs);
            if (rc < 0) {
                if (out) FREE(out);
                FREE(str2);
................................................................................
                                       Tcl_DStringValue (&dStr));
                Tcl_DStringFree (&dStr);
            } else {
                h = Tcl_FindHashEntry (&(xs->namedTemplates), localName);
            }
            if (!h) {
                reportError (actionNode, "xsl:call-template calls a non"
                             " existing template!", errMsg);
                return -1;
            } 
            tplChoosen = (xsltTemplate *) Tcl_GetHashValue (h);
            xsltPushVarFrame (xs);
            SETPARAMDEF;
            TRACE3("call template %s match='%s' name='%s' \n", localName, 
                   tplChoosen->match, tplChoosen->name);
................................................................................
                reportError (actionNode, "\"choose\" must have at least"
                             " one \"when\" clause", errMsg);
                return -1;
            }
            break;

        case comment:
            fragmentNode = domNewElementNode(xs->resultDoc, "");
            savedLastNode = xs->lastNode;
            xs->lastNode = fragmentNode;
            xsltPushVarFrame (xs);
            rc = ExecActions(xs, context, currentNode, currentPos,
                             actionNode->firstChild, errMsg);
            xsltPopVarFrame (xs);
            CHECK_RC;
................................................................................
                                 " nodes other than text nodes.", errMsg);
                    return -1;
                }
                child = child->nextSibling;
            }
            str = xpathGetStringValue (fragmentNode, &len);
            if (!domIsComment (str)) {
                reportError (actionNode, "Invalid comment value", errMsg);
                domDeleteNode (fragmentNode, NULL, NULL);
                FREE(str);
                return -1;
            }
            xs->lastNode = savedLastNode;
            domAppendNewTextNode(xs->lastNode, str, len, COMMENT_NODE, 0);
            domDeleteNode (fragmentNode, NULL, NULL);
................................................................................
            TRACE1(" copyOf select='%s':\n", select);
            DBG(rsPrint(&rs));
            if (rs.type == xNodeSetResult) {
                for (i=0; i<rs.nr_nodes; i++) {
                    if (rs.nodes[i]->nodeType == ATTRIBUTE_NODE) {
                        attr = (domAttrNode*)rs.nodes[i];
                        if (attr ->nodeFlags & IS_NS_NODE) {
                            /* If someone selects explicitly namespace nodes
                               to copy-of with e.g namespace::* (remember: @*
                               doesn't select namespace nodes), we must this
                               handle separately.*/
                            /* The xmlns:xml namespace node will always
                               be in scope, but never needed to be copied,
                               because the result tree will also always
                               already have it. To suppress, that the result
                               tree gets glutted with xmlns:xml declarations
                               (they would not harm, but ev. irritate some and
                               are unnecessary, we check this here as a 
................................................................................

        case message:
            str  = getAttr(actionNode,"terminate", a_terminate);
            if (!str) terminate = 0;
            else if (strcmp (str, "yes") == 0) terminate = 1;
            else if (strcmp (str, "no")  == 0) terminate = 0;
            else {
                reportError (actionNode, "Allowed values for the 'terminate'"
                             "attribute: 'yes' or 'no'", errMsg);
                return -1;
            }
            fragmentNode = domNewElementNode(xs->resultDoc, "");

            savedLastNode = xs->lastNode;
            xs->lastNode = fragmentNode;
            xsltPushVarFrame (xs);
            rc = ExecActions(xs, context, currentNode, currentPos,
                             actionNode->firstChild, errMsg);
            xsltPopVarFrame (xs);
            CHECK_RC;

            str2 = xpathGetStringValue(fragmentNode, &len);
            rc = xs->xsltMsgCB (xs->xsltMsgClientData, str2, len, terminate);
            FREE(str2);
            xs->lastNode = savedLastNode;
            domDeleteNode (fragmentNode, NULL, NULL);
            if (terminate) {
                reportError (actionNode, "xsl:message with attribute"
                             " \"terminate\"=\"yes\"", errMsg);
                return -1;
            }
            switch (rc) {
            case 0: return 0;
            case 3: 
                reportError (actionNode, "", errMsg);
                return -1;
            default:
                sprintf (tmpErr, "Error while executing message callback."
                         " Message callback result code: %d", rc);
                reportError (actionNode, tmpErr, errMsg);
                return -1;
            }
        case namespaceAlias: 
            reportError (actionNode, "xsl:namespaceAlias is only allowed"
                         " at toplevel.", errMsg);
            return -1;

        case number:
            if (actionNode->firstChild) {
................................................................................
                    return -1;
                }
            } else {
                reportError (actionNode, "xsl:processing-instruction:"
                             " missing mandatory attribute \"name\".", errMsg);
                return -1;
            }
            fragmentNode = domNewElementNode(xs->resultDoc, "");
            savedLastNode = xs->lastNode;
            xs->lastNode = fragmentNode;
            xsltPushVarFrame (xs);
            rc = ExecActions(xs, context, currentNode, currentPos,
                             actionNode->firstChild, errMsg);
            xsltPopVarFrame (xs);
            CHECK_RC;
................................................................................
                    FREE(str2);
                    return -1;
                }
                child = child->nextSibling;
            }
            str = xpathGetStringValue (fragmentNode, &len);
            if (!domIsPIValue (str)) {
                reportError (actionNode, "Invalid processing instruction "
                             "value", errMsg);
                domDeleteNode (fragmentNode, NULL, NULL);
                FREE(str);
                FREE(str2);
                return -1;
            }
            xs->lastNode = savedLastNode;
................................................................................
                        actionNode->nodeName, domNamespaceURI(actionNode) ););
            xs->lastNode = domAppendLiteralNode (xs->lastNode, actionNode);
            n = actionNode;

            while (n) {
                attr = n->firstAttr;
                while (attr && (attr->nodeFlags & IS_NS_NODE)) {
                    /* XSLT namespace isn't copied */
                    /* Well, XSLT implementors doesn't seem to agree
                       at which point this rule out of the second paragraph
                       of 7.1.1 must be applied: before or after applying
                       the namespace aliases (or, in other words: is this
                       rule (of not copying the XSLT namespace for lre)
                       considered, at the time, the lre is found in the
                       stylesheet or at the time, the lre is written to the
                       result doc). In deed the rec doesn't clarify this
................................................................................
            || ( modeURI && !tpl->modeURI)
            || ( modeURI && tpl->modeURI && (strcmp(modeURI, tpl->modeURI)!=0))
        ) {
            TRACE("doesn't match mode\n");
            continue; /* doesn't match mode */
        }
        TRACE4("tpl has prio='%f' precedence='%f', currentPrio='%f', currentPrec='%f'\n", tpl->prio, tpl->precedence, currentPrio, currentPrec);
        /* According to XSLT rec 5.5: First test precedence */
        if (tpl->precedence < currentPrec) break;
        if (tpl->precedence == currentPrec) {
            if (tpl->prio < currentPrio) break;
            if (tpl->prio == currentPrio
                && domPrecedes (tpl->content, tplChoosen->content))
                break;
        }
................................................................................
    char          ** errMsg
)
{
    domNode  * savedLastNode;
    int        i, rc, needNewVarFrame = 1;

    if (nodeList->type == xNodeSetResult) {
        if (xs->nestedApplyTemplates > xs->maxNestedApplyTemplates) {
            *errMsg = tdomstrdup("Maximum nested apply templates reached "
                                 "(potential infinite template recursion?).");
            return -1;
        }
        xs->nestedApplyTemplates++;
        savedLastNode = xs->lastNode;
        for (i=0; i < nodeList->nr_nodes; i++) {
            if (needNewVarFrame) {
                xsltPushVarFrame (xs);
                SETPARAMDEF;
                rc = setParamVars (xs, context, currentNode, currentPos,
                                   actionNode, errMsg);
................................................................................
                needNewVarFrame = 1;
            } else needNewVarFrame = 0;
        }
        if (!needNewVarFrame) {
            xsltPopVarFrame (xs);
        }
        xs->lastNode = savedLastNode;
        xs->nestedApplyTemplates--;
    } else {
        TRACE("ApplyTemplates: nodeList not a NodeSetResult !!!\n");
        DBG(rsPrint(nodeList);)
    }
    return 0;
}

................................................................................
    Tcl_HashTable  * HashTable,
    char          ** errMsg
    )
{
    char *pc, *start, save, prefix[MAX_PREFIX_LEN];
    const char *localName;
    int hnew;


    Tcl_DString dStr;
    domNS  *ns;

    Tcl_DStringInit (&dStr);
    pc = qnameList;
    while (*pc) {
................................................................................
            Tcl_DStringAppend (&dStr, prefix, -1);
            Tcl_DStringAppend (&dStr, "'.", 2);
            reportError (node, Tcl_DStringValue (&dStr), errMsg);
            Tcl_DStringFree (&dStr);
            return 0;
        }
        Tcl_DStringAppend (&dStr, localName, -1);
        Tcl_CreateHashEntry (HashTable, Tcl_DStringValue (&dStr), &hnew);
        Tcl_DStringSetLength (&dStr, 0);
        *pc = save;
    }
    return 1;
}
        
/*----------------------------------------------------------------------------
................................................................................
    }
    if (d > 1.0) {
        docData->fwCmpProcessing = 1;
    } else {
        if (d != 1.0) {
            reportError (xsltRoot, "Strange \"version\" value.", errMsg);
            return -1;

        }
    }

    str = getAttr (xsltRoot, "exclude-result-prefixes",
                   a_excludeResultPrefixes);
    rc = parseList (docData, xsltRoot, str, 0, errMsg);
    CHECK_RC;
................................................................................
    int          fixedXMLSource,
    char       **errMsg
    )
{
    Tcl_Obj      *cmdPtr, *resultObj, *extbaseObj, *xmlstringObj;
    Tcl_Obj      *channelIdObj, *resultTypeObj;
    int           len, mode, result, storeLineColumn;
    int           resultcode = 0;
    char         *resultType, *extbase, *xmlstring, *channelId, s[20];
    Tcl_Obj      *extResolver = NULL;

    const char   *str;
    domDocument  *doc;
    xsltSubDoc   *sdoc;
    XML_Parser    parser;
    Tcl_Channel   chan;
    Tcl_DString   dStr;
    
    if (isStylesheet && (href[0] == '\0')) {
        *errMsg = tdomstrdup("Recursive import/include: stylesheet tries "
                             "to access itself.");
        return NULL;
    }
    DBG(
        fprintf (stderr, "getExternalDocument: baseURI '%s'\n", baseURI);
        fprintf (stderr, "getExternalDocument: systemID '%s'\n", href);
    )
    
    cmdPtr = Tcl_NewStringObj (xsltDoc->extResolver, -1);
    Tcl_IncrRefCount (cmdPtr);
    if (baseURI) {
        Tcl_ListObjAppendElement(interp, cmdPtr,
                                 Tcl_NewStringObj (baseURI,
                                                   strlen(baseURI)));
    } else {
................................................................................
    }
    Tcl_ListObjAppendElement (interp, cmdPtr, (href ?
                              Tcl_NewStringObj (href, strlen (href))
                              : Tcl_NewStringObj ("", 0)));
    Tcl_ListObjAppendElement (interp, cmdPtr,
                              Tcl_NewStringObj ("", 0));




    result = Tcl_EvalObjEx (interp, cmdPtr, TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL);


    Tcl_DecrRefCount (cmdPtr);
    resultObj = Tcl_GetObjResult (interp);
    Tcl_IncrRefCount (resultObj);

    if (result != TCL_OK) {
        goto wrongScriptResult;
................................................................................
        storeLineColumn = 0;
    }

    parser = XML_ParserCreate_MM (NULL, MEM_SUITE, NULL);

    Tcl_ResetResult (interp);
    if (xsltDoc->extResolver) {
        extResolver = Tcl_NewStringObj(xsltDoc->extResolver, -1);
        Tcl_IncrRefCount (extResolver);
    }
    /* keep white space, no fiddling with the encoding (is this
       a good idea?) */
    doc = domReadDocument (parser, xmlstring, len, 0, 0, storeLineColumn,
                           0, 0, NULL, chan, extbase, extResolver, 0, 
                           (int) XML_PARAM_ENTITY_PARSING_ALWAYS, interp,
                           &resultcode);
    if (xsltDoc->extResolver) {
        Tcl_DecrRefCount (extResolver);
    }
    if (doc == NULL) {
        DBG(fprintf (stderr, "parse error, str len %d, xmlstring: -->%s<--\n",
                     strlen (xmlstring), xmlstring);)
        Tcl_DStringInit (&dStr);
        Tcl_DStringAppend (&dStr, "Error while processing external entity \"",
                           -1);
        Tcl_DStringAppend (&dStr, href, -1);
................................................................................
                    } else {
                        attrSet = (xsltAttrSet*)MALLOC(sizeof(xsltAttrSet));
                        xs->attrSets = attrSet;
                    }
                    attrSet->next    = NULL;
                    attrSet->content = node;
                    attrSet->name    = localName;
                    attrSet->inUse   = 0;
                    if (ns) {
                        attrSet->uri = ns->uri;
                    } else {
                        attrSet->uri = NULL;
                    }
                } else {
                    reportError (node, "xsl:attribute-set: missing mandatory"
................................................................................
                        df = df->next;
                    }
                    if (df == NULL) {
                        df = (xsltDecimalFormat*)MALLOC(sizeof(xsltDecimalFormat));
                        memset (df, 0, sizeof (xsltDecimalFormat));
                        newdf = 1;
                        /* initialize to defaults */











                        df->decimalSeparator  = 46;          
                        df->groupingSeparator = 44;          
                        df->infinity          = "Infinity";  
                        df->minusSign         = 45;          
                        df->NaN               = "NaN";       
                        df->percent           = 37;          
                        df->perMille          = 0x2030;      
                        df->zeroDigit         = 48;          
                        df->digit             = 35;          
                        df->patternSeparator  = 59;

                        df->name = tdomstrdup(str);
                        if (ns) df->uri = tdomstrdup(ns->uri);
                        else df->uri = NULL;
                        /* prepend into list of decimal format
                           after the default one */
                        df->next = xs->decimalFormats->next;
                        xs->decimalFormats->next = df;
................................................................................
                    }
                } else {
                    /* definitions for default decimal format */
                    df = xs->decimalFormats;
                }
                str = getAttr(node, "decimal-separator",  a_decimalSeparator);
                if (str) {









                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "decimal-separator has to be a"
                                     " single char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->decimalSeparator);

                }
                str = getAttr(node, "grouping-separator", a_groupingSeparator);
                if (str) {









                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "groupingSeparator has to be a"
                                     " single char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->groupingSeparator);

                }
                str = getAttr(node, "infinity",           a_infinity);
                if (str) df->infinity = str;
                str = getAttr(node, "minus-sign",         a_minusSign);
                if (str) {








                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "minus-sign has to be a single"
                                     " char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->minusSign);

                }
                str = getAttr(node, "NaN",                a_nan);
                if (str) df->NaN = str;
                str = getAttr(node, "percent",            a_percent);
                if (str) {

                    if (str[1] != '\0') {
                        reportError (node, "percent has to be a single"
                                     " char", errMsg);
                        return -1;
                    }
                    df->percent = str[0];

                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "percent has to be a single"
                                     " char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->percent);                    

                }
                str = getAttr(node, "per-mille",          a_perMille);
                if (str) {





                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "per-mille has to be a single"
                                     " char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->perMille);                    

                }
                str = getAttr(node, "zero-digit",         a_zeroDigit);
                if (str) {








                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "zero-digit has to be a single"
                                     " char", errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->zeroDigit);                    

                }
                str = getAttr(node, "digit",              a_digit);
                if (str) {








                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "digit has to be a single char",
                                     errMsg);
                        if (newdf) FREE((char*)df);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->digit);

                }
                str = getAttr(node, "pattern-separator",  a_patternSeparator);
                if (str) {








                    clen = UTF8_CHAR_LEN (str[0]);
                    if (str[clen] != '\0') {
                        reportError (node, "pattern-separator has to be a"
                                     " single char", errMsg);
                        return -1;
                    }
                    Tcl_UtfToUniChar (str, &df->patternSeparator);

                }
                break;

            case import:
                if (nonImportElemSeen) {
                    reportError (node, "xsl:import elements must come first",
                                 errMsg);
................................................................................

                keyInfo = (xsltKeyInfo *)MALLOC(sizeof(xsltKeyInfo));
                keyInfo->node = node;
                rc = xpathParse (match, node, XPATH_KEY_MATCH_PATTERN, NULL,
                                 NULL, &(keyInfo->matchAst), errMsg);
                if (rc < 0) {
                    reportError (node, *errMsg, errMsg);
                    FREE ((char*)keyInfo);
                    return rc;
                }
                keyInfo->use       = use;
                rc = xpathParse (use, node, XPATH_KEY_USE_EXPR, NULL,
                                 NULL, &(keyInfo->useAst), errMsg);
                if (rc < 0) {
                    reportError (node, *errMsg, errMsg);
                    xpathFreeAst (keyInfo->matchAst);
                    FREE ((char*)keyInfo);
                    return rc;
                }
                domSplitQName (name, prefix, &localName);
                Tcl_DStringInit (&dStr);
                if (prefix[0] != '\0') {
                    ns = domLookupPrefix (node, prefix);
                    if (!ns) {
................................................................................
            entryPtr = Tcl_NextHashEntry(&search)) {
        nf = (xsltNumberFormat *) Tcl_GetHashValue (entryPtr);
        FREE(nf->tokens);
        FREE(nf);
    }
    Tcl_DeleteHashTable(&xs->formats);


    for (entryPtr = Tcl_FirstHashEntry(&xs->topLevelVars, &search);
         entryPtr != (Tcl_HashEntry*) NULL;
         entryPtr = Tcl_NextHashEntry(&search)) {
        tlv = (xsltTopLevelVar *) Tcl_GetHashValue (entryPtr);
        FREE(tlv);
    }
    Tcl_DeleteHashTable (&xs->topLevelVars);


    /*--- free key definition information ---*/
    for (entryPtr = Tcl_FirstHashEntry (&xs->keyInfos, &search);
         entryPtr != (Tcl_HashEntry*) NULL;
         entryPtr = Tcl_NextHashEntry (&search)) {
        ki = (xsltKeyInfo *) Tcl_GetHashValue (entryPtr);
        while (ki) {
................................................................................
    /* Free the sub documents, which are resolved relative to nodes in
     * the xml source. */
    /* XML documents don't have excludeNS and extensionNS information
       and the already parsed XSLT documents information is
       preserved, therefor we don't touch excludeNS and extensionNS
       information */
    /* This loop works only as coded, because, the first subdoc will
     * always be the primary XSLT doc, so xs->subDocs will not
     * change. Crusty stuff, this code. */
    sd = xs->subDocs;
    while (sd)  {
        sdsave = sd;
        sd = sd->next;
        if (sdsave->isStylesheet || sdsave->fixedXMLSource) {
            if (lastSubDoc) {
................................................................................
            if (sdsave->baseURI) FREE(sdsave->baseURI);
            
            FREE(sdsave);
        }
    }
    xs->nsUniqeNr = 0;
    /* In theory, the varFramesStack and varStack pointers should
       be always back to there initial state. But to be sure, we
       re-initialize, just in case of a bizarre error or something. */
    xs->varFramesStackPtr = -1;
    xs->varStackPtr       = -1;
}

/*----------------------------------------------------------------------------
|   xsltCompileStylesheet
................................................................................
    Tcl_InitHashTable ( &(xs->xpaths), TCL_STRING_KEYS);
    Tcl_InitHashTable ( &(xs->pattern), TCL_STRING_KEYS);
    Tcl_InitHashTable ( &(xs->formats), TCL_STRING_KEYS);
    Tcl_InitHashTable ( &(xs->topLevelVars), TCL_STRING_KEYS);
    Tcl_InitHashTable ( &(xs->keyInfos), TCL_STRING_KEYS);
    xs->decimalFormats->name              = NULL;
    xs->decimalFormats->uri               = NULL;









    xs->decimalFormats->decimalSeparator  = 46;          
    xs->decimalFormats->groupingSeparator = 44;          
    xs->decimalFormats->minusSign         = 45;          
    xs->decimalFormats->percent           = 37;          
    xs->decimalFormats->perMille          = 0x2030;          
    xs->decimalFormats->zeroDigit         = 48;          
    xs->decimalFormats->digit             = 35;          
    xs->decimalFormats->patternSeparator  = 59;          

    xs->decimalFormats->infinity          = "Infinity";
    xs->decimalFormats->NaN               = "NaN";
    xs->decimalFormats->next              = NULL;
    xs->indentOutput = 0;
    memset (&xs->doctype, 0, sizeof (domDocInfo));
    
    node = xsltDoc->documentElement;

    /* add the XSLT doc to the doc list */
    sdoc = (xsltSubDoc*)MALLOC(sizeof (xsltSubDoc));
    sdoc->doc = xsltDoc;
    baseURI = findBaseURI (xsltDoc->documentElement);
    if (baseURI) {
        sdoc->baseURI = tdomstrdup (baseURI);
    } else {
        sdoc->baseURI = NULL;
................................................................................
    } else {
        rc = addExclExtNS (sdoc, node, errMsg);
        if (rc < 0) goto error;
        
        StripXSLTSpace (xsltDoc->rootNode);
        precedence = 1.0;
        precedenceLowBound = 0.0;

        rc = processTopLevel (xpathFuncClientData, node, xs, precedence, 
                              &precedenceLowBound, errMsg);
        if (rc != 0) goto error;
    }
        
    return xs;

................................................................................
\---------------------------------------------------------------------------*/
int xsltProcess (
    domDocument       * xsltDoc,
    domNode           * xmlNode,
    void              * xsltCmdData,
    char             ** parameters,
    int                 ignoreUndeclaredParameters,
    int                 maxApplyDepth,
    xpathFuncCallback   funcCB,
    void              * xpathFuncClientData,
    xsltMsgCB           xsltMsgCB,
    void              * xsltMsgClientData,
    char             ** errMsg,
    domDocument      ** resultDoc   
    )
................................................................................
        xs = (xsltState *) xsltCmdData;
    } else {
        xs = (xsltState *) xsltCompileStylesheet (xsltDoc, funcCB,
                                                  xpathFuncClientData,
                                                  1, errMsg);
        if (!xs) return -1;
    }
    xs->maxNestedApplyTemplates = maxApplyDepth;
    xs->nestedApplyTemplates = 0;
    
    if (xmlNode->nodeType == DOCUMENT_NODE) {
        xmlNode = ((domDocument *)xmlNode)->rootNode;
    } else {
        xmlNode = xmlNode->ownerDocument->rootNode;
    }
    DBG(printXML(xmlNode, 0, 1);)

................................................................................
    }
    return 0;

 error:
    xsltPopVarFrame (xs);
    xpathRSFree( &nodeList );
    domFreeDocument (xs->resultDoc, NULL, NULL);
    xs->resultDoc = NULL;
    if (xsltCmdData) {
        xsltResetState (xs);
    } else {
        xsltFreeState (xs);
    }
    return -1;

} /* xsltProcess */

Changes to generic/domxslt.h.

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

85
86
87
88
89
90
91
#ifndef __DOMXSLT_H__
#define __DOMXSLT_H__

#include <dom.h>
#include <domxpath.h>


typedef void (*xsltMsgCB) (void *clientData, char *str, 
                          int length, int terminate);

/*----------------------------------------------------------------------------
|   Prototypes
|
\---------------------------------------------------------------------------*/
int xsltProcess (domDocument       * xsltDoc,
                 domNode           * xmlNode,
                 void              * xsltCmdData,
                 char             ** parameters,
                 int                 ignoreUndeclaredParameters,

                 xpathFuncCallback   funcCB,
                 void              * xpathFuncClientData,
                 xsltMsgCB           xsltMsgCB,
                 void              * xsltMsgClientData,
                 char             ** errMsg,
                 domDocument      ** resultDoc
                );







|











>







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#ifndef __DOMXSLT_H__
#define __DOMXSLT_H__

#include <dom.h>
#include <domxpath.h>


typedef int (*xsltMsgCB) (void *clientData, char *str, 
                          int length, int terminate);

/*----------------------------------------------------------------------------
|   Prototypes
|
\---------------------------------------------------------------------------*/
int xsltProcess (domDocument       * xsltDoc,
                 domNode           * xmlNode,
                 void              * xsltCmdData,
                 char             ** parameters,
                 int                 ignoreUndeclaredParameters,
                 int                 maxApplyDepth,
                 xpathFuncCallback   funcCB,
                 void              * xpathFuncClientData,
                 xsltMsgCB           xsltMsgCB,
                 void              * xsltMsgClientData,
                 char             ** errMsg,
                 domDocument      ** resultDoc
                );

Deleted generic/encodings.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
/*------------------------------------------------------------------------
|   WARNING! This is file automatically generated by GenCompactCodings !  
|   WARNING!         Do not edit!                                         
|                                                                         
|   Unicode(UTF) ---> 8bit code conversion tables                         
|                                                                         
\-----------------------------------------------------------------------*/
static TEncodingRule TDOM_UnicodeToASCII [] = {
    { ENC_IDENTITY, 1, 126, "" }, 
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToCP1250 [] = {
    { ENC_IDENTITY, 1, 129, "" }, 
    { ENC_MAP, 131, 153, 
        "\203\077\077\077\210\077\077\077\077\077\077\077\220\077"
        "\077\077\077\077\077\077\230\077\077\077\077\077\077\077"
        "\240\077\077\077\244\077\246\247\250\251\077\253\077\255"
        "\256\077\260\261\077\077\264\265\266\267\270\077\077\273"
        "\077\077\077\077\077\301\302\077\304\077\077\307\077\311"
        "\077\313\077\315\316\077\077\077\077\323\324\077\326\327"
        "\077\077\332\077\334\335\077\337\077\341\342\077\344\077"
        "\077\347\077\351\077\353\077\355\356\077\077\077\077\363"
        "\364\077\366\367\077\077\372\077\374\375\077\077\077\077"
        "\303\343\245\271\306\346\077\077\077\077\310\350\317\357"
        "\320\360\077\077\077\077\077\077\312\352\314\354" },
    { ENC_MAP, 313, 70, 
        "\305\345\077\077\274\276\077\077\243\263\321\361\077\077"
        "\322\362\077\077\077\077\077\077\077\325\365\077\077\300"
        "\340\077\077\330\370\214\234\077\077\252\272\212\232\336"
        "\376\215\235\077\077\077\077\077\077\077\077\331\371\333"
        "\373\077\077\077\077\077\077\077\217\237\257\277\216\236"
    },
    { ENC_MAP, 711, 23, 
        "\241\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\077\077\242\377\077\262\077\275" },
    { ENC_MAP, 8211, 40, 
        "\226\227\077\077\077\221\222\202\077\223\224\204\077\206"
        "\207\225\077\077\077\205\077\077\077\077\077\077\077\077"
        "\077\211\077\077\077\077\077\077\077\077\213\233" },
    { ENC_MAP, 8482, 1, 
        "\231" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToCP1251 [] = {
    { ENC_IDENTITY, 1, 127, "" }, 
    { ENC_MAP, 136, 52, 
        "\210\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\230\077\077\077\077\077\077\077\240\077\077\077\244"
        "\077\246\247\077\251\077\253\254\255\256\077\260\261\077"
        "\077\077\265\266\267\077\077\077\273" },
    { ENC_MAP, 1025, 95, 
        "\250\200\201\252\275\262\257\243\212\214\216\215\077\241"
        "\217\300\301\302\303\304\305\306\307\310\311\312\313\314"
        "\315\316\317\320\321\322\323\324\325\326\327\330\331\332"
        "\333\334\335\336\337\340\341\342\343\344\345\346\347\350"
        "\351\352\353\354\355\356\357\360\361\362\363\364\365\366"
        "\367\370\371\372\373\374\375\376\377\077\270\220\203\272"
        "\276\263\277\274\232\234\236\235\077\242\237" },
    { ENC_MAP, 1168, 2, 
        "\245\264" },
    { ENC_MAP, 8211, 40, 
        "\226\227\077\077\077\221\222\202\077\223\224\204\077\206"
        "\207\225\077\077\077\205\077\077\077\077\077\077\077\077"
        "\077\211\077\077\077\077\077\077\077\077\213\233" },
    { ENC_MAP, 8470, 13, 
        "\271\077\077\077\077\077\077\077\077\077\077\077\231" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToCP1252 [] = {
    { ENC_IDENTITY, 1, 129, "" }, 
    { ENC_MAP, 141, 18, 
        "\215\216\217\220\077\077\077\077\077\077\077\077\235\236"
    },
    { ENC_IDENTITY, 160, 96, "" }, 
    { ENC_MAP, 338, 16, 
        "\214\234\077\077\077\077\077\077\077\077\077\077\077\077"
        "\212\232" },
    { ENC_MAP, 376, 1, 
        "\237" },
    { ENC_MAP, 402, 1, 
        "\203" },
    { ENC_MAP, 710, 1, 
        "\210" },
    { ENC_MAP, 732, 1, 
        "\230" },
    { ENC_MAP, 8211, 40, 
        "\226\227\077\077\077\221\222\202\077\223\224\204\077\206"
        "\207\225\077\077\077\205\077\077\077\077\077\077\077\077"
        "\077\211\077\077\077\077\077\077\077\077\213\233" },
    { ENC_MAP, 8482, 1, 
        "\231" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToCP1253 [] = {
    { ENC_IDENTITY, 1, 129, "" }, 
    { ENC_MAP, 136, 54, 
        "\210\212\077\214\215\216\217\220\077\077\077\077\077\077"
        "\077\230\077\232\077\234\235\236\237\240\077\077\243\244"
        "\245\246\247\250\251\077\253\254\255\256\077\260\261\262"
        "\263\077\265\266\267\077\077\077\273\077\275" },
    { ENC_MAP, 402, 1, 
        "\203" },
    { ENC_MAP, 900, 75, 
        "\264\241\242\077\270\271\272\077\274\077\276\277\300\301"
        "\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
        "\320\321\077\323\324\325\326\327\330\331\332\333\334\335"
        "\336\337\340\341\342\343\344\345\346\347\350\351\352\353"
        "\354\355\356\357\360\361\362\363\364\365\366\367\370\371"
        "\372\373\374\375\376" },
    { ENC_MAP, 8211, 40, 
        "\226\227\257\077\077\221\222\202\077\223\224\204\077\206"
        "\207\225\077\077\077\205\077\077\077\077\077\077\077\077"
        "\077\211\077\077\077\077\077\077\077\077\213\233" },
    { ENC_MAP, 8482, 1, 
        "\231" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToCP1254 [] = {
    { ENC_IDENTITY, 1, 129, "" }, 
    { ENC_MAP, 141, 115, 
        "\215\216\217\220\077\077\077\077\077\077\077\077\235\236"
        "\077\240\241\242\243\244\245\246\247\250\251\252\253\254"
        "\255\256\257\260\261\262\263\264\265\266\267\270\271\272"
        "\273\274\275\276\277\300\301\302\303\304\305\306\307\310"
        "\311\312\313\314\315\316\317\077\321\322\323\324\325\326"
        "\327\330\331\332\333\334\077\077\337\340\341\342\343\344"
        "\345\346\347\350\351\352\353\354\355\356\357\077\361\362"
        "\363\364\365\366\367\370\371\372\373\374\077\077\377" },
    { ENC_MAP, 286, 20, 
        "\320\360\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\077\077\077\335\375" },
    { ENC_MAP, 338, 16, 
        "\214\234\077\077\077\077\077\077\077\077\077\077\336\376"
        "\212\232" },
    { ENC_MAP, 376, 1, 
        "\237" },
    { ENC_MAP, 402, 1, 
        "\203" },
    { ENC_MAP, 710, 1, 
        "\210" },
    { ENC_MAP, 732, 1, 
        "\230" },
    { ENC_MAP, 8211, 40, 
        "\226\227\077\077\077\221\222\202\077\223\224\204\077\206"
        "\207\225\077\077\077\205\077\077\077\077\077\077\077\077"
        "\077\211\077\077\077\077\077\077\077\077\213\233" },
    { ENC_MAP, 8482, 1, 
        "\231" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToCP1255 [] = {
    { ENC_IDENTITY, 1, 129, "" }, 
    { ENC_MAP, 138, 53, 
        "\212\214\215\216\217\220\077\077\077\077\077\077\077\077"
        "\077\232\077\234\235\236\237\240\077\242\243\077\245\246"
        "\247\250\251\077\253\254\255\256\257\260\261\262\263\264"
        "\265\266\267\077\271\077\273\274\275\276" },
    { ENC_MAP, 402, 1, 
        "\203" },
    { ENC_MAP, 710, 1, 
        "\210" },
    { ENC_MAP, 732, 1, 
        "\230" },
    { ENC_MAP, 1456, 67, 
        "\300\301\302\303\304\305\306\307\310\311\312\313\314\315"
        "\316\317\320\321\322\323\077\077\077\077\077\077\077\077"
        "\077\077\077\077\340\341\342\343\344\345\346\347\350\351"
        "\352\353\354\355\356\357\360\361\362\363\364\365\366\367"
        "\370\371\372\077\077\077\077\077\324\325\326" },
    { ENC_MAP, 8206, 45, 
        "\375\376\077\077\077\226\227\077\077\077\221\222\202\077"
        "\223\224\204\077\206\207\225\077\077\077\205\077\077\077"
        "\077\077\077\077\077\077\211\077\077\077\077\077\077\077"
        "\077\213\233" },
    { ENC_MAP, 8362, 1, 
        "\244" },
    { ENC_MAP, 8482, 1, 
        "\231" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToCP1256 [] = {
    { ENC_IDENTITY, 1, 128, "" }, 
    { ENC_MAP, 138, 53, 
        "\212\077\077\077\217\077\077\077\077\077\077\077\077\230"
        "\077\232\077\077\077\077\237\240\077\242\243\244\245\246"
        "\247\250\251\077\253\254\255\256\257\260\261\262\263\264"
        "\265\266\267\270\271\077\273\274\275\276" },
    { ENC_MAP, 215, 38, 
        "\327\077\077\077\077\077\077\077\340\077\342\077\077\077"
        "\077\347\350\351\352\353\077\077\356\357\077\077\077\077"
        "\364\077\077\367\077\371\077\373\374" },
    { ENC_MAP, 338, 2, 
        "\214\234" },
    { ENC_MAP, 402, 1, 
        "\203" },
    { ENC_MAP, 710, 1, 
        "\210" },
    { ENC_MAP, 1548, 71, 
        "\241\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\272\077\077\077\277\077\301\302\303\304\305\306\307"
        "\310\311\312\313\314\315\316\317\320\321\322\323\324\325"
        "\326\330\331\332\333\077\077\077\077\077\334\335\336\337"
        "\341\343\344\345\346\354\355\360\361\362\363\365\366\370"
        "\372" },
    { ENC_MAP, 1662, 27, 
        "\201\077\077\077\077\077\077\077\215\077\077\077\077\077"
        "\077\077\077\077\077\077\077\077\077\077\077\077\216" },
    { ENC_MAP, 1711, 1, 
        "\220" },
    { ENC_MAP, 8204, 47, 
        "\235\236\375\376\077\077\077\226\227\077\077\077\221\222"
        "\202\077\223\224\204\077\206\207\225\077\077\077\205\077"
        "\077\077\077\077\077\077\077\077\211\077\077\077\077\077"
        "\077\077\077\213\233" },
    { ENC_MAP, 8482, 1, 
        "\231" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToCP437 [] = {
    { ENC_IDENTITY, 1, 127, "" }, 
    { ENC_MAP, 160, 96, 
        "\377\255\233\234\077\235\077\077\077\077\246\256\252\077"
        "\077\077\370\361\375\077\077\346\077\372\077\077\247\257"
        "\254\253\077\250\077\077\077\077\216\217\222\200\077\220"
        "\077\077\077\077\077\077\077\245\077\077\077\077\231\077"
        "\077\077\077\077\232\077\077\341\205\240\203\077\204\206"
        "\221\207\212\202\210\211\215\241\214\213\077\244\225\242"
        "\223\077\224\366\077\227\243\226\201\077\077\230" },
    { ENC_MAP, 402, 1, 
        "\237" },
    { ENC_MAP, 915, 52, 
        "\342\077\077\077\077\351\077\077\077\077\077\077\077\077"
        "\077\077\344\077\077\350\077\077\352\077\077\077\077\077"
        "\077\077\340\077\077\353\356\077\077\077\077\077\077\077"
        "\077\077\077\343\077\077\345\347\077\355" },
    { ENC_MAP, 8319, 1, 
        "\374" },
    { ENC_MAP, 8359, 1, 
        "\236" },
    { ENC_MAP, 8729, 17, 
        "\371\373\077\077\077\354\077\077\077\077\077\077\077\077"
        "\077\077\357" },
    { ENC_MAP, 8776, 1, 
        "\367" },
    { ENC_MAP, 8801, 5, 
        "\360\077\077\363\362" },
    { ENC_MAP, 8976, 18, 
        "\251\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\077\364\365" },
    { ENC_MAP, 9472, 161, 
        "\304\077\263\077\077\077\077\077\077\077\077\077\332\077"
        "\077\077\277\077\077\077\300\077\077\077\331\077\077\077"
        "\303\077\077\077\077\077\077\077\264\077\077\077\077\077"
        "\077\077\302\077\077\077\077\077\077\077\301\077\077\077"
        "\077\077\077\077\305\077\077\077\077\077\077\077\077\077"
        "\077\077\077\077\077\077\077\077\077\077\315\272\325\326"
        "\311\270\267\273\324\323\310\276\275\274\306\307\314\265"
        "\266\271\321\322\313\317\320\312\330\327\316\077\077\077"
        "\077\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\077\337\077\077\077\334\077\077\077\333\077\077\077"
        "\335\077\077\077\336\260\261\262\077\077\077\077\077\077"
        "\077\077\077\077\077\077\376" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToCP850 [] = {
    { ENC_IDENTITY, 1, 127, "" }, 
    { ENC_MAP, 160, 96, 
        "\377\255\275\234\317\276\335\365\371\270\246\256\252\360"
        "\251\356\370\361\375\374\357\346\364\372\367\373\247\257"
        "\254\253\363\250\267\265\266\307\216\217\222\200\324\220"
        "\322\323\336\326\327\330\321\245\343\340\342\345\231\236"
        "\235\353\351\352\232\355\350\341\205\240\203\306\204\206"
        "\221\207\212\202\210\211\215\241\214\213\320\244\225\242"
        "\223\344\224\366\233\227\243\226\201\354\347\230" },
    { ENC_MAP, 305, 1, 
        "\325" },
    { ENC_MAP, 402, 1, 
        "\237" },
    { ENC_MAP, 8215, 1, 
        "\362" },
    { ENC_MAP, 9472, 161, 
        "\304\077\263\077\077\077\077\077\077\077\077\077\332\077"
        "\077\077\277\077\077\077\300\077\077\077\331\077\077\077"
        "\303\077\077\077\077\077\077\077\264\077\077\077\077\077"
        "\077\077\302\077\077\077\077\077\077\077\301\077\077\077"
        "\077\077\077\077\305\077\077\077\077\077\077\077\077\077"
        "\077\077\077\077\077\077\077\077\077\077\315\272\077\077"
        "\311\077\077\273\077\077\310\077\077\274\077\077\314\077"
        "\077\271\077\077\313\077\077\312\077\077\316\077\077\077"
        "\077\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\077\337\077\077\077\334\077\077\077\333\077\077\077"
        "\077\077\077\077\077\260\261\262\077\077\077\077\077\077"
        "\077\077\077\077\077\077\376" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToISO88591 [] = {
    { ENC_IDENTITY, 1, 255, "" }, 
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToISO88592 [] = {
    { ENC_IDENTITY, 1, 160, "" }, 
    { ENC_MAP, 164, 120, 
        "\244\077\247\250\077\077\077\077\255\077\077\260\077\077"
        "\077\264\077\077\077\270\077\077\077\077\077\077\077\077"
        "\301\302\077\304\077\077\307\077\311\077\313\077\315\316"
        "\077\077\077\077\323\324\077\326\327\077\077\332\077\334"
        "\335\077\337\077\341\342\077\344\077\077\347\077\351\077"
        "\353\077\355\356\077\077\077\077\363\364\077\366\367\077"
        "\077\372\077\374\375\077\077\077\077\303\343\241\261\306"
        "\346\077\077\077\077\310\350\317\357\320\360\077\077\077"
        "\077\077\077\312\352\314\354" },
    { ENC_MAP, 313, 70, 
        "\305\345\077\077\245\265\077\077\243\263\321\361\077\077"
        "\322\362\077\077\077\077\077\077\077\325\365\077\077\300"
        "\340\077\077\330\370\246\266\077\077\252\272\251\271\336"
        "\376\253\273\077\077\077\077\077\077\077\077\331\371\333"
        "\373\077\077\077\077\077\077\077\254\274\257\277\256\276"
    },
    { ENC_MAP, 711, 23, 
        "\267\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\077\077\242\377\077\262\077\275" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToISO88593 [] = {
    { ENC_IDENTITY, 1, 160, "" }, 
    { ENC_MAP, 163, 147, 
        "\243\244\247\250\077\077\077\077\255\077\077\260\077\262"
        "\263\264\265\077\267\270\077\077\077\077\275\077\077\300"
        "\301\302\077\304\077\077\307\310\311\312\313\314\315\316"
        "\317\077\321\322\323\324\077\326\327\077\331\332\333\334"
        "\077\077\337\340\341\342\077\344\077\077\347\350\351\352"
        "\353\354\355\356\357\077\361\362\363\364\077\366\367\077"
        "\371\372\373\374\077\077\077\077\077\077\077\077\077\077"
        "\077\306\346\305\345\077\077\077\077\077\077\077\077\077"
        "\077\077\077\077\077\077\077\330\370\253\273\325\365\077"
        "\077\246\266\241\261\077\077\077\077\077\077\077\077\251"
        "\271\077\077\254\274" },
    { ENC_MAP, 348, 33, 
        "\336\376\252\272\077\077\077\077\077\077\077\077\077\077"
        "\077\077\335\375\077\077\077\077\077\077\077\077\077\077"
        "\077\077\077\257\277" },
    { ENC_MAP, 728, 2, 
        "\242\377" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToISO88594 [] = {
    { ENC_IDENTITY, 1, 160, "" }, 
    { ENC_MAP, 164, 219, 
        "\244\077\247\250\077\077\077\077\255\077\257\260\077\077"
        "\077\264\077\077\077\270\077\077\077\077\077\077\077\077"
        "\301\302\303\304\305\306\077\077\311\077\313\077\315\316"
        "\077\077\077\077\077\324\325\326\327\330\077\332\333\334"
        "\077\077\337\077\341\342\343\344\345\346\077\077\351\077"
        "\353\077\355\356\077\077\077\077\077\364\365\366\367\370"
        "\077\372\373\374\077\077\077\300\340\077\077\241\261\077"
        "\077\077\077\077\077\310\350\077\077\320\360\252\272\077"
        "\077\314\354\312\352\077\077\077\077\077\077\077\077\253"
        "\273\077\077\077\077\245\265\317\357\077\077\307\347\077"
        "\077\077\077\077\077\323\363\242\077\077\246\266\077\077"
        "\077\077\077\077\077\077\321\361\077\077\077\275\277\322"
        "\362\077\077\077\077\077\077\077\077\243\263\077\077\077"
        "\077\077\077\077\077\251\271\077\077\077\077\254\274\335"
        "\375\336\376\077\077\077\077\077\077\331\371\077\077\077"
        "\077\077\077\077\077\077\256\276" },
    { ENC_MAP, 711, 21, 
        "\267\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\077\077\077\377\077\262" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToISO88595 [] = {
    { ENC_IDENTITY, 1, 160, "" }, 
    { ENC_MAP, 167, 7, 
        "\375\077\077\077\077\077\255" },
    { ENC_MAP, 1025, 95, 
        "\241\242\243\244\245\246\247\250\251\252\253\254\077\256"
        "\257\260\261\262\263\264\265\266\267\270\271\272\273\274"
        "\275\276\277\300\301\302\303\304\305\306\307\310\311\312"
        "\313\314\315\316\317\320\321\322\323\324\325\326\327\330"
        "\331\332\333\334\335\336\337\340\341\342\343\344\345\346"
        "\347\350\351\352\353\354\355\356\357\077\361\362\363\364"
        "\365\366\367\370\371\372\373\374\077\376\377" },
    { ENC_MAP, 8470, 1, 
        "\360" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToISO88596 [] = {
    { ENC_IDENTITY, 1, 47, "" }, 
    { ENC_IDENTITY, 58, 103, "" }, 
    { ENC_MAP, 164, 10, 
        "\244\077\077\077\077\077\077\077\255" },
    { ENC_MAP, 1548, 94, 
        "\254\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\273\077\077\077\277\077\301\302\303\304\305\306\307"
        "\310\311\312\313\314\315\316\317\320\321\322\323\324\325"
        "\326\327\330\331\332\077\077\077\077\077\340\341\342\343"
        "\344\345\346\347\350\351\352\353\354\355\356\357\360\361"
        "\362\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\060\061\062\063\064\065\066\067\070\071" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToISO88597 [] = {
    { ENC_IDENTITY, 1, 160, "" }, 
    { ENC_MAP, 163, 27, 
        "\243\077\246\247\250\251\077\253\254\255\077\077\260\261"
        "\262\263\077\077\077\267\077\077\077\273\077\275" },
    { ENC_MAP, 700, 2, 
        "\242\241" },
    { ENC_MAP, 900, 75, 
        "\264\265\266\077\270\271\272\077\274\077\276\277\300\301"
        "\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
        "\320\321\077\323\324\325\326\327\330\331\332\333\334\335"
        "\336\337\340\341\342\343\344\345\346\347\350\351\352\353"
        "\354\355\356\357\360\361\362\363\364\365\366\367\370\371"
        "\372\373\374\375\376" },
    { ENC_MAP, 8213, 1, 
        "\257" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToISO88598 [] = {
    { ENC_IDENTITY, 1, 160, "" }, 
    { ENC_MAP, 162, 54, 
        "\242\243\244\245\246\247\250\251\253\254\255\256\260\261"
        "\262\263\264\265\266\267\270\271\273\274\275\276\077\077"
        "\077\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\077\077\252" },
    { ENC_MAP, 247, 1, 
        "\272" },
    { ENC_MAP, 1488, 27, 
        "\340\341\342\343\344\345\346\347\350\351\352\353\354\355"
        "\356\357\360\361\362\363\364\365\366\367\370\371\372" },
    { ENC_MAP, 8215, 1, 
        "\337" },
    { ENC_MAP, 8254, 1, 
        "\257" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToISO88599 [] = {
    { ENC_IDENTITY, 1, 207, "" }, 
    { ENC_MAP, 209, 54, 
        "\321\322\323\324\325\326\327\330\331\332\333\334\337\340"
        "\341\342\343\344\345\346\347\350\351\352\353\354\355\356"
        "\357\361\362\363\364\365\366\367\370\371\372\373\374\377"
    },
    { ENC_MAP, 286, 20, 
        "\320\360\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\077\077\077\335\375" },
    { ENC_MAP, 350, 2, 
        "\336\376" },
    { ENC_END, 0, 0, NULL } 
};

static TEncodingRule TDOM_UnicodeToKOI8R [] = {
    { ENC_IDENTITY, 1, 127, "" }, 
    { ENC_MAP, 160, 24, 
        "\232\077\077\077\077\077\077\077\077\277\077\077\077\077"
        "\077\077\234\077\235\077\077\077\077\236" },
    { ENC_MAP, 247, 1, 
        "\237" },
    { ENC_MAP, 1025, 81, 
        "\263\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\341\342\367\347\344\345\366\372\351\352\353\354\355"
        "\356\357\360\362\363\364\365\346\350\343\376\373\375\377"
        "\371\370\374\340\361\301\302\327\307\304\305\326\332\311"
        "\312\313\314\315\316\317\320\322\323\324\325\306\310\303"
        "\336\333\335\337\331\330\334\300\321\077\243" },
    { ENC_MAP, 8729, 2, 
        "\225\226" },
    { ENC_MAP, 8776, 1, 
        "\227" },
    { ENC_MAP, 8804, 2, 
        "\230\231" },
    { ENC_MAP, 8992, 2, 
        "\223\233" },
    { ENC_MAP, 9472, 161, 
        "\200\077\201\077\077\077\077\077\077\077\077\077\202\077"
        "\077\077\203\077\077\077\204\077\077\077\205\077\077\077"
        "\206\077\077\077\077\077\077\077\207\077\077\077\077\077"
        "\077\077\210\077\077\077\077\077\077\077\211\077\077\077"
        "\077\077\077\077\212\077\077\077\077\077\077\077\077\077"
        "\077\077\077\077\077\077\077\077\077\077\240\241\242\244"
        "\245\246\247\250\251\252\253\254\255\256\257\260\261\262"
        "\264\265\266\267\270\271\272\273\274\275\276\077\077\077"
        "\077\077\077\077\077\077\077\077\077\077\077\077\077\077"
        "\077\077\213\077\077\077\214\077\077\077\215\077\077\077"
        "\216\077\077\077\217\220\221\222\077\077\077\077\077\077"
        "\077\077\077\077\077\077\224" },
    { ENC_END, 0, 0, NULL } 
};


static TEncoding TDOM_UnicodeTo8bitEncodings [] = {
    { "ascii"     , 0x3F, TDOM_UnicodeToASCII },
    { "cp1250"    , 0x3F, TDOM_UnicodeToCP1250 },
    { "cp1251"    , 0x3F, TDOM_UnicodeToCP1251 },
    { "cp1252"    , 0x3F, TDOM_UnicodeToCP1252 },
    { "cp1253"    , 0x3F, TDOM_UnicodeToCP1253 },
    { "cp1254"    , 0x3F, TDOM_UnicodeToCP1254 },
    { "cp1255"    , 0x3F, TDOM_UnicodeToCP1255 },
    { "cp1256"    , 0x3F, TDOM_UnicodeToCP1256 },
    { "cp437"     , 0x3F, TDOM_UnicodeToCP437 },
    { "cp850"     , 0x3F, TDOM_UnicodeToCP850 },
    { "iso8859-1" , 0x3F, TDOM_UnicodeToISO88591 },
    { "iso8859-2" , 0x3F, TDOM_UnicodeToISO88592 },
    { "iso8859-3" , 0x3F, TDOM_UnicodeToISO88593 },
    { "iso8859-4" , 0x3F, TDOM_UnicodeToISO88594 },
    { "iso8859-5" , 0x3F, TDOM_UnicodeToISO88595 },
    { "iso8859-6" , 0x3F, TDOM_UnicodeToISO88596 },
    { "iso8859-7" , 0x3F, TDOM_UnicodeToISO88597 },
    { "iso8859-8" , 0x3F, TDOM_UnicodeToISO88598 },
    { "iso8859-9" , 0x3F, TDOM_UnicodeToISO88599 },
    { "koi8-r"    , 0x3F, TDOM_UnicodeToKOI8R },
    { NULL, 0, NULL }
};
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to generic/nodecmd.c.

84
85
86
87
88
89
90


91
92
93
94
95
96
97
..
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
...
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
...
195
196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
...
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
...
260
261
262
263
264
265
266



267
268
269
270
271
272
273
274
275
276
277
278
279
280

281
282
283
284

285
286
287
288
289
290
291
...
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362
363
364
365
...
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404
405


406

407

408
409
410
411
412
413
414
...
500
501
502
503
504
505
506
507
508
509
510
511
512
513

514

515

516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533



















534
535
536

537
538
539



540


541










542
543
544
545


546


















547
548
549
550
551
552
553
554
...
560
561
562
563
564
565
566
567
568
569
570
571
572
573


574
575
576
577
578
579
580
581
582
583
584









585
586
587
588
589
590
591

592
593
594










595
596
597
598
599
600
601
...
616
617
618
619
620
621
622



623
624




















625
626
627
628








629
630
631
632
633
634
635
636
637



638
639
640
641
642
643
644
...
654
655
656
657
658
659
660
661
662
663
664
665

666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
...
723
724
725
726
727
728
729
730
731
732
733
734
735
736

737
738
739
740
741
742
743
|   The structure stores, which type of node the command has
|   to create and, in case of elementNodes and if given, the
|   namespace of the node.
\---------------------------------------------------------------------------*/
typedef struct NodeInfo {
    int   type;
    char *namespace;


} NodeInfo;

#ifndef TCL_THREADS
  static CurrentStack dataKey;
# define TSDPTR(a) a
#else
  static Tcl_ThreadDataKey dataKey;
................................................................................
# define TSDPTR(a) (CurrentStack*)Tcl_GetThreadData((a),sizeof(CurrentStack))
#endif

/*----------------------------------------------------------------------------
|   Forward declarations
|
\---------------------------------------------------------------------------*/
static void * StackPush  _ANSI_ARGS_((void *));
static void * StackPop   _ANSI_ARGS_((void));
static void * StackTop   _ANSI_ARGS_((void));
static int    NodeObjCmd _ANSI_ARGS_((ClientData,Tcl_Interp*,int,Tcl_Obj *CONST o[]));
static void   StackFinalize _ANSI_ARGS_((ClientData));

extern int tcldom_appendXML (Tcl_Interp*, domNode*, Tcl_Obj*);


/*----------------------------------------------------------------------------
|   StackPush
|
\---------------------------------------------------------------------------*/
static void *
StackPush (element)
    void *element;
{

    StackSlot *newElement;
    CurrentStack *tsdPtr = TSDPTR(&dataKey);

    /*-------------------------------------------------------------------
    |   Reuse already allocated stack slots, if any
    |
    \------------------------------------------------------------------*/
................................................................................
}

/*----------------------------------------------------------------------------
|   StackPop  -  pops the element from stack
|
\---------------------------------------------------------------------------*/
static void *
StackPop ()
{
    void *element;
    CurrentStack *tsdPtr = TSDPTR(&dataKey);

    element = tsdPtr->currentSlot->element;
    if (tsdPtr->currentSlot->prevPtr) {
        tsdPtr->currentSlot = tsdPtr->currentSlot->prevPtr;
................................................................................
}

/*----------------------------------------------------------------------------
|   StackTop  -  returns top-level element from stack
|
\---------------------------------------------------------------------------*/
static void *
StackTop ()
{
    CurrentStack *tsdPtr = TSDPTR(&dataKey);

    if (tsdPtr->currentSlot == NULL) {
        return NULL;
    }

................................................................................


/*----------------------------------------------------------------------------
|   StackFinalize - reclaims stack memory (slots only, not elements)
|
\---------------------------------------------------------------------------*/
static void
StackFinalize (clientData)
    ClientData clientData;
{

    StackSlot *tmp, *stack = (StackSlot *)clientData;

    while (stack) {
        tmp = stack->nextPtr;
        FREE((char*)stack);
        stack = tmp;
    }
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
static char*
namespaceTail (nameObj) 
    Tcl_Obj *nameObj;

{
    char *name,*p;
    int   len;
    
    name = Tcl_GetStringFromObj(nameObj, &len);
    p = name + len;
    /* Isolate just the tail name, i.e. skip it's parent namespace */
................................................................................
    )
{
    NodeInfo *nodeInfo = (NodeInfo *) clientData;
    
    if (nodeInfo->namespace) {
        FREE (nodeInfo->namespace);
    }



    FREE (nodeInfo);
}

/*----------------------------------------------------------------------------
|   NodeObjCmd
|
\---------------------------------------------------------------------------*/
static int
NodeObjCmd (arg, interp, objc, objv)
    ClientData      arg;                /* Type of node to create. */
    Tcl_Interp    * interp;             /* Current interpreter. */
    int             objc;               /* Number of arguments. */
    Tcl_Obj *CONST  objv[];             /* Argument objects. */
{

    int type, createType, len, dlen, i, ret, disableOutputEscaping = 0, 
        index = 1;
    char *tag, *p, *tval, *aval;
    domNode *parent, *newNode = NULL;

    domDocument *doc;
    Tcl_Obj *cmdObj, **opts;
    NodeInfo *nodeInfo = (NodeInfo*) arg;

    /*------------------------------------------------------------------------
    |   Need parent node to get the owner document and to append new 
    |   child tag to it. The current parent node is stored on the stack.
................................................................................
            if (!tcldom_CDATACheck (interp, tval)) return TCL_ERROR;
            createType = CDATA_SECTION_NODE;
            break;
        default:
            createType = nodeInfo->type;
            break;
        }
        newNode = (domNode*)domNewTextNode(doc, tval, len, createType);

        if (disableOutputEscaping) {
            newNode->nodeFlags |= DISABLE_OUTPUT_ESCAPING;
        }
        domAppendChild(parent, newNode);
        break;

    case PROCESSING_INSTRUCTION_NODE_NAME_CHK:
    case PROCESSING_INSTRUCTION_NODE_VALUE_CHK:
    case PROCESSING_INSTRUCTION_NODE_CHK:
    case PROCESSING_INSTRUCTION_NODE:
        if (objc != 3) {
................................................................................
        ret = tcldom_appendXML(interp, parent, objv[1]);
        break;

    case ELEMENT_NODE_ANAME_CHK:
    case ELEMENT_NODE_AVALUE_CHK:
    case ELEMENT_NODE_CHK:
    case ELEMENT_NODE:

        tag = Tcl_GetStringFromObj(objv[0], &len);
        p = tag + len;
        /* Isolate just the tag name, i.e. skip it's parent namespace */
        while (--p > tag) {
            if ((*p == ':') && (*(p-1) == ':')) {
                p++; /* just after the last "::" */
                tag = p;
                break;
            }
        }




        newNode = domAppendNewElementNode (parent, tag, NULL);

        
        /*
         * Allow for following syntax:
         *   cmd ?-option value ...? ?script?
         *   cmd ?opton value ...? ?script?
         *   cmd key_value_list script
         *       where list contains "-key value ..." or "key value ..."
................................................................................
|           set title [html::title {html::t "This is an example"}]
|           $title setAttribute dummy 1
|      }
|      % puts [$n asHTML]
|
\---------------------------------------------------------------------------*/
int
nodecmd_createNodeCmd (interp, objc, objv, checkName, checkCharData)
    Tcl_Interp    * interp;             /* Current interpreter. */
    int             objc;               /* Number of arguments. */
    Tcl_Obj *CONST  objv[];             /* Argument objects. */
    int             checkName;          /* Flag: Name checks? */
    int             checkCharData;      /* Flag: Data checks? */
{

    int ix, index, ret, type, nodecmd = 0;

    char *nsName, buf[64];

    Tcl_DString cmdName;
    NodeInfo *nodeInfo;

    /*
     * Syntax:  
     *
     *     dom createNodeCmd ?-returnNodeCmd? nodeType commandName
     */

    enum subCmd {
        ELM_NODE, TXT_NODE, CDS_NODE, CMT_NODE, PIC_NODE, PRS_NODE
    };

    static CONST84 char *subcmds[] = {
        "elementNode", "textNode", "cdataNode", "commentNode", "piNode",
        "parserNode", NULL
    };




















    if (objc != 3 && objc != 4) {
        goto usage;
    }

    if (objc == 4) {
        if (strcmp(Tcl_GetString(objv[1]), "-returnNodeCmd")) {
            goto usage;



        }


        nodecmd = 1;










        ix = 2;
    } else {
        nodecmd = 0;
        ix = 1;


    }


















    ret = Tcl_GetIndexFromObj(interp, objv[ix], subcmds, "option", 0, &index);
    if (ret != TCL_OK) {
        return ret;
    }

    /*--------------------------------------------------------------------
    |   Construct fully qualified command name using current namespace
    |
................................................................................
        return ret;
    }
    nsName = (char *)Tcl_GetStringResult(interp);
    Tcl_DStringAppend(&cmdName, nsName, -1);
    if (strcmp(nsName, "::")) {
        Tcl_DStringAppend(&cmdName, "::", 2);
    }
    Tcl_DStringAppend(&cmdName, Tcl_GetString(objv[ix+1]), -1);

    nodeInfo = (NodeInfo *) MALLOC (sizeof (NodeInfo));
    nodeInfo->namespace = NULL;
    Tcl_ResetResult (interp);
    switch ((enum subCmd)index) {
    case ELM_NODE: 


        if (!tcldom_nameCheck(interp, namespaceTail(objv[ix+1]), "tag", 0)) {
            FREE (nodeInfo);
            return TCL_ERROR;
        }
        if (checkName && checkCharData) {
            type = ELEMENT_NODE_CHK;
        } else if (checkName) {
            type = ELEMENT_NODE_ANAME_CHK;
        } else if (checkCharData) {
            type = ELEMENT_NODE_AVALUE_CHK;
        } else {









            type = ELEMENT_NODE;
        }
        break;
    case PRS_NODE: 
        type = PARSER_NODE;
        break;
    case TXT_NODE: 

        if (checkCharData) {
            type = TEXT_NODE_CHK;
        } else {










            type = TEXT_NODE;
        }
        break;
    case CDS_NODE: 
        if (checkCharData) {
            type = CDATA_SECTION_NODE_CHK;
        } else {
................................................................................
            type = PROCESSING_INSTRUCTION_NODE_NAME_CHK;
        } else if (checkCharData) {
            type = PROCESSING_INSTRUCTION_NODE_VALUE_CHK;
        } else {
            type = PROCESSING_INSTRUCTION_NODE;
        }
        break;



    }
    




















    nodeInfo->type = type;
    if (nodecmd) {
        nodeInfo->type *= -1; /* Signal this fact */
    }








    Tcl_CreateObjCommand(interp, Tcl_DStringValue(&cmdName), NodeObjCmd,
                         (ClientData)nodeInfo, NodeObjCmdDeleteProc);
    Tcl_DStringResult(interp, &cmdName);
    Tcl_DStringFree(&cmdName);

    return TCL_OK;

 usage:
    Tcl_AppendResult(interp, "dom createNodeCmd ?-returnNodeCmd?"



                     " nodeType cmdName", NULL);
    return TCL_ERROR;
}

 
/*
 *----------------------------------------------------------------------
................................................................................
 * Side effects:
 *	Appends new child nodes to node.
 *
 *----------------------------------------------------------------------
 */

int
nodecmd_appendFromScript (interp, node, cmdObj)
    Tcl_Interp *interp;                 /* Current interpreter. */
    domNode    *node;                   /* Parent dom node */
    Tcl_Obj    *cmdObj;                 /* Argument objects. */
{

    int ret;
    domNode *oldLastChild, *child, *nextChild;

    if (node->nodeType != ELEMENT_NODE) {
        Tcl_SetResult (interp, "NOT_AN_ELEMENT : can't append nodes", NULL);
        return TCL_ERROR;
    }
    
    oldLastChild = node->lastChild;

    StackPush((void *)node);
    Tcl_AllowExceptions(interp);
    ret = Tcl_EvalObj(interp, cmdObj);
    if (ret != TCL_ERROR) {
        Tcl_ResetResult(interp);
    }
    StackPop();

    if (ret == TCL_ERROR) {
        if (oldLastChild) {
................................................................................
 * Side effects:
 *	Insert new child nodes before referenceChild to node.
 *
 *----------------------------------------------------------------------
 */

int
nodecmd_insertBeforeFromScript (interp, node, cmdObj, refChild)
    Tcl_Interp *interp;                 /* Current interpreter. */
    domNode    *node;                   /* Parent dom node */
    Tcl_Obj    *cmdObj;                 /* Argument objects. */
    domNode    *refChild;               /* Insert new childs before this
                                         * node; may be NULL */
{

    int      ret;
    domNode *storedLastChild, *n;

    if (!refChild) {
        return nodecmd_appendFromScript (interp, node, cmdObj);
    }
    







>
>







 







|
|
|
|
|









|
|
<
>







 







|







 







|







 







|
|
<
>







 







|
|
>







 







>
>
>








|
|
|
|
|
<
>




>







 







|
>

|

|







 







>
|
|
|
|
|
|
|
|
|
|
>
>
|
>
|
>







 







|
|
|
|
|
|
<
>
|
>

>













|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|


>
|
<
<
>
>
>

>
>
|
>
>
>
>
>
>
>
>
>
>
|
<
<
<
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







 







|

<
<



>
>
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>







>
|
|
|
>
>
>
>
>
>
>
>
>
>







 







>
>
>

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




>
>
>
>
>
>
>
>








|
>
>
>







 







|
|
|
|
<
>












|







 







|
|
|
|
|

<
>







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
...
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
...
197
198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213
...
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
293
294
295
296
297
298
...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
...
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
...
513
514
515
516
517
518
519
520
521
522
523
524
525

526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572


573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590



591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
...
625
626
627
628
629
630
631
632
633


634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
...
773
774
775
776
777
778
779
780
781
782
783

784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
...
842
843
844
845
846
847
848
849
850
851
852
853
854

855
856
857
858
859
860
861
862
|   The structure stores, which type of node the command has
|   to create and, in case of elementNodes and if given, the
|   namespace of the node.
\---------------------------------------------------------------------------*/
typedef struct NodeInfo {
    int   type;
    char *namespace;
    int   jsonType;
    char *tagName;
} NodeInfo;

#ifndef TCL_THREADS
  static CurrentStack dataKey;
# define TSDPTR(a) a
#else
  static Tcl_ThreadDataKey dataKey;
................................................................................
# define TSDPTR(a) (CurrentStack*)Tcl_GetThreadData((a),sizeof(CurrentStack))
#endif

/*----------------------------------------------------------------------------
|   Forward declarations
|
\---------------------------------------------------------------------------*/
static void * StackPush  (void *);
static void * StackPop   (void);
static void * StackTop   (void);
static int    NodeObjCmd (ClientData,Tcl_Interp*,int,Tcl_Obj *const o[]);
static void   StackFinalize (ClientData);

extern int tcldom_appendXML (Tcl_Interp*, domNode*, Tcl_Obj*);


/*----------------------------------------------------------------------------
|   StackPush
|
\---------------------------------------------------------------------------*/
static void *
StackPush (
    void *element

) {
    StackSlot *newElement;
    CurrentStack *tsdPtr = TSDPTR(&dataKey);

    /*-------------------------------------------------------------------
    |   Reuse already allocated stack slots, if any
    |
    \------------------------------------------------------------------*/
................................................................................
}

/*----------------------------------------------------------------------------
|   StackPop  -  pops the element from stack
|
\---------------------------------------------------------------------------*/
static void *
StackPop (void)
{
    void *element;
    CurrentStack *tsdPtr = TSDPTR(&dataKey);

    element = tsdPtr->currentSlot->element;
    if (tsdPtr->currentSlot->prevPtr) {
        tsdPtr->currentSlot = tsdPtr->currentSlot->prevPtr;
................................................................................
}

/*----------------------------------------------------------------------------
|   StackTop  -  returns top-level element from stack
|
\---------------------------------------------------------------------------*/
static void *
StackTop (void)
{
    CurrentStack *tsdPtr = TSDPTR(&dataKey);

    if (tsdPtr->currentSlot == NULL) {
        return NULL;
    }

................................................................................


/*----------------------------------------------------------------------------
|   StackFinalize - reclaims stack memory (slots only, not elements)
|
\---------------------------------------------------------------------------*/
static void
StackFinalize (
    ClientData clientData

) {
    StackSlot *tmp, *stack = (StackSlot *)clientData;

    while (stack) {
        tmp = stack->nextPtr;
        FREE((char*)stack);
        stack = tmp;
    }
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */
static char*
namespaceTail (
    Tcl_Obj *nameObj
)    
{
    char *name,*p;
    int   len;
    
    name = Tcl_GetStringFromObj(nameObj, &len);
    p = name + len;
    /* Isolate just the tail name, i.e. skip it's parent namespace */
................................................................................
    )
{
    NodeInfo *nodeInfo = (NodeInfo *) clientData;
    
    if (nodeInfo->namespace) {
        FREE (nodeInfo->namespace);
    }
    if (nodeInfo->tagName) {
        FREE (nodeInfo->tagName);
    }
    FREE (nodeInfo);
}

/*----------------------------------------------------------------------------
|   NodeObjCmd
|
\---------------------------------------------------------------------------*/
static int
NodeObjCmd (
    ClientData      arg,                /* Type of node to create. */
    Tcl_Interp    * interp,             /* Current interpreter. */
    int             objc,               /* Number of arguments. */
    Tcl_Obj *const  objv[]             /* Argument objects. */

) {
    int type, createType, len, dlen, i, ret, disableOutputEscaping = 0, 
        index = 1;
    char *tag, *p, *tval, *aval;
    domNode *parent, *newNode = NULL;
    domTextNode *textNode = NULL;
    domDocument *doc;
    Tcl_Obj *cmdObj, **opts;
    NodeInfo *nodeInfo = (NodeInfo*) arg;

    /*------------------------------------------------------------------------
    |   Need parent node to get the owner document and to append new 
    |   child tag to it. The current parent node is stored on the stack.
................................................................................
            if (!tcldom_CDATACheck (interp, tval)) return TCL_ERROR;
            createType = CDATA_SECTION_NODE;
            break;
        default:
            createType = nodeInfo->type;
            break;
        }
        textNode = domNewTextNode(doc, tval, len, createType);
        textNode->info = nodeInfo->jsonType;
        if (disableOutputEscaping) {
            textNode->nodeFlags |= DISABLE_OUTPUT_ESCAPING;
        }
        domAppendChild(parent, (domNode*) textNode);
        break;

    case PROCESSING_INSTRUCTION_NODE_NAME_CHK:
    case PROCESSING_INSTRUCTION_NODE_VALUE_CHK:
    case PROCESSING_INSTRUCTION_NODE_CHK:
    case PROCESSING_INSTRUCTION_NODE:
        if (objc != 3) {
................................................................................
        ret = tcldom_appendXML(interp, parent, objv[1]);
        break;

    case ELEMENT_NODE_ANAME_CHK:
    case ELEMENT_NODE_AVALUE_CHK:
    case ELEMENT_NODE_CHK:
    case ELEMENT_NODE:
        if (!nodeInfo->tagName) {
            tag = Tcl_GetStringFromObj(objv[0], &len);
            p = tag + len;
            /* Isolate just the tag name, i.e. skip it's parent namespace */
            while (--p > tag) {
                if ((*p == ':') && (*(p-1) == ':')) {
                    p++; /* just after the last "::" */
                    tag = p;
                    break;
                }
            }
        } else {
            tag = nodeInfo->tagName;
        }

        newNode = domAppendNewElementNode (parent, tag, nodeInfo->namespace);
        newNode->info = nodeInfo->jsonType;
        
        /*
         * Allow for following syntax:
         *   cmd ?-option value ...? ?script?
         *   cmd ?opton value ...? ?script?
         *   cmd key_value_list script
         *       where list contains "-key value ..." or "key value ..."
................................................................................
|           set title [html::title {html::t "This is an example"}]
|           $title setAttribute dummy 1
|      }
|      % puts [$n asHTML]
|
\---------------------------------------------------------------------------*/
int
nodecmd_createNodeCmd (
    Tcl_Interp    * interp,             /* Current interpreter. */
    int             objc,               /* Number of arguments. */
    Tcl_Obj *const  objv[],             /* Argument objects. */
    int             checkName,          /* Flag: Name checks? */
    int             checkCharData       /* Flag: Data checks? */

) {
    int index, ret, type, nodecmd = 0, jsonType = 0, haveJsonType = 0;
    int isElement = 0;
    char *nsName, buf[64];
    Tcl_Obj *tagName = NULL, *namespace = NULL;
    Tcl_DString cmdName;
    NodeInfo *nodeInfo;

    /*
     * Syntax:  
     *
     *     dom createNodeCmd ?-returnNodeCmd? nodeType commandName
     */

    enum subCmd {
        ELM_NODE, TXT_NODE, CDS_NODE, CMT_NODE, PIC_NODE, PRS_NODE
    };

    static const char *subcmds[] = {
        "elementNode", "textNode", "cdataNode", "commentNode", "piNode",
        "parserNode", NULL
    };

    static const char *options[] = {
        "-returnNodeCmd", "-jsonType", "-tagName", "-namespace", NULL
    };

    enum option {
        o_returnNodeCmd, o_jsonType, o_tagName, o_namespace
    };

    static const char *jsonTypes[] = {
        "NONE",
        "ARRAY",
        "OBJECT",
        "NULL",
        "TRUE",
        "FALSE",
        "STRING",
        "NUMBER"
    };

    if (objc < 3 ) {
        goto usage;
    }

    while (objc > 3) {


        if (Tcl_GetIndexFromObj (interp, objv[1], options, "option",
                                 0, &index) != TCL_OK) {
            return TCL_ERROR;
        }
        switch ((enum option) index) {
        case o_returnNodeCmd:
            nodecmd = 1;
            objc--;
            objv++;
            break;
            
        case o_jsonType:
            if (Tcl_GetIndexFromObj (interp, objv[2], jsonTypes, "jsonType",
                                     1, &jsonType) != TCL_OK) {
                return TCL_ERROR;
            }
            haveJsonType = 1;
            objc -= 2;



            objv += 2;
            break;
            
        case o_tagName:
            tagName = objv[2];
            objc -= 2;
            objv += 2;
            break;

        case o_namespace:
            namespace = objv[2];
            objc -= 2;
            objv += 2;
            break;
            
        }
    }
    if (objc != 3) {
        goto usage;
    }

    ret = Tcl_GetIndexFromObj(interp, objv[1], subcmds, "nodeType", 0, &index);
    if (ret != TCL_OK) {
        return ret;
    }

    /*--------------------------------------------------------------------
    |   Construct fully qualified command name using current namespace
    |
................................................................................
        return ret;
    }
    nsName = (char *)Tcl_GetStringResult(interp);
    Tcl_DStringAppend(&cmdName, nsName, -1);
    if (strcmp(nsName, "::")) {
        Tcl_DStringAppend(&cmdName, "::", 2);
    }
    Tcl_DStringAppend(&cmdName, Tcl_GetString(objv[2]), -1);



    Tcl_ResetResult (interp);
    switch ((enum subCmd)index) {
    case ELM_NODE: 
        isElement = 1;
        if (!haveJsonType) {
            if (!tcldom_nameCheck(interp, namespaceTail(objv[2]),
                                  "tag", 0)) {
                return TCL_ERROR;
            }
            if (checkName && checkCharData) {
                type = ELEMENT_NODE_CHK;
            } else if (checkName) {
                type = ELEMENT_NODE_ANAME_CHK;
            } else if (checkCharData) {
                type = ELEMENT_NODE_AVALUE_CHK;
            } else {
                type = ELEMENT_NODE;
            }
        } else {
            if (jsonType > 2) {
                Tcl_SetResult(interp, "For an element node the jsonType"
                              " argument must be one out of this list: ARRAY"
                              " OBJECT NONE.", NULL);
                return TCL_ERROR;
            }
            type = ELEMENT_NODE;
        }
        break;
    case PRS_NODE: 
        type = PARSER_NODE;
        break;
    case TXT_NODE: 
        if (!haveJsonType) {
            if (checkCharData) {
                type = TEXT_NODE_CHK;
            } else {
                type = TEXT_NODE;
            }
        } else {
            if (jsonType < 3 && jsonType > 0) {
                Tcl_SetResult(interp, "For a text node the jsonType "
                              "argument must be one out of this list: "
                              "TRUE FALSE NULL NUMBER STRING NONE",
                              NULL);
                return TCL_ERROR;
            }
            type = TEXT_NODE;
        }
        break;
    case CDS_NODE: 
        if (checkCharData) {
            type = CDATA_SECTION_NODE_CHK;
        } else {
................................................................................
            type = PROCESSING_INSTRUCTION_NODE_NAME_CHK;
        } else if (checkCharData) {
            type = PROCESSING_INSTRUCTION_NODE_VALUE_CHK;
        } else {
            type = PROCESSING_INSTRUCTION_NODE;
        }
        break;
    default:
        Tcl_SetResult (interp, "Invalid/unexpected node type", NULL);
        return TCL_ERROR;
    }

    if (tagName && !isElement) {
        Tcl_SetResult(interp, "The -tagName option is allowed only for "
                      "element node commands.", NULL);
        return TCL_ERROR;        
    }

    if (namespace && !isElement) {
        Tcl_SetResult(interp, "The -namespace option is allowed only for "
                      "element node commands.", NULL);
        return TCL_ERROR;        
    }
    
    if (haveJsonType && type != ELEMENT_NODE && type != TEXT_NODE) {
        Tcl_SetResult(interp, "Only element and text nodes may have a "
                      "JSON type.", NULL);
        return TCL_ERROR;        
    }
    
    nodeInfo = (NodeInfo *) MALLOC (sizeof (NodeInfo));
    nodeInfo->namespace = NULL;
    nodeInfo->type = type;
    if (nodecmd) {
        nodeInfo->type *= -1; /* Signal this fact */
    }
    nodeInfo->jsonType = jsonType;
    nodeInfo->tagName = NULL;
    if (namespace) {
        nodeInfo->namespace = tdomstrdup (Tcl_GetString(namespace));
    }
    if (tagName) {
        nodeInfo->tagName = tdomstrdup (Tcl_GetString(tagName));
    }
    Tcl_CreateObjCommand(interp, Tcl_DStringValue(&cmdName), NodeObjCmd,
                         (ClientData)nodeInfo, NodeObjCmdDeleteProc);
    Tcl_DStringResult(interp, &cmdName);
    Tcl_DStringFree(&cmdName);

    return TCL_OK;

 usage:
    Tcl_AppendResult(interp, "dom createNodeCmd\n"
                     "\t?-returnNodeCmd?\n"
                     "\t?-jsonType <jsonType>?\n"
                     "\t?-tagName <tagName>?\n"
                     " nodeType cmdName", NULL);
    return TCL_ERROR;
}

 
/*
 *----------------------------------------------------------------------
................................................................................
 * Side effects:
 *	Appends new child nodes to node.
 *
 *----------------------------------------------------------------------
 */

int
nodecmd_appendFromScript (
    Tcl_Interp *interp,                /* Current interpreter. */
    domNode    *node,                  /* Parent dom node */
    Tcl_Obj    *cmdObj                 /* Argument objects. */

) {
    int ret;
    domNode *oldLastChild, *child, *nextChild;

    if (node->nodeType != ELEMENT_NODE) {
        Tcl_SetResult (interp, "NOT_AN_ELEMENT : can't append nodes", NULL);
        return TCL_ERROR;
    }
    
    oldLastChild = node->lastChild;

    StackPush((void *)node);
    Tcl_AllowExceptions(interp);
    ret = Tcl_EvalObjEx(interp, cmdObj, 0);
    if (ret != TCL_ERROR) {
        Tcl_ResetResult(interp);
    }
    StackPop();

    if (ret == TCL_ERROR) {
        if (oldLastChild) {
................................................................................
 * Side effects:
 *	Insert new child nodes before referenceChild to node.
 *
 *----------------------------------------------------------------------
 */

int
nodecmd_insertBeforeFromScript (
    Tcl_Interp *interp,                 /* Current interpreter. */
    domNode    *node,                   /* Parent dom node */
    Tcl_Obj    *cmdObj,                 /* Argument objects. */
    domNode    *refChild                /* Insert new childs before this
                                         * node; may be NULL */

) {
    int      ret;
    domNode *storedLastChild, *n;

    if (!refChild) {
        return nodecmd_appendFromScript (interp, node, cmdObj);
    }
    

Changes to generic/nodecmd.h.

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|   Written by Zoran Vasiljevic
|   July 12, 2000
|
\---------------------------------------------------------------------------*/

int nodecmd_createNodeCmd (Tcl_Interp    * interp,
                           int             objc,
                           Tcl_Obj *CONST  objv[],
                           int             checkName,
                           int             checkCharData);

int nodecmd_appendFromScript (Tcl_Interp *interp, 
                              domNode    *node,
                              Tcl_Obj    *cmdObj);








|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|   Written by Zoran Vasiljevic
|   July 12, 2000
|
\---------------------------------------------------------------------------*/

int nodecmd_createNodeCmd (Tcl_Interp    * interp,
                           int             objc,
                           Tcl_Obj *const  objv[],
                           int             checkName,
                           int             checkCharData);

int nodecmd_appendFromScript (Tcl_Interp *interp, 
                              domNode    *node,
                              Tcl_Obj    *cmdObj);

Changes to generic/tcldom.c.

38
39
40
41
42
43
44
45
46
47
48
49
50
51

52

53
54

55
56
57
58
59
60
61
..
72
73
74
75
76
77
78


79
80
81
82



83
84
85
86
87
88
89
90
...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159









160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
...
191
192
193
194
195
196
197

198
199
200
201



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

223
224
225
226
227
228
229
...
232
233
234
235
236
237
238

239
240
241
242
243
244
245
...
295
296
297
298
299
300
301

302
303
304
305
306
307
308
...
327
328
329
330
331
332
333

334
335
336
337
338
339
340
341
342
343

344
345
346
347
348












349
350
351
352
353
354
355
356
357
358
359












360
361
362
363






364

365




366
367
368
369






370
371
372
373
374
375
376
...
388
389
390
391
392
393
394

395
396

397
398
399
400
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
...
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499

500
501
502
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533

534






535
536
537


538
539
540
541
542
543


544
545
546
547
548
549
550
551

552
553
554
555
556
557
558

559
560
561






562
563










564

565
566
567


568
569





570
571
572
573
574
575
576
577
578
579
580
581





582
583





584
585
586










587
588
589
590
591
592
593
...
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635

636

637
638
639







640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656


657
658
659
660



661
662
663
664
665
666
667



668

669



670


671
672




673
674
675
676
677
678
679
680
...
710
711
712
713
714
715
716

717
718
719
720
721
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
...
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
...
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
...
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
...
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
...
985
986
987
988
989
990
991

















































992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004

1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
....
1032
1033
1034
1035
1036
1037
1038

1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
....
1071
1072
1073
1074
1075
1076
1077
1078

1079


1080
1081
1082
1083
1084
1085
1086
....
1088
1089
1090
1091
1092
1093
1094
1095




1096
1097
1098
1099
1100
1101
1102

1103

1104

1105
1106
1107
1108
1109
1110




1111
1112
1113
1114
1115
1116
1117
....
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
....
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
....
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
....
1269
1270
1271
1272
1273
1274
1275
1276
1277

1278
1279
1280
1281
1282
1283
1284
1285







1286
1287
1288
1289
1290
1291
1292
....
1300
1301
1302
1303
1304
1305
1306

1307



1308







1309
1310
1311
1312
1313
1314
1315
....
1333
1334
1335
1336
1337
1338
1339

1340
1341
1342
1343
1344
1345
1346
....
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
....
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
....
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
....
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444

1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465



1466

1467
1468
1469
1470
1471
1472
1473
....
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
....
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518

1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
....
1543
1544
1545
1546
1547
1548
1549
1550

1551
1552





1553
1554
1555

1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566



1567
1568
1569
1570
1571
1572
1573
....
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592

1593
1594
1595
1596
1597
1598
1599
....
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612

1613
1614
1615
1616
1617
1618
1619
....
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636

1637
1638

1639
1640
1641
1642
1643
1644
1645
....
1646
1647
1648
1649
1650
1651
1652

1653
1654
1655

1656





1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
....
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
....
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
....
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051

2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064

2065
2066
2067
2068
2069
2070

2071
2072

2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
....
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
....
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368









2369

2370
2371
2372
2373
2374
2375
2376
2377
2378
....
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
....
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443


2444
2445
2446
2447
2448
2449
2450
....
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515

2516
2517
2518
2519
2520
2521
2522
....
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
....
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621

2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632


















2633
2634

2635
2636
2637
2638
2639
2640
2641
2642
....
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
....
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
....
2744
2745
2746
2747
2748
2749
2750











2751

2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
....
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819





2820

2821





2822

2823
2824
2825
2826
2827
2828
2829
....
2832
2833
2834
2835
2836
2837
2838
















































































































































































































































































































































































2839
2840
2841
2842
2843
2844
2845
....
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887

2888
2889
2890
2891
2892

2893
2894
2895
2896


2897
2898
2899
2900
2901

2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937






















2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979































2980
2981
2982
2983
2984
2985












2986
2987
2988
2989
2990
2991
2992
....
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020



3021





3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
....
3114
3115
3116
3117
3118
3119
3120
3121
3122






























































































3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
....
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
....
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
....
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
....
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
....
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361

3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376

3377
3378
3379
3380

3381
3382
3383
3384
3385
3386
3387
....
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
....
3420
3421
3422
3423
3424
3425
3426

















3427
3428
3429
3430
3431
3432
3433
....
3461
3462
3463
3464
3465
3466
3467
3468

3469
3470
3471
3472
3473
3474
3475



3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
....
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
....
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
....
3639
3640
3641
3642
3643
3644
3645

3646
3647
3648
3649
3650
3651
3652
....
3660
3661
3662
3663
3664
3665
3666
3667

3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691

3692
3693
3694
3695
3696
3697
3698
....
3789
3790
3791
3792
3793
3794
3795
3796









3797
3798
3799
3800
3801
3802
3803
3804
....
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
....
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
....
3866
3867
3868
3869
3870
3871
3872

3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
....
3898
3899
3900
3901
3902
3903
3904



























3905
3906
3907
3908
3909
3910
3911
....
3922
3923
3924
3925
3926
3927
3928






3929
3930
3931
3932
3933
3934
3935
....
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
....
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
....
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
....
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139



4140
4141
4142
4143
4144
4145
4146
4147

4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210



4211
4212
4213
4214
4215
4216
4217
4218

4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
....
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
....
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
....
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
....
4468
4469
4470
4471
4472
4473
4474







4475
4476
4477
4478
4479
4480
4481
....
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
....
4606
4607
4608
4609
4610
4611
4612







































4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
....
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
....
4664
4665
4666
4667
4668
4669
4670
4671

4672
4673
4674
4675
4676
4677
4678
....
4689
4690
4691
4692
4693
4694
4695
4696

4697
4698
4699
4700
4701
4702
4703
....
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
....
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825




4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
....
5110
5111
5112
5113
5114
5115
5116


5117
5118
5119
5120
5121
5122
5123
....
5183
5184
5185
5186
5187
5188
5189

5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
....
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222

5223
5224

5225
5226
5227
5228
5229




5230











5231

5232
5233
5234
5235
5236
5237
5238
5239
....
5242
5243
5244
5245
5246
5247
5248
5249

5250
5251
5252

5253
5254
5255
5256
5257
5258
5259
5260
5261



5262
5263

5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292

5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309


5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
....
5325
5326
5327
5328
5329
5330
5331

5332

5333
5334

5335

5336
5337

5338

5339
5340
5341


5342
5343
5344
5345

5346
5347
5348
5349
5350
5351






5352
5353
5354
5355
5356






5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
....
5380
5381
5382
5383
5384
5385
5386

























5387
5388
5389
5390
5391





5392
5393
5394











5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408





5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
....
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
....
5492
5493
5494
5495
5496
5497
5498
5499








5500


5501









































5502
5503
5504
5505
5506
5507
5508
....
5512
5513
5514
5515
5516
5517
5518
5519




5520
5521
5522
5523
5524
5525
5526
5527
5528
5529













































5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540

5541
5542
5543
5544
5545
5546
5547
....
5581
5582
5583
5584
5585
5586
5587
5588
5589

5590

5591
5592
5593
5594
5595
5596

5597
5598
5599
5600







5601

5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632













5633

5634
5635
5636

5637
5638
5639
5640
5641
5642
5643
5644


5645


















































































































5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670

5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682

5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
....
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
....
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
....
5900
5901
5902
5903
5904
5905
5906









5907
5908
5909
5910
5911
5912
5913
....
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
....
5950
5951
5952
5953
5954
5955
5956


5957

5958
5959

5960



5961
5962
5963
5964
5965
5966
5967
....
5986
5987
5988
5989
5990
5991
5992

5993
5994
5995
5996



5997
5998
5999
6000
6001
6002
6003
....
6017
6018
6019
6020
6021
6022
6023

6024
6025
6026
6027
6028
6029

6030
6031
6032
6033
6034

6035
6036
6037
6038
6039
6040
6041
....
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059


/*----------------------------------------------------------------------------
|   Includes
|
\---------------------------------------------------------------------------*/
#include <tcl.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dom.h>
#include <domxpath.h>
#include <domxslt.h>
#include <xmlsimple.h>

#include <domhtml.h>

#include <nodecmd.h>
#include <tcldom.h>


/* #define DEBUG */
/*----------------------------------------------------------------------------
|   Debug Macros
|
\---------------------------------------------------------------------------*/
#ifdef DEBUG
................................................................................
#define XP_CHILD         0
#define XP_DESCENDANT    1
#define XP_ANCESTOR      2
#define XP_FSIBLING      3
#define XP_PSIBLING      4

#define MAX_REWRITE_ARGS 50



#define SetResult(str) Tcl_ResetResult(interp); \
                     Tcl_SetStringObj(Tcl_GetObjResult(interp), (str), -1)




#define SetIntResult(i) Tcl_ResetResult(interp); \
                     Tcl_SetIntObj(Tcl_GetObjResult(interp), (i))
                     
#define SetDoubleResult(d) Tcl_ResetResult(interp); \
                     Tcl_SetDoubleObj(Tcl_GetObjResult(interp), (d))

#define SetBooleanResult(i) Tcl_ResetResult(interp); \
                     Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (i))
................................................................................
#define CheckPIValue(interp, text) \
                     if (!TSD(dontCheckCharData)) { \
                         if (!tcldom_PIValueCheck(interp, text)) {\
                             return TCL_ERROR; \
                         } \
                     }

#if TclOnly8Bits
#define writeChars(var,chan,buf,len)  (chan) ? \
                     ((void)Tcl_Write ((chan), (buf), (len) )) : \
                     (Tcl_AppendToObj ((var), (buf), (len) ));
#else
#define writeChars(var,chan,buf,len)  (chan) ? \
                     ((void)Tcl_WriteChars ((chan), (buf), (len) )) : \
                     (Tcl_AppendToObj ((var), (buf), (len) ));
#endif

#define DOM_CREATECMDMODE_AUTO 0
#define DOM_CREATECMDMODE_CMDS 1
#define DOM_CREATECMDMODE_TOKENS 2










/*----------------------------------------------------------------------------
|   Module Globals
|
\---------------------------------------------------------------------------*/
#ifndef TCL_THREADS
    static TEncoding *Encoding_to_8bit      = NULL;
    static int        storeLineColumn       = 0;
    static int        dontCreateObjCommands = 0;
    static int        dontCheckCharData     = 0;
    static int        dontCheckName         = 0;
    static int        domCreateCmdMode      = 0;
#   define TSD(x)     x
#   define GetTcldomTSD()
#else
    typedef struct ThreadSpecificData {
        TEncoding *Encoding_to_8bit;
        int        storeLineColumn;
        int        dontCreateObjCommands;
        int        dontCheckCharData;
        int        dontCheckName;
        int        domCreateCmdMode;
    } ThreadSpecificData;
    static Tcl_ThreadDataKey dataKey;
................................................................................
                                    sizeof(ThreadSpecificData));
#endif /* TCL_THREADS */

static char dom_usage[] =
    "Usage dom <subCommand> <args>, where subCommand can be:    \n"
    "    parse ?-keepEmpties? ?-channel <channel> ?-baseurl <baseurl>?  \n"
    "        ?-feedbackAfter <#Bytes>?                    \n"

    "        ?-externalentitycommand <cmd>?               \n"
    "        ?-useForeignDTD <boolean>?                   \n"
    "        ?-paramentityparsing <none|always|standalone>\n"
    "        ?-simple? ?-html? ?<xml>? ?<objVar>?         \n"



    "    createDocument docElemName ?objVar?              \n"
    "    createDocumentNS uri docElemName ?objVar?        \n"
    "    createDocumentNode ?objVar?                      \n"
    TDomThreaded(
    "    attachDocument domDoc ?objVar?                   \n"
    "    detachDocument domDoc                            \n"
    )
    "    createNodeCmd ?-returnNodeCmd? (element|comment|text|cdata|pi)Node cmdName \n"
    "    setResultEncoding ?encodingName?                 \n"
    "    setStoreLineColumn ?boolean?                     \n"
    "    setNameCheck ?boolean?                           \n"
    "    setTextCheck ?boolean?                           \n"
    "    setObjectCommands ?(automatic|token|command)?    \n"
    "    isCharData string                                \n"
    "    isComment string                                 \n"
    "    isCDATA string                                   \n"
    "    isPIValue string                                 \n"
    "    isName string                                    \n"
    "    isQName string                                   \n"
    "    isNCName string                                  \n"
    "    isPIName string                                  \n"

;

static char doc_usage[] =
    "Usage domDoc <method> <args>, where method can be:\n"
    "    documentElement ?objVar?                \n"
    "    getElementsByTagName name               \n"
    "    getElementsByTagNameNS uri localname    \n"
................................................................................
    "    createCDATASection data ?objVar?        \n"
    "    createTextNode text ?objVar?            \n"
    "    createComment text ?objVar?             \n"
    "    createProcessingInstruction target data ?objVar? \n"
    "    asXML ?-indent <none,0..8>? ?-channel <channel>? ?-escapeNonASCII? ?-escapeAllQuot? ?-doctypeDeclaration <boolean>?\n"
    "    asHTML ?-channel <channelId>? ?-escapeNonASCII? ?-htmlEntities?\n"
    "    asText                                  \n"

    "    getDefaultOutputMethod                  \n"
    "    publicId ?publicId?                     \n"
    "    systemId ?systemId?                     \n"
    "    internalSubset ?internalSubset?         \n"
    "    indent ?boolean?                        \n"
    "    omit-xml-declaration ?boolean?          \n"
    "    encoding ?value?                        \n"
................................................................................
    "    setAttribute attrName value ?attrName value ...? \n"
    "    removeAttribute attrName     \n"
    "    hasAttributeNS uri localName \n"
    "    getAttributeNS uri localName ?defaultValue? \n"
    "    setAttributeNS uri attrName value ?attrName value ...? \n"
    "    removeAttributeNS uri attrName \n"
    "    attributes ?attrNamePattern?   \n"

    "    appendChild new              \n"
    "    insertBefore new ref         \n"
    "    replaceChild new old         \n"
    "    removeChild child            \n"
    "    cloneNode ?-deep?            \n"
    "    ownerDocument                \n"
    "    getElementsByTagName name    \n"
................................................................................
    "    getLine                      \n"
    "    getColumn                    \n"
    "    @<attrName> ?defaultValue?   \n"
    "    asList                       \n"
    "    asXML ?-indent <none,0..8>? ?-channel <channel>? ?-escapeNonASCII? ?-escapeAllQuot? ?-doctypeDeclaration <boolean>?\n"
    "    asHTML ?-channel <channelId>? ?-escapeNonASCII? ?-htmlEntities?\n"
    "    asText                       \n"

    "    appendFromList nestedList    \n"
    "    appendFromScript script      \n"
    "    insertBeforeFromScript script ref \n"
    "    appendXML xmlString          \n"
    "    selectNodes ?-namespaces prefixUriList? ?-cache <boolean>? xpathQuery ?typeVar? \n"
    "    toXPath                      \n"
    "    disableOutputEscaping ?boolean? \n"
    "    precedes node                \n"
    "    normalize ?-forXPath?        \n"
    "    xslt ?-parameters parameterList? <xsltDocNode>\n"

    TDomThreaded(
    "    readlock                     \n"
    "    writelock                    \n"
    )
;













/*----------------------------------------------------------------------------
|   Types
|
\---------------------------------------------------------------------------*/

typedef struct XsltMsgCBInfo {
    Tcl_Interp * interp;
    Tcl_Obj    * msgcmd;
} XsltMsgCBInfo;













/*----------------------------------------------------------------------------
|   Prototypes for procedures defined later in this file:
|
\---------------------------------------------------------------------------*/








static Tcl_VarTraceProc  tcldom_docTrace;




static Tcl_VarTraceProc  tcldom_nodeTrace;

static Tcl_CmdDeleteProc tcldom_docCmdDeleteProc;
static Tcl_CmdDeleteProc tcldom_nodeCmdDeleteProc;







#ifdef TCL_THREADS

static int tcldom_EvalLocked(Tcl_Interp* interp, Tcl_Obj** objv,
                             domDocument* doc, int flag);

static int tcldom_RegisterDocShared(domDocument* doc);
................................................................................
\---------------------------------------------------------------------------*/

static void 
tcldom_Finalize(
    ClientData unused
)
{

    Tcl_MutexLock(&tableMutex);
    Tcl_DeleteHashTable(&sharedDocs);

    Tcl_MutexUnlock(&tableMutex);
}

/*----------------------------------------------------------------------------
|   tcldom_initialize
|   Activated at module load to initialize shared document table.
|   This is exported since we need it in tdominit.c.
\---------------------------------------------------------------------------*/

void tcldom_initialize()
{
    if (!tcldomInitialized) {

        Tcl_MutexLock(&tableMutex);
        Tcl_InitHashTable(&sharedDocs, TCL_ONE_WORD_KEYS);
        Tcl_CreateExitHandler(tcldom_Finalize, NULL);
        tcldomInitialized = 1;
        Tcl_MutexUnlock(&tableMutex);
    }
}
................................................................................
static
void tcldom_docCmdDeleteProc(
    ClientData clientData
)
{
    domDeleteInfo *dinfo = (domDeleteInfo *)clientData;
    domDocument   *doc   = dinfo->document;
    char          *var   = dinfo->traceVarName;
    
    DBG(fprintf(stderr, "--> tcldom_docCmdDeleteProc doc %p\n", doc));
    if (var) {
        DBG(fprintf(stderr, "--> tcldom_docCmdDeleteProc calls "
                    "Tcl_UntraceVar for \"%s\"\n", var));
        Tcl_UntraceVar(dinfo->interp, var, TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                       tcldom_docTrace, clientData);
        FREE(var);
        dinfo->traceVarName = NULL;
    }

    tcldom_deleteDoc(dinfo->interp, doc);

    FREE((void*)dinfo);
}


/*----------------------------------------------------------------------------
|   tcldom_nodeCmdDeleteProc
|
\---------------------------------------------------------------------------*/
static
void tcldom_nodeCmdDeleteProc (
    ClientData  clientData
)
{
    domDeleteInfo *dinfo = (domDeleteInfo *)clientData;
    char          *var   = dinfo->traceVarName;

    DBG(fprintf (stderr, "--> tcldom_nodeCmdDeleteProc node %p\n", 

                 dinfo->node));

    if (var) {
         DBG(fprintf(stderr, "--> tcldom_nodeCmdDeleteProc calls "
                    "Tcl_UntraceVar for \"%s\"\n", var));
        Tcl_UntraceVar(dinfo->interp, var, 
                       TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                       tcldom_nodeTrace, clientData);
        FREE(var);
        dinfo->traceVarName = NULL;
    }

    FREE((void*)dinfo);
}


/*----------------------------------------------------------------------------
|   tcldom_docTrace
|
\---------------------------------------------------------------------------*/
static
char * tcldom_docTrace (
    ClientData    clientData,
    Tcl_Interp   *interp,
    CONST84 char *name1,
    CONST84 char *name2,
    int           flags
)
{
    domDeleteInfo *dinfo = (domDeleteInfo*) clientData;
    domDocument   *doc   = dinfo->document;
    char           objCmdName[80];

    DBG(fprintf(stderr, "--> tcldom_docTrace %x %p\n", flags, doc));


    if (flags & TCL_INTERP_DESTROYED) {






        return NULL;
    }
    if (flags & TCL_TRACE_WRITES) {


        return "var is read-only";
    }
    if (flags & TCL_TRACE_UNSETS) {
        DOC_CMD(objCmdName, doc);
        DBG(fprintf(stderr, "--> tcldom_docTrace delete doc %p\n", doc));
        Tcl_DeleteCommand(interp, objCmdName);


    }

    return NULL;
}


/*----------------------------------------------------------------------------
|   tcldom_nodeTrace

|
\---------------------------------------------------------------------------*/
static
char * tcldom_nodeTrace (
    ClientData    clientData,
    Tcl_Interp   *interp,
    CONST84 char *name1,

    CONST84 char *name2,
    int           flags
)






{
    domDeleteInfo *dinfo = (domDeleteInfo*)clientData;










    domNode       *node = dinfo->node;

    char           objCmdName[80];

    DBG(fprintf(stderr, "--> tcldom_nodeTrace %x %p\n", flags, node));



    if (flags & TCL_INTERP_DESTROYED) {





        return NULL;
    }
    if (flags & TCL_TRACE_WRITES) {
        return "var is read-only";
    }
    if (flags & TCL_TRACE_UNSETS) {
        NODE_CMD(objCmdName, node);
        DBG(fprintf(stderr, "--> tcldom_nodeTrace delete node %p\n", node));
        Tcl_UntraceVar(interp, name1, TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
                       tcldom_nodeTrace, clientData);
        Tcl_DeleteCommand(interp, objCmdName);
        node->nodeFlags &= ~VISIBLE_IN_TCL;





    }






    return NULL;
}












/*----------------------------------------------------------------------------
|   tcldom_createNodeObj
|
\---------------------------------------------------------------------------*/
void tcldom_createNodeObj (
    Tcl_Interp * interp,
................................................................................
                             (ClientData)        node,
                             (Tcl_CmdDeleteProc*)NULL);
        node->nodeFlags |= VISIBLE_IN_TCL;
    }
}

/*----------------------------------------------------------------------------
|   tcldom_returnNodeObj
|
\---------------------------------------------------------------------------*/
static
int tcldom_returnNodeObj (
    Tcl_Interp *interp,
    domNode    *node,
    int         setVariable,
    Tcl_Obj    *var_name
)
{
    char            objCmdName[80], *objVar;
    domDeleteInfo * dinfo;
    Tcl_CmdInfo     cmdInfo;

    GetTcldomTSD()

    if (node == NULL) {
        if (setVariable) {
            objVar = Tcl_GetString(var_name);
            Tcl_UnsetVar(interp, objVar, 0);
            Tcl_SetVar(interp, objVar, "", 0);

        }

        SetResult("");
        return TCL_OK;
    }







    tcldom_createNodeObj(interp, node, objCmdName);
    if (TSD(dontCreateObjCommands)) {
        if (setVariable) {
            objVar = Tcl_GetString(var_name);
            Tcl_SetVar(interp, objVar, objCmdName, 0);
        }
    } else {
        if (setVariable) {
            objVar = Tcl_GetString(var_name);
            Tcl_UnsetVar(interp, objVar, 0);
            Tcl_SetVar  (interp, objVar, objCmdName, 0);
            Tcl_GetCommandInfo(interp, objCmdName, &cmdInfo);
            if (0) {
                dinfo = (domDeleteInfo*)MALLOC(sizeof(domDeleteInfo));
                dinfo->interp       = interp;
                dinfo->node         = node;
                dinfo->traceVarName = NULL;


                Tcl_TraceVar(interp, objVar, 
                             TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
                             (Tcl_VarTraceProc*)tcldom_nodeTrace,
                             (ClientData)dinfo);



                dinfo->traceVarName = tdomstrdup(objVar);

                /* Patch node object command to remove above trace 
                   on teardown */
                cmdInfo.deleteData = (ClientData)dinfo;
                cmdInfo.deleteProc = tcldom_nodeCmdDeleteProc;
                Tcl_SetCommandInfo(interp, objCmdName, &cmdInfo);



            }

        }



    }



    SetResult(objCmdName);




    return TCL_OK;
}

/*----------------------------------------------------------------------------
|   tcldom_returnDocumentObj
|
\---------------------------------------------------------------------------*/
int tcldom_returnDocumentObj (
................................................................................
            Tcl_SetVar(interp, objVar, objCmdName, 0);
        }
    } else {
        if (!Tcl_GetCommandInfo(interp, objCmdName, &cmd_info)) {
            dinfo = (domDeleteInfo*)MALLOC(sizeof(domDeleteInfo));
            dinfo->interp       = interp;
            dinfo->document     = document;

            dinfo->traceVarName = NULL;
            Tcl_CreateObjCommand(interp, objCmdName,
                                 (Tcl_ObjCmdProc *)  tcldom_DocObjCmd,
                                 (ClientData)        dinfo,
                                 (Tcl_CmdDeleteProc*)tcldom_docCmdDeleteProc);
        } else {
            dinfo = (domDeleteInfo*)cmd_info.objClientData;
        }
        if (setVariable) {
            objVar = Tcl_GetString(var_name);
            Tcl_UnsetVar(interp, objVar, 0);
            Tcl_SetVar  (interp, objVar, objCmdName, 0);
            if (trace) {

                dinfo->traceVarName = tdomstrdup(objVar);
                Tcl_TraceVar(interp,objVar,TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                             (Tcl_VarTraceProc*)tcldom_docTrace,
                             (ClientData)dinfo);
            }
        }
    }
................................................................................
    domNode    *node,
    int         nsIndex,
    const char *uri
)
{
    int         result;
    domNode    *child;
    char        prefix[MAX_PREFIX_LEN], objCmdName[80];
    const char *localName;
    Tcl_Obj    *namePtr, *resultPtr;

    /* nsIndex == -1 ==> DOM 1 no NS i.e getElementsByTagName
       nsIndex != -1 are the NS aware cases
       nsIndex == -2 ==> more than one namespace in the document with the 
                         requested namespace, we have to strcmp the URI
................................................................................
            if (nsIndex == -1) {
                localName = node->nodeName;
            } else {
                domSplitQName(node->nodeName, prefix, &localName);
            }
            if (Tcl_StringMatch(localName, namePattern)) {
                resultPtr = Tcl_GetObjResult(interp);
                tcldom_createNodeObj(interp, node, objCmdName);
                namePtr = Tcl_NewStringObj(objCmdName, -1);
                result = Tcl_ListObjAppendElement(interp, resultPtr, namePtr);
                if (result != TCL_OK) {
                    Tcl_DecrRefCount(namePtr);
                    return result;
                }
            }
        }
................................................................................
    domNode    * node,
    void       * clientData
)
{
    Tcl_Interp * interp = (Tcl_Interp*)clientData;
    Tcl_Obj    * resultPtr = Tcl_GetObjResult(interp);
    Tcl_Obj    * namePtr;
    char         objCmdName[80];
    int          result;


    tcldom_createNodeObj(interp, node, objCmdName);
    namePtr = Tcl_NewStringObj(objCmdName, -1);
    result  = Tcl_ListObjAppendElement(interp, resultPtr, namePtr);
    if (result != TCL_OK) {
        Tcl_DecrRefCount(namePtr);
    }
    return result;
}

................................................................................
\---------------------------------------------------------------------------*/
static
int tcldom_xpointerSearch (
    Tcl_Interp * interp,
    int          mode,
    domNode    * node,
    int          objc,
    Tcl_Obj    * CONST  objv[]
)
{
    char *str;
    int   i = 0;
    int   result = 0;
    int   all = 0;
    int   instance = 0;
................................................................................
    }
    if (result != 0) {
        return TCL_ERROR;
    }
    return TCL_OK;
}



















































/*----------------------------------------------------------------------------
|   tcldom_getNodeFromName
|
\---------------------------------------------------------------------------*/
domNode * tcldom_getNodeFromName (
    Tcl_Interp  *interp,
    char        *nodeName,
    char       **errMsg
)
{
    Tcl_CmdInfo  cmdInfo;
    domNode     *node = NULL;


    if (strncmp(nodeName, "domNode", 7)) {
        *errMsg = "parameter not a domNode!";
        return NULL;
    }
    if (sscanf(&nodeName[7], "%p", &node) != 1) {
        if (!Tcl_GetCommandInfo(interp, nodeName, &cmdInfo)) {
           *errMsg = "parameter not a domNode!";
           return NULL;
        }
        if (   (cmdInfo.isNativeObjectProc == 0)
            || (cmdInfo.objProc != (Tcl_ObjCmdProc*)tcldom_NodeObjCmd)) {
            *errMsg = "parameter not a domNode object command!";
................................................................................
    char        *docName,
    char       **errMsg
)
{
    Tcl_CmdInfo  cmdInfo;
    domDocument *doc = NULL;
    int          shared = 1;

    
    if (strncmp(docName, "domDoc", 6)) {
        *errMsg = "parameter not a domDoc!";
        return NULL;
    }
    if (sscanf(&docName[6], "%p", &doc) != 1) {
        if (!Tcl_GetCommandInfo(interp, docName, &cmdInfo)) {
            *errMsg = "parameter not a domDoc!";
            return NULL;
        }
        if (   (cmdInfo.isNativeObjectProc == 0)
            || (cmdInfo.objProc != (Tcl_ObjCmdProc*)tcldom_DocObjCmd)) {
            *errMsg = "parameter not a domDoc object command!";
................................................................................
\---------------------------------------------------------------------------*/
int tcldom_appendXML (
    Tcl_Interp *interp,
    domNode    *node,
    Tcl_Obj    *obj
)
{
    char        *xml_string, *extResolver = NULL;

    int          xml_string_len;


    domDocument *doc;
    domNode     *nodeToAppend;
    XML_Parser   parser;

    GetTcldomTSD()

    xml_string = Tcl_GetStringFromObj(obj, &xml_string_len);
................................................................................
#ifdef TDOM_NO_EXPAT
    SetResult("tDOM was compiled without Expat!");
    return TCL_ERROR;
#else
    parser = XML_ParserCreate_MM(NULL, MEM_SUITE, NULL);

    if (node->ownerDocument->extResolver) {
        extResolver = tdomstrdup (node->ownerDocument->extResolver);




    }

    doc = domReadDocument(parser,
                          xml_string,
                          xml_string_len,
                          1,
                          TSD(Encoding_to_8bit),

                          TSD(storeLineColumn),

                          0,

                          NULL,
                          NULL,
                          extResolver,
                          0,
                          (int) XML_PARAM_ENTITY_PARSING_ALWAYS,
                          interp);




    if (doc == NULL) {
        char s[50];
        long byteIndex, i;

        Tcl_ResetResult(interp);
        sprintf(s, "%ld", XML_GetCurrentLineNumber(parser));
        Tcl_AppendResult(interp, "error \"",
................................................................................
    nodeToAppend = doc->rootNode->firstChild;
    while (nodeToAppend) {
        domAppendChild(node, nodeToAppend);
        nodeToAppend = nodeToAppend->nextSibling;
    }
    domFreeDocument(doc, NULL, NULL);

    return tcldom_returnNodeObj(interp, node, 0, NULL);
#endif
}


/*----------------------------------------------------------------------------
|   tcldom_xpathResultSet
|
................................................................................
    xpathResultSet  *rs,
    Tcl_Obj         *type,
    Tcl_Obj         *value
)
{
    int          rc, i;
    Tcl_Obj     *namePtr, *objv[2];
    char         objCmdName[80];
    domAttrNode *attr;
    domNodeType  startType;
    int          mixedNodeSet;

    switch (rs->type) {
        case EmptyResult:
             Tcl_SetStringObj(type, "empty", -1);
................................................................................
                 if (rs->nodes[i]->nodeType == ATTRIBUTE_NODE) {
                     attr = (domAttrNode*)rs->nodes[i];
                     objv[0] = Tcl_NewStringObj(attr->nodeName, -1);
                     objv[1] = Tcl_NewStringObj(attr->nodeValue,
                                                attr->valueLength);
                     namePtr = Tcl_NewListObj(2, objv);
                 } else {
                     tcldom_createNodeObj(interp, rs->nodes[i], objCmdName);
                     namePtr = Tcl_NewStringObj(objCmdName, -1);
                 }
                 rc = Tcl_ListObjAppendElement(interp, value, namePtr);
                 if (rc != TCL_OK) {
                     Tcl_DecrRefCount(namePtr);
                     return rc;
                 }
             }
................................................................................
    xpathResultSets *args,
    xpathResultSet  *result,
    char           **errMsg
)
{
    Tcl_Interp  *interp = (Tcl_Interp*) clientData;
    char         tclxpathFuncName[200], objCmdName[80];
    char         *errStr, *typeStr, *nodeName;
    Tcl_Obj     *resultPtr, *objv[MAX_REWRITE_ARGS], *type, *value, *nodeObj;

    Tcl_CmdInfo  cmdInfo;
    int          objc, rc, i, errStrLen, listLen, intValue, res;
    double       doubleValue;
    domNode     *node;

    DBG(fprintf(stderr, "tcldom_xpathFuncCallBack functionName=%s "
                "position=%d argc=%d\n", functionName, position, argc);)








    sprintf (tclxpathFuncName, "::dom::xpathFunc::%s", functionName);
    DBG(fprintf(stderr, "testing %s\n", tclxpathFuncName);)
    rc = Tcl_GetCommandInfo (interp, tclxpathFuncName, &cmdInfo);
    if (!rc) {
        *errMsg = (char*)MALLOC (80 + strlen (functionName));
        strcpy (*errMsg, "Unknown XPath function: \"");
        strcat (*errMsg, functionName);
................................................................................
    if ( (5+(2*argc)) >= MAX_REWRITE_ARGS) {
        *errMsg = (char*)tdomstrdup("too many args for Tcl level method!");
        return XPATH_EVAL_ERR;
    }
    objc = 0;
    objv[objc] = Tcl_NewStringObj(tclxpathFuncName, -1);
    Tcl_IncrRefCount(objv[objc++]);

    tcldom_createNodeObj(interp, ctxNode, objCmdName);



    objv[objc] = Tcl_NewStringObj(objCmdName, -1);







    Tcl_IncrRefCount(objv[objc++]);

    objv[objc] = Tcl_NewIntObj(position);
    Tcl_IncrRefCount(objv[objc++]);

    type  = Tcl_NewObj();
    value = Tcl_NewObj();
................................................................................
        xpathRSInit(result);
        resultPtr = Tcl_GetObjResult(interp);
        rc = Tcl_ListObjLength(interp, resultPtr, &listLen);
        if (rc == TCL_OK) {
            if (listLen == 1) {
                rsSetString(result, Tcl_GetString(resultPtr));
                res = XPATH_OK;

                goto funcCallCleanup;
            }
            if (listLen != 2) {
                *errMsg = (char*)tdomstrdup("wrong return tuple; "
                                            "must be {type value}!");
                res = XPATH_EVAL_ERR;
                goto funcCallCleanup;
................................................................................
                if (rc != TCL_OK) {
                    *errMsg = tdomstrdup("value not a node list!");
                    res = XPATH_EVAL_ERR;
                    goto funcCallCleanup;
                }
                for (i=0; i < listLen; i++) {
                    rc = Tcl_ListObjIndex(interp, value, i, &nodeObj);
                    nodeName = Tcl_GetString(nodeObj);
                    node = tcldom_getNodeFromName(interp, nodeName, &errStr);
                    if (node == NULL) {
                        *errMsg = tdomstrdup(errStr);
                        res = XPATH_EVAL_ERR;
                        goto funcCallCleanup;
                    }
                    rsAddNode(result, node);
                }
                sortByDocOrder(result);
            } else
................................................................................
            if (strcmp(typeStr, "attrvalues")==0) {
                rsSetString(result, Tcl_GetString(value));
            } else {
                *errMsg = (char*)MALLOC (80 + strlen (typeStr)
                                         + strlen (functionName));
                strcpy(*errMsg, "Unknown type of return value \"");
                strcat(*errMsg, typeStr);
                strcat(*errMsg, "\" from tcl coded XPath function \"");
                strcat(*errMsg, functionName);
                strcat(*errMsg, "\"!");
                res = XPATH_EVAL_ERR;
                goto funcCallCleanup;
            }
        } else {
            DBG(fprintf(stderr, "ListObjLength != TCL_OK "
................................................................................
            goto funcCallCleanup;
        }
        Tcl_ResetResult(interp);
        res = XPATH_OK;
    } else {
        errStr = Tcl_GetStringFromObj( Tcl_GetObjResult(interp), &errStrLen);
        *errMsg = (char*)MALLOC(120+strlen(functionName) + errStrLen);
        strcpy(*errMsg, "Tcl error while executing XPATH extension function '");
        strcat(*errMsg, functionName );
        strcat(*errMsg, "':\n" );
        strcat(*errMsg, errStr);
        Tcl_ResetResult(interp);
        DBG(fprintf(stderr, "returning XPATH_EVAL_ERR \n");)
        res = XPATH_EVAL_ERR;
    }
................................................................................
}

/*----------------------------------------------------------------------------
|   tcldom_xsltMsgCB
|
\---------------------------------------------------------------------------*/
static
void tcldom_xsltMsgCB (
    void *clientData,
    char *str,
    int   length,
    int   terminate
    )
{
    XsltMsgCBInfo *msgCBInfo = (XsltMsgCBInfo *)clientData;
    Tcl_Obj       *cmdPtr;


    if (msgCBInfo->msgcmd == NULL) {
        return;
    }
    
    cmdPtr = Tcl_DuplicateObj(msgCBInfo->msgcmd);
    Tcl_IncrRefCount(cmdPtr);
    if (Tcl_ListObjAppendElement(msgCBInfo->interp, cmdPtr, 
                                 Tcl_NewStringObj(str, length)) != TCL_OK) {
        Tcl_DecrRefCount(cmdPtr);
        return;
    }
    if (terminate) {
        Tcl_ListObjAppendElement(msgCBInfo->interp, cmdPtr,
                                 Tcl_NewBooleanObj(1));
    } else {
        Tcl_ListObjAppendElement(msgCBInfo->interp, cmdPtr,
                                 Tcl_NewBooleanObj(0));
    }
    Tcl_GlobalEvalObj(msgCBInfo->interp, cmdPtr);
    Tcl_DecrRefCount(cmdPtr);



    return;

}

/*----------------------------------------------------------------------------
|   tcldom_xpathResolveVar
|
\---------------------------------------------------------------------------*/
static
................................................................................
char * tcldom_xpathResolveVar (
    void  *clientData,
    char  *strToParse,
    int   *offset,
    char **errMsg
    )
{
    CONST char *varValue;
    CONST char *termPtr;
    Tcl_Interp *interp = (Tcl_Interp *) clientData;
    
    *offset = 0;
    varValue = Tcl_ParseVar(interp, strToParse, &termPtr);
    if (varValue) {
        *offset = termPtr - strToParse;
        /* If strToParse start with a single '$' without a following
         * var name (according to tcl var name rules), Tcl_ParseVar()
         * doesn't report a parsing error but returns just a pointer
         * to a static string "$". */ 
        if (*offset == 1) {
            *errMsg = tdomstrdup ("Missing var name after '$'.");
            varValue = NULL;
        }
    } else {
................................................................................
|
\---------------------------------------------------------------------------*/
static
int tcldom_selectNodes (
    Tcl_Interp *interp,
    domNode    *node,
    int         objc,
    Tcl_Obj    *CONST objv[]
)
{
    char          *xpathQuery, *typeVar, *option;
    char          *errMsg = NULL, **mappings = NULL;
    int            rc, i, len, optionIndex, localmapping, cache = 0;

    xpathResultSet rs;
    Tcl_Obj       *type, *objPtr;
    xpathCBs       cbs;
    xpathParseVarCB parseVarCB;

    static CONST84 char *selectNodesOptions[] = {
        "-namespaces", "-cache", NULL
    };
    enum selectNodesOption {
        o_namespaces, o_cache
    };

    if (objc < 2) {
................................................................................
        }
        switch ((enum selectNodesOption) optionIndex) {
        case o_namespaces:
            rc = Tcl_ListObjLength (interp, objv[2], &len);
            if (rc != TCL_OK || (len % 2) != 0) {
                SetResult ("The \"-namespaces\" option requires a 'prefix"
                           " namespace' pairs list as argument");
                return TCL_ERROR;

            }
            if (mappings) {





                FREE (mappings);
            }
            mappings = MALLOC (sizeof (char *) * (len + 1));

            for (i = 0; i < len; i++) {
                Tcl_ListObjIndex (interp, objv[2], i, &objPtr);
                /* The prefixMappings array is only used at xpath expr
                   compile time. (And every needed info is strdup'ed.)
                   So, we don't need to fiddle around with the refcounts
                   of the prefixMappings list members.
                   If we, at some day, allow to evaluate tcl scripts during
                   xpath lexing/parsing, this must be revisited. */
                mappings[i] = Tcl_GetString (objPtr);
            }
            mappings[len] = NULL;



            objc -= 2;
            objv += 2;
            break;

        case o_cache:
            if (Tcl_GetBooleanFromObj (interp, objv[2], &cache) != TCL_OK) {
                return TCL_ERROR;
................................................................................
            Tcl_AppendResult (interp, "bad option \"", 
                              Tcl_GetString (objv[1]), "\"; must be "
                              "-namespaces", NULL);
            return TCL_ERROR;
        }
    }
    if (objc != 2 && objc != 3) {
        if (mappings) {
            FREE (mappings);
        }
        SetResult("Wrong # of arguments.");
        return TCL_ERROR;

    }

    xpathQuery = Tcl_GetString(objv[1]);

    xpathRSInit(&rs);

    cbs.funcCB         = tcldom_xpathFuncCallBack;
................................................................................
    cbs.varClientData  = NULL;

    parseVarCB.parseVarCB         = tcldom_xpathResolveVar;
    parseVarCB.parseVarClientData = interp;
    
    if (mappings == NULL) {
        mappings = node->ownerDocument->prefixNSMappings;
        localmapping = 0;
    } else {
        localmapping = 1;
    }

    if (cache) {
        if (!node->ownerDocument->xpathCache) {
            node->ownerDocument->xpathCache = MALLOC (sizeof (Tcl_HashTable));
            Tcl_InitHashTable (node->ownerDocument->xpathCache,
                               TCL_STRING_KEYS);
        }
        rc = xpathEval (node, node, xpathQuery, mappings, &cbs, &parseVarCB,
................................................................................
    if (rc != XPATH_OK) {
        xpathRSFree(&rs);
        SetResult(errMsg);
        DBG(fprintf(stderr, "errMsg = %s \n", errMsg);)
        if (errMsg) {
            FREE(errMsg);
        }
        if (localmapping && mappings) {
            FREE(mappings);
        }
        return TCL_ERROR;

    }
    if (errMsg) {

        FREE(errMsg);
    }
    typeVar = NULL;
    if (objc > 2) {
        typeVar = Tcl_GetString(objv[2]);
    }
    type = Tcl_NewObj();
................................................................................
    Tcl_IncrRefCount(type);
    DBG(fprintf(stderr, "before tcldom_xpathResultSet \n");)
    tcldom_xpathResultSet(interp, &rs, type, Tcl_GetObjResult(interp));
    DBG(fprintf(stderr, "after tcldom_xpathResultSet \n");)
    if (typeVar) {
        Tcl_SetVar(interp,typeVar, Tcl_GetString(type), 0);
    }

    Tcl_DecrRefCount(type);

    xpathRSFree( &rs );

    if (localmapping && mappings) {





        FREE (mappings);
    }
    return TCL_OK;
}

/*----------------------------------------------------------------------------
|   tcldom_nameCheck
|
\---------------------------------------------------------------------------*/
int tcldom_nameCheck (
................................................................................
    |   create element node
    \-----------------------------------------------------------------------*/
    if (length != 3) {
        SetResult("invalid element node list format!");
        return TCL_ERROR;
    }
    CheckName (interp, tag_name, "tag", 0);
    newnode = domNewElementNode(node->ownerDocument, tag_name, ELEMENT_NODE);
    domAppendChild(node, newnode);

    /*------------------------------------------------------------------------
    |   create atributes
    \-----------------------------------------------------------------------*/
    if ((rc = Tcl_ListObjIndex(interp, lnode, 1, &attrListObj)) != TCL_OK) {
        return rc;
    }
    if ((rc = Tcl_ListObjLength(interp, attrListObj, &attrLength))
        != TCL_OK) {
        return rc;
................................................................................
            return rc;
        }
        if ((rc = tcldom_appendFromTclList(interp, newnode, childObj))
            != TCL_OK) {
            return rc;
        }
    }
    return tcldom_returnNodeObj(interp, node, 0, NULL);
}


/*----------------------------------------------------------------------------
|   tcldom_treeAsTclList
|
\---------------------------------------------------------------------------*/
................................................................................
    objv[0] = name;
    objv[1] = attrsList;
    objv[2] = childList;

    return Tcl_NewListObj(3, objv);
}


/*----------------------------------------------------------------------------
|   tcldom_AppendEscaped
|
\---------------------------------------------------------------------------*/
static
void tcldom_AppendEscaped (
    Tcl_Obj    *xmlString,
    Tcl_Channel chan,
    char       *value,
    int         value_length,
    int         forAttr,
    int         escapeNonASCII,
    int         htmlEntities,
    int         escapeAllQuot
)
{
#define APESC_BUF_SIZE 512
#define AP(c)  *b++ = c;
#define AE(s)  pc1 = s; while(*pc1) *b++ = *pc1++;
    char  buf[APESC_BUF_SIZE+80], *b, *bLimit,  *pc, *pc1, *pEnd, charRef[10];
    int   charDone, i;
#if !TclOnly8Bits
    int   clen = 0;

    Tcl_UniChar uniChar;
#endif

    b = buf;
    bLimit = b + APESC_BUF_SIZE;
    pc = pEnd = value;
    if (value_length != -1) {
        pEnd = pc + value_length;
    }
    while (   (value_length == -1 && *pc)
           || (value_length != -1 && pc != pEnd)
    ) {
        if ((forAttr || escapeAllQuot) && (*pc == '"')) { 

            AP('&') AP('q') AP('u') AP('o') AP('t') AP(';')
        } else
        if (*pc == '&') { AP('&') AP('a') AP('m') AP('p') AP(';')
        } else
        if (*pc == '<') { AP('&') AP('l') AP('t') AP(';')
        } else

        if (*pc == '>') { AP('&') AP('g') AP('t') AP(';')
        } else

        if (forAttr && (*pc == '\n')) { AP('&') AP('#') AP('x') AP('A') AP(';')
        } else
        {
            charDone = 0;
            if (htmlEntities) {
                charDone = 1;
#if TclOnly8Bits
                switch ((unsigned int)*pc)
#else           
                Tcl_UtfToUniChar(pc, &uniChar);
                switch (uniChar) 
#endif
                {
                case 0240: AE("&nbsp;");    break;     
                case 0241: AE("&iexcl;");   break;    
                case 0242: AE("&cent;");    break;     
                case 0243: AE("&pound;");   break;    
                case 0244: AE("&curren;");  break;   
                case 0245: AE("&yen;");     break;      
................................................................................
                case 0371: AE("&ugrave;");  break;   
                case 0372: AE("&uacute;");  break;   
                case 0373: AE("&ucirc;");   break;    
                case 0374: AE("&uuml;");    break;     
                case 0375: AE("&yacute;");  break;   
                case 0376: AE("&thorn;");   break;    
                case 0377: AE("&yuml;");    break;     
#if !TclOnly8Bits
                /* "Special" chars, according to XHTML xhtml-special.ent */
                case 338:  AE("&OElig;");   break;
                case 339:  AE("&oelig;");   break;
                case 352:  AE("&Scaron;");  break;
                case 353:  AE("&scaron;");  break;
                case 376:  AE("&Yuml;");    break;
                case 710:  AE("&circ;");    break;
................................................................................
                case 9001: AE("&lang;");    break;     
                case 9002: AE("&rang;");    break;     
                case 9674: AE("&loz;");     break;      
                case 9824: AE("&spades;");  break;   
                case 9827: AE("&clubs;");   break;    
                case 9829: AE("&hearts;");  break;   
                case 9830: AE("&diams;");   break;    
#endif                    
                default: charDone = 0; 
                }
#if !TclOnly8Bits
                if (charDone) {
                    clen = UTF8_CHAR_LEN(*pc);
                    pc += (clen - 1);
                }
#endif
            }
#if TclOnly8Bits
            if (!charDone) {
                if (escapeNonASCII && ((unsigned char)*pc > 127)) {
                    AP('&') AP('#')
                    sprintf(charRef, "%d", (unsigned char)*pc);
                    for (i = 0; i < 3; i++) {
                        AP(charRef[i]);
                    }
                    AP(';')
                } else {
                    AP(*pc);
                }
            }
#else
            if (!charDone) {
                if ((unsigned char)*pc > 127) {
                    clen = UTF8_CHAR_LEN(*pc);
                    if (!clen) {
                        domPanic("tcldom_AppendEscaped: can only handle "
                                 "UTF-8 chars up to 3 bytes length");
                    }
                    if (escapeNonASCII) {









                        Tcl_UtfToUniChar(pc, &uniChar);

                        AP('&') AP('#')
                            sprintf(charRef, "%d", uniChar);
                        for (i = 0; i < (int)strlen(charRef); i++) {
                            AP(charRef[i]);
                        }
                        AP(';')
                        pc += (clen - 1);
                    } else {
                        for (i = 0; i < clen; i++) {
................................................................................
                        }
                        pc--;
                    }
                } else {
                    AP(*pc);
                }
            }
#endif
        }
        if (b >= bLimit) {
            writeChars(xmlString, chan, buf, b - buf);
            b = buf;
        }
        pc++;
    }
................................................................................
    Tcl_Channel  chan,
    int          escapeNonASCII,
    int          htmlEntities,
    int          doctypeDeclaration,
    int          noEscaping
)
{
    int          empty, scriptTag;
    domNode     *child;
    domAttrNode *attrs;
    domDocument *doc;
    char         tag[80], attrName[80];



    if (node->nodeType == DOCUMENT_NODE) {
        doc = (domDocument*) node;
        if (doctypeDeclaration && doc->documentElement) {
            writeChars(htmlString, chan, "<!DOCTYPE ", 10);
            writeChars(htmlString, chan, doc->documentElement->nodeName, -1);
            if (   doc->doctype 
                && doc->doctype->systemId 
................................................................................
        if ((node->nodeFlags & DISABLE_OUTPUT_ESCAPING) 
            || noEscaping) {
            writeChars(htmlString, chan, ((domTextNode*)node)->nodeValue,
                       ((domTextNode*)node)->valueLength);
        } else {
            tcldom_AppendEscaped(htmlString, chan,
                                 ((domTextNode*)node)->nodeValue,
                                 ((domTextNode*)node)->valueLength, 0,
                                 escapeNonASCII, htmlEntities, 0);
        }
        return;
    }

    if (node->nodeType == CDATA_SECTION_NODE) {
        if (noEscaping) {
            writeChars(htmlString, chan, ((domTextNode*)node)->nodeValue,
                       ((domTextNode*)node)->valueLength);
        } else {
            tcldom_AppendEscaped(htmlString, chan,
                                 ((domTextNode*)node)->nodeValue,
                                 ((domTextNode*)node)->valueLength, 0,
                                 escapeNonASCII, htmlEntities, 0);
        }

    }

    if (node->nodeType == COMMENT_NODE) {
        writeChars(htmlString, chan, "<!--", 4);
        writeChars(htmlString, chan, ((domTextNode*)node)->nodeValue,
                   ((domTextNode*)node)->valueLength);
        writeChars(htmlString, chan,  "-->", 3);
................................................................................
    |   empty tags and script tags (todo: HTML tags with
    |   URI attributes, to do escaping of Non-ASCII chars
    |   in the URI).
    \----------------------------------------------------------*/
    empty = 0;
    scriptTag = 0;
    switch (tag[0]) {
        case 'a':  if (!strcmp(tag,"area"))       empty = 1; break;
        case 'b':  if (!strcmp(tag,"br")     ||
                       !strcmp(tag,"base")   ||
                       !strcmp(tag,"basefont"))   empty = 1;
        case 'c':  if (!strcmp(tag,"col"))        empty = 1; break;
        case 'f':  if (!strcmp(tag,"frame"))      empty = 1; break;
        case 'h':  if (!strcmp(tag,"hr"))         empty = 1; break;
        case 'i':  if (!strcmp(tag,"img")    ||
                       !strcmp(tag,"input")  ||
                       !strcmp(tag,"isindex"))    empty = 1; break;
        case 'l':  if (!strcmp(tag,"link"))       empty = 1; break;
        case 'm':  if (!strcmp(tag,"meta"))       empty = 1; break;
        case 'p':  if (!strcmp(tag,"param"))      empty = 1; break;
        case 's':  if (!strcmp(tag,"script") ||     
                       !strcmp(tag,"style"))  scriptTag = 1; break;
    }


    attrs = node->firstAttr;
    while (attrs) {
        tcldom_tolower(attrs->nodeName, attrName, 80);
        writeChars(htmlString, chan, " ", 1);
        writeChars (htmlString, chan, attrName, -1);
        writeChars(htmlString, chan, "=\"", 2);
        tcldom_AppendEscaped(htmlString, chan, attrs->nodeValue, -1, 1,
                             escapeNonASCII, htmlEntities, 0);
        writeChars(htmlString, chan, "\"", 1);
        attrs = attrs->nextSibling;
    }
    writeChars(htmlString, chan, ">", 1);


    if (empty) {
................................................................................
void tcldom_treeAsXML (
    Tcl_Obj    *xmlString,
    domNode    *node,
    int         indent,
    int         level,
    int         doIndent,
    Tcl_Channel chan,
    int         escapeNonASCII,
    int         doctypeDeclaration,
    int         cdataChild,
    int         escapeAllQuot

)
{
    domAttrNode   *attrs;
    domNode       *child;
    domDocument   *doc;
    int            first, hasElements, i;
    char           prefix[MAX_PREFIX_LEN], *start, *p;
    const char    *localName;
    Tcl_HashEntry *h;
    Tcl_DString    dStr;



















    if (node->nodeType == DOCUMENT_NODE) {
        doc = (domDocument*) node;

        if (doctypeDeclaration && doc->documentElement) {
            writeChars(xmlString, chan, "<!DOCTYPE ", 10);
            writeChars(xmlString, chan, doc->documentElement->nodeName, -1);
            if (   doc->doctype 
                && doc->doctype->systemId
                && (doc->doctype->systemId[0] != '\0')) {
                if (   doc->doctype->publicId 
                    && doc->doctype->publicId[0] != '\0') {
................................................................................
                }
            }
            writeChars(xmlString, chan, ">\n", 2);
        }
        child = doc->rootNode->firstChild;
        while (child) {
            tcldom_treeAsXML(xmlString, child, indent, level, doIndent, chan,
                             escapeNonASCII, doctypeDeclaration, 0,
                             escapeAllQuot);
            child = child->nextSibling;
        }
        return;
    }

    if (node->nodeType == TEXT_NODE) {
        if (cdataChild) {
................................................................................
        } else {
            if (node->nodeFlags & DISABLE_OUTPUT_ESCAPING) {
                writeChars(xmlString, chan, ((domTextNode*)node)->nodeValue,
                           ((domTextNode*)node)->valueLength);
            } else {
                tcldom_AppendEscaped(xmlString, chan,
                                     ((domTextNode*)node)->nodeValue,
                                     ((domTextNode*)node)->valueLength, 0,
                                     escapeNonASCII, 0, escapeAllQuot);
            }
        }
        return;
    }

    if (node->nodeType == CDATA_SECTION_NODE) {
        writeChars(xmlString, chan, "<![CDATA[", 9);
................................................................................
    }

    writeChars(xmlString, chan, "<", 1);
    writeChars(xmlString, chan, node->nodeName, -1);

    attrs = node->firstAttr;
    while (attrs) {











        writeChars(xmlString, chan, " ", 1);

        writeChars(xmlString, chan, attrs->nodeName, -1);
        writeChars(xmlString, chan, "=\"", 2);
        tcldom_AppendEscaped(xmlString, chan, attrs->nodeValue, 
                             attrs->valueLength, 1, escapeNonASCII, 0,
                             escapeAllQuot);
        writeChars(xmlString, chan, "\"", 1);
        attrs = attrs->nextSibling;
    }

    hasElements = 0;
    first       = 1;
    doIndent    = 1;
................................................................................
                writeChars(xmlString, chan, ">", 1);
                if ((indent != -1) && hasElements) {
                    writeChars(xmlString, chan, "\n", 1);
                }
            }
            first = 0;
            tcldom_treeAsXML(xmlString, child, indent, level+1, doIndent,
                             chan, escapeNonASCII, doctypeDeclaration,
                             cdataChild, escapeAllQuot);
            doIndent = 0;
            if (  (child->nodeType == ELEMENT_NODE)
                ||(child->nodeType == PROCESSING_INSTRUCTION_NODE)
                ||(child->nodeType == COMMENT_NODE) )
            {
               doIndent = 1;
            }
            child = child->nextSibling;
        }
    }

    if (first) {
        if (indent != -1) {





            writeChars(xmlString, chan, "/>\n", 3);

        } else {





            writeChars(xmlString, chan, "/>",   2);

        }
    } else {
        if ((indent != -1) && hasElements) {
            for(i=0; i<level; i++) {
                writeChars(xmlString, chan, "        ", indent);
            }
        }
................................................................................
        if (indent != -1) {
            writeChars(xmlString, chan, ">\n", 2);
        } else {
            writeChars(xmlString, chan, ">",   1);
        }
    }
}

















































































































































































































































































































































































/*----------------------------------------------------------------------------
|   findBaseURI
|
\---------------------------------------------------------------------------*/
const char *findBaseURI (
    domNode *node
................................................................................
|   serializeAsXML
|
\---------------------------------------------------------------------------*/
static int serializeAsXML (
    domNode    *node,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *CONST objv[]
)
{
    char          *channelId, prefix[MAX_PREFIX_LEN];
    const char    *localName;
    int            indent, mode, escapeNonASCII = 0, doctypeDeclaration = 0;

    int            optionIndex, cdataChild, escapeAllQuot = 0;
    Tcl_Obj       *resultPtr;
    Tcl_Channel    chan = (Tcl_Channel) NULL;
    Tcl_HashEntry *h;
    Tcl_DString    dStr;


    static CONST84 char *asXMLOptions[] = {
        "-indent", "-channel", "-escapeNonASCII", "-doctypeDeclaration",
        "-escapeAllQuot", 


        NULL
    };
    enum asXMLOption {
        m_indent, m_channel, m_escapeNonASCII, m_doctypeDeclaration,
        m_escapeAllQuot

    };
    
    if (objc > 10) {
        Tcl_WrongNumArgs(interp, 2, objv,
                         "?-indent <0..8>? ?-channel <channelID>? "
                         "?-escapeNonASCII? ?-escapeAllQuot? "
                         "?-doctypeDeclaration <boolean>?");
        return TCL_ERROR;
    }
    indent = 4;
    while (objc > 2) {
        if (Tcl_GetIndexFromObj(interp, objv[2], asXMLOptions, "option", 0,
                               &optionIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        switch ((enum asXMLOption) optionIndex) {

        case m_indent:
            if (objc < 4) {
                SetResult("-indent must have an argument "
                          "(0..8 or 'no'/'none')");
                return TCL_ERROR;
            }
            if (strcmp("none", Tcl_GetString(objv[3]))==0) {
                indent = -1;
            }
            else if (strcmp("no", Tcl_GetString(objv[3]))==0) {
                indent = -1;
            }
            else if (Tcl_GetIntFromObj(interp, objv[3], &indent) != TCL_OK) {
                SetResult( "indent must be an integer (0..8) or 'no'/'none'");
                return TCL_ERROR;
            }
            objc -= 2;
            objv += 2;
            break;























        case m_channel:
            if (objc < 4) {
                SetResult("-channel must have a channeldID as argument");
                return TCL_ERROR;
            }
            channelId = Tcl_GetString(objv[3]);
            chan = Tcl_GetChannel(interp, channelId, &mode);
            if (chan == (Tcl_Channel) NULL) {
                SetResult("-channel must have a channeldID as argument");
                return TCL_ERROR;
            }
            if ((mode & TCL_WRITABLE) == 0) {
                Tcl_AppendResult(interp, "channel \"", channelId,
                                "\" wasn't opened for writing", (char*)NULL);
                return TCL_ERROR;
            }
            objc -= 2;
            objv += 2;
            break;

        case m_escapeNonASCII:
            escapeNonASCII = 1;
            objc--;
            objv++;
            break;
            
        case m_doctypeDeclaration:
            if (node->nodeType != DOCUMENT_NODE) {
                SetResult("-doctypeDeclaration as flag to the method "
                          "'asXML' is only allowed for domDocCmds");
                return TCL_ERROR;
            }
            if (objc < 4) {
                SetResult("-doctypeDeclaration must have a boolean value "
                          "as argument");
                return TCL_ERROR;
            }
            if (Tcl_GetBooleanFromObj(interp, objv[3], &doctypeDeclaration)
                != TCL_OK) {
                return TCL_ERROR;
            }































            objc -= 2;
            objv += 2;
            break;

        case m_escapeAllQuot:
            escapeAllQuot = 1;












            objc -= 1;
            objv += 1;
            break;
        }
    }
    if (indent > 8)  indent = 8;
    if (indent < -1) indent = -1;
................................................................................
                node->ownerDocument->doctype->cdataSectionElements,
                node->nodeName);
        }
        if (h) {
            cdataChild = 1;
        }
    }
    tcldom_treeAsXML(resultPtr, node, indent, 0, 1, chan, escapeNonASCII,
                     doctypeDeclaration, cdataChild, escapeAllQuot);
    Tcl_SetObjResult(interp, resultPtr);



    return TCL_OK;





}

/*----------------------------------------------------------------------------
|   serializeAsHTML
|
\---------------------------------------------------------------------------*/
static int serializeAsHTML (
    domNode    *node,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *CONST objv[]
)
{
    char       *channelId;
    int         optionIndex, mode, escapeNonASCII = 0, htmlEntities = 0;
    int         doctypeDeclaration = 0;
    Tcl_Obj    *resultPtr;
    Tcl_Channel chan = (Tcl_Channel) NULL;

    static CONST84 char *asHTMLOptions[] = {
        "-channel", "-escapeNonASCII", "-htmlEntities", "-doctypeDeclaration",
        NULL
    };
    enum asHTMLOption {
        m_channel, m_escapeNonASCII, m_htmlEntities, m_doctypeDeclaration
    };
    
................................................................................
    resultPtr = Tcl_NewStringObj("", 0);
    tcldom_treeAsHTML(resultPtr, node, chan, escapeNonASCII, htmlEntities,
                      doctypeDeclaration, 0);
    Tcl_AppendResult(interp, Tcl_GetString(resultPtr), NULL);
    Tcl_DecrRefCount(resultPtr);
    return TCL_OK;
}

/*----------------------------------------------------------------------------






























































































|   cdataSectionElements
|
\---------------------------------------------------------------------------*/
static int cdataSectionElements (
    domDocument *doc,
    Tcl_Interp  *interp,
    int          objc,
    Tcl_Obj     *CONST objv[] 
    )
{
    int result, hnew;
    Tcl_Obj *resultPtr,*namePtr;
    Tcl_HashEntry *h;
    Tcl_HashSearch search;
    
................................................................................
|   selectNodesNamespaces
|
\---------------------------------------------------------------------------*/
static int selectNodesNamespaces (
    domDocument *doc,
    Tcl_Interp  *interp,
    int          objc,
    Tcl_Obj     *CONST objv[] 
    )
{
    int      len, i, result;
    Tcl_Obj *objPtr, *listPtr;

    CheckArgs (2,3,2, "?prefixUriList?");
    if (objc == 3) {
................................................................................
|   renameNodes
|
\---------------------------------------------------------------------------*/
static int renameNodes (
    domDocument *doc,
    Tcl_Interp  *interp,
    int          objc,
    Tcl_Obj     *CONST objv[] 
    )
{
    int      len, i, hnew;
    char    *errMsg;
    Tcl_HashEntry *h;
    Tcl_Obj *objPtr;
    domNode     *node;
    
    CheckArgs (4,4,0, "<domDoc> renameNode nodeList name");
    if (Tcl_ListObjLength (interp, objv[2], &len) != TCL_OK) {
        SetResult ("The first argument to the renameNode method"
................................................................................
                   " must be a list of element nodes.");
        return TCL_ERROR;
    }
    h = Tcl_CreateHashEntry(&HASHTAB(doc,tdom_tagNames), 
                            Tcl_GetString(objv[3]), &hnew);
    for (i = 0; i < len; i++) {
        Tcl_ListObjIndex (interp, objv[2], i, &objPtr);
        node = tcldom_getNodeFromName (interp, Tcl_GetString (objPtr),
                                       &errMsg);
        if (node == NULL) {
            SetResult (errMsg);
            if (errMsg) FREE (errMsg);
            return TCL_ERROR;
        }
        node->nodeName = (char *)&(h->key);
    }
    return TCL_OK;
}

................................................................................
|   deleteXPathCache
|
\---------------------------------------------------------------------------*/
static int deleteXPathCache (
    domDocument *doc,
    Tcl_Interp  *interp,
    int          objc,
    Tcl_Obj     *CONST objv[] 
    )
{
    Tcl_HashEntry *h;
    Tcl_HashSearch search;
    
    CheckArgs (2,3,0, "<domDoc> deleteXPathCache ?xpathQuery?");
    if (objc == 3) {
................................................................................
|
\---------------------------------------------------------------------------*/
static int applyXSLT (
    domNode     *node,
    Tcl_Interp  *interp,
    void        *clientData,
    int          objc,
    Tcl_Obj     *CONST objv[]
    )
{
    char          *usage, **parameters = NULL, *errMsg, *option;
    Tcl_Obj       *objPtr, *localListPtr = (Tcl_Obj *)NULL;
    int            i, result, length, optionIndex;
    int            ignoreUndeclaredParameters = 0;

    domDocument   *xsltDoc, *xmlDoc, *resultDoc;
    XsltMsgCBInfo  xsltMsgInfo;

    static char *method_usage = 
        "wrong # args: should be \"nodeObj xslt ?-parameters parameterList? "
        "?-ignoreUndeclaredParameters? ?-xsltmessagecmd cmd? xsltDocNode "
        "?varname?\"";

    static char *cmd_usage = 
        "wrong # args: should be \"?-parameters parameterList? "
        "?-ignoreUndeclaredParameters? ?-xsltmessagecmd cmd? <xmlDocObj> "
        "?objVar?\"";

    static CONST84 char *xsltOptions[] = {
        "-parameters", "-ignoreUndeclaredParameters", "-xsltmessagecmd", NULL

    };

    enum xsltOption {
        m_parmeters, m_ignoreUndeclaredParameters, m_xsltmessagecmd

    };

    xsltMsgInfo.interp = interp;
    xsltMsgInfo.msgcmd = NULL;

    if (node)  usage = method_usage;
    else       usage = cmd_usage;
................................................................................
        if (Tcl_GetIndexFromObj(interp, objv[0], xsltOptions, "option", 0,
                                 &optionIndex) != TCL_OK) {
            goto applyXSLTCleanUP;
        }
    
        switch ((enum xsltOption) optionIndex) {

        case m_parmeters:
            if (objc < 3) {SetResult(usage); goto applyXSLTCleanUP;}
            if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK) {
                SetResult("ill-formed parameters list: the -parameters "
                          "option needs a list of parameter name and "
                          "parameter value pairs");
                goto applyXSLTCleanUP;
            }
................................................................................
            Tcl_IncrRefCount(localListPtr);
            parameters =  (char **)MALLOC(sizeof(char *)*(length+1));
            for (i = 0; i < length; i ++) {
                Tcl_ListObjIndex(interp, localListPtr, i, &objPtr);
                parameters[i] = Tcl_GetString(objPtr);
            }
            parameters[length] = NULL;

















            objc -= 2;
            objv += 2;
            break;
        
        case m_ignoreUndeclaredParameters:
            if (objc < 2) {SetResult(usage); goto applyXSLTCleanUP;}
            ignoreUndeclaredParameters = 1;
................................................................................
            SetResult( errMsg );
            goto applyXSLTCleanUP;
        }
        node = (domNode *) xmlDoc;
        xsltDoc = NULL;
    }
    result = xsltProcess(xsltDoc, node, clientData, parameters, 
                          ignoreUndeclaredParameters,

                          tcldom_xpathFuncCallBack,  interp,
                          tcldom_xsltMsgCB, &xsltMsgInfo,
                          &errMsg, &resultDoc);

    if (result < 0) {
        SetResult( errMsg );
        FREE(errMsg);



        goto applyXSLTCleanUP;
    }
    if (parameters) {
        Tcl_DecrRefCount(localListPtr);
        FREE((char *) parameters);
    }
    if (xsltMsgInfo.msgcmd) {
        Tcl_DecrRefCount(xsltMsgInfo.msgcmd);
    }
    return tcldom_returnDocumentObj(interp, resultDoc, (objc == 2),
                                     (objc == 2) ? objv[1] : NULL, 1, 0);
            
 applyXSLTCleanUP:
    if (localListPtr) {
        Tcl_DecrRefCount(localListPtr);
        FREE((char *) parameters);
    }
    if (xsltMsgInfo.msgcmd) {
................................................................................
|   tcldom_XSLTObjCmd
|
\---------------------------------------------------------------------------*/
static int tcldom_XSLTObjCmd (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *CONST objv[]
)
{
    int          index;
    char        *errMsg = NULL;
    
    static CONST84 char *options[] = {
        "transform", "delete", NULL
    };
    enum option {
        m_transform, m_delete
    };
    

................................................................................
|   tcldom_NodeObjCmd
|
\---------------------------------------------------------------------------*/
int tcldom_NodeObjCmd (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *CONST objv[]
)
{
    GetTcldomTSD()

    domNode     *node, *child, *refChild, *oldChild, *refNode;
    domNS       *ns;
    domAttrNode *attrs;
    domException exception;
    char         tmp[200], objCmdName[80], prefix[MAX_PREFIX_LEN],
                *method, *nodeName, *str, *attr_name, *attr_val, *filter,
                *errMsg;
    const char  *localName, *uri, *nsStr;
    int          result, length, methodIndex, i, line, column;
    int          nsIndex, bool, hnew;
    Tcl_Obj     *namePtr, *resultPtr;
    Tcl_Obj     *mobjv[MAX_REWRITE_ARGS];
    Tcl_CmdInfo  cmdInfo;
    Tcl_HashEntry *h;

    static CONST84 char *nodeMethods[] = {
        "firstChild",      "nextSibling",    "getAttribute",    "nodeName",
        "nodeValue",       "nodeType",       "attributes",      "asList",
        "find",            "setAttribute",   "removeAttribute", "parentNode",
        "previousSibling", "lastChild",      "appendChild",     "removeChild",
        "hasChildNodes",   "localName",      "childNodes",      "ownerDocument",
        "insertBefore",    "replaceChild",   "getLine",         "getColumn",
        "asXML",           "appendFromList", "child",           "fsibling",
................................................................................
        "target",          "data",           "selectNodes",     "namespaceURI",
        "getAttributeNS",  "setAttributeNS", "hasAttributeNS",  "removeAttributeNS",
        "asHTML",          "prefix",         "getBaseURI",      "appendFromScript",
        "xslt",            "toXPath",        "delete",          "getElementById",
        "getElementsByTagName",              "getElementsByTagNameNS",
        "disableOutputEscaping",             "precedes",         "asText",
        "insertBeforeFromScript",            "normalize",        "baseURI",

#ifdef TCL_THREADS
        "readlock",        "writelock",
#endif
        NULL
    };
    enum nodeMethod {
        m_firstChild,      m_nextSibling,    m_getAttribute,    m_nodeName,
................................................................................
        m_root,            m_hasAttribute,   m_cloneNode,       m_appendXML,
        m_target,          m_data,           m_selectNodes,     m_namespaceURI,
        m_getAttributeNS,  m_setAttributeNS, m_hasAttributeNS,  m_removeAttributeNS,
        m_asHTML,          m_prefix,         m_getBaseURI,      m_appendFromScript,
        m_xslt,            m_toXPath,        m_delete,          m_getElementById,
        m_getElementsByTagName,              m_getElementsByTagNameNS,
        m_disableOutputEscaping,             m_precedes,        m_asText,
        m_insertBeforeFromScript,            m_normalize,       m_baseURI

#ifdef TCL_THREADS
        ,m_readlock,        m_writelock
#endif
    };


    node = (domNode*) clientData;
    if (TSD(domCreateCmdMode) == DOM_CREATECMDMODE_AUTO) {
        TSD(dontCreateObjCommands) = 0;
    }
    if (node == NULL) {
        if (objc < 3) {
            SetResult(node_usage);
            return TCL_ERROR;
        }
        if (TSD(domCreateCmdMode) == DOM_CREATECMDMODE_AUTO) {
            TSD(dontCreateObjCommands) = 1;
        }
        nodeName = Tcl_GetString(objv[1]);
        node = tcldom_getNodeFromName(interp, nodeName, &errMsg);
        if (node == NULL) {
            SetResult(errMsg);
            return TCL_ERROR;
        }

        objc--;
        objv++;
    }
    if (objc < 2) {
        SetResult(node_usage);
        return TCL_ERROR;
    }
................................................................................
    /*----------------------------------------------------------------------
    |   dispatch the node object method
    |
    \---------------------------------------------------------------------*/
    switch ((enum nodeMethod)methodIndex) {

        case m_toXPath:
            CheckArgs(2,2,2,"");









            str = xpathNodeToXPath(node);
            SetResult (str);
            FREE (str);
            return TCL_OK;

        case m_xslt:
            CheckArgs(3,9,2, "?-parameters parameterList? "
                      "?-ignoreUndeclaredParameters? ?-xsltmessagecmd cmd? "
................................................................................
        case m_selectNodes:
            return tcldom_selectNodes (interp, node, --objc, ++objv);

        case m_find:
            CheckArgs(4,5,2,"attrName attrVal ?nodeObjVar?");
            attr_name = Tcl_GetStringFromObj(objv[2], NULL);
            attr_val  = Tcl_GetStringFromObj(objv[3], &length);
            return tcldom_returnNodeObj
                (interp, tcldom_find(node, attr_name, attr_val, length),
                 (objc == 5), (objc == 5) ? objv[4] : NULL);

        case m_child:
            CheckArgs(3,6,2,"instance|all ?type? ?attr value?");
            return tcldom_xpointerSearch(interp, XP_CHILD, node, objc, objv);

................................................................................
            return tcldom_xpointerSearch(interp, XP_PSIBLING, node,objc,objv);

        case m_root:
            CheckArgs(2,3,2,"?nodeObjVar?");
            while (node->parentNode) {
                node = node->parentNode;
            }
            return tcldom_returnNodeObj(interp, node, (objc == 3),
                                        (objc == 3) ? objv[2] : NULL);

        case m_text:
            CheckArgs(2,2,2,"");
            if (node->nodeType != ELEMENT_NODE) {
                SetResult("NOT_AN_ELEMENT");
                return TCL_ERROR;
................................................................................

        case m_attributes:
            CheckArgs(2,3,2,"?nameFilter?");
            if (node->nodeType != ELEMENT_NODE) {
                SetResult("");
                return TCL_OK;
            }

            if (objc == 3) {
                filter = Tcl_GetString(objv[2]);
            } else {
                filter = "*";
            }
            Tcl_ResetResult(interp);
            resultPtr = Tcl_GetObjResult(interp);

            attrs = node->firstAttr;
            while (attrs != NULL) {
                if (Tcl_StringMatch((char*)attrs->nodeName, filter)) {

                    if (attrs->namespace == 0) {
                        namePtr = Tcl_NewStringObj((char*)attrs->nodeName, -1);
                    } else {
                        domSplitQName((char*)attrs->nodeName, prefix, 
                                      &localName);
                        mobjv[0] = Tcl_NewStringObj((char*)localName, -1);
                        mobjv[1] = Tcl_NewStringObj(
................................................................................
                    }
                    result = Tcl_ListObjAppendElement(interp, resultPtr, 
                                                      namePtr);
                    if (result != TCL_OK) {
                        Tcl_DecrRefCount(namePtr);
                        return result;
                    }



























                }
                attrs = attrs->nextSibling;
            }
            break;

        case m_asList:
            CheckArgs(2,2,2,"");
................................................................................
        case m_asHTML:
            Tcl_ResetResult(interp);
            if (serializeAsHTML(node, interp, objc, objv) != TCL_OK) {
                return TCL_ERROR;
            }
            break;







        case m_getAttribute:
            CheckArgs(3,4,2,"attrName ?defaultValue?");
            if (node->nodeType != ELEMENT_NODE) {
                SetResult("NOT_AN_ELEMENT : there are no attributes");
                return TCL_ERROR;
            }
            attr_name = Tcl_GetString(objv[2]);
................................................................................
            for ( i = 2;  i < objc; ) {
                attr_name = Tcl_GetString(objv[i++]);
                CheckName (interp, attr_name, "attribute", 0);
                attr_val  = Tcl_GetString(objv[i++]);
                CheckText (interp, attr_val, "attribute");
                domSetAttribute(node, attr_name, attr_val);
            }
            return tcldom_returnNodeObj(interp, node, 0, NULL);

        case m_setAttributeNS:
            if (node->nodeType != ELEMENT_NODE) {
                SetResult("NOT_AN_ELEMENT : there are no attributes");
                return TCL_ERROR;
            }
            if ((objc < 5) || (((objc - 2) % 3) != 0)) {
................................................................................
                        SetResult("For all prefixed attributes with prefixes "
                                  "other than 'xml' or 'xmlns' "
                                  "you have to provide a namespace URI");
                    }
                    return TCL_ERROR;
                }
            }
            return tcldom_returnNodeObj(interp, node, 0, NULL);

        case m_hasAttribute:
            CheckArgs(3,3,2,"attrName");
            if (node->nodeType != ELEMENT_NODE) {		
                SetResult("NOT_AN_ELEMENT : there are no attributes");
                return TCL_ERROR;
            }
................................................................................
            result = domRemoveAttribute(node, attr_name);
            if (result) {
                SetResult("can't remove attribute '");
                AppendResult(attr_name);
                AppendResult("'");
                return TCL_ERROR;
            }
            return tcldom_returnNodeObj(interp, node, 0, NULL);

        case m_removeAttributeNS:
            CheckArgs(4,4,2,"uri attrName");
            if (node->nodeType != ELEMENT_NODE) {		
                SetResult("NOT_AN_ELEMENT : there are no attributes");
                return TCL_ERROR;
            }
................................................................................
            result = domRemoveAttributeNS(node, uri, localName);
            if (result < 0) {
                SetResult("can't remove attribute with localName '");
                AppendResult(localName);
                AppendResult("'");
                return TCL_ERROR;
            }
            return tcldom_returnNodeObj(interp, node, 0, NULL);

        case m_nextSibling:
            CheckArgs(2,3,2,"?nodeObjVar?");
            return tcldom_returnNodeObj(interp, node->nextSibling,
                                        (objc == 3), 
                                        (objc == 3) ? objv[2] : NULL);
        case m_previousSibling:
            CheckArgs(2,3,2,"?nodeObjVar?");
            return tcldom_returnNodeObj(interp, node->previousSibling,
                                        (objc == 3),
                                        (objc == 3) ? objv[2] : NULL);
        case m_firstChild:
            CheckArgs(2,3,2,"?nodeObjVar?");
            if (node->nodeType == ELEMENT_NODE) {
                return tcldom_returnNodeObj(interp, node->firstChild,
                                            (objc == 3),
                                            (objc == 3) ? objv[2] : NULL);
            }
            return tcldom_returnNodeObj(interp, NULL, (objc == 3),
                                        (objc == 3) ? objv[2] : NULL);
        case m_lastChild:
            CheckArgs(2,3,2,"?nodeObjVar?");
            if (node->nodeType == ELEMENT_NODE) {
                return tcldom_returnNodeObj(interp, node->lastChild,
                                            (objc == 3),
                                            (objc == 3) ? objv[2] : NULL);
            }
            return tcldom_returnNodeObj(interp, NULL, (objc == 3),
                                        (objc == 3) ? objv[2] : NULL);
        case m_parentNode:
            CheckArgs(2,3,2,"?nodeObjVar?");
            return tcldom_returnNodeObj(interp, node->parentNode, (objc == 3),
                                        (objc == 3) ? objv[2] : NULL);
        case m_appendFromList:
            CheckArgs(3,3,2,"list");
            return tcldom_appendFromTclList(interp, node, objv[2]);

        case m_appendFromScript:
            CheckArgs(3,3,2,"script");
            if (nodecmd_appendFromScript(interp, node, objv[2]) != TCL_OK) {
                return TCL_ERROR;
            }
            return tcldom_returnNodeObj(interp, node, 0, NULL);

        case m_insertBeforeFromScript:
            CheckArgs(4,4,2, "script refChild");



            nodeName = Tcl_GetString (objv[3]);
            if (nodeName[0] == '\0') {
                refChild = NULL;
            } else {
                refChild = tcldom_getNodeFromName (interp, nodeName, &errMsg);
                if (refChild == NULL) {
                    SetResult ( errMsg );
                    return TCL_ERROR;

                }
            }
            if (nodecmd_insertBeforeFromScript(interp, node, objv[2], refChild)
                != TCL_OK) {
                return TCL_ERROR;
            }
            return tcldom_returnNodeObj (interp, node, 0, NULL);
            
        case m_appendXML:
            CheckArgs(3,3,2,"xmlString");
            return tcldom_appendXML(interp, node, objv[2]);

        case m_appendChild:
            CheckArgs(3,3,2,"nodeToAppend");
            nodeName = Tcl_GetString(objv[2]);
            child = tcldom_getNodeFromName(interp, nodeName, &errMsg);
            if (child == NULL) {
                SetResult(errMsg);
                return TCL_ERROR;
            }
            exception = domAppendChild (node, child);
            if (exception != OK) {
                SetResult(domException2String(exception));
                return TCL_ERROR;
            }
            return tcldom_returnNodeObj(interp, child, 0, NULL);

        case m_cloneNode:
            CheckArgs(2,3,2,"?-deep?");
            if (objc == 3) {
                if (!strcmp(Tcl_GetString(objv[2]), "-deep")) {
                    return tcldom_returnNodeObj(interp, domCloneNode(node, 1),
                                                0, NULL);
                }
                SetResult("unknown option! Options: ?-deep? ");
                return TCL_ERROR;
            }
            return tcldom_returnNodeObj(interp, domCloneNode(node, 0), 0, NULL);

        case m_removeChild:
            CheckArgs(3,3,2,"childToRemove");
            nodeName = Tcl_GetString(objv[2]);
            child = tcldom_getNodeFromName(interp, nodeName, &errMsg);
            if (child == NULL) {
                SetResult(errMsg);
                return TCL_ERROR;
            }
            exception = domRemoveChild (node, child);
            if (exception != OK) {
                SetResult (domException2String (exception));
                return TCL_ERROR;
            }
            return tcldom_returnNodeObj(interp, child, 0, NULL);

        case m_insertBefore:
            CheckArgs(4,4,2,"childToInsert refChild");
            nodeName = Tcl_GetString(objv[2]);
            child = tcldom_getNodeFromName(interp, nodeName, &errMsg);
            if (child == NULL) {
                SetResult(errMsg);
                return TCL_ERROR;
            }




            nodeName = Tcl_GetString (objv[3]);
            if (nodeName[0] == '\0') {
                refChild = NULL;
            } else {
                refChild = tcldom_getNodeFromName (interp, nodeName, &errMsg);
                if (refChild == NULL) {
                    SetResult ( errMsg );
                    return TCL_ERROR;

                }
            }
            exception = domInsertBefore(node, child, refChild);
            if (exception != OK) {
                SetResult(domException2String(exception));
                return TCL_ERROR;
            }
            return tcldom_returnNodeObj(interp, child, 0, NULL);

        case m_replaceChild:
            CheckArgs(4,4,2,"new old");
            nodeName = Tcl_GetString(objv[2]);
            child = tcldom_getNodeFromName(interp, nodeName, &errMsg);
            if (child == NULL) {
                SetResult(errMsg);
                return TCL_ERROR;
            }

            nodeName = Tcl_GetString(objv[3]);
            oldChild = tcldom_getNodeFromName(interp, nodeName, &errMsg);
            if (oldChild == NULL) {
                SetResult(errMsg);
                return TCL_ERROR;
            }
            exception = domReplaceChild(node, child, oldChild);
            if (exception != OK) {
                SetResult(domException2String(exception));
                return TCL_ERROR;
            }
            return tcldom_returnNodeObj(interp, oldChild, 0, NULL);

        case m_hasChildNodes:
            CheckArgs(2,2,2,"");
            if (node->nodeType == ELEMENT_NODE) {
                SetIntResult(node->firstChild ? 1 : 0);
            } else {
                SetIntResult(0);
................................................................................

        case m_childNodes:
            CheckArgs(2,2,2,"");
            resultPtr = Tcl_GetObjResult(interp);
            if (node->nodeType == ELEMENT_NODE) {
                child = node->firstChild;
                while (child != NULL) {
                    tcldom_createNodeObj(interp, child, objCmdName);
                    namePtr = Tcl_NewStringObj(objCmdName, -1);
                    result  = Tcl_ListObjAppendElement(interp, resultPtr,
                                                       namePtr);
                    if (result != TCL_OK) {
                        Tcl_DecrRefCount(namePtr);
                        return result;
                    }
                    child = child->nextSibling;
................................................................................
                        }
                        nsIndex = node->ownerDocument->namespaces[i]->index;
                    }
                }
            }
            if (nsIndex == -1) {
                /* There isn't such a namespace declared in this document.
                   Since getElementsByTagNameNS doesn't raise an execption
                   short cut: return empty result */
                Tcl_ResetResult(interp);
                return TCL_OK;
            }
            return tcldom_getElementsByTagName(interp, str, node->firstChild,
                                                nsIndex, uri);
            
................................................................................
        case m_getElementById:
            CheckArgs(3,3,2,"id");
            if (node->ownerDocument->ids) {
                str = Tcl_GetString(objv[2]);
                h = Tcl_FindHashEntry(node->ownerDocument->ids, str);
                if (h) {
                    domNode *node = Tcl_GetHashValue(h);
                    return tcldom_returnNodeObj(interp, node, 0, NULL);
                }
            }
            SetResult("");
            return TCL_OK;

        case m_nodeName:
            CheckArgs(2,2,2,"");
................................................................................
                                 dpn->targetValue, dpn->targetLength);
            }
            break;

        case m_delete:
            CheckArgs(2,2,2,"");
            domDeleteNode(node, tcldom_deleteNode, interp);







            break;

        case m_data:
            CheckArgs(2,2,2,"");
            if (node->nodeType == PROCESSING_INSTRUCTION_NODE) {
                domProcessingInstructionNode *dpn;
                dpn = (domProcessingInstructionNode*)node;
................................................................................
                    node->nodeFlags &= (~DISABLE_OUTPUT_ESCAPING);
                }
            }
            break;

        case m_precedes:
            CheckArgs(3,3,2, "node");
            nodeName = Tcl_GetString(objv[2]);
            refNode = tcldom_getNodeFromName(interp, nodeName, &errMsg);
            if (refNode == NULL) {
                SetResult(errMsg);
                return TCL_ERROR;
            }
            if (node->ownerDocument != refNode->ownerDocument) {
                SetResult("Cannot compare the relative order of nodes "
                          "out of different documents.");
                return TCL_ERROR;
            }
................................................................................
                    SetResult("unknown option! Options: ?-forXPath?");
                    return TCL_ERROR;
                }
            }
            domNormalize (node, bool, tcldom_deleteNode, interp);
            return TCL_OK;








































        TDomThreaded(
        case m_writelock:
            CheckArgs(3,3,2,"script");
            return tcldom_EvalLocked(interp, (Tcl_Obj**)objv, 
                                     node->ownerDocument, LOCK_WRITE);
        case m_readlock:
            CheckArgs(3,3,2,"script");
            return tcldom_EvalLocked(interp, (Tcl_Obj**)objv, 
                                     node->ownerDocument, LOCK_READ);
        )
    }
    return TCL_OK;
}


/*----------------------------------------------------------------------------
|   tcldom_DocObjCmd
|
\---------------------------------------------------------------------------*/
int tcldom_DocObjCmd (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *CONST objv[]
)
{
    GetTcldomTSD()

    domDeleteInfo       * dinfo;
    domDocument         * doc;
    char                * method, *tag, *data, *target, *uri, tmp[100];
................................................................................
    int                   methodIndex, result, data_length, target_length, i;
    int                   nsIndex, forXPath, bool, setDocumentElement = 0;
    int                   restoreDomCreateCmdMode = 0;
    domNode             * n;
    Tcl_CmdInfo           cmdInfo;
    Tcl_Obj             * mobjv[MAX_REWRITE_ARGS];

    static CONST84 char *docMethods[] = {
        "documentElement", "getElementsByTagName",       "delete",
        "createElement",   "createCDATASection",         "createTextNode",
        "createComment",   "createProcessingInstruction",
        "createElementNS", "getDefaultOutputMethod",     "asXML",
        "asHTML",          "getElementsByTagNameNS",     "xslt", 
        "publicId",        "systemId",                   "internalSubset",
        "toXSLTcmd",       "asText",                     "normalize",
................................................................................
        "renameNode",      "deleteXPathCache", 
        /* The following methods will be dispatched to tcldom_NodeObjCmd */
        "getElementById",  "firstChild",                 "lastChild",
        "appendChild",     "removeChild",                "hasChildNodes",
        "childNodes",      "ownerDocument",              "insertBefore",
        "replaceChild",    "appendFromList",             "appendXML",
        "selectNodes",     "baseURI",                    "appendFromScript",
        "insertBeforeFromScript",

#ifdef TCL_THREADS
        "readlock",        "writelock",                  "renumber",
#endif
        NULL
    };
    enum docMethod {
        m_documentElement,  m_getElementsByTagName,       m_delete,
................................................................................
        m_renameNode,       m_deleteXPathCache,
        /* The following methods will be dispatched to tcldom_NodeObjCmd */
        m_getElementById,   m_firstChild,                 m_lastChild,
        m_appendChild,      m_removeChild,                m_hasChildNodes,
        m_childNodes,       m_ownerDocument,              m_insertBefore,
        m_replaceChild,     m_appendFromList,             m_appendXML,
        m_selectNodes,      m_baseURI,                    m_appendFromScript,
        m_insertBeforeFromScript

#ifdef TCL_THREADS
       ,m_readlock,         m_writelock,                  m_renumber
#endif
    };

    dinfo = (domDeleteInfo*)clientData;
    if (TSD(domCreateCmdMode) == DOM_CREATECMDMODE_AUTO) {
................................................................................
        mobjv[1] = objv[0];
        for (i = 2; i < objc; i++) {
            mobjv[i] = objv[i];
        }
        return cmdInfo.objProc(cmdInfo.objClientData, interp, objc, mobjv);
    }

    CheckArgs (2,10,1,dom_usage);
    Tcl_ResetResult (interp);

    /*----------------------------------------------------------------------
    |   dispatch the doc object method
    |
    \---------------------------------------------------------------------*/

    switch ((enum docMethod) methodIndex ) {

        case m_documentElement:
            CheckArgs(2,3,2,"");
            return tcldom_returnNodeObj(interp, doc->documentElement,
                                        (objc == 3), 
                                        (objc == 3) ? objv[2] : NULL);
        case m_getElementsByTagName:
            CheckArgs(3,3,2,"elementName");
            return tcldom_getElementsByTagName(interp, Tcl_GetString(objv[2]),
                                               doc->documentElement, -1, NULL);
        case m_getElementsByTagNameNS:
................................................................................
                        }
                        nsIndex = doc->namespaces[i]->index;
                    }
                }
            }
            if (nsIndex == -1) {
                /* There isn't such a namespace declared in this document.
                   Since getElementsByTagNameNS doesn't raise an execption
                   short cut: return empty result */
                return TCL_OK;
            }
            return tcldom_getElementsByTagName(interp, str,
                                               doc->documentElement, nsIndex,
                                               uri);
        case m_createElement:
            CheckArgs(3,4,2,"elementName ?newObjVar?");
            tag = Tcl_GetString(objv[2]);
            CheckName (interp, tag, "tag", 0);
            n = domNewElementNode(doc, tag, ELEMENT_NODE);
            return tcldom_returnNodeObj(interp, n, (objc == 4),
                                        (objc == 4) ? objv[3] : NULL);

        case m_createElementNS:
            CheckArgs(4,5,2,"elementName uri ?newObjVar?");
            uri = Tcl_GetString(objv[2]);
            tag = Tcl_GetString(objv[3]);
            CheckName (interp, tag, "full qualified tag", 1);
            n = domNewElementNodeNS(doc, tag, uri, ELEMENT_NODE);




            return tcldom_returnNodeObj(interp, n, (objc == 5),
                                        (objc == 5) ? objv[4] : NULL);

        case m_createTextNode:
            CheckArgs(3,4,2,"data ?newObjVar?");
            data = Tcl_GetStringFromObj(objv[2], &data_length);
            CheckText (interp, data, "text");
            n = (domNode*)domNewTextNode(doc, data, data_length, TEXT_NODE);
            return tcldom_returnNodeObj(interp, n, (objc == 4),
                                        (objc == 4) ? objv[3] : NULL);

        case m_createCDATASection:
            CheckArgs(3,4,2,"data ?newObjVar?");
            data = Tcl_GetStringFromObj(objv[2], &data_length);
            CheckCDATA (interp, data);
            n = (domNode*)domNewTextNode(doc, data, data_length, 
                                         CDATA_SECTION_NODE);
            return tcldom_returnNodeObj(interp, n, (objc == 4),
                                        (objc == 4) ? objv[3] : NULL);

        case m_createComment:
            CheckArgs(3,4,2,"data ?newObjVar?");
            data = Tcl_GetStringFromObj(objv[2], &data_length);
            CheckComment(interp, data);
            n = (domNode*)domNewTextNode(doc, data, data_length, COMMENT_NODE);
            return tcldom_returnNodeObj(interp, n, (objc == 4),
                                        (objc == 4) ? objv[3] : NULL);

        case m_createProcessingInstruction:
            CheckArgs(4,5,2,"target data ?newObjVar?");
            target = Tcl_GetStringFromObj(objv[2], &target_length);
            CheckPIName (interp, target);
            data   = Tcl_GetStringFromObj(objv[3], &data_length);
            CheckPIValue (interp, data);
            n = (domNode*)domNewProcessingInstructionNode(doc, target, 
                                                          target_length, data, 
                                                          data_length);
            return tcldom_returnNodeObj(interp, n, (objc == 5),
                                        (objc == 5) ? objv[4] : NULL);

        case m_delete:
            CheckArgs(2,2,2,"");
            if (clientData != NULL) {
                Tcl_DeleteCommand(interp, Tcl_GetString (objv[0]));
            } else {
                tcldom_deleteDoc(interp, doc);
            }
            SetResult("");
            return TCL_OK;

................................................................................
        case m_firstChild:
        case m_lastChild:
        case m_hasChildNodes:
        case m_childNodes:
        case m_ownerDocument:
        case m_selectNodes:
        case m_baseURI:


        case m_getElementById:
            /* We dispatch the method call to tcldom_NodeObjCmd */
            if (TSD(domCreateCmdMode) == DOM_CREATECMDMODE_AUTO) {
                if (dinfo == NULL) {
                    /* tcldom_DocObjCmd was called with a doc token.
                       Since the domCreateCmdMode is 'automatic'
                       and we call tcldom_DocObjCmd with the root node
................................................................................
    Tcl_Obj    * const objv[]
)
{
    int          setVariable = 0;
    domDocument *doc;
    Tcl_Obj     *newObjName = NULL;



    CheckArgs(2,3,1,"docElemName ?newObjVar?");

    if (objc == 3) {
        newObjName = objv[2];
        setVariable = 1;
    }

    doc = domCreateDocument(interp, NULL, Tcl_GetString(objv[1]));
    if (doc == NULL) {
        return TCL_ERROR;
    }

    return tcldom_returnDocumentObj(interp, doc, setVariable, newObjName, 1,
                                    0);
}

/*----------------------------------------------------------------------------
|   tcldom_createDocumentNode
|
................................................................................
int tcldom_createDocumentNode (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    * const objv[]
)
{
    int          setVariable = 0;
    domDocument *doc;
    Tcl_Obj     *newObjName = NULL;



    CheckArgs(1,2,1,"?newObjVar?");


    if (objc == 2) {
        newObjName = objv[1];
        setVariable = 1;
    }
















    doc = domCreateDoc(NULL, 0);


    return tcldom_returnDocumentObj(interp, doc, setVariable, newObjName, 1,
                                    0);
}

/*----------------------------------------------------------------------------
|   tcldom_createDocumentNS
|
................................................................................
int tcldom_createDocumentNS (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    * const objv[]
)
{
    int          setVariable = 0;

    domDocument *doc;
    Tcl_Obj     *newObjName = NULL;



    CheckArgs(3,4,1,"uri docElemName ?newObjVar?");

    if (objc == 4) {
        newObjName = objv[3];
        setVariable = 1;
    }

    doc = domCreateDocument(interp, Tcl_GetString(objv[1]),



                            Tcl_GetString(objv[2]));
    if (doc == NULL) {

        return TCL_ERROR;
    }

    return tcldom_returnDocumentObj(interp, doc, setVariable, newObjName, 1,
                                    0);
}


/*----------------------------------------------------------------------------
|   tcldom_setResultEncoding
|
\---------------------------------------------------------------------------*/
static
int tcldom_setResultEncoding (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    * const objv[]
)
{
    GetTcldomTSD()

    TEncoding *encoding;
    char      *encodingName;

    CheckArgs(1,2,1,"?encodingName?");
    if (objc == 1) {
        if (TSD(Encoding_to_8bit) == NULL) {
            Tcl_AppendResult(interp, "UTF-8", NULL);

        } else {
            Tcl_AppendResult(interp, TSD(Encoding_to_8bit->name), NULL);
        }
        return TCL_OK;
    }
    encodingName = Tcl_GetString(objv[1]);
    if ( (strcmp(encodingName, "UTF-8")==0)
       ||(strcmp(encodingName, "UTF8")==0)
       ||(strcmp(encodingName, "utf-8")==0)
       ||(strcmp(encodingName, "utf8")==0)) {

        TSD(Encoding_to_8bit) = NULL;
    } else {
        encoding = tdom_GetEncoding ( encodingName );
        if (encoding == NULL) {
             Tcl_AppendResult(interp, "encoding not found", NULL);
             return TCL_ERROR;


        }
        TSD(Encoding_to_8bit) = encoding;
    }
    return TCL_OK;
}


/*----------------------------------------------------------------------------
|   tcldom_parse
|
\---------------------------------------------------------------------------*/
static
int tcldom_parse (
................................................................................
    int         objc,
    Tcl_Obj    * const objv[]
)
{
    GetTcldomTSD()

    char        *xml_string, *option, *errStr, *channelId, *baseURI = NULL;

    char        *extResolver = NULL;

    CONST84 char *interpResult;
    int          optionIndex, value, xml_string_len, mode;

    int          ignoreWhiteSpaces   = 1;

    int          takeSimpleParser    = 0;
    int          takeHTMLParser      = 0;

    int          setVariable         = 0;

    int          feedbackAfter       = 0;
    int          useForeignDTD       = 0;
    int          paramEntityParsing  = (int)XML_PARAM_ENTITY_PARSING_ALWAYS;


    domDocument *doc;
    Tcl_Obj     *newObjName = NULL;
    XML_Parser   parser;
    Tcl_Channel  chan = (Tcl_Channel) NULL;


    static CONST84 char *parseOptions[] = {
        "-keepEmpties",           "-simple",        "-html",
        "-feedbackAfter",         "-channel",       "-baseurl",
        "-externalentitycommand", "-useForeignDTD", "-paramentityparsing",
        NULL






    };
    enum parseOption {
        o_keepEmpties,            o_simple,         o_html,
        o_feedbackAfter,          o_channel,        o_baseurl,
        o_externalentitycommand,  o_useForeignDTD,  o_paramentityparsing






    };

    static CONST84 char *paramEntityParsingValues[] = {
        "always",
        "never",
        "notstandalone",
        (char *) NULL
    };
    enum paramEntityParsingValue {
        EXPAT_PARAMENTITYPARSINGALWAYS,
        EXPAT_PARAMENTITYPARSINGNEVER,
        EXPAT_PARAMENTITYPARSINGNOTSTANDALONE
    };
    
    while (objc > 1) {
        option = Tcl_GetString(objv[1]);
        if (option[0] != '-') {
            break;
        }
        if (Tcl_GetIndexFromObj(interp, objv[1], parseOptions, "option", 0,
                                 &optionIndex) != TCL_OK) {
................................................................................

        switch ((enum parseOption) optionIndex) {

        case o_keepEmpties:
            ignoreWhiteSpaces = 0;
            objv++;  objc--; continue;


























        case o_simple:
            takeSimpleParser = 1;
            objv++;  objc--; continue;

        case o_html:





            takeSimpleParser = 1;
            takeHTMLParser = 1;
            objv++;  objc--; continue;











            
        case o_feedbackAfter:
            objv++; objc--;
            if (objc > 1) {
                if (Tcl_GetIntFromObj(interp, objv[1], &feedbackAfter)
                    != TCL_OK) {
                    SetResult("-feedbackAfter must have an integer argument");
                    return TCL_ERROR;
                }
            } else {
                SetResult("The \"dom parse\" option \"-feedbackAfter\" requires"
                          " an integer as argument.");
                return TCL_ERROR;
            }





            objv++; objc--;
            continue;

        case o_channel:
            objv++; objc--;
            if (objc > 1) {
                channelId = Tcl_GetString(objv[1]);
            } else {
                SetResult("The \"dom parse\" option \"-channel\" "
                          "requires a tcl channel as argument.");
                return TCL_ERROR;
            }
            chan = Tcl_GetChannel(interp, channelId, &mode);
            if (chan == (Tcl_Channel) NULL) {
                return TCL_ERROR;
            }
            if ((mode & TCL_READABLE) == 0) {
................................................................................
            }
            objv++; objc--;
            continue;

        case o_externalentitycommand:
            objv++; objc--;
            if (objc > 1) {
                extResolver = tdomstrdup (Tcl_GetString (objv[1]));
            } else {
                SetResult("The \"dom parse\" option \"-externalentitycommand\" "
                          "requires a script as argument.");
                return TCL_ERROR;
            }
            objv++; objc--;
            continue;
................................................................................
                SetResult("-paramEntityParsing requires 'always', 'never' "
                          "or 'notstandalone' as argument");
                return TCL_ERROR;
            }
            objv++; objc--;
            objv++; objc--;
            continue;
        }








    }


    









































    if (chan == NULL) {
        if (objc < 2) {
            SetResult(dom_usage);
            return TCL_ERROR;
        }
        xml_string = Tcl_GetStringFromObj( objv[1], &xml_string_len);
        if (objc == 3) {
................................................................................
    } else {
        if (objc > 2) {
            SetResult(dom_usage);
            return TCL_ERROR;
        }
        xml_string = NULL;
        xml_string_len = 0;
        if (takeSimpleParser || takeHTMLParser) {




            Tcl_AppendResult(interp, "simple and/or HTML parser(s) "
                             " don't support channel reading", NULL);
            return TCL_ERROR;
        }
        if (objc == 2) {
            newObjName = objv[1];
            setVariable = 1;
        }
    }














































    if (takeSimpleParser) {
        char s[50];
        int  byteIndex, i;

        errStr = NULL;

        if (takeHTMLParser) {
            doc = HTML_SimpleParseDocument(xml_string, ignoreWhiteSpaces,
                                           &byteIndex, &errStr);
        } else {
            doc = XML_SimpleParseDocument(xml_string, ignoreWhiteSpaces,

                                          baseURI, extResolver,
                                          &byteIndex, &errStr);
        }
        if (errStr != NULL) {
            domFreeDocument (doc, NULL, interp);

            Tcl_ResetResult(interp);
................................................................................
#else
    parser = XML_ParserCreate_MM(NULL, MEM_SUITE, NULL);
    Tcl_ResetResult(interp);

    doc = domReadDocument(parser, xml_string,
                          xml_string_len,
                          ignoreWhiteSpaces,
                          TSD(Encoding_to_8bit),
                          TSD(storeLineColumn),

                          feedbackAfter,

                          chan,
                          baseURI,
                          extResolver,
                          useForeignDTD,
                          paramEntityParsing,
                          interp);

    if (doc == NULL) {
        char s[50];
        long byteIndex, i;








        interpResult = Tcl_GetStringResult(interp);

        if (interpResult[0] == '\0') {
            /* If the interp result isn't empty, then there was an error
               in an enternal entity and the interp result has already the
               error msg. If we don't got a document, but interp result is
               empty, the error occured in the main document and we
               build the error msg as follows. */
            sprintf(s, "%ld", XML_GetCurrentLineNumber(parser));
            Tcl_AppendResult(interp, "error \"", 
                             XML_ErrorString(XML_GetErrorCode(parser)),
                             "\" at line ", s, " character ", NULL);
            sprintf(s, "%ld", XML_GetCurrentColumnNumber(parser));
            Tcl_AppendResult(interp, s, NULL);
            byteIndex = XML_GetCurrentByteIndex(parser);
            if ((byteIndex != -1) && (chan == NULL)) {
                Tcl_AppendResult(interp, "\n\"", NULL);
                s[1] = '\0';
                for (i=-20; i < 40; i++) {
                    if ((byteIndex+i)>=0) {
                        if (xml_string[byteIndex+i]) {
                            s[0] = xml_string[byteIndex+i];
                            Tcl_AppendResult(interp, s, NULL);
                            if (i==0) {
                                Tcl_AppendResult(interp, " <--Error-- ", NULL);
                            }
                        } else {
                            break;
                        }
                    }
                }
                Tcl_AppendResult(interp, "\"",NULL);
            }













        }

        XML_ParserFree(parser);
        return TCL_ERROR;
    }

    XML_ParserFree(parser);

    return tcldom_returnDocumentObj (interp, doc, setVariable, newObjName, 1,
                                     0);
#endif

}






















































































































/*----------------------------------------------------------------------------
|   tcldom_DomObjCmd
|
\---------------------------------------------------------------------------*/
int tcldom_DomObjCmd (
    ClientData   clientData,
    Tcl_Interp * interp,
    int          objc,
    Tcl_Obj    * CONST objv[]
)
{
    GetTcldomTSD()

    char        * method, tmp[300];
    int           methodIndex, result, i, bool;
    Tcl_CmdInfo   cmdInfo;
    Tcl_Obj     * mobjv[MAX_REWRITE_ARGS];

    static CONST84 char *domMethods[] = {
        "createDocument",  "createDocumentNS",   "createNodeCmd",
        "parse",           "setResultEncoding",  "setStoreLineColumn",
        "isCharData",      "isName",             "isPIName",
        "isQName",         "isComment",          "isCDATA",
        "isPIValue",       "isNCName",           "createDocumentNode",
        "setNameCheck",    "setTextCheck",       "setObjectCommands",

#ifdef TCL_THREADS
        "attachDocument",  "detachDocument",
#endif
        NULL
    };
    enum domMethod {
        m_createDocument,    m_createDocumentNS,   m_createNodeCmd,
        m_parse,             m_setResultEncoding,  m_setStoreLineColumn,
        m_isCharData,        m_isName,             m_isPIName,
        m_isQName,           m_isComment,          m_isCDATA,
        m_isPIValue,         m_isNCName,           m_createDocumentNode,
        m_setNameCheck,      m_setTextCheck,       m_setObjectCommands

#ifdef TCL_THREADS
        ,m_attachDocument,   m_detachDocument
#endif
    };

    static CONST84 char *nodeModeValues[] = {
        "automatic", "command", "token", NULL
    };
    enum nodeModeValue {
        v_automatic, v_command, v_token
    };

    if (objc < 2) {
................................................................................
    method = Tcl_GetString(objv[1]);
    if (Tcl_GetIndexFromObj(NULL, objv[1], domMethods, "method", 0,
                            &methodIndex) != TCL_OK) {
        /*--------------------------------------------------------
        |   try to find method implemented as normal Tcl proc
        \-------------------------------------------------------*/
        if ((strlen(method)-1) >= 270) {
            SetResult("method name to long!");
            return TCL_ERROR;
        }
        sprintf(tmp, "::dom::DOMImplementation::%s", method);
        DBG(fprintf(stderr, "testing %s\n", tmp));
        result = Tcl_GetCommandInfo(interp, tmp, &cmdInfo);
        if (!result) {
            SetResult(dom_usage);
................................................................................
                }
                SetResult("");
                return TCL_OK;
            }
            break;
#endif

        case m_setResultEncoding:
            return tcldom_setResultEncoding(clientData, interp, --objc, objv+1);

        case m_setStoreLineColumn:
            if (objc == 3) {
                if (Tcl_GetBooleanFromObj(interp, objv[2], &bool) != TCL_OK) {
                    return TCL_ERROR;
                }
                TSD(storeLineColumn) = bool;
            }
................................................................................
            return TCL_OK;
            
        case m_isNCName:
            CheckArgs(3,3,2,"string");
            SetBooleanResult(domIsNCNAME(Tcl_GetString(objv[2])));
            return TCL_OK;










    }
    SetResult( dom_usage);
    return TCL_ERROR;
}

#ifdef TCL_THREADS

................................................................................
int tcldom_EvalLocked (
    Tcl_Interp  * interp, 
    Tcl_Obj    ** objv, 
    domDocument * doc,
    int          flag
)
{
    int ret = TCL_OK;
    domlock *dl = doc->lock;

    domLocksLock(dl, flag);

    Tcl_AllowExceptions(interp);
    ret = Tcl_EvalObj(interp, objv[2]);
    if (ret == TCL_ERROR) {
        char msg[64 + TCL_INTEGER_SPACE];
        sprintf(msg, "\n    (\"%s %s\" body line %d)", Tcl_GetString(objv[0]),
                Tcl_GetString(objv[1]), interp->errorLine);
        Tcl_AddErrorInfo(interp, msg);
    }

    domLocksUnlock(dl);

    return (ret == TCL_BREAK) ? TCL_OK : ret;
}
................................................................................

static
int tcldom_RegisterDocShared (
    domDocument * doc
)
{
    Tcl_HashEntry *entryPtr;


    int refCount, newEntry;


    Tcl_MutexLock(&tableMutex);

    refCount = ++doc->refCount;



    entryPtr = Tcl_CreateHashEntry(&sharedDocs, (char*)doc, &newEntry);
    if (newEntry) {
        Tcl_SetHashValue(entryPtr, (ClientData)doc);
    }
    Tcl_MutexUnlock(&tableMutex);

    DBG(fprintf(stderr, "--> tcldom_RegisterDocShared: doc %p %s "
................................................................................
    Tcl_MutexLock(&tableMutex);
    if (doc->refCount > 1) {
        tcldom_deleteNode(doc->rootNode, interp);
        domFreeNode(doc->rootNode, tcldom_deleteNode, interp, 1);
        doc->refCount--;
        deleted = 0;
    } else {

        Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&sharedDocs, (char*)doc);
        if (entryPtr) {
            Tcl_DeleteHashEntry(entryPtr);
            deleted = 1;



        } else {
            deleted = 0;
        }
    }
    Tcl_MutexUnlock(&tableMutex);

    DBG(fprintf(stderr, "--> tcldom_UnregisterDocShared: doc %p %s "
................................................................................
)
{
    Tcl_HashEntry *entryPtr;
    domDocument *tabDoc = NULL;
    int found = 0;

    Tcl_MutexLock(&tableMutex);

    entryPtr = Tcl_FindHashEntry(&sharedDocs, (char*)doc);
    if (entryPtr == NULL) {
        found = 0;
    } else {
        tabDoc = (domDocument*)Tcl_GetHashValue(entryPtr);
        found  = tabDoc ? 1 : 0;

    }
    Tcl_MutexUnlock(&tableMutex);

    if (found && doc != tabDoc) {
        Tcl_Panic("document mismatch; doc=%p, in table=%p\n", doc, tabDoc);

    }

    return found;
}

#endif /* TCL_THREADS */

................................................................................
|   tcldom_unknownCmd
|
\---------------------------------------------------------------------------*/
int tcldom_unknownCmd (
    ClientData   clientData,
    Tcl_Interp * interp,
    int          objc,
    Tcl_Obj    * CONST objv[]
)
{
    int          len, i, rc, openedParen, count, args;
    char        *cmd, *dot, *paren, *arg[MAX_REWRITE_ARGS], *object, *method;
    Tcl_DString  callString;
    Tcl_CmdInfo  cmdInfo;
    Tcl_Obj     *vector[2+MAX_REWRITE_ARGS];







<
<
<




>

>


>







 







>
>




>
>
>
|







 







<
<
<
<
<



<





>
>
>
>
>
>
>
>
>





<









<







 







>



|
>
>
>







|
<












>







 







>







 







>







 







>





|




>





>
>
>
>
>
>
>
>
>
>
>
>











>
>
>
>
>
>
>
>
>
>
>
>




>
>
>
>
>
>
|
>
|
>
>
>
>
|
<

<
>
>
>
>
>
>







 







>


>









|


>







 







|


<
<
<
<
<
<
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
<
<
>
|
|
|









|
|









>
|
>
>
>
>
>
>



>
>






>
>





<

<
>


|
<
|
|
<
>
|
|
|
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
|
>
|

<
>
>
|
<
>
>
>
>
>
|
|
<
<

<
<
<
<
<
<
<
>
>
>
>
>
|
|
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>







 







|



|






|
|
<
|




|
|
|
>
|
>



>
>
>
>
>
>
>
|
<
<
<
<
|
<
|
<
<
<
<
|
|
|
<
<
>
>
|
<
<
<
>
>
>
|
|
|
|
|
|
|
>
>
>
|
>
|
>
>
>

>
>
|
<
>
>
>
>
|







 







>













>







 







|







 







|
<







 







<



|
<







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













>





|







 







>
|




|







 







|
>

>
>







 







|
>
>
>
>






<
>

>

>





|
>
>
>
>







 







|







 







<







 







|
<







 







|
|
>








>
>
>
>
>
>
>







 







>
|
>
>
>
|
>
>
>
>
>
>
>







 







>







 







<
|

|







 







|







 







|







 







|








>
|

|







|








|

>
>
>
|
>







 







|
|







|







 







|




|
>

|



|







 







|
>


>
>
>
>
>



>


<
|
<
<
<
<



>
>
>







 







<
<
<

|
>







 







<
<
<

>







 







<
<
<
|
>


>







 







>



>
|
>
>
>
>
>


|







 







|



|







 







|







 







<










|
<
<
<







<

>

<
|









|
>






>
|

>
|



|

<
<
<


<







 







<







 







<


<




<

<
<
<
<
<
<
<
<
<
<
<
<
<
<





|
|
<
>
>
>
>
>
>
>
>
>
|
>

|







 







<







 







|





>
>







 







|
|











|
|

>







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|









|
|







 







|
<

|
>











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
|







 







|
<







 







|
|







 







>
>
>
>
>
>
>
>
>
>
>
|
>



|
|







 







|
<













>
>
>
>
>
|
>

>
>
>
>
>
|
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|




|
>
|
|



>

|

<
>
>




|
>


<
<
<
<
<
<
<




|







|









|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|





|



|
|






|








|




|

|

|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|

|
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|

>
>
>

>
>
>
>
>










|








|







 









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|







 







|







 







|



<







 







|
<

<
<







 







|







 







|






>
|




|
|



|
|

|
|
>



|
>







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
>
|
|
|




>
>
>










|







 







|





|







 







|








|
|
<


|





|







 







>







 







|
>

|


<













<
|

<


>







 







|
>
>
>
>
>
>
>
>
>
|







 







|







 







|







 







>


<
<






|
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>







 







|







 







|







 







|







 







|



|




|





|



|




|



|



|










|



>
>
>
|
|
|
|
|
|
<
|
>






|







<
|

<







|





|





|



<
|

<







|



<
|

<



>
>
>
|
|
|
|
|
|
<
|
>







|



<
|

<


<
<
|

<







|







 







|
<







 







|







 







|







 







>
>
>
>
>
>
>







 







<
|

<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











|
|










|







 







|







 







|
>







 







|
>







 







|











|







 







|










|
|







|
>
>
>
>
|







|








|







|











|




|







 







>
>







 







>








|
|
<
<
<







 







|



>
|
<
>





>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>

>
|







 







|
>



>








|
>
>
>
|
<
>
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
>
>
|
<
<
<
<
<







 







>
|
>
|

>

>


>

>



>
>




>

|



<
>
>
>
>
>
>




|
>
>
>
>
>
>


|










|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>



>
>
>
>
>
>
>
>
>
>
>











|


>
>
>
>
>









|







 







|







 







|
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
>
>
>
>
|









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











>







 







|

>

>





|
>



|
>
>
>
>
>
>
>
|
>
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
|
|
>








>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








|









|

|




>







|



|
>





|







 







|







 







<
<
<







 







>
>
>
>
>
>
>
>
>







 







|





|



|







 







>
>
|
>


>

>
>
>







 







>
|
|
|
|
>
>
>







 







>
|
|
|
|
|
|
>




|
>







 







|







38
39
40
41
42
43
44



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
...
144
145
146
147
148
149
150





151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
...
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
...
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
...
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

416

417
418
419
420
421
422
423
424
425
426
427
428
429
...
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
...
518
519
520
521
522
523
524
525
526
527









528
529

















530
531










532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581

582

583
584
585
586

587
588

589
590
591
592
593
594
595
596
597
598
599

600
601
602
603
604
605
606
607
608
609
610
611
612
613

614
615
616

617
618
619
620
621
622
623


624







625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
...
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689

690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711




712

713




714
715
716


717
718
719



720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742

743
744
745
746
747
748
749
750
751
752
753
754
...
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
...
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
...
866
867
868
869
870
871
872
873

874
875
876
877
878
879
880
...
942
943
944
945
946
947
948

949
950
951
952

953
954
955
956
957
958
959
...
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
....
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
....
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
....
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
....
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232

1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
....
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
....
1303
1304
1305
1306
1307
1308
1309

1310
1311
1312
1313
1314
1315
1316
....
1361
1362
1363
1364
1365
1366
1367
1368

1369
1370
1371
1372
1373
1374
1375
....
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
....
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
....
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
....
1524
1525
1526
1527
1528
1529
1530

1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
....
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
....
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
....
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
....
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
....
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
....
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724

1725




1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
....
1746
1747
1748
1749
1750
1751
1752



1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
....
1765
1766
1767
1768
1769
1770
1771



1772
1773
1774
1775
1776
1777
1778
1779
1780
....
1787
1788
1789
1790
1791
1792
1793



1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
....
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
....
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
....
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
....
2188
2189
2190
2191
2192
2193
2194

2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205



2206
2207
2208
2209
2210
2211
2212

2213
2214
2215

2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243



2244
2245

2246
2247
2248
2249
2250
2251
2252
....
2336
2337
2338
2339
2340
2341
2342

2343
2344
2345
2346
2347
2348
2349
....
2490
2491
2492
2493
2494
2495
2496

2497
2498

2499
2500
2501
2502

2503














2504
2505
2506
2507
2508
2509
2510

2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
....
2533
2534
2535
2536
2537
2538
2539

2540
2541
2542
2543
2544
2545
2546
....
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
....
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
....
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
....
2765
2766
2767
2768
2769
2770
2771
2772

2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
....
2831
2832
2833
2834
2835
2836
2837
2838

2839
2840
2841
2842
2843
2844
2845
....
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
....
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
....
2982
2983
2984
2985
2986
2987
2988
2989

2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
....
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
....
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460

3461
3462
3463
3464
3465
3466
3467
3468
3469
3470







3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
....
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
....
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
....
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
....
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004

4005
4006
4007
4008
4009
4010
4011
....
4012
4013
4014
4015
4016
4017
4018
4019

4020


4021
4022
4023
4024
4025
4026
4027
....
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
....
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
....
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
....
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
....
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
....
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
....
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366

4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
....
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
....
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419

4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432

4433
4434

4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
....
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
....
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
....
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
....
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630


4631
4632
4633
4634
4635
4636
4637

4638
4639
4640
4641
4642
4643
4644
....
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
....
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
....
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
....
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
....
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
....
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934

4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950

4951
4952

4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975

4976
4977

4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988

4989
4990

4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002

5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015

5016
5017

5018
5019


5020
5021

5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
....
5039
5040
5041
5042
5043
5044
5045
5046

5047
5048
5049
5050
5051
5052
5053
....
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
....
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
....
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
....
5347
5348
5349
5350
5351
5352
5353

5354
5355

5356
5357
5358
5359
5360
5361
5362
....
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
....
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
....
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
....
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
....
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
....
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
....
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
....
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032



6033
6034
6035
6036
6037
6038
6039
....
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054

6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
....
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114

6115
6116
6117
6118


























6119
6120




6121




6122






6123
6124
6125





6126
6127
6128
6129
6130
6131
6132
....
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169

6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
....
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
....
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
....
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
....
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
....
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595

6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
....
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
....
6911
6912
6913
6914
6915
6916
6917



6918
6919
6920
6921
6922
6923
6924
....
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
....
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
....
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
....
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
....
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
....
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199


/*----------------------------------------------------------------------------
|   Includes
|
\---------------------------------------------------------------------------*/
#include <tcl.h>



#include <dom.h>
#include <domxpath.h>
#include <domxslt.h>
#include <xmlsimple.h>
#include <domjson.h>
#include <domhtml.h>
#include <domhtml5.h>
#include <nodecmd.h>
#include <tcldom.h>
#include <versionhash.h>

/* #define DEBUG */
/*----------------------------------------------------------------------------
|   Debug Macros
|
\---------------------------------------------------------------------------*/
#ifdef DEBUG
................................................................................
#define XP_CHILD         0
#define XP_DESCENDANT    1
#define XP_ANCESTOR      2
#define XP_FSIBLING      3
#define XP_PSIBLING      4

#define MAX_REWRITE_ARGS 50

#define MAX_XSLT_APPLY_DEPTH 3000

#define SetResult(str) Tcl_ResetResult(interp); \
                     Tcl_SetStringObj(Tcl_GetObjResult(interp), (str), -1)

#define SetResult3(str1,str2,str3) Tcl_ResetResult(interp);     \
                     Tcl_AppendResult(interp, (str1), (str2), (str3), NULL)

#define SetIntResult(i) Tcl_ResetResult(interp);                        \
                     Tcl_SetIntObj(Tcl_GetObjResult(interp), (i))
                     
#define SetDoubleResult(d) Tcl_ResetResult(interp); \
                     Tcl_SetDoubleObj(Tcl_GetObjResult(interp), (d))

#define SetBooleanResult(i) Tcl_ResetResult(interp); \
                     Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (i))
................................................................................
#define CheckPIValue(interp, text) \
                     if (!TSD(dontCheckCharData)) { \
                         if (!tcldom_PIValueCheck(interp, text)) {\
                             return TCL_ERROR; \
                         } \
                     }






#define writeChars(var,chan,buf,len)  (chan) ? \
                     ((void)Tcl_WriteChars ((chan), (buf), (len) )) : \
                     (Tcl_AppendToObj ((var), (buf), (len) ));


#define DOM_CREATECMDMODE_AUTO 0
#define DOM_CREATECMDMODE_CMDS 1
#define DOM_CREATECMDMODE_TOKENS 2

#define SERIALIZE_XML_DECLARATION 1
#define SERIALIZE_DOCTYPE_DECLARATION 2
#define SERIALIZE_FOR_ATTR 4 
#define SERIALIZE_ESCAPE_NON_ASCII 8
#define SERIALIZE_HTML_ENTITIES 16
#define SERIALIZE_ESCAPE_ALL_QUOT 32
#define SERIALIZE_NO_GT_ESCAPE 64
#define SERIALIZE_NO_EMPTY_ELEMENT_TAG 128

/*----------------------------------------------------------------------------
|   Module Globals
|
\---------------------------------------------------------------------------*/
#ifndef TCL_THREADS

    static int        storeLineColumn       = 0;
    static int        dontCreateObjCommands = 0;
    static int        dontCheckCharData     = 0;
    static int        dontCheckName         = 0;
    static int        domCreateCmdMode      = 0;
#   define TSD(x)     x
#   define GetTcldomTSD()
#else
    typedef struct ThreadSpecificData {

        int        storeLineColumn;
        int        dontCreateObjCommands;
        int        dontCheckCharData;
        int        dontCheckName;
        int        domCreateCmdMode;
    } ThreadSpecificData;
    static Tcl_ThreadDataKey dataKey;
................................................................................
                                    sizeof(ThreadSpecificData));
#endif /* TCL_THREADS */

static char dom_usage[] =
    "Usage dom <subCommand> <args>, where subCommand can be:    \n"
    "    parse ?-keepEmpties? ?-channel <channel> ?-baseurl <baseurl>?  \n"
    "        ?-feedbackAfter <#Bytes>?                    \n"
    "        ?-feedbackcmd <cmd>?                         \n"
    "        ?-externalentitycommand <cmd>?               \n"
    "        ?-useForeignDTD <boolean>?                   \n"
    "        ?-paramentityparsing <none|always|standalone>\n"
    "        ?-simple? ?-html? ?-html5? ?-json?           \n"
    "        ?-jsonmaxnesting <#nr>?                      \n"
    "        ?-jsonroot name?                             \n"
    "        ?<xml|html|json>? ?<objVar>?                 \n"
    "    createDocument docElemName ?objVar?              \n"
    "    createDocumentNS uri docElemName ?objVar?        \n"
    "    createDocumentNode ?objVar?                      \n"
    TDomThreaded(
    "    attachDocument domDoc ?objVar?                   \n"
    "    detachDocument domDoc                            \n"
    )
    "    createNodeCmd ?-returnNodeCmd? ?-tagName name? ?-jsonType jsonType? ?-namespace URI? (element|comment|text|cdata|pi)Node cmdName \n"

    "    setStoreLineColumn ?boolean?                     \n"
    "    setNameCheck ?boolean?                           \n"
    "    setTextCheck ?boolean?                           \n"
    "    setObjectCommands ?(automatic|token|command)?    \n"
    "    isCharData string                                \n"
    "    isComment string                                 \n"
    "    isCDATA string                                   \n"
    "    isPIValue string                                 \n"
    "    isName string                                    \n"
    "    isQName string                                   \n"
    "    isNCName string                                  \n"
    "    isPIName string                                  \n"
    "    featureinfo feature                              \n"
;

static char doc_usage[] =
    "Usage domDoc <method> <args>, where method can be:\n"
    "    documentElement ?objVar?                \n"
    "    getElementsByTagName name               \n"
    "    getElementsByTagNameNS uri localname    \n"
................................................................................
    "    createCDATASection data ?objVar?        \n"
    "    createTextNode text ?objVar?            \n"
    "    createComment text ?objVar?             \n"
    "    createProcessingInstruction target data ?objVar? \n"
    "    asXML ?-indent <none,0..8>? ?-channel <channel>? ?-escapeNonASCII? ?-escapeAllQuot? ?-doctypeDeclaration <boolean>?\n"
    "    asHTML ?-channel <channelId>? ?-escapeNonASCII? ?-htmlEntities?\n"
    "    asText                                  \n"
    "    asJSON ?-indent <none,0..8>?            \n"
    "    getDefaultOutputMethod                  \n"
    "    publicId ?publicId?                     \n"
    "    systemId ?systemId?                     \n"
    "    internalSubset ?internalSubset?         \n"
    "    indent ?boolean?                        \n"
    "    omit-xml-declaration ?boolean?          \n"
    "    encoding ?value?                        \n"
................................................................................
    "    setAttribute attrName value ?attrName value ...? \n"
    "    removeAttribute attrName     \n"
    "    hasAttributeNS uri localName \n"
    "    getAttributeNS uri localName ?defaultValue? \n"
    "    setAttributeNS uri attrName value ?attrName value ...? \n"
    "    removeAttributeNS uri attrName \n"
    "    attributes ?attrNamePattern?   \n"
    "    attributeNames ?attrNamePattern?   \n"
    "    appendChild new              \n"
    "    insertBefore new ref         \n"
    "    replaceChild new old         \n"
    "    removeChild child            \n"
    "    cloneNode ?-deep?            \n"
    "    ownerDocument                \n"
    "    getElementsByTagName name    \n"
................................................................................
    "    getLine                      \n"
    "    getColumn                    \n"
    "    @<attrName> ?defaultValue?   \n"
    "    asList                       \n"
    "    asXML ?-indent <none,0..8>? ?-channel <channel>? ?-escapeNonASCII? ?-escapeAllQuot? ?-doctypeDeclaration <boolean>?\n"
    "    asHTML ?-channel <channelId>? ?-escapeNonASCII? ?-htmlEntities?\n"
    "    asText                       \n"
    "    asJSON ?-indent <none,0..8>? \n"
    "    appendFromList nestedList    \n"
    "    appendFromScript script      \n"
    "    insertBeforeFromScript script ref \n"
    "    appendXML xmlString          \n"
    "    selectNodes ?-namespaces prefixUriList? ?-cache <boolean>? xpathQuery ?typeVar? \n"
    "    toXPath ?-legacy?            \n"
    "    disableOutputEscaping ?boolean? \n"
    "    precedes node                \n"
    "    normalize ?-forXPath?        \n"
    "    xslt ?-parameters parameterList? <xsltDocNode>\n"
    "    jsonType ?jsonType?          \n"
    TDomThreaded(
    "    readlock                     \n"
    "    writelock                    \n"
    )
;

static const char *jsonTypes[] = {
    "NONE",
    "ARRAY",
    "OBJECT",
    "NULL",
    "TRUE",
    "FALSE",
    "STRING",
    "NUMBER",
    NULL
};

/*----------------------------------------------------------------------------
|   Types
|
\---------------------------------------------------------------------------*/

typedef struct XsltMsgCBInfo {
    Tcl_Interp * interp;
    Tcl_Obj    * msgcmd;
} XsltMsgCBInfo;


static void UpdateStringOfTdomNode(Tcl_Obj *objPtr);
static int  SetTdomNodeFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);

const Tcl_ObjType tdomNodeType = {
    "tdom-node",
    NULL,
    NULL,
    UpdateStringOfTdomNode,
    SetTdomNodeFromAny
};

/*----------------------------------------------------------------------------
|   Prototypes for procedures defined later in this file:
|
\---------------------------------------------------------------------------*/
#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION <= 3)
/*
 * Before Tcl 8.4, Tcl_VarTraceProc and Tcl_CmdDeleteProc were not
 * CONST84'ified. When compiling with -DTCL_NO_DEPRECATED, CONST84 is
 * gone, therefore we can't use the function type definitions of
 * Tcl_VarTraceProc and Tcl_CmdDeleteProc for these old version.
 * 
 */
static char * tcldom_docTrace(
    ClientData clientData, Tcl_Interp *interp,
    const char *part1, const char *part2, int flags);
static void tcldom_docCmdDeleteProc(ClientData clientData);
#else 
static Tcl_VarTraceProc  tcldom_docTrace;

static Tcl_CmdDeleteProc tcldom_docCmdDeleteProc;

#endif

static void tcldom_treeAsJSON(Tcl_Obj *jstring, domNode *node,
                              Tcl_Channel channel, int indent,
                              int level,
                              int inside);

#ifdef TCL_THREADS

static int tcldom_EvalLocked(Tcl_Interp* interp, Tcl_Obj** objv,
                             domDocument* doc, int flag);

static int tcldom_RegisterDocShared(domDocument* doc);
................................................................................
\---------------------------------------------------------------------------*/

static void 
tcldom_Finalize(
    ClientData unused
)
{
    DBG(fprintf(stderr, "--> tcldom_Finalize\n"));
    Tcl_MutexLock(&tableMutex);
    Tcl_DeleteHashTable(&sharedDocs);
    tcldomInitialized = 0;
    Tcl_MutexUnlock(&tableMutex);
}

/*----------------------------------------------------------------------------
|   tcldom_initialize
|   Activated at module load to initialize shared document table.
|   This is exported since we need it in tdominit.c.
\---------------------------------------------------------------------------*/

void tcldom_initialize(void)
{
    if (!tcldomInitialized) {
        DBG(fprintf(stderr, "--> tcldom_initialize\n"));
        Tcl_MutexLock(&tableMutex);
        Tcl_InitHashTable(&sharedDocs, TCL_ONE_WORD_KEYS);
        Tcl_CreateExitHandler(tcldom_Finalize, NULL);
        tcldomInitialized = 1;
        Tcl_MutexUnlock(&tableMutex);
    }
}
................................................................................
static
void tcldom_docCmdDeleteProc(
    ClientData clientData
)
{
    domDeleteInfo *dinfo = (domDeleteInfo *)clientData;
    domDocument   *doc   = dinfo->document;
    int            hasTrace  = dinfo->document->nodeFlags & VAR_TRACE;
    
    DBG(fprintf(stderr, "--> tcldom_docCmdDeleteProc doc %p\n", doc));









    tcldom_deleteDoc(dinfo->interp, doc);


















    if (hasTrace) {
        dinfo->document = NULL;










    } else {
        FREE((void*)dinfo);
    }
}

/*----------------------------------------------------------------------------
|   tcldom_docTrace
|
\---------------------------------------------------------------------------*/
static
char * tcldom_docTrace (
    ClientData    clientData,
    Tcl_Interp   *interp,
    const char *name1,
    const char *name2,
    int           flags
)
{
    domDeleteInfo *dinfo = (domDeleteInfo*) clientData;
    domDocument   *doc   = dinfo->document;
    char           objCmdName[80];

    DBG(fprintf(stderr, "--> tcldom_docTrace %x %p\n", flags, doc));

    if (doc == NULL) {
        if (!(flags & TCL_INTERP_DESTROYED)) {
            Tcl_UntraceVar(dinfo->interp, dinfo->traceVarName,
                           TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                           tcldom_docTrace, clientData);
        }
        FREE (dinfo->traceVarName);
        FREE (dinfo);
        return NULL;
    }
    if (flags & TCL_TRACE_WRITES) {
        DOC_CMD(objCmdName, doc);
        Tcl_SetVar2 (interp, name1, name2, objCmdName, TCL_LEAVE_ERR_MSG);
        return "var is read-only";
    }
    if (flags & TCL_TRACE_UNSETS) {
        DOC_CMD(objCmdName, doc);
        DBG(fprintf(stderr, "--> tcldom_docTrace delete doc %p\n", doc));
        Tcl_DeleteCommand(interp, objCmdName);
        FREE (dinfo->traceVarName);
        FREE (dinfo);
    }

    return NULL;
}


/*----------------------------------------------------------------------------

|   UpdateStringOfTdomNode
|
\---------------------------------------------------------------------------*/
static void

UpdateStringOfTdomNode(
    Tcl_Obj *objPtr)

{
    char nodeName[80];
    int  len;
    
    NODE_CMD(nodeName, objPtr->internalRep.otherValuePtr);
    len = strlen(nodeName);
    objPtr->bytes = (ckalloc((unsigned char) len+1));
    memcpy(objPtr->bytes, nodeName, len+1);
    objPtr->length = len;
}


/*----------------------------------------------------------------------------
|   SetTdomNodeFromAny
|
\---------------------------------------------------------------------------*/
static int
SetTdomNodeFromAny(
    Tcl_Interp *interp,		/* Tcl interpreter or NULL */
    Tcl_Obj *objPtr)		/* Pointer to the object to parse */
{
    Tcl_CmdInfo  cmdInfo;
    domNode     *node = NULL;
    char        *nodeName;
    char         eolcheck;


    if (objPtr->typePtr == &tdomNodeType) {
        return TCL_OK;
    }


    nodeName = Tcl_GetString(objPtr);
    if (strncmp(nodeName, "domNode", 7)) {
        if (interp) {
            SetResult3("Parameter \"", nodeName, "\" is not a domNode.");
            return TCL_ERROR;
        }


    }







    if (sscanf(&nodeName[7], "%p%1c", (void **)&node, &eolcheck) != 1) {
        if (!Tcl_GetCommandInfo(interp, nodeName, &cmdInfo)) {
            if (interp) {
                SetResult3("Parameter \"", nodeName, "\" is not a domNode.");
                return TCL_ERROR;
            }
        }
        if (   (cmdInfo.isNativeObjectProc == 0)
            || (cmdInfo.objProc != (Tcl_ObjCmdProc*)tcldom_NodeObjCmd)) {
            if (interp) {
                SetResult3("Parameter \"", nodeName, "\" is not a domNode"
                    " object command");
                return TCL_ERROR;
            }
        }
        node = (domNode*)cmdInfo.objClientData;
    }
    if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc) {
        objPtr->typePtr->freeIntRepProc(objPtr);
    }
    objPtr->internalRep.otherValuePtr = node;
    objPtr->typePtr = &tdomNodeType;
    
    return TCL_OK;
}

/*----------------------------------------------------------------------------
|   tcldom_createNodeObj
|
\---------------------------------------------------------------------------*/
void tcldom_createNodeObj (
    Tcl_Interp * interp,
................................................................................
                             (ClientData)        node,
                             (Tcl_CmdDeleteProc*)NULL);
        node->nodeFlags |= VISIBLE_IN_TCL;
    }
}

/*----------------------------------------------------------------------------
|   tcldom_setInterpAndReturnVar
|
\---------------------------------------------------------------------------*/
static
int tcldom_setInterpAndReturnVar (
    Tcl_Interp *interp,
    domNode    *node,
    int         setVariable,
    Tcl_Obj    *var_name
)
{
    char     objCmdName[80];
    Tcl_Obj *resultObj;

    
    GetTcldomTSD()

    if (node == NULL) {
        if (setVariable) {
            if (!Tcl_ObjSetVar2 (interp, var_name, NULL,
                                 Tcl_NewStringObj("",0),
                                 TCL_LEAVE_ERR_MSG)) {
                return TCL_ERROR;
            }
        }
        SetResult("");
        return TCL_OK;
    }
    resultObj = Tcl_NewObj();
    resultObj->bytes = NULL;
    resultObj->length = 0;
    resultObj->internalRep.otherValuePtr = node;
    resultObj->typePtr = &tdomNodeType;
    Tcl_SetObjResult (interp, resultObj);
    if (TSD(dontCreateObjCommands) == 0) {
        tcldom_createNodeObj(interp, node, objCmdName);




    }

    if (setVariable) {




        if (!Tcl_ObjSetVar2 (interp, var_name, NULL, resultObj,
                             TCL_LEAVE_ERR_MSG)) {
            return TCL_ERROR;


        }
    }
    return TCL_OK;



}

/*----------------------------------------------------------------------------
|   tcldom_returnNodeObj
|
\---------------------------------------------------------------------------*/
static
Tcl_Obj *tcldom_returnNodeObj (
    Tcl_Interp *interp,
    domNode    *node)
{
    char     objCmdName[80];
    Tcl_Obj *resultObj;
    
    GetTcldomTSD()

    resultObj = Tcl_NewObj();
    if (node == NULL) {
        return resultObj;
    }
    if (TSD(dontCreateObjCommands) == 0) {
        tcldom_createNodeObj(interp, node, objCmdName);
    }

    resultObj->bytes = NULL;
    resultObj->length = 0;
    resultObj->internalRep.otherValuePtr = node;
    resultObj->typePtr = &tdomNodeType;
    return resultObj;
}

/*----------------------------------------------------------------------------
|   tcldom_returnDocumentObj
|
\---------------------------------------------------------------------------*/
int tcldom_returnDocumentObj (
................................................................................
            Tcl_SetVar(interp, objVar, objCmdName, 0);
        }
    } else {
        if (!Tcl_GetCommandInfo(interp, objCmdName, &cmd_info)) {
            dinfo = (domDeleteInfo*)MALLOC(sizeof(domDeleteInfo));
            dinfo->interp       = interp;
            dinfo->document     = document;
            document->nodeFlags |= DOCUMENT_CMD;
            dinfo->traceVarName = NULL;
            Tcl_CreateObjCommand(interp, objCmdName,
                                 (Tcl_ObjCmdProc *)  tcldom_DocObjCmd,
                                 (ClientData)        dinfo,
                                 (Tcl_CmdDeleteProc*)tcldom_docCmdDeleteProc);
        } else {
            dinfo = (domDeleteInfo*)cmd_info.objClientData;
        }
        if (setVariable) {
            objVar = Tcl_GetString(var_name);
            Tcl_UnsetVar(interp, objVar, 0);
            Tcl_SetVar  (interp, objVar, objCmdName, 0);
            if (trace) {
                document->nodeFlags |= VAR_TRACE;
                dinfo->traceVarName = tdomstrdup(objVar);
                Tcl_TraceVar(interp,objVar,TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
                             (Tcl_VarTraceProc*)tcldom_docTrace,
                             (ClientData)dinfo);
            }
        }
    }
................................................................................
    domNode    *node,
    int         nsIndex,
    const char *uri
)
{
    int         result;
    domNode    *child;
    char        prefix[MAX_PREFIX_LEN];
    const char *localName;
    Tcl_Obj    *namePtr, *resultPtr;

    /* nsIndex == -1 ==> DOM 1 no NS i.e getElementsByTagName
       nsIndex != -1 are the NS aware cases
       nsIndex == -2 ==> more than one namespace in the document with the 
                         requested namespace, we have to strcmp the URI
................................................................................
            if (nsIndex == -1) {
                localName = node->nodeName;
            } else {
                domSplitQName(node->nodeName, prefix, &localName);
            }
            if (Tcl_StringMatch(localName, namePattern)) {
                resultPtr = Tcl_GetObjResult(interp);
                namePtr = tcldom_returnNodeObj(interp, node);

                result = Tcl_ListObjAppendElement(interp, resultPtr, namePtr);
                if (result != TCL_OK) {
                    Tcl_DecrRefCount(namePtr);
                    return result;
                }
            }
        }
................................................................................
    domNode    * node,
    void       * clientData
)
{
    Tcl_Interp * interp = (Tcl_Interp*)clientData;
    Tcl_Obj    * resultPtr = Tcl_GetObjResult(interp);
    Tcl_Obj    * namePtr;

    int          result;


    namePtr = tcldom_returnNodeObj(interp, node);

    result  = Tcl_ListObjAppendElement(interp, resultPtr, namePtr);
    if (result != TCL_OK) {
        Tcl_DecrRefCount(namePtr);
    }
    return result;
}

................................................................................
\---------------------------------------------------------------------------*/
static
int tcldom_xpointerSearch (
    Tcl_Interp * interp,
    int          mode,
    domNode    * node,
    int          objc,
    Tcl_Obj    * const  objv[]
)
{
    char *str;
    int   i = 0;
    int   result = 0;
    int   all = 0;
    int   instance = 0;
................................................................................
    }
    if (result != 0) {
        return TCL_ERROR;
    }
    return TCL_OK;
}


/*----------------------------------------------------------------------------
|   tcldom_getNodeFromObj
|
\---------------------------------------------------------------------------*/
domNode * tcldom_getNodeFromObj (
    Tcl_Interp  *interp,
    Tcl_Obj     *nodeObj
)
{
    Tcl_CmdInfo  cmdInfo;
    domNode     *node = NULL;
    char        *nodeName;
    char         eolcheck;

    GetTcldomTSD()

    if (nodeObj->typePtr == &tdomNodeType) {
        return (domNode*)nodeObj->internalRep.otherValuePtr;
    }
    
    if (TSD(dontCreateObjCommands)) {
        if (SetTdomNodeFromAny (interp, nodeObj) == TCL_OK) {
            return (domNode*)nodeObj->internalRep.otherValuePtr;
        }
        return NULL;
    }
    
    nodeName = Tcl_GetString(nodeObj);
    if (strncmp(nodeName, "domNode", 7)) {
        SetResult3("Parameter \"", nodeName, "\" is not a domNode.");
        return NULL;
    }
    if (sscanf(&nodeName[7], "%p%1c", (void **)&node, &eolcheck) != 1) {
        if (!Tcl_GetCommandInfo(interp, nodeName, &cmdInfo)) {
            SetResult3("Parameter \"", nodeName, "\" is not a domNode.");
            return NULL;
        }
        if (   (cmdInfo.isNativeObjectProc == 0)
            || (cmdInfo.objProc != (Tcl_ObjCmdProc*)tcldom_NodeObjCmd)) {
            SetResult3("Parameter \"", nodeName, "\" is not a domNode"
                       " object command.");
            return NULL;
        }
        node = (domNode*)cmdInfo.objClientData;
    }

    return node;
}

/*----------------------------------------------------------------------------
|   tcldom_getNodeFromName
|
\---------------------------------------------------------------------------*/
domNode * tcldom_getNodeFromName (
    Tcl_Interp  *interp,
    char        *nodeName,
    char       **errMsg
)
{
    Tcl_CmdInfo  cmdInfo;
    domNode     *node = NULL;
    char         eolcheck;

    if (strncmp(nodeName, "domNode", 7)) {
        *errMsg = "parameter not a domNode!";
        return NULL;
    }
    if (sscanf(&nodeName[7], "%p%1c", (void **)&node, &eolcheck) != 1) {
        if (!Tcl_GetCommandInfo(interp, nodeName, &cmdInfo)) {
           *errMsg = "parameter not a domNode!";
           return NULL;
        }
        if (   (cmdInfo.isNativeObjectProc == 0)
            || (cmdInfo.objProc != (Tcl_ObjCmdProc*)tcldom_NodeObjCmd)) {
            *errMsg = "parameter not a domNode object command!";
................................................................................
    char        *docName,
    char       **errMsg
)
{
    Tcl_CmdInfo  cmdInfo;
    domDocument *doc = NULL;
    int          shared = 1;
    char         eolcheck;

    if (strncmp(docName, "domDoc", 6)) {
        *errMsg = "parameter not a domDoc!";
        return NULL;
    }
    if (sscanf(&docName[6], "%p%1c", (void **)&doc, &eolcheck) != 1) {
        if (!Tcl_GetCommandInfo(interp, docName, &cmdInfo)) {
            *errMsg = "parameter not a domDoc!";
            return NULL;
        }
        if (   (cmdInfo.isNativeObjectProc == 0)
            || (cmdInfo.objProc != (Tcl_ObjCmdProc*)tcldom_DocObjCmd)) {
            *errMsg = "parameter not a domDoc object command!";
................................................................................
\---------------------------------------------------------------------------*/
int tcldom_appendXML (
    Tcl_Interp *interp,
    domNode    *node,
    Tcl_Obj    *obj
)
{
    char        *xml_string;
    Tcl_Obj     *extResolver = NULL;
    int          xml_string_len;
    int          resultcode = 0;
    int          ignorexmlns = 0;
    domDocument *doc;
    domNode     *nodeToAppend;
    XML_Parser   parser;

    GetTcldomTSD()

    xml_string = Tcl_GetStringFromObj(obj, &xml_string_len);
................................................................................
#ifdef TDOM_NO_EXPAT
    SetResult("tDOM was compiled without Expat!");
    return TCL_ERROR;
#else
    parser = XML_ParserCreate_MM(NULL, MEM_SUITE, NULL);

    if (node->ownerDocument->extResolver) {
        extResolver = Tcl_NewStringObj(node->ownerDocument->extResolver, -1);
        Tcl_IncrRefCount (extResolver);
    }
    if (node->ownerDocument->nodeFlags & IGNORE_XMLNS) {
        ignorexmlns = 1;
    }

    doc = domReadDocument(parser,
                          xml_string,
                          xml_string_len,
                          1,

                          0,
                          TSD(storeLineColumn),
                          ignorexmlns,
                          0,
                          NULL,
                          NULL,
                          NULL,
                          extResolver,
                          0,
                          (int) XML_PARAM_ENTITY_PARSING_ALWAYS,
                          interp,
                          &resultcode);
    if (extResolver) {
        Tcl_DecrRefCount(extResolver);
    }
    if (doc == NULL) {
        char s[50];
        long byteIndex, i;

        Tcl_ResetResult(interp);
        sprintf(s, "%ld", XML_GetCurrentLineNumber(parser));
        Tcl_AppendResult(interp, "error \"",
................................................................................
    nodeToAppend = doc->rootNode->firstChild;
    while (nodeToAppend) {
        domAppendChild(node, nodeToAppend);
        nodeToAppend = nodeToAppend->nextSibling;
    }
    domFreeDocument(doc, NULL, NULL);

    return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);
#endif
}


/*----------------------------------------------------------------------------
|   tcldom_xpathResultSet
|
................................................................................
    xpathResultSet  *rs,
    Tcl_Obj         *type,
    Tcl_Obj         *value
)
{
    int          rc, i;
    Tcl_Obj     *namePtr, *objv[2];

    domAttrNode *attr;
    domNodeType  startType;
    int          mixedNodeSet;

    switch (rs->type) {
        case EmptyResult:
             Tcl_SetStringObj(type, "empty", -1);
................................................................................
                 if (rs->nodes[i]->nodeType == ATTRIBUTE_NODE) {
                     attr = (domAttrNode*)rs->nodes[i];
                     objv[0] = Tcl_NewStringObj(attr->nodeName, -1);
                     objv[1] = Tcl_NewStringObj(attr->nodeValue,
                                                attr->valueLength);
                     namePtr = Tcl_NewListObj(2, objv);
                 } else {
                     namePtr = tcldom_returnNodeObj(interp, rs->nodes[i]);

                 }
                 rc = Tcl_ListObjAppendElement(interp, value, namePtr);
                 if (rc != TCL_OK) {
                     Tcl_DecrRefCount(namePtr);
                     return rc;
                 }
             }
................................................................................
    xpathResultSets *args,
    xpathResultSet  *result,
    char           **errMsg
)
{
    Tcl_Interp  *interp = (Tcl_Interp*) clientData;
    char         tclxpathFuncName[200], objCmdName[80];
    char         *errStr, *typeStr;
    Tcl_Obj     *resultPtr, *objv[MAX_REWRITE_ARGS], *type, *value, *nodeObj,
                *tmpObj;
    Tcl_CmdInfo  cmdInfo;
    int          objc, rc, i, errStrLen, listLen, intValue, res;
    double       doubleValue;
    domNode     *node;

    DBG(fprintf(stderr, "tcldom_xpathFuncCallBack functionName=%s "
                "position=%d argc=%d\n", functionName, position, argc);)

    if (strlen(functionName) > 199) {
        *errMsg = (char*)MALLOC (80 + strlen (functionName));
        strcpy (*errMsg, "Unreasonable long XPath function name: \"");
        strcat (*errMsg, functionName);
        strcat (*errMsg, "\"!");
        return XPATH_EVAL_ERR;
    }
    sprintf (tclxpathFuncName, "::dom::xpathFunc::%s", functionName);
    DBG(fprintf(stderr, "testing %s\n", tclxpathFuncName);)
    rc = Tcl_GetCommandInfo (interp, tclxpathFuncName, &cmdInfo);
    if (!rc) {
        *errMsg = (char*)MALLOC (80 + strlen (functionName));
        strcpy (*errMsg, "Unknown XPath function: \"");
        strcat (*errMsg, functionName);
................................................................................
    if ( (5+(2*argc)) >= MAX_REWRITE_ARGS) {
        *errMsg = (char*)tdomstrdup("too many args for Tcl level method!");
        return XPATH_EVAL_ERR;
    }
    objc = 0;
    objv[objc] = Tcl_NewStringObj(tclxpathFuncName, -1);
    Tcl_IncrRefCount(objv[objc++]);
    if (ctxNode->nodeType == ATTRIBUTE_NODE) {
        tcldom_createNodeObj(interp, ((domAttrNode*)ctxNode)->parentNode,
                             objCmdName);
        tmpObj = Tcl_NewListObj(0, NULL);
        Tcl_ListObjAppendElement(interp, tmpObj, 
                                 Tcl_NewStringObj(objCmdName, -1));
        Tcl_ListObjAppendElement(
            interp, tmpObj,
            Tcl_NewStringObj(((domAttrNode*)ctxNode)->nodeName, -1));
    } else {
        tmpObj = tcldom_returnNodeObj(interp, ctxNode);
    }
    objv[objc] = tmpObj;
    Tcl_IncrRefCount(objv[objc++]);

    objv[objc] = Tcl_NewIntObj(position);
    Tcl_IncrRefCount(objv[objc++]);

    type  = Tcl_NewObj();
    value = Tcl_NewObj();
................................................................................
        xpathRSInit(result);
        resultPtr = Tcl_GetObjResult(interp);
        rc = Tcl_ListObjLength(interp, resultPtr, &listLen);
        if (rc == TCL_OK) {
            if (listLen == 1) {
                rsSetString(result, Tcl_GetString(resultPtr));
                res = XPATH_OK;
                Tcl_ResetResult(interp);
                goto funcCallCleanup;
            }
            if (listLen != 2) {
                *errMsg = (char*)tdomstrdup("wrong return tuple; "
                                            "must be {type value}!");
                res = XPATH_EVAL_ERR;
                goto funcCallCleanup;
................................................................................
                if (rc != TCL_OK) {
                    *errMsg = tdomstrdup("value not a node list!");
                    res = XPATH_EVAL_ERR;
                    goto funcCallCleanup;
                }
                for (i=0; i < listLen; i++) {
                    rc = Tcl_ListObjIndex(interp, value, i, &nodeObj);

                    node = tcldom_getNodeFromObj(interp, nodeObj);
                    if (node == NULL) {
                        *errMsg = tdomstrdup(Tcl_GetStringResult(interp));
                        res = XPATH_EVAL_ERR;
                        goto funcCallCleanup;
                    }
                    rsAddNode(result, node);
                }
                sortByDocOrder(result);
            } else
................................................................................
            if (strcmp(typeStr, "attrvalues")==0) {
                rsSetString(result, Tcl_GetString(value));
            } else {
                *errMsg = (char*)MALLOC (80 + strlen (typeStr)
                                         + strlen (functionName));
                strcpy(*errMsg, "Unknown type of return value \"");
                strcat(*errMsg, typeStr);
                strcat(*errMsg, "\" from Tcl coded XPath function \"");
                strcat(*errMsg, functionName);
                strcat(*errMsg, "\"!");
                res = XPATH_EVAL_ERR;
                goto funcCallCleanup;
            }
        } else {
            DBG(fprintf(stderr, "ListObjLength != TCL_OK "
................................................................................
            goto funcCallCleanup;
        }
        Tcl_ResetResult(interp);
        res = XPATH_OK;
    } else {
        errStr = Tcl_GetStringFromObj( Tcl_GetObjResult(interp), &errStrLen);
        *errMsg = (char*)MALLOC(120+strlen(functionName) + errStrLen);
        strcpy(*errMsg, "Tcl error while executing XPath extension function '");
        strcat(*errMsg, functionName );
        strcat(*errMsg, "':\n" );
        strcat(*errMsg, errStr);
        Tcl_ResetResult(interp);
        DBG(fprintf(stderr, "returning XPATH_EVAL_ERR \n");)
        res = XPATH_EVAL_ERR;
    }
................................................................................
}

/*----------------------------------------------------------------------------
|   tcldom_xsltMsgCB
|
\---------------------------------------------------------------------------*/
static
int tcldom_xsltMsgCB (
    void *clientData,
    char *str,
    int   length,
    int   terminate
    )
{
    XsltMsgCBInfo *msgCBInfo = (XsltMsgCBInfo *)clientData;
    Tcl_Obj       *cmdPtr;
    int            rc;
    
    if (msgCBInfo->msgcmd == NULL) {
        return 0;
    }
    
    cmdPtr = Tcl_DuplicateObj(msgCBInfo->msgcmd);
    Tcl_IncrRefCount(cmdPtr);
    if (Tcl_ListObjAppendElement(msgCBInfo->interp, cmdPtr, 
                                 Tcl_NewStringObj(str, length)) != TCL_OK) {
        Tcl_DecrRefCount(cmdPtr);
        return 1;
    }
    if (terminate) {
        Tcl_ListObjAppendElement(msgCBInfo->interp, cmdPtr,
                                 Tcl_NewBooleanObj(1));
    } else {
        Tcl_ListObjAppendElement(msgCBInfo->interp, cmdPtr,
                                 Tcl_NewBooleanObj(0));
    }
    rc = Tcl_GlobalEvalObj(msgCBInfo->interp, cmdPtr);
    Tcl_DecrRefCount(cmdPtr);
    switch (rc) {
    case TCL_OK: return 0;
    case TCL_BREAK: return 3;
    default: return rc;
    }
}

/*----------------------------------------------------------------------------
|   tcldom_xpathResolveVar
|
\---------------------------------------------------------------------------*/
static
................................................................................
char * tcldom_xpathResolveVar (
    void  *clientData,
    char  *strToParse,
    int   *offset,
    char **errMsg
    )
{
    const char *varValue;
    const char *termPtr;
    Tcl_Interp *interp = (Tcl_Interp *) clientData;
    
    *offset = 0;
    varValue = Tcl_ParseVar(interp, strToParse, &termPtr);
    if (varValue) {
        *offset = termPtr - strToParse;
        /* If strToParse start with a single '$' without a following
         * var name (according to Tcl var name rules), Tcl_ParseVar()
         * doesn't report a parsing error but returns just a pointer
         * to a static string "$". */ 
        if (*offset == 1) {
            *errMsg = tdomstrdup ("Missing var name after '$'.");
            varValue = NULL;
        }
    } else {
................................................................................
|
\---------------------------------------------------------------------------*/
static
int tcldom_selectNodes (
    Tcl_Interp *interp,
    domNode    *node,
    int         objc,
    Tcl_Obj    *const objv[]
)
{
    char          *xpathQuery, *typeVar, *option;
    char          *errMsg = NULL, **mappings = NULL;
    int            rc, i, len, optionIndex, localmapping = 0, cache = 0;
    int            mappingListObjLen = 0;
    xpathResultSet rs;
    Tcl_Obj       *type, *objPtr, *objPtr1, *mappingListObj = NULL;
    xpathCBs       cbs;
    xpathParseVarCB parseVarCB;

    static const char *selectNodesOptions[] = {
        "-namespaces", "-cache", NULL
    };
    enum selectNodesOption {
        o_namespaces, o_cache
    };

    if (objc < 2) {
................................................................................
        }
        switch ((enum selectNodesOption) optionIndex) {
        case o_namespaces:
            rc = Tcl_ListObjLength (interp, objv[2], &len);
            if (rc != TCL_OK || (len % 2) != 0) {
                SetResult ("The \"-namespaces\" option requires a 'prefix"
                           " namespace' pairs list as argument");
                rc = TCL_ERROR;
                goto cleanup;
            }
            if (mappings) {
                for (i = 0; i < mappingListObjLen; i++) {
                    Tcl_ListObjIndex (interp, mappingListObj, i, &objPtr1);
                    Tcl_DecrRefCount (objPtr1);
                }
                Tcl_DecrRefCount (mappingListObj);
                FREE (mappings);
            }
            mappings = MALLOC (sizeof (char *) * (len + 1));
            localmapping = 1;
            for (i = 0; i < len; i++) {
                Tcl_ListObjIndex (interp, objv[2], i, &objPtr);

                Tcl_IncrRefCount (objPtr);




                mappings[i] = Tcl_GetString (objPtr);
            }
            mappings[len] = NULL;
            mappingListObj = objv[2];
            Tcl_IncrRefCount (mappingListObj);
            mappingListObjLen = len;
            objc -= 2;
            objv += 2;
            break;

        case o_cache:
            if (Tcl_GetBooleanFromObj (interp, objv[2], &cache) != TCL_OK) {
                return TCL_ERROR;
................................................................................
            Tcl_AppendResult (interp, "bad option \"", 
                              Tcl_GetString (objv[1]), "\"; must be "
                              "-namespaces", NULL);
            return TCL_ERROR;
        }
    }
    if (objc != 2 && objc != 3) {



        SetResult("Wrong # of arguments.");
        rc = TCL_ERROR;
        goto cleanup;
    }

    xpathQuery = Tcl_GetString(objv[1]);

    xpathRSInit(&rs);

    cbs.funcCB         = tcldom_xpathFuncCallBack;
................................................................................
    cbs.varClientData  = NULL;

    parseVarCB.parseVarCB         = tcldom_xpathResolveVar;
    parseVarCB.parseVarClientData = interp;
    
    if (mappings == NULL) {
        mappings = node->ownerDocument->prefixNSMappings;



    }

    if (cache) {
        if (!node->ownerDocument->xpathCache) {
            node->ownerDocument->xpathCache = MALLOC (sizeof (Tcl_HashTable));
            Tcl_InitHashTable (node->ownerDocument->xpathCache,
                               TCL_STRING_KEYS);
        }
        rc = xpathEval (node, node, xpathQuery, mappings, &cbs, &parseVarCB,
................................................................................
    if (rc != XPATH_OK) {
        xpathRSFree(&rs);
        SetResult(errMsg);
        DBG(fprintf(stderr, "errMsg = %s \n", errMsg);)
        if (errMsg) {
            FREE(errMsg);
        }



        rc = TCL_ERROR;
        goto cleanup;
    }
    if (errMsg) {
        fprintf (stderr, "Why this: '%s'\n", errMsg);
        FREE(errMsg);
    }
    typeVar = NULL;
    if (objc > 2) {
        typeVar = Tcl_GetString(objv[2]);
    }
    type = Tcl_NewObj();
................................................................................
    Tcl_IncrRefCount(type);
    DBG(fprintf(stderr, "before tcldom_xpathResultSet \n");)
    tcldom_xpathResultSet(interp, &rs, type, Tcl_GetObjResult(interp));
    DBG(fprintf(stderr, "after tcldom_xpathResultSet \n");)
    if (typeVar) {
        Tcl_SetVar(interp,typeVar, Tcl_GetString(type), 0);
    }
    rc = TCL_OK;
    Tcl_DecrRefCount(type);

    xpathRSFree( &rs );
cleanup:
    if (localmapping) {
        for (i = 0; i < mappingListObjLen; i++) {
            Tcl_ListObjIndex (interp, mappingListObj, i, &objPtr1);
            Tcl_DecrRefCount (objPtr1);
        }
        Tcl_DecrRefCount (mappingListObj);
        FREE (mappings);
    }
    return rc;
}

/*----------------------------------------------------------------------------
|   tcldom_nameCheck
|
\---------------------------------------------------------------------------*/
int tcldom_nameCheck (
................................................................................
    |   create element node
    \-----------------------------------------------------------------------*/
    if (length != 3) {
        SetResult("invalid element node list format!");
        return TCL_ERROR;
    }
    CheckName (interp, tag_name, "tag", 0);
    newnode = domNewElementNode(node->ownerDocument, tag_name);
    domAppendChild(node, newnode);

    /*------------------------------------------------------------------------
    |   create attributes
    \-----------------------------------------------------------------------*/
    if ((rc = Tcl_ListObjIndex(interp, lnode, 1, &attrListObj)) != TCL_OK) {
        return rc;
    }
    if ((rc = Tcl_ListObjLength(interp, attrListObj, &attrLength))
        != TCL_OK) {
        return rc;
................................................................................
            return rc;
        }
        if ((rc = tcldom_appendFromTclList(interp, newnode, childObj))
            != TCL_OK) {
            return rc;
        }
    }
    return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);
}


/*----------------------------------------------------------------------------
|   tcldom_treeAsTclList
|
\---------------------------------------------------------------------------*/
................................................................................
    objv[0] = name;
    objv[1] = attrsList;
    objv[2] = childList;

    return Tcl_NewListObj(3, objv);
}


/*----------------------------------------------------------------------------
|   tcldom_AppendEscaped
|
\---------------------------------------------------------------------------*/
static
void tcldom_AppendEscaped (
    Tcl_Obj    *xmlString,
    Tcl_Channel chan,
    char       *value,
    int         value_length,
    int         outputFlags



)
{
#define APESC_BUF_SIZE 512
#define AP(c)  *b++ = c;
#define AE(s)  pc1 = s; while(*pc1) *b++ = *pc1++;
    char  buf[APESC_BUF_SIZE+80], *b, *bLimit,  *pc, *pc1, *pEnd, charRef[10];
    int   charDone, i;

    int   clen = 0;
    int   unicode;
    Tcl_UniChar uniChar;

    
    b = buf;
    bLimit = b + APESC_BUF_SIZE;
    pc = pEnd = value;
    if (value_length != -1) {
        pEnd = pc + value_length;
    }
    while (   (value_length == -1 && *pc)
           || (value_length != -1 && pc != pEnd)
    ) {
        if ((*pc == '"') && (outputFlags & SERIALIZE_FOR_ATTR
                             || outputFlags & SERIALIZE_ESCAPE_ALL_QUOT)) { 
            AP('&') AP('q') AP('u') AP('o') AP('t') AP(';')
        } else
        if (*pc == '&') { AP('&') AP('a') AP('m') AP('p') AP(';')
        } else
        if (*pc == '<') { AP('&') AP('l') AP('t') AP(';')
        } else
        if (*pc == '>' && !(outputFlags & SERIALIZE_NO_GT_ESCAPE)) {
            AP('&') AP('g') AP('t') AP(';')
        } else
        if ((*pc == '\n') && outputFlags & SERIALIZE_FOR_ATTR) {
            AP('&') AP('#') AP('x') AP('A') AP(';')
        } else
        {
            charDone = 0;
            if (outputFlags & SERIALIZE_HTML_ENTITIES) {
                charDone = 1;



                Tcl_UtfToUniChar(pc, &uniChar);
                switch (uniChar) 

                {
                case 0240: AE("&nbsp;");    break;     
                case 0241: AE("&iexcl;");   break;    
                case 0242: AE("&cent;");    break;     
                case 0243: AE("&pound;");   break;    
                case 0244: AE("&curren;");  break;   
                case 0245: AE("&yen;");     break;      
................................................................................
                case 0371: AE("&ugrave;");  break;   
                case 0372: AE("&uacute;");  break;   
                case 0373: AE("&ucirc;");   break;    
                case 0374: AE("&uuml;");    break;     
                case 0375: AE("&yacute;");  break;   
                case 0376: AE("&thorn;");   break;    
                case 0377: AE("&yuml;");    break;     

                /* "Special" chars, according to XHTML xhtml-special.ent */
                case 338:  AE("&OElig;");   break;
                case 339:  AE("&oelig;");   break;
                case 352:  AE("&Scaron;");  break;
                case 353:  AE("&scaron;");  break;
                case 376:  AE("&Yuml;");    break;
                case 710:  AE("&circ;");    break;
................................................................................
                case 9001: AE("&lang;");    break;     
                case 9002: AE("&rang;");    break;     
                case 9674: AE("&loz;");     break;      
                case 9824: AE("&spades;");  break;   
                case 9827: AE("&clubs;");   break;    
                case 9829: AE("&hearts;");  break;   
                case 9830: AE("&diams;");   break;    

                default: charDone = 0; 
                }

                if (charDone) {
                    clen = UTF8_CHAR_LEN(*pc);
                    pc += (clen - 1);
                }

            }














            if (!charDone) {
                if ((unsigned char)*pc > 127) {
                    clen = UTF8_CHAR_LEN(*pc);
                    if (!clen) {
                        domPanic("tcldom_AppendEscaped: can only handle "
                                 "UTF-8 chars up to 4 bytes length");


                    }
                    if (clen == 4 || outputFlags & SERIALIZE_ESCAPE_NON_ASCII) {
                        if (clen == 4) {
                            unicode = ((pc[0] & 0x07) << 18) 
                                + ((pc[1] & 0x3F) << 12)
                                + ((pc[2] & 0x3F) <<  6) 
                                + (pc[3] & 0x3F);
                        } else {
                            unicode = 0;
                            Tcl_UtfToUniChar(pc, (Tcl_UniChar*)&unicode);
                        }
                        AP('&') AP('#')
                        sprintf(charRef, "%d", unicode);
                        for (i = 0; i < (int)strlen(charRef); i++) {
                            AP(charRef[i]);
                        }
                        AP(';')
                        pc += (clen - 1);
                    } else {
                        for (i = 0; i < clen; i++) {
................................................................................
                        }
                        pc--;
                    }
                } else {
                    AP(*pc);
                }
            }

        }
        if (b >= bLimit) {
            writeChars(xmlString, chan, buf, b - buf);
            b = buf;
        }
        pc++;
    }
................................................................................
    Tcl_Channel  chan,
    int          escapeNonASCII,
    int          htmlEntities,
    int          doctypeDeclaration,
    int          noEscaping
)
{
    int          empty, scriptTag, outputFlags = 0;
    domNode     *child;
    domAttrNode *attrs;
    domDocument *doc;
    char         tag[80], attrName[80];

    if (escapeNonASCII) outputFlags = SERIALIZE_ESCAPE_NON_ASCII;
    if (htmlEntities) outputFlags |= SERIALIZE_HTML_ENTITIES;
    if (node->nodeType == DOCUMENT_NODE) {
        doc = (domDocument*) node;
        if (doctypeDeclaration && doc->documentElement) {
            writeChars(htmlString, chan, "<!DOCTYPE ", 10);
            writeChars(htmlString, chan, doc->documentElement->nodeName, -1);
            if (   doc->doctype 
                && doc->doctype->systemId 
................................................................................
        if ((node->nodeFlags & DISABLE_OUTPUT_ESCAPING) 
            || noEscaping) {
            writeChars(htmlString, chan, ((domTextNode*)node)->nodeValue,
                       ((domTextNode*)node)->valueLength);
        } else {
            tcldom_AppendEscaped(htmlString, chan,
                                 ((domTextNode*)node)->nodeValue,
                                 ((domTextNode*)node)->valueLength,
                                 outputFlags);
        }
        return;
    }

    if (node->nodeType == CDATA_SECTION_NODE) {
        if (noEscaping) {
            writeChars(htmlString, chan, ((domTextNode*)node)->nodeValue,
                       ((domTextNode*)node)->valueLength);
        } else {
            tcldom_AppendEscaped(htmlString, chan,
                                 ((domTextNode*)node)->nodeValue,
                                 ((domTextNode*)node)->valueLength,
                                 outputFlags);
        }
        return;
    }

    if (node->nodeType == COMMENT_NODE) {
        writeChars(htmlString, chan, "<!--", 4);
        writeChars(htmlString, chan, ((domTextNode*)node)->nodeValue,
                   ((domTextNode*)node)->valueLength);
        writeChars(htmlString, chan,  "-->", 3);
................................................................................
    |   empty tags and script tags (todo: HTML tags with
    |   URI attributes, to do escaping of Non-ASCII chars
    |   in the URI).
    \----------------------------------------------------------*/
    empty = 0;
    scriptTag = 0;
    switch (tag[0]) {
    case 'a':  if (!strcmp(tag,"area"))       {empty = 1;} break;
    case 'b':  if (!strcmp(tag,"br")     ||
                   !strcmp(tag,"base")   ||
                   !strcmp(tag,"basefont"))   {empty = 1;} break;
    case 'c':  if (!strcmp(tag,"col"))        {empty = 1;} break;
    case 'f':  if (!strcmp(tag,"frame"))      {empty = 1;} break;
    case 'h':  if (!strcmp(tag,"hr"))         {empty = 1;} break;
    case 'i':  if (!strcmp(tag,"img")    ||
                   !strcmp(tag,"input")  ||
                   !strcmp(tag,"isindex"))    {empty = 1;} break;
    case 'l':  if (!strcmp(tag,"link"))       {empty = 1;} break;
    case 'm':  if (!strcmp(tag,"meta"))       {empty = 1;} break;
    case 'p':  if (!strcmp(tag,"param"))      {empty = 1;} break;
    case 's':  if (!strcmp(tag,"script") ||     
                   !strcmp(tag,"style"))  {scriptTag = 1;} break;
    }


    attrs = node->firstAttr;
    while (attrs) {
        tcldom_tolower(attrs->nodeName, attrName, 80);
        writeChars(htmlString, chan, " ", 1);
        writeChars (htmlString, chan, attrName, -1);
        writeChars(htmlString, chan, "=\"", 2);
        tcldom_AppendEscaped(htmlString, chan, attrs->nodeValue, -1,
                             outputFlags | SERIALIZE_FOR_ATTR);
        writeChars(htmlString, chan, "\"", 1);
        attrs = attrs->nextSibling;
    }
    writeChars(htmlString, chan, ">", 1);


    if (empty) {
................................................................................
void tcldom_treeAsXML (
    Tcl_Obj    *xmlString,
    domNode    *node,
    int         indent,
    int         level,
    int         doIndent,
    Tcl_Channel chan,
    Tcl_Obj    *encString,

    int         cdataChild,
    int         outputFlags,
    int         indentAttrs
)
{
    domAttrNode   *attrs;
    domNode       *child;
    domDocument   *doc;
    int            first, hasElements, i;
    char           prefix[MAX_PREFIX_LEN], *start, *p;
    const char    *localName;
    Tcl_HashEntry *h;
    Tcl_DString    dStr;

    if (outputFlags & SERIALIZE_XML_DECLARATION) {
        outputFlags &= ~SERIALIZE_XML_DECLARATION;
        writeChars(xmlString, chan, "<?xml version=\"1.0\"", 19);
        if (encString) {
            writeChars(xmlString, chan, " encoding=\"", 11);
            writeChars(xmlString, chan,
                       Tcl_GetString(encString), -1);
            writeChars(xmlString, chan, "\"", 1);
        } else if (node->nodeType == DOCUMENT_NODE &&
                   ((domDocument*) node)->doctype &&
                   ((domDocument*) node)->doctype->encoding) {
            writeChars(xmlString, chan, " encoding=\"", 11);
            writeChars(xmlString, chan,
                       ((domDocument*) node)->doctype->encoding, -1);
            writeChars(xmlString, chan, "\"", 1);
        }
        writeChars(xmlString, chan, "?>\n", 3);
    }
    if (node->nodeType == DOCUMENT_NODE) {
        doc = (domDocument*) node;
        if (outputFlags & SERIALIZE_DOCTYPE_DECLARATION
            && doc->documentElement) {
            writeChars(xmlString, chan, "<!DOCTYPE ", 10);
            writeChars(xmlString, chan, doc->documentElement->nodeName, -1);
            if (   doc->doctype 
                && doc->doctype->systemId
                && (doc->doctype->systemId[0] != '\0')) {
                if (   doc->doctype->publicId 
                    && doc->doctype->publicId[0] != '\0') {
................................................................................
                }
            }
            writeChars(xmlString, chan, ">\n", 2);
        }
        child = doc->rootNode->firstChild;
        while (child) {
            tcldom_treeAsXML(xmlString, child, indent, level, doIndent, chan,
                             NULL, 0, outputFlags, indentAttrs);

            child = child->nextSibling;
        }
        return;
    }

    if (node->nodeType == TEXT_NODE) {
        if (cdataChild) {
................................................................................
        } else {
            if (node->nodeFlags & DISABLE_OUTPUT_ESCAPING) {
                writeChars(xmlString, chan, ((domTextNode*)node)->nodeValue,
                           ((domTextNode*)node)->valueLength);
            } else {
                tcldom_AppendEscaped(xmlString, chan,
                                     ((domTextNode*)node)->nodeValue,
                                     ((domTextNode*)node)->valueLength,
                                     outputFlags);
            }
        }
        return;
    }

    if (node->nodeType == CDATA_SECTION_NODE) {
        writeChars(xmlString, chan, "<![CDATA[", 9);
................................................................................
    }

    writeChars(xmlString, chan, "<", 1);
    writeChars(xmlString, chan, node->nodeName, -1);

    attrs = node->firstAttr;
    while (attrs) {
        if (indentAttrs > -1) {
            writeChars(xmlString, chan, "\n", 1);
            if ((indent != -1) && doIndent) {
                for(i=0; i<level; i++) {
                    writeChars(xmlString, chan, "        ", indent);
                }
                if (indentAttrs) {
                    writeChars(xmlString, chan, "        ", indentAttrs);
                }
            }
        } else {
            writeChars(xmlString, chan, " ", 1);
        }
        writeChars(xmlString, chan, attrs->nodeName, -1);
        writeChars(xmlString, chan, "=\"", 2);
        tcldom_AppendEscaped(xmlString, chan, attrs->nodeValue, 
                             attrs->valueLength,
                             outputFlags | SERIALIZE_FOR_ATTR);
        writeChars(xmlString, chan, "\"", 1);
        attrs = attrs->nextSibling;
    }

    hasElements = 0;
    first       = 1;
    doIndent    = 1;
................................................................................
                writeChars(xmlString, chan, ">", 1);
                if ((indent != -1) && hasElements) {
                    writeChars(xmlString, chan, "\n", 1);
                }
            }
            first = 0;
            tcldom_treeAsXML(xmlString, child, indent, level+1, doIndent,
                             chan, NULL, cdataChild, outputFlags, indentAttrs);

            doIndent = 0;
            if (  (child->nodeType == ELEMENT_NODE)
                ||(child->nodeType == PROCESSING_INSTRUCTION_NODE)
                ||(child->nodeType == COMMENT_NODE) )
            {
               doIndent = 1;
            }
            child = child->nextSibling;
        }
    }

    if (first) {
        if (indent != -1) {
            if (outputFlags & SERIALIZE_NO_EMPTY_ELEMENT_TAG) {
                writeChars (xmlString, chan, "></", 3);
                writeChars(xmlString, chan, node->nodeName, -1);
                writeChars(xmlString, chan, ">\n", 2);
            } else {
                writeChars(xmlString, chan, "/>\n", 3);
            }
        } else {
            if (outputFlags & SERIALIZE_NO_EMPTY_ELEMENT_TAG) {
                writeChars (xmlString, chan, "></", 3);
                writeChars(xmlString, chan, node->nodeName, -1);
                writeChars(xmlString, chan, ">", 1);
            } else {
                writeChars(xmlString, chan, "/>",   2);
            }
        }
    } else {
        if ((indent != -1) && hasElements) {
            for(i=0; i<level; i++) {
                writeChars(xmlString, chan, "        ", indent);
            }
        }
................................................................................
        if (indent != -1) {
            writeChars(xmlString, chan, ">\n", 2);
        } else {
            writeChars(xmlString, chan, ">",   1);
        }
    }
}

/*----------------------------------------------------------------------------
|   tcldom_AppendEscapedJSON
|
\---------------------------------------------------------------------------*/
static
void tcldom_AppendEscapedJSON (
    Tcl_Obj    *jstring,
    Tcl_Channel chan,
    char       *value,
    int         value_length
)
{
    char  buf[APESC_BUF_SIZE+80], *b, *bLimit,  *pc, *pEnd;
    int   i;
    int   clen = 0;

    b = buf;
    bLimit = b + APESC_BUF_SIZE;
    pc = pEnd = value;
    if (value_length != -1) {
        pEnd = pc + value_length;
    }
    AP('"');
    while (
        (value_length == -1 && *pc)
        || (value_length != -1 && pc != pEnd)
    ) {
        clen = UTF8_CHAR_LEN(*pc);
        if (!clen) {
            /* This would be invalid utf-8 encoding. */
            clen = 1;
        }
        if (clen == 1) {
            if (*pc == '\\') {
                AP('\\'); AP('\\');
            } else if (*pc == '"') {
                AP('\\'); AP('"');
            } else if (*pc == '\b') {
                AP('\\'); AP('b');
            } else if (*pc == '\f') {
                AP('\\'); AP('f');
            } else if (*pc == '\n') {
                AP('\\'); AP('n');
            } else if (*pc == '\r') {
                AP('\\'); AP('r');
            } else if (*pc == '\t') {
                AP('\\'); AP('t');
            } else if ((unsigned char)*pc < 0x20) {
                AP('\\'); AP('u'); AP('0'); AP('0');
                AP('0' + (*pc>>4));
                AP("0123456789abcdef"[*pc&0xf]);
            } else {
                AP(*pc);
            }
            pc++;
        } else {
            if ((unsigned char)*pc == 0xC0 && (unsigned char)*(pc+1) == 0x80) {
                AP('\\');AP('u');AP('0');AP('0');AP('0');AP('0');
                pc++;pc++;
            } else {
                for (i = 0; i < clen; i++) {
                    AP(*pc);
                    pc++;
                }
            }
        }
        if (b >= bLimit) {
            writeChars(jstring, chan, buf, b - buf);
            b = buf;
        }
    }
    AP('"');
    writeChars(jstring, chan, buf, b - buf);
}

static
void tcldom_childsAsJSON (
    Tcl_Obj     *jstring,
    domNode     *node, /* Must be an ELEMENT_NODE */
    Tcl_Channel  channel,
    int          indent,
    int          level,
    int          inside
    )
{
    domNode   *child, *nextChild;
    int i, effectivParentType = 0;
    int first = 1;

    child = node->firstChild;
    while (child
           && child->nodeType != TEXT_NODE
           && child->nodeType != ELEMENT_NODE) {
        child = child->nextSibling;
    }

    if (node->info == JSON_ARRAY || node->info == JSON_OBJECT) {
        effectivParentType = node->info;
    } else if (child == NULL) {
        /* Need 'heuristic rule' to decide, what to do. */
        switch (inside) {
        case JSON_OBJECT:
            /* The childs to serialize are the value of an object member. */
            /* No content at all. This could be an empty string,
             * an empty object or an empty array. We default to
             * empty string. */
            writeChars(jstring, channel, "\"\"",2);
            return;
        case JSON_START:
        case JSON_ARRAY:
            /* The childs, we serialize are the value of an array
             * element. The node is a container for either a
             * (nested, in case of JSON_ARRAY) array or an object. */
            /* Look, if the name of the container gives a hint.*/
            if (strcmp (node->nodeName, JSON_ARRAY_CONTAINER)==0) {
                effectivParentType = JSON_ARRAY;
                break;
            }
            /* If we here, heuristics didn't helped. We have to
             * default to something. Let's say ... */
            effectivParentType = JSON_OBJECT;
            break;
        }
    } else {
        if (child->nodeType == ELEMENT_NODE) {
            /* The first 'relevant' child node is ELEMENT_NODE */
            effectivParentType = JSON_OBJECT;
            if (inside == JSON_ARRAY) {
                /* Though, if we inside of an array and the node name
                 * of the first 'relevant' child is the array
                 * container element, we assume an array (with a
                 * nested array as first value of that array. */
                if (strcmp (child->nodeName, JSON_ARRAY_CONTAINER))
                    effectivParentType = JSON_ARRAY;
            }
        } else {
            /* If we are here, the first 'relevant' child is a
             * text node. If there is any other 'relevant' child,
             * we assume the value to be an array. Otherwise (only
             * single 'relevant' child is a text node), this is
             * any of string, true, false null. Child may have a
             * type hint. */
            nextChild = child->nextSibling;
            while (nextChild
                   && nextChild->nodeType != TEXT_NODE
                   && nextChild->nodeType != ELEMENT_NODE) {
                nextChild = nextChild->nextSibling;
            }
            if (nextChild) {
                effectivParentType = JSON_ARRAY;
            } else {
                /* Exactly one 'relevant' child node, a text node;
                 * serialize it as simple token value. */
                tcldom_treeAsJSON (jstring, child, channel, indent,
                                   level, JSON_ARRAY);
                return;
            }
        }
    }
        
    switch (effectivParentType) {
    case JSON_ARRAY:
        writeChars(jstring, channel, "[",1);
        while (child) {
            if (first) {
                first = 0;
                level++;
            } else {
                writeChars(jstring, channel, ",", 1);
            }
            if (indent > -1) {
                writeChars(jstring, channel, "\n", 1);
                if (first) level++;
                for (i = 0; i < level; i++) {
                    writeChars(jstring, channel, "        ", indent);
                }
            }
            tcldom_treeAsJSON (jstring, child, channel, indent,
                               level, JSON_ARRAY);
            child = child->nextSibling;
            while (child
                   && child->nodeType != TEXT_NODE
                   && child->nodeType != ELEMENT_NODE) {
                child = child->nextSibling;
            }
        }
        if (indent > -1 && first == 0) {
            writeChars(jstring, channel, "\n", 1);
            level--;
            for (i = 0; i < level; i++) {
                writeChars(jstring, channel, "        ", indent);
            }
        }
        writeChars(jstring, channel, "]",1);
        break;
    case JSON_OBJECT:
        writeChars(jstring, channel, "{",1);
        while (child) {
            if (first) {
                first = 0;
                level++;
            } else {
                writeChars(jstring, channel, ",", 1);
            }
            if (indent > -1) {
                writeChars(jstring, channel, "\n", 1);
                if (first) level++;
                for (i = 0; i < level; i++) {
                    writeChars(jstring, channel, "        ", indent);
                }
            }
            tcldom_treeAsJSON (jstring, child, channel, indent,
                               level, JSON_OBJECT);
            child = child->nextSibling;
            /* Inside of a JSON_OBJECT, only element childs make
             * semantically sense. */
            while (child && child->nodeType != ELEMENT_NODE) {
                child = child->nextSibling;
            }
        }
        if (indent > -1 && first == 0) {
            writeChars(jstring, channel, "\n", 1);
            level--;
            for (i = 0; i < level; i++) {
                writeChars(jstring, channel, "        ", indent);
            }
        }
        writeChars(jstring, channel, "}",1);
        break;
    default:
        break;
    }
}


/*----------------------------------------------------------------------------
|   tcldom_treeAsJSON
|
\---------------------------------------------------------------------------*/
static
void tcldom_treeAsJSON (
    Tcl_Obj     *jstring,
    domNode     *node,  /* Must not be NULL */
    Tcl_Channel  channel,
    int          indent,
    int          level,
    int          inside
    )
{
    domTextNode *textNode;
    int i, seenDP, seenE;
    unsigned char c;
    char *num;
    
    switch (node->nodeType) {
    case TEXT_NODE:
        if (inside == JSON_OBJECT) {
            /* We're inside a JSON object. A text node can not be
             * meaningful interpreted as member of an object. Ignore
             * the node */
            return;
        }
        textNode = (domTextNode *) node;
        switch (node->info) {
        case JSON_NUMBER:
            /* Check, if the text value is a JSON number and fall back
             * to string token, if not. This is to ensure, the
             * serialization is always a valid JSON string. */
            if (textNode->valueLength == 0) goto notANumber;
            seenDP = 0;
            seenE = 0;
            i = 0;
            num = textNode->nodeValue;
            c = num[0];
            if (!(c == '-' || (c>='0' && c<='9'))) goto notANumber;
            if (c<='0') {
                i = (c == '-' ? i+1 : i);
                if (i+1 < textNode->valueLength) {
                    if (num[i] == '0' && num[i+1] >= '0' && num[i+1] <= '9') {
                        goto notANumber;
                    }
                }
            }
            i = 1;
            for (; i < textNode->valueLength; i++) {
                c = num[i];
                if (c >= '0' && c <= '9') continue;
                if (c == '.') {
                    if (num[i-1] == '-') goto notANumber;
                    if (seenDP) goto notANumber;
                    seenDP = 1;
                    continue;
                }
                if (c == 'e' || c == 'E') {
                    if (num[i-1] < '0') goto notANumber;
                    if (seenE) goto notANumber;
                    seenDP = seenE = 1;
                    c = num[i+1];
                    if (c == '+' || c == '-') {
                        i++;
                        c = num[i+1];
                    }
                    if (c < '0' || c > '9') goto notANumber;
                    continue;
                }
                break;
            }
            /* Catches a plain '-' without following digits */
            if (num[i-1] < '0') goto notANumber;
            /* Catches trailing chars */
            if (i < textNode->valueLength) goto notANumber;
            writeChars(jstring, channel, textNode->nodeValue,
                       textNode->valueLength);
            break;
            notANumber:
            tcldom_AppendEscapedJSON (jstring, channel,
                                      textNode->nodeValue,
                                      textNode->valueLength);
            break;
        case JSON_NULL:
            writeChars(jstring, channel, "null",4);
            break;
        case JSON_TRUE:
            writeChars(jstring, channel, "true",4);
            break;
        case JSON_FALSE:
            writeChars(jstring, channel, "false",5);
            break;
        case JSON_STRING:
            /* Fall through */
        default:
            tcldom_AppendEscapedJSON (jstring, channel,
                                      textNode->nodeValue,
                                      textNode->valueLength);
            break;
        };
        return;
    case ELEMENT_NODE:
        switch (inside) {
        case JSON_OBJECT:
            /* Write the member name and recurse to the childs for the
             * value. */
            tcldom_AppendEscapedJSON (jstring, channel,
                                      node->nodeName, -1);
            writeChars (jstring, channel, ":", 1);
            tcldom_childsAsJSON (jstring, node, channel, indent,
                                 level, inside);
            break;
        case JSON_ARRAY:
            /* Since we're already inside of an array, the element can
               only be interpreted as a container for a nested JSON
               object or array. */
            tcldom_childsAsJSON (jstring, node, channel, indent,
                                 level, inside);
            break;
        case JSON_START:
            tcldom_childsAsJSON (jstring, node, channel, indent,
                                 level, inside);            
            break;
        }
        return;
    default:
        /* Any other node types (COMMENT_NODE, CDATA_SECTION_NODE, 
           PROCESSING_INSTRUCTION_NODE) are ignored. */
        return;
    }
}

/*----------------------------------------------------------------------------
|   findBaseURI
|
\---------------------------------------------------------------------------*/
const char *findBaseURI (
    domNode *node
................................................................................
|   serializeAsXML
|
\---------------------------------------------------------------------------*/
static int serializeAsXML (
    domNode    *node,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *const objv[]
)
{
    char          *channelId, prefix[MAX_PREFIX_LEN];
    const char    *localName;
    int            indent, mode, bool;
    int            outputFlags = 0;
    int            optionIndex, cdataChild;
    Tcl_Obj       *resultPtr, *encString = NULL;
    Tcl_Channel    chan = (Tcl_Channel) NULL;
    Tcl_HashEntry *h;
    Tcl_DString    dStr;
    int            indentAttrs = -1;

    static const char *asXMLOptions[] = {
        "-indent", "-channel", "-escapeNonASCII", "-doctypeDeclaration",

        "-xmlDeclaration", "-encString", "-escapeAllQuot", "-indentAttrs",
        "-nogtescape", "-noEmptyElementTag",
        NULL
    };
    enum asXMLOption {
        m_indent, m_channel, m_escapeNonASCII, m_doctypeDeclaration,
        m_xmlDeclaration, m_encString, m_escapeAllQuot, m_indentAttrs,
        m_nogtescape, m_noEmptyElementTag
    };
    







    indent = 4;
    while (objc > 2) {
        if (Tcl_GetIndexFromObj(interp, objv[2], asXMLOptions, "option", 0,
                               &optionIndex) != TCL_OK) {
            goto cleanup;
        }
        switch ((enum asXMLOption) optionIndex) {

        case m_indent:
            if (objc < 4) {
                SetResult("-indent must have an argument "
                          "(0..8 or 'no'/'none')");
                goto cleanup;
            }
            if (strcmp("none", Tcl_GetString(objv[3]))==0) {
                indent = -1;
            }
            else if (strcmp("no", Tcl_GetString(objv[3]))==0) {
                indent = -1;
            }
            else if (Tcl_GetIntFromObj(interp, objv[3], &indent) != TCL_OK) {
                SetResult( "indent must be an integer (0..8) or 'no'/'none'");
                goto cleanup;
            }
            objc -= 2;
            objv += 2;
            break;

        case m_indentAttrs:
            if (objc < 4) {
                SetResult("-indentAttrs must have an argument "
                          "(0..8 or 'no'/'none')");
                goto cleanup;
            }
            if (strcmp("none", Tcl_GetString(objv[3]))==0) {
                indentAttrs = -1;
            }
            else if (strcmp("no", Tcl_GetString(objv[3]))==0) {
                indentAttrs = -1;
            }
            else if (Tcl_GetIntFromObj(interp, objv[3], &indentAttrs) != TCL_OK) {
                SetResult( "indentAttrs must be an integer (0..8) or 'no'/'none'");
                goto cleanup;
            }
            if (indentAttrs > 8) indentAttrs = 8;
            if (indentAttrs < 0) indentAttrs = 0;
            objc -= 2;
            objv += 2;
            break;

        case m_channel:
            if (objc < 4) {
                SetResult("-channel must have a channeldID as argument");
                goto cleanup;
            }
            channelId = Tcl_GetString(objv[3]);
            chan = Tcl_GetChannel(interp, channelId, &mode);
            if (chan == (Tcl_Channel) NULL) {
                SetResult("-channel must have a channeldID as argument");
                goto cleanup;
            }
            if ((mode & TCL_WRITABLE) == 0) {
                Tcl_AppendResult(interp, "channel \"", channelId,
                                "\" isnt't opened for writing", (char*)NULL);
                goto cleanup;
            }
            objc -= 2;
            objv += 2;
            break;

        case m_escapeNonASCII:
            outputFlags |= SERIALIZE_ESCAPE_NON_ASCII;
            objc--;
            objv++;
            break;
            
        case m_doctypeDeclaration:
            if (node->nodeType != DOCUMENT_NODE) {
                SetResult("-doctypeDeclaration as flag to the method "
                          "'asXML' is only allowed for domDocCmds");
                goto cleanup;
            }
            if (objc < 4) {
                SetResult("-doctypeDeclaration must have a boolean value "
                          "as argument");
                goto cleanup;
            }
            if (Tcl_GetBooleanFromObj(interp, objv[3], &bool)
                != TCL_OK) {
                goto cleanup;
            }
            if (bool) outputFlags |= SERIALIZE_DOCTYPE_DECLARATION;
            objc -= 2;
            objv += 2;
            break;

        case m_xmlDeclaration:
            if (objc < 4) {
                SetResult("-xmlDeclaration must have a boolean value "
                          "as argument");
                goto cleanup;
            }
            if (Tcl_GetBooleanFromObj(interp, objv[3], &bool)
                != TCL_OK) {
                goto cleanup;
            }
            if (bool) outputFlags |= SERIALIZE_XML_DECLARATION;
            objc -= 2;
            objv += 2;
            break;

        case m_encString:
            if (objc < 4) {
                SetResult("-encString must have a string "
                          "as argument");
                goto cleanup;
            }
            if (encString) {
                Tcl_DecrRefCount(encString);
            }
            encString = objv[3];
            Tcl_IncrRefCount(encString);
            objc -= 2;
            objv += 2;
            break;
            
        case m_escapeAllQuot:
            outputFlags |= SERIALIZE_ESCAPE_ALL_QUOT;
            objc -= 1;
            objv += 1;
            break;

        case m_nogtescape:
            outputFlags |= SERIALIZE_NO_GT_ESCAPE;
            objc -= 1;
            objv += 1;
            break;

        case m_noEmptyElementTag:
            outputFlags |= SERIALIZE_NO_EMPTY_ELEMENT_TAG;
            objc -= 1;
            objv += 1;
            break;
        }
    }
    if (indent > 8)  indent = 8;
    if (indent < -1) indent = -1;
................................................................................
                node->ownerDocument->doctype->cdataSectionElements,
                node->nodeName);
        }
        if (h) {
            cdataChild = 1;
        }
    }
    tcldom_treeAsXML(resultPtr, node, indent, 0, 1, chan, encString,
                     cdataChild, outputFlags, indentAttrs);
    Tcl_SetObjResult(interp, resultPtr);
    if (encString) {
        Tcl_DecrRefCount(encString);
    }
    return TCL_OK;
cleanup:
    if (encString) {
        Tcl_DecrRefCount(encString);
    }
    return TCL_ERROR;
}

/*----------------------------------------------------------------------------
|   serializeAsHTML
|
\---------------------------------------------------------------------------*/
static int serializeAsHTML (
    domNode    *node,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *const objv[]
)
{
    char       *channelId;
    int         optionIndex, mode, escapeNonASCII = 0, htmlEntities = 0;
    int         doctypeDeclaration = 0;
    Tcl_Obj    *resultPtr;
    Tcl_Channel chan = (Tcl_Channel) NULL;

    static const char *asHTMLOptions[] = {
        "-channel", "-escapeNonASCII", "-htmlEntities", "-doctypeDeclaration",
        NULL
    };
    enum asHTMLOption {
        m_channel, m_escapeNonASCII, m_htmlEntities, m_doctypeDeclaration
    };
    
................................................................................
    resultPtr = Tcl_NewStringObj("", 0);
    tcldom_treeAsHTML(resultPtr, node, chan, escapeNonASCII, htmlEntities,
                      doctypeDeclaration, 0);
    Tcl_AppendResult(interp, Tcl_GetString(resultPtr), NULL);
    Tcl_DecrRefCount(resultPtr);
    return TCL_OK;
}

/*----------------------------------------------------------------------------
|   serializeAsJSON
|
\---------------------------------------------------------------------------*/
static int serializeAsJSON (
    domNode    *node,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *const objv[]
)
{
    char       *channelId;
    int         optionIndex, mode, indent = -1;
    Tcl_Obj    *resultPtr;
    Tcl_Channel chan = (Tcl_Channel) NULL;

    static const char *asJSONOptions[] = {
        "-channel", "-indent",
        NULL
    };
    enum asJSONOption {
        m_channel, m_indent
    };

    if (node->nodeType != ELEMENT_NODE) {
        SetResult("Not an element node.\n");
        return TCL_ERROR;
    }
    
    if (objc > 5) {
        Tcl_WrongNumArgs(interp, 2, objv,
                         "?-channel <channelId>? "
                         "?-indent <none,0..8>?");
        return TCL_ERROR;
    }
    while (objc > 2) {
        if (Tcl_GetIndexFromObj(interp, objv[2], asJSONOptions, "option", 
                                0, &optionIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        switch ((enum asJSONOption) optionIndex) {

        case m_channel:
            if (objc < 4) {
                SetResult("-channel must have a channeldID as argument");
                return TCL_ERROR;
            }
            channelId = Tcl_GetString(objv[3]);
            chan = Tcl_GetChannel(interp, channelId, &mode);
            if (chan == (Tcl_Channel) NULL) {
                SetResult("-channel must have a channeldID as argument");
                return TCL_ERROR;
            }
            if ((mode & TCL_WRITABLE) == 0) {
                Tcl_AppendResult(interp, "channel \"", channelId,
                                "\" wasn't opened for writing", (char*)NULL);
                return TCL_ERROR;
            }
            objc -= 2;
            objv += 2;
            break;

        case m_indent:
            if (objc < 4) {
                SetResult("-indent must have an argument "
                          "(0..8 or 'no'/'none')");
                return TCL_ERROR;
            }
            if (strcmp("none", Tcl_GetString(objv[3]))==0) {
                indent = -1;
            }
            else if (strcmp("no", Tcl_GetString(objv[3]))==0) {
                indent = -1;
            }
            else if (Tcl_GetIntFromObj(interp, objv[3], &indent) != TCL_OK) {
                SetResult( "indent must be an integer (0..8) or 'no'/'none'");
                return TCL_ERROR;
            } else if (indent < 0 || indent > 8) {
                SetResult( "indent must be an integer (0..8) or 'no'/'none'");
                return TCL_ERROR;
            }
                
            objc -= 2;
            objv += 2;
            break;
        }
    }
    resultPtr = Tcl_NewStringObj("", 0);
    tcldom_treeAsJSON(resultPtr, node, chan, indent, 0, JSON_START);
    Tcl_AppendResult(interp, Tcl_GetString(resultPtr), NULL);
    Tcl_DecrRefCount(resultPtr);
    return TCL_OK;
}

/*----------------------------------------------------------------------------
|   cdataSectionElements
|
\---------------------------------------------------------------------------*/
static int cdataSectionElements (
    domDocument *doc,
    Tcl_Interp  *interp,
    int          objc,
    Tcl_Obj     *const objv[] 
    )
{
    int result, hnew;
    Tcl_Obj *resultPtr,*namePtr;
    Tcl_HashEntry *h;
    Tcl_HashSearch search;
    
................................................................................
|   selectNodesNamespaces
|
\---------------------------------------------------------------------------*/
static int selectNodesNamespaces (
    domDocument *doc,
    Tcl_Interp  *interp,
    int          objc,
    Tcl_Obj     *const objv[] 
    )
{
    int      len, i, result;
    Tcl_Obj *objPtr, *listPtr;

    CheckArgs (2,3,2, "?prefixUriList?");
    if (objc == 3) {
................................................................................
|   renameNodes
|
\---------------------------------------------------------------------------*/
static int renameNodes (
    domDocument *doc,
    Tcl_Interp  *interp,
    int          objc,
    Tcl_Obj     *const objv[] 
    )
{
    int      len, i, hnew;

    Tcl_HashEntry *h;
    Tcl_Obj *objPtr;
    domNode     *node;
    
    CheckArgs (4,4,0, "<domDoc> renameNode nodeList name");
    if (Tcl_ListObjLength (interp, objv[2], &len) != TCL_OK) {
        SetResult ("The first argument to the renameNode method"
................................................................................
                   " must be a list of element nodes.");
        return TCL_ERROR;
    }
    h = Tcl_CreateHashEntry(&HASHTAB(doc,tdom_tagNames), 
                            Tcl_GetString(objv[3]), &hnew);
    for (i = 0; i < len; i++) {
        Tcl_ListObjIndex (interp, objv[2], i, &objPtr);
        node = tcldom_getNodeFromObj (interp, objPtr);

        if (node == NULL) {


            return TCL_ERROR;
        }
        node->nodeName = (char *)&(h->key);
    }
    return TCL_OK;
}

................................................................................
|   deleteXPathCache
|
\---------------------------------------------------------------------------*/
static int deleteXPathCache (
    domDocument *doc,
    Tcl_Interp  *interp,
    int          objc,
    Tcl_Obj     *const objv[] 
    )
{
    Tcl_HashEntry *h;
    Tcl_HashSearch search;
    
    CheckArgs (2,3,0, "<domDoc> deleteXPathCache ?xpathQuery?");
    if (objc == 3) {
................................................................................
|
\---------------------------------------------------------------------------*/
static int applyXSLT (
    domNode     *node,
    Tcl_Interp  *interp,
    void        *clientData,
    int          objc,
    Tcl_Obj     *const objv[]
    )
{
    char          *usage, **parameters = NULL, *errMsg, *option;
    Tcl_Obj       *objPtr, *localListPtr = (Tcl_Obj *)NULL;
    int            i, result, length, optionIndex;
    int            ignoreUndeclaredParameters = 0;
    int            maxApplyDepth = MAX_XSLT_APPLY_DEPTH;
    domDocument   *xsltDoc, *xmlDoc, *resultDoc = NULL;
    XsltMsgCBInfo  xsltMsgInfo;

    static char *method_usage = 
        "wrong # args: should be \"nodeObj xslt ?-parameters parameterList? "
        "?-ignoreUndeclaredParameters? ?-maxApplyDepth int? "
        "?-xsltmessagecmd cmd? xsltDocNode ?varname?\"";

    static char *cmd_usage = 
        "wrong # args: should be \"?-parameters parameterList? "
        "?-ignoreUndeclaredParameters? ?-maxApplyDepth int? "
        "?-xsltmessagecmd cmd? <xmlDocObj> ?objVar?\"";

    static const char *xsltOptions[] = {
        "-parameters", "-ignoreUndeclaredParameters",
        "-maxApplyDepth", "-xsltmessagecmd", NULL
    };

    enum xsltOption {
        m_parameters, m_ignoreUndeclaredParameters, m_maxApplyDepth,
        m_xsltmessagecmd
    };

    xsltMsgInfo.interp = interp;
    xsltMsgInfo.msgcmd = NULL;

    if (node)  usage = method_usage;
    else       usage = cmd_usage;
................................................................................
        if (Tcl_GetIndexFromObj(interp, objv[0], xsltOptions, "option", 0,
                                 &optionIndex) != TCL_OK) {
            goto applyXSLTCleanUP;
        }
    
        switch ((enum xsltOption) optionIndex) {

        case m_parameters:
            if (objc < 3) {SetResult(usage); goto applyXSLTCleanUP;}
            if (Tcl_ListObjLength(interp, objv[1], &length) != TCL_OK) {
                SetResult("ill-formed parameters list: the -parameters "
                          "option needs a list of parameter name and "
                          "parameter value pairs");
                goto applyXSLTCleanUP;
            }
................................................................................
            Tcl_IncrRefCount(localListPtr);
            parameters =  (char **)MALLOC(sizeof(char *)*(length+1));
            for (i = 0; i < length; i ++) {
                Tcl_ListObjIndex(interp, localListPtr, i, &objPtr);
                parameters[i] = Tcl_GetString(objPtr);
            }
            parameters[length] = NULL;
            objc -= 2;
            objv += 2;
            break;

        case m_maxApplyDepth:
            if (objc < 3) {SetResult(usage); goto applyXSLTCleanUP;}
            if (Tcl_GetIntFromObj(interp, objv[1], &maxApplyDepth)
                != TCL_OK) {
                SetResult("-maxApplyDepth requires a positive integer "
                          "as argument");
                goto applyXSLTCleanUP;
            }
            if (maxApplyDepth < 1) {
                SetResult("-maxApplyDepth requires a positive integer "
                          "as argument");
                goto applyXSLTCleanUP;
            }
            objc -= 2;
            objv += 2;
            break;
        
        case m_ignoreUndeclaredParameters:
            if (objc < 2) {SetResult(usage); goto applyXSLTCleanUP;}
            ignoreUndeclaredParameters = 1;
................................................................................
            SetResult( errMsg );
            goto applyXSLTCleanUP;
        }
        node = (domNode *) xmlDoc;
        xsltDoc = NULL;
    }
    result = xsltProcess(xsltDoc, node, clientData, parameters, 
                         ignoreUndeclaredParameters,
                         maxApplyDepth,
                         tcldom_xpathFuncCallBack,  interp,
                         tcldom_xsltMsgCB, &xsltMsgInfo,
                         &errMsg, &resultDoc);

    if (result < 0) {
        SetResult( errMsg );
        FREE(errMsg);
        if (objc == 2) {
            Tcl_SetVar (interp, Tcl_GetString(objv[1]), "", 0);
        }
        goto applyXSLTCleanUP;
    }
    if (parameters) {
        Tcl_DecrRefCount(localListPtr);
        FREE((char *) parameters);
    }
    if (xsltMsgInfo.msgcmd) {
        Tcl_DecrRefCount(xsltMsgInfo.msgcmd);
    }
    return tcldom_returnDocumentObj(interp, resultDoc, (objc == 2),
                                    (objc == 2) ? objv[1] : NULL, 1, 0);
            
 applyXSLTCleanUP:
    if (localListPtr) {
        Tcl_DecrRefCount(localListPtr);
        FREE((char *) parameters);
    }
    if (xsltMsgInfo.msgcmd) {
................................................................................
|   tcldom_XSLTObjCmd
|
\---------------------------------------------------------------------------*/
static int tcldom_XSLTObjCmd (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *const objv[]
)
{
    int          index;
    char        *errMsg = NULL;
    
    static const char *options[] = {
        "transform", "delete", NULL
    };
    enum option {
        m_transform, m_delete
    };
    

................................................................................
|   tcldom_NodeObjCmd
|
\---------------------------------------------------------------------------*/
int tcldom_NodeObjCmd (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *const objv[]
)
{
    GetTcldomTSD()

    domNode     *node, *child, *refChild, *oldChild, *refNode;
    domNS       *ns;
    domAttrNode *attrs;
    domException exception;
    char         tmp[200], prefix[MAX_PREFIX_LEN], *method, *nodeName,
                 *str, *attr_name, *attr_val, *filter;

    const char  *localName, *uri, *nsStr;
    int          result, length, methodIndex, i, line, column;
    int          nsIndex, bool, hnew, legacy, jsonType, fromToken = 0;
    Tcl_Obj     *namePtr, *resultPtr;
    Tcl_Obj     *mobjv[MAX_REWRITE_ARGS];
    Tcl_CmdInfo  cmdInfo;
    Tcl_HashEntry *h;

    static const char *nodeMethods[] = {
        "firstChild",      "nextSibling",    "getAttribute",    "nodeName",
        "nodeValue",       "nodeType",       "attributes",      "asList",
        "find",            "setAttribute",   "removeAttribute", "parentNode",
        "previousSibling", "lastChild",      "appendChild",     "removeChild",
        "hasChildNodes",   "localName",      "childNodes",      "ownerDocument",
        "insertBefore",    "replaceChild",   "getLine",         "getColumn",
        "asXML",           "appendFromList", "child",           "fsibling",
................................................................................
        "target",          "data",           "selectNodes",     "namespaceURI",
        "getAttributeNS",  "setAttributeNS", "hasAttributeNS",  "removeAttributeNS",
        "asHTML",          "prefix",         "getBaseURI",      "appendFromScript",
        "xslt",            "toXPath",        "delete",          "getElementById",
        "getElementsByTagName",              "getElementsByTagNameNS",
        "disableOutputEscaping",             "precedes",         "asText",
        "insertBeforeFromScript",            "normalize",        "baseURI",
        "asJSON",          "jsonType",       "attributeNames",
#ifdef TCL_THREADS
        "readlock",        "writelock",
#endif
        NULL
    };
    enum nodeMethod {
        m_firstChild,      m_nextSibling,    m_getAttribute,    m_nodeName,
................................................................................
        m_root,            m_hasAttribute,   m_cloneNode,       m_appendXML,
        m_target,          m_data,           m_selectNodes,     m_namespaceURI,
        m_getAttributeNS,  m_setAttributeNS, m_hasAttributeNS,  m_removeAttributeNS,
        m_asHTML,          m_prefix,         m_getBaseURI,      m_appendFromScript,
        m_xslt,            m_toXPath,        m_delete,          m_getElementById,
        m_getElementsByTagName,              m_getElementsByTagNameNS,
        m_disableOutputEscaping,             m_precedes,        m_asText,
        m_insertBeforeFromScript,            m_normalize,       m_baseURI,
        m_asJSON,          m_jsonType,       m_attributeNames
#ifdef TCL_THREADS
        ,m_readlock,       m_writelock
#endif
    };


    node = (domNode*) clientData;
    if (TSD(domCreateCmdMode) == DOM_CREATECMDMODE_AUTO) {
        TSD(dontCreateObjCommands) = 0;
    }
    if (node == NULL) {
        if (objc < 3) {
            SetResult(node_usage);
            return TCL_ERROR;
        }
        if (TSD(domCreateCmdMode) == DOM_CREATECMDMODE_AUTO) {
            TSD(dontCreateObjCommands) = 1;
        }

        node = tcldom_getNodeFromObj(interp, objv[1]);
        if (node == NULL) {

            return TCL_ERROR;
        }
        fromToken = 1;
        objc--;
        objv++;
    }
    if (objc < 2) {
        SetResult(node_usage);
        return TCL_ERROR;
    }
................................................................................
    /*----------------------------------------------------------------------
    |   dispatch the node object method
    |
    \---------------------------------------------------------------------*/
    switch ((enum nodeMethod)methodIndex) {

        case m_toXPath:
            CheckArgs(2,3,2,"?-legacy?");
            legacy = 0;
            if (objc == 3) {
                if (!strcmp(Tcl_GetString(objv[2]), "-legacy")) {
                    legacy = 1;
                } else {
                    SetResult("unknown option! Options: ?-legacy?");
                    return TCL_ERROR;
                }
            }
            str = xpathNodeToXPath(node, legacy);
            SetResult (str);
            FREE (str);
            return TCL_OK;

        case m_xslt:
            CheckArgs(3,9,2, "?-parameters parameterList? "
                      "?-ignoreUndeclaredParameters? ?-xsltmessagecmd cmd? "
................................................................................
        case m_selectNodes:
            return tcldom_selectNodes (interp, node, --objc, ++objv);

        case m_find:
            CheckArgs(4,5,2,"attrName attrVal ?nodeObjVar?");
            attr_name = Tcl_GetStringFromObj(objv[2], NULL);
            attr_val  = Tcl_GetStringFromObj(objv[3], &length);
            return tcldom_setInterpAndReturnVar
                (interp, tcldom_find(node, attr_name, attr_val, length),
                 (objc == 5), (objc == 5) ? objv[4] : NULL);

        case m_child:
            CheckArgs(3,6,2,"instance|all ?type? ?attr value?");
            return tcldom_xpointerSearch(interp, XP_CHILD, node, objc, objv);

................................................................................
            return tcldom_xpointerSearch(interp, XP_PSIBLING, node,objc,objv);

        case m_root:
            CheckArgs(2,3,2,"?nodeObjVar?");
            while (node->parentNode) {
                node = node->parentNode;
            }
            return tcldom_setInterpAndReturnVar(interp, node, (objc == 3),
                                        (objc == 3) ? objv[2] : NULL);

        case m_text:
            CheckArgs(2,2,2,"");
            if (node->nodeType != ELEMENT_NODE) {
                SetResult("NOT_AN_ELEMENT");
                return TCL_ERROR;
................................................................................

        case m_attributes:
            CheckArgs(2,3,2,"?nameFilter?");
            if (node->nodeType != ELEMENT_NODE) {
                SetResult("");
                return TCL_OK;
            }
            filter = NULL;
            if (objc == 3) {
                filter = Tcl_GetString(objv[2]);


            }
            Tcl_ResetResult(interp);
            resultPtr = Tcl_GetObjResult(interp);

            attrs = node->firstAttr;
            while (attrs != NULL) {
                if (!filter || Tcl_StringMatch((char*)attrs->nodeName, filter)) {

                    if (attrs->namespace == 0) {
                        namePtr = Tcl_NewStringObj((char*)attrs->nodeName, -1);
                    } else {
                        domSplitQName((char*)attrs->nodeName, prefix, 
                                      &localName);
                        mobjv[0] = Tcl_NewStringObj((char*)localName, -1);
                        mobjv[1] = Tcl_NewStringObj(
................................................................................
                    }
                    result = Tcl_ListObjAppendElement(interp, resultPtr, 
                                                      namePtr);
                    if (result != TCL_OK) {
                        Tcl_DecrRefCount(namePtr);
                        return result;
                    }
                }
                attrs = attrs->nextSibling;
            }
            break;

        case m_attributeNames:
            CheckArgs(2,3,2,"?nameFilter?");
            if (node->nodeType != ELEMENT_NODE) {
                SetResult("");
                return TCL_OK;
            }
            filter = NULL;
            if (objc == 3) {
                filter = Tcl_GetString(objv[2]);
            }
            resultPtr = Tcl_GetObjResult(interp);

            attrs = node->firstAttr;
            while (attrs != NULL) {
                if (!filter || Tcl_StringMatch((char*)attrs->nodeName, filter)) {
                    namePtr = Tcl_NewStringObj((char*)attrs->nodeName, -1);
                    result = Tcl_ListObjAppendElement(interp, resultPtr, 
                                                      namePtr);
                    if (result != TCL_OK) {
                        Tcl_DecrRefCount(namePtr);
                        return result;
                    }
                }
                attrs = attrs->nextSibling;
            }
            break;

        case m_asList:
            CheckArgs(2,2,2,"");
................................................................................
        case m_asHTML:
            Tcl_ResetResult(interp);
            if (serializeAsHTML(node, interp, objc, objv) != TCL_OK) {
                return TCL_ERROR;
            }
            break;

        case m_asJSON:
            if (serializeAsJSON(node, interp, objc, objv) != TCL_OK) {
                return TCL_ERROR;
            }
            break;
            
        case m_getAttribute:
            CheckArgs(3,4,2,"attrName ?defaultValue?");
            if (node->nodeType != ELEMENT_NODE) {
                SetResult("NOT_AN_ELEMENT : there are no attributes");
                return TCL_ERROR;
            }
            attr_name = Tcl_GetString(objv[2]);
................................................................................
            for ( i = 2;  i < objc; ) {
                attr_name = Tcl_GetString(objv[i++]);
                CheckName (interp, attr_name, "attribute", 0);
                attr_val  = Tcl_GetString(objv[i++]);
                CheckText (interp, attr_val, "attribute");
                domSetAttribute(node, attr_name, attr_val);
            }
            return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);

        case m_setAttributeNS:
            if (node->nodeType != ELEMENT_NODE) {
                SetResult("NOT_AN_ELEMENT : there are no attributes");
                return TCL_ERROR;
            }
            if ((objc < 5) || (((objc - 2) % 3) != 0)) {
................................................................................
                        SetResult("For all prefixed attributes with prefixes "
                                  "other than 'xml' or 'xmlns' "
                                  "you have to provide a namespace URI");
                    }
                    return TCL_ERROR;
                }
            }
            return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);

        case m_hasAttribute:
            CheckArgs(3,3,2,"attrName");
            if (node->nodeType != ELEMENT_NODE) {		
                SetResult("NOT_AN_ELEMENT : there are no attributes");
                return TCL_ERROR;
            }
................................................................................
            result = domRemoveAttribute(node, attr_name);
            if (result) {
                SetResult("can't remove attribute '");
                AppendResult(attr_name);
                AppendResult("'");
                return TCL_ERROR;
            }
            return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);

        case m_removeAttributeNS:
            CheckArgs(4,4,2,"uri attrName");
            if (node->nodeType != ELEMENT_NODE) {		
                SetResult("NOT_AN_ELEMENT : there are no attributes");
                return TCL_ERROR;
            }
................................................................................
            result = domRemoveAttributeNS(node, uri, localName);
            if (result < 0) {
                SetResult("can't remove attribute with localName '");
                AppendResult(localName);
                AppendResult("'");
                return TCL_ERROR;
            }
            return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);

        case m_nextSibling:
            CheckArgs(2,3,2,"?nodeObjVar?");
            return tcldom_setInterpAndReturnVar(interp, node->nextSibling,
                                        (objc == 3), 
                                        (objc == 3) ? objv[2] : NULL);
        case m_previousSibling:
            CheckArgs(2,3,2,"?nodeObjVar?");
            return tcldom_setInterpAndReturnVar(interp, node->previousSibling,
                                        (objc == 3),
                                        (objc == 3) ? objv[2] : NULL);
        case m_firstChild:
            CheckArgs(2,3,2,"?nodeObjVar?");
            if (node->nodeType == ELEMENT_NODE) {
                return tcldom_setInterpAndReturnVar(interp, node->firstChild,
                                            (objc == 3),
                                            (objc == 3) ? objv[2] : NULL);
            }
            return tcldom_setInterpAndReturnVar(interp, NULL, (objc == 3),
                                        (objc == 3) ? objv[2] : NULL);
        case m_lastChild:
            CheckArgs(2,3,2,"?nodeObjVar?");
            if (node->nodeType == ELEMENT_NODE) {
                return tcldom_setInterpAndReturnVar(interp, node->lastChild,
                                            (objc == 3),
                                            (objc == 3) ? objv[2] : NULL);
            }
            return tcldom_setInterpAndReturnVar(interp, NULL, (objc == 3),
                                        (objc == 3) ? objv[2] : NULL);
        case m_parentNode:
            CheckArgs(2,3,2,"?nodeObjVar?");
            return tcldom_setInterpAndReturnVar(interp, node->parentNode, (objc == 3),
                                        (objc == 3) ? objv[2] : NULL);
        case m_appendFromList:
            CheckArgs(3,3,2,"list");
            return tcldom_appendFromTclList(interp, node, objv[2]);

        case m_appendFromScript:
            CheckArgs(3,3,2,"script");
            if (nodecmd_appendFromScript(interp, node, objv[2]) != TCL_OK) {
                return TCL_ERROR;
            }
            return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);

        case m_insertBeforeFromScript:
            CheckArgs(4,4,2, "script refChild");
            if (objv[3]->typePtr == &tdomNodeType) {
                refChild = objv[3]->internalRep.otherValuePtr;
            } else {
                nodeName = Tcl_GetString (objv[3]);
                if (nodeName[0] == '\0') {
                    refChild = NULL;
                } else {
                    refChild = tcldom_getNodeFromObj (interp, objv[3]);
                    if (refChild == NULL) {

                        return TCL_ERROR;
                    }
                }
            }
            if (nodecmd_insertBeforeFromScript(interp, node, objv[2], refChild)
                != TCL_OK) {
                return TCL_ERROR;
            }
            return tcldom_setInterpAndReturnVar (interp, node, 0, NULL);
            
        case m_appendXML:
            CheckArgs(3,3,2,"xmlString");
            return tcldom_appendXML(interp, node, objv[2]);

        case m_appendChild:
            CheckArgs(3,3,2,"nodeToAppend");

            child = tcldom_getNodeFromObj(interp, objv[2]);
            if (child == NULL) {

                return TCL_ERROR;
            }
            exception = domAppendChild (node, child);
            if (exception != OK) {
                SetResult(domException2String(exception));
                return TCL_ERROR;
            }
            return tcldom_setInterpAndReturnVar(interp, child, 0, NULL);

        case m_cloneNode:
            CheckArgs(2,3,2,"?-deep?");
            if (objc == 3) {
                if (!strcmp(Tcl_GetString(objv[2]), "-deep")) {
                    return tcldom_setInterpAndReturnVar(interp, domCloneNode(node, 1),
                                                0, NULL);
                }
                SetResult("unknown option! Options: ?-deep? ");
                return TCL_ERROR;
            }
            return tcldom_setInterpAndReturnVar(interp, domCloneNode(node, 0), 0, NULL);

        case m_removeChild:
            CheckArgs(3,3,2,"childToRemove");

            child = tcldom_getNodeFromObj(interp, objv[2]);
            if (child == NULL) {

                return TCL_ERROR;
            }
            exception = domRemoveChild (node, child);
            if (exception != OK) {
                SetResult (domException2String (exception));
                return TCL_ERROR;
            }
            return tcldom_setInterpAndReturnVar(interp, child, 0, NULL);

        case m_insertBefore:
            CheckArgs(4,4,2,"childToInsert refChild");

            child = tcldom_getNodeFromObj(interp, objv[2]);
            if (child == NULL) {

                return TCL_ERROR;
            }

            if (objv[3]->typePtr == &tdomNodeType) {
                refChild = objv[3]->internalRep.otherValuePtr;
            } else {
                nodeName = Tcl_GetString (objv[3]);
                if (nodeName[0] == '\0') {
                    refChild = NULL;
                } else {
                    refChild = tcldom_getNodeFromObj (interp, objv[3]);
                    if (refChild == NULL) {

                        return TCL_ERROR;
                    }
                }
            }
            exception = domInsertBefore(node, child, refChild);
            if (exception != OK) {
                SetResult(domException2String(exception));
                return TCL_ERROR;
            }
            return tcldom_setInterpAndReturnVar(interp, child, 0, NULL);

        case m_replaceChild:
            CheckArgs(4,4,2,"new old");

            child = tcldom_getNodeFromObj(interp, objv[2]);
            if (child == NULL) {

                return TCL_ERROR;
            }


            oldChild = tcldom_getNodeFromObj(interp, objv[3]);
            if (oldChild == NULL) {

                return TCL_ERROR;
            }
            exception = domReplaceChild(node, child, oldChild);
            if (exception != OK) {
                SetResult(domException2String(exception));
                return TCL_ERROR;
            }
            return tcldom_setInterpAndReturnVar(interp, oldChild, 0, NULL);

        case m_hasChildNodes:
            CheckArgs(2,2,2,"");
            if (node->nodeType == ELEMENT_NODE) {
                SetIntResult(node->firstChild ? 1 : 0);
            } else {
                SetIntResult(0);
................................................................................

        case m_childNodes:
            CheckArgs(2,2,2,"");
            resultPtr = Tcl_GetObjResult(interp);
            if (node->nodeType == ELEMENT_NODE) {
                child = node->firstChild;
                while (child != NULL) {
                    namePtr = tcldom_returnNodeObj(interp, child);

                    result  = Tcl_ListObjAppendElement(interp, resultPtr,
                                                       namePtr);
                    if (result != TCL_OK) {
                        Tcl_DecrRefCount(namePtr);
                        return result;
                    }
                    child = child->nextSibling;
................................................................................
                        }
                        nsIndex = node->ownerDocument->namespaces[i]->index;
                    }
                }
            }
            if (nsIndex == -1) {
                /* There isn't such a namespace declared in this document.
                   Since getElementsByTagNameNS doesn't raise an exception
                   short cut: return empty result */
                Tcl_ResetResult(interp);
                return TCL_OK;
            }
            return tcldom_getElementsByTagName(interp, str, node->firstChild,
                                                nsIndex, uri);
            
................................................................................
        case m_getElementById:
            CheckArgs(3,3,2,"id");
            if (node->ownerDocument->ids) {
                str = Tcl_GetString(objv[2]);
                h = Tcl_FindHashEntry(node->ownerDocument->ids, str);
                if (h) {
                    domNode *node = Tcl_GetHashValue(h);
                    return tcldom_setInterpAndReturnVar(interp, node, 0, NULL);
                }
            }
            SetResult("");
            return TCL_OK;

        case m_nodeName:
            CheckArgs(2,2,2,"");
................................................................................
                                 dpn->targetValue, dpn->targetLength);
            }
            break;

        case m_delete:
            CheckArgs(2,2,2,"");
            domDeleteNode(node, tcldom_deleteNode, interp);
            if (fromToken && (objv[0]->typePtr == &tdomNodeType)) {
                if (objv[0]->bytes) ckfree (objv[0]->bytes);
                objv[0]->typePtr = NULL;
                objv[0]->bytes = ckalloc((unsigned char) 1);
                objv[0]->bytes[0] = '\0';
                objv[0]->length = 0;
            }
            break;

        case m_data:
            CheckArgs(2,2,2,"");
            if (node->nodeType == PROCESSING_INSTRUCTION_NODE) {
                domProcessingInstructionNode *dpn;
                dpn = (domProcessingInstructionNode*)node;
................................................................................
                    node->nodeFlags &= (~DISABLE_OUTPUT_ESCAPING);
                }
            }
            break;

        case m_precedes:
            CheckArgs(3,3,2, "node");

            refNode = tcldom_getNodeFromObj(interp, objv[2]);
            if (refNode == NULL) {

                return TCL_ERROR;
            }
            if (node->ownerDocument != refNode->ownerDocument) {
                SetResult("Cannot compare the relative order of nodes "
                          "out of different documents.");
                return TCL_ERROR;
            }
................................................................................
                    SetResult("unknown option! Options: ?-forXPath?");
                    return TCL_ERROR;
                }
            }
            domNormalize (node, bool, tcldom_deleteNode, interp);
            return TCL_OK;

        case m_jsonType:
            CheckArgs (2,3,2, "?jsonType?");
            if (node->nodeType != ELEMENT_NODE
                && node->nodeType != TEXT_NODE) {
                SetResult("Only element and text nodes may have a JSON type.");
                return TCL_ERROR;
            }
            if (objc == 3) {
                if (Tcl_GetIndexFromObj (interp, objv[2], jsonTypes,
                                         "jsonType", 0, &jsonType)
                    != TCL_OK) {
                    return TCL_ERROR;
                }
                if (node->nodeType == ELEMENT_NODE) {
                    if (jsonType > 2) {
                        SetResult("For an element node the jsonType argument "
                                  "must be one out of this list: ARRAY OBJECT NONE.");
                        return TCL_ERROR;
                    }
                } else {
                    /* Text nodes */
                    if (jsonType < 3 && jsonType > 0) {
                        SetResult("For a text node the jsonType argument must be "
                                  "one out of this list: TRUE FALSE NULL NUMBER "
                                  "STRING NONE");
                        return TCL_ERROR;
                    }
                }
                node->info = jsonType;
                SetIntResult(jsonType);
                return TCL_OK;
            }
            if (node->info < 0 || node->info > 7) {
                SetResult(jsonTypes[0]);
            } else {
                SetResult(jsonTypes[node->info]);
            }
            return TCL_OK;
            
        TDomThreaded(
        case m_writelock:
            CheckArgs(3,3,2,"script");
            return tcldom_EvalLocked(interp, (Tcl_Obj**)objv, 
                                     node->ownerDocument, LOCK_WRITE);
        case m_readlock:
            CheckArgs(3,3,2,"script");
            return tcldom_EvalLocked(interp, (Tcl_Obj**)objv, 
                                     node->ownerDocument, LOCK_READ);
        )
    }
    return TCL_OK;}



/*----------------------------------------------------------------------------
|   tcldom_DocObjCmd
|
\---------------------------------------------------------------------------*/
int tcldom_DocObjCmd (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *const objv[]
)
{
    GetTcldomTSD()

    domDeleteInfo       * dinfo;
    domDocument         * doc;
    char                * method, *tag, *data, *target, *uri, tmp[100];
................................................................................
    int                   methodIndex, result, data_length, target_length, i;
    int                   nsIndex, forXPath, bool, setDocumentElement = 0;
    int                   restoreDomCreateCmdMode = 0;
    domNode             * n;
    Tcl_CmdInfo           cmdInfo;
    Tcl_Obj             * mobjv[MAX_REWRITE_ARGS];

    static const char *docMethods[] = {
        "documentElement", "getElementsByTagName",       "delete",
        "createElement",   "createCDATASection",         "createTextNode",
        "createComment",   "createProcessingInstruction",
        "createElementNS", "getDefaultOutputMethod",     "asXML",
        "asHTML",          "getElementsByTagNameNS",     "xslt", 
        "publicId",        "systemId",                   "internalSubset",
        "toXSLTcmd",       "asText",                     "normalize",
................................................................................
        "renameNode",      "deleteXPathCache", 
        /* The following methods will be dispatched to tcldom_NodeObjCmd */
        "getElementById",  "firstChild",                 "lastChild",
        "appendChild",     "removeChild",                "hasChildNodes",
        "childNodes",      "ownerDocument",              "insertBefore",
        "replaceChild",    "appendFromList",             "appendXML",
        "selectNodes",     "baseURI",                    "appendFromScript",
        "insertBeforeFromScript",                        "asJSON",
        "jsonType",
#ifdef TCL_THREADS
        "readlock",        "writelock",                  "renumber",
#endif
        NULL
    };
    enum docMethod {
        m_documentElement,  m_getElementsByTagName,       m_delete,
................................................................................
        m_renameNode,       m_deleteXPathCache,
        /* The following methods will be dispatched to tcldom_NodeObjCmd */
        m_getElementById,   m_firstChild,                 m_lastChild,
        m_appendChild,      m_removeChild,                m_hasChildNodes,
        m_childNodes,       m_ownerDocument,              m_insertBefore,
        m_replaceChild,     m_appendFromList,             m_appendXML,
        m_selectNodes,      m_baseURI,                    m_appendFromScript,
        m_insertBeforeFromScript,                         m_asJSON,
        m_jsonType
#ifdef TCL_THREADS
       ,m_readlock,         m_writelock,                  m_renumber
#endif
    };

    dinfo = (domDeleteInfo*)clientData;
    if (TSD(domCreateCmdMode) == DOM_CREATECMDMODE_AUTO) {
................................................................................
        mobjv[1] = objv[0];
        for (i = 2; i < objc; i++) {
            mobjv[i] = objv[i];
        }
        return cmdInfo.objProc(cmdInfo.objClientData, interp, objc, mobjv);
    }

    CheckArgs (2,10,1,doc_usage);
    Tcl_ResetResult (interp);

    /*----------------------------------------------------------------------
    |   dispatch the doc object method
    |
    \---------------------------------------------------------------------*/

    switch ((enum docMethod) methodIndex ) {

        case m_documentElement:
            CheckArgs(2,3,2,"");
            return tcldom_setInterpAndReturnVar(interp, doc->documentElement,
                                        (objc == 3), 
                                        (objc == 3) ? objv[2] : NULL);
        case m_getElementsByTagName:
            CheckArgs(3,3,2,"elementName");
            return tcldom_getElementsByTagName(interp, Tcl_GetString(objv[2]),
                                               doc->documentElement, -1, NULL);
        case m_getElementsByTagNameNS:
................................................................................
                        }
                        nsIndex = doc->namespaces[i]->index;
                    }
                }
            }
            if (nsIndex == -1) {
                /* There isn't such a namespace declared in this document.
                   Since getElementsByTagNameNS doesn't raise an exception
                   short cut: return empty result */
                return TCL_OK;
            }
            return tcldom_getElementsByTagName(interp, str,
                                               doc->documentElement, nsIndex,
                                               uri);
        case m_createElement:
            CheckArgs(3,4,2,"elementName ?newObjVar?");
            tag = Tcl_GetString(objv[2]);
            CheckName (interp, tag, "tag", 0);
            n = domNewElementNode(doc, tag);
            return tcldom_setInterpAndReturnVar(interp, n, (objc == 4),
                                        (objc == 4) ? objv[3] : NULL);

        case m_createElementNS:
            CheckArgs(4,5,2,"elementName uri ?newObjVar?");
            uri = Tcl_GetString(objv[2]);
            tag = Tcl_GetString(objv[3]);
            CheckName (interp, tag, "full qualified tag", 1);
            n = domNewElementNodeNS(doc, tag, uri);
            if (n == NULL) {
                SetResult("Missing URI in Namespace declaration");
                return TCL_ERROR;
            }
            return tcldom_setInterpAndReturnVar(interp, n, (objc == 5),
                                        (objc == 5) ? objv[4] : NULL);

        case m_createTextNode:
            CheckArgs(3,4,2,"data ?newObjVar?");
            data = Tcl_GetStringFromObj(objv[2], &data_length);
            CheckText (interp, data, "text");
            n = (domNode*)domNewTextNode(doc, data, data_length, TEXT_NODE);
            return tcldom_setInterpAndReturnVar(interp, n, (objc == 4),
                                        (objc == 4) ? objv[3] : NULL);

        case m_createCDATASection:
            CheckArgs(3,4,2,"data ?newObjVar?");
            data = Tcl_GetStringFromObj(objv[2], &data_length);
            CheckCDATA (interp, data);
            n = (domNode*)domNewTextNode(doc, data, data_length, 
                                         CDATA_SECTION_NODE);
            return tcldom_setInterpAndReturnVar(interp, n, (objc == 4),
                                        (objc == 4) ? objv[3] : NULL);

        case m_createComment:
            CheckArgs(3,4,2,"data ?newObjVar?");
            data = Tcl_GetStringFromObj(objv[2], &data_length);
            CheckComment(interp, data);
            n = (domNode*)domNewTextNode(doc, data, data_length, COMMENT_NODE);
            return tcldom_setInterpAndReturnVar(interp, n, (objc == 4),
                                        (objc == 4) ? objv[3] : NULL);

        case m_createProcessingInstruction:
            CheckArgs(4,5,2,"target data ?newObjVar?");
            target = Tcl_GetStringFromObj(objv[2], &target_length);
            CheckPIName (interp, target);
            data   = Tcl_GetStringFromObj(objv[3], &data_length);
            CheckPIValue (interp, data);
            n = (domNode*)domNewProcessingInstructionNode(doc, target, 
                                                          target_length, data, 
                                                          data_length);
            return tcldom_setInterpAndReturnVar(interp, n, (objc == 5),
                                        (objc == 5) ? objv[4] : NULL);

        case m_delete:
            CheckArgs(2,2,2,"");
            if (clientData != NULL || doc->nodeFlags & DOCUMENT_CMD) {
                Tcl_DeleteCommand(interp, Tcl_GetString (objv[0]));
            } else {
                tcldom_deleteDoc(interp, doc);
            }
            SetResult("");
            return TCL_OK;

................................................................................
        case m_firstChild:
        case m_lastChild:
        case m_hasChildNodes:
        case m_childNodes:
        case m_ownerDocument:
        case m_selectNodes:
        case m_baseURI:
        case m_asJSON:
        case m_jsonType:
        case m_getElementById:
            /* We dispatch the method call to tcldom_NodeObjCmd */
            if (TSD(domCreateCmdMode) == DOM_CREATECMDMODE_AUTO) {
                if (dinfo == NULL) {
                    /* tcldom_DocObjCmd was called with a doc token.
                       Since the domCreateCmdMode is 'automatic'
                       and we call tcldom_DocObjCmd with the root node
................................................................................
    Tcl_Obj    * const objv[]
)
{
    int          setVariable = 0;
    domDocument *doc;
    Tcl_Obj     *newObjName = NULL;

    GetTcldomTSD()

    CheckArgs(2,3,1,"docElemName ?newObjVar?");

    if (objc == 3) {
        newObjName = objv[2];
        setVariable = 1;
    }

    CheckName(interp, Tcl_GetString(objv[1]), "root element", 0);
    doc = domCreateDocument(NULL, Tcl_GetString(objv[1]));



    return tcldom_returnDocumentObj(interp, doc, setVariable, newObjName, 1,
                                    0);
}

/*----------------------------------------------------------------------------
|   tcldom_createDocumentNode
|
................................................................................
int tcldom_createDocumentNode (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    * const objv[]
)
{
    int          setVariable = 0, jsonType = 0, index;
    domDocument *doc;
    Tcl_Obj     *newObjName = NULL;

    static const char *options[] = {"-jsonType", NULL};
    

    CheckArgs(1,4,1,"?-jsonType jsonType? ?newObjVar?");

    if (objc == 2) {
        newObjName = objv[1];
        setVariable = 1;
    }
    if (objc > 2) {
        if (Tcl_GetIndexFromObj(interp, objv[1], options, "option",
                                0, &index) != TCL_OK) {
            return TCL_ERROR;
        }
        Tcl_ResetResult(interp);
            if (Tcl_GetIndexFromObj(interp, objv[2], jsonTypes, "jsonType",
                                0, &jsonType) != TCL_OK) {
            return TCL_ERROR;
        }
        if (objc == 4) {
            newObjName = objv[3];
            setVariable = 1;
        }
    }

    doc = domCreateDoc(NULL, 0);
    doc->rootNode->info = jsonType;
    
    return tcldom_returnDocumentObj(interp, doc, setVariable, newObjName, 1,
                                    0);
}

/*----------------------------------------------------------------------------
|   tcldom_createDocumentNS
|
................................................................................
int tcldom_createDocumentNS (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    * const objv[]
)
{
    int          setVariable = 0, len;
    char        *uri;
    domDocument *doc;
    Tcl_Obj     *newObjName = NULL;

    GetTcldomTSD()

    CheckArgs(3,4,1,"uri docElemName ?newObjVar?");

    if (objc == 4) {
        newObjName = objv[3];
        setVariable = 1;
    }

    CheckName(interp, Tcl_GetString(objv[2]), "root element", 1);
    uri = Tcl_GetStringFromObj (objv[1], &len);
    if (len == 0) {
        if (!TSD(dontCheckName)) {
            if (!domIsNCNAME (Tcl_GetString(objv[2]))) {

                SetResult ("Missing URI in Namespace declaration");
                return TCL_ERROR;
            }
        }


























        doc = domCreateDocument (NULL, Tcl_GetString(objv[2]));
    } else {




        doc = domCreateDocument (uri, Tcl_GetString(objv[2]));




    }






    return tcldom_returnDocumentObj (interp, doc, setVariable, newObjName, 1,
                                    0);
}






/*----------------------------------------------------------------------------
|   tcldom_parse
|
\---------------------------------------------------------------------------*/
static
int tcldom_parse (
................................................................................
    int         objc,
    Tcl_Obj    * const objv[]
)
{
    GetTcldomTSD()

    char        *xml_string, *option, *errStr, *channelId, *baseURI = NULL;
    char        *jsonRoot = NULL;
    Tcl_Obj     *extResolver = NULL;
    Tcl_Obj     *feedbackCmd = NULL;
    const char  *interpResult;
    int          optionIndex, value, xml_string_len, mode;
    int          jsonmaxnesting = JSON_MAX_NESTING;
    int          ignoreWhiteSpaces   = 1;
    int          takeJSONParser      = 0;
    int          takeSimpleParser    = 0;
    int          takeHTMLParser      = 0;
    int          takeGUMBOParser     = 0;
    int          setVariable         = 0;
    int          ignorexmlns         = 0;
    int          feedbackAfter       = 0;
    int          useForeignDTD       = 0;
    int          paramEntityParsing  = (int)XML_PARAM_ENTITY_PARSING_ALWAYS;
    int          keepCDATA           = 0;
    int          status              = 0;
    domDocument *doc;
    Tcl_Obj     *newObjName = NULL;
    XML_Parser   parser;
    Tcl_Channel  chan = (Tcl_Channel) NULL;
    Tcl_CmdInfo  cmdInfo;

    static const char *parseOptions[] = {
        "-keepEmpties",           "-simple",        "-html",
        "-feedbackAfter",         "-channel",       "-baseurl",
        "-externalentitycommand", "-useForeignDTD", "-paramentityparsing",

        "-feedbackcmd",           "-json",          "-jsonroot",
#ifdef TDOM_HAVE_GUMBO
        "-html5",
#endif
        "-jsonmaxnesting",        "-ignorexmlns",   "--",
        "-keepCDATA",                NULL
    };
    enum parseOption {
        o_keepEmpties,            o_simple,         o_html,
        o_feedbackAfter,          o_channel,        o_baseurl,
        o_externalentitycommand,  o_useForeignDTD,  o_paramentityparsing,
        o_feedbackcmd,            o_json,           o_jsonroot,
#ifdef TDOM_HAVE_GUMBO
        o_htmlfive,
#endif
        o_jsonmaxnesting,         o_ignorexmlns,    o_LAST,
        o_keepCDATA
    };

    static const char *paramEntityParsingValues[] = {
        "always",
        "never",
        "notstandalone",
        (char *) NULL
    };
    enum paramEntityParsingValue {
        EXPAT_PARAMENTITYPARSINGALWAYS,
        EXPAT_PARAMENTITYPARSINGNEVER,
        EXPAT_PARAMENTITYPARSINGNOTSTANDALONE
    };

    while (objc > 1) {
        option = Tcl_GetString(objv[1]);
        if (option[0] != '-') {
            break;
        }
        if (Tcl_GetIndexFromObj(interp, objv[1], parseOptions, "option", 0,
                                 &optionIndex) != TCL_OK) {
................................................................................

        switch ((enum parseOption) optionIndex) {

        case o_keepEmpties:
            ignoreWhiteSpaces = 0;
            objv++;  objc--; continue;

        case o_json:
            if (takeGUMBOParser || takeHTMLParser) {
                SetResult("The options -html, -html5 and -json are "
                          "mutually exclusive.");
                return TCL_ERROR;
            }
            takeJSONParser = 1;
            objv++;  objc--; continue;
            
        case o_jsonroot:
            objv++; objc--;
            if (objc > 1) {
                jsonRoot = Tcl_GetString(objv[1]);
            } else {
                SetResult("The \"dom parse\" option \"-jsonroot\" "
                          "expects the document element name of the "
                          "DOM tree to create as argument.");
                return TCL_ERROR;
            }
            if (!domIsNAME(jsonRoot)) {
                SetResult("-jsonroot value: not a valid element name");
                return TCL_ERROR;
            }
            objv++; objc--; continue;
            
        case o_simple:
            takeSimpleParser = 1;
            objv++;  objc--; continue;

        case o_html:
            if (takeGUMBOParser || takeJSONParser) {
                SetResult("The options -html, -html5 and -json are "
                          "mutually exclusive.");
                return TCL_ERROR;
            }
            takeSimpleParser = 1;
            takeHTMLParser = 1;
            objv++;  objc--; continue;

#ifdef TDOM_HAVE_GUMBO
        case o_htmlfive:
            if (takeHTMLParser || takeJSONParser) {
                SetResult("The options -html, -html5 and -json are "
                          "mutually exclusive.");
                return TCL_ERROR;
            }
            takeGUMBOParser = 1;
            objv++;  objc--; continue;
#endif
            
        case o_feedbackAfter:
            objv++; objc--;
            if (objc > 1) {
                if (Tcl_GetIntFromObj(interp, objv[1], &feedbackAfter)
                    != TCL_OK) {
                    SetResult("-feedbackAfter must have an integer argument");
                    return TCL_ERROR;
                }
            } else {
                SetResult("The \"dom parse\" option \"-feedbackAfter\" requires"
                          " a positive integer as argument.");
                return TCL_ERROR;
            }
            if (feedbackAfter <= 0) {
                SetResult("The \"dom parse\" option \"-feedbackAfter\" requires"
                          " a positive integer as argument.");
                return TCL_ERROR;
            }                
            objv++; objc--;
            continue;

        case o_channel:
            objv++; objc--;
            if (objc > 1) {
                channelId = Tcl_GetString(objv[1]);
            } else {
                SetResult("The \"dom parse\" option \"-channel\" "
                          "requires a Tcl channel as argument.");
                return TCL_ERROR;
            }
            chan = Tcl_GetChannel(interp, channelId, &mode);
            if (chan == (Tcl_Channel) NULL) {
                return TCL_ERROR;
            }
            if ((mode & TCL_READABLE) == 0) {
................................................................................
            }
            objv++; objc--;
            continue;

        case o_externalentitycommand:
            objv++; objc--;
            if (objc > 1) {
                extResolver = objv[1];
            } else {
                SetResult("The \"dom parse\" option \"-externalentitycommand\" "
                          "requires a script as argument.");
                return TCL_ERROR;
            }
            objv++; objc--;
            continue;
................................................................................
                SetResult("-paramEntityParsing requires 'always', 'never' "
                          "or 'notstandalone' as argument");
                return TCL_ERROR;
            }
            objv++; objc--;
            objv++; objc--;
            continue;

        case o_feedbackcmd:
            objv++; objc--;
            if (objc > 1) {
                feedbackCmd = objv[1];
            } else {
                SetResult("The \"dom parse\" option \"-feedbackcmd\" "
                          "requires a script as argument.");
                return TCL_ERROR;
            }
            objv++; objc--;
            continue;
            
        case o_ignorexmlns:
            ignorexmlns = 1;
            objv++;  objc--; continue;

        case o_jsonmaxnesting:
            objv++; objc--;
            if (objc < 2) {
                SetResult("The \"dom parse\" option \"-jsonmaxnesting\" "
                          "requires an integer as argument.");
                return TCL_ERROR;
            }
            if (Tcl_GetIntFromObj(interp, objv[1], &jsonmaxnesting)
                != TCL_OK) {
                SetResult("-jsonmaxnesting must have an integer argument");
                return TCL_ERROR;
            }
            if (jsonmaxnesting < 0) {
                SetResult("The value of -jsonmaxnesting cannot be negativ");
                return TCL_ERROR;
            }
            objv++;  objc--; continue;
                        
        case o_LAST:
            objv++;  objc--; break;
            
        case o_keepCDATA:
            keepCDATA = 1;
            objv++;  objc--; break;
            
        }
        if ((enum parseOption) optionIndex == o_LAST) break;
    }

    if (feedbackAfter && !feedbackCmd) {
        if (!Tcl_GetCommandInfo(interp, "::dom::domParseFeedback", 
                                &cmdInfo)) {
            SetResult("If -feedbackAfter is used, "
                      "-feedbackcmd must also be used.");
            return TCL_ERROR;
        }
    }
    if (chan == NULL) {
        if (objc < 2) {
            SetResult(dom_usage);
            return TCL_ERROR;
        }
        xml_string = Tcl_GetStringFromObj( objv[1], &xml_string_len);
        if (objc == 3) {
................................................................................
    } else {
        if (objc > 2) {
            SetResult(dom_usage);
            return TCL_ERROR;
        }
        xml_string = NULL;
        xml_string_len = 0;
        if (takeSimpleParser || takeHTMLParser || takeJSONParser
#ifdef TDOM_HAVE_GUMBO
                || takeGUMBOParser
#endif
            ) {
            Tcl_AppendResult(interp, "simple, JSON or HTML parser(s) "
                             " don't support channel reading", NULL);
            return TCL_ERROR;
        }
        if (objc == 2) {
            newObjName = objv[1];
            setVariable = 1;
        }
    }

#ifdef TDOM_HAVE_GUMBO
    if (takeGUMBOParser) {
        doc = HTML_GumboParseDocument(xml_string, ignoreWhiteSpaces,
                                      ignorexmlns);
        return tcldom_returnDocumentObj (interp, doc, setVariable, newObjName,
                                         1, 0);
    }
#endif
    
    if (takeJSONParser) {
        char s[50];
        int byteIndex, i;

        errStr = NULL;

        doc = JSON_Parse (xml_string, jsonRoot, jsonmaxnesting, &errStr,
                          &byteIndex);
        if (doc) {
            return tcldom_returnDocumentObj (interp, doc, setVariable,
                                             newObjName, 1, 0);
        } else {
            Tcl_ResetResult(interp);
            sprintf(s, "%d", byteIndex);
            Tcl_AppendResult(interp, "error \"", errStr, "\" at position ", 
                             s, NULL);
            Tcl_AppendResult(interp, "\n\"", NULL);
            s[1] = '\0';
            for (i=-20; i < 40; i++) {
                if (byteIndex+i>=0) {
                    if (xml_string[byteIndex+i]) {
                        s[0] = xml_string[byteIndex+i];
                        Tcl_AppendResult(interp, s, NULL);
                        if (i==0) {
                            Tcl_AppendResult(interp, " <--Error-- ", NULL);
                        }
                    } else {
                        break;
                    }
                }
            }
            Tcl_AppendResult(interp, "\"",NULL);
            return TCL_ERROR;
        }
    }
    
    if (takeSimpleParser) {
        char s[50];
        int  byteIndex, i;

        errStr = NULL;

        if (takeHTMLParser) {
            doc = HTML_SimpleParseDocument(xml_string, ignoreWhiteSpaces,
                                           &byteIndex, &errStr);
        } else {
            doc = XML_SimpleParseDocument(xml_string, ignoreWhiteSpaces,
                                          keepCDATA,
                                          baseURI, extResolver,
                                          &byteIndex, &errStr);
        }
        if (errStr != NULL) {
            domFreeDocument (doc, NULL, interp);

            Tcl_ResetResult(interp);
................................................................................
#else
    parser = XML_ParserCreate_MM(NULL, MEM_SUITE, NULL);
    Tcl_ResetResult(interp);

    doc = domReadDocument(parser, xml_string,
                          xml_string_len,
                          ignoreWhiteSpaces,
                          keepCDATA,
                          TSD(storeLineColumn),
                          ignorexmlns,
                          feedbackAfter,
                          feedbackCmd,
                          chan,
                          baseURI,
                          extResolver,
                          useForeignDTD,
                          paramEntityParsing,
                          interp,
                          &status);
    if (doc == NULL) {
        char s[50];
        long byteIndex, i;
        
        switch (status) {
        case TCL_BREAK:
            /* Abort of parsing by the application */
            Tcl_ResetResult(interp);
            XML_ParserFree(parser);
            return TCL_OK;
        default:
            interpResult = Tcl_GetStringResult(interp);
            sprintf(s, "%ld", XML_GetCurrentLineNumber(parser));
            if (interpResult[0] == '\0') {
                /* If the interp result isn't empty, then there was an error
                   in an enternal entity and the interp result has already the
                   error msg. If we don't got a document, but interp result is
                   empty, the error occurred in the main document and we
                   build the error msg as follows. */

                Tcl_AppendResult(interp, "error \"", 
                                 XML_ErrorString(XML_GetErrorCode(parser)),
                                 "\" at line ", s, " character ", NULL);
                sprintf(s, "%ld", XML_GetCurrentColumnNumber(parser));
                Tcl_AppendResult(interp, s, NULL);
                byteIndex = XML_GetCurrentByteIndex(parser);
                if ((byteIndex != -1) && (chan == NULL)) {
                    Tcl_AppendResult(interp, "\n\"", NULL);
                    s[1] = '\0';
                    for (i=-20; i < 40; i++) {
                        if ((byteIndex+i)>=0) {
                            if (xml_string[byteIndex+i]) {
                                s[0] = xml_string[byteIndex+i];
                                Tcl_AppendResult(interp, s, NULL);
                                if (i==0) {
                                    Tcl_AppendResult(interp, " <--Error-- ", NULL);
                                }
                            } else {
                                break;
                            }
                        }
                    }
                    Tcl_AppendResult(interp, "\"",NULL);
                }
            } else {
                if (status == TCL_OK) {
                    /* For Tcl errors (in -externalentitycommand or
                     * feedback callback) we leave the error msg in
                     * the interpreter alone. If there wasn't a Tcl
                     * error, there was a parsing error. Because the
                     * interp has already an error msg, that parsing
                     * error was in an external entity. Therefore, we
                     * just add the place of the referencing entity in
                     * the mail document.*/
                    Tcl_AppendResult(interp, ", referenced at line ", s, NULL);
                    sprintf(s, "%ld", XML_GetCurrentColumnNumber(parser));
                    Tcl_AppendResult(interp, " character ", s, NULL);
                }
            }
            XML_ParserFree(parser);
            return TCL_ERROR;
        }
    }
    XML_ParserFree(parser);

    return tcldom_returnDocumentObj (interp, doc, setVariable, newObjName, 1,
                                     0);
#endif

}

/*----------------------------------------------------------------------------
|   tcldom_featureinfo
|
\---------------------------------------------------------------------------*/
static
int tcldom_featureinfo (
    ClientData  clientData,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    * const objv[]
)
{
    int featureIndex, result;
    
    static const char *features[] = {
        "expatversion",      "expatmajorversion",  "expatminorversion",
        "expatmicroversion", "dtd",                "ns",
        "unknown",           "tdomalloc",          "lessns",
        "html5",             "jsonmaxnesting",     "versionhash",
        "pullparser",        "TCL_UTF_MAX",        NULL
    };
    enum feature {
        o_expatversion,      o_expatmajorversion,  o_expatminorversion,
        o_expatmicroversion, o_dtd,                o_ns,
        o_unknown,           o_tdomalloc,          o_lessns,
        o_html5,             o_jsonmaxnesting,     o_versionhash,
        o_pullparser,        o_TCL_UTF_MAX,
    };

    if (Tcl_GetIndexFromObj(interp, objv[1], features, "feature", 0,
                            &featureIndex) != TCL_OK) {
        return TCL_ERROR;
    }

    switch ((enum feature) featureIndex) {
    case o_expatversion:
        SetResult(XML_ExpatVersion());
        break;
    case o_expatmajorversion:
        SetIntResult(XML_MAJOR_VERSION);
        break;
    case o_expatminorversion:
        SetIntResult(XML_MINOR_VERSION);
        break;
    case o_expatmicroversion:
        SetIntResult(XML_MICRO_VERSION);
        break;
    case o_dtd:
#ifdef XML_DTD
        result = 1;
#else
        result = 0;
#endif
        SetBooleanResult(result);
        break;
    case o_ns:
#ifdef XML_NS
        result = 1;
#else
        result = 0;
#endif
        SetBooleanResult(result);
        break;
    case o_unknown:       
#ifdef TDOM_NO_UNKNOWN_CMD
        result = 0;
#else
        result = 1;
#endif
        SetBooleanResult(result);
        break;
    case o_tdomalloc:
#ifdef USE_NORMAL_ALLOCATOR
        result = 0;
#else
        result = 1;
#endif
        SetBooleanResult(result);
        break;
    case o_lessns:
#ifdef TDOM_LESS_NS
        result = 1;
#else
        result = 0;
#endif
        SetBooleanResult(result);
        break;
    case o_html5:
#ifdef TDOM_HAVE_GUMBO
        result = 1;
#else
        result = 0;
#endif
        SetBooleanResult(result);
        break;
    case o_jsonmaxnesting:
        SetIntResult(JSON_MAX_NESTING);
        break;

    case o_versionhash:
        SetResult(FOSSIL_HASH);
        break;
    case o_pullparser:
#ifndef TDOM_NO_PULL
        result = 1;
#else
        result = 0;
#endif
        SetBooleanResult(result);
        break;
    case o_TCL_UTF_MAX:
        SetIntResult(TCL_UTF_MAX);
        break;
    }
    return TCL_OK;
}

/*----------------------------------------------------------------------------
|   tcldom_DomObjCmd
|
\---------------------------------------------------------------------------*/
int tcldom_DomObjCmd (
    ClientData   clientData,
    Tcl_Interp * interp,
    int          objc,
    Tcl_Obj    * const objv[]
)
{
    GetTcldomTSD()

    char        * method, tmp[300];
    int           methodIndex, result, i, bool;
    Tcl_CmdInfo   cmdInfo;
    Tcl_Obj     * mobjv[MAX_REWRITE_ARGS];

    static const char *domMethods[] = {
        "createDocument",  "createDocumentNS",   "createNodeCmd",
        "parse",                                 "setStoreLineColumn",
        "isCharData",      "isName",             "isPIName",
        "isQName",         "isComment",          "isCDATA",
        "isPIValue",       "isNCName",           "createDocumentNode",
        "setNameCheck",    "setTextCheck",       "setObjectCommands",
        "featureinfo",     "isBMPCharData",
#ifdef TCL_THREADS
        "attachDocument",  "detachDocument",
#endif
        NULL
    };
    enum domMethod {
        m_createDocument,    m_createDocumentNS,   m_createNodeCmd,
        m_parse,                                   m_setStoreLineColumn,
        m_isCharData,        m_isName,             m_isPIName,
        m_isQName,           m_isComment,          m_isCDATA,
        m_isPIValue,         m_isNCName,           m_createDocumentNode,
        m_setNameCheck,      m_setTextCheck,       m_setObjectCommands,
        m_featureinfo,       m_isBMPCharData
#ifdef TCL_THREADS
        ,m_attachDocument,   m_detachDocument
#endif
    };

    static const char *nodeModeValues[] = {
        "automatic", "command", "token", NULL
    };
    enum nodeModeValue {
        v_automatic, v_command, v_token
    };

    if (objc < 2) {
................................................................................
    method = Tcl_GetString(objv[1]);
    if (Tcl_GetIndexFromObj(NULL, objv[1], domMethods, "method", 0,
                            &methodIndex) != TCL_OK) {
        /*--------------------------------------------------------
        |   try to find method implemented as normal Tcl proc
        \-------------------------------------------------------*/
        if ((strlen(method)-1) >= 270) {
            SetResult("method name too long!");
            return TCL_ERROR;
        }
        sprintf(tmp, "::dom::DOMImplementation::%s", method);
        DBG(fprintf(stderr, "testing %s\n", tmp));
        result = Tcl_GetCommandInfo(interp, tmp, &cmdInfo);
        if (!result) {
            SetResult(dom_usage);
................................................................................
                }
                SetResult("");
                return TCL_OK;
            }
            break;
#endif




        case m_setStoreLineColumn:
            if (objc == 3) {
                if (Tcl_GetBooleanFromObj(interp, objv[2], &bool) != TCL_OK) {
                    return TCL_ERROR;
                }
                TSD(storeLineColumn) = bool;
            }
................................................................................
            return TCL_OK;
            
        case m_isNCName:
            CheckArgs(3,3,2,"string");
            SetBooleanResult(domIsNCNAME(Tcl_GetString(objv[2])));
            return TCL_OK;

        case m_featureinfo:
            CheckArgs(3,3,2,"feature")
            return tcldom_featureinfo(clientData, interp, --objc, objv+1);

        case m_isBMPCharData:
            CheckArgs(3,3,2,"string");
            SetBooleanResult(domIsBMPChar(Tcl_GetString(objv[2])));
            return TCL_OK;
                
    }
    SetResult( dom_usage);
    return TCL_ERROR;
}

#ifdef TCL_THREADS

................................................................................
int tcldom_EvalLocked (
    Tcl_Interp  * interp, 
    Tcl_Obj    ** objv, 
    domDocument * doc,
    int          flag
)
{
    int ret;
    domlock *dl = doc->lock;

    domLocksLock(dl, flag);

    Tcl_AllowExceptions(interp);
    ret = Tcl_EvalObjEx(interp, objv[2], 0);
    if (ret == TCL_ERROR) {
        char msg[64 + TCL_INTEGER_SPACE];
        sprintf(msg, "\n    (\"%s %s\" body line %d)", Tcl_GetString(objv[0]),
                Tcl_GetString(objv[1]), Tcl_GetErrorLine(interp));
        Tcl_AddErrorInfo(interp, msg);
    }

    domLocksUnlock(dl);

    return (ret == TCL_BREAK) ? TCL_OK : ret;
}
................................................................................

static
int tcldom_RegisterDocShared (
    domDocument * doc
)
{
    Tcl_HashEntry *entryPtr;
    int newEntry = 0;
#ifdef DEBUG    
    int refCount;
#endif

    Tcl_MutexLock(&tableMutex);
#ifdef DEBUG    
    refCount = ++doc->refCount;
#else
    ++doc->refCount;
#endif
    entryPtr = Tcl_CreateHashEntry(&sharedDocs, (char*)doc, &newEntry);
    if (newEntry) {
        Tcl_SetHashValue(entryPtr, (ClientData)doc);
    }
    Tcl_MutexUnlock(&tableMutex);

    DBG(fprintf(stderr, "--> tcldom_RegisterDocShared: doc %p %s "
................................................................................
    Tcl_MutexLock(&tableMutex);
    if (doc->refCount > 1) {
        tcldom_deleteNode(doc->rootNode, interp);
        domFreeNode(doc->rootNode, tcldom_deleteNode, interp, 1);
        doc->refCount--;
        deleted = 0;
    } else {
        if (tcldomInitialized) {
            Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&sharedDocs, (char*)doc);
            if (entryPtr) {
                Tcl_DeleteHashEntry(entryPtr);
                deleted = 1;
            } else {
                deleted = 0;
            }
        } else {
            deleted = 0;
        }
    }
    Tcl_MutexUnlock(&tableMutex);

    DBG(fprintf(stderr, "--> tcldom_UnregisterDocShared: doc %p %s "
................................................................................
)
{
    Tcl_HashEntry *entryPtr;
    domDocument *tabDoc = NULL;
    int found = 0;

    Tcl_MutexLock(&tableMutex);
    if (tcldomInitialized) {
        entryPtr = Tcl_FindHashEntry(&sharedDocs, (char*)doc);
        if (entryPtr == NULL) {
            found = 0;
        } else {
            tabDoc = (domDocument*)Tcl_GetHashValue(entryPtr);
            found  = tabDoc ? 1 : 0;
        }
    }
    Tcl_MutexUnlock(&tableMutex);

    if (found && doc != tabDoc) {
        Tcl_Panic("document mismatch; doc=%p, in table=%p\n", (void *)doc,
                  (void *)tabDoc);
    }

    return found;
}

#endif /* TCL_THREADS */

................................................................................
|   tcldom_unknownCmd
|
\---------------------------------------------------------------------------*/
int tcldom_unknownCmd (
    ClientData   clientData,
    Tcl_Interp * interp,
    int          objc,
    Tcl_Obj    * const objv[]
)
{
    int          len, i, rc, openedParen, count, args;
    char        *cmd, *dot, *paren, *arg[MAX_REWRITE_ARGS], *object, *method;
    Tcl_DString  callString;
    Tcl_CmdInfo  cmdInfo;
    Tcl_Obj     *vector[2+MAX_REWRITE_ARGS];

Changes to generic/tcldom.h.

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Tcl_ObjCmdProc tcldom_DomObjCmd;
Tcl_ObjCmdProc tcldom_DocObjCmd;
Tcl_ObjCmdProc tcldom_NodeObjCmd;
Tcl_ObjCmdProc TclExpatObjCmd;
Tcl_ObjCmdProc tcldom_unknownCmd;
Tcl_ObjCmdProc TclTdomObjCmd;

#if defined(_MSC_VER)
#  undef TCL_STORAGE_CLASS
#  define TCL_STORAGE_CLASS DLLEXPORT
#endif

#define STR_TDOM_VERSION(v) (VERSION)

EXTERN int Tdom_Init     _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int Tdom_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));

#endif









|






|
|




58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Tcl_ObjCmdProc tcldom_DomObjCmd;
Tcl_ObjCmdProc tcldom_DocObjCmd;
Tcl_ObjCmdProc tcldom_NodeObjCmd;
Tcl_ObjCmdProc TclExpatObjCmd;
Tcl_ObjCmdProc tcldom_unknownCmd;
Tcl_ObjCmdProc TclTdomObjCmd;

#if defined(_MSC_VER) || defined(__MINGW32__)
#  undef TCL_STORAGE_CLASS
#  define TCL_STORAGE_CLASS DLLEXPORT
#endif

#define STR_TDOM_VERSION(v) (VERSION)

EXTERN int Tdom_Init     (Tcl_Interp *interp);
EXTERN int Tdom_SafeInit (Tcl_Interp *interp);

#endif


Changes to generic/tclexpat.c.

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

56

57
58
59
60
61
62
63
...
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

192


193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
...
221
222
223
224
225
226
227
228
229
230

231
232
233
234
235
236
237
...
274
275
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
...
331
332
333
334
335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
...
429
430
431
432
433
434
435
436
437
438

439
440
441
442
443
444
445
...
472
473
474
475
476
477
478
479
480
481
482
483

484
485
486
487
488
489
490
...
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580

581

582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
...
623
624
625
626
627
628
629
630
631
632

633
634
635
636
637
638
639
...
644
645
646
647
648
649
650












































651
652
653
654
655
656
657
...
658
659
660
661
662
663
664
665
666
667
668
669
670

671
672
673
674
675
676
677

678
679
680
681

682
683
684
685
686
687
688
...
707
708
709
710
711
712
713































714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
...
812
813
814
815
816
817
818
819
820
821
822
823
824
825

826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
...
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908

909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
...
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978

979
980
981
982
983
984
985
986
987
988
989
990
991
...
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015

1016
1017
1018
1019
1020
1021
1022
....
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055

1056
1057
1058
1059
1060
1061
1062
1063
....
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
....
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
....
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
....
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
....
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
....
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553

1554
1555
1556
1557
1558
1559
1560
1561
....
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954

1955
1956
1957
1958
1959
1960
1961
1962
1963
....
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
....
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040

2041
2042
2043

2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054

2055
2056
2057
2058
2059
2060
2061

2062
2063
2064
2065
2066
2067
2068

2069
2070
2071










2072
2073
2074
2075
2076
2077

2078
2079
2080
2081
2082
2083
2084
....
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105

2106
2107
2108
2109
2110
2111
2112
....
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
....
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244

2245
2246
2247
2248
2249
2250
2251
....
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
....
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370

2371
2372
2373
2374
2375
2376
2377
....
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
....
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469

2470
2471
2472
2473
2474
2475
2476
....
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
....
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564

2565
2566
2567
2568
2569
2570
2571
....
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598

2599
2600
2601
2602
2603
2604
2605
....
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633

2634
2635
2636
2637
2638
2639
2640
....
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
....
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
....
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758

2759
2760
2761
2762
2763
2764
2765
....
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
....
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849

2850
2851
2852
2853
2854
2855
2856
....
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
....
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946

2947
2948
2949
2950
2951
2952
2953
....
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
....
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068

3069
3070
3071
3072
3073
3074
3075
....
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
....
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170

3171
3172
3173
3174
3175
3176
3177
....
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219

3220
3221
3222
3223
3224
3225
3226
....
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
....
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440

3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
....
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
....
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544

3545
3546
3547
3548
3549
3550
3551
....
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627

3628
3629
3630
3631
3632
3633
3634
....
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704

3705
3706
3707
3708
3709
3710
3711
....
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784

3785
3786
3787
3788
3789
3790
3791
....
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848

3849
3850
3851
3852
3853
3854
3855
....
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930

3931
3932
3933
3934
3935
3936
3937
....
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028

4029
4030
4031
4032
4033
4034
4035
....
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129

4130
4131
4132
4133
4134
4135
4136
....
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229

4230
4231
4232
4233
4234
4235
4236
....
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321

4322
4323
4324
4325
4326
4327
4328
....
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411

4412
4413
4414
4415
4416
4417
4418
....
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521

4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539

4540
4541
4542
4543
4544
4545
4546
....
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
....
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577

4578
4579
4580
4581
4582
4583
4584
....
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617

4618
4619
4620
4621
4622
4623
4624
....
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644

4645
4646
4647
4648
4649
4650
4651
....
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670

4671
4672
4673
4674
4675
4676
#include <string.h>
#include <dom.h>
#include <tclexpat.h>
#include <fcntl.h>

#ifdef _MSC_VER
#include <io.h>
#endif

#ifdef _POSIX_SOURCE
#include <unistd.h>
#endif

/* Used internal als status, like TCL_OK, TCL_ERROR etc.  As a
   consequent, application specific error codes must be at least
   greater than 5 */
#define ERROR_IN_EXTREFHANDLER 5


#define READ_SIZE (1024*8)

#ifndef O_BINARY
#ifdef _O_BINARY
#define O_BINARY _O_BINARY
#else
#define O_BINARY 0
#endif
#endif
................................................................................
                                */
TDomThreaded(static Tcl_Mutex counterMutex;) /* Protect the counter (zv) */

/*----------------------------------------------------------------------------
|   Prototypes for procedures defined later in this file:
|
\---------------------------------------------------------------------------*/
int             TclExpatObjCmd _ANSI_ARGS_((ClientData dummy,
                    Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
static int      TclExpatInstanceCmd _ANSI_ARGS_((ClientData dummy,
                    Tcl_Interp *interp, int objc, struct Tcl_Obj *CONST objv[]));
static void     TclExpatDeleteCmd _ANSI_ARGS_((ClientData clientData));

static Tcl_Obj* FindUniqueCmdName _ANSI_ARGS_((Tcl_Interp *interp));
static int      TclExpatCheckWhiteData _ANSI_ARGS_((char *pc, int len));

static int      TclExpatInitializeParser _ANSI_ARGS_((Tcl_Interp *interp,
                    TclGenExpatInfo *expat, int resetOptions ));
static void     TclExpatFreeParser  _ANSI_ARGS_((TclGenExpatInfo *expat));
static int      TclExpatParse _ANSI_ARGS_((Tcl_Interp *interp,
                    TclGenExpatInfo *expat, char *data, int len,
                                     TclExpat_InputType type));
static int      TclExpatConfigure _ANSI_ARGS_((Tcl_Interp *interp,
                    TclGenExpatInfo *expat, int objc, Tcl_Obj *CONST objv[]));
static int      TclExpatCget _ANSI_ARGS_((Tcl_Interp *interp,
                    TclGenExpatInfo *expat, int objc, Tcl_Obj *CONST objv[]));

static int	TclExpatGet _ANSI_ARGS_((Tcl_Interp *interp,
		    TclGenExpatInfo *expat, int objc, Tcl_Obj *CONST objv[]));
static void	TclExpatDispatchPCDATA _ANSI_ARGS_((TclGenExpatInfo *expat));
static void TclGenExpatElementStartHandler _ANSI_ARGS_((void *userdata,
                                                        const XML_Char *name,
                                                        const XML_Char **atts));
static void TclGenExpatElementEndHandler _ANSI_ARGS_((void *userData,
                                                      const XML_Char *name));
static void TclGenExpatCharacterDataHandler _ANSI_ARGS_((void *userData,
                                                         const XML_Char *s,
                                                         int len));

static void 	TclGenExpatProcessingInstructionHandler _ANSI_ARGS_((
	    	    void *userData, const XML_Char *target,
	    	    const XML_Char *data));
static int 	TclGenExpatExternalEntityRefHandler _ANSI_ARGS_((
	    	    XML_Parser parser, const XML_Char *openEntityNames,
	    	    const XML_Char *base, const XML_Char *systemId,
	    	    const XML_Char *publicId));
static void 	TclGenExpatDefaultHandler _ANSI_ARGS_ ((void *userData,
	    	    const XML_Char *s, int len));
static void 	TclGenExpatNotationDeclHandler _ANSI_ARGS_ ((void *userData,
		    const XML_Char *notationName, const XML_Char *base,
		    const XML_Char *systemId, const XML_Char *publicId));
static int	TclGenExpatUnknownEncodingHandler _ANSI_ARGS_ ((
		    void *encodingHandlerData, const XML_Char *name,
		    XML_Encoding *info));

static void  TclGenExpatStartNamespaceDeclHandler _ANSI_ARGS_((void *userdata,
                                                               const XML_Char *prefix,
                                                               const XML_Char *uri));
static void  TclGenExpatEndNamespaceDeclHandler _ANSI_ARGS_((void *userData,
                                                          const XML_Char *prefix));


/* Following added by ericm@scriptics, 1999.6.25 */
/* Prototype definition for the TclExpat comment handler */
static void 	TclGenExpatCommentHandler _ANSI_ARGS_ ((void *userData,
						     const XML_Char *data));
/* Prototype for TclExpat Not Standalone Handler */
static int 	TclGenExpatNotStandaloneHandler _ANSI_ARGS_ ((void *userData));

/* Prototype for TclExpat {Start|End}CdataSectionHandler */
static void 	TclGenExpatStartCdataSectionHandler _ANSI_ARGS_((void *userData));
static void 	TclGenExpatEndCdataSectionHandler _ANSI_ARGS_((void *userData));

/* Added by ericm@scriptics.com, 1999.09.13 */
/* Prototype for TclExpat (Element|Attlist) Declaration Handlers */
static void     TclGenExpatElementDeclHandler _ANSI_ARGS_((void *userData,
                    const XML_Char *name, XML_Content *model));
static void     TclGenExpatAttlistDeclHandler _ANSI_ARGS_((void *userData,
                    const XML_Char *elname, const XML_Char *name,
                    const XML_Char *type, const XML_Char *dflt,
                    int isrequired));
/* Prototypes for the TclExpat Doctype Decl handlers */
static void     TclGenExpatStartDoctypeDeclHandler _ANSI_ARGS_((void *userData,

                    const XML_Char *doctypeName, const XML_Char *sysid,


                    const XML_Char *pubid, int has_internal_subset));
static void     TclGenExpatEndDoctypeDeclHandler _ANSI_ARGS_((void *userData));
static void     TclGenExpatXmlDeclHandler _ANSI_ARGS_((void *userData,
                                                       const XML_Char *version,
                                                       const XML_Char *encoding,
                                                       int standalone));
static void     TclGenExpatEntityDeclHandler _ANSI_ARGS_((void *userData,
                                                          const XML_Char *entityname,
                                                          int is_param,
                                                          const XML_Char *value,
                                                          int length,
                                                          CONST XML_Char *base,
                                                          CONST XML_Char *systemId,
                                                          CONST XML_Char *publicId,
                                                          CONST XML_Char *notationName));


/*
 *----------------------------------------------------------------------------
 *
 * CreateTclHandlerSet --
 *
 *	Malloc's and initializes a tclHandlerSet.
................................................................................
 *	Mallocs memory for the structure and the 'name' field, sets all
 *      handler scripts to NULL and inits some other fields.
 *
 *----------------------------------------------------------------------------
 */

static TclHandlerSet*
CreateTclHandlerSet (name)
    char *name;
{

    TclHandlerSet *handlerSet;

    handlerSet = (TclHandlerSet*) MALLOC (sizeof (TclHandlerSet)); \
    handlerSet->name                      = tdomstrdup (name);
    handlerSet->ignoreWhiteCDATAs         = 0;
    handlerSet->status                    = TCL_OK;
    handlerSet->continueCount             = 0;
................................................................................
 *	Mallocs memory for the 'name' of the structure, sets all
 *      handler functions to NULL and inits some other fields.
 *
 *----------------------------------------------------------------------------
 */

CHandlerSet*
CHandlerSetCreate (name)
    char *name;
{

    CHandlerSet *handlerSet;

    handlerSet = (CHandlerSet *) MALLOC (sizeof (CHandlerSet));
    handlerSet->name                     = tdomstrdup (name);
    handlerSet->ignoreWhiteCDATAs        = 0;
    handlerSet->nextHandlerSet           = NULL;

................................................................................
 * Side effects:
 *	This creates an expat parser.
 *
 *----------------------------------------------------------------------------
 */

int
TclExpatObjCmd(dummy, interp, objc, objv)
     ClientData dummy;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *CONST objv[];
{

  TclGenExpatInfo *genexpat;
  int ns_mode = 0;
  char *nsoption;


  /*
   * Create the data structures for this parser.
................................................................................
 * Side effects:
 *	Allocates Tcl object.
 *
 *----------------------------------------------------------------------------
 */

static Tcl_Obj *
FindUniqueCmdName(interp)
     Tcl_Interp *interp;
{

  Tcl_Obj *name;
  Tcl_CmdInfo info;
  char s[20];

  name = Tcl_NewStringObj("", 0);
  Tcl_IncrRefCount(name);

................................................................................
 *	Creates or reset an expat parser.
 *	Modifies TclExpatInfo fields.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatInitializeParser(interp, expat, resetOptions)
     Tcl_Interp      *interp;
     TclGenExpatInfo *expat;
     int              resetOptions;
{

    CHandlerSet *activeCHandlerSet;
    ExpatElemContent *eContent, *eContentSave;

    if (expat->parser) {
        XML_ParserReset (expat->parser, NULL);
        activeCHandlerSet = expat->firstCHandlerSet;
        while (activeCHandlerSet) {
................................................................................
    }
    
    /*
     * Set handlers for the parser to routines in this module.
     */

    XML_SetElementHandler(expat->parser,
                          (XML_StartElementHandler) TclGenExpatElementStartHandler,
                          (XML_EndElementHandler) TclGenExpatElementEndHandler);
    XML_SetNamespaceDeclHandler(expat->parser,
                                (XML_StartNamespaceDeclHandler) TclGenExpatStartNamespaceDeclHandler,
                                (XML_EndNamespaceDeclHandler) TclGenExpatEndNamespaceDeclHandler);
    XML_SetCharacterDataHandler(expat->parser,
                                (XML_CharacterDataHandler) TclGenExpatCharacterDataHandler);
    XML_SetProcessingInstructionHandler(expat->parser,
                                        (XML_ProcessingInstructionHandler) TclGenExpatProcessingInstructionHandler);
    XML_SetDefaultHandlerExpand(expat->parser,
                                (XML_DefaultHandler) TclGenExpatDefaultHandler);
    
    XML_SetNotationDeclHandler(expat->parser,
                               (XML_NotationDeclHandler) TclGenExpatNotationDeclHandler);
    XML_SetExternalEntityRefHandler(expat->parser,
                                    (XML_ExternalEntityRefHandler) TclGenExpatExternalEntityRefHandler);
    XML_SetUnknownEncodingHandler(expat->parser,
                                  (XML_UnknownEncodingHandler) TclGenExpatUnknownEncodingHandler,
                                  (void *) expat);
    
    
    XML_SetCommentHandler(expat->parser, TclGenExpatCommentHandler);
    
    XML_SetNotStandaloneHandler(expat->parser, TclGenExpatNotStandaloneHandler);
    

    XML_SetCdataSectionHandler(expat->parser, TclGenExpatStartCdataSectionHandler,

                               TclGenExpatEndCdataSectionHandler);
    
    XML_SetElementDeclHandler(expat->parser, TclGenExpatElementDeclHandler);
    
    XML_SetAttlistDeclHandler(expat->parser, TclGenExpatAttlistDeclHandler);
    
    XML_SetDoctypeDeclHandler(expat->parser,
                              TclGenExpatStartDoctypeDeclHandler,
                              TclGenExpatEndDoctypeDeclHandler);
    
    XML_SetXmlDeclHandler (expat->parser, TclGenExpatXmlDeclHandler);
    
    XML_SetEntityDeclHandler (expat->parser,
                              TclGenExpatEntityDeclHandler);
    if (expat->noexpand) {
        XML_SetDefaultHandlerExpand(expat->parser, NULL);
        XML_SetDefaultHandler(expat->parser,
                              (XML_DefaultHandler) TclGenExpatDefaultHandler);
    } else {
        XML_SetDefaultHandler(expat->parser, NULL);
        XML_SetDefaultHandlerExpand(expat->parser,
                              (XML_DefaultHandler) TclGenExpatDefaultHandler);
    }
    
    XML_SetUserData(expat->parser, (void *) expat);
    
    return TCL_OK;
}

................................................................................
 *	Frees any memory allocated for the XML parser and (if still present)
 *      the stored content models.
 *
 *----------------------------------------------------------------------------
 */

static void
TclExpatFreeParser(expat)
     TclGenExpatInfo *expat;
{

  ExpatElemContent *eContent, *eContentSave;

  eContent = expat->eContents;
  while (eContent) {
      XML_FreeContentModel (expat->parser, eContent->content);
      eContentSave = eContent;
      eContent = eContent->next;
................................................................................
  XML_ParserFree(expat->parser);
  expat->parser = NULL;
}

/*
 *----------------------------------------------------------------------------
 *












































 * TclExpatInstanceCmd --
 *
 *	Implements instance command for expat class objects.
 *
 * Results:
 *	Depends on the method.
 *
................................................................................
 * Side effects:
 *	Depends on the method.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatInstanceCmd (clientData, interp, objc, objv)
     ClientData clientData;
     Tcl_Interp *interp;
     int objc;
     Tcl_Obj *CONST objv[];
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) clientData;
  char *data;
  int len = 0, optionIndex, result = TCL_OK;

  static CONST84 char *options[] = {
      "configure", "cget", "free", "get",
      "parse", "parsechannel", "parsefile", "reset", NULL

  };
  enum options {
      EXPAT_CONFIGURE, EXPAT_CGET, EXPAT_FREE, EXPAT_GET,
      EXPAT_PARSE, EXPAT_PARSECHANNEL, EXPAT_PARSEFILE, EXPAT_RESET

  };


  if (objc < 2) {
      Tcl_SetResult (interp, 
                     "wrong # args: should be \"parserCmd method ?arg ...?\"",
                     TCL_STATIC);
................................................................................

    case EXPAT_CGET:

        CheckArgs (3,5,2, "?-handlerset handlersetname? switch");
        result = TclExpatCget(interp, expat, objc - 2, objv + 2);
        break;
































    case EXPAT_FREE:

        CheckArgs (2,2,1,"");

        if (expat->parsingState > 1) {
            Tcl_SetResult (interp, "parser freeing not allowed from within "
                           "callback", TCL_STATIC);
            result = TCL_ERROR;
        } else {
            Tcl_DeleteCommand(interp, Tcl_GetString(expat->name));
            result = TCL_OK;
        }
	break;

    case EXPAT_GET:


        /* ericm@scriptics.com, 1999.6.28 */
        result = TclExpatGet(interp, expat, objc - 2, objv + 2);
        break;

    case EXPAT_PARSE:

        CheckArgs (3,3,2,"<XML-String>");
................................................................................
 * Side effects:
 *     Sets interpreter result as appropriate.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatParse (interp, expat, data, len, type)
     Tcl_Interp *interp;
     TclGenExpatInfo *expat;
     char *data;
     int len;
     TclExpat_InputType type;
{

  int result, mode, done;
  size_t bytesread;
  char s[255], buf[8*1024];
  int fd;
  XML_Parser  parser;
  Tcl_Channel channel = NULL;
  CHandlerSet *activeCHandlerSet;
#if !TclOnly8Bits
  Tcl_Obj       *bufObj = NULL;
  Tcl_DString    dStr;
  int            useBinary;
  char          *str;
#endif

  if (expat->finished) {
      if ((result = TclExpatInitializeParser (interp, expat, 0)) != TCL_OK) 
          return TCL_ERROR;
  }

  if (!expat->parsingState) {
................................................................................
      }
      if (!(mode & TCL_READABLE)) {
          Tcl_ResetResult (interp);
          Tcl_AppendResult (interp, "channel \"", data,
                            "wasn't opened for reading", (char *) NULL);
          return TCL_ERROR;
      }
#if !TclOnly8Bits
      Tcl_DStringInit (&dStr);
      if (Tcl_GetChannelOption (interp, channel, "-encoding", &dStr) 
          != TCL_OK) {
          return TCL_ERROR;
      }
      if (strcmp (Tcl_DStringValue (&dStr), "binary")==0 ) useBinary = 1;
      else useBinary = 0;
      Tcl_DStringFree (&dStr);
      expat->parsingState = 2;
      if (useBinary) {
          do {
              bytesread = Tcl_Read (channel, buf, sizeof (buf));
              done = bytesread < sizeof (buf);
              if (done) {
                  result = XML_Parse (expat->parser, buf, bytesread, done);
              } else {
                  if (!XML_Parse (expat->parser, buf, bytesread, done)) {
                      result = 0;
                      break;
                  }
              }

          } while (!done);
      } else {
          bufObj = Tcl_NewObj();
          Tcl_IncrRefCount (bufObj);
          Tcl_SetObjLength (bufObj, 6144);
          do {
              len = Tcl_ReadChars (channel, bufObj, 1024, 0);
              done = (len < 1024);
              str = Tcl_GetStringFromObj (bufObj, &len);
              if (!XML_Parse (expat->parser, str, len, done)) {
                  result = 0;
                  break;
              }
          } while (!done);
          /* In case of a parsing error we need the string rep of the
             bufObj until the error reporting is done (otherwise,
             calling XML_GetCurrentLineNumber() results in invalid mem
             reads */
          if (result) {
              Tcl_DecrRefCount (bufObj);
          }
      }
#else
      expat->parsingState = 2;
      do {
          bytesread = Tcl_Read (channel, buf, sizeof (buf));
          done = bytesread < sizeof (buf);
          if (done) {
              result = XML_Parse (expat->parser, buf, bytesread, done);
          } else {
              if (!XML_Parse (expat->parser, buf, bytesread, done)) {
                  result = 0;
                      break;
              }
          }
      } while (!done);
#endif /* !TclOnly8Bits */
      expat->parsingState = 1;
      break;

  case EXPAT_INPUT_FILENAME:
      fd = open(data, O_BINARY|O_RDONLY);
      if (fd < 0) {
          Tcl_ResetResult (interp);
................................................................................
                            data, "\"", (char *) NULL);
          return TCL_ERROR;
      }
      parser = expat->parser;
      expat->parsingState = 2;
      for (;;) {
          int nread;
          char *fbuf = XML_GetBuffer (parser, READ_SIZE);
          if (!fbuf) {
              close (fd);
              Tcl_ResetResult (interp);
              Tcl_SetResult (interp, "Out of memory\n", NULL);
              expat->parsingState = 1;
              return TCL_ERROR;
          }
          nread = read(fd, fbuf, READ_SIZE);
          if (nread < 0) {
              close (fd);
              Tcl_ResetResult (interp);
              Tcl_AppendResult (interp, "error reading from file \"",
                                data, "\"", (char *) NULL);
              expat->parsingState = 1;
              return TCL_ERROR;
          }
          if (!XML_ParseBuffer (parser, nread, nread == 0)) {

              close (fd);
              result = 0;
              break;
          }
          if (nread == 0) {
              close(fd);
              break;
          }
      }
      expat->parsingState = 1;
      break;
  }

................................................................................
          sprintf(s, "%ld", XML_GetCurrentLineNumber(expat->parser));
          Tcl_AppendResult(interp, "error \"",
                           XML_ErrorString(XML_GetErrorCode(expat->parser)),
                           "\" at line ", s, " character ", NULL);
          sprintf(s, "%ld", XML_GetCurrentColumnNumber(expat->parser));
          Tcl_AppendResult(interp, s, NULL);
      }
#if !TclOnly8Bits
      if (bufObj) {
          Tcl_DecrRefCount (bufObj);
      }
#endif
      return TCL_ERROR;
  }
  switch (expat->status) {
    case TCL_OK:
    case TCL_BREAK:
    case TCL_CONTINUE:

      Tcl_ResetResult(interp);
      return TCL_OK;

    case TCL_ERROR:
      Tcl_SetObjResult(interp, expat->result);
      return TCL_ERROR;

................................................................................
 * Side effects:
 *	Depends on the method.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatConfigure (interp, expat, objc, objv)
     Tcl_Interp *interp;
     TclGenExpatInfo *expat;
     int objc;
     Tcl_Obj *CONST objv[];
{

  static CONST84 char *switches[] = {
    "-final",
    "-baseurl",
    "-elementstartcommand",
    "-elementendcommand",
    "-characterdatacommand",
    "-processinginstructioncommand",
    "-defaultcommand",
................................................................................
    EXPAT_XMLDECLCMD,
    EXPAT_PARAMENTITYPARSING,
    EXPAT_ENTITYDECLCOMMAND,
    EXPAT_NOWHITESPACE,
    EXPAT_HANDLERSET,
    EXPAT_NOEXPAND
  };
  static CONST84 char *paramEntityParsingValues[] = {
      "always",
      "never",
      "notstandalone",
      (char *) NULL
  };
  enum paramEntityParsingValues {
      EXPAT_PARAMENTITYPARSINGALWAYS,
      EXPAT_PARAMENTITYPARSINGNEVER,
      EXPAT_PARAMENTITYPARSINGNOTSTANDALONE
  };
  int optionIndex, value, bool;
  Tcl_Obj *CONST *objPtr = objv;
  Tcl_CmdInfo cmdInfo;
  int rc;
  char *handlerSetName = NULL;
  TclHandlerSet *tmpTclHandlerSet, *activeTclHandlerSet = NULL;

  if (expat->firstTclHandlerSet 
      && (strcmp ("default", expat->firstTclHandlerSet->name)==0)) {
................................................................................
	Tcl_IncrRefCount(activeTclHandlerSet->elementstartcommand);
        rc = Tcl_GetCommandInfo(interp, Tcl_GetString(objPtr[1]), &cmdInfo);
        if (rc && cmdInfo.isNativeObjectProc) {
            activeTclHandlerSet->elementstartObjProc = cmdInfo.objProc;
            activeTclHandlerSet->elementstartclientData 
                = cmdInfo.objClientData;
        } else {
            /* hmoreau 22 May 2003 */
            activeTclHandlerSet->elementstartObjProc = NULL;
        }
	break;

      case EXPAT_ELEMENTENDCMD:		/* -elementendcommand */

        CheckDefaultTclHandlerSet;
................................................................................
	activeTclHandlerSet->elementendcommand = objPtr[1];
	Tcl_IncrRefCount(activeTclHandlerSet->elementendcommand);
        rc = Tcl_GetCommandInfo(interp, Tcl_GetString(objPtr[1]), &cmdInfo);
        if (rc && cmdInfo.isNativeObjectProc) {
            activeTclHandlerSet->elementendObjProc = cmdInfo.objProc;
            activeTclHandlerSet->elementendclientData = cmdInfo.objClientData;
        } else {
            /* hmoreau 22 May 2003 */
            activeTclHandlerSet->elementendObjProc = NULL;
        }
	break;

      case EXPAT_STARTNAMESPACEDECLCMD:	/* -startnamespacedeclcommand */

        CheckDefaultTclHandlerSet;
................................................................................
	activeTclHandlerSet->datacommand = objPtr[1];
	Tcl_IncrRefCount(activeTclHandlerSet->datacommand);
        rc = Tcl_GetCommandInfo (interp, Tcl_GetString(objPtr[1]), &cmdInfo);
        if (rc && cmdInfo.isNativeObjectProc) {
            activeTclHandlerSet->datacommandObjProc = cmdInfo.objProc;
            activeTclHandlerSet->datacommandclientData = cmdInfo.objClientData;
        } else {
            /* hmoreau 22 May 2003 */
            activeTclHandlerSet->datacommandObjProc = NULL;
        }
	break;

      case EXPAT_PICMD:			/* -processinginstructioncommand */

        CheckDefaultTclHandlerSet;
................................................................................
        break;

    case EXPAT_NOEXPAND:
        if (Tcl_GetBooleanFromObj (interp, objv[1], &bool) != TCL_OK) {
            return TCL_ERROR;
        }
        if (bool) {
            XML_SetDefaultHandlerExpand(expat->parser, NULL);
            XML_SetDefaultHandler(expat->parser,
                        (XML_DefaultHandler) TclGenExpatDefaultHandler);
        }
        else {
            XML_SetDefaultHandler(expat->parser, NULL);
            XML_SetDefaultHandlerExpand(expat->parser,
                        (XML_DefaultHandler) TclGenExpatDefaultHandler);
        }
        expat->noexpand = bool;
        break;

    }

    objPtr += 2;
................................................................................
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatCget (interp, expat, objc, objv)
     Tcl_Interp *interp;
     TclGenExpatInfo *expat;
     int objc;
     Tcl_Obj *CONST objv[];
{

    static CONST84 char *switches[] = {
        "-final",
        "-baseurl",
        "-elementstartcommand",
        "-elementendcommand",
        "-characterdatacommand",
        "-processinginstructioncommand",
        "-defaultcommand",
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------------
 */
static int
TclExpatGet (interp, expat, objc, objv)
     Tcl_Interp *interp;
     TclGenExpatInfo *expat;
     int objc;
     Tcl_Obj *CONST objv[];

{
  static CONST84 char *getSwitches[] = {
    "-specifiedattributecount",
    "-currentbytecount",
    "-currentlinenumber",
    "-currentcolumnnumber",
    "-currentbyteindex",
    (char *) NULL
  };
................................................................................
    EXPAT_CURRENTLINENUMBER,
    EXPAT_CURRENTCOLUMNNUMBER,
    EXPAT_CURRENTBYTEINDEX
  };
  int switchIndex;
  Tcl_Obj *resultPtr;

  if (objc > 1) {
    Tcl_SetResult(interp, "Only one value may be requested at a time",
		  TCL_STATIC);
    return TCL_ERROR;
  }

  if (Tcl_GetIndexFromObj(interp, objv[0], getSwitches,
			  "switch", 0, &switchIndex) != TCL_OK) {
    return TCL_ERROR;
  }
  resultPtr = Tcl_GetObjResult(interp);

  switch ((enum getSwitch) switchIndex) {
................................................................................
 * Side Effects:
 *	Further invocation of callback scripts may be inhibited.
 *
 *----------------------------------------------------------------------------
 */

static void
TclExpatHandlerResult(expat, handlerSet, result)
     TclGenExpatInfo *expat;
     TclHandlerSet *handlerSet;
     int result;
{

  switch (result) {
    case TCL_OK:
      handlerSet->status = TCL_OK;

      break;

    case TCL_CONTINUE:
      /*
       * Skip callbacks until the matching end element event
       * occurs for the currently open element.
       * Keep a reference count to handle nested
       * elements.
       */
      handlerSet->status = TCL_CONTINUE;
      handlerSet->continueCount = 1;

      break;

    case TCL_BREAK:
      /*
       * Skip all further callbacks, but return OK.
       */
      handlerSet->status = TCL_BREAK;

      break;

    case TCL_ERROR:
      /*
       * Skip all further callbacks, and return error.
       */
      expat->status = TCL_ERROR;

      expat->result = Tcl_GetObjResult(expat->interp);
      Tcl_IncrRefCount(expat->result);
      break;










      
    default:
      /*
       * Skip all further callbacks, set return value and return error.
       */
      expat->status = result;

      expat->result = Tcl_GetObjResult(expat->interp);
      Tcl_IncrRefCount(expat->result);
      break;
  }
}

/*
................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatElementStartHandler(userData, name, atts)
     void *userData;
     const char *name;
     const char **atts;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *atList = NULL;
  const char **atPtr;
  int result;
  Tcl_Obj *vector[3];
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;
................................................................................
              cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->elementstartcommand);
              Tcl_IncrRefCount(cmdPtr);
              Tcl_Preserve((ClientData) expat->interp);

              Tcl_ListObjAppendElement(expat->interp, cmdPtr,
                                       Tcl_NewStringObj((char *)name, -1));
              Tcl_ListObjAppendElement(expat->interp, cmdPtr, atList);

              /*
               * It would be desirable to be able to terminate parsing
               * if the return result is TCL_ERROR or TCL_BREAK.
               */
#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
              result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
              result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                                     TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatElementEndHandler(userData, name)
     void *userData;
     CONST char *name;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  int result;
  Tcl_Obj *vector[2], *ename = NULL;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;
  Tcl_Obj      *cmdPtr;

................................................................................

              cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->elementendcommand);
              Tcl_IncrRefCount(cmdPtr);
              Tcl_Preserve((ClientData) expat->interp);

              Tcl_ListObjAppendElement(expat->interp, cmdPtr,
                                       Tcl_NewStringObj((char *)name, -1));

              /*
               * It would be desirable to be able to terminate parsing
               * if the return result is TCL_ERROR or TCL_BREAK.
               */
#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
              result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
              result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                                     TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT );
#endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatStartNamespaceDeclHandler(userData, prefix, uri)
     void       *userData;
     const char *prefix;
     const char *uri;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj      *cmdPtr;
  int           result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  if (expat->status != TCL_OK) {
................................................................................
      Tcl_IncrRefCount(cmdPtr);
      Tcl_Preserve((ClientData) expat->interp);

      Tcl_ListObjAppendElement(expat->interp, cmdPtr,
                               Tcl_NewStringObj((char *)prefix, -1));
      Tcl_ListObjAppendElement(expat->interp, cmdPtr,
                               Tcl_NewStringObj((char *)uri,    -1));

      /*
       * It would be desirable to be able to terminate parsing
       * if the return result is TCL_ERROR or TCL_BREAK.
       */
#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
      result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
      result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatEndNamespaceDeclHandler(userData, prefix)
     void       *userData;
     CONST char *prefix;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  if (expat->status != TCL_OK) {
................................................................................
       */

      cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->endnsdeclcommand);
      Tcl_IncrRefCount(cmdPtr);
      Tcl_Preserve((ClientData) expat->interp);

      Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)prefix, -1));

      /*
       * It would be desirable to be able to terminate parsing
       * if the return result is TCL_ERROR or TCL_BREAK.
       */
#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
      result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
      result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Results:
 *	1 if string contains just white characters
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatCheckWhiteData (pc, len)
     char         *pc;
     int           len;
{

    for (; len > 0; len--, pc++) {
        if ( (*pc != ' ')  &&
             (*pc != '\t') &&
             (*pc != '\n') &&
             (*pc != '\r') ) {
            return 0;
        }
................................................................................
 * Side Effects:
 *	Callback script is invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatCharacterDataHandler(userData, s, len)
     void *userData;
     CONST char *s;
     int len;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;

  if (expat->status != TCL_OK) {
      return;
  }

  if (!expat->cdata) {
................................................................................
 * Side Effects:
 *	Callback script evaluated.
 *
 *----------------------------------------------------------------------------
 */

static void
TclExpatDispatchPCDATA(expat)
     TclGenExpatInfo *expat;
{

  int len, result, onlyWhiteSpace = 0;
  Tcl_Obj *vector[2];
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;
  Tcl_Obj* cmdPtr;
  char *s;

................................................................................
           */
          cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->datacommand);
          Tcl_IncrRefCount(cmdPtr);
          Tcl_Preserve((ClientData) expat->interp);

          Tcl_ListObjAppendElement(expat->interp, cmdPtr,
                                   Tcl_NewStringObj((char *)s, len));

          /*
           * It would be desirable to be able to terminate parsing
           * if the return result is TCL_ERROR or TCL_BREAK.
           */
#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
          result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
          result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                                 TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
              activeCHandlerSet->datacommand (activeCHandlerSet->userData,
                                              s, len);
          }
      }
      activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
  }
  Tcl_DecrRefCount (expat->cdata);
  expat->cdata = 0;
  return;
}


/*
 *----------------------------------------------------------------------------
 *
................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatProcessingInstructionHandler(userData, target, data)
     void *userData;
     CONST char *target;
     CONST char *data;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  if (expat->status != TCL_OK) {
................................................................................

      cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->picommand);
      Tcl_IncrRefCount(cmdPtr);
      Tcl_Preserve((ClientData) expat->interp);

      Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)target, strlen(target)));
      Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)data, strlen(data)));

      /*
       * It would be desirable to be able to terminate parsing
       * if the return result is TCL_ERROR or TCL_BREAK.
       */
#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
      result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
      result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatDefaultHandler(userData, s, len)
     void *userData;
     CONST char *s;
     int len;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);
................................................................................
       */

      cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->defaultcommand);
      Tcl_IncrRefCount(cmdPtr);
      Tcl_Preserve((ClientData) expat->interp);

      Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)s, len));

      /*
       * It would be desirable to be able to terminate parsing
       * if the return result is TCL_ERROR or TCL_BREAK.
       */
#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
      result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
      result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatEntityDeclHandler(userData, entityname, is_param, value, length, base, systemId, publicId, notationName)
     void *userData;
     CONST char *entityname;
     int         is_param;
     CONST char *value;
     int         length;
     CONST char *base;
     CONST char *systemId;
     CONST char *publicId;
     CONST char *notationName;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);
................................................................................
          Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)publicId, strlen(publicId)));
      }
      if (notationName == NULL) {
          Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewListObj(0, NULL));
      } else {
          Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)notationName, strlen(notationName)));
      }

      /*
       * It would be desirable to be able to terminate parsing
       * if the return result is TCL_ERROR or TCL_BREAK.
       */
#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
      result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
      result = Tcl_EvalObjEx(expat->interp, cmdPtr,
                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatNotationDeclHandler(userData, notationName, base, systemId, publicId)
     void *userData;
     CONST char *notationName;
     CONST char *base;
     CONST char *systemId;
     CONST char *publicId;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);
................................................................................
          Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)systemId, strlen(systemId)));
      }
      if (publicId == NULL) {
          Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewListObj(0, NULL));
      } else {
          Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)publicId, strlen(publicId)));
      }

      /*
       * It would be desirable to be able to terminate parsing
       * if the return result is TCL_ERROR or TCL_BREAK.
       */
#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
      result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
      result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static int
TclGenExpatUnknownEncodingHandler(encodingHandlerData, name, info)
     void *encodingHandlerData;
     CONST char *name;
     XML_Encoding *info;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) encodingHandlerData;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);

  if (expat->status != TCL_OK) {
      return 1;
................................................................................
 *
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */
static int
TclGenExpatExternalEntityRefHandler(parser, openEntityNames, base, systemId,
                                    publicId)
     XML_Parser parser;
     CONST char *openEntityNames;
     CONST char *base;
     CONST char *systemId;
     CONST char *publicId;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) XML_GetUserData(parser);
  Tcl_Obj *cmdPtr, *resultObj, *resultTypeObj, *extbaseObj, *dataObj;
  int result, mode, done, fd, tclLen;
  size_t len;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;
  XML_Parser extparser, oldparser = NULL;
................................................................................
              expat->parser = oldparser;
              return 0;
          }
          result = 1;
          do {
              len = Tcl_Read (chan, buf, sizeof (buf));
              done = len < sizeof (buf);
              if (!XML_Parse (extparser, buf, len, done)) {
                  result = 0;
                  break;
              }
          } while (!done);
          Tcl_UnregisterChannel (expat->interp, chan);
          break;

      case EXPAT_INPUT_FILENAME:
          fd = open(dataStr, O_BINARY|O_RDONLY);
          if (fd < 0) {
................................................................................
              XML_ParserFree (extparser);
              expat->parser = oldparser;
              return 0;
          }
          result = 1;
          for (;;) {
              int nread;
              char *fbuf = XML_GetBuffer (extparser, READ_SIZE);
              if (!fbuf) {
                  close (fd);
                  Tcl_ResetResult (expat->interp);
                  Tcl_SetResult (expat->interp, "Out of memory\n", NULL);
                  TclExpatHandlerResult (expat, activeTclHandlerSet,
                                         ERROR_IN_EXTREFHANDLER);
                  return 0;
              }
              nread = read(fd, fbuf, READ_SIZE);
              if (nread < 0) {
                  close (fd);
                  Tcl_ResetResult (expat->interp);
                  Tcl_AppendResult (expat->interp,
                                    "error reading from file \"",
                                    dataStr, "\"", (char *) NULL);
                  TclExpatHandlerResult (expat, activeTclHandlerSet,
                                         ERROR_IN_EXTREFHANDLER);
                  return 0;
              }
              if (!XML_ParseBuffer (extparser, nread, nread == 0)) {

                  close (fd);
                  result = 0;
                  break;
              }
              if (nread == 0) {
                  close(fd);
                  break;
              }
          }
          break;
      }

      Tcl_DecrRefCount (resultObj);
................................................................................
          TclExpatHandlerResult(expat, activeTclHandlerSet,
                                ERROR_IN_EXTREFHANDLER);
          return 0;
      }
      
      /* The last node in the external entity may be a text node. To call 
         TclExpatDispatchPCDATA, before switching back to the old parser
         ensures, that that last text node has the right base URI. */
      TclExpatDispatchPCDATA(expat);

      XML_ParserFree (extparser);
      expat->parser = oldparser;

      activeCHandlerSet = expat->firstCHandlerSet;
      while (activeCHandlerSet) {
................................................................................
 *
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */
static void
TclGenExpatCommentHandler(userData, data)
    void *userData;
    const char *data;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;


................................................................................
 *
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */
static int
TclGenExpatNotStandaloneHandler(userData)
    void *userData;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);
................................................................................
 *
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */
static void
TclGenExpatStartCdataSectionHandler(userData)
    void *userData;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  if (expat->status != TCL_OK) {
................................................................................
 *
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */
static void
TclGenExpatEndCdataSectionHandler(userData)
    void *userData;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  if (expat->status != TCL_OK) {
................................................................................
      activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
  }
  return;
}


static void
generateModel (interp, rep, model)
    Tcl_Interp  *interp;
    Tcl_Obj     *rep;
    XML_Content *model;
{

    Tcl_Obj *cp, *detail;
    unsigned int      i;


    switch (model->type) {
    case XML_CTYPE_EMPTY:
        Tcl_ListObjAppendElement (interp, rep, Tcl_NewStringObj ("EMPTY", 5));
................................................................................
 * Side effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------
 */

static void
TclGenExpatElementDeclHandler(userData, name, model)
    void *userData;
    const XML_Char *name;
    XML_Content *model;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  Tcl_Obj *content;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;
  ExpatElemContent *eContent;
................................................................................
 * Side effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------
 */

static void
TclGenExpatAttlistDeclHandler(userData, elname, name, type, dflt, isrequired)
    void           *userData;
    const XML_Char *elname;
    const XML_Char *name;
    const XML_Char *type;
    const XML_Char *dflt;
    int             isrequired;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);
................................................................................
 * Side effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------
 */

static void
TclGenExpatStartDoctypeDeclHandler(userData, doctypeName, sysid, pubid, has_internal_subset)
    void *userData;
    const XML_Char *doctypeName;
    const XML_Char *sysid;
    const XML_Char *pubid;
    int   has_internal_subset;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);
................................................................................
 * Side effects:
 *	Callback script is invoked.
 *
 *----------------------------------------------------------------------
 */

static void
TclGenExpatEndDoctypeDeclHandler(userData)
    void *userData;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;
  ExpatElemContent *eContent, *eContentSave;

................................................................................
 * Side effects:
 *	Callback script is invoked.
 *
 *----------------------------------------------------------------------
 */

static void
TclGenExpatXmlDeclHandler (userData, version, encoding, standalone)
    void *userData;
    const char *version;
    const char *encoding;
    int   standalone;
{

    TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
    Tcl_Obj *cmdPtr;
    int result;
    TclHandlerSet *activeTclHandlerSet;
    CHandlerSet *activeCHandlerSet;

    if (expat->status != TCL_OK) {
................................................................................
 * Side Effects:
 *	Memory structures are freed.
 *
 *----------------------------------------------------------------------------
 */

static void
TclExpatDeleteCmd(clientData)
     ClientData clientData;
{

  TclGenExpatInfo *expat = (TclGenExpatInfo *) clientData;
  TclHandlerSet *activeTclHandlerSet, *tmpTclHandlerSet;
  CHandlerSet *activeCHandlerSet, *tmpCHandlerSet;

  TclExpatFreeParser(expat);

  Tcl_DecrRefCount(expat->name);
................................................................................
  }

  FREE( (char*) expat);
}


int
CheckExpatParserObj (interp, nameObj)
    Tcl_Interp *interp;
    Tcl_Obj *CONST nameObj;
{

    Tcl_CmdInfo info;


    if (!Tcl_GetCommandInfo (interp, Tcl_GetString(nameObj), &info)) {
        return 0;
    }
    if (!info.isNativeObjectProc || info.objProc != TclExpatInstanceCmd) {
        return 0;
    }
    return 1;
}

int
CHandlerSetInstall (interp, expatObj, handlerSet)
    Tcl_Interp *interp;
    Tcl_Obj *CONST expatObj;
    CHandlerSet *handlerSet;
{

    Tcl_CmdInfo info;
    TclGenExpatInfo *expat;
    CHandlerSet *activeCHandlerSet;

    if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
        return 1;
    }
................................................................................
        activeCHandlerSet = expat->firstCHandlerSet;
        while (1) {
            if (strcmp (activeCHandlerSet->name, handlerSet->name) == 0) {
                return 2;
            }
            if (activeCHandlerSet->nextHandlerSet == NULL) {
                break;
            }
            else {
                activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
            }
        }
        activeCHandlerSet->nextHandlerSet = handlerSet;
    }
    else {
        expat->firstCHandlerSet = handlerSet;
................................................................................
    if (handlerSet->ignoreWhiteCDATAs) {
        expat->needWSCheck = 1;
    }
    return 0;
}

int
CHandlerSetRemove (interp, expatObj, handlerSetName)
    Tcl_Interp *interp;
    Tcl_Obj *CONST expatObj;
    char *handlerSetName;
{

    Tcl_CmdInfo info;
    TclGenExpatInfo *expat;
    CHandlerSet *activeCHandlerSet, *parentHandlerSet = NULL;

    if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
        return 1;
    }
................................................................................
        parentHandlerSet = activeCHandlerSet;
        activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
    }
    return 2;
}

CHandlerSet *
CHandlerSetGet (interp, expatObj, handlerSetName)
    Tcl_Interp *interp;
    Tcl_Obj *CONST expatObj;
    char *handlerSetName;
{

    Tcl_CmdInfo info;
    TclGenExpatInfo *expat;
    CHandlerSet *activeCHandlerSet;

    if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
        return NULL;
    }
................................................................................
        }
        activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
    }
    return NULL;
}

void *
CHandlerSetGetUserData (interp, expatObj, handlerSetName)
    Tcl_Interp *interp;
    Tcl_Obj *CONST expatObj;
    char *handlerSetName;
{

    Tcl_CmdInfo info;
    TclGenExpatInfo *expat;
    CHandlerSet *activeCHandlerSet;

    if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
        return NULL;
    }
................................................................................
        }
        activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
    }
    return NULL;
}

TclGenExpatInfo *
GetExpatInfo (interp, expatObj)
    Tcl_Interp *interp;
    Tcl_Obj *CONST expatObj;
{

    Tcl_CmdInfo info;
    if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
        return NULL;
    }
    return (TclGenExpatInfo *) info.objClientData;
}







|
<
<




|



>
|
>







 







|
|
|
|
|

|
|

|
|
|
|

|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|

|

|
|


|
|
|
|

|
|

|

|
|
|
|
|




|
|

|


|
|



|
|
|


|

|
>
|
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<







 







|
|
<
>







 







|
|
<
>







 







|
|
|
|
|
<
>







 







|
|
<
>







 







|
|
|
|
<
>







 







|
|

|
|

|

|
|
<
<

|

|

|

<
<

<
|
<
>
|
>

<

<

<



<

<



<

|

<

|







 







|
|
<
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
|
|
|
<
>




|
|
|
>


|
|
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|










>







 







|
|
|
|
|
|
<
>







<




<







 







<













<
|
<
<
<
<
<
<
>









|
|
<
<









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







|








|
>

<
<
<
<
<







 







<



<






>







 







|
|
|
|
|
<
>
|







 







|











|







 







<







 







<







 







<







 







<
|
|
<
|
<
|
|







 







|
|
|
|
|
<
>
|







 







|
|
|
|
|
>

|







 







<
<
<
<
<
<







 







|
|
|
|
<
>



>











>




|


>




|


>



>
>
>
>
>
>
>
>
>
>



|


>







 







|
|
|
|
<
>







 







<
<
<
<
<







 







|
|
|
<
>







 







<
<
<
<
<







 







|
|
|
|
<
>







 







<
<
<
<
<







 







|
|
|
<
>







 







<
<
<
<
<







 







|
|
|
<
>







 







|
|
|
|
<
>







 







|
|
<
>







 







<
<
<
<
<







 







|







 







|
|
|
|
<
>







 







<
<
<
<
<







 







|
|
|
|
<
>







 







<
<
<
<
<







 







|
|
|
|
|
|
|
|
|
|
<
>







 







<
<
<
<
<







 







|
|
|
|
|
|
<
>







 







<
<
<
<
<







 







|
|
|
|
<
>







 







|
<
|
|
|
|
|
<
>







 







|
|
<
<







 







|








|










|
>

<
<
<
<
<







 







|







 







|
|
|
<
>







 







|
|
<
>







 







|
|
<
>







 







|
|
<
>







 







|
|
|
|
<
>







 







|
|
|
|
<
>







 







|
|
|
|
|
|
|
<
>







 







|
|
|
|
|
|
<
>







 







|
|
<
>







 







|
|
|
|
|
<
>







 







|
|
<
>







 







|
|
|
<
>

<











|
|
|
|
<
>







 







<
|







 







|
|
|
|
<
>







 







|
|
|
|
<
>







 







|
|
|
|
<
>







 







|
|
|
<
>






38
39
40
41
42
43
44
45


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
...
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
...
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
...
276
277
278
279
280
281
282
283
284

285
286
287
288
289
290
291
292
...
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352
...
431
432
433
434
435
436
437
438
439

440
441
442
443
444
445
446
447
...
474
475
476
477
478
479
480
481
482
483
484

485
486
487
488
489
490
491
492
...
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567


568
569
570
571
572
573
574


575

576

577
578
579
580

581

582

583
584
585

586

587
588
589

590
591
592

593
594
595
596
597
598
599
600
601
...
614
615
616
617
618
619
620
621
622

623
624
625
626
627
628
629
630
...
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
...
693
694
695
696
697
698
699
700
701
702
703
704

705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
...
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
...
881
882
883
884
885
886
887
888
889
890
891
892
893

894
895
896
897
898
899
900
901

902
903
904
905

906
907
908
909
910
911
912
...
947
948
949
950
951
952
953

954
955
956
957
958
959
960
961
962
963
964
965
966

967






968
969
970
971
972
973
974
975
976
977
978
979


980
981
982
983
984
985
986
987
988















989
990
991
992
993
994
995
...
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023





1024
1025
1026
1027
1028
1029
1030
....
1037
1038
1039
1040
1041
1042
1043

1044
1045
1046

1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
....
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092

1093
1094
1095
1096
1097
1098
1099
1100
1101
....
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
....
1211
1212
1213
1214
1215
1216
1217

1218
1219
1220
1221
1222
1223
1224
....
1229
1230
1231
1232
1233
1234
1235

1236
1237
1238
1239
1240
1241
1242
....
1271
1272
1273
1274
1275
1276
1277

1278
1279
1280
1281
1282
1283
1284
....
1537
1538
1539
1540
1541
1542
1543

1544
1545

1546

1547
1548
1549
1550
1551
1552
1553
1554
1555
....
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584

1585
1586
1587
1588
1589
1590
1591
1592
1593
....
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
....
2000
2001
2002
2003
2004
2005
2006






2007
2008
2009
2010
2011
2012
2013
....
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066

2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
....
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146

2147
2148
2149
2150
2151
2152
2153
2154
....
2221
2222
2223
2224
2225
2226
2227





2228
2229
2230
2231
2232
2233
2234
....
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280

2281
2282
2283
2284
2285
2286
2287
2288
....
2341
2342
2343
2344
2345
2346
2347





2348
2349
2350
2351
2352
2353
2354
....
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401

2402
2403
2404
2405
2406
2407
2408
2409
....
2442
2443
2444
2445
2446
2447
2448





2449
2450
2451
2452
2453
2454
2455
....
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495

2496
2497
2498
2499
2500
2501
2502
2503
....
2535
2536
2537
2538
2539
2540
2541





2542
2543
2544
2545
2546
2547
2548
....
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585

2586
2587
2588
2589
2590
2591
2592
2593
....
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619

2620
2621
2622
2623
2624
2625
2626
2627
....
2646
2647
2648
2649
2650
2651
2652
2653
2654

2655
2656
2657
2658
2659
2660
2661
2662
....
2712
2713
2714
2715
2716
2717
2718





2719
2720
2721
2722
2723
2724
2725
....
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
....
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774

2775
2776
2777
2778
2779
2780
2781
2782
....
2807
2808
2809
2810
2811
2812
2813





2814
2815
2816
2817
2818
2819
2820
....
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860

2861
2862
2863
2864
2865
2866
2867
2868
....
2892
2893
2894
2895
2896
2897
2898





2899
2900
2901
2902
2903
2904
2905
....
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952

2953
2954
2955
2956
2957
2958
2959
2960
....
3012
3013
3014
3015
3016
3017
3018





3019
3020
3021
3022
3023
3024
3025
....
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069

3070
3071
3072
3073
3074
3075
3076
3077
....
3111
3112
3113
3114
3115
3116
3117





3118
3119
3120
3121
3122
3123
3124
....
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166

3167
3168
3169
3170
3171
3172
3173
3174
....
3202
3203
3204
3205
3206
3207
3208
3209

3210
3211
3212
3213
3214

3215
3216
3217
3218
3219
3220
3221
3222
....
3385
3386
3387
3388
3389
3390
3391
3392
3393


3394
3395
3396
3397
3398
3399
3400
....
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436





3437
3438
3439
3440
3441
3442
3443
....
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
....
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533

3534
3535
3536
3537
3538
3539
3540
3541
....
3608
3609
3610
3611
3612
3613
3614
3615
3616

3617
3618
3619
3620
3621
3622
3623
3624
....
3685
3686
3687
3688
3689
3690
3691
3692
3693

3694
3695
3696
3697
3698
3699
3700
3701
....
3765
3766
3767
3768
3769
3770
3771
3772
3773

3774
3775
3776
3777
3778
3779
3780
3781
....
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837

3838
3839
3840
3841
3842
3843
3844
3845
....
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919

3920
3921
3922
3923
3924
3925
3926
3927
....
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017

4018
4019
4020
4021
4022
4023
4024
4025
....
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118

4119
4120
4121
4122
4123
4124
4125
4126
....
4210
4211
4212
4213
4214
4215
4216
4217
4218

4219
4220
4221
4222
4223
4224
4225
4226
....
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310

4311
4312
4313
4314
4315
4316
4317
4318
....
4392
4393
4394
4395
4396
4397
4398
4399
4400

4401
4402
4403
4404
4405
4406
4407
4408
....
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510

4511
4512

4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527

4528
4529
4530
4531
4532
4533
4534
4535
....
4538
4539
4540
4541
4542
4543
4544

4545
4546
4547
4548
4549
4550
4551
4552
....
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564

4565
4566
4567
4568
4569
4570
4571
4572
....
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604

4605
4606
4607
4608
4609
4610
4611
4612
....
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631

4632
4633
4634
4635
4636
4637
4638
4639
....
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657

4658
4659
4660
4661
4662
4663
4664
#include <string.h>
#include <dom.h>
#include <tclexpat.h>
#include <fcntl.h>

#ifdef _MSC_VER
#include <io.h>
#else


#include <unistd.h>
#endif

/* Used internal als status, like TCL_OK, TCL_ERROR etc.  As a
   consequence, application specific error codes must be at least
   greater than 5 */
#define ERROR_IN_EXTREFHANDLER 5

#ifndef TDOM_EXPAT_READ_SIZE
# define TDOM_EXPAT_READ_SIZE (1024*8)
#endif
#ifndef O_BINARY
#ifdef _O_BINARY
#define O_BINARY _O_BINARY
#else
#define O_BINARY 0
#endif
#endif
................................................................................
                                */
TDomThreaded(static Tcl_Mutex counterMutex;) /* Protect the counter (zv) */

/*----------------------------------------------------------------------------
|   Prototypes for procedures defined later in this file:
|
\---------------------------------------------------------------------------*/
int             TclExpatObjCmd (ClientData dummy,
                    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
static int      TclExpatInstanceCmd (ClientData dummy,
                    Tcl_Interp *interp, int objc, struct Tcl_Obj *const objv[]);
static void     TclExpatDeleteCmd (ClientData clientData);

static Tcl_Obj* FindUniqueCmdName (Tcl_Interp *interp);
static int      TclExpatCheckWhiteData (char *pc, int len);

static int      TclExpatInitializeParser (Tcl_Interp *interp,
                    TclGenExpatInfo *expat, int resetOptions );
static void     TclExpatFreeParser  (TclGenExpatInfo *expat);
static int      TclExpatParse (Tcl_Interp *interp,
                    TclGenExpatInfo *expat, char *data, int len,
                               TclExpat_InputType type);
static int      TclExpatConfigure (Tcl_Interp *interp,
                    TclGenExpatInfo *expat, int objc, Tcl_Obj *const objv[]);
static int      TclExpatCget (Tcl_Interp *interp,
                    TclGenExpatInfo *expat, int objc, Tcl_Obj *const objv[]);

static int	TclExpatGet (Tcl_Interp *interp,
		    TclGenExpatInfo *expat, int objc, Tcl_Obj *const objv[]);
static void	TclExpatDispatchPCDATA (TclGenExpatInfo *expat);
static void TclGenExpatElementStartHandler (void *userdata,
                                            const XML_Char *name,
                                            const XML_Char **atts);
static void TclGenExpatElementEndHandler (void *userData,
                                          const XML_Char *name);
static void TclGenExpatCharacterDataHandler (void *userData,
                                             const XML_Char *s,
                                             int len);

static void 	TclGenExpatProcessingInstructionHandler (
	    	    void *userData, const XML_Char *target,
	    	    const XML_Char *data);
static int 	TclGenExpatExternalEntityRefHandler (
	    	    XML_Parser parser, const XML_Char *openEntityNames,
	    	    const XML_Char *base, const XML_Char *systemId,
	    	    const XML_Char *publicId);
static void 	TclGenExpatDefaultHandler (void *userData,
	    	    const XML_Char *s, int len);
static void 	TclGenExpatNotationDeclHandler (void *userData,
		    const XML_Char *notationName, const XML_Char *base,
		    const XML_Char *systemId, const XML_Char *publicId);
static int	TclGenExpatUnknownEncodingHandler (
		    void *encodingHandlerData, const XML_Char *name,
		    XML_Encoding *info);

static void  TclGenExpatStartNamespaceDeclHandler (void *userdata,
                                                   const XML_Char *prefix,
						   const XML_Char *uri);
static void  TclGenExpatEndNamespaceDeclHandler (void *userData,
						 const XML_Char *prefix);


/* Following added by ericm@scriptics, 1999.6.25 */
/* Prototype definition for the TclExpat comment handler */
static void 	TclGenExpatCommentHandler (void *userData,
					   const XML_Char *data);
/* Prototype for TclExpat Not Standalone Handler */
static int 	TclGenExpatNotStandaloneHandler (void *userData);

/* Prototype for TclExpat {Start|End}CdataSectionHandler */
static void 	TclGenExpatStartCdataSectionHandler (void *userData);
static void 	TclGenExpatEndCdataSectionHandler (void *userData);

/* Added by ericm@scriptics.com, 1999.09.13 */
/* Prototype for TclExpat (Element|Attlist) Declaration Handlers */
static void     TclGenExpatElementDeclHandler (void *userData,
                    const XML_Char *name, XML_Content *model);
static void     TclGenExpatAttlistDeclHandler (void *userData,
                    const XML_Char *elname, const XML_Char *name,
                    const XML_Char *type, const XML_Char *dflt,
                    int isrequired);
/* Prototypes for the TclExpat Doctype Decl handlers */
static void     TclGenExpatStartDoctypeDeclHandler (
    void *userData,
    const XML_Char *doctypeName,
    const XML_Char *sysid,
    const XML_Char *pubid,
    int has_internal_subset);
static void     TclGenExpatEndDoctypeDeclHandler (void *userData);
static void     TclGenExpatXmlDeclHandler (void *userData,
                                           const XML_Char *version,
                                           const XML_Char *encoding,
					   int standalone);
static void     TclGenExpatEntityDeclHandler (void *userData,
                                              const XML_Char *entityname,
                                              int is_param,
                                              const XML_Char *value,
                                              int length,
                                              const XML_Char *base,
                                              const XML_Char *systemId,
                                              const XML_Char *publicId,
					      const XML_Char *notationName);


/*
 *----------------------------------------------------------------------------
 *
 * CreateTclHandlerSet --
 *
 *	Malloc's and initializes a tclHandlerSet.
................................................................................
 *	Mallocs memory for the structure and the 'name' field, sets all
 *      handler scripts to NULL and inits some other fields.
 *
 *----------------------------------------------------------------------------
 */

static TclHandlerSet*
CreateTclHandlerSet (
    char *name

) {
    TclHandlerSet *handlerSet;

    handlerSet = (TclHandlerSet*) MALLOC (sizeof (TclHandlerSet)); \
    handlerSet->name                      = tdomstrdup (name);
    handlerSet->ignoreWhiteCDATAs         = 0;
    handlerSet->status                    = TCL_OK;
    handlerSet->continueCount             = 0;
................................................................................
 *	Mallocs memory for the 'name' of the structure, sets all
 *      handler functions to NULL and inits some other fields.
 *
 *----------------------------------------------------------------------------
 */

CHandlerSet*
CHandlerSetCreate (
    char *name

) {
    CHandlerSet *handlerSet;

    handlerSet = (CHandlerSet *) MALLOC (sizeof (CHandlerSet));
    handlerSet->name                     = tdomstrdup (name);
    handlerSet->ignoreWhiteCDATAs        = 0;
    handlerSet->nextHandlerSet           = NULL;

................................................................................
 * Side effects:
 *	This creates an expat parser.
 *
 *----------------------------------------------------------------------------
 */

int
TclExpatObjCmd(
    ClientData dummy,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[]

) {
  TclGenExpatInfo *genexpat;
  int ns_mode = 0;
  char *nsoption;


  /*
   * Create the data structures for this parser.
................................................................................
 * Side effects:
 *	Allocates Tcl object.
 *
 *----------------------------------------------------------------------------
 */

static Tcl_Obj *
FindUniqueCmdName(
    Tcl_Interp *interp

) {
  Tcl_Obj *name;
  Tcl_CmdInfo info;
  char s[20];

  name = Tcl_NewStringObj("", 0);
  Tcl_IncrRefCount(name);

................................................................................
 *	Creates or reset an expat parser.
 *	Modifies TclExpatInfo fields.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatInitializeParser(
    Tcl_Interp      *interp,
    TclGenExpatInfo *expat,
    int              resetOptions

) {
    CHandlerSet *activeCHandlerSet;
    ExpatElemContent *eContent, *eContentSave;

    if (expat->parser) {
        XML_ParserReset (expat->parser, NULL);
        activeCHandlerSet = expat->firstCHandlerSet;
        while (activeCHandlerSet) {
................................................................................
    }
    
    /*
     * Set handlers for the parser to routines in this module.
     */

    XML_SetElementHandler(expat->parser,
                          TclGenExpatElementStartHandler,
                          TclGenExpatElementEndHandler);
    XML_SetNamespaceDeclHandler(expat->parser,
                                TclGenExpatStartNamespaceDeclHandler,
                                TclGenExpatEndNamespaceDeclHandler);
    XML_SetCharacterDataHandler(expat->parser,
                                TclGenExpatCharacterDataHandler);
    XML_SetProcessingInstructionHandler(expat->parser,
                                        TclGenExpatProcessingInstructionHandler);
    XML_SetDefaultHandlerExpand(expat->parser, TclGenExpatDefaultHandler);


    XML_SetNotationDeclHandler(expat->parser,
                               TclGenExpatNotationDeclHandler);
    XML_SetExternalEntityRefHandler(expat->parser,
                                    TclGenExpatExternalEntityRefHandler);
    XML_SetUnknownEncodingHandler(expat->parser,
                                  TclGenExpatUnknownEncodingHandler,
                                  (void *) expat);


    XML_SetCommentHandler(expat->parser, TclGenExpatCommentHandler);

    XML_SetNotStandaloneHandler(expat->parser, 

                                TclGenExpatNotStandaloneHandler);
    XML_SetCdataSectionHandler(expat->parser, 
                               TclGenExpatStartCdataSectionHandler,
                               TclGenExpatEndCdataSectionHandler);

    XML_SetElementDeclHandler(expat->parser, TclGenExpatElementDeclHandler);

    XML_SetAttlistDeclHandler(expat->parser, TclGenExpatAttlistDeclHandler);

    XML_SetDoctypeDeclHandler(expat->parser,
                              TclGenExpatStartDoctypeDeclHandler,
                              TclGenExpatEndDoctypeDeclHandler);

    XML_SetXmlDeclHandler (expat->parser, TclGenExpatXmlDeclHandler);

    XML_SetEntityDeclHandler (expat->parser,
                              TclGenExpatEntityDeclHandler);
    if (expat->noexpand) {

        XML_SetDefaultHandler(expat->parser,
                              TclGenExpatDefaultHandler);
    } else {

        XML_SetDefaultHandlerExpand(expat->parser,
                                    TclGenExpatDefaultHandler);
    }
    
    XML_SetUserData(expat->parser, (void *) expat);
    
    return TCL_OK;
}

................................................................................
 *	Frees any memory allocated for the XML parser and (if still present)
 *      the stored content models.
 *
 *----------------------------------------------------------------------------
 */

static void
TclExpatFreeParser(
    TclGenExpatInfo *expat

) {
  ExpatElemContent *eContent, *eContentSave;

  eContent = expat->eContents;
  while (eContent) {
      XML_FreeContentModel (expat->parser, eContent->content);
      eContentSave = eContent;
      eContent = eContent->next;
................................................................................
  XML_ParserFree(expat->parser);
  expat->parser = NULL;
}

/*
 *----------------------------------------------------------------------------
 *
 * CurrentmarkupCommand --
 *
 *	Set as defaultHandler prior to XML_Currentmarkup() call.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Stores the markup context in expapt->currentmarkup.
 *
 *----------------------------------------------------------------------------
 */
static void
CurrentmarkupCommand (
    void *userData,
    const char *s,
    int len
) {
    TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;

    if (expat->status != TCL_OK) {
        return;
    }
  
    if (expat->cdata) {
        /* TclGenExpatCharacterDataHandler() was called and
         * initialized expat->cdata, but expat->cdata isn't reset by
         * TclExpatDispatchPCDATA(), so we're called from
         * -characterdatacommand and return the empty string by
         * definition. */
        expat->currentmarkup = NULL;
        expat->currentmarkuplen = 0;
        return;
    }
    expat->currentmarkup = s;
    expat->currentmarkuplen = len;
    return;
}



/*
 *----------------------------------------------------------------------------
 *
 * TclExpatInstanceCmd --
 *
 *	Implements instance command for expat class objects.
 *
 * Results:
 *	Depends on the method.
 *
................................................................................
 * Side effects:
 *	Depends on the method.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatInstanceCmd (
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[]

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) clientData;
  char *data;
  int len = 0, optionIndex, result = TCL_OK;

  static const char *options[] = {
      "configure", "cget", "currentmarkup", "free", "get",
      "parse", "parsechannel", "parsefile", "reset", "delete",
      NULL
  };
  enum options {
      EXPAT_CONFIGURE, EXPAT_CGET, EXPAT_CURRENTMARKUP, EXPAT_FREE, EXPAT_GET,
      EXPAT_PARSE, EXPAT_PARSECHANNEL, EXPAT_PARSEFILE, EXPAT_RESET,
      EXPAT_DELETE
  };


  if (objc < 2) {
      Tcl_SetResult (interp, 
                     "wrong # args: should be \"parserCmd method ?arg ...?\"",
                     TCL_STATIC);
................................................................................

    case EXPAT_CGET:

        CheckArgs (3,5,2, "?-handlerset handlersetname? switch");
        result = TclExpatCget(interp, expat, objc - 2, objv + 2);
        break;

    case EXPAT_CURRENTMARKUP:

        CheckArgs (2,2,1, "");
        if (expat->parsingState < 2) {
            Tcl_ResetResult(expat->interp);
            break;
        }
        
        XML_SetDefaultHandlerExpand(expat->parser,
                                    CurrentmarkupCommand);
        XML_DefaultCurrent(expat->parser);
        if (expat->currentmarkuplen) {
            Tcl_SetObjResult(expat->interp, 
                             Tcl_NewStringObj(expat->currentmarkup,
                                              expat->currentmarkuplen));
        } else {
            Tcl_ResetResult(expat->interp);
        }
        expat->currentmarkup = NULL;
        expat->currentmarkuplen = 0;
        if (expat->noexpand) {
            XML_SetDefaultHandler(expat->parser,
                                  TclGenExpatDefaultHandler);
        } else {
            XML_SetDefaultHandlerExpand(expat->parser,
                                        TclGenExpatDefaultHandler);
        }
        result = TCL_OK;
        break;

    case EXPAT_DELETE:
    case EXPAT_FREE:

        CheckArgs (2,2,1,"");

        if (expat->parsingState > 1) {
            Tcl_SetResult (interp, "parser delete not allowed from within "
                           "callback", TCL_STATIC);
            result = TCL_ERROR;
        } else {
            Tcl_DeleteCommand(interp, Tcl_GetString(expat->name));
            result = TCL_OK;
        }
	break;

    case EXPAT_GET:

        CheckArgs (3,3,2,"<option>");
        /* ericm@scriptics.com, 1999.6.28 */
        result = TclExpatGet(interp, expat, objc - 2, objv + 2);
        break;

    case EXPAT_PARSE:

        CheckArgs (3,3,2,"<XML-String>");
................................................................................
 * Side effects:
 *     Sets interpreter result as appropriate.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatParse (
    Tcl_Interp *interp,
    TclGenExpatInfo *expat,
    char *data,
    int len,
    TclExpat_InputType type

) {
  int result, mode, done;
  size_t bytesread;
  char s[255], buf[8*1024];
  int fd;
  XML_Parser  parser;
  Tcl_Channel channel = NULL;
  CHandlerSet *activeCHandlerSet;

  Tcl_Obj       *bufObj = NULL;
  Tcl_DString    dStr;
  int            useBinary;
  char          *str;


  if (expat->finished) {
      if ((result = TclExpatInitializeParser (interp, expat, 0)) != TCL_OK) 
          return TCL_ERROR;
  }

  if (!expat->parsingState) {
................................................................................
      }
      if (!(mode & TCL_READABLE)) {
          Tcl_ResetResult (interp);
          Tcl_AppendResult (interp, "channel \"", data,
                            "wasn't opened for reading", (char *) NULL);
          return TCL_ERROR;
      }

      Tcl_DStringInit (&dStr);
      if (Tcl_GetChannelOption (interp, channel, "-encoding", &dStr) 
          != TCL_OK) {
          return TCL_ERROR;
      }
      if (strcmp (Tcl_DStringValue (&dStr), "binary")==0 ) useBinary = 1;
      else useBinary = 0;
      Tcl_DStringFree (&dStr);
      expat->parsingState = 2;
      if (useBinary) {
          do {
              bytesread = Tcl_Read (channel, buf, sizeof (buf));
              done = bytesread < sizeof (buf);

              result = XML_Parse (expat->parser, buf, bytesread, done);






              if (result != XML_STATUS_OK) break;
          } while (!done);
      } else {
          bufObj = Tcl_NewObj();
          Tcl_IncrRefCount (bufObj);
          Tcl_SetObjLength (bufObj, 6144);
          do {
              len = Tcl_ReadChars (channel, bufObj, 1024, 0);
              done = (len < 1024);
              str = Tcl_GetStringFromObj (bufObj, &len);
              result = XML_Parse (expat->parser, str, len, done);
              if (result != XML_STATUS_OK) break;


          } while (!done);
          /* In case of a parsing error we need the string rep of the
             bufObj until the error reporting is done (otherwise,
             calling XML_GetCurrentLineNumber() results in invalid mem
             reads */
          if (result) {
              Tcl_DecrRefCount (bufObj);
          }
      }















      expat->parsingState = 1;
      break;

  case EXPAT_INPUT_FILENAME:
      fd = open(data, O_BINARY|O_RDONLY);
      if (fd < 0) {
          Tcl_ResetResult (interp);
................................................................................
                            data, "\"", (char *) NULL);
          return TCL_ERROR;
      }
      parser = expat->parser;
      expat->parsingState = 2;
      for (;;) {
          int nread;
          char *fbuf = XML_GetBuffer (parser, TDOM_EXPAT_READ_SIZE);
          if (!fbuf) {
              close (fd);
              Tcl_ResetResult (interp);
              Tcl_SetResult (interp, "Out of memory\n", NULL);
              expat->parsingState = 1;
              return TCL_ERROR;
          }
          nread = read(fd, fbuf, TDOM_EXPAT_READ_SIZE);
          if (nread < 0) {
              close (fd);
              Tcl_ResetResult (interp);
              Tcl_AppendResult (interp, "error reading from file \"",
                                data, "\"", (char *) NULL);
              expat->parsingState = 1;
              return TCL_ERROR;
          }
          result = XML_ParseBuffer (parser, nread, nread == 0);
          if (result != XML_STATUS_OK || !nread) {
              close (fd);





              break;
          }
      }
      expat->parsingState = 1;
      break;
  }

................................................................................
          sprintf(s, "%ld", XML_GetCurrentLineNumber(expat->parser));
          Tcl_AppendResult(interp, "error \"",
                           XML_ErrorString(XML_GetErrorCode(expat->parser)),
                           "\" at line ", s, " character ", NULL);
          sprintf(s, "%ld", XML_GetCurrentColumnNumber(expat->parser));
          Tcl_AppendResult(interp, s, NULL);
      }

      if (bufObj) {
          Tcl_DecrRefCount (bufObj);
      }

      return TCL_ERROR;
  }
  switch (expat->status) {
    case TCL_OK:
    case TCL_BREAK:
    case TCL_CONTINUE:
    case TCL_RETURN:
      Tcl_ResetResult(interp);
      return TCL_OK;

    case TCL_ERROR:
      Tcl_SetObjResult(interp, expat->result);
      return TCL_ERROR;

................................................................................
 * Side effects:
 *	Depends on the method.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatConfigure (
    Tcl_Interp *interp,
    TclGenExpatInfo *expat,
    int objc,
    Tcl_Obj *const objv[]

) {
  static const char *switches[] = {
    "-final",
    "-baseurl",
    "-elementstartcommand",
    "-elementendcommand",
    "-characterdatacommand",
    "-processinginstructioncommand",
    "-defaultcommand",
................................................................................
    EXPAT_XMLDECLCMD,
    EXPAT_PARAMENTITYPARSING,
    EXPAT_ENTITYDECLCOMMAND,
    EXPAT_NOWHITESPACE,
    EXPAT_HANDLERSET,
    EXPAT_NOEXPAND
  };
  static const char *paramEntityParsingValues[] = {
      "always",
      "never",
      "notstandalone",
      (char *) NULL
  };
  enum paramEntityParsingValues {
      EXPAT_PARAMENTITYPARSINGALWAYS,
      EXPAT_PARAMENTITYPARSINGNEVER,
      EXPAT_PARAMENTITYPARSINGNOTSTANDALONE
  };
  int optionIndex, value, bool;
  Tcl_Obj *const *objPtr = objv;
  Tcl_CmdInfo cmdInfo;
  int rc;
  char *handlerSetName = NULL;
  TclHandlerSet *tmpTclHandlerSet, *activeTclHandlerSet = NULL;

  if (expat->firstTclHandlerSet 
      && (strcmp ("default", expat->firstTclHandlerSet->name)==0)) {
................................................................................
	Tcl_IncrRefCount(activeTclHandlerSet->elementstartcommand);
        rc = Tcl_GetCommandInfo(interp, Tcl_GetString(objPtr[1]), &cmdInfo);
        if (rc && cmdInfo.isNativeObjectProc) {
            activeTclHandlerSet->elementstartObjProc = cmdInfo.objProc;
            activeTclHandlerSet->elementstartclientData 
                = cmdInfo.objClientData;
        } else {

            activeTclHandlerSet->elementstartObjProc = NULL;
        }
	break;

      case EXPAT_ELEMENTENDCMD:		/* -elementendcommand */

        CheckDefaultTclHandlerSet;
................................................................................
	activeTclHandlerSet->elementendcommand = objPtr[1];
	Tcl_IncrRefCount(activeTclHandlerSet->elementendcommand);
        rc = Tcl_GetCommandInfo(interp, Tcl_GetString(objPtr[1]), &cmdInfo);
        if (rc && cmdInfo.isNativeObjectProc) {
            activeTclHandlerSet->elementendObjProc = cmdInfo.objProc;
            activeTclHandlerSet->elementendclientData = cmdInfo.objClientData;
        } else {

            activeTclHandlerSet->elementendObjProc = NULL;
        }
	break;

      case EXPAT_STARTNAMESPACEDECLCMD:	/* -startnamespacedeclcommand */

        CheckDefaultTclHandlerSet;
................................................................................
	activeTclHandlerSet->datacommand = objPtr[1];
	Tcl_IncrRefCount(activeTclHandlerSet->datacommand);
        rc = Tcl_GetCommandInfo (interp, Tcl_GetString(objPtr[1]), &cmdInfo);
        if (rc && cmdInfo.isNativeObjectProc) {
            activeTclHandlerSet->datacommandObjProc = cmdInfo.objProc;
            activeTclHandlerSet->datacommandclientData = cmdInfo.objClientData;
        } else {

            activeTclHandlerSet->datacommandObjProc = NULL;
        }
	break;

      case EXPAT_PICMD:			/* -processinginstructioncommand */

        CheckDefaultTclHandlerSet;
................................................................................
        break;

    case EXPAT_NOEXPAND:
        if (Tcl_GetBooleanFromObj (interp, objv[1], &bool) != TCL_OK) {
            return TCL_ERROR;
        }
        if (bool) {

            XML_SetDefaultHandler( expat->parser,
                                   TclGenExpatDefaultHandler);

        } else {

            XML_SetDefaultHandlerExpand( expat->parser,
                                         TclGenExpatDefaultHandler);
        }
        expat->noexpand = bool;
        break;

    }

    objPtr += 2;
................................................................................
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatCget (
    Tcl_Interp *interp,
    TclGenExpatInfo *expat,
    int objc,
    Tcl_Obj *const objv[]

) {
    static const char *switches[] = {
        "-final",
        "-baseurl",
        "-elementstartcommand",
        "-elementendcommand",
        "-characterdatacommand",
        "-processinginstructioncommand",
        "-defaultcommand",
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------------
 */
static int
TclExpatGet (
    Tcl_Interp *interp,
    TclGenExpatInfo *expat,
    int objc,
    Tcl_Obj *const objv[]
)
{
  static const char *getSwitches[] = {
    "-specifiedattributecount",
    "-currentbytecount",
    "-currentlinenumber",
    "-currentcolumnnumber",
    "-currentbyteindex",
    (char *) NULL
  };
................................................................................
    EXPAT_CURRENTLINENUMBER,
    EXPAT_CURRENTCOLUMNNUMBER,
    EXPAT_CURRENTBYTEINDEX
  };
  int switchIndex;
  Tcl_Obj *resultPtr;







  if (Tcl_GetIndexFromObj(interp, objv[0], getSwitches,
			  "switch", 0, &switchIndex) != TCL_OK) {
    return TCL_ERROR;
  }
  resultPtr = Tcl_GetObjResult(interp);

  switch ((enum getSwitch) switchIndex) {
................................................................................
 * Side Effects:
 *	Further invocation of callback scripts may be inhibited.
 *
 *----------------------------------------------------------------------------
 */

static void
TclExpatHandlerResult(
    TclGenExpatInfo *expat,
    TclHandlerSet *handlerSet,
    int result

) {
  switch (result) {
    case TCL_OK:
      handlerSet->status = TCL_OK;
      Tcl_ResetResult (expat->interp);
      break;

    case TCL_CONTINUE:
      /*
       * Skip callbacks until the matching end element event
       * occurs for the currently open element.
       * Keep a reference count to handle nested
       * elements.
       */
      handlerSet->status = TCL_CONTINUE;
      handlerSet->continueCount = 1;
      Tcl_ResetResult (expat->interp);
      break;

    case TCL_BREAK:
      /*
       * Skip all further callbacks of this handlerSet, but return OK.
       */
      handlerSet->status = TCL_BREAK;
      Tcl_ResetResult (expat->interp);
      break;

    case TCL_ERROR:
      /*
       * Cancel parsing and return error.
       */
      expat->status = TCL_ERROR;
      XML_StopParser (expat->parser, 1);
      expat->result = Tcl_GetObjResult(expat->interp);
      Tcl_IncrRefCount(expat->result);
      break;

    case TCL_RETURN:
      /*
       * Cancel parser and return OK.
       */
      expat->status = TCL_RETURN;
      XML_StopParser (expat->parser, 1);
      expat->result = Tcl_NewObj ();
      Tcl_IncrRefCount(expat->result);
      break;
      
    default:
      /*
       * Cancel parser and return the error code.
       */
      expat->status = result;
      XML_StopParser (expat->parser, 1);
      expat->result = Tcl_GetObjResult(expat->interp);
      Tcl_IncrRefCount(expat->result);
      break;
  }
}

/*
................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatElementStartHandler(
    void *userData,
    const char *name,
    const char **atts

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *atList = NULL;
  const char **atPtr;
  int result;
  Tcl_Obj *vector[3];
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;
................................................................................
              cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->elementstartcommand);
              Tcl_IncrRefCount(cmdPtr);
              Tcl_Preserve((ClientData) expat->interp);

              Tcl_ListObjAppendElement(expat->interp, cmdPtr,
                                       Tcl_NewStringObj((char *)name, -1));
              Tcl_ListObjAppendElement(expat->interp, cmdPtr, atList);





#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
              result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
              result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                                     TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatElementEndHandler(
    void *userData,
    const char *name

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  int result;
  Tcl_Obj *vector[2], *ename = NULL;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;
  Tcl_Obj      *cmdPtr;

................................................................................

              cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->elementendcommand);
              Tcl_IncrRefCount(cmdPtr);
              Tcl_Preserve((ClientData) expat->interp);

              Tcl_ListObjAppendElement(expat->interp, cmdPtr,
                                       Tcl_NewStringObj((char *)name, -1));





#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
              result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
              result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                                     TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT );
#endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatStartNamespaceDeclHandler(
    void       *userData,
    const char *prefix,
    const char *uri

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj      *cmdPtr;
  int           result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  if (expat->status != TCL_OK) {
................................................................................
      Tcl_IncrRefCount(cmdPtr);
      Tcl_Preserve((ClientData) expat->interp);

      Tcl_ListObjAppendElement(expat->interp, cmdPtr,
                               Tcl_NewStringObj((char *)prefix, -1));
      Tcl_ListObjAppendElement(expat->interp, cmdPtr,
                               Tcl_NewStringObj((char *)uri,    -1));





#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
      result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
      result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatEndNamespaceDeclHandler(
    void       *userData,
    const char *prefix

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  if (expat->status != TCL_OK) {
................................................................................
       */

      cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->endnsdeclcommand);
      Tcl_IncrRefCount(cmdPtr);
      Tcl_Preserve((ClientData) expat->interp);

      Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)prefix, -1));





#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
      result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
      result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Results:
 *	1 if string contains just white characters
 *
 *----------------------------------------------------------------------------
 */

static int
TclExpatCheckWhiteData (
    char         *pc,
    int           len

) {
    for (; len > 0; len--, pc++) {
        if ( (*pc != ' ')  &&
             (*pc != '\t') &&
             (*pc != '\n') &&
             (*pc != '\r') ) {
            return 0;
        }
................................................................................
 * Side Effects:
 *	Callback script is invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatCharacterDataHandler(
    void *userData,
    const char *s,
    int len

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;

  if (expat->status != TCL_OK) {
      return;
  }

  if (!expat->cdata) {
................................................................................
 * Side Effects:
 *	Callback script evaluated.
 *
 *----------------------------------------------------------------------------
 */

static void
TclExpatDispatchPCDATA(
    TclGenExpatInfo *expat

) {
  int len, result, onlyWhiteSpace = 0;
  Tcl_Obj *vector[2];
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;
  Tcl_Obj* cmdPtr;
  char *s;

................................................................................
           */
          cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->datacommand);
          Tcl_IncrRefCount(cmdPtr);
          Tcl_Preserve((ClientData) expat->interp);

          Tcl_ListObjAppendElement(expat->interp, cmdPtr,
                                   Tcl_NewStringObj((char *)s, len));





#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
          result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
          result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                                 TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
              activeCHandlerSet->datacommand (activeCHandlerSet->userData,
                                              s, len);
          }
      }
      activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
  }
  Tcl_DecrRefCount (expat->cdata);
  expat->cdata = NULL;
  return;
}


/*
 *----------------------------------------------------------------------------
 *
................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatProcessingInstructionHandler(
    void *userData,
    const char *target,
    const char *data

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  if (expat->status != TCL_OK) {
................................................................................

      cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->picommand);
      Tcl_IncrRefCount(cmdPtr);
      Tcl_Preserve((ClientData) expat->interp);

      Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)target, strlen(target)));
      Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)data, strlen(data)));





#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
      result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
      result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatDefaultHandler(
    void *userData,
    const char *s,
    int len

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);
................................................................................
       */

      cmdPtr = Tcl_DuplicateObj(activeTclHandlerSet->defaultcommand);
      Tcl_IncrRefCount(cmdPtr);
      Tcl_Preserve((ClientData) expat->interp);

      Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)s, len));





#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
      result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
      result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatEntityDeclHandler(
    void *userData,
    const char *entityname,
    int         is_param,
    const char *value,
    int         length,
    const char *base,
    const char *systemId,
    const char *publicId,
    const char *notationName

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);
................................................................................
          Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)publicId, strlen(publicId)));
      }
      if (notationName == NULL) {
          Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewListObj(0, NULL));
      } else {
          Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)notationName, strlen(notationName)));
      }





#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
      result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
      result = Tcl_EvalObjEx(expat->interp, cmdPtr,
                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static void
TclGenExpatNotationDeclHandler(
    void *userData,
    const char *notationName,
    const char *base,
    const char *systemId,
    const char *publicId

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);
................................................................................
          Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)systemId, strlen(systemId)));
      }
      if (publicId == NULL) {
          Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewListObj(0, NULL));
      } else {
          Tcl_ListObjAppendElement(expat->interp, cmdPtr, Tcl_NewStringObj((char *)publicId, strlen(publicId)));
      }





#if (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0)
      result = Tcl_GlobalEvalObj(expat->interp, cmdPtr);
#else
      result = Tcl_EvalObjEx(expat->interp, cmdPtr, 
                             TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
#endif /* if TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 0 */

................................................................................
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */

static int
TclGenExpatUnknownEncodingHandler(
    void *encodingHandlerData,
    const char *name,
    XML_Encoding *info

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) encodingHandlerData;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);

  if (expat->status != TCL_OK) {
      return 1;
................................................................................
 *
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */
static int
TclGenExpatExternalEntityRefHandler(

    XML_Parser parser,
    const char *openEntityNames,
    const char *base,
    const char *systemId,
    const char *publicId

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) XML_GetUserData(parser);
  Tcl_Obj *cmdPtr, *resultObj, *resultTypeObj, *extbaseObj, *dataObj;
  int result, mode, done, fd, tclLen;
  size_t len;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;
  XML_Parser extparser, oldparser = NULL;
................................................................................
              expat->parser = oldparser;
              return 0;
          }
          result = 1;
          do {
              len = Tcl_Read (chan, buf, sizeof (buf));
              done = len < sizeof (buf);
              result = XML_Parse (extparser, buf, len, done);
              if (result != XML_STATUS_OK) break;


          } while (!done);
          Tcl_UnregisterChannel (expat->interp, chan);
          break;

      case EXPAT_INPUT_FILENAME:
          fd = open(dataStr, O_BINARY|O_RDONLY);
          if (fd < 0) {
................................................................................
              XML_ParserFree (extparser);
              expat->parser = oldparser;
              return 0;
          }
          result = 1;
          for (;;) {
              int nread;
              char *fbuf = XML_GetBuffer (extparser, TDOM_EXPAT_READ_SIZE);
              if (!fbuf) {
                  close (fd);
                  Tcl_ResetResult (expat->interp);
                  Tcl_SetResult (expat->interp, "Out of memory\n", NULL);
                  TclExpatHandlerResult (expat, activeTclHandlerSet,
                                         ERROR_IN_EXTREFHANDLER);
                  return 0;
              }
              nread = read(fd, fbuf, TDOM_EXPAT_READ_SIZE);
              if (nread < 0) {
                  close (fd);
                  Tcl_ResetResult (expat->interp);
                  Tcl_AppendResult (expat->interp,
                                    "error reading from file \"",
                                    dataStr, "\"", (char *) NULL);
                  TclExpatHandlerResult (expat, activeTclHandlerSet,
                                         ERROR_IN_EXTREFHANDLER);
                  return 0;
              }
              result = XML_ParseBuffer (extparser, nread, nread == 0);
              if (result != XML_STATUS_OK || !nread) {
                  close (fd);





                  break;
              }
          }
          break;
      }

      Tcl_DecrRefCount (resultObj);
................................................................................
          TclExpatHandlerResult(expat, activeTclHandlerSet,
                                ERROR_IN_EXTREFHANDLER);
          return 0;
      }
      
      /* The last node in the external entity may be a text node. To call 
         TclExpatDispatchPCDATA, before switching back to the old parser
         ensures, that last text node has the right base URI. */
      TclExpatDispatchPCDATA(expat);

      XML_ParserFree (extparser);
      expat->parser = oldparser;

      activeCHandlerSet = expat->firstCHandlerSet;
      while (activeCHandlerSet) {
................................................................................
 *
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */
static void
TclGenExpatCommentHandler(
    void *userData,
    const char *data

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;


................................................................................
 *
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */
static int
TclGenExpatNotStandaloneHandler(
    void *userData

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);
................................................................................
 *
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */
static void
TclGenExpatStartCdataSectionHandler(
    void *userData

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  if (expat->status != TCL_OK) {
................................................................................
 *
 * Side Effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------------
 */
static void
TclGenExpatEndCdataSectionHandler(
    void *userData

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  if (expat->status != TCL_OK) {
................................................................................
      activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
  }
  return;
}


static void
generateModel (
	       Tcl_Interp  *interp,
	       Tcl_Obj     *rep,
	       XML_Content *model

) {
    Tcl_Obj *cp, *detail;
    unsigned int      i;


    switch (model->type) {
    case XML_CTYPE_EMPTY:
        Tcl_ListObjAppendElement (interp, rep, Tcl_NewStringObj ("EMPTY", 5));
................................................................................
 * Side effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------
 */

static void
TclGenExpatElementDeclHandler(
    void *userData,
    const XML_Char *name,
    XML_Content *model

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  Tcl_Obj *content;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;
  ExpatElemContent *eContent;
................................................................................
 * Side effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------
 */

static void
TclGenExpatAttlistDeclHandler(
    void           *userData,
    const XML_Char *elname,
    const XML_Char *name,
    const XML_Char *type,
    const XML_Char *dflt,
    int             isrequired

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);
................................................................................
 * Side effects:
 *	Callback scripts are invoked.
 *
 *----------------------------------------------------------------------
 */

static void
TclGenExpatStartDoctypeDeclHandler(
    void *userData,
    const XML_Char *doctypeName,
    const XML_Char *sysid,
    const XML_Char *pubid,
    int   has_internal_subset

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;

  TclExpatDispatchPCDATA(expat);
................................................................................
 * Side effects:
 *	Callback script is invoked.
 *
 *----------------------------------------------------------------------
 */

static void
TclGenExpatEndDoctypeDeclHandler(
    void *userData

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
  Tcl_Obj *cmdPtr;
  int result;
  TclHandlerSet *activeTclHandlerSet;
  CHandlerSet *activeCHandlerSet;
  ExpatElemContent *eContent, *eContentSave;

................................................................................
 * Side effects:
 *	Callback script is invoked.
 *
 *----------------------------------------------------------------------
 */

static void
TclGenExpatXmlDeclHandler (
    void *userData,
    const char *version,
    const char *encoding,
    int   standalone

) {
    TclGenExpatInfo *expat = (TclGenExpatInfo *) userData;
    Tcl_Obj *cmdPtr;
    int result;
    TclHandlerSet *activeTclHandlerSet;
    CHandlerSet *activeCHandlerSet;

    if (expat->status != TCL_OK) {
................................................................................
 * Side Effects:
 *	Memory structures are freed.
 *
 *----------------------------------------------------------------------------
 */

static void
TclExpatDeleteCmd(
    ClientData clientData

) {
  TclGenExpatInfo *expat = (TclGenExpatInfo *) clientData;
  TclHandlerSet *activeTclHandlerSet, *tmpTclHandlerSet;
  CHandlerSet *activeCHandlerSet, *tmpCHandlerSet;

  TclExpatFreeParser(expat);

  Tcl_DecrRefCount(expat->name);
................................................................................
  }

  FREE( (char*) expat);
}


int
CheckExpatParserObj (
    Tcl_Interp *interp,
    Tcl_Obj *const nameObj

) {
    Tcl_CmdInfo info;


    if (!Tcl_GetCommandInfo (interp, Tcl_GetString(nameObj), &info)) {
        return 0;
    }
    if (!info.isNativeObjectProc || info.objProc != TclExpatInstanceCmd) {
        return 0;
    }
    return 1;
}

int
CHandlerSetInstall (
    Tcl_Interp *interp,
    Tcl_Obj *const expatObj,
    CHandlerSet *handlerSet

) {
    Tcl_CmdInfo info;
    TclGenExpatInfo *expat;
    CHandlerSet *activeCHandlerSet;

    if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
        return 1;
    }
................................................................................
        activeCHandlerSet = expat->firstCHandlerSet;
        while (1) {
            if (strcmp (activeCHandlerSet->name, handlerSet->name) == 0) {
                return 2;
            }
            if (activeCHandlerSet->nextHandlerSet == NULL) {
                break;

            } else {
                activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
            }
        }
        activeCHandlerSet->nextHandlerSet = handlerSet;
    }
    else {
        expat->firstCHandlerSet = handlerSet;
................................................................................
    if (handlerSet->ignoreWhiteCDATAs) {
        expat->needWSCheck = 1;
    }
    return 0;
}

int
CHandlerSetRemove (
    Tcl_Interp *interp,
    Tcl_Obj *const expatObj,
    char *handlerSetName

) {
    Tcl_CmdInfo info;
    TclGenExpatInfo *expat;
    CHandlerSet *activeCHandlerSet, *parentHandlerSet = NULL;

    if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
        return 1;
    }
................................................................................
        parentHandlerSet = activeCHandlerSet;
        activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
    }
    return 2;
}

CHandlerSet *
CHandlerSetGet (
    Tcl_Interp *interp,
    Tcl_Obj *const expatObj,
    char *handlerSetName

) {
    Tcl_CmdInfo info;
    TclGenExpatInfo *expat;
    CHandlerSet *activeCHandlerSet;

    if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
        return NULL;
    }
................................................................................
        }
        activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
    }
    return NULL;
}

void *
CHandlerSetGetUserData (
    Tcl_Interp *interp,
    Tcl_Obj *const expatObj,
    char *handlerSetName

) {
    Tcl_CmdInfo info;
    TclGenExpatInfo *expat;
    CHandlerSet *activeCHandlerSet;

    if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
        return NULL;
    }
................................................................................
        }
        activeCHandlerSet = activeCHandlerSet->nextHandlerSet;
    }
    return NULL;
}

TclGenExpatInfo *
GetExpatInfo (
    Tcl_Interp *interp,
    Tcl_Obj *const expatObj

) {
    Tcl_CmdInfo info;
    if (!Tcl_GetCommandInfo (interp, Tcl_GetString(expatObj), &info)) {
        return NULL;
    }
    return (TclGenExpatInfo *) info.objClientData;
}

Changes to generic/tclexpat.h.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
130
131
132
133
134
135
136


137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172


typedef struct CHandlerSet {
    struct CHandlerSet *nextHandlerSet;
    char *name;                     /* refname of the handler set */
    int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */

    void *userData;                 /* Handler set specific Data Structure;
                                       the C handler set extention has to
                                       malloc the needed structure in his
                                       init func and has to provide a
                                       cleanup func (to free it). */

    CHandlerSet_userDataReset        resetProc;
    CHandlerSet_userDataFree         freeProc;
    CHandlerSet_parserReset          parserResetProc;
................................................................................
    int parsingState;           /* 0 == freshly (re-)initialized
                                   1 == initParserProcs called
                                   2 == parsing an input chunk */
    XML_Char nsSeparator;       
    int paramentityparsing;     
    int noexpand;
    int useForeignDTD;



    TclHandlerSet *firstTclHandlerSet;
    CHandlerSet *firstCHandlerSet;
} TclGenExpatInfo;

/*--------------------------------------------------------------------------
|   Function prototypes
|
\-------------------------------------------------------------------------*/

#if defined(_MSC_VER) || defined(BUILD_tdom)
#  undef TCL_STORAGE_CLASS
#  define TCL_STORAGE_CLASS DLLEXPORT
#endif

EXTERN int TclExpatObjCmd _ANSI_ARGS_((ClientData dummy,

                                       Tcl_Interp *interp,
                                       int objc, Tcl_Obj *CONST objv[]));
EXTERN int CheckExpatParserObj _ANSI_ARGS_((Tcl_Interp *interp,
                                            Tcl_Obj *CONST nameObj));
EXTERN int CHandlerSetInstall _ANSI_ARGS_((Tcl_Interp *interp,
                                           Tcl_Obj *CONST expatObj,
                                           CHandlerSet *handlerSet));
EXTERN int CHandlerSetRemove _ANSI_ARGS_((Tcl_Interp *interp,
                                          Tcl_Obj *CONST expatObj,
                                          char *handlerSetName));
EXTERN CHandlerSet * CHandlerSetCreate _ANSI_ARGS_((char *name));
EXTERN CHandlerSet * CHandlerSetGet _ANSI_ARGS_((Tcl_Interp *interp,
                                               Tcl_Obj *CONST expatObj,
                                               char *handlerSetName));
EXTERN void * CHandlerSetGetUserData _ANSI_ARGS_((Tcl_Interp *interp,
                                               Tcl_Obj *CONST expatObj,
                                               char *handlerSetName));

EXTERN TclGenExpatInfo * GetExpatInfo _ANSI_ARGS_((Tcl_Interp *interp,
                                                   Tcl_Obj *CONST expatObj));








|







 







>
>
|









|




|
>
|
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
<
>
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

173

typedef struct CHandlerSet {
    struct CHandlerSet *nextHandlerSet;
    char *name;                     /* refname of the handler set */
    int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */

    void *userData;                 /* Handler set specific Data Structure;
                                       the C handler set extension has to
                                       malloc the needed structure in his
                                       init func and has to provide a
                                       cleanup func (to free it). */

    CHandlerSet_userDataReset        resetProc;
    CHandlerSet_userDataFree         freeProc;
    CHandlerSet_parserReset          parserResetProc;
................................................................................
    int parsingState;           /* 0 == freshly (re-)initialized
                                   1 == initParserProcs called
                                   2 == parsing an input chunk */
    XML_Char nsSeparator;       
    int paramentityparsing;     
    int noexpand;
    int useForeignDTD;
    const char *currentmarkup;  /* Used to transfer data for method */
    int currentmarkuplen;       /* currentmarkup */
 
    TclHandlerSet *firstTclHandlerSet;
    CHandlerSet *firstCHandlerSet;
} TclGenExpatInfo;

/*--------------------------------------------------------------------------
|   Function prototypes
|
\-------------------------------------------------------------------------*/

#if defined(_MSC_VER) || defined(BUILD_tdom) || defined(__MINGW32__) 
#  undef TCL_STORAGE_CLASS
#  define TCL_STORAGE_CLASS DLLEXPORT
#endif

EXTERN Tcl_ObjCmdProc TclExpatObjCmd;

EXTERN int CheckExpatParserObj (Tcl_Interp *interp,


				Tcl_Obj *const nameObj);
EXTERN int CHandlerSetInstall (Tcl_Interp *interp,
			       Tcl_Obj *const expatObj,
			       CHandlerSet *handlerSet);
EXTERN int CHandlerSetRemove (Tcl_Interp *interp,
			      Tcl_Obj *const expatObj,
			      char *handlerSetName);
EXTERN CHandlerSet * CHandlerSetCreate (char *name);
EXTERN CHandlerSet * CHandlerSetGet (Tcl_Interp *interp,
                                     Tcl_Obj *const expatObj,
				     char *handlerSetName);
EXTERN void * CHandlerSetGetUserData (Tcl_Interp *interp,
                                      Tcl_Obj *const expatObj,
				      char *handlerSetName);

EXTERN TclGenExpatInfo * GetExpatInfo (Tcl_Interp *interp,

				       Tcl_Obj *const expatObj);

Added generic/tclpull.c.







































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
/*----------------------------------------------------------------------------
|   Copyright (c) 2018  Rolf Ade (rolf@pointsman.de)
|-----------------------------------------------------------------------------
|
|
|   The contents of this file are subject to the Mozilla Public License
|   Version 1.1 (the "License"); you may not use this file except in
|   compliance with the License. You may obtain a copy of the License at
|   http://www.mozilla.org/MPL/
|
|   Software distributed under the License is distributed on an "AS IS"
|   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|   License for the specific language governing rights and limitations
|   under the License.
|
|   Contributor(s):
|
|
|   written by Rolf Ade
|   February 2018
|
\---------------------------------------------------------------------------*/

#ifndef TDOM_NO_PULL

#include <tdom.h>
#include <fcntl.h>
#ifdef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#endif

#ifndef O_BINARY
#ifdef _O_BINARY
#define O_BINARY _O_BINARY
#else
#define O_BINARY 0
#endif
#endif

#ifndef TDOM_EXPAT_READ_SIZE
# define TDOM_EXPAT_READ_SIZE (1024*8)
#endif

/* For information about why this work-around for a certain expat
 * version is necessary see
 * https://github.com/libexpat/libexpat/issues/204 */
#if (XML_MAJOR_VERSION == 2) && (XML_MINOR_VERSION == 2) && (XML_MICRO_VERSION == 5)
# define EXPAT_RESUME_BUG
#endif

/* #define DEBUG */
/*----------------------------------------------------------------------------
|   Debug Macros
|
\---------------------------------------------------------------------------*/
#ifdef DEBUG
# define DBG(x) x
#else
# define DBG(x) 
#endif

typedef enum {
    PULLPARSERSTATE_READY,
    PULLPARSERSTATE_START_DOCUMENT,
    PULLPARSERSTATE_END_DOCUMENT,
    PULLPARSERSTATE_START_TAG,
    PULLPARSERSTATE_END_TAG,
    PULLPARSERSTATE_TEXT,
    PULLPARSERSTATE_PARSE_ERROR
} PullParserState;

typedef enum {
    PULLPARSEMODE_NORMAL,
    PULLPARSEMODE_SKIP,
    PULLPARSEMODE_FIND
} PullParseMode;
    
typedef struct tDOM_PullParserInfo 
{
    XML_Parser      parser;
    Tcl_Obj        *inputString;
    Tcl_Channel     inputChannel;
    int             inputfd;
    PullParserState state;
    PullParserState nextState;
    PullParserState next2State;
    Tcl_DString    *cdata;
    Tcl_HashTable  *elmCache;
    Tcl_Obj        *currentElm;
    const char    **atts;
    Tcl_Obj        *channelReadBuf;
    Tcl_Obj        *start_tag;
    Tcl_Obj        *end_tag;
    Tcl_Obj        *text;
    int             ignoreWhiteSpaces;
    PullParseMode   mode;
    int             skipDepth;
    char           *findElement;
#ifdef EXPAT_RESUME_BUG
    long            elmStartCounter;
#endif
} tDOM_PullParserInfo;

#define SetResult(str) Tcl_ResetResult(interp); \
                     Tcl_SetStringObj(Tcl_GetObjResult(interp), (str), -1)

DBG(
static void
printParserState (
    XML_Parser parser
    )
{
    XML_ParsingStatus pstatus;
    
    XML_GetParsingStatus (parser, &pstatus);
    switch (pstatus.parsing) {
    case XML_INITIALIZED:
        fprintf (stderr, "parser status: XML_INITIALIZED\n");
        break;
    case XML_PARSING:
        fprintf (stderr, "parser status: XML_PARSING\n");
        break;
    case XML_FINISHED:
        fprintf (stderr, "parser status: XML_FINISHED\n");
        break;
    case XML_SUSPENDED:
        fprintf (stderr, "parser status: XML_SUSPENDED\n");
        break;
    default:
        fprintf (stderr, "unexpected parser status: %d\n",
                 pstatus.parsing);
        break;
    }
}
)

static void
characterDataHandler (
    void        *userData,
    const char  *s,
    int          len
)
{
    tDOM_PullParserInfo *pullInfo = userData;

    DBG(fprintf(stderr, "cdata handler called\n"));
    Tcl_DStringAppend (pullInfo->cdata, s, len);    
}

static void
endElement (
    void        *userData,
    const char  *name
)
{
    tDOM_PullParserInfo *pullInfo = userData;
    XML_ParsingStatus status;
    int reportStartTag = 0, reportText = 0, hnew;
    Tcl_HashEntry *h;

    DBG(fprintf(stderr, "endElement tag %s\n", name));

    if (pullInfo->mode == PULLPARSEMODE_SKIP) {
        if (pullInfo->skipDepth > 0) {
            pullInfo->skipDepth--;
            return;
        }
        pullInfo->mode = PULLPARSEMODE_NORMAL;
        XML_SetCharacterDataHandler (pullInfo->parser, characterDataHandler);
    }
            
    XML_GetParsingStatus (pullInfo->parser, &status);
    if (status.parsing == XML_SUSPENDED) {
        reportStartTag = 1;
    }

    if (Tcl_DStringLength (pullInfo->cdata) > 0) {
        if (pullInfo->ignoreWhiteSpaces) {
            char *pc; int len;
            len = Tcl_DStringLength(pullInfo->cdata);
            for (pc = Tcl_DStringValue (pullInfo->cdata);
                 len > 0;
                 len--, pc++) 
            {
                if ( (*pc != ' ')  &&
                     (*pc != '\t') &&
                     (*pc != '\n') &&
                     (*pc != '\r') ) {
                    reportText = 1;
                    break;
                }
            }
        } else {
            reportText = 1;
        }
    }

    if (reportStartTag && reportText) {
        /* This happens if in mixed content an empty element written
         * with the empty element syntax (<foo/>) follows text. */
        DBG(fprintf(stderr, "schedule 2 events\n"));
        pullInfo->state = PULLPARSERSTATE_TEXT;
        pullInfo->nextState= PULLPARSERSTATE_START_TAG;
        pullInfo->next2State = PULLPARSERSTATE_END_TAG;
    } else if (reportStartTag) {
        /* This happens if not in mixed content and the parser saw an
         * empty element written with the empty element syntax. */
        DBG(fprintf(stderr, "schedule 1 event (reportStartTag)\n"));
        pullInfo->state = PULLPARSERSTATE_START_TAG;
        pullInfo->nextState = PULLPARSERSTATE_END_TAG;
#ifdef EXPAT_RESUME_BUG
        DBG(fprintf(stderr, "EXPAT_RESUME_BUG\n"));
        if (pullInfo->elmStartCounter == 1) {
            pullInfo->next2State = PULLPARSERSTATE_END_DOCUMENT;
        }
#endif        
    } else if (reportText) {
        DBG(fprintf(stderr, "schedule 1 event (reportText)\n"));
        pullInfo->state = PULLPARSERSTATE_TEXT;
        pullInfo->nextState = PULLPARSERSTATE_END_TAG;
    } else {
        pullInfo->state = PULLPARSERSTATE_END_TAG;
    }

    h = Tcl_FindHashEntry (pullInfo->elmCache, name);
    if (h == NULL) {
        /* The start tag entry creation was skipped during a
         * find-element, create it now. */
        h = Tcl_CreateHashEntry (pullInfo->elmCache, name, &hnew);
        DBG(fprintf(stderr, "endElement: create tag hash table entry %s\n", name));
        pullInfo->currentElm = Tcl_NewStringObj (name, -1);
        Tcl_IncrRefCount (pullInfo->currentElm);
        Tcl_SetHashValue (h, pullInfo->currentElm);
    }
    pullInfo->currentElm = (Tcl_Obj *) Tcl_GetHashValue(h);
    XML_StopParser(pullInfo->parser, 1);
}

static void
startElement(
    void         *userData,
    const char   *name,
    const char  **atts
)
{
    tDOM_PullParserInfo *pullInfo = userData;
    int hnew;
    Tcl_HashEntry *h;
    
    DBG(fprintf(stderr, "startElement tag %s\n", name));

#ifdef EXPAT_RESUME_BUG
    pullInfo->elmStartCounter++;
#endif

    switch (pullInfo->mode) {
    case PULLPARSEMODE_SKIP:
        DBG(fprintf (stderr, "PULLPARSEMODE_SKIP\n"));
        pullInfo->skipDepth++;
        return;
    case PULLPARSEMODE_FIND:
        DBG(fprintf (stderr, "PULLPARSEMODE_FIND this %s search for %s\n",
                     name, pullInfo->findElement));
        if (strcmp (name, pullInfo->findElement) != 0) {
            return;
        }
        pullInfo->mode = PULLPARSEMODE_NORMAL;
        XML_SetCharacterDataHandler (pullInfo->parser, characterDataHandler);
        XML_SetEndElementHandler (pullInfo->parser, endElement);
        break;
    case PULLPARSEMODE_NORMAL:
        break;
    }
    if (Tcl_DStringLength (pullInfo->cdata) > 0) {
        if (pullInfo->ignoreWhiteSpaces) {
            char *pc; int len, wso = 1;
            len = Tcl_DStringLength(pullInfo->cdata);
            for (pc = Tcl_DStringValue (pullInfo->cdata);
                 len > 0;
                 len--, pc++) 
            {
                if ( (*pc != ' ')  &&
                     (*pc != '\t') &&
                     (*pc != '\n') &&
                     (*pc != '\r') ) {
                    wso = 0;
                    break;
                }
            }
            if (wso) {
                Tcl_DStringSetLength (pullInfo->cdata, 0);
                pullInfo->state = PULLPARSERSTATE_START_TAG;
            } else {
                DBG(fprintf(stderr, "schedule TEXT event\n"));
                pullInfo->state = PULLPARSERSTATE_TEXT;
                pullInfo->nextState = PULLPARSERSTATE_START_TAG;
            }
        } else {
            DBG(fprintf(stderr, "schedule TEXT event\n"));
            pullInfo->state = PULLPARSERSTATE_TEXT;
            pullInfo->nextState = PULLPARSERSTATE_START_TAG;
        }
    } else {
        pullInfo->state = PULLPARSERSTATE_START_TAG;
    }
    h = Tcl_CreateHashEntry (pullInfo->elmCache, name, &hnew);
    if (hnew) {
        DBG(fprintf(stderr, "startElement: create tag hash table entry %s\n", name));
        pullInfo->currentElm = Tcl_NewStringObj (name, -1);
        Tcl_IncrRefCount (pullInfo->currentElm);
        Tcl_SetHashValue (h, pullInfo->currentElm);
    } else {
        pullInfo->currentElm = (Tcl_Obj *) Tcl_GetHashValue (h);
    }
    pullInfo->atts = atts;

    XML_StopParser(pullInfo->parser, 1);
}

static void
tDOM_PullParserDeleteCmd (
    ClientData clientdata
    )
{
    tDOM_PullParserInfo *pullInfo = clientdata;
    Tcl_HashEntry *entryPtr;
    Tcl_HashSearch search;

    XML_ParserFree (pullInfo->parser);
    if (pullInfo->inputString) {
        Tcl_DecrRefCount (pullInfo->inputString);
    }
    if (pullInfo->inputfd) {
        close (pullInfo->inputfd);
    }
    Tcl_DStringFree (pullInfo->cdata);
    FREE (pullInfo->cdata);
    if (pullInfo->channelReadBuf) {
        Tcl_DecrRefCount (pullInfo->channelReadBuf);
    }
    entryPtr = Tcl_FirstHashEntry(pullInfo->elmCache, &search);
    while (entryPtr) {
        Tcl_DecrRefCount ((Tcl_Obj*) Tcl_GetHashValue (entryPtr));
        entryPtr = Tcl_NextHashEntry (&search);
    }
    Tcl_DeleteHashTable (pullInfo->elmCache);
    FREE (pullInfo->elmCache);
    Tcl_DecrRefCount(pullInfo->start_tag);
    Tcl_DecrRefCount(pullInfo->end_tag);
    Tcl_DecrRefCount(pullInfo->text);
    FREE (pullInfo);
}

static void
tDOM_ReportXMLError (
    Tcl_Interp *interp,
    tDOM_PullParserInfo *pullInfo
    )
{
    char s[255];

    Tcl_ResetResult (interp);
    sprintf(s, "%ld", XML_GetCurrentLineNumber(pullInfo->parser));
    Tcl_AppendResult(interp, "error \"",
                     XML_ErrorString(
                         XML_GetErrorCode(pullInfo->parser)),
                     "\" at line ", s, " character ", NULL);
    sprintf(s, "%ld", XML_GetCurrentColumnNumber(pullInfo->parser));
    Tcl_AppendResult(interp, s, NULL);
}

static void
tDOM_CleanupInputSource (
    tDOM_PullParserInfo *pullInfo
    )
{
    if (pullInfo->inputString) {
        Tcl_DecrRefCount (pullInfo->inputString);
        pullInfo->inputString = NULL;
    }
    pullInfo->inputChannel = NULL;
    if (pullInfo->inputfd) {
        close (pullInfo->inputfd);
        pullInfo->inputfd = 0;
    }
}

static int
tDOM_resumeParseing (
    Tcl_Interp *interp,
    tDOM_PullParserInfo *pullInfo
    ) 
{
    XML_ParsingStatus pstatus;
    int len, done, result;
    char *data;
    

    switch (XML_ResumeParser (pullInfo->parser)) {
    case XML_STATUS_OK:
        if (pullInfo->inputString) {
            Tcl_DecrRefCount (pullInfo->inputString);
            pullInfo->inputString = NULL;
            pullInfo->state = PULLPARSERSTATE_END_DOCUMENT;
            break;
        }
        XML_GetParsingStatus (pullInfo->parser, &pstatus);
        if (pstatus.parsing == XML_FINISHED) {
            tDOM_CleanupInputSource (pullInfo);
            pullInfo->state = PULLPARSERSTATE_END_DOCUMENT;
            break;
        }
        if (pullInfo->inputChannel) {
            do {
                len = Tcl_ReadChars (pullInfo->inputChannel,
                                     pullInfo->channelReadBuf,
                                     1024, 0);
                done = (len < 1024);
                data = Tcl_GetStringFromObj (
                    pullInfo->channelReadBuf, &len
                    );
                result = XML_Parse (pullInfo->parser, data,
                                    len, done);
            } while (result == XML_STATUS_OK && !done);
        } else {
            /* inputfile */
            do {
                char *fbuf = 
                    XML_GetBuffer (pullInfo->parser,
                                   TDOM_EXPAT_READ_SIZE);
                len = read (pullInfo->inputfd, fbuf,
                            TDOM_EXPAT_READ_SIZE);
                done = (len < TDOM_EXPAT_READ_SIZE);
                result = XML_ParseBuffer (pullInfo->parser,
                                          len, done);
            } while (result == XML_STATUS_OK && !done);
        }
        if (result == XML_STATUS_ERROR) {
            tDOM_CleanupInputSource (pullInfo);
            tDOM_ReportXMLError (interp, pullInfo);
            pullInfo->state = PULLPARSERSTATE_PARSE_ERROR;
            return TCL_ERROR;
        }
        if (done && result == XML_STATUS_OK) {
            tDOM_CleanupInputSource (pullInfo);
            pullInfo->state = PULLPARSERSTATE_END_DOCUMENT;
        }
        /* If here result == XML_STATUS_SUSPENDED,
         * state was set in handler, just take care to
         * report */
        break;
    case XML_STATUS_ERROR:
        tDOM_CleanupInputSource (pullInfo);
        tDOM_ReportXMLError (interp, pullInfo);
        pullInfo->state = PULLPARSERSTATE_PARSE_ERROR;
        return TCL_ERROR;
    case XML_STATUS_SUSPENDED:
        /* Nothing to do here, state was set in handler, just
         * take care to report */
        break;
    }
    
    return TCL_OK;
}

static int
tDOM_PullParserInstanceCmd (
    ClientData  clientdata,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *const objv[]
    )
{
    tDOM_PullParserInfo *pullInfo = clientdata;
    int methodIndex, len, result, mode, fd;
    char *data;
    const char **atts;
    Tcl_Obj *resultPtr;
    Tcl_Channel channel;
    
    static const char *const methods[] = {
        "input", "inputchannel", "inputfile",
        "next", "state", "tag", "attributes",
        "text", "delete", "reset", "skip",
        "find-element", "line", "column", NULL
    };

    enum method {
        m_input, m_inputchannel, m_inputfile,
        m_next, m_state, m_tag, m_attributes,
        m_text, m_delete, m_reset, m_skip,
        m_find_element, m_line, m_column
    };

    if (objc == 1) {
        /* Default method call is next */
        methodIndex = m_next;
    } else {
        if (Tcl_GetIndexFromObj (interp, objv[1], methods, "method", 0,
                                 &methodIndex) != TCL_OK) {
            return TCL_ERROR;
        }
    }
    switch ((enum method) methodIndex) {

    case m_input:
        if (objc != 3) {
            Tcl_WrongNumArgs (interp, 2, objv, "<xml>");
            return TCL_ERROR;
        }
        if (pullInfo->state != PULLPARSERSTATE_READY) {
            SetResult ("Can't change input while already parsing.");
            return TCL_ERROR;
        }
        Tcl_IncrRefCount (objv[2]);
        pullInfo->inputString = objv[2];
        pullInfo->state = PULLPARSERSTATE_START_DOCUMENT;
        break;

    case m_inputchannel:
        if (objc != 3) {
            Tcl_WrongNumArgs (interp, 2, objv, "<channel>");
            return TCL_ERROR;
        }
        if (pullInfo->state != PULLPARSERSTATE_READY) {
            SetResult ("Can't change input while already parsing.");
            return TCL_ERROR;
        }
        channel = Tcl_GetChannel (interp, Tcl_GetString(objv[2]), &mode);
        if (channel == NULL) {
            Tcl_ResetResult (interp);
            Tcl_AppendResult (interp, "\"", Tcl_GetString(objv[2]),
                              "\" isn't a Tcl channel in this interpreter", 
                              NULL);
            return TCL_ERROR;
        }
        if (!(mode & TCL_READABLE)) {
            Tcl_ResetResult (interp);
            Tcl_AppendResult (interp, "channel \"", Tcl_GetString(objv[2]),
                              "wasn't opened for reading", NULL);
            return TCL_ERROR;
        }
        pullInfo->inputChannel = channel;
        if (pullInfo->channelReadBuf == NULL) {
            pullInfo->channelReadBuf = Tcl_NewObj ();
            Tcl_IncrRefCount (pullInfo->channelReadBuf);
            Tcl_SetObjLength (pullInfo->channelReadBuf, 6144);
        }
        pullInfo->state = PULLPARSERSTATE_START_DOCUMENT;
        break;

    case m_inputfile:
        if (objc != 3) {
            Tcl_WrongNumArgs (interp, 2, objv, "<filename>");
            return TCL_ERROR;
        }
        if (pullInfo->state != PULLPARSERSTATE_READY) {
            SetResult ("Can't change input while already parsing.");
            return TCL_ERROR;
        }
        fd = open(Tcl_GetString(objv[2]), O_BINARY|O_RDONLY);
        if (fd < 0) {
            Tcl_ResetResult (interp);
            Tcl_AppendResult (interp, "error opening file \"",
                              Tcl_GetString(objv[2]), "\"", NULL);
            return TCL_ERROR;
        }
        pullInfo->inputfd = fd;
        pullInfo->state = PULLPARSERSTATE_START_DOCUMENT;
        break;

    case m_next:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
        if (pullInfo->state == PULLPARSERSTATE_TEXT) {
            Tcl_DStringSetLength (pullInfo->cdata, 0);
        }
        if (pullInfo->next2State) {
            pullInfo->state = pullInfo->nextState;
            pullInfo->nextState = pullInfo->next2State;
            pullInfo->next2State = 0;
        } else if (pullInfo->nextState) {
            pullInfo->state = pullInfo->nextState;
            pullInfo->nextState = 0;
        } else {
            switch (pullInfo->state) {
            case PULLPARSERSTATE_READY:
                SetResult ("No input");
                return TCL_ERROR;
            case PULLPARSERSTATE_PARSE_ERROR:
                SetResult ("Parsing stopped with XML parsing error.");
                return TCL_ERROR;
            case PULLPARSERSTATE_END_DOCUMENT:
                SetResult ("No next event after END_DOCUMENT");
                return TCL_ERROR;
            case PULLPARSERSTATE_TEXT:
                /* Since PULLPARSERSTATE_TEXT always has nextState set
                 * this case is handled in the if part of this if else
                 * and this is never reached. It's just here to eat up
                 * this case in the switch. */
                break;
            case PULLPARSERSTATE_START_DOCUMENT:
                if (pullInfo->inputfd) {
                    do {
                        char *fbuf =
                            XML_GetBuffer (pullInfo->parser,
                                           TDOM_EXPAT_READ_SIZE);
                        len = read(pullInfo->inputfd, fbuf,
                                   TDOM_EXPAT_READ_SIZE);
                        result = XML_ParseBuffer (pullInfo->parser,
                                                  len, len == 0);
                    } while (result == XML_STATUS_OK);
                } else if (pullInfo->inputChannel) {
                    do {
                        len = Tcl_ReadChars (pullInfo->inputChannel,
                                             pullInfo->channelReadBuf,
                                             1024, 0);
                        data = Tcl_GetString (pullInfo->channelReadBuf);
                        result = XML_Parse (pullInfo->parser, data, len,
                                            len == 0);
                    } while (result == XML_STATUS_OK);
                } else {
                    data = Tcl_GetStringFromObj(pullInfo->inputString, &len);
                    result = XML_Parse (pullInfo->parser, data, len, 1);
                }
                switch (result) {
                case XML_STATUS_OK:
                    tDOM_CleanupInputSource (pullInfo);
                    pullInfo->state = PULLPARSERSTATE_END_DOCUMENT;
                    break;
                case XML_STATUS_ERROR:
                    tDOM_CleanupInputSource (pullInfo);
                    tDOM_ReportXMLError (interp, pullInfo);
                    pullInfo->state = PULLPARSERSTATE_PARSE_ERROR;
                    return TCL_ERROR;
                case XML_STATUS_SUSPENDED:
                    /* Nothing to do here, state was set in handler, just
                     * take care to report */
                    break;
                }
                break;
            default:
                DBG (printParserState(pullInfo->parser));
                if (tDOM_resumeParseing (interp, pullInfo) != TCL_OK) {
                    return TCL_ERROR;
                }
                DBG (printParserState(pullInfo->parser));
                break;
            }
        }
        /* Fall throu to reporting state */
    case m_state:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
        switch (pullInfo->state) {
        case PULLPARSERSTATE_READY:
            SetResult("READY");
            break;
        case PULLPARSERSTATE_PARSE_ERROR:
            SetResult("PARSE_ERROR");
            break;
        case PULLPARSERSTATE_START_DOCUMENT:
            SetResult("START_DOCUMENT");
            break;
        case PULLPARSERSTATE_END_DOCUMENT:
            SetResult("END_DOCUMENT");
            break;
        case PULLPARSERSTATE_START_TAG:
            Tcl_SetObjResult (interp, pullInfo->start_tag);
            break;
        case PULLPARSERSTATE_END_TAG:
            Tcl_SetObjResult (interp, pullInfo->end_tag);
            break;
        case PULLPARSERSTATE_TEXT:
            Tcl_SetObjResult (interp, pullInfo->text);
            break;
        }
        break;

    case m_tag:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
        if (pullInfo->state != PULLPARSERSTATE_START_TAG
            && pullInfo->state != PULLPARSERSTATE_END_TAG) {
            SetResult("Invalid state");
            return TCL_ERROR;
        }
        Tcl_SetObjResult (interp, pullInfo->currentElm);
        break;

    case m_attributes:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
        if (pullInfo->state != PULLPARSERSTATE_START_TAG) {
            SetResult("Invalid state - attribute method is only valid in state START_TAG.");
            return TCL_ERROR;
        }
        Tcl_ResetResult(interp);
        resultPtr = Tcl_GetObjResult(interp);
        atts = pullInfo->atts;
        while (atts[0] != NULL) {
            Tcl_ListObjAppendElement (interp, resultPtr,
                                      Tcl_NewStringObj(atts[0], -1));
            atts++;
        }
        break;

    case m_text:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
        Tcl_ResetResult (interp);
        Tcl_SetStringObj (
            Tcl_GetObjResult (interp),
            Tcl_DStringValue (pullInfo->cdata),
            Tcl_DStringLength (pullInfo->cdata)
            );
        break;

    case m_skip:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
        if (pullInfo->state != PULLPARSERSTATE_START_TAG) {
            SetResult("Invalid state - skip method is only valid in state START_TAG.");
            return TCL_ERROR;
        }
        if (pullInfo->nextState == PULLPARSERSTATE_END_TAG
            || pullInfo->next2State == PULLPARSERSTATE_END_TAG) {
            pullInfo->state = PULLPARSERSTATE_END_TAG;
#ifdef EXPAT_RESUME_BUG
            if (pullInfo->next2State == PULLPARSERSTATE_END_DOCUMENT) {
                pullInfo->nextState = PULLPARSERSTATE_END_DOCUMENT;
            } else {
                pullInfo->nextState = 0;
            }
#else            
            pullInfo->nextState = 0;
#endif            
            pullInfo->next2State = 0;
            Tcl_DStringSetLength (pullInfo->cdata, 0);
            Tcl_SetObjResult (interp, pullInfo->end_tag);
            break;
        }
        pullInfo->mode = PULLPARSEMODE_SKIP;
        pullInfo->skipDepth = 0;
        Tcl_DStringSetLength (pullInfo->cdata, 0);
        XML_SetCharacterDataHandler (pullInfo->parser, NULL);
        if (tDOM_resumeParseing (interp, pullInfo) != TCL_OK) {
            return TCL_ERROR;
        }
        Tcl_SetObjResult (interp, pullInfo->end_tag);
        break;
        
    case m_find_element:
        if (objc != 3) {
            Tcl_WrongNumArgs (interp, 2, objv, "elementName");
            return TCL_ERROR;
        }
        if (pullInfo->state != PULLPARSERSTATE_START_TAG
            && pullInfo->state != PULLPARSERSTATE_END_TAG
            && pullInfo->state != PULLPARSERSTATE_START_DOCUMENT) {
            SetResult("Invalid state - find-element method is only valid in states "
                      "START_DOCUMENT, START_TAG and END_TAG.");
            return TCL_ERROR;
        }
#ifdef EXPAT_RESUME_BUG
        if (pullInfo->state == PULLPARSERSTATE_END_TAG
            && pullInfo->nextState == PULLPARSERSTATE_END_DOCUMENT) {
            pullInfo->state = PULLPARSERSTATE_END_DOCUMENT;
            SetResult ("END_DOCUMENT");
            break;
        }
#endif
        pullInfo->mode = PULLPARSEMODE_FIND;
        /* As long as we don't evalute any tcl script code during a
         * pull parser method call this should be secure. */
        pullInfo->findElement = Tcl_GetString (objv[2]);
        Tcl_DStringSetLength (pullInfo->cdata, 0);
        XML_SetCharacterDataHandler (pullInfo->parser, NULL);
        XML_SetEndElementHandler (pullInfo->parser, NULL);
        if (pullInfo->state == PULLPARSERSTATE_START_DOCUMENT) {
            Tcl_Obj * thisObjv[2];
            Tcl_Obj * thisMethod = Tcl_NewStringObj ("next", 4);
            Tcl_IncrRefCount (thisMethod);
            thisObjv[0] = objv[0];
            thisObjv[1] = thisMethod;
            result = tDOM_PullParserInstanceCmd (pullInfo, interp, 2,
                                                 thisObjv);
            Tcl_DecrRefCount (thisMethod);
            if (result != TCL_OK) {
                return TCL_ERROR;
            }
        } else {
            if (tDOM_resumeParseing (interp, pullInfo) != TCL_OK) {
                return TCL_ERROR;
            }
        }
        if (pullInfo->state == PULLPARSERSTATE_START_TAG) {
            Tcl_SetObjResult (interp, pullInfo->start_tag);
        } else {
            SetResult ("END_DOCUMENT");
        }
        break;

    case m_line:
    case m_column:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
        switch (pullInfo->state) {
        case PULLPARSERSTATE_READY:
            SetResult("No input");
            return TCL_ERROR;
        case PULLPARSERSTATE_TEXT:
            SetResult("Invalid state");
            return TCL_ERROR;
        case PULLPARSERSTATE_END_TAG:
        case PULLPARSERSTATE_START_TAG:
        case PULLPARSERSTATE_END_DOCUMENT:
        case PULLPARSERSTATE_PARSE_ERROR:
            if ((enum method) methodIndex == m_line) {
                Tcl_SetObjResult(interp,
                    Tcl_NewIntObj (XML_GetCurrentLineNumber(pullInfo->parser)));
            } else {
                Tcl_SetObjResult(interp,
                    Tcl_NewIntObj (XML_GetCurrentColumnNumber(pullInfo->parser)));
            }
            break;
        case PULLPARSERSTATE_START_DOCUMENT:
            Tcl_SetObjResult(interp, Tcl_NewIntObj (0));
            break;
        }
        break;
        
    case m_delete:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
        Tcl_DeleteCommand (interp, Tcl_GetString (objv[0]));
        break;

    case m_reset:
        if (objc != 2) {
            Tcl_WrongNumArgs (interp, 2, objv, "");
            return TCL_ERROR;
        }
        tDOM_CleanupInputSource (pullInfo);
        pullInfo->state = PULLPARSERSTATE_READY;
        pullInfo->nextState = 0;
        Tcl_DStringSetLength (pullInfo->cdata, 0);
        if (XML_ParserReset (pullInfo->parser, NULL) != XML_TRUE) {
            SetResult ("Parser reset failed!");
            return TCL_ERROR;
        }
        XML_SetElementHandler (pullInfo->parser, startElement, endElement);
        XML_SetUserData (pullInfo->parser, pullInfo);
        break;
        
    }

    return TCL_OK;
}


int
tDOM_PullParserCmd (
    ClientData  dummy,
    Tcl_Interp *interp,
    int         objc,
    Tcl_Obj    *const objv[]
    )
{
    tDOM_PullParserInfo *pullInfo;
    int flagIndex, ignoreWhiteSpaces = 0;

    static const char *const flags[] = {
        "-ignorewhitecdata", NULL
    };
    
    enum flag {
        f_ignoreWhiteSpaces
    };

    if (objc < 2 || objc > 3) {
        Tcl_WrongNumArgs (interp, 1, objv, "cmdName ?-ignorewhitecdata?");
        return TCL_ERROR;
    }

    if (objc == 3) {
        if (Tcl_GetIndexFromObj (interp, objv[2], flags, "flag", 0,
                                 &flagIndex) != TCL_OK) {
            return TCL_ERROR;
        }
        switch ((enum flag) flagIndex) {
        case f_ignoreWhiteSpaces:
            ignoreWhiteSpaces = 1;
            break;
        }
    }
    
    pullInfo = (tDOM_PullParserInfo *) MALLOC(sizeof(tDOM_PullParserInfo));
    memset (pullInfo, 0, sizeof (tDOM_PullParserInfo));

    pullInfo->parser = XML_ParserCreate_MM(NULL, MEM_SUITE, NULL);
    XML_SetUserData (pullInfo->parser, pullInfo);
    XML_SetElementHandler (pullInfo->parser, startElement, endElement);
    XML_SetCharacterDataHandler (pullInfo->parser, characterDataHandler);
    pullInfo->cdata = (Tcl_DString*) MALLOC (sizeof (Tcl_DString));
    Tcl_DStringInit (pullInfo->cdata);
    pullInfo->state = PULLPARSERSTATE_READY;
    pullInfo->start_tag = Tcl_NewStringObj("START_TAG", 9);
    Tcl_IncrRefCount (pullInfo->start_tag);
    pullInfo->end_tag = Tcl_NewStringObj("END_TAG", 7);
    Tcl_IncrRefCount (pullInfo->end_tag);
    pullInfo->text = Tcl_NewStringObj("TEXT", 4);
    Tcl_IncrRefCount (pullInfo->text);
    pullInfo->ignoreWhiteSpaces = ignoreWhiteSpaces;
    pullInfo->elmCache = (Tcl_HashTable *)MALLOC(sizeof (Tcl_HashTable));
    Tcl_InitHashTable(pullInfo->elmCache, TCL_STRING_KEYS);
    pullInfo->mode = PULLPARSEMODE_NORMAL;
#ifdef EXPAT_RESUME_BUG
    pullInfo->elmStartCounter = 0;
#endif
    
    Tcl_CreateObjCommand (interp, Tcl_GetString(objv[1]),
                          tDOM_PullParserInstanceCmd, (ClientData) pullInfo,
                          tDOM_PullParserDeleteCmd);
    Tcl_SetObjResult(interp, objv[1]);
    return TCL_OK;
}

#endif /* ifndef TDOM_NO_PULL */

Added generic/tclpull.h.







>
>
>
1
2
3

int tDOM_PullParserCmd (ClientData dummy, Tcl_Interp *interp, int objc,
                        Tcl_Obj *const objv[]);

Changes to generic/tdom.decls.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

library tdom
interface tdom
#hooks {}

declare 0 generic {
    int TclExpatObjCmd (ClientData dummy, Tcl_Interp *interp, 
                        int objc, Tcl_Obj *CONST objv[])
}
declare 1 generic {
    int CheckExpatParserObj (Tcl_Interp *interp, Tcl_Obj *CONST nameObj)
}
declare 2 generic {
     int CHandlerSetInstall (Tcl_Interp *interp, Tcl_Obj *CONST expatObj,
                             CHandlerSet *handlerSet)
}
declare 3 generic {
     int CHandlerSetRemove (Tcl_Interp *interp, Tcl_Obj *CONST expatObj,
                            char *handlerSetName)
}
declare 4 generic {
     CHandlerSet * CHandlerSetCreate (char *name)
}
declare 5 generic {
     CHandlerSet * CHandlerSetGet (Tcl_Interp *interp, Tcl_Obj *CONST expatObj,
                                   char *handlerSetName)
}
declare 6 generic {
     void * CHandlerSetGetUserData (Tcl_Interp *interp, 
                                    Tcl_Obj *CONST expatObj,
                                    char *handlerSetName)
}
declare 7 generic {
     TclGenExpatInfo * GetExpatInfo (Tcl_Interp *interp,
                                     Tcl_Obj *CONST expatObj)
}
declare 8 generic {
     XML_Size XML_GetCurrentLineNumber(XML_Parser parser)
}
declare 9 generic {
     XML_Size XML_GetCurrentColumnNumber(XML_Parser parser)
}







|


|


|



|






|




|




|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

library tdom
interface tdom
#hooks {}

declare 0 generic {
    int TclExpatObjCmd (ClientData dummy, Tcl_Interp *interp, 
                        int objc, Tcl_Obj *const objv[])
}
declare 1 generic {
    int CheckExpatParserObj (Tcl_Interp *interp, Tcl_Obj *const nameObj)
}
declare 2 generic {
     int CHandlerSetInstall (Tcl_Interp *interp, Tcl_Obj *const expatObj,
                             CHandlerSet *handlerSet)
}
declare 3 generic {
     int CHandlerSetRemove (Tcl_Interp *interp, Tcl_Obj *const expatObj,
                            char *handlerSetName)
}
declare 4 generic {
     CHandlerSet * CHandlerSetCreate (char *name)
}
declare 5 generic {
     CHandlerSet * CHandlerSetGet (Tcl_Interp *interp, Tcl_Obj *const expatObj,
                                   char *handlerSetName)
}
declare 6 generic {
     void * CHandlerSetGetUserData (Tcl_Interp *interp, 
                                    Tcl_Obj *const expatObj,
                                    char *handlerSetName)
}
declare 7 generic {
     TclGenExpatInfo * GetExpatInfo (Tcl_Interp *interp,
                                     Tcl_Obj *const expatObj)
}
declare 8 generic {
     XML_Size XML_GetCurrentLineNumber(XML_Parser parser)
}
declare 9 generic {
     XML_Size XML_GetCurrentColumnNumber(XML_Parser parser)
}

Changes to generic/tdom.h.

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

typedef struct CHandlerSet {
    struct CHandlerSet *nextHandlerSet;
    char *name;                     /* refname of the handler set */
    int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */

    void *userData;                 /* Handler set specific Data Structure;
                                       the C handler set extention has to
                                       malloc the needed structure in his
                                       init func and has to provide a
                                       cleanup func (to free it). */

    CHandlerSet_userDataReset        resetProc;
    CHandlerSet_userDataFree         freeProc;
    CHandlerSet_parserReset          parserResetProc;







|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

typedef struct CHandlerSet {
    struct CHandlerSet *nextHandlerSet;
    char *name;                     /* refname of the handler set */
    int ignoreWhiteCDATAs;          /* ignore 'white' CDATA sections */

    void *userData;                 /* Handler set specific Data Structure;
                                       the C handler set extension has to
                                       malloc the needed structure in his
                                       init func and has to provide a
                                       cleanup func (to free it). */

    CHandlerSet_userDataReset        resetProc;
    CHandlerSet_userDataFree         freeProc;
    CHandlerSet_parserReset          parserResetProc;

Changes to generic/tdomDecls.h.

1
2
3
4
5
6




7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
69
70

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185

/* This is generated by the getStubs.tcl tool (see the tcl distribution)
   out of the tdom.decls file */


/* !BEGIN!: Do not edit below this line. */





/*
 * Exported function declarations:
 */

/* 0 */
EXTERN int		TclExpatObjCmd _ANSI_ARGS_((ClientData dummy, 
				Tcl_Interp * interp, int objc, 
				Tcl_Obj *CONST objv[]));
/* 1 */
EXTERN int		CheckExpatParserObj _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj *CONST nameObj));
/* 2 */
EXTERN int		CHandlerSetInstall _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj *CONST expatObj, 
				CHandlerSet * handlerSet));
/* 3 */
EXTERN int		CHandlerSetRemove _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj *CONST expatObj, 
				char * handlerSetName));
/* 4 */
EXTERN CHandlerSet *	CHandlerSetCreate _ANSI_ARGS_((char * name));
/* 5 */
EXTERN CHandlerSet *	CHandlerSetGet _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj *CONST expatObj, 
				char * handlerSetName));
/* 6 */
EXTERN void *		CHandlerSetGetUserData _ANSI_ARGS_((
				Tcl_Interp * interp, Tcl_Obj *CONST expatObj, 

				char * handlerSetName));
/* 7 */
EXTERN TclGenExpatInfo * GetExpatInfo _ANSI_ARGS_((Tcl_Interp * interp, 
				Tcl_Obj *CONST expatObj));

/* 8 */
EXTERN XML_Size		XML_GetCurrentLineNumber _ANSI_ARGS_((
				XML_Parser parser));
/* 9 */
EXTERN XML_Size		XML_GetCurrentColumnNumber _ANSI_ARGS_((
				XML_Parser parser));
/* 10 */
EXTERN XML_Index	XML_GetCurrentByteIndex _ANSI_ARGS_((
				XML_Parser parser));
/* 11 */
EXTERN int		XML_GetCurrentByteCount _ANSI_ARGS_((
				XML_Parser parser));
/* 12 */
EXTERN enum XML_Status	XML_SetBase _ANSI_ARGS_((XML_Parser parser, 
				const XML_Char * base));
/* 13 */
EXTERN const XML_Char *	 XML_GetBase _ANSI_ARGS_((XML_Parser parser));
/* 14 */
EXTERN int		XML_GetSpecifiedAttributeCount _ANSI_ARGS_((
				XML_Parser parser));
/* 15 */
EXTERN int		XML_GetIdAttributeIndex _ANSI_ARGS_((
				XML_Parser parser));
/* 16 */
EXTERN domNode *	tcldom_getNodeFromName _ANSI_ARGS_((
				Tcl_Interp * interp, char * nodeName, 
				char ** errMsg));

/* 17 */
EXTERN domDocument *	tcldom_getDocumentFromName _ANSI_ARGS_((
				Tcl_Interp * interp, char * docName, 
				char ** errMsg));


typedef struct TdomStubs {
    int magic;
    struct TdomStubHooks *hooks;

    int (*tclExpatObjCmd) _ANSI_ARGS_((ClientData dummy, Tcl_Interp * interp, int objc, Tcl_Obj *CONST objv[])); /* 0 */
    int (*checkExpatParserObj) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj *CONST nameObj)); /* 1 */
    int (*cHandlerSetInstall) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj *CONST expatObj, CHandlerSet * handlerSet)); /* 2 */
    int (*cHandlerSetRemove) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj *CONST expatObj, char * handlerSetName)); /* 3 */
    CHandlerSet * (*cHandlerSetCreate) _ANSI_ARGS_((char * name)); /* 4 */
    CHandlerSet * (*cHandlerSetGet) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj *CONST expatObj, char * handlerSetName)); /* 5 */
    void * (*cHandlerSetGetUserData) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj *CONST expatObj, char * handlerSetName)); /* 6 */
    TclGenExpatInfo * (*getExpatInfo) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj *CONST expatObj)); /* 7 */
    XML_Size (*xML_GetCurrentLineNumber) _ANSI_ARGS_((XML_Parser parser)); /* 8 */
    XML_Size (*xML_GetCurrentColumnNumber) _ANSI_ARGS_((XML_Parser parser)); /* 9 */
    XML_Index (*xML_GetCurrentByteIndex) _ANSI_ARGS_((XML_Parser parser)); /* 10 */
    int (*xML_GetCurrentByteCount) _ANSI_ARGS_((XML_Parser parser)); /* 11 */
    enum XML_Status (*xML_SetBase) _ANSI_ARGS_((XML_Parser parser, const XML_Char * base)); /* 12 */
    const XML_Char * (*xML_GetBase) _ANSI_ARGS_((XML_Parser parser)); /* 13 */
    int (*xML_GetSpecifiedAttributeCount) _ANSI_ARGS_((XML_Parser parser)); /* 14 */
    int (*xML_GetIdAttributeIndex) _ANSI_ARGS_((XML_Parser parser)); /* 15 */
    domNode * (*tcldom_getNodeFromName) _ANSI_ARGS_((Tcl_Interp * interp, char * nodeName, char ** errMsg)); /* 16 */
    domDocument * (*tcldom_getDocumentFromName) _ANSI_ARGS_((Tcl_Interp * interp, char * docName, char ** errMsg)); /* 17 */
} TdomStubs;

#ifdef __cplusplus
extern "C" {
#endif
extern TdomStubs *tdomStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TDOM_STUBS) && !defined(USE_TDOM_STUB_PROCS)

/*
 * Inline function declarations:
 */

#ifndef TclExpatObjCmd
#define TclExpatObjCmd \
	(tdomStubsPtr->tclExpatObjCmd) /* 0 */
#endif
#ifndef CheckExpatParserObj
#define CheckExpatParserObj \
	(tdomStubsPtr->checkExpatParserObj) /* 1 */
#endif
#ifndef CHandlerSetInstall
#define CHandlerSetInstall \
	(tdomStubsPtr->cHandlerSetInstall) /* 2 */
#endif
#ifndef CHandlerSetRemove
#define CHandlerSetRemove \
	(tdomStubsPtr->cHandlerSetRemove) /* 3 */
#endif
#ifndef CHandlerSetCreate
#define CHandlerSetCreate \
	(tdomStubsPtr->cHandlerSetCreate) /* 4 */
#endif
#ifndef CHandlerSetGet
#define CHandlerSetGet \
	(tdomStubsPtr->cHandlerSetGet) /* 5 */
#endif
#ifndef CHandlerSetGetUserData
#define CHandlerSetGetUserData \
	(tdomStubsPtr->cHandlerSetGetUserData) /* 6 */
#endif
#ifndef GetExpatInfo
#define GetExpatInfo \
	(tdomStubsPtr->getExpatInfo) /* 7 */
#endif
#ifndef XML_GetCurrentLineNumber
#define XML_GetCurrentLineNumber \
	(tdomStubsPtr->xML_GetCurrentLineNumber) /* 8 */
#endif
#ifndef XML_GetCurrentColumnNumber
#define XML_GetCurrentColumnNumber \
	(tdomStubsPtr->xML_GetCurrentColumnNumber) /* 9 */
#endif
#ifndef XML_GetCurrentByteIndex
#define XML_GetCurrentByteIndex \
	(tdomStubsPtr->xML_GetCurrentByteIndex) /* 10 */
#endif
#ifndef XML_GetCurrentByteCount
#define XML_GetCurrentByteCount \
	(tdomStubsPtr->xML_GetCurrentByteCount) /* 11 */
#endif
#ifndef XML_SetBase
#define XML_SetBase \
	(tdomStubsPtr->xML_SetBase) /* 12 */
#endif
#ifndef XML_GetBase
#define XML_GetBase \
	(tdomStubsPtr->xML_GetBase) /* 13 */
#endif
#ifndef XML_GetSpecifiedAttributeCount
#define XML_GetSpecifiedAttributeCount \
	(tdomStubsPtr->xML_GetSpecifiedAttributeCount) /* 14 */
#endif
#ifndef XML_GetIdAttributeIndex
#define XML_GetIdAttributeIndex \
	(tdomStubsPtr->xML_GetIdAttributeIndex) /* 15 */
#endif
#ifndef tcldom_getNodeFromName
#define tcldom_getNodeFromName \
	(tdomStubsPtr->tcldom_getNodeFromName) /* 16 */
#endif
#ifndef tcldom_getDocumentFromName
#define tcldom_getDocumentFromName \
	(tdomStubsPtr->tcldom_getDocumentFromName) /* 17 */
#endif

#endif /* defined(USE_TDOM_STUBS) && !defined(USE_TDOM_STUB_PROCS) */

/* !END!: Do not edit above this line. */

|




>
>
>
>






|
|
<

|
|

|
|
|

|
|
|

|

|
|
|

|
<
>
|

|
<
>

|
<

|
<

|
<

|
<

|
<

|

|
<

|
<

|
<
<
>

|
<
<
>



|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|


<
<
<
|
>




|





<


<
<


<
<


<
<


<
<


<
<


<
<


<
<


<
<


<
<


<
<


<
<


<
<


<
<


<
<


<
<


<
<


<
<


<

|


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41

42
43
44

45
46

47
48

49
50

51
52

53
54
55
56

57
58

59
60


61
62
63


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89



90
91
92
93
94
95
96
97
98
99
100
101

102
103


104
105


106
107


108
109


110
111


112
113


114
115


116
117


118
119


120
121


122
123


124
125


126
127


128
129


130
131


132
133


134
135


136
137

138
139
140
141

/* This is generated by the genStubs.tcl tool (see the tcl distribution)
   out of the tdom.decls file */


/* !BEGIN!: Do not edit below this line. */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Exported function declarations:
 */

/* 0 */
EXTERN int		TclExpatObjCmd(ClientData dummy, Tcl_Interp *interp,
				int objc, Tcl_Obj *const objv[]);

/* 1 */
EXTERN int		CheckExpatParserObj(Tcl_Interp *interp,
				Tcl_Obj *const nameObj);
/* 2 */
EXTERN int		CHandlerSetInstall(Tcl_Interp *interp,
				Tcl_Obj *const expatObj, 
				CHandlerSet *handlerSet);
/* 3 */
EXTERN int		CHandlerSetRemove(Tcl_Interp *interp,
				Tcl_Obj *const expatObj, 
				char *handlerSetName);
/* 4 */
EXTERN CHandlerSet *	CHandlerSetCreate(char *name);
/* 5 */
EXTERN CHandlerSet *	CHandlerSetGet(Tcl_Interp *interp,
				Tcl_Obj *const expatObj, 
				char *handlerSetName);
/* 6 */
EXTERN void *		CHandlerSetGetUserData(Tcl_Interp *interp,

				Tcl_Obj *const expatObj,
				char *handlerSetName);
/* 7 */
EXTERN TclGenExpatInfo * GetExpatInfo(Tcl_Interp *interp,

				Tcl_Obj *const expatObj);
/* 8 */
EXTERN XML_Size		XML_GetCurrentLineNumber(XML_Parser parser);

/* 9 */
EXTERN XML_Size		XML_GetCurrentColumnNumber(XML_Parser parser);

/* 10 */
EXTERN XML_Index	XML_GetCurrentByteIndex(XML_Parser parser);

/* 11 */
EXTERN int		XML_GetCurrentByteCount(XML_Parser parser);

/* 12 */
EXTERN enum XML_Status	XML_SetBase(XML_Parser parser, const XML_Char *base);

/* 13 */
EXTERN const XML_Char *	 XML_GetBase(XML_Parser parser);
/* 14 */
EXTERN int		XML_GetSpecifiedAttributeCount(XML_Parser parser);

/* 15 */
EXTERN int		XML_GetIdAttributeIndex(XML_Parser parser);

/* 16 */
EXTERN domNode *	tcldom_getNodeFromName(Tcl_Interp *interp,


				char *nodeName, char **errMsg);
/* 17 */
EXTERN domDocument *	tcldom_getDocumentFromName(Tcl_Interp *interp,


				char *docName, char **errMsg);

typedef struct TdomStubs {
    int magic;
    void *hooks;

    int (*tclExpatObjCmd) (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 0 */
    int (*checkExpatParserObj) (Tcl_Interp *interp, Tcl_Obj *const nameObj); /* 1 */
    int (*cHandlerSetInstall) (Tcl_Interp *interp, Tcl_Obj *const expatObj, CHandlerSet *handlerSet); /* 2 */
    int (*cHandlerSetRemove) (Tcl_Interp *interp, Tcl_Obj *const expatObj, char *handlerSetName); /* 3 */
    CHandlerSet * (*cHandlerSetCreate) (char *name); /* 4 */
    CHandlerSet * (*cHandlerSetGet) (Tcl_Interp *interp, Tcl_Obj *const expatObj, char *handlerSetName); /* 5 */
    void * (*cHandlerSetGetUserData) (Tcl_Interp *interp, Tcl_Obj *const expatObj, char *handlerSetName); /* 6 */
    TclGenExpatInfo * (*getExpatInfo) (Tcl_Interp *interp, Tcl_Obj *const expatObj); /* 7 */
    XML_Size (*xML_GetCurrentLineNumber) (XML_Parser parser); /* 8 */
    XML_Size (*xML_GetCurrentColumnNumber) (XML_Parser parser); /* 9 */
    XML_Index (*xML_GetCurrentByteIndex) (XML_Parser parser); /* 10 */
    int (*xML_GetCurrentByteCount) (XML_Parser parser); /* 11 */
    enum XML_Status (*xML_SetBase) (XML_Parser parser, const XML_Char *base); /* 12 */
    const XML_Char * (*xML_GetBase) (XML_Parser parser); /* 13 */
    int (*xML_GetSpecifiedAttributeCount) (XML_Parser parser); /* 14 */
    int (*xML_GetIdAttributeIndex) (XML_Parser parser); /* 15 */
    domNode * (*tcldom_getNodeFromName) (Tcl_Interp *interp, char *nodeName, char **errMsg); /* 16 */
    domDocument * (*tcldom_getDocumentFromName) (Tcl_Interp *interp, char *docName, char **errMsg); /* 17 */
} TdomStubs;




extern const TdomStubs *tdomStubsPtr;

#ifdef __cplusplus
}
#endif

#if defined(USE_TDOM_STUBS)

/*
 * Inline function declarations:
 */


#define TclExpatObjCmd \
	(tdomStubsPtr->tclExpatObjCmd) /* 0 */


#define CheckExpatParserObj \
	(tdomStubsPtr->checkExpatParserObj) /* 1 */


#define CHandlerSetInstall \
	(tdomStubsPtr->cHandlerSetInstall) /* 2 */


#define CHandlerSetRemove \
	(tdomStubsPtr->cHandlerSetRemove) /* 3 */


#define CHandlerSetCreate \
	(tdomStubsPtr->cHandlerSetCreate) /* 4 */


#define CHandlerSetGet \
	(tdomStubsPtr->cHandlerSetGet) /* 5 */


#define CHandlerSetGetUserData \
	(tdomStubsPtr->cHandlerSetGetUserData) /* 6 */


#define GetExpatInfo \
	(tdomStubsPtr->getExpatInfo) /* 7 */


#define XML_GetCurrentLineNumber \
	(tdomStubsPtr->xML_GetCurrentLineNumber) /* 8 */


#define XML_GetCurrentColumnNumber \
	(tdomStubsPtr->xML_GetCurrentColumnNumber) /* 9 */


#define XML_GetCurrentByteIndex \
	(tdomStubsPtr->xML_GetCurrentByteIndex) /* 10 */


#define XML_GetCurrentByteCount \
	(tdomStubsPtr->xML_GetCurrentByteCount) /* 11 */


#define XML_SetBase \
	(tdomStubsPtr->xML_SetBase) /* 12 */


#define XML_GetBase \
	(tdomStubsPtr->xML_GetBase) /* 13 */


#define XML_GetSpecifiedAttributeCount \
	(tdomStubsPtr->xML_GetSpecifiedAttributeCount) /* 14 */


#define XML_GetIdAttributeIndex \
	(tdomStubsPtr->xML_GetIdAttributeIndex) /* 15 */


#define tcldom_getNodeFromName \
	(tdomStubsPtr->tcldom_getNodeFromName) /* 16 */


#define tcldom_getDocumentFromName \
	(tdomStubsPtr->tcldom_getDocumentFromName) /* 17 */


#endif /* defined(USE_TDOM_STUBS) */

/* !END!: Do not edit above this line. */

Changes to generic/tdomStubInit.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21

/* This is generated by the getStubs.tcl tool (see the tcl distribution)
   out of the tdom.decls file */
   
#ifdef USE_TCL_STUBS

#include <dom.h>
#include <tdom.h>

/* !BEGIN!: Do not edit below this line. */

TdomStubs tdomStubs = {
    TCL_STUB_MAGIC,
    NULL,

    TclExpatObjCmd, /* 0 */
    CheckExpatParserObj, /* 1 */
    CHandlerSetInstall, /* 2 */
    CHandlerSetRemove, /* 3 */
    CHandlerSetCreate, /* 4 */
    CHandlerSetGet, /* 5 */
    CHandlerSetGetUserData, /* 6 */

|









|

<
>







1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21

/* This is generated by the getStubs.tcl tool (see the Tcl distribution)
   out of the tdom.decls file */
   
#ifdef USE_TCL_STUBS

#include <dom.h>
#include <tdom.h>

/* !BEGIN!: Do not edit below this line. */

const TdomStubs tdomStubs = {
    TCL_STUB_MAGIC,

    0,
    TclExpatObjCmd, /* 0 */
    CheckExpatParserObj, /* 1 */
    CHandlerSetInstall, /* 2 */
    CHandlerSetRemove, /* 3 */
    CHandlerSetCreate, /* 4 */
    CHandlerSetGet, /* 5 */
    CHandlerSetGetUserData, /* 6 */

Changes to generic/tdomStubLib.c.

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
 * Ensure that Tdom_InitStubs is built as an exported symbol.  The other stub
 * functions should be built as non-exported symbols.
 */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT

TdomStubs *tdomStubsPtr;

/*----------------------------------------------------------------------------
|   Tdom_InitStubs
|
\---------------------------------------------------------------------------*/

CONST char *
Tdom_InitStubs (
    Tcl_Interp *interp, 
    char *version, 
    int exact
    )
{
    CONST char *actualVersion;
    ClientData clientData = NULL;

#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 0)
    Tcl_SetResult(interp, "Too old Tcl version. Binary extensions "
                  "to tDOM are not possible, with a that outdated "
                  "Tcl version.", TCL_STATIC);
    return NULL;







|






|






|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
 * Ensure that Tdom_InitStubs is built as an exported symbol.  The other stub
 * functions should be built as non-exported symbols.
 */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT

const TdomStubs *tdomStubsPtr;

/*----------------------------------------------------------------------------
|   Tdom_InitStubs
|
\---------------------------------------------------------------------------*/

const char *
Tdom_InitStubs (
    Tcl_Interp *interp, 
    char *version, 
    int exact
    )
{
    const char *actualVersion;
    ClientData clientData = NULL;

#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 0)
    Tcl_SetResult(interp, "Too old Tcl version. Binary extensions "
                  "to tDOM are not possible, with a that outdated "
                  "Tcl version.", TCL_STATIC);
    return NULL;

Changes to generic/tdominit.c.

38
39
40
41
42
43
44

45
46
47
48
49
50
51
..
58
59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77
78
79
..
86
87
88
89
90
91
92




93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
|   Includes
|
\---------------------------------------------------------------------------*/
#include <tcl.h>
#include <dom.h>
#include <tdom.h>
#include <tcldom.h>


extern TdomStubs tdomStubs;

/*
 *----------------------------------------------------------------------------
 *
 * Tdom_Init --
................................................................................
 * Side effects:
 *	Defines "expat"/"dom" commands in the interpreter.
 *
 *----------------------------------------------------------------------------
 */

int
Tdom_Init (interp)
     Tcl_Interp *interp; /* Interpreter to initialize. */

{

#ifdef USE_TCL_STUBS
    Tcl_InitStubs(interp, "8", 0);
#endif

    domModuleInitialize();

#ifdef TCL_THREADS
    tcldom_initialize();
#endif /* TCL_THREADS */

#ifndef TDOM_NO_UNKNOWN_CMD
................................................................................
    Tcl_CreateObjCommand(interp, "domNode", tcldom_NodeObjCmd,  NULL, NULL );
    Tcl_CreateObjCommand(interp, "tdom",    TclTdomObjCmd,      NULL, NULL );

#ifndef TDOM_NO_EXPAT    
    Tcl_CreateObjCommand(interp, "expat",       TclExpatObjCmd, NULL, NULL );
    Tcl_CreateObjCommand(interp, "xml::parser", TclExpatObjCmd, NULL, NULL );
#endif




    
#ifdef USE_TCL_STUBS
    Tcl_PkgProvideEx(interp, PACKAGE_NAME, PACKAGE_VERSION, 
                     (ClientData) &tdomStubs);
#else
    Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION);
#endif

    return TCL_OK;
}

int
Tdom_SafeInit (interp)
     Tcl_Interp *interp;
{

    return Tdom_Init (interp);
}

/*
 * Load the AOLserver stub. This allows the library
 * to be loaded as AOLserver module.
 */

#if defined (NS_AOLSERVER)
# include "aolstub.cpp"
#endif








>







 







|
|
>
|
<



|







 







>
>
>
>












|
|
<
>












38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
..
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
..
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
124
|   Includes
|
\---------------------------------------------------------------------------*/
#include <tcl.h>
#include <dom.h>
#include <tdom.h>
#include <tcldom.h>
#include <tclpull.h>

extern TdomStubs tdomStubs;

/*
 *----------------------------------------------------------------------------
 *
 * Tdom_Init --
................................................................................
 * Side effects:
 *	Defines "expat"/"dom" commands in the interpreter.
 *
 *----------------------------------------------------------------------------
 */

int
Tdom_Init (
     Tcl_Interp *interp /* Interpreter to initialize. */
) {
        

#ifdef USE_TCL_STUBS
    Tcl_InitStubs(interp, "8", 0);
#endif
        
    domModuleInitialize();

#ifdef TCL_THREADS
    tcldom_initialize();
#endif /* TCL_THREADS */

#ifndef TDOM_NO_UNKNOWN_CMD
................................................................................
    Tcl_CreateObjCommand(interp, "domNode", tcldom_NodeObjCmd,  NULL, NULL );
    Tcl_CreateObjCommand(interp, "tdom",    TclTdomObjCmd,      NULL, NULL );

#ifndef TDOM_NO_EXPAT    
    Tcl_CreateObjCommand(interp, "expat",       TclExpatObjCmd, NULL, NULL );
    Tcl_CreateObjCommand(interp, "xml::parser", TclExpatObjCmd, NULL, NULL );
#endif

#ifndef TDOM_NO_PULL
    Tcl_CreateObjCommand(interp, "tdom::pullparser", tDOM_PullParserCmd, NULL, NULL );    
#endif
    
#ifdef USE_TCL_STUBS
    Tcl_PkgProvideEx(interp, PACKAGE_NAME, PACKAGE_VERSION, 
                     (ClientData) &tdomStubs);
#else
    Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION);
#endif

    return TCL_OK;
}

int
Tdom_SafeInit (
     Tcl_Interp *interp

) {
    return Tdom_Init (interp);
}

/*
 * Load the AOLserver stub. This allows the library
 * to be loaded as AOLserver module.
 */

#if defined (NS_AOLSERVER)
# include "aolstub.cpp"
#endif

Deleted generic/utf8conv.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*---------------------------------------------------------------------------
|   Copyright (C) 1999  Jochen C. Loewer (loewerj@hotmail.com)
+----------------------------------------------------------------------------
|
|   $Id$
|
|
|   Functions, which (try) to convert UTF-8 encoded Unicode strings back 
|   to some 8bit encodings like ISO-8859-*, ... 
|
|
|   The contents of this file are subject to the Mozilla Public License
|   Version 1.1 (the "License"); you may not use this file except in
|   compliance with the License. You may obtain a copy of the License at
|   http://www.mozilla.org/MPL/
|
|   Software distributed under the License is distributed on an "AS IS"
|   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|   License for the specific language governing rights and limitations
|   under the License.
|
|   The Original Code is tDOM.
|
|   The Initial Developer of the Original Code is Jochen Loewer
|   Portions created by Jochen Loewer are Copyright (C) 1998, 1999
|   Jochen Loewer. All Rights Reserved.
|
|   Contributor(s):
|
|
|   $Log$
|   Revision 1.2  2004/08/14 14:42:27  rolf
|   Use 'Id' cvs keyword (instead of 'Header') in the file heads.
|
|   Revision 1.1.1.1  2002/02/22 01:05:35  rolf
|   tDOM0.7test with Jochens first set of patches
|
|
|
|   written by Jochen Loewer
|   November, 1999
|
\--------------------------------------------------------------------------*/



/*---------------------------------------------------------------------------
|   Includes
|
\--------------------------------------------------------------------------*/
#include <tcl.h>
#include <stdlib.h>
#include <string.h>
#include <utf8conv.h>

/*---------------------------------------------------------------------------
|   Defines
|
\--------------------------------------------------------------------------*/
#define DBG(x)

#define ENC_END       0
#define ENC_IDENTITY  1
#define ENC_MAP       2

#if defined(_MSC_VER)
# define STRCASECMP(a,b)  stricmp (a,b)
#else
# define STRCASECMP(a,b)  strcasecmp (a,b)
#endif


/*---------------------------------------------------------------------------
|   Static Globals
|
\--------------------------------------------------------------------------*/
#include "encodings.inc"



/*---------------------------------------------------------------------------
|   tdom_GetEncoding  -  Looks up a encoding table for the given encoding
|                        name. If nothing was found NULL is returned.
|
\--------------------------------------------------------------------------*/
TEncoding * 
tdom_GetEncoding (
    char  * name
)
{
    TEncoding *encoding = TDOM_UnicodeTo8bitEncodings;
    
    while (encoding && encoding->name) {
        DBG(fprintf(stderr, "encoding=%x encoding->name='%s' name='%s'",
                             encoding, encoding->name, name);)
        if (STRCASECMP(encoding->name,name)==0) {
            return encoding;
        }
        encoding++;
    }
    return NULL;
}


/*---------------------------------------------------------------------------
|   tdom_GetEncodingName
|
\--------------------------------------------------------------------------*/
char *
tdom_GetEncodingName (TEncoding *encoding) 
{
    TEncoding *knownencoding = TDOM_UnicodeTo8bitEncodings;
    
    while (knownencoding && knownencoding->name) {
        if (knownencoding == encoding) {
            return (char*) knownencoding->name;
        }
        knownencoding++;
    }
    return NULL;
}
    

/*---------------------------------------------------------------------------
|   tdom_Utf8to8Bit  -  Convert a UTF-8 encode string with byte length 
|                       *len to 8bit encoding using the specify encoding.
|
\--------------------------------------------------------------------------*/
void 
tdom_Utf8to8Bit (
    TEncoding  * encoding,
    const char * utf8_string,
    int        * len
)
{
    unsigned char  *in, *end, *out;
    TEncodingRule  *rule;
    int             byte;
    int             unicode;
        
        
    if (encoding == NULL) {
       /* don't convert; keep UTF-8 */
       return;
    }
         
    in  = (unsigned char*) utf8_string;
    out = (unsigned char*) utf8_string;
    end = in + *len;
    unicode = 0;
    
    while (in < end) {

        byte = *in;

        /* extract unicode character from (multiple) UTF-8 bytes */

        if (byte < 0xC0) { 
            unicode = byte;
            in++;
        } else if (byte < 0xE0) {
            if ((in[1] & 0xC0) == 0x80) {
                unicode = ((byte & 0x1F) << 6) | (in[1] & 0x3F);
                in += 2;
            } else {
                unicode = byte; 
                in++;
            }
        } else if (byte < 0xF0) {
            if (((in[1] & 0xC0) == 0x80) && ((in[2] & 0xC0) == 0x80)) {
                unicode =  ((byte  & 0x0F) << 12)
                         | ((in[1] & 0x3F) << 6 )
                         | ((in[2] & 0x3F)      );
                in += 3;
            } else {
                unicode = byte; 
                in++; 
            }
        } else {
            /* ??? > 3 bytes UTF chars ??? */
            in++;
        }

        /* convert unicode character to 8bit representation */
        rule = encoding->rules;
        while (rule && rule->type != ENC_END) {
            if (   (unicode >= rule->start_code) 
                && (unicode < (rule->start_code + rule->len)) ) {

                if (rule->type == ENC_MAP) {
                    *out++ = rule->map[unicode - rule->start_code];
                } else {
                    *out++ = unicode & 0xFF;
                }
                break;
            }
            rule++;
        }
        if (rule->type == ENC_END) {
            /* no rule foun, use fallback */
            *out++ = encoding->fallback_char & 0x0FF;
        }
    }
    if (out < end) {
        *out = '\0';
    }
    *len = ( (char*)out - utf8_string);
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































Deleted generic/utf8conv.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*---------------------------------------------------------------------------
|   Copyright (C) 1999  Jochen C. Loewer (loewerj@hotmail.com)
+----------------------------------------------------------------------------
|
|   $Id$
|
|
|   Functions, which (try) to convert UTF-8 encoded Unicode strings back 
|   to some 8bit encodings like ISO-8859-*, ... 
|
|
|   The contents of this file are subject to the Mozilla Public License
|   Version 1.1 (the "License"); you may not use this file except in
|   compliance with the License. You may obtain a copy of the License at
|   http://www.mozilla.org/MPL/
|
|   Software distributed under the License is distributed on an "AS IS"
|   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|   License for the specific language governing rights and limitations
|   under the License.
|
|   The Original Code is tDOM.
|
|   The Initial Developer of the Original Code is Jochen Loewer
|   Portions created by Jochen Loewer are Copyright (C) 1998, 1999
|   Jochen Loewer. All Rights Reserved.
|
|   Contributor(s):
|
|
|   $Log$
|   Revision 1.3  2004/08/14 14:42:27  rolf
|   Use 'Id' cvs keyword (instead of 'Header') in the file heads.
|
|   Revision 1.2  2002/07/04 15:06:49  zoran
|   fixed reference to unsigned* to char since Sun compiler barfs at it.
|
|   Revision 1.1.1.1  2002/02/22 01:05:35  rolf
|   tDOM0.7test with Jochens first set of patches
|
|
|
|   written by Jochen Loewer
|   November, 1999
|
\--------------------------------------------------------------------------*/

#ifndef __UTF8CONV_H__
#define __UTF8CONV_H__


/*---------------------------------------------------------------------------
|   Includes
|
\--------------------------------------------------------------------------*/
#include <tcl.h>
#include <stdlib.h>
#include <string.h>


/*---------------------------------------------------------------------------
|   Typedefs
|
\--------------------------------------------------------------------------*/
typedef struct {
    int             type;
    int             start_code;
    int             len;
    char          * map;
} TEncodingRule;

typedef struct {
    const char    * name;
    int             fallback_char;
    TEncodingRule * rules;
} TEncoding;


             
/*--------------------------------------------------------------------------
|   Function prototypes
|
\-------------------------------------------------------------------------*/
TEncoding * tdom_GetEncoding (char *name);
char *      tdom_GetEncodingName (TEncoding *encoding);
void        tdom_Utf8to8Bit (TEncoding  *encoding, 
                             const char *utf8_string, int *len);

#endif

    
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































Changes to generic/xmlsimple.c.

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
..
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
...
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
...
402
403
404
405
406
407
408

409
410
411
412
413
414
415
...
456
457
458
459
460
461
462




















463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490







491
492
493
494
495
496
497
...
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
...
617
618
619
620
621
622
623

624
625







626
627
628

629

















630
631
632
633
634



635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650


651
652
653
654
655
656
657
....
1022
1023
1024
1025
1026
1027
1028








1029
1030
1031
1032
1033
1034
1035
....
1060
1061
1062
1063
1064
1065
1066

1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
|
|
|   adopted/written by Jochen Loewer
|   July 1999
|
|   ------------------------------------------------------------------------
|
|   A parser for XML.
|
|   Copyright (C) 1998 D. Richard Hipp
|
|   This library is free software; you can redistribute it and/or
|   modify it under the terms of the GNU Library General Public
|   License as published by the Free Software Foundation; either
|   version 2 of the License, or (at your option) any later version.
|
|   This library is distributed in the hope that it will be useful,
|   but WITHOUT ANY WARRANTY; without even the implied warranty of
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
|   Library General Public License for more details.
|
|   You should have received a copy of the GNU Library General Public
|   License along with this library; if not, write to the
|   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|   Boston, MA  02111-1307, USA.
|
|   Author contact information:
|     drh@acm.org
|     http://www.hwaci.com/drh/
|
\---------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------
|   Includes
|
................................................................................
#ifdef TDOM_NS
# define RetError(m,p) *errStr=m; *pos=p; FREE((char*)activeNS); return TCL_ERROR;
#else 
# define RetError(m,p) *errStr=m; *pos=p; return TCL_ERROR;
#endif
#define SPACE(c)       ((c)==' ' || (c)=='\n' || (c)=='\t' || (c)=='\r')

/*---------------------------------------------------------------------------
|   type domActiveNS
|
\--------------------------------------------------------------------------*/
typedef struct _domActiveNS {

    int    depth;
    domNS *namespace;

} domActiveNS;

/*----------------------------------------------------------------------------
|   Begin Character Entity Translator
|
|
|   The next section of code implements routines used to translate
|   character entity references into their corresponding strings.
|
................................................................................
\---------------------------------------------------------------------------*/
static Er er_sequences[] = {
    { "amp",       "&",        0 },
    { "lt",        "<",        0 },
    { "gt",        ">",        0 },
    { "apos",      "'",        0 },
    { "quot",      "\"",       0 },
#if TclOnly8Bits
    { "nbsp",      "\240",     0 },
#else
    { "nbsp",      "\xC2\xA0",    0 },
#endif
};


/*----------------------------------------------------------------------------
|   ErInit --
|
|       Initialize the entity reference hash table
................................................................................
                    }
                }
                if (!z[i] || (z[i]!=';')) {
                    return 0;
                    /* error */
                }
                from = i+1;
#if TclOnly8Bits
                z[to++] = value;
#else 
                if (value < 0x80) {
                    z[to++] = value;
                } else if (value <= 0x7FF) {
                    z[to++] = (char) ((value >> 6) | 0xC0);
                    z[to++] = (char) ((value | 0x80) & 0xBF);
                } else if (value <= 0xFFFF) {
                    z[to++] = (char) ((value >> 12) | 0xE0);
                    z[to++] = (char) (((value >> 6) | 0x80) & 0xBF);
                    z[to++] = (char) ((value | 0x80) & 0xBF);
                } else {
                    /* error */
                    return 0;
                }
#endif
            } else {
                while (z[i] && isalpha((unsigned char)z[i])) {
                   i++;
                }
                if (!z[i] || (z[i]!=';')) {
                    return 0;
                }
................................................................................
    *newLen = to;
    return 1;
}
/*----------------------------------------------------------------------------
|   End Of Character Entity Translator
\---------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------
|   domIsNamespaceInScope
|
\--------------------------------------------------------------------------*/
static int
domIsNamespaceInScope (
    domActiveNS *NSstack,
    int          NSstackPos,
    const char  *prefix,
    const char  *namespaceURI
)
{
    int    i;

    for (i = NSstackPos; i >= 0; i--) {
        if (NSstack[i].namespace->prefix[0] &&
            (strcmp(NSstack[i].namespace->prefix, prefix)==0)) {
            if (strcmp(NSstack[i].namespace->uri, namespaceURI)==0) {
                /* OK, exactly the same namespace declaration is in scope */
                return 1;
            } else {
                /* This prefix is currently assigned to another uri,
                   we need a new NS declaration, to override this one */
                return 0;
            }
        }
    }
    return 0;
}

/*----------------------------------------------------------------------------
|   XML_SimpleParse (non recursive)
|
|       Parses the XML string starting at 'pos' and continuing to the
|       first encountered error.
|
\---------------------------------------------------------------------------*/
................................................................................
static int
XML_SimpleParse (
    char        *xml,   /* XML string  */
    int         *pos,   /* Index of next unparsed character in xml */
    domDocument *doc,
    domNode     *parent_nodeOld,
    int          ignoreWhiteSpaces,

    char       **errStr
) {
    register int   c;          /* Next character of the input file */
    register char *pn;
    register char *x, *start, *piSep;
    int            saved;
    int            hasContent;
................................................................................
                     (c != '\n') &&
                     (c != '\r') ) {
                    only_whites = 0;
                }
                x++;
            }
            if (!(only_whites && ignoreWhiteSpaces) && parent_node) {




















                /*--------------------------------------------------------
                |   allocate new TEXT node
                 \-------------------------------------------------------*/
                tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                memset(tnode, 0, sizeof(domTextNode));
                tnode->nodeType    = TEXT_NODE;
                tnode->nodeFlags   = 0;
                tnode->namespace   = 0;
                tnode->ownerDocument = doc;
                tnode->nodeNumber  = NODE_NO(doc);
                tnode->valueLength = (x - start);
                tnode->nodeValue   = (char*)MALLOC((x - start)+1);
                memmove(tnode->nodeValue, start, (x - start));
                *(tnode->nodeValue + (x - start)) = 0;
                if (ampersandSeen) {
                    if (!TranslateEntityRefs(tnode->nodeValue, 
                                             &(tnode->valueLength) )) {
                        RetError("Entity parsing error", (x - xml));
                    }
                }
                tnode->parentNode = parent_node;
                if (parent_node->firstChild)  {
                    parent_node->lastChild->nextSibling = (domNode*)tnode;
                    tnode->previousSibling = parent_node->lastChild;
                    parent_node->lastChild = (domNode*)tnode;
                } else {
                    parent_node->firstChild = parent_node->lastChild = 
                        (domNode*)tnode;







                }
            }

        } else if (x[1]=='/') {
            /*------------------------------------------------------------
            |   read and check closing tag
            \-----------------------------------------------------------*/
................................................................................
                        /*----------------------------------------------------
                        |   allocate new COMMENT node for comments
                        \---------------------------------------------------*/
                        tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                        memset(tnode, 0, sizeof(domTextNode));
                        tnode->nodeType      = COMMENT_NODE;
                        tnode->nodeFlags     = 0;
                        tnode->namespace     = 0;
                        tnode->ownerDocument = doc;
                        tnode->nodeNumber    = NODE_NO(doc);
                        tnode->parentNode    = parent_node;
                        tnode->valueLength   = x - start - 4;
                        tnode->nodeValue     = (char*)MALLOC(tnode->valueLength+1);
                        memmove(tnode->nodeValue, start+4, tnode->valueLength);
                        *(tnode->nodeValue + tnode->valueLength) = 0;
................................................................................
                           x[3]=='D' && x[4]=='A' &&
                           x[5]=='T' && x[6]=='A' && x[7]=='[' ) {
                    /*--------------------------------------------------------
                    |   read over a <![CDATA[ section
                    \-------------------------------------------------------*/
                    x += 8;
                    start = x;

                    while ( (*x!=0) &&
                            ((*x!=']') || (x[1]!=']') || (x[2]!='>'))) {







                        x++;
                    }
                    if (*x) {

                        if (parent_node && (x - start)) {

















                            /*----------------------------------------------------
                            |   allocate new TEXT node for CDATA section data
                            \---------------------------------------------------*/
                            tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                            memset(tnode, 0, sizeof(domTextNode));



                            tnode->nodeType      = TEXT_NODE;
                            tnode->nodeFlags     = 0;
                            tnode->namespace     = 0;
                            tnode->ownerDocument = doc;
                            tnode->nodeNumber    = NODE_NO(doc);
                            tnode->parentNode    = parent_node;
                            tnode->valueLength   = (x - start);
                            tnode->nodeValue     = (char*)MALLOC((x - start)+1);
                            memmove(tnode->nodeValue, start, (x - start));
                            *(tnode->nodeValue + (x - start)) = 0;
                            if (parent_node->firstChild)  {
                                parent_node->lastChild->nextSibling = (domNode*)tnode;
                                tnode->previousSibling = parent_node->lastChild;
                                parent_node->lastChild = (domNode*)tnode;
                            } else {
                                parent_node->firstChild = parent_node->lastChild = (domNode*)tnode;


                            }
                        }
                        x += 3;
                    } else {
                        RetError("Unterminated CDATA definition",(start-xml) );
                    }
                    continue;
................................................................................
#endif
            if (*x=='/') {
                hasContent = 0;
                x++;
                if (*x!='>') {
                    RetError("Syntax Error",(x - xml - 1) );
                }








            }
            if (x[1] == 0) {
#ifdef TDOM_NS
                FREE ((char *) activeNS);
#endif                
                return TCL_OK;
            }
................................................................................
|       continuing to the first encountered error.
|
\---------------------------------------------------------------------------*/
domDocument *
XML_SimpleParseDocument (
    char    *xml,              /* Complete text of the file being parsed  */
    int      ignoreWhiteSpaces,

    char    *baseURI,
    char    *extResolver,
    int     *pos,
    char   **errStr
) {
    domDocument   *doc = domCreateDoc(baseURI, 0);

    if (extResolver) {
        doc->extResolver = extResolver;
    }
    
    *pos = 0;
    XML_SimpleParse (xml, pos, doc, NULL, ignoreWhiteSpaces, errStr);
    domSetDocumentElement (doc);

    return doc;

} /* XML_SimpleParseDocument */








|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<
<
<
<
<
<
<
<
<
<
<







 







<
<
<

<







 







<
<
<













<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
<
|
|
|
|
|
|
<
<
<
<
<
<
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>







 







<







 







>
|

>
>
>
>
>
>
>



>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
>
>
>
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>







 







>
>
>
>
>
>
>
>







 







>

|






|



|






29
30
31
32
33
34
35
36
37
38



















39
40
41
42
43
44
45
..
58
59
60
61
62
63
64











65
66
67
68
69
70
71
...
158
159
160
161
162
163
164



165

166
167
168
169
170
171
172
...
268
269
270
271
272
273
274



275
276
277
278
279
280
281
282
283
284
285
286
287

288
289
290
291
292
293
294
...
319
320
321
322
323
324
325































326
327
328
329
330
331
332
...
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
...
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421

422
423
424
425
426
427






428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
...
502
503
504
505
506
507
508

509
510
511
512
513
514
515
...
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616

617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
....
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
....
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
|
|
|   adopted/written by Jochen Loewer
|   July 1999
|
|   ------------------------------------------------------------------------
|
|   Partly based on a parser for XML (for TMML by R.Hipp 1998). 
|   This source code is released into the public domain by the author.
|   on 2002, December 17.



















|
\---------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------
|   Includes
|
................................................................................
#ifdef TDOM_NS
# define RetError(m,p) *errStr=m; *pos=p; FREE((char*)activeNS); return TCL_ERROR;
#else 
# define RetError(m,p) *errStr=m; *pos=p; return TCL_ERROR;
#endif
#define SPACE(c)       ((c)==' ' || (c)=='\n' || (c)=='\t' || (c)=='\r')












/*----------------------------------------------------------------------------
|   Begin Character Entity Translator
|
|
|   The next section of code implements routines used to translate
|   character entity references into their corresponding strings.
|
................................................................................
\---------------------------------------------------------------------------*/
static Er er_sequences[] = {
    { "amp",       "&",        0 },
    { "lt",        "<",        0 },
    { "gt",        ">",        0 },
    { "apos",      "'",        0 },
    { "quot",      "\"",       0 },



    { "nbsp",      "\xC2\xA0",    0 },

};


/*----------------------------------------------------------------------------
|   ErInit --
|
|       Initialize the entity reference hash table
................................................................................
                    }
                }
                if (!z[i] || (z[i]!=';')) {
                    return 0;
                    /* error */
                }
                from = i+1;



                if (value < 0x80) {
                    z[to++] = value;
                } else if (value <= 0x7FF) {
                    z[to++] = (char) ((value >> 6) | 0xC0);
                    z[to++] = (char) ((value | 0x80) & 0xBF);
                } else if (value <= 0xFFFF) {
                    z[to++] = (char) ((value >> 12) | 0xE0);
                    z[to++] = (char) (((value >> 6) | 0x80) & 0xBF);
                    z[to++] = (char) ((value | 0x80) & 0xBF);
                } else {
                    /* error */
                    return 0;
                }

            } else {
                while (z[i] && isalpha((unsigned char)z[i])) {
                   i++;
                }
                if (!z[i] || (z[i]!=';')) {
                    return 0;
                }
................................................................................
    *newLen = to;
    return 1;
}
/*----------------------------------------------------------------------------
|   End Of Character Entity Translator
\---------------------------------------------------------------------------*/
































/*----------------------------------------------------------------------------
|   XML_SimpleParse (non recursive)
|
|       Parses the XML string starting at 'pos' and continuing to the
|       first encountered error.
|
\---------------------------------------------------------------------------*/
................................................................................
static int
XML_SimpleParse (
    char        *xml,   /* XML string  */
    int         *pos,   /* Index of next unparsed character in xml */
    domDocument *doc,
    domNode     *parent_nodeOld,
    int          ignoreWhiteSpaces,
    int          keepCDATA,
    char       **errStr
) {
    register int   c;          /* Next character of the input file */
    register char *pn;
    register char *x, *start, *piSep;
    int            saved;
    int            hasContent;
................................................................................
                     (c != '\n') &&
                     (c != '\r') ) {
                    only_whites = 0;
                }
                x++;
            }
            if (!(only_whites && ignoreWhiteSpaces) && parent_node) {
                if (parent_node->lastChild
                    && parent_node->lastChild->nodeType == TEXT_NODE) {
                    /* normalize text node, i.e. there are no adjacent
                     * text nodes */
                    tnode = (domTextNode*)parent_node->lastChild;
                    tnode->nodeValue = REALLOC(tnode->nodeValue,
                                               tnode->valueLength + x - start + 1);
                    memmove(tnode->nodeValue + tnode->valueLength,
                            start, x - start);
                    saved = tnode->valueLength;
                    tnode->valueLength += (x - start);
                    *(tnode->nodeValue + tnode->valueLength) = 0;
                    if (ampersandSeen) {
                        if (!TranslateEntityRefs(tnode->nodeValue + saved, 
                                                 &(tnode->valueLength) )) {
                            RetError("Entity parsing error", (x - xml));
                        }
                        tnode->valueLength += saved;
                    }
                } else {
                    /*--------------------------------------------------------
                      |   allocate new TEXT node
                      \-------------------------------------------------------*/
                    tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                    memset(tnode, 0, sizeof(domTextNode));
                    tnode->nodeType    = TEXT_NODE;
                    tnode->nodeFlags   = 0;

                    tnode->ownerDocument = doc;
                    tnode->nodeNumber  = NODE_NO(doc);
                    tnode->valueLength = (x - start);
                    tnode->nodeValue   = (char*)MALLOC((x - start)+1);
                    memmove(tnode->nodeValue, start, (x - start));
                    *(tnode->nodeValue + (x - start)) = 0;






                    tnode->parentNode = parent_node;
                    if (parent_node->firstChild)  {
                        parent_node->lastChild->nextSibling = (domNode*)tnode;
                        tnode->previousSibling = parent_node->lastChild;
                        parent_node->lastChild = (domNode*)tnode;
                    } else {
                        parent_node->firstChild = parent_node->lastChild = 
                            (domNode*)tnode;
                    }
                    if (ampersandSeen) {
                        if (!TranslateEntityRefs(tnode->nodeValue, 
                                                 &(tnode->valueLength) )) {
                            RetError("Entity parsing error", (x - xml));
                        }
                    }
                }
            }

        } else if (x[1]=='/') {
            /*------------------------------------------------------------
            |   read and check closing tag
            \-----------------------------------------------------------*/
................................................................................
                        /*----------------------------------------------------
                        |   allocate new COMMENT node for comments
                        \---------------------------------------------------*/
                        tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                        memset(tnode, 0, sizeof(domTextNode));
                        tnode->nodeType      = COMMENT_NODE;
                        tnode->nodeFlags     = 0;

                        tnode->ownerDocument = doc;
                        tnode->nodeNumber    = NODE_NO(doc);
                        tnode->parentNode    = parent_node;
                        tnode->valueLength   = x - start - 4;
                        tnode->nodeValue     = (char*)MALLOC(tnode->valueLength+1);
                        memmove(tnode->nodeValue, start+4, tnode->valueLength);
                        *(tnode->nodeValue + tnode->valueLength) = 0;
................................................................................
                           x[3]=='D' && x[4]=='A' &&
                           x[5]=='T' && x[6]=='A' && x[7]=='[' ) {
                    /*--------------------------------------------------------
                    |   read over a <![CDATA[ section
                    \-------------------------------------------------------*/
                    x += 8;
                    start = x;
                    only_whites = 1;
                    while ( ((c=*x)!=0) &&
                            ((*x!=']') || (x[1]!=']') || (x[2]!='>'))) {
                        if (only_whites &&
                            (c != ' ')  &&
                            (c != '\t') &&
                            (c != '\n') &&
                            (c != '\r') ) {
                            only_whites = 0;
                        }
                        x++;
                    }
                    if (*x) {
                        if (parent_node && ((x - start) || keepCDATA)) {
                            if (parent_node->lastChild
                                && parent_node->lastChild->nodeType == TEXT_NODE
                                && !keepCDATA) {
                                if ((x - start) && !(only_whites && ignoreWhiteSpaces)) {
                                    /* normalize text node, i.e. there
                                     * are no adjacent text nodes */
                                    tnode = (domTextNode*)parent_node->lastChild;
                                    tnode->nodeValue =
                                        REALLOC(tnode->nodeValue,
                                                tnode->valueLength + x - start + 1);
                                    memmove(tnode->nodeValue + tnode->valueLength,
                                            start, x - start);
                                    tnode->valueLength += (x - start);
                                    *(tnode->nodeValue + tnode->valueLength) = 0;
                                }
                            } else {
                                if (!(only_whites && ignoreWhiteSpaces)
                                    && ((x - start) || keepCDATA)) {
                                    /*----------------------------------------------------
                                      |   allocate new node for CDATA section data
                                      \---------------------------------------------------*/
                                    tnode = (domTextNode*) domAlloc(sizeof(domTextNode));
                                    memset(tnode, 0, sizeof(domTextNode));
                                    if (keepCDATA)
                                        tnode->nodeType      = CDATA_SECTION_NODE;
                                    else 
                                        tnode->nodeType      = TEXT_NODE;
                                    tnode->nodeFlags     = 0;

                                    tnode->ownerDocument = doc;
                                    tnode->nodeNumber    = NODE_NO(doc);
                                    tnode->parentNode    = parent_node;
                                    tnode->valueLength   = (x - start);
                                    tnode->nodeValue     = (char*)MALLOC((x - start)+1);
                                    memmove(tnode->nodeValue, start, (x - start));
                                    *(tnode->nodeValue + (x - start)) = 0;
                                    if (parent_node->firstChild)  {
                                        parent_node->lastChild->nextSibling = (domNode*)tnode;
                                        tnode->previousSibling = parent_node->lastChild;
                                        parent_node->lastChild = (domNode*)tnode;
                                    } else {
                                        parent_node->firstChild = parent_node->lastChild = (domNode*)tnode;
                                    }
                                }
                            }
                        }
                        x += 3;
                    } else {
                        RetError("Unterminated CDATA definition",(start-xml) );
                    }
                    continue;
................................................................................
#endif
            if (*x=='/') {
                hasContent = 0;
                x++;
                if (*x!='>') {
                    RetError("Syntax Error",(x - xml - 1) );
                }
#ifdef TDOM_NS 
                /* pop active namespaces */
                while ( (activeNSpos >= 0) &&
                        (activeNS[activeNSpos].depth == depth) )
                {
                    activeNSpos--;
                } 
#endif                                   
            }
            if (x[1] == 0) {
#ifdef TDOM_NS
                FREE ((char *) activeNS);
#endif                
                return TCL_OK;
            }
................................................................................
|       continuing to the first encountered error.
|
\---------------------------------------------------------------------------*/
domDocument *
XML_SimpleParseDocument (
    char    *xml,              /* Complete text of the file being parsed  */
    int      ignoreWhiteSpaces,
    int      keepCDATA,
    char    *baseURI,
    Tcl_Obj *extResolver,
    int     *pos,
    char   **errStr
) {
    domDocument   *doc = domCreateDoc(baseURI, 0);

    if (extResolver) {
        doc->extResolver = tdomstrdup (Tcl_GetString (extResolver));
    }
    
    *pos = 0;
    XML_SimpleParse (xml, pos, doc, NULL, ignoreWhiteSpaces, keepCDATA, errStr);
    domSetDocumentElement (doc);

    return doc;

} /* XML_SimpleParseDocument */

Changes to generic/xmlsimple.h.

1
2

3
4

domDocument *  XML_SimpleParseDocument ( char *xml, int ignoreWhiteSpaces, 

                                         char *baseURI, char *extResolver,
                                         int *pos, char **errStr );

|
>
|

1
2
3
4
5

domDocument *  XML_SimpleParseDocument ( char *xml, int ignoreWhiteSpaces,
                                         int keepCDATA,
                                         char *baseURI, Tcl_Obj *extResolver,
                                         int *pos, char **errStr );

Changes to lib/tdom.tcl.

47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
...
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
...
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
...
731
732
733
734
735
736
737
738
739
740
741
742







743
744
745
746
747
748
749
...
755
756
757
758
759
760
761
762
763
764

765

766
767
768












769
770
771
772

773
774
775
776
777
778
779
...
810
811
812
813
814
815
816
817
818
819








820




821
822

823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838














839
840
841
842
843
844
















845
846
847
848
849
850
851
852
853
854
855
856
857
...
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886







887
888
889
890
891
892
893
...
896
897
898
899
900
901
902


903
904
905
906
907


908
909

910







911
912
913
914


















915
    }
    namespace eval  xpathFunc {
    }
    namespace eval  xpathFuncHelper {
    }
}

namespace eval ::tDOM { 
    variable extRefHandlerDebug 0
    variable useForeignDTD ""

    namespace export xmlOpenFile xmlReadFile extRefHandler baseURL

}

#----------------------------------------------------------------------------
#   hasFeature (DOMImplementation method)
#
#
#   @in  url    the URL, where to get the XML document
................................................................................
# cp1251 koi8-u macDingbats iso8859-7 cp1252 iso8859-8 cp1253
# iso8859-9 cp1254 cp1255 cp850 cp1256 cp932 identity cp1257 cp852
# macJapan cp1258 shiftjis utf-8 cp855 cp936 symbol cp775 unicode
# cp857
# 
# Just add more mappings (and mail them to the tDOM mailing list, please).

proc tDOM::IANAEncoding2TclEncoding {IANAName} {
    
    # First the most widespread encodings with there
    # preferred MIME name, to speed lookup in this
    # usual cases. Later the official names and the
    # aliases.
    #
    # For "official names for character sets that may be
................................................................................
    # (that's the source for the encoding names below)
    # 
    # Matching is case-insensitive

    switch [string tolower $IANAName] {
        "us-ascii"    {return ascii}
        "utf-8"       {return utf-8}
        "utf-16"      {return unicode; # not sure about this}
        "iso-8859-1"  {return iso8859-1}
        "iso-8859-2"  {return iso8859-2}
        "iso-8859-3"  {return iso8859-3}
        "iso-8859-4"  {return iso8859-4}
        "iso-8859-5"  {return iso8859-5}
        "iso-8859-6"  {return iso8859-6}
        "iso-8859-7"  {return iso8859-7}
................................................................................
            # It's only laziness, that let me stop here.
            error "Unrecognized encoding name '$IANAName'"
        }
    }
}

#----------------------------------------------------------------------------
#   xmlOpenFile
#
#----------------------------------------------------------------------------
proc tDOM::xmlOpenFile {filename {encodingString {}}} {








    set fd [open $filename]

    if {$encodingString != {}} {
        upvar $encodingString encString
    }

    # The autodetection of the encoding follows
................................................................................
        seek $fd 0 start
        set encString UTF-8
        return $fd
    }
    
    # First check for BOM
    switch [string range $firstBytes 0 3] {
        "feff" -
        "fffe" {
            # feff: UTF-16, big-endian BOM

            # ffef: UTF-16, little-endian BOM

            seek $fd 0 start
            set encString UTF-16            
            fconfigure $fd -encoding identity












            return $fd
        }
    }


    # If the entity has a XML Declaration, the first four characters
    # must be "<?xm".
    switch $firstBytes {
        "3c3f786d" {
            # UTF-8, ISO 646, ASCII, some part of ISO 8859, Shift-JIS,
            # EUC, or any other 7-bit, 8-bit, or mixed-width encoding which 
            # ensures that the characters of ASCII have their normal positions,
................................................................................
        "0000003c" -
        "0000003c" -
        "3c000000" -
        "00003c00" {
            # UCS-4
            error "UCS-4 not supported"
        }
        "003c003f" -
        "3c003f00" {
            # UTF-16, big-endian, no BOM








            # UTF-16, little-endian, no BOM




            seek $fd 0 start
            set encoding identity

            set encString UTF-16
        }
        "4c6fa794" {
            # EBCDIC in some flavor
            error "EBCDIC not supported"
        }
        default {
            # UTF-8 without an encoding declaration
            seek $fd 0 start
            set encoding identity
            set encString "UTF-8"
        }
    }
    fconfigure $fd -encoding $encoding
    return $fd
}















#----------------------------------------------------------------------------
#   xmlReadFile
#
#----------------------------------------------------------------------------
proc tDOM::xmlReadFile {filename {encodingString {}}} {

















    if {$encodingString != {}} {
        upvar $encodingString encString
    }
    
    set fd [xmlOpenFile $filename encString]
    set data [read $fd [file size $filename]]
    close $fd 
    return $data
}

#----------------------------------------------------------------------------
#   extRefHandler
................................................................................
#   
#   A very simple external entity resolver, included for convenience.
#   Depends on the tcllib package uri and resolves only file URLs. 
#
#----------------------------------------------------------------------------

if {![catch {package require uri}]} {
    proc tDOM::extRefHandler {base systemId publicId} {
        variable extRefHandlerDebug
        variable useForeignDTD

        if {$extRefHandlerDebug} {
            puts stderr "tDOM::extRefHandler called with:"
            puts stderr "\tbase:     '$base'"
            puts stderr "\tsystemId: '$systemId'"
            puts stderr "\tpublicId: '$publicId'"
        }
        if {$systemId == ""} {
            if {$useForeignDTD != ""} {
                set systemId $useForeignDTD
            } else {
                error "::tDOM::useForeignDTD does\
                        not point to the foreign DTD"
            }
        }
        set absolutURI [uri::resolve $base $systemId]
        array set uriData [uri::split $absolutURI]
        switch $uriData(scheme) {
            file {







                return [list string $absolutURI [xmlReadFile $uriData(path)]]
            }
            default {
                error "can only handle file URI's"
            }
        }
    }
................................................................................
#----------------------------------------------------------------------------
#   baseURL
#   
#   A simple convenience proc which returns an absolute URL for a given
#   filename.
#
#----------------------------------------------------------------------------



proc tDOM::baseURL {path} {
    switch [file pathtype $path] {
        "relative" {
            return "file://[pwd]/$path"


        }
        default {

            return "file://$path"







        }
    }
}



















# EOF







|



|
>







 







|







 







|







 







|


|

>
>
>
>
>
>
>







 







|
<

>
|
>

|
|
>
>
>
>
>
>
>
>
>
>
>
>



|
>







 







|
<

>
>
>
>
>
>
>
>

>
>
>
>
|
|
>
|








|






>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|







 







|




|








|







>
>
>
>
>
>
>







 







>
>

<
<
|
|
>
>
|
<
>
|
>
>
>
>
>
>
>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
...
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
...
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
...
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
...
763
764
765
766
767
768
769
770

771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
...
832
833
834
835
836
837
838
839

840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
...
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
...
967
968
969
970
971
972
973
974
975
976


977
978
979
980
981

982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
    }
    namespace eval  xpathFunc {
    }
    namespace eval  xpathFuncHelper {
    }
}

namespace eval ::tdom { 
    variable extRefHandlerDebug 0
    variable useForeignDTD ""

    namespace export xmlOpenFile xmlReadFile xmlReadFileForSimple \
        extRefHandler baseURL
}

#----------------------------------------------------------------------------
#   hasFeature (DOMImplementation method)
#
#
#   @in  url    the URL, where to get the XML document
................................................................................
# cp1251 koi8-u macDingbats iso8859-7 cp1252 iso8859-8 cp1253
# iso8859-9 cp1254 cp1255 cp850 cp1256 cp932 identity cp1257 cp852
# macJapan cp1258 shiftjis utf-8 cp855 cp936 symbol cp775 unicode
# cp857
# 
# Just add more mappings (and mail them to the tDOM mailing list, please).

proc tdom::IANAEncoding2TclEncoding {IANAName} {
    
    # First the most widespread encodings with there
    # preferred MIME name, to speed lookup in this
    # usual cases. Later the official names and the
    # aliases.
    #
    # For "official names for character sets that may be
................................................................................
    # (that's the source for the encoding names below)
    # 
    # Matching is case-insensitive

    switch [string tolower $IANAName] {
        "us-ascii"    {return ascii}
        "utf-8"       {return utf-8}
        "utf-16"      {return unicode}
        "iso-8859-1"  {return iso8859-1}
        "iso-8859-2"  {return iso8859-2}
        "iso-8859-3"  {return iso8859-3}
        "iso-8859-4"  {return iso8859-4}
        "iso-8859-5"  {return iso8859-5}
        "iso-8859-6"  {return iso8859-6}
        "iso-8859-7"  {return iso8859-7}
................................................................................
            # It's only laziness, that let me stop here.
            error "Unrecognized encoding name '$IANAName'"
        }
    }
}

#----------------------------------------------------------------------------
#   xmlOpenFileWorker
#
#----------------------------------------------------------------------------
proc tdom::xmlOpenFileWorker {filename {encodingString {}} {forSimple 0} {forRead 0}} {

    # This partly (mis-)use the encoding of a channel handed to [dom
    # parse -channel ..] as a marker: if the channel encoding is utf-8
    # then behind the scene Tcl_Read() is used, otherwise
    # Tcl_ReadChars(). This is used for the encodings understood (and
    # checked) by the used expat implementation: utf-8 and utf-16 (in
    # either byte order).
    
    set fd [open $filename]

    if {$encodingString != {}} {
        upvar $encodingString encString
    }

    # The autodetection of the encoding follows
................................................................................
        seek $fd 0 start
        set encString UTF-8
        return $fd
    }
    
    # First check for BOM
    switch [string range $firstBytes 0 3] {
        "feff" {

            # feff: UTF-16, big-endian BOM
            if {$forSimple || $forRead} {
                error "UTF-16be is not supported"
            }
            seek $fd 0 start
            set encString UTF-16be
            fconfigure $fd -encoding utf-8
            return $fd
        }
        "fffe" {
            # ffef: UTF-16, little-endian BOM
            set encString UTF-16le          
            if {$forSimple || $forRead} {
                seek $fd 2 start
                fconfigure $fd -encoding unicode
            } else {
                seek $fd 0 start
                fconfigure $fd -encoding utf-8
            }
            return $fd
        }
    }
    
    
    # If the entity has a XML Declaration, the first four characters
    # must be "<?xm".
    switch $firstBytes {
        "3c3f786d" {
            # UTF-8, ISO 646, ASCII, some part of ISO 8859, Shift-JIS,
            # EUC, or any other 7-bit, 8-bit, or mixed-width encoding which 
            # ensures that the characters of ASCII have their normal positions,
................................................................................
        "0000003c" -
        "0000003c" -
        "3c000000" -
        "00003c00" {
            # UCS-4
            error "UCS-4 not supported"
        }
            "003c003f" {

            # UTF-16, big-endian, no BOM
            if {$forSimple} {
                error "UTF-16be is not supported by the simple parser"
            }
            seek $fd 0 start
            set encoding utf-8
            set encString UTF-16be
        }
        "3c003f00" {
            # UTF-16, little-endian, no BOM
            if {$forSimple} {
                seek $fd 2 start
                set encoding unicode
            } else {
                seek $fd 0 start
                set encoding utf-8
            }
            set encString UTF-16le          
        }
        "4c6fa794" {
            # EBCDIC in some flavor
            error "EBCDIC not supported"
        }
        default {
            # UTF-8 without an encoding declaration
            seek $fd 0 start
            set encoding utf-8
            set encString "UTF-8"
        }
    }
    fconfigure $fd -encoding $encoding
    return $fd
}

#----------------------------------------------------------------------------
#   xmlOpenFile
#
#----------------------------------------------------------------------------
proc tdom::xmlOpenFile {filename {encodingString {}}} {

    if {$encodingString != {}} {
        upvar $encodingString encString
    }
    
    set fd [xmlOpenFileWorker $filename encString]
    return $fd
}

#----------------------------------------------------------------------------
#   xmlReadFile
#
#----------------------------------------------------------------------------
proc tdom::xmlReadFile {filename {encodingString {}}} {

    if {$encodingString != {}} {
        upvar $encodingString encString
    }
    
    set fd [xmlOpenFileWorker $filename encString 0 1]
    set data [read $fd [file size $filename]]
    close $fd 
    return $data
}

#----------------------------------------------------------------------------
#   xmlReadFileForSimple
#
#----------------------------------------------------------------------------
proc tdom::xmlReadFileForSimple {filename {encodingString {}}} {

    if {$encodingString != {}} {
        upvar $encodingString encString
    }
    
    set fd [xmlOpenFileWorker $filename encString 1]
    set data [read $fd [file size $filename]]
    close $fd 
    return $data
}

#----------------------------------------------------------------------------
#   extRefHandler
................................................................................
#   
#   A very simple external entity resolver, included for convenience.
#   Depends on the tcllib package uri and resolves only file URLs. 
#
#----------------------------------------------------------------------------

if {![catch {package require uri}]} {
    proc tdom::extRefHandler {base systemId publicId} {
        variable extRefHandlerDebug
        variable useForeignDTD

        if {$extRefHandlerDebug} {
            puts stderr "tdom::extRefHandler called with:"
            puts stderr "\tbase:     '$base'"
            puts stderr "\tsystemId: '$systemId'"
            puts stderr "\tpublicId: '$publicId'"
        }
        if {$systemId == ""} {
            if {$useForeignDTD != ""} {
                set systemId $useForeignDTD
            } else {
                error "::tdom::useForeignDTD does\
                        not point to the foreign DTD"
            }
        }
        set absolutURI [uri::resolve $base $systemId]
        array set uriData [uri::split $absolutURI]
        switch $uriData(scheme) {
            file {
                if {$::tcl_platform(platform) eq "windows"} {
                    # Strip leading / for drive based paths
                    if {[string match /?:* $uriData(path)]} {
                        set uriData(path) [string range $uriData(path) 1 end]
                    }
                }
                # FIXME - path should be URL-decoded
                return [list string $absolutURI [xmlReadFile $uriData(path)]]
            }
            default {
                error "can only handle file URI's"
            }
        }
    }
................................................................................
#----------------------------------------------------------------------------
#   baseURL
#   
#   A simple convenience proc which returns an absolute URL for a given
#   filename.
#
#----------------------------------------------------------------------------
proc tdom::baseURL {path} {
    # FIXME - path components need to be URL-encoded



    # Note [file join] will return path as is if it is already absolute.
    # Also on Windows, it will change \ -> /. This is necessary because
    # file URIs must always use /, never \.
    set path [file join [pwd] $path]


    if {$::tcl_platform(platform) ne "windows"} {
        return "file://$path"
    } else {
        if {[string match //* $path]} {
            # UNC path
            return "file:$path"
        } else {
            # Drive based path
            return "file:///$path"
        }
    }
}

namespace eval ::tDOM { 
    variable extRefHandlerDebug 0
    variable useForeignDTD ""

    namespace export xmlOpenFile xmlReadFile xmlReadFileForSimple \
        extRefHandler baseURL
}

foreach cmd {
    xmlOpenFile
    xmlReadFile
    xmlReadFileForSimple
    extRefHandler
    baseURL
} {
    interp alias {} tDOM::$cmd {} tdom::$cmd
}

# EOF

Deleted mac/PrecompHeaders/CoreHeadersMach-O.c.

1
/*   =========================================================================== 	MacHeadersMach-O.c	ฉ 2000-2002 Metrowerks Corporation.  All rights reserved.   ===========================================================================  	Includes used to generate the 'MacHeadersMach-O' precompiled header for 	Metrowerks C/C++. */  #define _MSL_MACHEADERS_INCLUDES_CMATH 0  #if defined(__cplusplus) && _MSL_USING_MW_C_HEADERS && _MSL_MACHEADERS_INCLUDES_CMATH 	#include <cmath> #endif   // Apple Framework Headers  #ifndef __NOEXTENSIONS__ 	#define __NOEXTENSIONS__ #endif #ifndef __CF_USE_FRAMEWORK_INCLUDES__ 	#define __CF_USE_FRAMEWORK_INCLUDES__ #endif  #include <CoreServices/CoreServices.h>
<


Deleted mac/PrecompHeaders/CoreHeadersMach-O.h.

1
// CoreHeadersMach-O.h  #if __mwlinker__ 		#include <CoreHeadersMacOSX> #else 		#include <CoreHeadersMach-O> #endif
<


Deleted mac/PrecompHeaders/CoreHeadersMach-O.pch.

1
// CoreHeadersMach-O.pch   #pragma c99 on #define _MSL_USING_MW_C_HEADERS 1  #if __mwlinker__ 	#pragma precompile_target "CoreHeadersMacOSX" #else 	#pragma precompile_target "CoreHeadersMach-O" #endif   /* Now just include the "CoreHeadersMach-O.c" source file ... */  #pragma once on  #include "CoreHeadersMach-O.c"
<


Deleted mac/Prefix/expatPrefix.h.

1
#define MACOS_CLASSIC
<


Deleted mac/Prefix/expatPrefix_OSX.h.

1
#define MACOS_CLASSIC  #include "MSL MacHeadersMach-O.h"
<


Deleted mac/Prefix/tDOMPrefix.h.

1
#pragma once on  #include "tclMacCommonPch.h"  #define USE_TCL_STUBS 1  #define TDOM_NO_UNKNOWN_CMD  #define VERSION "0.8.3"  
<


Deleted mac/Prefix/tDOMPrefix_OSX.h.

1
#pragma once on  #include "CoreHeadersMach-O.h"   // These symbols are defined from MSL MacHeadersMach-O.h  // (errno.h and stat.h are in the Kernel.framework) // and are redefined later in TclErrno.h : undef them // to avoid error message #undef	EOVERFLOW #undef	EOPNOTSUPP  // This avoids the loading of stat.h from tclMacPort.h #define	_MSL_STAT_H   // --------------------------------------------------------------- // Replace #include "tclMacCommonPch.h" by its partial contents. #if !__option(enumsalwaysint) #error Tcl requires the Metrowerks setting "Enums always ints". #endif   // Tell Tcl (or any Tcl extensions) that we are compiling for the Macintosh platform. #define MAC_TCL  // ---------------------------------------------------------------  #define USE_TCL_STUBS 1  // See dom.h for this one: #define USE_NORMAL_ALLOCATOR  #define TCL_MEM_DEBUG  #define MAC_OSX_TCL  #define TDOM_NO_UNKNOWN_CMD  #define VERSION "0.8.3"  #include <Tcl/tcl.h>
<


Deleted mac/Prefix/tncPrefix.h.

1
#pragma once on  #include "tclMacCommonPch.h"  #define USE_TCL_STUBS 1  #define USE_TDOM_STUBS 1  #undef VERSION #define VERSION "0.3"   
<


Deleted mac/Prefix/tncPrefix_OSX.h.

1
#pragma once on  #define USE_TDOM_STUBS 1  #include "tDOMPrefix_OSX.h"  #undef VERSION #define VERSION "0.3" 
<


Deleted mac/Readme_Mac_Compiling.

1
Readme_Mac_Compiling ====================    This folder contains the CodeWarrior (CW Pro8) project files to compile the tDOM and tnc extensions. These files are in  XML  format  to  ensure  their portability. To recreate the projects,  you  must  launch  CodeWarrior  and choose the "Import Project..." command in the File menu:  - tDOM.prj.xml contains targets  to  build  tDOM  and  tnc  as  CFM  shared libraries (shlibs) for MacOS classic (system 8 or 9): 	ฅ Expat static lib 	ฅ tDOM stublib 	ฅ tDOM shlib 	ฅ Tnc shlib  - tDOM_OSX.prj.xml contains targets to build tDOM and tnc as Mach-O dynamic libraries (dylibs) for MacOSX: 	ฅ Precomp 	ฅ Expat Mach-O static 	ฅ tDOM stubs 	ฅ tDOM dylib 	ฅ Tnc dylib  To build these extensions, you need the TclStub.lib  stubs  library  coming with Tcl 8.4 for the classic project and the  Tcl.framework  framework  for the OSX project. You also need to have the Expat  sources  in  the  "expat" folder (http://expat.sourceforge.net/). There is a target in both  projects to build Expat as a static library.  The only thing to do, before starting the Make process, is  to  check  that the access paths are set correctly for your installation. All the paths are relative: if you have a standard installation, you should just have to  set the {TclTk} source tree to point to your Tcl/Tk  sources  folder.  This  is done in the "Source Trees Setting Panel": there is already a {TclTk} source tree defined there, just let it point to the right location. Note also that the OSX project file has a target  to  build  a  precompiled  header:  this precompiled header contains a minimal set of Mac headers to work  around  a problem due to a conflicting symbol name "Pattern" defined both in tDOM and in QuickDraw.h.  Both extensions should now build out of the box  provided  you  "make"  the targets in the order. The targets have been made interdependant anyway.  You can also find already compiled binaries on my web page: <http://webperso.easyconnect.fr/bdesgraupes/tcl.html>   Bernard Desgraupes <bdesgraupes@easyconnect.fr>  Last modification: 2003-02-28 06:51:51
<


Deleted mac/macconfig.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/* Copyright 2000, Clark Cooper
   All rights reserved.

   This is free software. You are permitted to copy, distribute, or modify
   it under the terms of the MIT/X license (contained in the COPYING file
   with this distribution.)
*/

/* Define to empty if the keyword does not work.  */
#undef const

/* Define if you have a working `mmap' system call.  */
#undef HAVE_MMAP

/* Define to `long' if <sys/types.h> doesn't define.  */
#undef off_t

/* Define to `unsigned' if <sys/types.h> doesn't define.  */
#undef size_t

/* Define if you have the ANSI C header files.  */
#define STDC_HEADERS 1

/* Define if your processor stores words with the most significant
   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
//#undef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN

/* Define if you have the bcopy function.  */
#undef HAVE_BCOPY

/* Define if you have the getpagesize function.  */
#undef HAVE_GETPAGESIZE

/* Define if you have the memmove function.  */
#define HAVE_MEMMOVE 1

/* Define if you have the <fcntl.h> header file.  */
// #undef HAVE_FCNTL_H
#define HAVE_FCNTL_H

/* Define if you have the <unistd.h> header file.  */
#define HAVE_UNISTD_H 1

#define XML_NS
#define XML_DTD

#ifdef WORDS_BIGENDIAN
#define XML_BYTE_ORDER 21
#else
#define XML_BYTE_ORDER 12
#endif

#define XML_CONTEXT_BYTES 1024

#ifndef HAVE_MEMMOVE
#ifdef HAVE_BCOPY
#define memmove(d,s,l) bcopy((s),(d),(l))
#else
#define memmove(d,s,l) ;punting on memmove;
#endif

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































Deleted mac/tDOM.exp.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Tdom_Init
Tdom_SafeInit
CHandlerSetCreate
CHandlerSetGet
CHandlerSetGetUserData
CHandlerSetInstall
CHandlerSetRemove
CheckExpatParserObj
GetExpatInfo
TclExpatObjCmd
XML_GetBase
XML_GetCurrentByteCount
XML_GetCurrentByteIndex
XML_GetCurrentColumnNumber
XML_GetCurrentLineNumber
XML_GetIdAttributeIndex
XML_GetSpecifiedAttributeCount
XML_SetBase
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































Deleted mac/tDOM.prj.xml.

cannot compute difference between binary files

Deleted mac/tDOM.r.

1
// Macintosh port of J. Loewer's tDOM lib for Tcl // Author: Bernard Desgraupes // e-mail: bdesgraupes@easyconnect.fr // web-page: http://webperso.easyconnect.fr/bdesgraupes/ // Last modification : 2003-02-16 19:36:06  #include <Types.r> #include <SysTypes.r>  #define TDOM_MAJOR 	0 #define TDOM_MINOR 	7 #define TDOM_SUBMINOR 6 #define TCL_MAJOR 		8 #define TCL_MINOR 		4  // developStage, alphaStage, betaStage, finalStage #define TDOM_STAGE 		betaStage  #if	(TDOM_STAGE == developStage) #		define	TDOM_STAGE_CODE	'd' #elif	(TDOM_STAGE == alphaStage) #		define	TDOM_STAGE_CODE	'a' #elif	(TDOM_STAGE == betaStage) #	 	define	TDOM_STAGE_CODE	'b' #elif	(TDOM_STAGE == finalStage) #	 	define	TDOM_STAGE_CODE	'f' #endif  #define	TDOM_MAJOR_BCD	((TDOM_MAJOR / 10) * 16) + (TDOM_MAJOR % 10) #define	TDOM_MINOR_BCD	(TDOM_MINOR * 16)  // #define	TDOM_VERSION_STRING	$$Format("%d.%d%c%d", TDOM_MAJOR, TDOM_MINOR, \ // 											TDOM_STAGE_CODE, TDOM_SUBMINOR)  #define	TDOM_VERSION_STRING	$$Format("%d.%d.%d", TDOM_MAJOR, TDOM_MINOR, TDOM_SUBMINOR)  resource 'vers' (1) { 	TDOM_MAJOR_BCD,  	TDOM_MINOR_BCD, 	TDOM_STAGE,  	0x00,  	verUS, 	TDOM_VERSION_STRING, 	$$Format("%s %s ฉ %d\nported to Mac by B. Desgraupes",  					"tDOM", TDOM_VERSION_STRING, $$YEAR) };   resource 'vers' (2) { 	TDOM_MAJOR_BCD,  	TDOM_MINOR_BCD, 	TDOM_STAGE,  	0x00,  	verUS, 	TDOM_VERSION_STRING, 	"Mac port of J. Loewer's tDOM lib" };   /*  * The -16397 string will be displayed by Finder when a user  * tries to open the shared library. The string should  * give the user a little detail about the library's capabilities  * and enough information to install the library in the correct location.    * A similar string should be placed in all shared libraries.  */ resource 'STR ' (-16397, purgeable) { 	"tDOM  Library\n\n" 	"This library provides an XML/DOM/XPath/XSLT implementation for Tcl." 	" It should be placed in the ิTool Command Languageี folder " 	"within the Extensions folder. To load it: " 	"'package require tdom'" };  data 'TEXT' (1000,"pkgIndex",purgeable, preload) { 		$$Format("# Tcl package index file, version 1.0\npackage ifneeded tdom %d.%d.%d \"load [list [file join $dir tDOM%d.%d[info sharedlibextension]]] Tdom\"\n", TDOM_MAJOR, TDOM_MINOR, TDOM_SUBMINOR, TCL_MAJOR, TCL_MINOR) }; 
<


Deleted mac/tDOM/pkgIndex.tcl.

1
2
3
4
5
6
7
if {[catch {package require Tcl 8.2}]} return

package ifneeded tdom 0.7.8 [list load [file join $dir tDOM.0.7.8.dylib] Tdom]


package ifneeded tnc 0.3.0 "package require tdom;
load [list [file join $dir tnc.0.3.0.dylib]] tnc"
<
<
<
<
<
<
<














Deleted mac/tDOM/tdom.tcl.

1
#---------------------------------------------------------------------------- #   Copyright (c) 1999 Jochen Loewer (loewerj@hotmail.com) #---------------------------------------------------------------------------- # #   $Header$ # # #   The higher level functions of tDOM written in plain Tcl. # # #   The contents of this file are subject to the Mozilla Public License #   Version 1.1 (the "License"); you may not use this file except in #   compliance with the License. You may obtain a copy of the License at #   http://www.mozilla.org/MPL/ # #   Software distributed under the License is distributed on an "AS IS" #   basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the #   License for the specific language governing rights and limitations #   under the License. # #   The Original Code is tDOM. # #   The Initial Developer of the Original Code is Jochen Loewer #   Portions created by Jochen Loewer are Copyright (C) 1998, 1999 #   Jochen Loewer. All Rights Reserved. # #   Contributor(s): #       Rolf Ade (rolf@pointsman.de):   'fake' nodelists/live childNodes # #   written by Jochen Loewer #   April, 1999 # #----------------------------------------------------------------------------  package require tdom   #---------------------------------------------------------------------------- #   setup namespaces for additional Tcl level methods, etc. # #---------------------------------------------------------------------------- namespace eval ::dom {     namespace eval  domDoc {     }     namespace eval  domNode {     }     namespace eval  DOMImplementation {     }     namespace eval  xpathFunc {     }     namespace eval  xpathFuncHelper {     } }  namespace eval ::tDOM {      variable extRefHandlerDebug 0     variable useForeignDTD "" }  #---------------------------------------------------------------------------- #   hasFeature (DOMImplementation method) # # #   @in  url    the URL, where to get the XML document # #   @return     document object #   @exception  XML parse errors, ... # #---------------------------------------------------------------------------- proc ::dom::DOMImplementation::hasFeature { dom feature {version ""} } {      switch $feature {         xml -         XML {             if {($version == "") || ($version == "1.0")} {                 return 1             }         }     }     return 0  }  #---------------------------------------------------------------------------- #   load (DOMImplementation method) # #       requests a XML document via http using the given URL and #       builds up a DOM tree in memory returning the document object # # #   @in  url    the URL, where to get the XML document # #   @return     document object #   @exception  XML parse errors, ... # #---------------------------------------------------------------------------- proc ::dom::DOMImplementation::load { dom url } {      error "Sorry, load method not implemented yet!"  }  #---------------------------------------------------------------------------- #   isa (docDoc method, for [incr tcl] compatibility) # # #   @in  className # #   @return         1 iff inherits from the given class # #---------------------------------------------------------------------------- proc ::dom::domDoc::isa { doc className } {      if {$className == "domDoc"} {         return 1     }     return 0 }  #---------------------------------------------------------------------------- #   info (domDoc method, for [incr tcl] compatibility) # # #   @in  subcommand #   @in  args # #---------------------------------------------------------------------------- proc ::dom::domDoc::info { doc subcommand args } {      switch $subcommand {         class {             return "domDoc"         }         inherit {             return ""         }         heritage {             return "domDoc {}"         }         default {             error "domDoc::info subcommand $subcommand not yet implemented!"         }     } }  #---------------------------------------------------------------------------- #   importNode (domDoc method) # #       Document Object Model (Core) Level 2 method # # #   @in  subcommand #   @in  args # #---------------------------------------------------------------------------- proc ::dom::domDoc::importNode { doc importedNode deep } {      if {$deep || ($deep == "-deep"} {         set node [$importedNode cloneNode -deep]     } else {         set node [$importedNode cloneNode]     }     return $node }  #---------------------------------------------------------------------------- #   isa (domNode method, for [incr tcl] compatibility) # # #   @in  className # #   @return         1 iff inherits from the given class # #---------------------------------------------------------------------------- proc ::dom::domNode::isa { doc className } {      if {$className == "domNode"} {         return 1     }     return 0 }  #---------------------------------------------------------------------------- #   info (domNode method, for [incr tcl] compatibility) # # #   @in  subcommand #   @in  args # #---------------------------------------------------------------------------- proc ::dom::domNode::info { doc subcommand args } {      switch $subcommand {         class {             return "domNode"         }         inherit {             return ""         }         heritage {             return "domNode {}"         }         default {             error "domNode::info subcommand $subcommand not yet implemented!"         }     } }  #---------------------------------------------------------------------------- #   isWithin (domNode method) # #       tests, whether a node object is nested below another tag # # #   @in  tagName  the nodeName of an elment node # #   @return       1 iff node is nested below a element with nodeName tagName #                 0 otherwise # #---------------------------------------------------------------------------- proc ::dom::domNode::isWithin { node tagName } {      while {[$node parentNode] != ""} {         set node [$node parentNode]         if {[$node nodeName] == $tagName} {             return 1         }     }     return 0 }  #---------------------------------------------------------------------------- #   tagName (domNode method) # #       same a nodeName for element interface # #---------------------------------------------------------------------------- proc ::dom::domNode::tagName { node } {      if {[$node nodeType] == "ELEMENT_NODE"} {         return [$node nodeName]     }     return -code error "NOT_SUPPORTED_ERR not an element!" }  #---------------------------------------------------------------------------- #   simpleTranslate (domNode method) # #       applies simple translation rules similar to Cost's simple #       translations to a node # # #   @in  output_var #   @in  trans_specs # #---------------------------------------------------------------------------- proc ::dom::domNode::simpleTranslate { node output_var trans_specs } {      upvar $output_var output      if {[$node nodeType] == "TEXT_NODE"} {         append output [cgiQuote [$node nodeValue]]         return     }     set found 0      foreach {match action} $trans_specs {          if {[catch {             if {!$found && ([$node selectNode self::$match] != "") } {               set found 1             }         } err]} {             if {![string match "NodeSet expected for parent axis!" $err]} {                 error $err             }         }         if {$found && ($action != "-")} {             set stop 0             foreach {type value} $action {                 switch $type {                     prefix { append output [subst $value] }                     tag    { append output <$value>       }                     start  { append output [eval $value]  }                     stop   { set stop 1                   }                 }             }             if {!$stop} {                 foreach child [$node childNodes] {                     simpleTranslate  $child output $trans_specs                 }             }             foreach {type value} $action {                 switch $type {                     suffix { append output [subst $value] }                     end    { append output [eval $value]  }                     tag    { append output </$value>      }                 }             }             return         }     }     foreach child [$node childNodes] {         simpleTranslate $child output $trans_specs     } }  #---------------------------------------------------------------------------- #   a DOM conformant 'live' childNodes # #   @return   a 'nodelist' object (it is just the normal node) # #---------------------------------------------------------------------------- proc ::dom::domNode::childNodesLive { node } {      return $node }  #---------------------------------------------------------------------------- #   item method on a 'nodelist' object # #   @return   a 'nodelist' object (it is just a normal # #---------------------------------------------------------------------------- proc ::dom::domNode::item { nodeListNode index } {      return [lindex [$nodeListNode childNodes] $index] }  #---------------------------------------------------------------------------- #   length method on a 'nodelist' object # #   @return   a 'nodelist' object (it is just a normal # #---------------------------------------------------------------------------- proc ::dom::domNode::length { nodeListNode } {      return [llength [$nodeListNode childNodes] $childNodes] }  #---------------------------------------------------------------------------- #   appendData on a 'CharacterData' object # #---------------------------------------------------------------------------- proc ::dom::domNode::appendData { node  arg } {      set type [$node nodeType]     if {($type != "TEXT_NODE") && ($type != "CDATA_SECTION_NODE") &&         ($type != "COMMENT_NODE")     } {         return -code error "NOT_SUPPORTED_ERR: node is not a cdata node"     }     set oldValue [$node nodeValue]     $node nodeValue [append oldValue $arg] }  #---------------------------------------------------------------------------- #   deleteData on a 'CharacterData' object # #---------------------------------------------------------------------------- proc ::dom::domNode::deleteData { node offset count } {      set type [$node nodeType]     if {($type != "TEXT_NODE") && ($type != "CDATA_SECTION_NODE") &&         ($type != "COMMENT_NODE")     } {         return -code error "NOT_SUPPORTED_ERR: node is not a cdata node"     }     incr offset -1     set before [string range [$node nodeValue] 0 $offset]     incr offset     incr offset $count     set after  [string range [$node nodeValue] $offset end]     $node nodeValue [append before $after] }  #---------------------------------------------------------------------------- #   insertData on a 'CharacterData' object # #---------------------------------------------------------------------------- proc ::dom::domNode::insertData { node  offset arg } {      set type [$node nodeType]     if {($type != "TEXT_NODE") && ($type != "CDATA_SECTION_NODE") &&         ($type != "COMMENT_NODE")     } {         return -code error "NOT_SUPPORTED_ERR: node is not a cdata node"     }     incr offset -1     set before [string range [$node nodeValue] 0 $offset]     incr offset     set after  [string range [$node nodeValue] $offset end]     $node nodeValue [append before $arg $after] }  #---------------------------------------------------------------------------- #   replaceData on a 'CharacterData' object # #---------------------------------------------------------------------------- proc ::dom::domNode::replaceData { node offset count arg } {      set type [$node nodeType]     if {($type != "TEXT_NODE") && ($type != "CDATA_SECTION_NODE") &&         ($type != "COMMENT_NODE")     } {         return -code error "NOT_SUPPORTED_ERR: node is not a cdata node"     }     incr offset -1     set before [string range [$node nodeValue] 0 $offset]     incr offset     incr offset $count     set after  [string range [$node nodeValue] $offset end]     $node nodeValue [append before $arg $after] }  #---------------------------------------------------------------------------- #   substringData on a 'CharacterData' object # #   @return   part of the node value (text) # #---------------------------------------------------------------------------- proc ::dom::domNode::substringData { node offset count } {      set type [$node nodeType]     if {($type != "TEXT_NODE") && ($type != "CDATA_SECTION_NODE") &&         ($type != "COMMENT_NODE")     } {         return -code error "NOT_SUPPORTED_ERR: node is not a cdata node"     }     set endOffset [expr $offset + $count - 1]     return [string range [$node nodeValue] $offset $endOffset] }  #---------------------------------------------------------------------------- #   coerce2number # #---------------------------------------------------------------------------- proc ::dom::xpathFuncHelper::coerce2number { type value } {     switch $type {         empty      { return 0 }         number -         string     { return $value }         attrvalues { return [lindex $value 0] }         nodes      { return [[lindex $value 0] selectNodes number()] }         attrnodes  { return [lindex $value 1] }     } }  #---------------------------------------------------------------------------- #   coerce2string # #---------------------------------------------------------------------------- proc ::dom::xpathFuncHelper::coerce2string { type value } {     switch $type {         empty      { return "" }         number -         string     { return $value }         attrvalues { return [lindex $value 0] }         nodes      { return [[lindex $value 0] selectNodes string()] }         attrnodes  { return [lindex $value 1] }     } }  #---------------------------------------------------------------------------- #   function-available # #---------------------------------------------------------------------------- proc ::dom::xpathFunc::function-available { ctxNode pos                                             nodeListType nodeList args} {      if {[llength $args] != 2} {         error "function-available(): wrong # of args!"     }     foreach { arg1Typ arg1Value } $args break     set str [::dom::xpathFuncHelper::coerce2string $arg1Typ $arg1Value ]     switch $str {         boolean -         ceiling -         concat -         contains -         count -         current -         document -         element-available -         false -         floor -         format-number -         generate-id -         id -         key -         last -         lang -         local-name -         name -         namespace-uri -         normalize-space -         not -         number -         position -         round -         starts-with -         string -         string-length -         substring -         substring-after -         substring-before -         sum -         translate -         true -         unparsed-entity-uri {             return [list bool true]         }         default {             set TclXpathFuncs [info procs ::dom::xpathFunc::*]             if {[lsearch -exact $TclXpathFuncs $str] != -1} {                 return [list bool true]             } else {                 return [list bool false]             }         }     } }  #---------------------------------------------------------------------------- #   element-available # #   This is not strictly correct. The XSLT namespace may be bound #   to another prefix (and the prefix 'xsl' may be bound to another #   namespace). Since the expression context isn't available at the #   moment at tcl coded XPath functions, this couldn't be done better #   than this "works in the 'normal' cases" version. #---------------------------------------------------------------------------- proc ::dom::xpathFunc::element-available { ctxNode pos                                             nodeListType nodeList args} {      if {[llength $args] != 2} {         error "element-available(): wrong # of args!"     }     foreach { arg1Typ arg1Value } $args break     set str [::dom::xpathFuncHelper::coerce2string $arg1Typ $arg1Value ]     switch $str {         xsl:stylesheet -         xsl:transform -         xsl:include -         xsl:import -         xsl:strip-space -         xsl:preserve-space -         xsl:template -         xsl:apply-templates -         xsl:apply-imports -         xsl:call-template -         xsl:element -         xsl:attribute -         xsl:attribute-set -         xsl:text -         xsl:processing-instruction -         xsl:comment -         xsl:copy -         xsl:value-of -         xsl:number -         xsl:for-each -         xsl:if -         xsl:choose -         xsl:when -         xsl:otherwise -         xsl:sort -         xsl:variable -         xsl:param -         xsl:copy-of -         xsl:with-param -         xsl:key -         xsl:message -         xsl:decimal-format -         xsl:namespace-alias -         xsl:fallback {             return [list bool true]         }         xsl:output -         default {             return [list bool false]         }     } }  #---------------------------------------------------------------------------- #   system-property # #   This is not strictly correct. The XSLT namespace may be bound #   to another prefix (and the prefix 'xsl' may be bound to another #   namespace). Since the expression context isn't available at the #   moment at tcl coded XPath functions, this couldn't be done better #   than this "works in the 'normal' cases" version. #---------------------------------------------------------------------------- proc ::dom::xpathFunc::system-property { ctxNode pos                                          nodeListType nodeList args } {      if {[llength $args] != 2} {         error "system-property(): wrong # of args!"     }     foreach { arg1Typ arg1Value } $args break     set str [::dom::xpathFuncHelper::coerce2string $arg1Typ $arg1Value ]     switch $str {         xsl:version {             return [list number 1.0]         }         xsl:vendor {             return [list string "Jochen Loewer (loewerj@hotmail.com), Rolf Ade (rolf@pointsman.de) et. al."]         }         xsl:vendor-url {             return [list string "http://www.tdom.org"]         }         default {             return [list string ""]         }     } }  #---------------------------------------------------------------------------- #   IANAEncoding2TclEncoding # #----------------------------------------------------------------------------  # As of version 8.3.4 tcl supports  # cp860 cp861 cp862 cp863 tis-620 cp864 cp865 cp866 gb12345 cp949 # cp950 cp869 dingbats ksc5601 macCentEuro cp874 macUkraine jis0201 # gb2312 euc-cn euc-jp iso8859-10 macThai jis0208 iso2022-jp # macIceland iso2022 iso8859-13 iso8859-14 jis0212 iso8859-15 cp737 # iso8859-16 big5 euc-kr macRomania macTurkish gb1988 iso2022-kr # macGreek ascii cp437 macRoman iso8859-1 iso8859-2 iso8859-3 ebcdic # macCroatian koi8-r iso8859-4 iso8859-5 cp1250 macCyrillic iso8859-6 # cp1251 koi8-u macDingbats iso8859-7 cp1252 iso8859-8 cp1253 # iso8859-9 cp1254 cp1255 cp850 cp1256 cp932 identity cp1257 cp852 # macJapan cp1258 shiftjis utf-8 cp855 cp936 symbol cp775 unicode # cp857 #  # Just add more mappings (and mail them to the tDOM mailing list, please).  proc tDOM::IANAEncoding2TclEncoding {IANAName} {          # First the most widespread encodings with there     # preferred MIME name, to speed lookup in this     # usual cases. Later the official names and the     # aliases.     #     # For "official names for character sets that may be     # used in the Internet" see      # http://www.iana.org/assignments/character-sets     # (that's the source for the encoding names below)     #      # Matching is case-insensitive      switch [string tolower $IANAName] {         "us-ascii"    {return ascii}         "utf-8"       {return utf-8}         "utf-16"      {return unicode; # not sure about this}         "iso-8859-1"  {return iso8859-1}         "iso-8859-2"  {return iso8859-2}         "iso-8859-3"  {return iso8859-3}         "iso-8859-4"  {return iso8859-4}         "iso-8859-5"  {return iso8859-5}         "iso-8859-6"  {return iso8859-6}         "iso-8859-7"  {return iso8859-7}         "iso-8859-8"  {return iso8859-8}         "iso-8859-9"  {return iso8859-9}         "iso-8859-10" {return iso8859-10}         "iso-8859-13" {return iso8859-13}         "iso-8859-14" {return iso8859-14}         "iso-8859-15" {return iso8859-15}         "iso-8859-16" {return iso8859-16}         "iso-2022-kr" {return iso2022-kr}         "euc-kr"      {return euc-kr}         "iso-2022-jp" {return iso2022-jp}         "koi8-r"      {return koi8-r}         "shift_jis"   {return shiftjis}         "euc-jp"      {return euc-jp}         "gb2312"      {return gb2312}         "big5"        {return big5}         "cp866"       {return cp866}          "windows-1251" -         "cp1251"      {return cp1251}                  "iso_8859-1:1987" -         "iso-ir-100" -         "iso_8859-1" -         "latin1" -         "l1" -         "ibm819" -         "cp819" -         "csisolatin1" {return iso8859-1}                  "iso_8859-2:1987" -         "iso-ir-101" -         "iso_8859-2" -         "iso-8859-2" -         "latin2" -         "l2" -         "csisolatin2" {return iso8859-2}          "iso_8859-5:1988" -         "iso-ir-144" -         "iso_8859-5" -         "iso-8859-5" -         "cyrillic" -         "csisolatincyrillic" {return iso8859-5}          "ms_kanji" -         "csshiftjis"  {return shiftjis}                  "csiso2022kr" {return iso2022-kr}          "ibm866" -         "csibm866"    {return cp866}                  default {             # There are much more encoding names out there             # It's only laziness, that let me stop here.             error "Unrecognized encoding name '$IANAName'"         }     } }  #---------------------------------------------------------------------------- #   xmlOpenFile # #---------------------------------------------------------------------------- proc tDOM::xmlOpenFile {filename {encodingString {}}} {      set fd [open $filename]      if {$encodingString != {}} {         upvar $encodingString encString     }      # The autodetection of the encoding follows     # XML Recomendation, Appendix F      fconfigure $fd -encoding binary     if {![binary scan [read $fd 4] "H8" firstBytes]} {         # very short (< 4 Bytes) file         seek $fd 0 start         set encString UTF-8         return $fd     }          # First check for BOM     switch [string range $firstBytes 0 3] {         "feff" -         "fffe" {             # feff: UTF-16, big-endian BOM             # ffef: UTF-16, little-endian BOM             seek $fd 0 start             set encString UTF-16                         fconfigure $fd -encoding identity             return $fd         }     }      # If the entity has a XML Declaration, the first four characters     # must be "<?xm".     switch $firstBytes {         "3c3f786d" {             # UTF-8, ISO 646, ASCII, some part of ISO 8859, Shift-JIS,             # EUC, or any other 7-bit, 8-bit, or mixed-width encoding which              # ensures that the characters of ASCII have their normal positions,             # width and values; the actual encoding declaration must be read to             # detect which of these applies, but since all of these encodings             # use the same bit patterns for the ASCII characters, the encoding             # declaration itself be read reliably.              # First 300 bytes should be enough for a XML Declaration             # This is of course not 100 percent bullet-proof.             set head [read $fd 296]              # Try to find the end of the XML Declaration             set closeIndex [string first ">" $head]             if {$closeIndex == -1} {                 error "Wired XML data or not XML data at all"             }              seek $fd 0 start             set xmlDeclaration [read $fd [expr {$closeIndex + 5}]]             # extract the encoding information             set pattern {encoding=[\x20\x9\xd\xa]*["']([^ "']+)['"]}             # emacs: "             if {![regexp $pattern $head - encStr]} {                 # Probably something like <?xml version="1.0"?>.                  # Without encoding declaration this must be UTF-8                 set encoding utf-8                 set encString UTF-8             } else {                 set encoding [IANAEncoding2TclEncoding $encStr]                 set encString $encStr             }         }         "0000003c" -         "0000003c" -         "3c000000" -         "00003c00" {             # UCS-4             error "UCS-4 not supported"         }         "003c003f" -         "3c003f00" {             # UTF-16, big-endian, no BOM             # UTF-16, little-endian, no BOM             seek $fd 0 start             set encoding identity             set encString UTF-16         }         "4c6fa794" {             # EBCDIC in some flavor             error "EBCDIC not supported"         }         default {             # UTF-8 without an encoding declaration             seek $fd 0 start             set encoding identity             set encString "UTF-8"         }     }     fconfigure $fd -encoding $encoding     return $fd }  #---------------------------------------------------------------------------- #   xmlReadFile # #---------------------------------------------------------------------------- proc tDOM::xmlReadFile {filename {encodingString {}}} {      if {$encodingString != {}} {         upvar $encodingString encString     }          set fd [xmlOpenFile $filename encString]     set data [read $fd [file size $filename]]     close $fd      return $data }  #---------------------------------------------------------------------------- #   extRefHandler #    #   A very simple external entity resolver, included for convenience. #   Depends on the tcllib package uri and resolves only file URLs.  # #----------------------------------------------------------------------------  if {![catch {package require uri}]} {     proc tDOM::extRefHandler {base systemId publicId} {         variable extRefHandlerDebug         variable useForeignDTD          if {$extRefHandlerDebug} {             puts stderr "tDOM::extRefHandler called with:"             puts stderr "\tbase:     '$base'"             puts stderr "\tsystemId: '$systemId'"             puts stderr "\tpublicId: '$publicId'"         }         if {$systemId == ""} {             if {$useForeignDTD != ""} {                 set systemId $useForeignDTD             } else {                 return -code error -errorinfo "::tDOM::useForeignDTD does\                         not point to the foreign DTD"             }         }         set absolutURI [uri::resolve $base $systemId]         array set uriData [uri::split $absolutURI]         switch $uriData(scheme) {             file {                 return [list string $absolutURI [xmlReadFile $uriData(path)]]             }             default {                 return -code error  -errorinfo "can only handle file URI's"             }         }     } }  #---------------------------------------------------------------------------- #   baseURL #    #   A simple convenience proc which returns an absolute URL for a given #   filename. # #----------------------------------------------------------------------------  proc tDOM::baseURL {path} {     switch [file pathtype $path] {         "relative" {             return "file://[pwd]/$path"         }         default {             return "file://$path"         }     } }  # EOF 
<


Deleted mac/tDOM_OSX.prj.xml.

cannot compute difference between binary files

Deleted mac/tnc.exp.

1
Tnc_Init
<


Deleted mac/tnc.r.

1
// Macintosh port of the tnc extension for tDOM for Tcl // Author: Bernard Desgraupes // e-mail: bdesgraupes@easyconnect.fr // web-page: http://webperso.easyconnect.fr/bdesgraupes/ // Last modification : 2003-02-19 08:53:51  #include <Types.r> #include <SysTypes.r>  #define TNC_MAJOR 		0 #define TNC_MINOR 		3 #define TNC_SUBMINOR	0 #define TCL_MAJOR 		8 #define TCL_MINOR 		4  // developStage, alphaStage, betaStage, finalStage #define TNC_STAGE 		betaStage  #if	(TNC_STAGE == developStage) #		define	TNC_STAGE_CODE	'd' #elif	(TNC_STAGE == alphaStage) #		define	TNC_STAGE_CODE	'a' #elif	(TNC_STAGE == betaStage) #	 	define	TNC_STAGE_CODE	'b' #elif	(TNC_STAGE == finalStage) #	 	define	TNC_STAGE_CODE	'f' #endif  #define	TNC_MAJOR_BCD	((TNC_MAJOR / 10) * 16) + (TNC_MAJOR % 10) #define	TNC_MINOR_BCD	(TNC_MINOR * 16)  // #define	TNC_VERSION_STRING	$$Format("%d.%d%c%d", TNC_MAJOR, TNC_MINOR, \ // 											TNC_STAGE_CODE, TNC_SUBMINOR)  #define	TNC_VERSION_STRING	$$Format("%d.%d.%d", TNC_MAJOR, TNC_MINOR, TNC_SUBMINOR)  resource 'vers' (1) { 	TNC_MAJOR_BCD,  	TNC_MINOR_BCD, 	TNC_STAGE,  	0x00,  	verUS, 	TNC_VERSION_STRING, 	$$Format("%s %s ฉ %d\nported to Mac by B. Desgraupes",  					"tnc", TNC_VERSION_STRING, $$YEAR) };   resource 'vers' (2) { 	TNC_MAJOR_BCD,  	TNC_MINOR_BCD, 	TNC_STAGE,  	0x00,  	verUS, 	TNC_VERSION_STRING, 	"Mac port of tnc extension for tDOM" };   /*  * The -16397 string will be displayed by Finder when a user  * tries to open the shared library. The string should  * give the user a little detail about the library's capabilities  * and enough information to install the library in the correct location.    * A similar string should be placed in all shared libraries.  */ resource 'STR ' (-16397, purgeable) { 	"tnc Library\n\n" 	"This library implements a set of tDOM C Handlers." 	" It should be placed in the ิTool Command Languageี folder " 	"within the Extensions folder. To load it: " 	"'package require tnc'" };  data 'TEXT' (1000,"pkgIndex",purgeable, preload) { 		$$Format("# Tcl package index file, version 1.0\npackage ifneeded tnc %d.%d.%d \"package require tdom;\nload [list [file join $dir tnc%d.%d[info sharedlibextension]]] tnc\"\n", TNC_MAJOR, TNC_MINOR, TNC_SUBMINOR, TCL_MAJOR, TCL_MINOR) }; 
<


Changes to macosx/README.

1
2
3
4
5
6

Please go to ../unix directory and inspect the CONFIG file.
There you will find example on how to configure and make
the library on Mac OSX using GNU configure/make tools.

-EOF



|


1
2
3
4
5
6

Please go to ../unix directory and inspect the CONFIG file.
There you will find example on how to configure and make
the library on macOS using GNU configure/make tools.

-EOF

Changes to tclconfig/README.txt.

1
2
3
4
5
6
7
8
9
10
11















The other files in this directory are the functional core of the Tcl
Extension Architecture (TEA). For more information on TEA see:

	http://www.tcl.tk/doc/tea/

The other files in this directory are out of the tclconfig directory
of:

http://cvs.sourceforge.net/viewcvs.py/tcl/sampleextension/

from 2007-07-26 (TEA 3.6).















|
|



|
|

|

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
These files comprise the basic building blocks for a Tcl Extension
Architecture (TEA) extension.  For more information on TEA see:

	http://www.tcl.tk/doc/tea/

This package is part of the Tcl project at SourceForge, and latest
sources should be available there:

	http://tcl.sourceforge.net/

This package is a freely available open source package.  You can do
virtually anything you like with it, such as modifying it, redistributing
it, and selling it either in whole or in part.

CONTENTS
========
The following is a short description of the files you will find in
the sample extension.

README.txt	This file

install-sh	Program used for copying binaries and script files
		to their install locations.

tcl.m4		Collection of Tcl autoconf macros.  Included by a package's
		aclocal.m4 to define TEA_* macros.

Changes to tclconfig/install-sh.

1

2

3
4
5



6
7






























8
9
10
11

12

13
14
15
16
17





18
19
20

21
22
23

24
25
26





27
28
29
30

















31
32
33
34

35
36


37
38


39
40


































41
42







43
44
45
46









47
48
49
50
51
52




53
54
55
56

57





58
59

60
61





62
63

64
65
66
67











































68
69

70
71
72








73



74




75
76
77
78












79
80
81
82
83

84
85
86
87





88
89
90




















91
92






























































93
94

















95








96
97




98
99



































































100

101
102


103
104


105
106
107
108
109
110
111



112





















113

114











115
116




117

118



119












#!/bin/sh



#
# install - install a program, script, or datafile
# This comes from X11R5; it is not part of GNU.



#
# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $






























#
# This script is compatible with the BSD install script, but was written
# from scratch.
#




# set DOITPROG to echo to test this script

# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"







# put in absolute paths if you don't have them in your path; or use env. vars.


mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"

chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"





stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"

instcmd="$mvprog"

















chmodcmd=""
chowncmd=""
chgrpcmd=""
stripcmd=""

rmcmd="$rmprog -f"
mvcmd="$mvprog"


src=""
dst=""



while [ x"$1" != x ]; do


































    case $1 in
	-c) instcmd="$cpprog"







	    shift
	    continue;;

	-m) chmodcmd="$chmodprog $2"









	    shift
	    shift
	    continue;;

	-o) chowncmd="$chownprog $2"
	    shift




	    shift
	    continue;;

	-g) chgrpcmd="$chgrpprog $2"

	    shift





	    shift
	    continue;;


	-s) stripcmd="$stripprog"





	    shift
	    continue;;


	*)  if [ x"$src" = x ]
	    then
		src=$1











































	    else
		dst=$1

	    fi
	    shift
	    continue;;








    esac



done





if [ x"$src" = x ]
then
	echo "install:  no input file specified"












	exit 1
fi

if [ x"$dst" = x ]
then

	echo "install:  no destination specified"
	exit 1
fi







# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic





















if [ -d $dst ]






























































then
	dst="$dst"/`basename $src`

















fi









# Make a temp file name in the proper directory.





dstdir=`dirname $dst`



































































dsttmp=$dstdir/#inst.$$#


# Move or copy the file name to the temp name



$doit $instcmd $src $dsttmp



# and set any options; do chmod last to preserve setuid bits

if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi

























# Now rename the file to the real destination.













$doit $rmcmd $dst
$doit $mvcmd $dsttmp $dst










exit 0













>

>
|
<
<
>
>
>

<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
>
|
>




|
>
>
>
>
>

<
|
>

<
<
>
|
|
<
>
>
>
>
>
|
<

<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
<
>

<
>
>
|
|
>
>

<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
|
<

<
>
>
>
>
>
>
>
>
>
|
<
<

|
|
>
>
>
>
|
<

<
>
|
>
>
>
>
>
|
<
>

<
>
>
>
>
>
|
<
>

<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
|
<
<
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>

<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
|
|

<
<
>
|
|
|

>
>
>
>
>

|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>

<
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>

<
>
>

<
>
>

|
|
<
<
<
<
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>

>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
|
>

>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5


6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60


61
62
63

64
65
66
67
68
69

70

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89


90
91

92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141

142

143
144
145
146
147
148
149
150
151
152


153
154
155
156
157
158
159
160

161

162
163
164
165
166
167
168
169

170
171

172
173
174
175
176
177

178
179



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

224
225


226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258


259
260
261
262
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

382
383
384
385
386

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456

457
458
459

460
461
462
463
464




465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
#!/bin/sh
# install - install a program, script, or datafile

scriptversion=2011-04-20.01; # UTC



# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#

# Copyright (C) 1994 X Consortium
#
# 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
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.

nl='
'
IFS=" ""	$nl"

# set DOITPROG to echo to test this script

# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
  doit_exec=exec
else
  doit_exec=$doit
fi


# Put in absolute file names if you don't have them in your path;
# or use environment vars.



chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}

cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}



posix_glob='?'
initialize_posix_glob='
  test "$posix_glob" != "?" || {
    if (set -f) 2>/dev/null; then
      posix_glob=
    else
      posix_glob=:
    fi
  }
'

posix_mkdir=

# Desired mode of installed file.
mode=0755

chgrpcmd=
chmodcmd=$chmodprog
chowncmd=


mvcmd=$mvprog
rmcmd="$rmprog -f"

stripcmd=

src=
dst=
dir_arg=
dst_arg=


copy_on_change=false
no_target_directory=

usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
   or: $0 [OPTION]... SRCFILES... DIRECTORY
   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
   or: $0 [OPTION]... -d DIRECTORIES...

In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.

Options:
     --help     display this help and exit.
     --version  display version info and exit.

  -c            (ignored)
  -C            install only if different (preserve the last data modification time)
  -d            create directories instead of installing files.
  -g GROUP      $chgrpprog installed files to GROUP.
  -m MODE       $chmodprog installed files to MODE.
  -o USER       $chownprog installed files to USER.
  -s            $stripprog installed files.
  -S            $stripprog installed files.
  -t DIRECTORY  install into DIRECTORY.
  -T            report an error if DSTFILE is a directory.

Environment variables override the default commands:
  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
  RMPROG STRIPPROG
"

while test $# -ne 0; do
  case $1 in

    -c) ;;

    -C) copy_on_change=true;;

    -d) dir_arg=true;;

    -g) chgrpcmd="$chgrpprog $2"
	shift;;



    --help) echo "$usage"; exit $?;;

    -m) mode=$2
	case $mode in
	  *' '* | *'	'* | *'
'*	  | *'*'* | *'?'* | *'['*)
	    echo "$0: invalid mode: $mode" >&2
	    exit 1;;
	esac
	shift;;



    -o) chowncmd="$chownprog $2"
	shift;;

    -s) stripcmd=$stripprog;;

    -S) stripcmd="$stripprog $2"
	shift;;



    -t) dst_arg=$2
	shift;;

    -T) no_target_directory=true;;

    --version) echo "$0 $scriptversion"; exit $?;;

    --)	shift

	break;;


    -*)	echo "$0: invalid option: $1" >&2
	exit 1;;

    *)  break;;
  esac
  shift

done




if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
  # When -d is used, all remaining arguments are directories to create.
  # When -t is used, the destination is already specified.
  # Otherwise, the last argument is the destination.  Remove it from $@.
  for arg
  do
    if test -n "$dst_arg"; then
      # $@ is not empty: it contains at least $arg.
      set fnord "$@" "$dst_arg"
      shift # fnord
    fi
    shift # arg
    dst_arg=$arg
  done
fi

if test $# -eq 0; then
  if test -z "$dir_arg"; then
    echo "$0: no input file specified." >&2
    exit 1
  fi
  # It's OK to call `install-sh -d' without argument.
  # This can happen when creating conditional directories.
  exit 0
fi

if test -z "$dir_arg"; then
  do_exit='(exit $ret); exit $ret'
  trap "ret=129; $do_exit" 1
  trap "ret=130; $do_exit" 2
  trap "ret=141; $do_exit" 13
  trap "ret=143; $do_exit" 15

  # Set umask so as not to create temps with too-generous modes.
  # However, 'strip' requires both read and write access to temps.
  case $mode in
    # Optimize common cases.
    *644) cp_umask=133;;
    *755) cp_umask=22;;

    *[0-7])
      if test -z "$stripcmd"; then
	u_plus_rw=
      else

	u_plus_rw='% 200'
      fi


      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
    *)
      if test -z "$stripcmd"; then
	u_plus_rw=
      else
	u_plus_rw=,u+rw
      fi
      cp_umask=$mode$u_plus_rw;;
  esac
fi

for src
do
  # Protect names starting with `-'.
  case $src in
    -*) src=./$src;;
  esac




  if test -n "$dir_arg"; then
    dst=$src
    dstdir=$dst
    test -d "$dstdir"
    dstdir_status=$?
  else

    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
    # might cause directories to be created, which would be especially bad
    # if $src (and thus $dsttmp) contains '*'.
    if test ! -f "$src" && test ! -d "$src"; then
      echo "$0: $src does not exist." >&2
      exit 1
    fi



    if test -z "$dst_arg"; then
      echo "$0: no destination specified." >&2
      exit 1
    fi

    dst=$dst_arg
    # Protect names starting with `-'.
    case $dst in
      -*) dst=./$dst;;
    esac

    # If destination is a directory, append the input filename; won't work

    # if double slashes aren't ignored.
    if test -d "$dst"; then
      if test -n "$no_target_directory"; then
	echo "$0: $dst_arg: Is a directory" >&2
	exit 1
      fi
      dstdir=$dst
      dst=$dstdir/`basename "$src"`
      dstdir_status=0
    else
      # Prefer dirname, but fall back on a substitute if dirname fails.
      dstdir=`
	(dirname "$dst") 2>/dev/null ||
	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
	     X"$dst" : 'X\(//\)[^/]' \| \
	     X"$dst" : 'X\(//\)$' \| \
	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
	echo X"$dst" |
	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
		   s//\1/
		   q

		 }
		 /^X\(\/\/\)[^/].*/{
		   s//\1/
		   q
		 }
		 /^X\(\/\/\)$/{
		   s//\1/
		   q
		 }
		 /^X\(\/\).*/{
		   s//\1/
		   q
		 }
		 s/.*/./; q'
      `

      test -d "$dstdir"
      dstdir_status=$?
    fi
  fi

  obsolete_mkdir_used=false

  if test $dstdir_status != 0; then
    case $posix_mkdir in
      '')
	# Create intermediate dirs using mode 755 as modified by the umask.
	# This is like FreeBSD 'install' as of 1997-10-28.
	umask=`umask`
	case $stripcmd.$umask in
	  # Optimize common cases.
	  *[2367][2367]) mkdir_umask=$umask;;
	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;

	  *[0-7])
	    mkdir_umask=`expr $umask + 22 \
	      - $umask % 100 % 40 + $umask % 20 \
	      - $umask % 10 % 4 + $umask % 2
	    `;;
	  *) mkdir_umask=$umask,go-w;;
	esac

	# With -d, create the new directory with the user-specified mode.
	# Otherwise, rely on $mkdir_umask.
	if test -n "$dir_arg"; then
	  mkdir_mode=-m$mode
	else
	  mkdir_mode=
	fi

	posix_mkdir=false
	case $umask in
	  *[123567][0-7][0-7])
	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
	    ;;
	  *)
	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0

	    if (umask $mkdir_umask &&
		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
	    then

	      if test -z "$dir_arg" || {
		   # Check for POSIX incompatibilities with -m.
		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
		   # other-writeable bit of parent directory when it shouldn't.
		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
		   case $ls_ld_tmpdir in
		     d????-?r-*) different_mode=700;;
		     d????-?--*) different_mode=755;;
		     *) false;;
		   esac &&
		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
		   }
		 }
	      then posix_mkdir=:
	      fi
	      rmdir "$tmpdir/d" "$tmpdir"
	    else
	      # Remove any dirs left behind by ancient mkdir implementations.
	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
	    fi
	    trap '' 0;;
	esac;;
    esac


    if
      $posix_mkdir && (
	umask $mkdir_umask &&
	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
      )

    then :
    else

      # The umask is ridiculous, or mkdir does not conform to POSIX,
      # or it failed possibly due to a race condition.  Create the
      # directory the slow way, step by step, checking for races as we go.

      case $dstdir in
	/*) prefix='/';;
	-*) prefix='./';;
	*)  prefix='';;
      esac

      eval "$initialize_posix_glob"

      oIFS=$IFS
      IFS=/
      $posix_glob set -f
      set fnord $dstdir
      shift
      $posix_glob set +f
      IFS=$oIFS

      prefixes=

      for d
      do
	test -z "$d" && continue

	prefix=$prefix$d
	if test -d "$prefix"; then
	  prefixes=
	else
	  if $posix_mkdir; then
	    (umask=$mkdir_umask &&
	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
	    # Don't fail if two instances are running concurrently.
	    test -d "$prefix" || exit 1
	  else
	    case $prefix in
	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
	      *) qprefix=$prefix;;
	    esac
	    prefixes="$prefixes '$qprefix'"
	  fi
	fi
	prefix=$prefix/
      done

      if test -n "$prefixes"; then
	# Don't fail if two instances are running concurrently.
	(umask $mkdir_umask &&
	 eval "\$doit_exec \$mkdirprog $prefixes") ||
	  test -d "$dstdir" || exit 1
	obsolete_mkdir_used=true
      fi
    fi
  fi

  if test -n "$dir_arg"; then
    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
  else

    # Make a couple of temp file names in the proper directory.
    dsttmp=$dstdir/_inst.$$_
    rmtmp=$dstdir/_rm.$$_


    # Trap to clean up those temp files at exit.
    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0


    # Copy the file name to the temp name.
    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&

    # and set any options; do chmod last to preserve setuid bits.
    #




    # If any of these fail, we abort the whole thing.  If we want to
    # ignore errors from any of these, just make sure not to ignore
    # errors from the above "$doit $cpprog $src $dsttmp" command.
    #
    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&

    # If -C, don't bother to copy if it wouldn't change the file.
    if $copy_on_change &&
       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&

       eval "$initialize_posix_glob" &&
       $posix_glob set -f &&
       set X $old && old=:$2:$4:$5:$6 &&
       set X $new && new=:$2:$4:$5:$6 &&
       $posix_glob set +f &&

       test "$old" = "$new" &&
       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
    then
      rm -f "$dsttmp"
    else
      # Rename the file to the real destination.
      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||

      # The rename failed, perhaps because mv can't rename something else
      # to itself, or perhaps because mv is so ancient that it does not
      # support -f.
      {
	# Now remove or move aside any old file at destination location.
	# We try this two ways since rm can't unlink itself on some
	# systems and the destination file might be busy for other
	# reasons.  In this case, the final cleanup might fail but the new
	# file should still install successfully.
	{
	  test ! -f "$dst" ||
	  $doit $rmcmd -f "$dst" 2>/dev/null ||
	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
	  } ||
	  { echo "$0: cannot unlink or rename $dst" >&2
	    (exit 1); exit 1
	  }
	} &&

	# Now rename the file to the real destination.
	$doit $mvcmd "$dsttmp" "$dst"
      }
    fi || exit 1

    trap '' 0
  fi
done

# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

Changes to tclconfig/tcl.m4.

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
..
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
..
88
89
90
91
92
93
94





95
96
97
98
99
100
101
102
103
104
105
106
107



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151





152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
...
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
...
231
232
233
234
235
236
237





238
239
240
241
242
243
244
245
246
247
248
249
250



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265

266







267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294





295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
...
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395
396
397
398




























399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
...
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
...
495
496
497
498
499
500
501

502
503
504
505
506




















































































































507
508
509
510
511
512
513
514
515
516
517

518
519
520
521
522
523
524





525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540













541
542
543

544
545
546
547




548









549

550
551
552
553
554
555
556
...
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
...
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
...
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733

734
735
736
737
738
739
740

741
742
743
744
745
746
747
...
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
...
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817

818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
...
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
...
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
...
933
934
935
936
937
938
939
940
941
942
943


944
945
























946
947
948
949


950

951
952

953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973

974
975
976
977
978
979

980
981
982
983
984
985
986
987
988


989
990
991
992
993
994

995
996
997
998

999

1000
1001
1002
1003
1004
1005
1006
....
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
....
1091
1092
1093
1094
1095
1096
1097








1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
....
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154






























1155
1156
1157
1158
1159
1160
1161
1162


1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191

1192
1193
1194
1195

1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208

1209
1210
1211
1212
1213
1214
1215
1216


1217
1218
1219
1220
1221
1222
1223
1224
1225

1226
1227

1228
1229

1230
1231
1232


1233
1234


1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265

1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312







1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350

1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363

1364
1365
1366
1367
1368

1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401

1402
1403
1404
1405
1406
1407

1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426

1427
1428
1429
1430
1431
1432
1433
1434
1435

1436
1437
1438
1439
1440
1441


1442
1443
1444
1445
1446
1447

1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458

1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474


1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511

1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565


1566
1567

1568
1569

1570
1571
1572
1573
1574
1575

1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587





1588
1589
1590

1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603

1604
1605
1606
1607
1608
1609
1610
1611

















1612
1613
1614


1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
....
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678




1679
1680
1681
1682
1683
1684
1685
1686
1687

1688
1689
1690

1691
1692
1693
1694






1695
1696
1697
1698
1699
1700
1701

1702































1703


1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752

1753
1754
1755

1756
1757
1758

1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773

1774
1775
1776
1777
1778


1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800

1801
1802
1803

1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864

1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887

1888
1889
1890
1891
1892
1893


1894
1895
1896
1897
1898

1899
1900
1901

1902
1903
1904

1905
1906






1907
1908


1909





1910
1911
1912
1913


1914
1915
1916

1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929

1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940












1941

1942
1943
1944

1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962

1963
1964
1965
1966
1967
1968
1969
1970

1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002

2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015

2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032





2033

2034
2035
2036

2037



























2038
2039

2040
































































2041
2042
2043
2044
2045
2046
2047
....
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
....
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
....
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
....
2355
2356
2357
2358
2359
2360
2361

2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
....
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
....
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
....
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
....
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799





2800

2801
2802

2803
2804
2805
2806




2807
2808







2809
2810


2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821


2822
2823
2824
2825
2826
2827
2828
....
2833
2834
2835
2836
2837
2838
2839



2840
2841
2842
2843
2844
2845
2846
....
2863
2864
2865
2866
2867
2868
2869


2870
2871

2872
2873
2874
2875
2876
2877
2878
....
2908
2909
2910
2911
2912
2913
2914

2915
2916
2917
2918
2919
2920
2921
....
3046
3047
3048
3049
3050
3051
3052
















3053
3054
3055
3056
3057
3058
3059
....
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
....
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
....
3201
3202
3203
3204
3205
3206
3207


3208
3209
3210
3211
3212
3213











3214
3215
3216
3217
3218
3219
3220
3221
....
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240




3241
3242
3243


3244

3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
....
3274
3275
3276
3277
3278
3279
3280


3281
3282
3283
3284
3285
3286
3287
....
3321
3322
3323
3324
3325
3326
3327


3328
3329
3330
3331
3332
3333
3334
....
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379


3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390











3391
3392
3393
3394
3395


3396
3397
3398
3399
3400
3401
3402
3403

3404
3405

3406

3407
3408

3409
3410
3411
3412

3413

3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425

3426
3427
3428
3429
3430
3431
3432
....
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
....
3456
3457
3458
3459
3460
3461
3462

3463
3464
3465
3466
3467
3468
3469
....
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537


3538
3539
3540
3541
3542

3543









3544
3545
3546
3547
3548
3549
3550


3551
3552
3553




3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565

3566
3567



3568
3569

3570
3571
3572
3573

3574

3575
3576
3577
3578
3579
3580
3581
3582
3583
3584

3585
3586
3587
3588
3589
3590
3591
....
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
....
3615
3616
3617
3618
3619
3620
3621

3622
3623
3624
3625
3626
3627
3628
....
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650




3651
3652
3653
3654
3655
3656
3657
....
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
....
3875
3876
3877
3878
3879
3880
3881

3882

3883
3884
3885
3886
3887
3888
3889
....
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
....
3940
3941
3942
3943
3944
3945
3946


3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958









3959













































































3960
3961
3962
3963
3964
3965
3966
....
4021
4022
4023
4024
4025
4026
4027


4028















































































































































4029
4030
4031
#	a Tcl extension.
#
# Copyright (c) 1999-2000 Ajuba Solutions.
# Copyright (c) 2002-2005 ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id$

AC_PREREQ(2.57)

dnl TEA extensions pass us the version of TEA they think they
dnl are compatible with (must be set in TEA_INIT below)
dnl TEA_VERSION="3.6"

# Possible values for key variables defined:
#
# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
# TEA_PLATFORM        - windows unix

#

#------------------------------------------------------------------------
# TEA_PATH_TCLCONFIG --
#
#	Locate the tclConfig.sh file and perform a sanity check on
#	the Tcl compile flags
................................................................................
#
#	Defines the following vars:
#		TCL_BIN_DIR	Full path to the directory containing
#				the tclConfig.sh file
#------------------------------------------------------------------------

AC_DEFUN([TEA_PATH_TCLCONFIG], [
    dnl Make sure we are initialized
    AC_REQUIRE([TEA_INIT])
    #
    # Ok, lets find the tcl configuration
    # First, look for one uninstalled.
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true
	AC_ARG_WITH(tcl,
	    AC_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    with_tclconfig=${withval})
	AC_MSG_CHECKING([for Tcl configuration])
	AC_CACHE_VAL(ac_cv_c_tclconfig,[

	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case ${with_tclconfig} in
		    */tclConfig.sh )
			if test -f ${with_tclconfig}; then
			    AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
			    with_tclconfig=`echo ${with_tclconfig} | sed 's!/tclConfig\.sh$!!'`
			fi ;;
		esac
		if test -f "${with_tclconfig}/tclConfig.sh" ; then
		    ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
		else
		    AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
		fi
	    fi

	    # then check for a private Tcl installation
	    if test x"${ac_cv_c_tclconfig}" = x ; then
................................................................................
			`ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
			../../../tcl \
			`ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do





		    if test -f "$i/unix/tclConfig.sh" ; then
			ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
			break
		    fi
		done
	    fi

	    # on Darwin, check in Framework installation locations
	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
			`ls -d /Library/Frameworks 2>/dev/null` \
			`ls -d /Network/Library/Frameworks 2>/dev/null` \
			`ls -d /System/Library/Frameworks 2>/dev/null` \



			; do
		    if test -f "$i/Tcl.framework/tclConfig.sh" ; then
			ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)`
			break
		    fi
		done
	    fi

	    # on Windows, check in common installation locations
	    if test "${TEA_PLATFORM}" = "windows" \
		-a x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig=`(cd $i; pwd)`
			break
		    fi
		done
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \

			`ls -d /usr/lib 2>/dev/null` \







			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig=`(cd $i; pwd)`
			break
		    fi
		done
	    fi

	    # check in a few other private locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in \
			${srcdir}/../tcl \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do





		    if test -f "$i/unix/tclConfig.sh" ; then
		    ac_cv_c_tclconfig=`(cd $i/unix; pwd)`
		    break
		fi
		done
	    fi
	])

	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    AC_MSG_WARN([Can't find Tcl configuration definitions])
	    exit 0
	else
	    no_tcl=
	    TCL_BIN_DIR=${ac_cv_c_tclconfig}
	    AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
	fi
    fi
])

#------------------------------------------------------------------------
# TEA_PATH_TKCONFIG --
................................................................................

    if test x"${no_tk}" = x ; then
	# we reset no_tk in case something fails here
	no_tk=true
	AC_ARG_WITH(tk,
	    AC_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    with_tkconfig=${withval})
	AC_MSG_CHECKING([for Tk configuration])
	AC_CACHE_VAL(ac_cv_c_tkconfig,[

	    # First check to see if --with-tkconfig was specified.
	    if test x"${with_tkconfig}" != x ; then
		case ${with_tkconfig} in
		    */tkConfig.sh )
			if test -f ${with_tkconfig}; then
			    AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
			    with_tkconfig=`echo ${with_tkconfig} | sed 's!/tkConfig\.sh$!!'`
			fi ;;
		esac
		if test -f "${with_tkconfig}/tkConfig.sh" ; then
		    ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)`
		else
		    AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
		fi
	    fi

	    # then check for a private Tk library
	    if test x"${ac_cv_c_tkconfig}" = x ; then
................................................................................
			`ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
			../../../tk \
			`ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do





		    if test -f "$i/unix/tkConfig.sh" ; then
			ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
			break
		    fi
		done
	    fi

	    # on Darwin, check in Framework installation locations
	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
			`ls -d /Library/Frameworks 2>/dev/null` \
			`ls -d /Network/Library/Frameworks 2>/dev/null` \
			`ls -d /System/Library/Frameworks 2>/dev/null` \



			; do
		    if test -f "$i/Tk.framework/tkConfig.sh" ; then
			ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)`
			break
		    fi
		done
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \

			`ls -d /usr/lib 2>/dev/null` \







			; do
		    if test -f "$i/tkConfig.sh" ; then
			ac_cv_c_tkconfig=`(cd $i; pwd)`
			break
		    fi
		done
	    fi

	    # on Windows, check in common installation locations
	    if test "${TEA_PLATFORM}" = "windows" \
		-a x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
			; do
		    if test -f "$i/tkConfig.sh" ; then
			ac_cv_c_tkconfig=`(cd $i; pwd)`
			break
		    fi
		done
	    fi

	    # check in a few other private locations
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in \
			${srcdir}/../tk \
			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do





		    if test -f "$i/unix/tkConfig.sh" ; then
			ac_cv_c_tkconfig=`(cd $i/unix; pwd)`
			break
		    fi
		done
	    fi
	])

	if test x"${ac_cv_c_tkconfig}" = x ; then
	    TK_BIN_DIR="# no Tk configs found"
	    AC_MSG_WARN([Can't find Tk configuration definitions])
	    exit 0
	else
	    no_tk=
	    TK_BIN_DIR=${ac_cv_c_tkconfig}
	    AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
	fi
    fi
])

#------------------------------------------------------------------------
# TEA_LOAD_TCLCONFIG --
#
#	Load the tclConfig.sh file
#
# Arguments:
#	
#	Requires the following vars to be set:
#		TCL_BIN_DIR
#
# Results:
#
#	Subst the following vars:
#		TCL_BIN_DIR
#		TCL_SRC_DIR
#		TCL_LIB_FILE
#

#------------------------------------------------------------------------

AC_DEFUN([TEA_LOAD_TCLCONFIG], [
    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
        AC_MSG_RESULT([loading])
................................................................................
    # If the TCL_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TCL_LIB_SPEC will be set to the value
    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.
    if test -f "${TCL_BIN_DIR}/Makefile" ; then
        TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC}
        TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC}
        TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH}
    elif test "`uname -s`" = "Darwin"; then
	# If Tcl was built as a framework, attempt to use the libraries
	# from the framework at the given location so that linking works
	# against Tcl.framework installed in an arbitary location.
	case ${TCL_DEFS} in
	    *TCL_FRAMEWORK*)
		if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
		    for i in "`cd ${TCL_BIN_DIR}; pwd`" \
			     "`cd ${TCL_BIN_DIR}/../..; pwd`"; do
			if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
			    TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}"
			    break
			fi
		    done
		fi
		if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
		    TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}"
		    TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
		fi
		;;
	esac
    fi

    # eval is required to do the TCL_DBGX substitution
    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""

    AC_SUBST(TCL_VERSION)

    AC_SUBST(TCL_BIN_DIR)
    AC_SUBST(TCL_SRC_DIR)

    AC_SUBST(TCL_LIB_FILE)
    AC_SUBST(TCL_LIB_FLAG)
    AC_SUBST(TCL_LIB_SPEC)

    AC_SUBST(TCL_STUB_LIB_FILE)
    AC_SUBST(TCL_STUB_LIB_FLAG)
    AC_SUBST(TCL_STUB_LIB_SPEC)





























    AC_SUBST(TCL_LIBS)
    AC_SUBST(TCL_DEFS)
    AC_SUBST(TCL_EXTRA_CFLAGS)
    AC_SUBST(TCL_LD_FLAGS)
    AC_SUBST(TCL_SHLIB_LD_LIBS)
])

#------------------------------------------------------------------------
# TEA_LOAD_TKCONFIG --
#
#	Load the tkConfig.sh file
#
# Arguments:
#	
#	Requires the following vars to be set:
#		TK_BIN_DIR
#
# Results:
#
#	Sets the following vars that should be in tkConfig.sh:
#		TK_BIN_DIR
................................................................................
    # If the TK_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TK_LIB_SPEC will be set to the value
    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
    # instead of TK_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.
    if test -f "${TK_BIN_DIR}/Makefile" ; then
        TK_LIB_SPEC=${TK_BUILD_LIB_SPEC}
        TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC}
        TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH}
    elif test "`uname -s`" = "Darwin"; then
	# If Tk was built as a framework, attempt to use the libraries
	# from the framework at the given location so that linking works
	# against Tk.framework installed in an arbitary location.
	case ${TK_DEFS} in
	    *TK_FRAMEWORK*)
		if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
		    for i in "`cd ${TK_BIN_DIR}; pwd`" \
			     "`cd ${TK_BIN_DIR}/../..; pwd`"; do
			if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
			    TK_LIB_SPEC="-F`dirname "$i"` -framework ${TK_LIB_FILE}"
			    break
			fi
		    done
		fi
		if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
		    TK_STUB_LIB_SPEC="-L${TK_BIN_DIR} ${TK_STUB_LIB_FLAG}"
		    TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
		fi
		;;
	esac
    fi

    # eval is required to do the TK_DBGX substitution
    eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
    eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
    eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
    eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""

    # Ensure windowingsystem is defined
    if test "${TEA_PLATFORM}" = "unix" ; then
	case ${TK_DEFS} in
	    *MAC_OSX_TK*)
		AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
		TEA_WINDOWINGSYSTEM="aqua"
		;;
	    *)
................................................................................
    AC_SUBST(TK_LIB_FLAG)
    AC_SUBST(TK_LIB_SPEC)

    AC_SUBST(TK_STUB_LIB_FILE)
    AC_SUBST(TK_STUB_LIB_FLAG)
    AC_SUBST(TK_STUB_LIB_SPEC)


    AC_SUBST(TK_LIBS)
    AC_SUBST(TK_XINCLUDES)
])

#------------------------------------------------------------------------




















































































































# TEA_ENABLE_SHARED --
#
#	Allows the building of shared libraries
#
# Arguments:
#	none
#	
# Results:
#
#	Adds the following arguments to configure:
#		--enable-shared=yes|no

#
#	Defines the following vars:
#		STATIC_BUILD	Used for building import/export libraries
#				on Windows.
#
#	Sets the following vars:
#		SHARED_BUILD	Value of 1 or 0





#------------------------------------------------------------------------

AC_DEFUN([TEA_ENABLE_SHARED], [
    AC_MSG_CHECKING([how to build libraries])
    AC_ARG_ENABLE(shared,
	AC_HELP_STRING([--enable-shared],
	    [build and link with shared libraries (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])

    if test "${enable_shared+set}" = set; then
	enableval="$enable_shared"
	tcl_ok=$enableval
    else
	tcl_ok=yes
    fi














    if test "$tcl_ok" = "yes" ; then
	AC_MSG_RESULT([shared])
	SHARED_BUILD=1

    else
	AC_MSG_RESULT([static])
	SHARED_BUILD=0
	AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?])




    fi









    AC_SUBST(SHARED_BUILD)

])

#------------------------------------------------------------------------
# TEA_ENABLE_THREADS --
#
#	Specify if thread support should be enabled.  If "yes" is specified
#	as an arg (optional), threads are enabled by default, "no" means
................................................................................
#
#	Note that it is legal to have a thread enabled extension run in a
#	threaded or non-threaded Tcl core, but a non-threaded extension may
#	only run in a non-threaded Tcl core.
#
# Arguments:
#	none
#	
# Results:
#
#	Adds the following arguments to configure:
#		--enable-threads
#
#	Sets the following vars:
#		THREADS_LIBS	Thread library(s)
#
#	Defines the following vars:
#		TCL_THREADS
#		_REENTRANT
#		_THREAD_SAFE
#
#------------------------------------------------------------------------

AC_DEFUN([TEA_ENABLE_THREADS], [
    AC_ARG_ENABLE(threads,
	AC_HELP_STRING([--enable-threads],
	    [build with threads]),
	[tcl_ok=$enableval], [tcl_ok=yes])

    if test "${enable_threads+set}" = set; then
	enableval="$enable_threads"
	tcl_ok=$enableval
    else
	tcl_ok=yes
................................................................................
    fi

    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
	TCL_THREADS=1

	if test "${TEA_PLATFORM}" != "windows" ; then
	    # We are always OK on Windows, so check what this platform wants:
    
	    # USE_THREAD_ALLOC tells us to try the special thread-based
	    # allocator that significantly reduces lock contention
	    AC_DEFINE(USE_THREAD_ALLOC, 1,
		[Do we want to use the threaded memory allocator?])
	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
	    if test "`uname -s`" = "SunOS" ; then
		AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
................................................................................
# TEA_ENABLE_SYMBOLS --
#
#	Specify if debugging symbols should be used.
#	Memory (TCL_MEM_DEBUG) debugging can also be enabled.
#
# Arguments:
#	none
#	
#	TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
#	the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
#	Requires the following vars to be set in the Makefile:
#		CFLAGS_DEFAULT
#		LDFLAGS_DEFAULT
#	
# Results:
#
#	Adds the following arguments to configure:
#		--enable-symbols
#
#	Defines the following vars:
#		CFLAGS_DEFAULT	Sets to $(CFLAGS_DEBUG) if true
#				Sets to $(CFLAGS_OPTIMIZE) if false
#		LDFLAGS_DEFAULT	Sets to $(LDFLAGS_DEBUG) if true
#				Sets to $(LDFLAGS_OPTIMIZE) if false
#		DBGX		Formerly used as debug library extension;
#				always blank now.
#
#------------------------------------------------------------------------

AC_DEFUN([TEA_ENABLE_SYMBOLS], [
    dnl Make sure we are initialized
    AC_REQUIRE([TEA_CONFIG_CFLAGS])
    AC_MSG_CHECKING([for build with symbols])
    AC_ARG_ENABLE(symbols,
	AC_HELP_STRING([--enable-symbols],
	    [build with debugging symbols (default: off)]),
	[tcl_ok=$enableval], [tcl_ok=no])
    DBGX=""
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}"
	LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
	AC_MSG_RESULT([no])
    else
	CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
	LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
	if test "$tcl_ok" = "yes"; then
	    AC_MSG_RESULT([yes (standard debugging)])
	fi
    fi

    if test "${TEA_PLATFORM}" != "windows" ; then
	LDFLAGS_DEFAULT="${LDFLAGS}"
    fi

    AC_SUBST(TCL_DBGX)
    AC_SUBST(CFLAGS_DEFAULT)
    AC_SUBST(LDFLAGS_DEFAULT)


    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
	AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
    fi

    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
	if test "$tcl_ok" = "all"; then
................................................................................
# TEA_ENABLE_LANGINFO --
#
#	Allows use of modern nl_langinfo check for better l10n.
#	This is only relevant for Unix.
#
# Arguments:
#	none
#	
# Results:
#
#	Adds the following arguments to configure:
#		--enable-langinfo=yes|no (default is yes)
#
#	Defines the following vars:
#		HAVE_LANGINFO	Triggers use of nl_langinfo if defined.
#
#------------------------------------------------------------------------

AC_DEFUN([TEA_ENABLE_LANGINFO], [
    AC_ARG_ENABLE(langinfo,
	AC_HELP_STRING([--enable-langinfo],
	    [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
	[langinfo_ok=$enableval], [langinfo_ok=yes])
................................................................................
	AC_CACHE_VAL(tcl_cv_langinfo_h, [
	    AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
		    [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
	AC_MSG_RESULT([$tcl_cv_langinfo_h])
	if test $tcl_cv_langinfo_h = yes; then
	    AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
	fi
    else 
	AC_MSG_RESULT([$langinfo_ok])
    fi
])

#--------------------------------------------------------------------
# TEA_CONFIG_SYSTEM
#
#	Determine what the system is (some things cannot be easily checked
#	on a feature-driven basis, alas). This can usually be done via the
#	"uname" command, but there are a few systems, like Next, where
#	this doesn't work.
#
# Arguments:
#	none
#
# Results:
#	Defines the following var:
#
#	system -	System/platform/version identification code.
#
#--------------------------------------------------------------------

AC_DEFUN([TEA_CONFIG_SYSTEM], [
    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [

	if test "${TEA_PLATFORM}" = "windows" ; then
	    tcl_cv_sys_version=windows
	elif test -f /usr/lib/NextStep/software_version; then
	    tcl_cv_sys_version=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
	else
	    tcl_cv_sys_version=`uname -s`-`uname -r`
	    if test "$?" -ne 0 ; then
		AC_MSG_WARN([can't find uname command])
		tcl_cv_sys_version=unknown
	    else
		# Special check for weird MP-RAS system (uname returns weird
		# results, and the version is kept in special file).

		if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then
		    tcl_cv_sys_version=MP-RAS-`awk '{print $[3]}' /etc/.relid`
		fi
		if test "`uname -s`" = "AIX" ; then
		    tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
		fi
	    fi
	fi
    ])
    system=$tcl_cv_sys_version
................................................................................
# Arguments:
#	none
#
# Results:
#
#	Defines and substitutes the following vars:
#
#       DL_OBJS -       Name of the object file that implements dynamic
#                       loading for Tcl on this system.
#       DL_LIBS -       Library file(s) to include in tclsh and other base
#                       applications in order for the "load" command to work.
#       LDFLAGS -      Flags to pass to the compiler when linking object
#                       files into an executable application binary such
#                       as tclsh.
#       LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
#                       that tell the run-time dynamic linker where to look
#                       for shared libraries such as libtcl.so.  Depends on
#                       the variable LIB_RUNTIME_DIR in the Makefile. Could
................................................................................
#                       of a shared library (may request position-independent
#                       code, among other things).
#       SHLIB_LD -      Base command to use for combining object files
#                       into a shared library.
#       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
#                       creating shared libraries.  This symbol typically
#                       goes at the end of the "ld" commands that build
#                       shared libraries. The value of the symbol is
#                       "${LIBS}" if all of the dependent libraries should
#                       be specified when creating a shared library.  If
#                       dependent libraries should not be specified (as on
#                       SunOS 4.x, where they cause the link to fail, or in
#                       general if Tcl and Tk aren't themselves shared
#                       libraries), then this symbol has an empty string
#                       as its value.
#       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
#                       extensions.  An empty string means we don't know how
#                       to use shared libraries on this platform.
#       LIB_SUFFIX -    Specifies everything that comes after the "libfoo"
#                       in a static or shared library name, using the $VERSION variable
#                       to put the version in the right place.  This is used
#                       by platforms that need non-standard library names.
#                       Examples:  ${VERSION}.so.1.1 on NetBSD, since it needs
#                       to have a version after the .so, and ${VERSION}.a
#                       on AIX, since a shared library needs to have
#                       a .a extension whereas shared objects for loadable
#                       extensions have a .so extension.  Defaults to
#                       ${VERSION}${SHLIB_SUFFIX}.
#       TCL_NEEDS_EXP_FILE -
#                       1 means that an export file is needed to link to a
#                       shared library.
#       TCL_EXP_FILE -  The name of the installed export / import file which
#                       should be used to link to the Tcl shared library.
#                       Empty if Tcl is unshared.
#       TCL_BUILD_EXP_FILE -
#                       The name of the built export / import file which
#                       should be used to link to the Tcl shared library.
#                       Empty if Tcl is unshared.
#	CFLAGS_DEBUG -
#			Flags used when running the compiler in debug mode
#	CFLAGS_OPTIMIZE -
#			Flags used when running the compiler in optimize mode
#	CFLAGS -	Additional CFLAGS added as necessary (usually 64-bit)
#
#--------------------------------------------------------------------

AC_DEFUN([TEA_CONFIG_CFLAGS], [
    dnl Make sure we are initialized
    AC_REQUIRE([TEA_INIT])

    # Step 0.a: Enable 64 bit support?

    AC_MSG_CHECKING([if 64bit support is requested])
    AC_ARG_ENABLE(64bit,
	AC_HELP_STRING([--enable-64bit],
................................................................................

    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
    AC_ARG_ENABLE(64bit-vis,
	AC_HELP_STRING([--enable-64bit-vis],
	    [enable 64bit Sparc VIS support (default: off)]),
	[do64bitVIS=$enableval], [do64bitVIS=no])
    AC_MSG_RESULT([$do64bitVIS])

    if test "$do64bitVIS" = "yes"; then
	# Force 64bit on with VIS
	do64bit=yes


    fi

























    # Step 0.c: Cross-compiling options for Windows/CE builds?

    if test "${TEA_PLATFORM}" = "windows" ; then
	AC_MSG_CHECKING([if Windows/CE build is requested])


	AC_ARG_ENABLE(wince,[  --enable-wince          enable Win/CE support (where applicable)], [doWince=$enableval], [doWince=no])

	AC_MSG_RESULT([$doWince])
    fi


    # Step 1: set the variable "system" to hold the name and version number
    # for the system.

    TEA_CONFIG_SYSTEM

    # Step 2: check for existence of -ldl library.  This is needed because
    # Linux can use either -ldl or -ldld for dynamic loading.

    AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)

    # Require ranlib early so we can override it in special cases below.

    AC_REQUIRE([AC_PROG_RANLIB])

    # Step 3: set configuration options based on system name and version.
    # This is similar to Tcl's unix/tcl.m4 except that we've added a
    # "windows" case.

    do64bit_ok=no
    LDFLAGS_ORIG="$LDFLAGS"

    # When ld needs options to work in 64-bit mode, put them in
    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
    # is disabled by the user. [Bug 1016796]
    LDFLAGS_ARCH=""
    TCL_EXPORT_FILE_SUFFIX=""
    UNSHARED_LIB_SUFFIX=""

    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
    TCL_LIB_VERSIONS_OK=ok
    CFLAGS_DEBUG=-g
    CFLAGS_OPTIMIZE=-O
    if test "$GCC" = "yes" ; then
	CFLAGS_OPTIMIZE=-O2
	CFLAGS_WARNING="-Wall -Wno-implicit-int"
    else


	CFLAGS_WARNING=""
    fi
    TCL_NEEDS_EXP_FILE=0
    TCL_BUILD_EXP_FILE=""
    TCL_EXP_FILE=""
dnl FIXME: Replace AC_CHECK_PROG with AC_CHECK_TOOL once cross compiling is fixed.

dnl AC_CHECK_TOOL(AR, ar)
    AC_CHECK_PROG(AR, ar, ar)
    STLIB_LD='${AR} cr'
    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"

    case $system in

	windows)
	    # This is a 2-stage check to make sure we have the 64-bit SDK
	    # We have to know where the SDK is installed.
	    # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
	    # MACHINE is IX86 for LINK, but this is used by the manifest,
	    # which requires x86|amd64|ia64.
	    MACHINE="X86"
................................................................................
			PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
			;;
		    ia64)
			MACHINE="IA64"
			PATH64="${MSSDK}/Bin/Win64"
			;;
		esac
		if test ! -d "${PATH64}" ; then
		    AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
		    AC_MSG_WARN([Ensure latest Platform SDK is installed])
		    do64bit="no"
		else
		    AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		    do64bit_ok="yes"
		fi
................................................................................

	    if test "$GCC" != "yes" ; then
	        if test "${SHARED_BUILD}" = "0" ; then
		    runtime=-MT
	        else
		    runtime=-MD
	        fi









                if test "$do64bit" != "no" ; then
		    # All this magic is necessary for the Win64 SDK RC1 - hobbs
		    CC="\"${PATH64}/cl.exe\""
		    CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
		    RC="\"${MSSDK}/bin/rc.exe\""
		    lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
		    LINKBIN="\"${PATH64}/link.exe\""
		    CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
		    # Avoid 'unresolved external symbol __security_cookie'
		    # errors, c.f. http://support.microsoft.com/?id=894573
		    TEA_ADD_LIBS([bufferoverflowU.lib])
		elif test "$doWince" != "no" ; then
................................................................................
			AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
		    done
		    AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
		    AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
		    CFLAGS_DEBUG="-nologo -Zi -Od"
		    CFLAGS_OPTIMIZE="-nologo -Ox"
		    lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
		    lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
		    LINKBIN="\"${CEBINROOT}/link.exe\""
		    AC_SUBST(CELIB_DIR)
		else
		    RC="rc"
		    lflags="-nologo"
    		    LINKBIN="link"
		    CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
		fi
	    fi

	    if test "$GCC" = "yes"; then
		# mingw gcc mode
		RC="windres"
		CFLAGS_DEBUG="-g"
		CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
		SHLIB_LD="$CC -shared"
		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
		LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
		LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"






























	    else
		SHLIB_LD="${LINKBIN} -dll ${lflags}"
		# link -lib only works when -lib is the first arg
		STLIB_LD="${LINKBIN} -lib ${lflags}"
		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
		PATHTYPE=-w
		# For information on what debugtype is most useful, see:
		# http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp


		# This essentially turns it all on.
		LDFLAGS_DEBUG="-debug:full -debugtype:both -warn:2"
		LDFLAGS_OPTIMIZE="-release"
		if test "$doWince" != "no" ; then
		    LDFLAGS_CONSOLE="-link ${lflags}"
		    LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
		else
		    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
		    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
		fi
	    fi

	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".dll"
	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'

	    TCL_LIB_VERSIONS_OK=nodots
	    # Bogus to avoid getting this turned off
	    DL_OBJS="tclLoadNone.obj"
    	    ;;
	AIX-*)
	    if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes" ; then
		# AIX requires the _r compiler when gcc isn't being used
		case "${CC}" in
		    *_r)
			# ok ...
			;;
		    *)
			CC=${CC}_r

			;;
		esac
		AC_MSG_RESULT([Using $CC for compiling with threads])
	    fi

	    LIBS="$LIBS -lc"
	    SHLIB_CFLAGS=""
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"

	    DL_OBJS="tclLoadDl.o"
	    LD_LIBRARY_PATH_VAR="LIBPATH"

	    # Check to enable 64-bit flags for compiler/linker on AIX 4+
	    if test "$do64bit" = "yes" -a "`uname -v`" -gt "3" ; then
		if test "$GCC" = "yes" ; then
		    AC_MSG_WARN([64bit mode not supported with GCC on $system])
		else 

		    do64bit_ok=yes
		    CFLAGS="$CFLAGS -q64"
		    LDFLAGS_ARCH="-q64"
		    RANLIB="${RANLIB} -X64"
		    AR="${AR} -X64"
		    SHLIB_LD_FLAGS="-b64"
		fi
	    fi



	    if test "`uname -m`" = "ia64" ; then
		# AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
		# AIX-5 has dl* in libc.so
		DL_LIBS=""
		if test "$GCC" = "yes" ; then
		    CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		else

		    CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
		fi

		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
	    else

		if test "$GCC" = "yes" ; then
		    SHLIB_LD="gcc -shared"
		else


		    SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry"
		fi


		SHLIB_LD="${TCL_SRC_DIR}/unix/ldAix ${SHLIB_LD} ${SHLIB_LD_FLAGS}"
		DL_LIBS="-ldl"
		CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
		TCL_NEEDS_EXP_FILE=1
		TCL_EXPORT_FILE_SUFFIX='${PACKAGE_VERSION}.exp'
	    fi

	    # AIX v<=4.1 has some different flags than 4.2+
	    if test "$system" = "AIX-4.1" -o "`uname -v`" -lt "4" ; then
		AC_LIBOBJ([tclLoadAix])
		DL_LIBS="-lld"
	    fi

	    # On AIX <=v4 systems, libbsd.a has to be linked in to support
	    # non-blocking file IO.  This library has to be linked in after
	    # the MATH_LIBS or it breaks the pow() function.  The way to
	    # insure proper sequencing, is to add it to the tail of MATH_LIBS.
	    # This library also supplies gettimeofday.
	    #
	    # AIX does not have a timezone field in struct tm. When the AIX
	    # bsd library is used, the timezone global and the gettimeofday
	    # methods are to be avoided for timezone deduction instead, we
	    # deduce the timezone by comparing the localtime result on a
	    # known GMT value.

	    AC_CHECK_LIB(bsd, gettimeofday, libbsd=yes, libbsd=no)
	    if test $libbsd = yes; then
	    	MATH_LIBS="$MATH_LIBS -lbsd"
	    	AC_DEFINE(USE_DELTA_FOR_TZ, 1, [Do we need a special AIX hack for timezones?])
	    fi

	    ;;
	BeOS*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -nostart"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"

	    #-----------------------------------------------------------
	    # Check for inet_ntoa in -lbind, for BeOS (which also needs
	    # -lsocket, even if the network functions are in -lnet which
	    # is always linked to, for compatibility.
	    #-----------------------------------------------------------
	    AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
	    ;;
	BSD/OS-2.1*|BSD/OS-3*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="shlicc -r"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	BSD/OS-4.*)
	    SHLIB_CFLAGS="-export-dynamic -fPIC"
	    SHLIB_LD="cc -shared"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	dgux*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD="cc -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;







	HP-UX-*.11.*)
	    # Use updated header definitions where possible
	    AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
	    # Needed by Tcl, but not most extensions
	    #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
	    #LIBS="$LIBS -lxnet"               # Use the XOPEN network library

	    if test "`uname -m`" = "ia64" ; then
		SHLIB_SUFFIX=".so"
	    else
		SHLIB_SUFFIX=".sl"
	    fi
	    AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
	    if test "$tcl_ok" = yes; then
		SHLIB_CFLAGS="+z"
		SHLIB_LD="ld -b"
		SHLIB_LD_LIBS='${LIBS}'
		DL_OBJS="tclLoadShl.o"
		DL_LIBS="-ldld"
		LDFLAGS="$LDFLAGS -Wl,-E"
		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
	    fi
	    if test "$GCC" = "yes" ; then
		SHLIB_LD="gcc -shared"
		SHLIB_LD_LIBS='${LIBS}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    fi

	    # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
	    #CFLAGS="$CFLAGS +DAportable"

	    # Check to enable 64-bit flags for compiler/linker
	    if test "$do64bit" = "yes" ; then
		if test "$GCC" = "yes" ; then
		    hpux_arch=`${CC} -dumpmachine`
		    case $hpux_arch in

			hppa64*)
			    # 64-bit gcc in use.  Fix flags for GNU ld.
			    do64bit_ok=yes
			    SHLIB_LD="${CC} -shared"
			    SHLIB_LD_LIBS='${LIBS}'
			    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
			    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
			    ;;
			*)
			    AC_MSG_WARN([64bit mode not supported with GCC on $system])
			    ;;
		    esac
		else

		    do64bit_ok=yes
		    CFLAGS="$CFLAGS +DD64"
		    LDFLAGS_ARCH="+DD64"
		fi
	    fi

	    ;;
	HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
	    SHLIB_SUFFIX=".sl"
	    AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
	    if test "$tcl_ok" = yes; then
		SHLIB_CFLAGS="+z"
		SHLIB_LD="ld -b"
		SHLIB_LD_LIBS=""
		DL_OBJS="tclLoadShl.o"
		DL_LIBS="-ldld"
		LDFLAGS="$LDFLAGS -Wl,-E"
		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
	    fi
	    ;;
	IRIX-5.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -shared -rdata_shared"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
	    ;;
	IRIX-6.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""

	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
	    if test "$GCC" = "yes" ; then
		CFLAGS="$CFLAGS -mabi=n32"
		LDFLAGS="$LDFLAGS -mabi=n32"
	    else

		case $system in
		    IRIX-6.3)
			# Use to build 6.2 compatible binaries on 6.3.
			CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
			;;
		    *)
			CFLAGS="$CFLAGS -n32"
			;;
		esac
		LDFLAGS="$LDFLAGS -n32"
	    fi
	    ;;
	IRIX64-6.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""

	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'

	    # Check to enable 64-bit flags for compiler/linker

	    if test "$do64bit" = "yes" ; then
	        if test "$GCC" = "yes" ; then
	            AC_MSG_WARN([64bit mode not supported by gcc])
	        else

	            do64bit_ok=yes
	            SHLIB_LD="ld -64 -shared -rdata_shared"
	            CFLAGS="$CFLAGS -64"
	            LDFLAGS_ARCH="-64"
	        fi
	    fi


	    ;;
	Linux*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"


	    CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings 
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.
	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"

	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    if test "`uname -m`" = "alpha" ; then
		CFLAGS="$CFLAGS -mieee"
	    fi
	    if test $do64bit = yes; then
		AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
		    hold_cflags=$CFLAGS
		    CFLAGS="$CFLAGS -m64"
		    AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
		    CFLAGS=$hold_cflags])
		if test $tcl_cv_cc_m64 = yes; then
		    CFLAGS="$CFLAGS -m64"
		    do64bit_ok=yes
		fi
	    fi



	    # The combo of gcc + glibc has a bug related
	    # to inlining of functions like strtod(). The
	    # -fno-builtin flag should address this problem
	    # but it does not work. The -fno-inline flag
	    # is kind of overkill but it works.
	    # Disable inlining only when one of the
	    # files in compat/*.c is being linked in.
	    if test x"${USE_COMPAT}" != x ; then
	        CFLAGS="$CFLAGS -fno-inline"
	    fi

	    ;;
	GNU*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"

	    SHLIB_LD="${CC} -shared"
	    DL_OBJS=""
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    if test "`uname -m`" = "alpha" ; then
		CFLAGS="$CFLAGS -mieee"
	    fi
	    ;;
	Lynx*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    CFLAGS_OPTIMIZE=-02
	    SHLIB_LD="${CC} -shared "
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-mshared -ldl"
	    LD_FLAGS="-Wl,--export-dynamic"

	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    ;;
	MP-RAS-02*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD="cc -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	MP-RAS-*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD="cc -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,-Bexport"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	NetBSD-*|FreeBSD-[[1-2]].*)
	    # NetBSD/SPARC needs -fPIC, -fpic will not do.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
	    AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
		AC_EGREP_CPP(yes, [
#ifdef __ELF__
	yes
#endif
		], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
	    if test $tcl_cv_ld_elf = yes; then
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
	    else
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
	    fi

	    # Ancient FreeBSD doesn't handle version numbers with dots.

	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	OpenBSD-*)
	    # OpenBSD/SPARC[64] needs -fPIC, -fpic will not do.
	    case `machine` in


	    sparc|sparc64)
		SHLIB_CFLAGS="-fPIC";;

	    *)
		SHLIB_CFLAGS="-fpic";;

	    esac
	    SHLIB_LD="${CC} -shared ${SHLIB_CFLAGS}"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""

	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
	    AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [
		AC_EGREP_CPP(yes, [
#ifdef __ELF__
	yes
#endif
		], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)])
	    if test $tcl_cv_ld_elf = yes; then
		LDFLAGS=-Wl,-export-dynamic
	    else





		LDFLAGS=""
	    fi


	    # OpenBSD doesn't do version numbers with dots.
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	FreeBSD-*)
	    # FreeBSD 3.* and greater have ELF.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -export-dynamic"

	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
	    if test "${TCL_THREADS}" = "1" ; then
		# The -pthread needs to go in the CFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS -pthread"
	    	LDFLAGS="$LDFLAGS -pthread"
	    fi

















	    case $system in
	    FreeBSD-3.*)
	    	# FreeBSD-3 doesn't handle version numbers with dots.


	    	UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    	SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
	    	TCL_LIB_VERSIONS_OK=nodots
		;;
	    esac
	    ;;
	Darwin-*)
	    CFLAGS_OPTIMIZE="-Os"
	    SHLIB_CFLAGS="-fno-common"
	    # To avoid discrepancies between what headers configure sees during
................................................................................
	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
	    CFLAGS="`echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
	    if test $do64bit = yes; then
		case `arch` in
		    ppc)
			AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
				tcl_cv_cc_arch_ppc64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
				    tcl_cv_cc_arch_ppc64=no)
			    CFLAGS=$hold_cflags])
			if test $tcl_cv_cc_arch_ppc64 = yes; then
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    do64bit_ok=yes
			fi;;
		    i386)
			AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
				tcl_cv_cc_arch_x86_64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch x86_64"
			    AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
				    tcl_cv_cc_arch_x86_64=no)
			    CFLAGS=$hold_cflags])
			if test $tcl_cv_cc_arch_x86_64 = yes; then
			    CFLAGS="$CFLAGS -arch x86_64"
			    do64bit_ok=yes
			fi;;
		    *)
			AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
		esac
	    else
		# Check for combined 32-bit and 64-bit fat build
		echo "$CFLAGS " | grep -E -q -- '-arch (ppc64|x86_64) ' && \
		    echo "$CFLAGS " | grep -E -q -- '-arch (ppc|i386) ' && \
		    fat_32_64=yes
	    fi
	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS here:
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
	    AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
		AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
		LDFLAGS=$hold_ldflags])
	    if test $tcl_cv_ld_single_module = yes; then
		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
	    fi
	    SHLIB_LD_LIBS='${LIBS}'




	    SHLIB_SUFFIX=".dylib"
	    DL_OBJS="tclLoadDyld.o"
	    DL_LIBS=""
	    # Don't use -prebind when building for Mac OS X 10.4 or later only:
	    test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
		"`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4 && \
		LDFLAGS="$LDFLAGS -prebind"
	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
	    AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [

		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
		AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes, tcl_cv_ld_search_paths_first=no)

		LDFLAGS=$hold_ldflags])
	    if test $tcl_cv_ld_search_paths_first = yes; then
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
	    fi






	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"

	    # TEA specific: for Tk extensions, remove 64-bit arch flags from
	    # CFLAGS et al. for combined 32 & 64 bit fat builds as neither
	    # TkAqua nor TkX11 can be built for 64-bit at present.

	    test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}" && for v in CFLAGS CPPFLAGS LDFLAGS; do































		eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'; done


	    ;;
	NEXTSTEP-*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="cc -nostdlib -r"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadNext.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OS/390-*)
	    CFLAGS_OPTIMIZE=""		# Optimizer is buggy
	    AC_DEFINE(_OE_SOCKETS, 1,	# needed in sys/socket.h
		[Should OS/390 do the right thing with sockets?])
	    ;;      
	OSF1-1.0|OSF1-1.1|OSF1-1.2)
	    # OSF/1 1.[012] from OSF, and derivatives, including Paragon OSF/1
	    SHLIB_CFLAGS=""
	    # Hack: make package name same as library name
	    SHLIB_LD='ld -R -export $@:'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadOSF.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OSF1-1.*)
	    # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
	    SHLIB_CFLAGS="-fPIC"
	    if test "$SHARED_BUILD" = "1" ; then
	        SHLIB_LD="ld -shared"
	    else
	        SHLIB_LD="ld -non_shared"
	    fi
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	OSF1-V*)
	    # Digital OSF/1
	    SHLIB_CFLAGS=""
	    if test "$SHARED_BUILD" = "1" ; then
	        SHLIB_LD='ld -shared -expect_unresolved "*"'
	    else

	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'
	    fi
	    SHLIB_LD_LIBS=""

	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""

	    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
	    if test "$GCC" = "yes" ; then
		CFLAGS="$CFLAGS -mieee"
            else
		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
	    fi
	    # see pthread_intro(3) for pthread support on osf1, k.furukawa
	    if test "${TCL_THREADS}" = "1" ; then
		CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
		CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
		LIBS=`echo $LIBS | sed s/-lpthreads//`
		if test "$GCC" = "yes" ; then
		    LIBS="$LIBS -lpthread -lmach -lexc"
		else

		    CFLAGS="$CFLAGS -pthread"
		    LDFLAGS="$LDFLAGS -pthread"
		fi
	    fi



	    ;;
	QNX-6*)
	    # QNX RTP
	    # This may work for all QNX, but it was only reported for v6.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    # dlopen is in -lc on QNX
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SCO_SV-3.2*)
	    # Note, dlopen is available only on SCO 3.2.5 and greater. However,
	    # this test works, since "uname -s" was non-standard in 3.2.4 and
	    # below.
	    if test "$GCC" = "yes" ; then
	    	SHLIB_CFLAGS="-fPIC -melf"
	    	LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
	    else

	    	SHLIB_CFLAGS="-Kpic -belf"
	    	LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
	    fi

	    SHLIB_LD="ld -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SINIX*5.4*)
	    SHLIB_CFLAGS="-K PIC"
	    SHLIB_LD="cc -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SunOS-4*)
	    SHLIB_CFLAGS="-PIC"
	    SHLIB_LD="ld"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}

	    # SunOS can't handle version numbers with dots in them in library
	    # specs, like -ltcl7.5, so use -ltcl75 instead.  Also, it
	    # requires an extra version number at the end of .so file names.
	    # So, the library has to have a name like libtcl75.so.1.0

	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.1.0'
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	SunOS-5.[[0-6]])
	    # Careful to not let 5.10+ fall into this case

	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.

	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
		[Do we really want to follow the standard? Yes we do!])

	    SHLIB_CFLAGS="-KPIC"

	    # Note: need the LIBS below, otherwise Tk won't find Tcl's
	    # symbols when dynamically loaded into tclsh.

	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    if test "$GCC" = "yes" ; then
		SHLIB_LD="$CC -shared"
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    else

		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
		CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    fi
	    ;;
	SunOS-5*)
	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.

	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
		[Do we really want to follow the standard? Yes we do!])

	    SHLIB_CFLAGS="-KPIC"

	    # Check to enable 64-bit flags for compiler/linker
	    if test "$do64bit" = "yes" ; then
		arch=`isainfo`
		if test "$arch" = "sparcv9 sparc" ; then
			if test "$GCC" = "yes" ; then
			    if test "`gcc -dumpversion | awk -F. '{print [$]1}'`" -lt "3" ; then
				AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])
			    else

				do64bit_ok=yes
				CFLAGS="$CFLAGS -m64 -mcpu=v9"
				LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
				SHLIB_CFLAGS="-fPIC"
			    fi
			else


			    do64bit_ok=yes
			    if test "$do64bitVIS" = "yes" ; then
				CFLAGS="$CFLAGS -xarch=v9a"
			    	LDFLAGS_ARCH="-xarch=v9a"
			    else

				CFLAGS="$CFLAGS -xarch=v9"
			    	LDFLAGS_ARCH="-xarch=v9"
			    fi

			    # Solaris 64 uses this as well
			    #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
			fi

		elif test "$arch" = "amd64 i386" ; then
		    if test "$GCC" = "yes" ; then






			AC_MSG_WARN([64bit mode not supported with GCC on $system])
		    else


			do64bit_ok=yes





			CFLAGS="$CFLAGS -xarch=amd64"
			LDFLAGS="$LDFLAGS -xarch=amd64"
		    fi
		else


		    AC_MSG_WARN([64bit mode not supported for $arch])
		fi
	    fi

	    
	    # Note: need the LIBS below, otherwise Tk won't find Tcl's
	    # symbols when dynamically loaded into tclsh.

	    SHLIB_LD_LIBS='${LIBS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    if test "$GCC" = "yes" ; then
		SHLIB_LD="$CC -shared"
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
		if test "$do64bit_ok" = "yes" ; then

		    # We need to specify -static-libgcc or we need to
		    # add the path to the sparv9 libgcc.
		    # JH: static-libgcc is necessary for core Tcl, but may
		    # not be necessary for extensions.
		    SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
		    # for finding sparcv9 libgcc, get the regular libgcc
		    # path, remove so name and append 'sparcv9'
		    #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
		    #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
		fi
	    else












		SHLIB_LD="/usr/ccs/bin/ld -G -z text"

		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
	    fi

	    ;;
	UNIX_SV* | UnixWare-5*)
	    SHLIB_CFLAGS="-KPIC"
	    SHLIB_LD="cc -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
	    # that don't grok the -Bexport option.  Test that it does.
	    AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
		AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
	        LDFLAGS=$hold_ldflags])
	    if test $tcl_cv_ld_Bexport = yes; then
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
	    fi

	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
    esac

    if test "$do64bit" = "yes" -a "$do64bit_ok" = "no" ; then
	AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])
    fi


dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
dnl # until the end of configure, as configure's compile and link tests use
dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
dnl # preprocessing tests use only CPPFLAGS.
    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])

    # Step 4: disable dynamic loading if requested via a command-line switch.

    AC_ARG_ENABLE(load,
	AC_HELP_STRING([--enable-load],
	    [allow dynamic loading and "load" command (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])
    if test "$tcl_ok" = "no"; then
	DL_OBJS=""
    fi

    if test "x$DL_OBJS" != "x" ; then
	BUILD_DLTEST="\$(DLTEST_TARGETS)"
    else
	echo "Can't figure out how to do dynamic loading or shared libraries"
	echo "on this system."
	SHLIB_CFLAGS=""
	SHLIB_LD=""
	SHLIB_SUFFIX=""
	DL_OBJS="tclLoadNone.o"
	DL_LIBS=""
	LDFLAGS="$LDFLAGS_ORIG"
	CC_SEARCH_FLAGS=""
	LD_SEARCH_FLAGS=""
	BUILD_DLTEST=""
    fi

    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"

    # If we're running gcc, then change the C flags for compiling shared
    # libraries to the right flags for gcc, instead of those for the
    # standard manufacturer compiler.

    if test "$DL_OBJS" != "tclLoadNone.o" ; then
	if test "$GCC" = "yes" ; then
	    case $system in
		AIX-*)
		    ;;
		BSD/OS*)
		    ;;

		IRIX*)
		    ;;
		NetBSD-*|FreeBSD-*)
		    ;;
		Darwin-*)
		    ;;
		SCO_SV-3.2*)
		    ;;
		windows)
		    ;;
		*)
		    SHLIB_CFLAGS="-fPIC"
		    ;;
	    esac
	fi
    fi






    if test "$SHARED_LIB_SUFFIX" = "" ; then

	SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'
    fi
    if test "$UNSHARED_LIB_SUFFIX" = "" ; then

	UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'



























    fi


    AC_SUBST(DL_LIBS)

































































    AC_SUBST(CFLAGS_DEBUG)
    AC_SUBST(CFLAGS_OPTIMIZE)
    AC_SUBST(CFLAGS_WARNING)

    AC_SUBST(STLIB_LD)
    AC_SUBST(SHLIB_LD)
................................................................................
#	Note that #include lines must begin in leftmost column for
#	some compilers to recognize them as preprocessor directives,
#	and some build environments have stdin not pointing at a
#	pseudo-terminal (usually /dev/null instead.)
#
# Arguments:
#	none
#	
# Results:
#
#	Defines only one of the following vars:
#		HAVE_SYS_MODEM_H
#		USE_TERMIOS
#		USE_TERMIO
#		USE_SGTTY
#
#--------------------------------------------------------------------

AC_DEFUN([TEA_SERIAL_PORT], [
    AC_CHECK_HEADERS(sys/modem.h)
    AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
    AC_TRY_RUN([
#include <termios.h>
................................................................................
    case $tcl_cv_api_serial in
	termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
	termio)  AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
	sgtty)   AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
    esac
])

#--------------------------------------------------------------------
# TEA_MISSING_POSIX_HEADERS
#
#	Supply substitutes for missing POSIX header files.  Special
#	notes:
#	    - stdlib.h doesn't define strtol, strtoul, or
#	      strtod insome versions of SunOS
#	    - some versions of string.h don't declare procedures such
#	      as strstr
#
# Arguments:
#	none
#	
# Results:
#
#	Defines some of the following vars:
#		NO_DIRENT_H
#		NO_ERRNO_H
#		NO_VALUES_H
#		HAVE_LIMITS_H or NO_LIMITS_H
#		NO_STDLIB_H
#		NO_STRING_H
#		NO_SYS_WAIT_H
#		NO_DLFCN_H
#		HAVE_SYS_PARAM_H
#
#		HAVE_STRING_H ?
#
# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and
# CHECK on limits.h
#--------------------------------------------------------------------

AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [
    AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [
    AC_TRY_LINK([#include <sys/types.h>
#include <dirent.h>], [
#ifndef _POSIX_SOURCE
#   ifdef __Lynx__
	/*
	 * Generate compilation error to make the test fail:  Lynx headers
	 * are only valid if really in the POSIX environment.
	 */

	missing_procedure();
#   endif
#endif
DIR *d;
struct dirent *entryPtr;
char *p;
d = opendir("foobar");
entryPtr = readdir(d);
p = entryPtr->d_name;
closedir(d);
], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)])

    if test $tcl_cv_dirent_h = no; then
	AC_DEFINE(NO_DIRENT_H, 1, [Do we have <dirent.h>?])
    fi

    AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have <errno.h>?])])
    AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have <float.h>?])])
    AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have <values.h>?])])
    AC_CHECK_HEADER(limits.h,
	[AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have <limits.h>?])],
	[AC_DEFINE(NO_LIMITS_H, 1, [Do we have <limits.h>?])])
    AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0)
    AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0)
    AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0)
    if test $tcl_ok = 0; then
	AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
    fi
    AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
    AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
    AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)

    # See also memmove check below for a place where NO_STRING_H can be
    # set and why.

    if test $tcl_ok = 0; then
	AC_DEFINE(NO_STRING_H, 1, [Do we have <string.h>?])
    fi

    AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have <sys/wait.h>?])])
    AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have <dlfcn.h>?])])

    # OS/390 lacks sys/param.h (and doesn't need it, by chance).
    AC_HAVE_HEADERS(sys/param.h)
])

#--------------------------------------------------------------------
# TEA_PATH_X
#
#	Locate the X11 header files and the X11 library archive.  Try
#	the ac_path_x macro first, but if it doesn't find the X stuff
#	(e.g. because there's no xmkmf program) then check through
#	a list of possible directories.  Under some conditions the
................................................................................
#	no include files, so double-check its result just to be safe.
#
#	This should be called after TEA_CONFIG_CFLAGS as setting the
#	LIBS line can confuse some configure macro magic.
#
# Arguments:
#	none
#	
# Results:
#
#	Sets the following vars:
#		XINCLUDES
#		XLIBSW
#		PKG_LIBS (appends to)
#
#--------------------------------------------------------------------

AC_DEFUN([TEA_PATH_X], [
    if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
	TEA_PATH_UNIX_X
    fi
])

AC_DEFUN([TEA_PATH_UNIX_X], [
    AC_PATH_X
    not_really_there=""
    if test "$no_x" = ""; then
	if test "$x_includes" = ""; then
	    AC_TRY_CPP([#include <X11/XIntrinsic.h>], , not_really_there="yes")
	else
	    if test ! -r $x_includes/X11/Intrinsic.h; then
		not_really_there="yes"
	    fi
	fi
    fi
    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
	AC_MSG_CHECKING([for X11 header files])
	found_xincludes="no"
	AC_TRY_CPP([#include <X11/Intrinsic.h>], found_xincludes="yes", found_xincludes="no")
	if test "$found_xincludes" = "no"; then
	    dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
	    for i in $dirs ; do
		if test -r $i/X11/Intrinsic.h; then
		    AC_MSG_RESULT([$i])
		    XINCLUDES=" -I$i"
		    found_xincludes="yes"
		    break
		fi
	    done
	fi
    else
	if test "$x_includes" != ""; then
	    XINCLUDES="-I$x_includes"
	    found_xincludes="yes"
	fi
    fi
    if test found_xincludes = "no"; then
	AC_MSG_RESULT([couldn't find any!])
    fi

    if test "$no_x" = yes; then
	AC_MSG_CHECKING([for X11 libraries])
	XLIBSW=nope
	dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
	for i in $dirs ; do
	    if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then
		AC_MSG_RESULT([$i])
		XLIBSW="-L$i -lX11"
		x_libraries="$i"
		break
	    fi
	done
    else
................................................................................
    if test "$XLIBSW" = nope ; then
	AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
    fi
    if test "$XLIBSW" = nope ; then
	AC_MSG_RESULT([could not find any!  Using -lX11.])
	XLIBSW=-lX11
    fi

    if test x"${XLIBSW}" != x ; then
	PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
    fi
])

#--------------------------------------------------------------------
# TEA_BLOCKING_STYLE
#
#	The statements below check for systems where POSIX-style
#	non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. 
#	On these systems (mostly older ones), use the old BSD-style
#	FIONBIO approach instead.
#
# Arguments:
#	none
#	
# Results:
#
#	Defines some of the following vars:
#		HAVE_SYS_IOCTL_H
#		HAVE_SYS_FILIO_H
#		USE_FIONBIO
#		O_NONBLOCK
#
#--------------------------------------------------------------------

AC_DEFUN([TEA_BLOCKING_STYLE], [
    AC_CHECK_HEADERS(sys/ioctl.h)
    AC_CHECK_HEADERS(sys/filio.h)
    TEA_CONFIG_SYSTEM
    AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
    case $system in
	# There used to be code here to use FIONBIO under AIX.  However, it
	# was reported that FIONBIO doesn't work under AIX 3.2.5.  Since
	# using O_NONBLOCK seems fine under AIX 4.*, I removed the FIONBIO
	# code (JO, 5/31/97).

	OSF*)
	    AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
	    AC_MSG_RESULT([FIONBIO])
	    ;;
	SunOS-4*)
	    AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
	    AC_MSG_RESULT([FIONBIO])
	    ;;
	*)
	    AC_MSG_RESULT([O_NONBLOCK])
	    ;;
    esac
])

#--------------------------------------------------------------------
# TEA_TIME_HANLDER
#
#	Checks how the system deals with time.h, what time structures
#	are used on the system, and what fields the structures have.
#
# Arguments:
#	none
#	
# Results:
#
#	Defines some of the following vars:
#		USE_DELTA_FOR_TZ
#		HAVE_TM_GMTOFF
#		HAVE_TM_TZADJ
#		HAVE_TIMEZONE_VAR
#
#--------------------------------------------------------------------

AC_DEFUN([TEA_TIME_HANDLER], [
    AC_CHECK_HEADERS(sys/time.h)
    AC_HEADER_TIME
    AC_STRUCT_TIMEZONE

................................................................................
#	and if the problem exists use a substitute procedure
#	"fixstrtod" (provided by Tcl) that corrects the error.
#	Also, on Compaq's Tru64 Unix 5.0,
#	strtod(" ") returns 0.0 instead of a failure to convert.
#
# Arguments:
#	none
#	
# Results:
#
#	Might defines some of the following vars:
#		strtod (=fixstrtod)
#
#--------------------------------------------------------------------

AC_DEFUN([TEA_BUGGY_STRTOD], [
    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
    if test "$tcl_strtod" = 1; then
	AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
	    AC_TRY_RUN([
................................................................................
	    AC_LIBOBJ([fixstrtod])
	    USE_COMPAT=1
	    AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
	fi
    fi
])

#--------------------------------------------------------------------
# TEA_TCL_LINK_LIBS
#
#	Search for the libraries needed to link the Tcl shell.
#	Things like the math library (-lm) and socket stuff (-lsocket vs.
#	-lnsl) are dealt with here.
#
# Arguments:
#	Requires the following vars to be set in the Makefile:
#		DL_LIBS
#		LIBS
#		MATH_LIBS
#	
# Results:
#
#	Subst's the following var:
#		TCL_LIBS
#		MATH_LIBS
#
#	Might append to the following vars:
#		LIBS
#
#	Might define the following vars:
#		HAVE_NET_ERRNO_H
#
#--------------------------------------------------------------------

AC_DEFUN([TEA_TCL_LINK_LIBS], [
    #--------------------------------------------------------------------
    # On a few very rare systems, all of the libm.a stuff is
    # already in libc.a.  Set compiler flags accordingly.
    # Also, Linux requires the "ieee" library for math to work
    # right (and it must appear before "-lm").
    #--------------------------------------------------------------------

    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
    AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])

    #--------------------------------------------------------------------
    # Interactive UNIX requires -linet instead of -lsocket, plus it
    # needs net/errno.h to define the socket-related error codes.
    #--------------------------------------------------------------------

    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
    AC_CHECK_HEADER(net/errno.h, [
	AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have <net/errno.h>?])])

    #--------------------------------------------------------------------
    #	Check for the existence of the -lsocket and -lnsl libraries.
    #	The order here is important, so that they end up in the right
    #	order in the command line generated by make.  Here are some
    #	special considerations:
    #	1. Use "connect" and "accept" to check for -lsocket, and
    #	   "gethostbyname" to check for -lnsl.
    #	2. Use each function name only once:  can't redo a check because
    #	   autoconf caches the results of the last check and won't redo it.
    #	3. Use -lnsl and -lsocket only if they supply procedures that
    #	   aren't already present in the normal libraries.  This is because
    #	   IRIX 5.2 has libraries, but they aren't needed and they're
    #	   bogus:  they goof up name resolution if used.
    #	4. On some SVR4 systems, can't use -lsocket without -lnsl too.
    #	   To get around this problem, check for both libraries together
    #	   if -lsocket doesn't work by itself.
    #--------------------------------------------------------------------

    tcl_checkBoth=0
    AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1)
    if test "$tcl_checkSocket" = 1; then
	AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt,
	    LIBS="$LIBS -lsocket", tcl_checkBoth=1)])
    fi
    if test "$tcl_checkBoth" = 1; then
	tk_oldLibs=$LIBS
	LIBS="$LIBS -lsocket -lnsl"
	AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs])
    fi
    AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname,
	    [LIBS="$LIBS -lnsl"])])
    
    # Don't perform the eval of the libraries here because DL_LIBS
    # won't be set until we call TEA_CONFIG_CFLAGS

    TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}'
    AC_SUBST(TCL_LIBS)
    AC_SUBST(MATH_LIBS)
])

#--------------------------------------------------------------------
# TEA_TCL_EARLY_FLAGS
#
#	Check for what flags are needed to be passed so the correct OS
#	features are available.
#
# Arguments:
#	None
#	
# Results:
#
#	Might define the following vars:
#		_ISOC99_SOURCE
#		_LARGEFILE64_SOURCE
#		_LARGEFILE_SOURCE64
#
#--------------------------------------------------------------------

AC_DEFUN([TEA_TCL_EARLY_FLAG],[
    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
	AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
	    AC_TRY_COMPILE([[#define ]$1[ 1
]$2], $3,
................................................................................
#--------------------------------------------------------------------
# TEA_TCL_64BIT_FLAGS
#
#	Check for what is defined in the way of 64-bit features.
#
# Arguments:
#	None
#	
# Results:
#
#	Might define the following vars:
#		TCL_WIDE_INT_IS_LONG
#		TCL_WIDE_INT_TYPE
#		HAVE_STRUCT_DIRENT64
#		HAVE_STRUCT_STAT64
#		HAVE_TYPE_OFF64_T
#
#--------------------------------------------------------------------

AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
    AC_MSG_CHECKING([for 64-bit integer type])
    AC_CACHE_VAL(tcl_cv_type_64bit,[
	tcl_cv_type_64bit=none
	# See if the compiler knows natively about __int64
	AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
	    tcl_type_64bit=__int64, tcl_type_64bit="long long")
	# See if we should use long anyway  Note that we substitute in the
	# type that is our current guess for a 64-bit type inside this check
	# program, so it should be modified only carefully...
        AC_TRY_COMPILE(,[switch (0) { 
            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ; 
        }],tcl_cv_type_64bit=${tcl_type_64bit})])
    if test "${tcl_cv_type_64bit}" = none ; then
	AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
	AC_MSG_RESULT([using long])
    elif test "${tcl_cv_type_64bit}" = "__int64" \
		-a "${TEA_PLATFORM}" = "windows" ; then
	# We actually want to use the default tcl.h checks in this
	# case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
	AC_MSG_RESULT([using Tcl header defaults])
    else
	AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
	    [What type should be used to define wide integers?])
	AC_MSG_RESULT([${tcl_cv_type_64bit}])

	# Now check for auxiliary declarations
	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
	    AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/dirent.h>],[struct dirent64 p;],
		tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
	fi

	AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
	    AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
................................................................................
# EXEEXT
#	Select the executable extension based on the host type.  This
#	is a lightweight replacement for AC_EXEEXT that doesn't require
#	a compiler.
#------------------------------------------------------------------------

AC_DEFUN([TEA_INIT], [
    # TEA extensions pass this us the version of TEA they think they
    # are compatible with.
    TEA_VERSION="3.6"

    AC_MSG_CHECKING([for correct TEA configuration])
    if test x"${PACKAGE_NAME}" = x ; then
	AC_MSG_ERROR([
The PACKAGE_NAME variable must be defined by your TEA configure.in])
    fi
    if test x"$1" = x ; then
	AC_MSG_ERROR([
TEA version not specified.])
    elif test "$1" != "${TEA_VERSION}" ; then
	AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"])
    else
	AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])





    fi

    case "`uname -s`" in
	*win32*|*WIN32*|*CYGWIN_NT*|*CYGWIN_9*|*CYGWIN_ME*|*MINGW32_*)

	    AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo)
	    EXEEXT=".exe"
	    TEA_PLATFORM="windows"
	    ;;




	*)
	    CYGPATH=echo







	    EXEEXT=""
	    TEA_PLATFORM="unix"


	    ;;
    esac

    # Check if exec_prefix is set. If not use fall back to prefix.
    # Note when adjusted, so that TEA_PREFIX can correct for this.
    # This is needed for recursive configures, since autoconf propagates
    # $prefix, but not $exec_prefix (doh!).
    if test x$exec_prefix = xNONE ; then
	exec_prefix_default=yes
	exec_prefix=$prefix
    fi



    AC_SUBST(EXEEXT)
    AC_SUBST(CYGPATH)

    # This package name must be replaced statically for AC_SUBST to work
    AC_SUBST(PKG_LIB_FILE)
    # Substitute STUB_LIB_FILE in case package creates a stub library too.
................................................................................
    AC_SUBST(PKG_STUB_SOURCES)
    AC_SUBST(PKG_STUB_OBJECTS)
    AC_SUBST(PKG_TCL_SOURCES)
    AC_SUBST(PKG_HEADERS)
    AC_SUBST(PKG_INCLUDES)
    AC_SUBST(PKG_LIBS)
    AC_SUBST(PKG_CFLAGS)



])

#------------------------------------------------------------------------
# TEA_ADD_SOURCES --
#
#	Specify one or more source files.  Users should check for
#	the right platform before adding to their list.
................................................................................
	    [\$]*)
		# allow $-var names
		PKG_SOURCES="$PKG_SOURCES $i"
		PKG_OBJECTS="$PKG_OBJECTS $i"
		;;
	    *)
		# check for existence - allows for generic/win/unix VPATH


		if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
		    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \

		    ; then
		    AC_MSG_ERROR([could not find source file '$i'])
		fi
		PKG_SOURCES="$PKG_SOURCES $i"
		# this assumes it is in a VPATH dir
		i=`basename $i`
		# handle user calling this before or after TEA_SETUP_COMPILER
................................................................................
#------------------------------------------------------------------------
AC_DEFUN([TEA_ADD_STUB_SOURCES], [
    vars="$@"
    for i in $vars; do
	# check for existence - allows for generic/win/unix VPATH
	if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
	    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \

	    ; then
	    AC_MSG_ERROR([could not find stub source file '$i'])
	fi
	PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
	# this assumes it is in a VPATH dir
	i=`basename $i`
	# handle user calling this before or after TEA_SETUP_COMPILER
................................................................................
#	Defines and substs the following vars:
#		PKG_CFLAGS
#------------------------------------------------------------------------
AC_DEFUN([TEA_ADD_CFLAGS], [
    PKG_CFLAGS="$PKG_CFLAGS $@"
    AC_SUBST(PKG_CFLAGS)
])

















#------------------------------------------------------------------------
# TEA_PREFIX --
#
#	Handle the --prefix=... option by defaulting to what Tcl gave
#
# Arguments:
................................................................................
    fi
])

#------------------------------------------------------------------------
# TEA_SETUP_COMPILER_CC --
#
#	Do compiler checks the way we want.  This is just a replacement
#	for AC_PROG_CC in TEA configure.in files to make them cleaner.
#
# Arguments:
#	none
#
# Results:
#
#	Sets up CC var and other standard bits we need to make executables.
#------------------------------------------------------------------------
AC_DEFUN([TEA_SETUP_COMPILER_CC], [
    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
    # in this macro, they need to go into TEA_SETUP_COMPILER instead.

    # If the user did not set CFLAGS, set it now to keep
    # the AC_PROG_CC macro from adding "-g -O2".
    if test "${CFLAGS+set}" != "set" ; then
	CFLAGS=""
    fi

    AC_PROG_CC
    AC_PROG_CPP

    AC_PROG_INSTALL

    #--------------------------------------------------------------------
    # Checks to see if the make program sets the $MAKE variable.
    #--------------------------------------------------------------------

    AC_PROG_MAKE_SET

    #--------------------------------------------------------------------
    # Find ranlib
    #--------------------------------------------------------------------

    AC_PROG_RANLIB

    #--------------------------------------------------------------------
    # Determines the correct binary file extension (.o, .obj, .exe etc.)
    #--------------------------------------------------------------------

    AC_OBJEXT
    AC_EXEEXT
................................................................................
    fi

    #--------------------------------------------------------------------
    # Common compiler flag setup
    #--------------------------------------------------------------------

    AC_C_BIGENDIAN
    if test "${TEA_PLATFORM}" = "unix" ; then
	TEA_TCL_LINK_LIBS
	TEA_MISSING_POSIX_HEADERS
	# Let the user call this, because if it triggers, they will
	# need a compat/strtod.c that is correct.  Users can also
	# use Tcl_GetDouble(FromObj) instead.
	#TEA_BUGGY_STRTOD
    fi
])

#------------------------------------------------------------------------
# TEA_MAKE_LIB --
#
#	Generate a line that can be used to build a shared/unshared library
#	in a platform independent manner.
................................................................................
#	CFLAGS -	Done late here to note disturb other AC macros
#       MAKE_LIB -      Command to execute to build the Tcl library;
#                       differs depending on whether or not Tcl is being
#                       compiled as a shared library.
#	MAKE_SHARED_LIB	Makefile rule for building a shared library
#	MAKE_STATIC_LIB	Makefile rule for building a static library
#	MAKE_STUB_LIB	Makefile rule for building a stub library


#------------------------------------------------------------------------

AC_DEFUN([TEA_MAKE_LIB], [
    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
	MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
	MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"











	MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)"
    else
	MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
	MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
	MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)"
    fi

    if test "${SHARED_BUILD}" = "1" ; then
................................................................................
    # substituted. (@@@ Might not be necessary anymore)
    #--------------------------------------------------------------------

    if test "${TEA_PLATFORM}" = "windows" ; then
	if test "${SHARED_BUILD}" = "1" ; then
	    # We force the unresolved linking of symbols that are really in
	    # the private libraries of Tcl and Tk.
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
	    if test x"${TK_BIN_DIR}" != x ; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
	    fi




	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
	else
	    eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"


	fi

	# Some packages build their own stubs libraries
	eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
	if test "$GCC" = "yes"; then
	    PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
	fi
	# These aren't needed on Windows (either MSVC or gcc)
	RANLIB=:
	RANLIB_STUB=:
    else
	RANLIB_STUB="${RANLIB}"
	if test "${SHARED_BUILD}" = "1" ; then
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
	    if test x"${TK_BIN_DIR}" != x ; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
	    fi
	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
	    RANLIB=:
	else
	    eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
	fi
	# Some packages build their own stubs libraries
	eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
    fi

    # These are escaped so that only CFLAGS is picked up at configure time.
    # The other values will be substituted at make time.
    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
    if test "${SHARED_BUILD}" = "1" ; then
	CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
................................................................................
    fi

    AC_SUBST(MAKE_LIB)
    AC_SUBST(MAKE_SHARED_LIB)
    AC_SUBST(MAKE_STATIC_LIB)
    AC_SUBST(MAKE_STUB_LIB)
    AC_SUBST(RANLIB_STUB)


])

#------------------------------------------------------------------------
# TEA_LIB_SPEC --
#
#	Compute the name of an existing object library located in libdir
#	from the given base name and produce the appropriate linker flags.
................................................................................
    for i in \
	    `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
	    `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
	    `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
	    `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
	    `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
	    `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \


	    `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
	    `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
	if test -f "$i" ; then
	    tea_lib_name_dir=`dirname $i`
	    $1_LIB_NAME=`basename $i`
	    $1_LIB_PATH_NAME=$i
	    break
................................................................................
#
#	Locate the private Tcl include files
#
# Arguments:
#
#	Requires:
#		TCL_SRC_DIR	Assumes that TEA_LOAD_TCLCONFIG has
#				 already been called.
#
# Results:
#
#	Substs the following vars:
#		TCL_TOP_DIR_NATIVE
#		TCL_GENERIC_DIR_NATIVE
#		TCL_UNIX_DIR_NATIVE
#		TCL_WIN_DIR_NATIVE
#		TCL_BMAP_DIR_NATIVE
#		TCL_TOOL_DIR_NATIVE
#		TCL_PLATFORM_DIR_NATIVE
#		TCL_BIN_DIR_NATIVE
#		TCL_INCLUDES
#------------------------------------------------------------------------

AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [


    AC_MSG_CHECKING([for Tcl private include files])

    TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
    TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"
    TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
    TCL_UNIX_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
    TCL_WIN_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
    TCL_BMAP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/bitmaps\"
    TCL_TOOL_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/tools\"
    TCL_COMPAT_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/compat\"












    if test "${TEA_PLATFORM}" = "windows"; then
	TCL_PLATFORM_DIR_NATIVE=${TCL_WIN_DIR_NATIVE}
    else
	TCL_PLATFORM_DIR_NATIVE=${TCL_UNIX_DIR_NATIVE}
    fi


    # We want to ensure these are substituted so as not to require
    # any *_NATIVE vars be defined in the Makefile
    TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
    if test "`uname -s`" = "Darwin"; then
        # If Tcl was built as a framework, attempt to use
        # the framework's Headers and PrivateHeaders directories
        case ${TCL_DEFS} in
	    *TCL_FRAMEWORK*)

	        if test -d "${TCL_BIN_DIR}/Headers" -a -d "${TCL_BIN_DIR}/PrivateHeaders"; then
	        TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"; else

	        TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"; fi

	        ;;
	esac

    else
	if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
	    AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
	fi

    fi



    AC_SUBST(TCL_TOP_DIR_NATIVE)
    AC_SUBST(TCL_GENERIC_DIR_NATIVE)
    AC_SUBST(TCL_UNIX_DIR_NATIVE)
    AC_SUBST(TCL_WIN_DIR_NATIVE)
    AC_SUBST(TCL_BMAP_DIR_NATIVE)
    AC_SUBST(TCL_TOOL_DIR_NATIVE)
    AC_SUBST(TCL_PLATFORM_DIR_NATIVE)

    AC_SUBST(TCL_INCLUDES)
    AC_MSG_RESULT([Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}])

])

#------------------------------------------------------------------------
# TEA_PUBLIC_TCL_HEADERS --
#
#	Locate the installed public Tcl header files
#
................................................................................
#	CYGPATH must be set
#
# Results:
#
#	Adds a --with-tclinclude switch to configure.
#	Result is cached.
#
#	Substs the following vars:
#		TCL_INCLUDES
#------------------------------------------------------------------------

AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
    AC_MSG_CHECKING([for Tcl public headers])

    AC_ARG_WITH(tclinclude, [  --with-tclinclude       directory containing the public Tcl header files], with_tclinclude=${withval})
................................................................................
	if test x"${with_tclinclude}" != x ; then
	    if test -f "${with_tclinclude}/tcl.h" ; then
		ac_cv_c_tclh=${with_tclinclude}
	    else
		AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
	    fi
	else

	    if test "`uname -s`" = "Darwin"; then
		# If Tcl was built as a framework, attempt to use
		# the framework's Headers directory
		case ${TCL_DEFS} in
		    *TCL_FRAMEWORK*)
			list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
			;;
................................................................................
#
#	Requires:
#		TK_SRC_DIR	Assumes that TEA_LOAD_TKCONFIG has
#				 already been called.
#
# Results:
#
#	Substs the following vars:
#		TK_INCLUDES
#------------------------------------------------------------------------

AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [


    AC_MSG_CHECKING([for Tk private include files])

    TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
    TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"
    TK_UNIX_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"

    TK_WIN_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"









    TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
    TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
    if test "${TEA_PLATFORM}" = "windows"; then
	TK_PLATFORM_DIR_NATIVE=${TK_WIN_DIR_NATIVE}
    else
	TK_PLATFORM_DIR_NATIVE=${TK_UNIX_DIR_NATIVE}
    fi


    # We want to ensure these are substituted so as not to require
    # any *_NATIVE vars be defined in the Makefile
    TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"




    if test "${TEA_WINDOWINGSYSTEM}" = "win32" \
	-o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
	TK_INCLUDES="${TK_INCLUDES} -I${TK_XLIB_DIR_NATIVE}"
    fi
    if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
	TK_INCLUDES="${TK_INCLUDES} -I${TK_SRC_DIR_NATIVE}/macosx"
    fi
    if test "`uname -s`" = "Darwin"; then
        # If Tk was built as a framework, attempt to use
        # the framework's Headers and PrivateHeaders directories
        case ${TK_DEFS} in
	    *TK_FRAMEWORK*)

	        if test -d "${TK_BIN_DIR}/Headers" -a -d "${TK_BIN_DIR}/PrivateHeaders"; then
	        TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"; fi



	        ;;
	esac

    else
	if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
	    AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
	fi

    fi


    AC_SUBST(TK_TOP_DIR_NATIVE)
    AC_SUBST(TK_UNIX_DIR_NATIVE)
    AC_SUBST(TK_WIN_DIR_NATIVE)
    AC_SUBST(TK_GENERIC_DIR_NATIVE)
    AC_SUBST(TK_XLIB_DIR_NATIVE)
    AC_SUBST(TK_PLATFORM_DIR_NATIVE)

    AC_SUBST(TK_INCLUDES)
    AC_MSG_RESULT([Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}])

])

#------------------------------------------------------------------------
# TEA_PUBLIC_TK_HEADERS --
#
#	Locate the installed public Tk header files
#
................................................................................
#	CYGPATH must be set
#
# Results:
#
#	Adds a --with-tkinclude switch to configure.
#	Result is cached.
#
#	Substs the following vars:
#		TK_INCLUDES
#------------------------------------------------------------------------

AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
    AC_MSG_CHECKING([for Tk public headers])

    AC_ARG_WITH(tkinclude, [  --with-tkinclude        directory containing the public Tk header files], with_tkinclude=${withval})
................................................................................
	if test x"${with_tkinclude}" != x ; then
	    if test -f "${with_tkinclude}/tk.h" ; then
		ac_cv_c_tkh=${with_tkinclude}
	    else
		AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
	    fi
	else

	    if test "`uname -s`" = "Darwin"; then
		# If Tk was built as a framework, attempt to use
		# the framework's Headers directory.
		case ${TK_DEFS} in
		    *TK_FRAMEWORK*)
			list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
			;;
................................................................................
	    # Look in the source dir only if Tk is not installed,
	    # and in that situation, look there before installed locations.
	    if test -f "${TK_BIN_DIR}/Makefile" ; then
		list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
	    fi

	    # Check order: pkg --prefix location, Tk's --prefix location,
	    # relative to directory of tkConfig.sh, Tcl's --prefix location, 
	    # relative to directory of tclConfig.sh.

	    eval "temp_includedir=${includedir}"
	    list="$list \
		`ls -d ${temp_includedir}        2>/dev/null` \
		`ls -d ${TK_PREFIX}/include      2>/dev/null` \
		`ls -d ${TK_BIN_DIR}/../include  2>/dev/null` \
		`ls -d ${TCL_PREFIX}/include     2>/dev/null` \
		`ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
	    if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
		list="$list /usr/local/include /usr/include"




	    fi
	    for i in $list ; do
		if test -f "$i/tk.h" ; then
		    ac_cv_c_tkh=$i
		    break
		fi
	    done
................................................................................

    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`

    TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"

    AC_SUBST(TK_INCLUDES)

    if test "${TEA_WINDOWINGSYSTEM}" = "win32" \
	-o "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
	# On Windows and Aqua, we need the X compat headers
	AC_MSG_CHECKING([for X11 header files])
	if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
	    INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
	    TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
	    AC_SUBST(TK_XINCLUDES)
	fi
	AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
    fi
])

#------------------------------------------------------------------------
# TEA_PROG_TCLSH
#	Determine the fully qualified path name of the tclsh executable
#	in the Tcl build directory or the tclsh installed in a bin
#	directory. This macro will correctly determine the name
#	of the tclsh executable even if tclsh has not yet been
#	built in the build directory. The tclsh found is always
#	associated with a tclConfig.sh file. This tclsh should be used
#	only for running extension test cases. It should never be
#	or generation of files (like pkgIndex.tcl) at build time.
#
# Arguments
#	none
#
# Results
#	Subst's the following values:
#		TCLSH_PROG
#------------------------------------------------------------------------

AC_DEFUN([TEA_PROG_TCLSH], [
    AC_MSG_CHECKING([for tclsh])
    if test -f "${TCL_BIN_DIR}/Makefile" ; then
        # tclConfig.sh is in Tcl build directory
        if test "${TEA_PLATFORM}" = "windows"; then
            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
        else
            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
        fi
    else
        # tclConfig.sh is in install location
        if test "${TEA_PLATFORM}" = "windows"; then
            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
        else
            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
        fi
        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
        for i in $list ; do
            if test -f "$i/${TCLSH_PROG}" ; then
                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
                break
            fi
        done
        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
    fi
    AC_MSG_RESULT([${TCLSH_PROG}])
    AC_SUBST(TCLSH_PROG)
])

#------------------------------------------------------------------------
# TEA_PROG_WISH
#	Determine the fully qualified path name of the wish executable
#	in the Tk build directory or the wish installed in a bin
#	directory. This macro will correctly determine the name
#	of the wish executable even if wish has not yet been
#	built in the build directory. The wish found is always
#	associated with a tkConfig.sh file. This wish should be used
#	only for running extension test cases. It should never be
#	or generation of files (like pkgIndex.tcl) at build time.
#
# Arguments
#	none
#
# Results
#	Subst's the following values:
#		WISH_PROG
#------------------------------------------------------------------------

AC_DEFUN([TEA_PROG_WISH], [
    AC_MSG_CHECKING([for wish])
    if test -f "${TK_BIN_DIR}/Makefile" ; then
        # tkConfig.sh is in Tk build directory
        if test "${TEA_PLATFORM}" = "windows"; then
            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
        else
            WISH_PROG="${TK_BIN_DIR}/wish"
        fi
    else
        # tkConfig.sh is in install location
        if test "${TEA_PLATFORM}" = "windows"; then
            WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
        else
            WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
        fi
        list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
              `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
              `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
        for i in $list ; do
            if test -f "$i/${WISH_PROG}" ; then
                REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
                break
            fi
        done
        WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
    fi
    AC_MSG_RESULT([${WISH_PROG}])
    AC_SUBST(WISH_PROG)
])

#------------------------------------------------------------------------
# TEA_PATH_CONFIG --
#
#	Locate the ${1}Config.sh file and perform a sanity check on
#	the ${1} compile flags.  These are used by packages like
#	[incr Tk] that load *Config.sh files from more than Tcl and Tk.
#
................................................................................
	    # check in a few common install locations
	    if test x"${ac_cv_c_$1config}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \

			`ls -d /usr/lib 2>/dev/null` \

			; do
		    if test -f "$i/$1Config.sh" ; then
			ac_cv_c_$1config=`(cd $i; pwd)`
			break
		    fi
		done
	    fi
................................................................................

#------------------------------------------------------------------------
# TEA_LOAD_CONFIG --
#
#	Load the $1Config.sh file
#
# Arguments:
#	
#	Requires the following vars to be set:
#		$1_BIN_DIR
#
# Results:
#
#	Subst the following vars:
#		$1_SRC_DIR
#		$1_LIB_FILE
#		$1_LIB_SPEC
#
#------------------------------------------------------------------------

AC_DEFUN([TEA_LOAD_CONFIG], [
    AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])

    if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
        AC_MSG_RESULT([loading])
................................................................................
    #

    if test -f "${$1_BIN_DIR}/Makefile" ; then
	AC_MSG_WARN([Found Makefile - using build library specs for $1])
        $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
        $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
        $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}


    fi

    AC_SUBST($1_VERSION)
    AC_SUBST($1_BIN_DIR)
    AC_SUBST($1_SRC_DIR)

    AC_SUBST($1_LIB_FILE)
    AC_SUBST($1_LIB_SPEC)

    AC_SUBST($1_STUB_LIB_FILE)
    AC_SUBST($1_STUB_LIB_SPEC)
    AC_SUBST($1_STUB_LIB_PATH)









])














































































#------------------------------------------------------------------------
# TEA_PATH_CELIB --
#
#	Locate Keuchel's celib emulation layer for targeting Win/CE
#
# Arguments:
................................................................................
	    CELIB_DIR=${ac_cv_c_celibconfig}
	    CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
	    AC_MSG_RESULT([found $CELIB_DIR])
	fi
    fi
])



















































































































































# Local Variables:
# mode: autoconf
# End:







<
<



<
<
<
<




>







 







|













|





|

|

|



|







 







>
>
>
>
>

|











>
>
>


|





|






|












>

>
>
>
>
>
>
>


|












>
>
>
>
>

|
|
|






|
<


|







 







|





|

|

|



|







 







>
>
>
>
>

|











>
>
>


|












>

>
>
>
>
>
>
>


|





|






|












>
>
>
>
>

|








|
<


|











|





|



|
>







 







|
|
|



|



|
|

|





|













>











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













|







 







|
|
|



|



|
|

|





|












|







 







>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|




>







>
>
>
>
>

<





|



|

|


>
>
>
>
>
>
>
>
>
>
>
>
>
|


>



|
>
>
>
>
|
>
>
>
>
>
>
>
>
>

>







 







|












<





|







 







|







 







|





|







|




<



|








|









>



<
<


>







 







|







<







 







|









|
<








<




>


<
<






<
<
<
<
<
<







 







|
<
<
<







 







|











|


|
|



<
<
<
|
<
<
<
<
<
<
<





<



|







 







<
<
|
|
>
>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

|

>
>
|
>

<
>

|




<
<
<
<
<




|

|


|
>




<

>




<
|

|
<
>
>

<
<
<
<
<
>
|
<


>

>







 







|







 







>
>
>
>
>
>
>
>






|







 







|




|
|







|


|



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








>
>

|










<




<
<


|


|



|
>



<
>


<


<


|
|
|

<
>






<
<
>
>

|


<
<
|

<
>

<
>

<
>
|
<
<
>
>
|
<
>
>
|
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>



|
<

<
<








<
<
<
<
<
<
<
<
<
<


|
<

<
<




|
|
|
|
|
|
|



>
>
>
>
>
>
>



|



|
|
|
|
|
|
|
|
|
|
|
<




|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>



|
|
|






<
>



<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



<

<
<
>
|
|
|


<
>










|




<

<
<
>
|
|



|
|

<
>




<
<
>
>

|

<


>

<
<
<
<

|
|
<
<

>
|

|
<
<
|





|


<
<
>
>

|
<
|
|
<
|

<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
|
<



<


|
<
<

>
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
>
>
|
|
>

|
>

|
<

<
<
>
|

|
<
<
<
<
<
<
<
|
<
>
>
>
>
>
|
<
<
>




|
|

|
<

<
<

>
|
|
|




<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


<
>
>
|
|
|







 







|









|


|








|


|



|
|
|
|
|
|
|






|

<
<
>
>
>
>

<
<

|
|
|

|
>


|
>

|

<
>
>
>
>
>
>



<
<
|
<
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>

<
<
<
<
<
<
<
<
<
<




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




|

<
>

<
<
>

<
<
>
|
|
<
|
<
|
<

|



|

<
>


<
<
<
>
>








<
<
<




<
<
<
|
|
|
<
>
|
|
<
>



<
<



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











<
<
<
<
<

<
<
|
|


<
>



|












|

|
|
|
|
<
>
|
|
|
|
<
<
>
>
|
|
|
|
<
>
|
|
<
>
|
|
<
>
|
|
>
>
>
>
>
>
|
<
>
>

>
>
>
>
>
|
|
<
<
>
>
|
<
<
>
|
<
<
<
<

<
<
|
|


|
>
|
|
|
|
|
|
|
|
|
<
<
>
>
>
>
>
>
>
>
>
>
>
>
|
>


<
>



|


<
<







|

<
>





|

<
>







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>






<
|
|
|
<
|
<
>
|
<
|
<
|
<
|
<
|
<
<
|
<
|
<
<

>
>
>
>
>
|
>
|
<
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|






<













|

|







|



|













|








|







 







>









|





|







<








<
<
<
<
<

<
<
<
<










|






|







<







 







|




<







 








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







|






<







 







|








<












|
|






|
|









|







 







<
<
|

|


|

<
<
<
<
<
<
|
>
>
>
>
>

>

<
>
|



>
>
>
>


>
>
>
>
>
>
>
|
|
>
>











>
>







 







>
>
>







 







>
>


>







 







>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|












<
<
<
<
<
<



<
<










|







 







<
<
<
<
<
<
<
<







 







>
>






>
>
>
>
>
>
>
>
>
>
>
|







 







<



>
>
>
>
|

|
>
>
|
>

|













|


|


|







 







>
>







 







>
>







 







|



|

<
<
<
<
<
<
<




>
>




<
<
<
<
<
<

>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
>
>
|
|
|
|
|
|
|
|
>
|
|
>
|
>
|
|
>
|
|
|
|
>
|
>

<

<
<
<
<
<
<


<
>







 







|







 







>







 







|




>
>




<
>
|
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
>
>
|
|
|
>
>
>
>
|
<
|
|
|
|
|
|
|
|
|
|
>
|
|
>
>
>
|
|
>
|
|
|
|
>
|
>


<
<
<

<


<
>







 







|







 







>







 







|











>
>
>
>







 







|
<











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>

>







 







|





|



<







 







>
>












>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



4
5
6
7
8
9
10


11
12
13




14
15
16
17
18
19
20
21
22
23
24
25
..
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
..
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
...
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
...
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341

342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
...
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
...
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
...
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713

714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
...
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796

797
798
799
800
801
802
803
804
805
806
807
808
809
...
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
...
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924

925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950


951
952
953
954
955
956
957
958
959
960
...
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983

984
985
986
987
988
989
990
...
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015

1016
1017
1018
1019
1020
1021
1022
1023

1024
1025
1026
1027
1028
1029
1030


1031
1032
1033
1034
1035
1036






1037
1038
1039
1040
1041
1042
1043
....
1052
1053
1054
1055
1056
1057
1058
1059



1060
1061
1062
1063
1064
1065
1066
....
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099



1100







1101
1102
1103
1104
1105

1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
....
1122
1123
1124
1125
1126
1127
1128


1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167

1168
1169
1170
1171
1172
1173
1174





1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189

1190
1191
1192
1193
1194
1195

1196
1197
1198

1199
1200
1201





1202
1203

1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
....
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
....
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
....
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423

1424
1425
1426
1427


1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441

1442
1443
1444

1445
1446

1447
1448
1449
1450
1451
1452

1453
1454
1455
1456
1457
1458
1459


1460
1461
1462
1463
1464
1465


1466
1467

1468
1469

1470
1471

1472
1473


1474
1475
1476

1477
1478
1479

1480
1481



























1482
1483
1484
1485
1486

1487


1488
1489
1490
1491
1492
1493
1494
1495










1496
1497
1498

1499


1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538

1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570

1571
1572
1573
1574


1575
1576

























1577
1578
1579

1580


1581
1582
1583
1584
1585
1586

1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602

1603


1604
1605
1606
1607
1608
1609
1610
1611
1612

1613
1614
1615
1616
1617


1618
1619
1620
1621
1622

1623
1624
1625
1626




1627
1628
1629


1630
1631
1632
1633
1634


1635
1636
1637
1638
1639
1640
1641
1642
1643


1644
1645
1646
1647

1648
1649

1650
1651



1652













1653

1654
1655
1656

1657
1658
1659


1660
1661
1662
1663
1664
















































1665


1666
1667
1668
1669
1670
1671
1672
1673
1674
1675

1676


1677
1678
1679
1680







1681

1682
1683
1684
1685
1686
1687


1688
1689
1690
1691
1692
1693
1694
1695
1696

1697


1698
1699
1700
1701
1702
1703
1704
1705
1706

1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725

1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
....
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789


1790
1791
1792
1793
1794


1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808

1809
1810
1811
1812
1813
1814
1815
1816
1817


1818

1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855










1856
1857
1858
1859



























1860
1861
1862
1863
1864
1865

1866
1867


1868
1869


1870
1871
1872

1873

1874

1875
1876
1877
1878
1879
1880
1881

1882
1883
1884



1885
1886
1887
1888
1889
1890
1891
1892
1893
1894



1895
1896
1897
1898



1899
1900
1901

1902
1903
1904

1905
1906
1907
1908


1909
1910
1911





























1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922





1923


1924
1925
1926
1927

1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950

1951
1952
1953
1954
1955


1956
1957
1958
1959
1960
1961

1962
1963
1964

1965
1966
1967

1968
1969
1970
1971
1972
1973
1974
1975
1976
1977

1978
1979
1980
1981
1982
1983
1984
1985
1986
1987


1988
1989
1990


1991
1992




1993


1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008


2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024

2025
2026
2027
2028
2029
2030
2031


2032
2033
2034
2035
2036
2037
2038
2039
2040

2041
2042
2043
2044
2045
2046
2047
2048

2049
2050
2051
2052
2053
2054
2055
2056
2057
























2058
2059
2060
2061
2062
2063
2064

2065
2066
2067

2068

2069
2070

2071

2072

2073

2074


2075

2076


2077
2078
2079
2080
2081
2082
2083
2084
2085

2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
....
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221

2222
2223
2224
2225
2226
2227
2228
....
2313
2314
2315
2316
2317
2318
2319


























































































2320
2321
2322
2323
2324
2325
2326
....
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341

2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
....
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436

2437
2438
2439
2440
2441
2442
2443
2444





2445




2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470

2471
2472
2473
2474
2475
2476
2477
....
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538

2539
2540
2541
2542
2543
2544
2545
....
2567
2568
2569
2570
2571
2572
2573
2574























































































2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588

2589
2590
2591
2592
2593
2594
2595
....
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635

2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
....
2728
2729
2730
2731
2732
2733
2734


2735
2736
2737
2738
2739
2740
2741






2742
2743
2744
2745
2746
2747
2748
2749
2750

2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
....
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
....
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
....
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
....
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
....
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094






3095
3096
3097


3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
....
3149
3150
3151
3152
3153
3154
3155








3156
3157
3158
3159
3160
3161
3162
....
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
....
3214
3215
3216
3217
3218
3219
3220

3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
....
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
....
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
....
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362







3363
3364
3365
3366
3367
3368
3369
3370
3371
3372






3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416

3417






3418
3419

3420
3421
3422
3423
3424
3425
3426
3427
....
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
....
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
....
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539

3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567

3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595



3596

3597
3598

3599
3600
3601
3602
3603
3604
3605
3606
....
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
....
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
....
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
....
3690
3691
3692
3693
3694
3695
3696
3697

3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708




































































































3709
3710
3711
3712
3713
3714
3715
....
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
....
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840

3841
3842
3843
3844
3845
3846
3847
....
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
....
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
#	a Tcl extension.
#
# Copyright (c) 1999-2000 Ajuba Solutions.
# Copyright (c) 2002-2005 ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.



AC_PREREQ(2.57)





# Possible values for key variables defined:
#
# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem')
# TEA_PLATFORM        - windows unix
# TEA_TK_EXTENSION    - True if this is a Tk extension
#

#------------------------------------------------------------------------
# TEA_PATH_TCLCONFIG --
#
#	Locate the tclConfig.sh file and perform a sanity check on
#	the Tcl compile flags
................................................................................
#
#	Defines the following vars:
#		TCL_BIN_DIR	Full path to the directory containing
#				the tclConfig.sh file
#------------------------------------------------------------------------

AC_DEFUN([TEA_PATH_TCLCONFIG], [
    dnl TEA specific: Make sure we are initialized
    AC_REQUIRE([TEA_INIT])
    #
    # Ok, lets find the tcl configuration
    # First, look for one uninstalled.
    # the alternative search directory is invoked by --with-tcl
    #

    if test x"${no_tcl}" = x ; then
	# we reset no_tcl in case something fails here
	no_tcl=true
	AC_ARG_WITH(tcl,
	    AC_HELP_STRING([--with-tcl],
		[directory containing tcl configuration (tclConfig.sh)]),
	    with_tclconfig="${withval}")
	AC_MSG_CHECKING([for Tcl configuration])
	AC_CACHE_VAL(ac_cv_c_tclconfig,[

	    # First check to see if --with-tcl was specified.
	    if test x"${with_tclconfig}" != x ; then
		case "${with_tclconfig}" in
		    */tclConfig.sh )
			if test -f "${with_tclconfig}"; then
			    AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself])
			    with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`"
			fi ;;
		esac
		if test -f "${with_tclconfig}/tclConfig.sh" ; then
		    ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`"
		else
		    AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh])
		fi
	    fi

	    # then check for a private Tcl installation
	    if test x"${ac_cv_c_tclconfig}" = x ; then
................................................................................
			`ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \
			../../../tcl \
			`ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
		    if test "${TEA_PLATFORM}" = "windows" \
			    -a -f "$i/win/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
			break
		    fi
		    if test -f "$i/unix/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
			break
		    fi
		done
	    fi

	    # on Darwin, check in Framework installation locations
	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
			`ls -d /Library/Frameworks 2>/dev/null` \
			`ls -d /Network/Library/Frameworks 2>/dev/null` \
			`ls -d /System/Library/Frameworks 2>/dev/null` \
			`ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
			`ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
			`ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
			; do
		    if test -f "$i/Tcl.framework/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`"
			break
		    fi
		done
	    fi

	    # TEA specific: on Windows, check in common installation locations
	    if test "${TEA_PLATFORM}" = "windows" \
		-a x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/lib/tcl8.6 2>/dev/null` \
			`ls -d /usr/lib/tcl8.5 2>/dev/null` \
			`ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
			`ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi

	    # check in a few other private locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in \
			${srcdir}/../tcl \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do
		    if test "${TEA_PLATFORM}" = "windows" \
			    -a -f "$i/win/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i/win; pwd)`"
			break
		    fi
		    if test -f "$i/unix/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i/unix; pwd)`"
			break
		    fi
		done
	    fi
	])

	if test x"${ac_cv_c_tclconfig}" = x ; then
	    TCL_BIN_DIR="# no Tcl configs found"
	    AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh])

	else
	    no_tcl=
	    TCL_BIN_DIR="${ac_cv_c_tclconfig}"
	    AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh])
	fi
    fi
])

#------------------------------------------------------------------------
# TEA_PATH_TKCONFIG --
................................................................................

    if test x"${no_tk}" = x ; then
	# we reset no_tk in case something fails here
	no_tk=true
	AC_ARG_WITH(tk,
	    AC_HELP_STRING([--with-tk],
		[directory containing tk configuration (tkConfig.sh)]),
	    with_tkconfig="${withval}")
	AC_MSG_CHECKING([for Tk configuration])
	AC_CACHE_VAL(ac_cv_c_tkconfig,[

	    # First check to see if --with-tkconfig was specified.
	    if test x"${with_tkconfig}" != x ; then
		case "${with_tkconfig}" in
		    */tkConfig.sh )
			if test -f "${with_tkconfig}"; then
			    AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself])
			    with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`"
			fi ;;
		esac
		if test -f "${with_tkconfig}/tkConfig.sh" ; then
		    ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`"
		else
		    AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh])
		fi
	    fi

	    # then check for a private Tk library
	    if test x"${ac_cv_c_tkconfig}" = x ; then
................................................................................
			`ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \
			../../../tk \
			`ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
		    if test "${TEA_PLATFORM}" = "windows" \
			    -a -f "$i/win/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
			break
		    fi
		    if test -f "$i/unix/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
			break
		    fi
		done
	    fi

	    # on Darwin, check in Framework installation locations
	    if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ~/Library/Frameworks 2>/dev/null` \
			`ls -d /Library/Frameworks 2>/dev/null` \
			`ls -d /Network/Library/Frameworks 2>/dev/null` \
			`ls -d /System/Library/Frameworks 2>/dev/null` \
			`ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \
			`ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \
			`ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \
			; do
		    if test -f "$i/Tk.framework/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`"
			break
		    fi
		done
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/lib/tk8.6 2>/dev/null` \
			`ls -d /usr/lib/tk8.5 2>/dev/null` \
			`ls -d /usr/local/lib/tk8.6 2>/dev/null` \
			`ls -d /usr/local/lib/tk8.5 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \
			; do
		    if test -f "$i/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi

	    # TEA specific: on Windows, check in common installation locations
	    if test "${TEA_PLATFORM}" = "windows" \
		-a x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d C:/Tcl/lib 2>/dev/null` \
			`ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \
			; do
		    if test -f "$i/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi

	    # check in a few other private locations
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in \
			${srcdir}/../tk \
			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \
			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \
			`ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do
		    if test "${TEA_PLATFORM}" = "windows" \
			    -a -f "$i/win/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i/win; pwd)`"
			break
		    fi
		    if test -f "$i/unix/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i/unix; pwd)`"
			break
		    fi
		done
	    fi
	])

	if test x"${ac_cv_c_tkconfig}" = x ; then
	    TK_BIN_DIR="# no Tk configs found"
	    AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh])

	else
	    no_tk=
	    TK_BIN_DIR="${ac_cv_c_tkconfig}"
	    AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh])
	fi
    fi
])

#------------------------------------------------------------------------
# TEA_LOAD_TCLCONFIG --
#
#	Load the tclConfig.sh file
#
# Arguments:
#
#	Requires the following vars to be set:
#		TCL_BIN_DIR
#
# Results:
#
#	Substitutes the following vars:
#		TCL_BIN_DIR
#		TCL_SRC_DIR
#		TCL_LIB_FILE
#		TCL_ZIP_FILE
#		TCL_ZIPFS_SUPPORT
#------------------------------------------------------------------------

AC_DEFUN([TEA_LOAD_TCLCONFIG], [
    AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])

    if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
        AC_MSG_RESULT([loading])
................................................................................
    # If the TCL_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TCL_LIB_SPEC will be set to the value
    # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC
    # instead of TCL_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.
    if test -f "${TCL_BIN_DIR}/Makefile" ; then
        TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
        TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
        TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
    elif test "`uname -s`" = "Darwin"; then
	# If Tcl was built as a framework, attempt to use the libraries
	# from the framework at the given location so that linking works
	# against Tcl.framework installed in an arbitrary location.
	case ${TCL_DEFS} in
	    *TCL_FRAMEWORK*)
		if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then
		    for i in "`cd "${TCL_BIN_DIR}"; pwd`" \
			     "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do
			if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then
			    TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}"
			    break
			fi
		    done
		fi
		if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then
		    TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}"
		    TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"
		fi
		;;
	esac
    fi

    # eval is required to do the TCL_DBGX substitution
    eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
    eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
    eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\""
    eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\""

    AC_SUBST(TCL_VERSION)
    AC_SUBST(TCL_PATCH_LEVEL)
    AC_SUBST(TCL_BIN_DIR)
    AC_SUBST(TCL_SRC_DIR)

    AC_SUBST(TCL_LIB_FILE)
    AC_SUBST(TCL_LIB_FLAG)
    AC_SUBST(TCL_LIB_SPEC)

    AC_SUBST(TCL_STUB_LIB_FILE)
    AC_SUBST(TCL_STUB_LIB_FLAG)
    AC_SUBST(TCL_STUB_LIB_SPEC)

    AC_MSG_CHECKING([platform])
    hold_cc=$CC; CC="$TCL_CC"
    AC_TRY_COMPILE(,[
	    #ifdef _WIN32
		#error win32
	    #endif
	], [
	    TEA_PLATFORM="unix"
	    CYGPATH=echo
	], [
	    TEA_PLATFORM="windows"
	    AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)	]
    )
    CC=$hold_cc
    AC_MSG_RESULT($TEA_PLATFORM)

    # The BUILD_$pkg is to define the correct extern storage class
    # handling when making this package
    AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [],
	    [Building extension source?])
    # Do this here as we have fully defined TEA_PLATFORM now
    if test "${TEA_PLATFORM}" = "windows" ; then
	EXEEXT=".exe"
	CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp"
    fi

    # TEA specific:
    AC_SUBST(CLEANFILES)
    AC_SUBST(TCL_LIBS)
    AC_SUBST(TCL_DEFS)
    AC_SUBST(TCL_EXTRA_CFLAGS)
    AC_SUBST(TCL_LD_FLAGS)
    AC_SUBST(TCL_SHLIB_LD_LIBS)
])

#------------------------------------------------------------------------
# TEA_LOAD_TKCONFIG --
#
#	Load the tkConfig.sh file
#
# Arguments:
#
#	Requires the following vars to be set:
#		TK_BIN_DIR
#
# Results:
#
#	Sets the following vars that should be in tkConfig.sh:
#		TK_BIN_DIR
................................................................................
    # If the TK_BIN_DIR is the build directory (not the install directory),
    # then set the common variable name to the value of the build variables.
    # For example, the variable TK_LIB_SPEC will be set to the value
    # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC
    # instead of TK_BUILD_LIB_SPEC since it will work with both an
    # installed and uninstalled version of Tcl.
    if test -f "${TK_BIN_DIR}/Makefile" ; then
        TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
        TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
        TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
    elif test "`uname -s`" = "Darwin"; then
	# If Tk was built as a framework, attempt to use the libraries
	# from the framework at the given location so that linking works
	# against Tk.framework installed in an arbitrary location.
	case ${TK_DEFS} in
	    *TK_FRAMEWORK*)
		if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then
		    for i in "`cd "${TK_BIN_DIR}"; pwd`" \
			     "`cd "${TK_BIN_DIR}"/../..; pwd`"; do
			if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then
			    TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}"
			    break
			fi
		    done
		fi
		if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then
		    TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}"  | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}"
		    TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"
		fi
		;;
	esac
    fi

    # eval is required to do the TK_DBGX substitution
    eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\""
    eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\""
    eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\""
    eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\""

    # TEA specific: Ensure windowingsystem is defined
    if test "${TEA_PLATFORM}" = "unix" ; then
	case ${TK_DEFS} in
	    *MAC_OSX_TK*)
		AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?])
		TEA_WINDOWINGSYSTEM="aqua"
		;;
	    *)
................................................................................
    AC_SUBST(TK_LIB_FLAG)
    AC_SUBST(TK_LIB_SPEC)

    AC_SUBST(TK_STUB_LIB_FILE)
    AC_SUBST(TK_STUB_LIB_FLAG)
    AC_SUBST(TK_STUB_LIB_SPEC)

    # TEA specific:
    AC_SUBST(TK_LIBS)
    AC_SUBST(TK_XINCLUDES)
])

#------------------------------------------------------------------------
# TEA_PROG_TCLSH
#	Determine the fully qualified path name of the tclsh executable
#	in the Tcl build directory or the tclsh installed in a bin
#	directory. This macro will correctly determine the name
#	of the tclsh executable even if tclsh has not yet been
#	built in the build directory. The tclsh found is always
#	associated with a tclConfig.sh file. This tclsh should be used
#	only for running extension test cases. It should never be
#	or generation of files (like pkgIndex.tcl) at build time.
#
# Arguments:
#	none
#
# Results:
#	Substitutes the following vars:
#		TCLSH_PROG
#------------------------------------------------------------------------

AC_DEFUN([TEA_PROG_TCLSH], [
    AC_MSG_CHECKING([for tclsh])
    if test -f "${TCL_BIN_DIR}/Makefile" ; then
        # tclConfig.sh is in Tcl build directory
        if test "${TEA_PLATFORM}" = "windows"; then
          if test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" ; then
            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}" ; then
            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}s${EXEEXT}"
          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}" ; then
            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}t${EXEEXT}"
          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}" ; then
            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}st${EXEEXT}"
          fi
        else
            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
        fi
    else
        # tclConfig.sh is in install location
        if test "${TEA_PLATFORM}" = "windows"; then
            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}"
        else
            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}"
        fi
        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
        for i in $list ; do
            if test -f "$i/${TCLSH_PROG}" ; then
                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
                break
            fi
        done
        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
    fi
    AC_MSG_RESULT([${TCLSH_PROG}])
    AC_SUBST(TCLSH_PROG)
])

#------------------------------------------------------------------------
# TEA_PROG_WISH
#	Determine the fully qualified path name of the wish executable
#	in the Tk build directory or the wish installed in a bin
#	directory. This macro will correctly determine the name
#	of the wish executable even if wish has not yet been
#	built in the build directory. The wish found is always
#	associated with a tkConfig.sh file. This wish should be used
#	only for running extension test cases. It should never be
#	or generation of files (like pkgIndex.tcl) at build time.
#
# Arguments:
#	none
#
# Results:
#	Substitutes the following vars:
#		WISH_PROG
#------------------------------------------------------------------------

AC_DEFUN([TEA_PROG_WISH], [
    AC_MSG_CHECKING([for wish])
    if test -f "${TK_BIN_DIR}/Makefile" ; then
        # tkConfig.sh is in Tk build directory
        if test "${TEA_PLATFORM}" = "windows"; then
          if test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" ; then
            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
          elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}s${EXEEXT}" ; then
            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}$s{EXEEXT}"
          elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}t${EXEEXT}" ; then
            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}t${EXEEXT}"
          elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}st${EXEEXT}" ; then
            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}st${EXEEXT}"
          fi
        else
            WISH_PROG="${TK_BIN_DIR}/wish"
        fi
    else
        # tkConfig.sh is in install location
        if test "${TEA_PLATFORM}" = "windows"; then
            WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}"
        else
            WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}"
        fi
        list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
              `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
              `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
        for i in $list ; do
            if test -f "$i/${WISH_PROG}" ; then
                REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
                break
            fi
        done
        WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
    fi
    AC_MSG_RESULT([${WISH_PROG}])
    AC_SUBST(WISH_PROG)
])

#------------------------------------------------------------------------
# TEA_ENABLE_SHARED --
#
#	Allows the building of shared libraries
#
# Arguments:
#	none
#
# Results:
#
#	Adds the following arguments to configure:
#		--enable-shared=yes|no
#		--enable-stubs=yes|no
#
#	Defines the following vars:
#		STATIC_BUILD	Used for building import/export libraries
#				on Windows.
#
#	Sets the following vars:
#		SHARED_BUILD	Value of 1 or 0
#               STUBS_BUILD     Value if 1 or 0
#               USE_TCL_STUBS   Value true: if SHARED_BUILD or --enable-stubs
#               USE_TCLOO_STUBS Value true: if SHARED_BUILD or --enable-stubs
#               USE_TK_STUBS    Value true: if SHARED_BUILD or --enable-stubs
#                                AND TEA_WINDOWING_SYSTEM != ""
#------------------------------------------------------------------------

AC_DEFUN([TEA_ENABLE_SHARED], [
    AC_MSG_CHECKING([how to build libraries])
    AC_ARG_ENABLE(shared,
	AC_HELP_STRING([--enable-shared],
	    [build and link with shared libraries (default: on)]),
	[shared_ok=$enableval], [shared_ok=yes])

    if test "${enable_shared+set}" = set; then
	enableval="$enable_shared"
	shared_ok=$enableval
    else
	shared_ok=yes
    fi

    AC_ARG_ENABLE(stubs,
	AC_HELP_STRING([--enable-stubs],
	    [build and link with stub libraries. Always true for shared builds (default: on)]),
	[stubs_ok=$enableval], [stubs_ok=yes])

    if test "${enable_stubs+set}" = set; then
	enableval="$enable_stubs"
	stubs_ok=$enableval
    else
	stubs_ok=yes
    fi

    # Stubs are always enabled for shared builds
    if test "$shared_ok" = "yes" ; then
	AC_MSG_RESULT([shared])
	SHARED_BUILD=1
        STUBS_BUILD=1
    else
	AC_MSG_RESULT([static])
	SHARED_BUILD=0
	AC_DEFINE(STATIC_BUILD, 1, [This a static build])
        if test "$stubs_ok" = "yes" ; then
          STUBS_BUILD=1
        else
          STUBS_BUILD=0
        fi
    fi
    if test "${STUBS_BUILD}" = "1" ; then
      AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
      AC_DEFINE(USE_TCLOO_STUBS, 1, [Use TclOO stubs])
      if test "${TEA_WINDOWINGSYSTEM}" != ""; then
        AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
      fi
    fi

    AC_SUBST(SHARED_BUILD)
    AC_SUBST(STUBS_BUILD)
])

#------------------------------------------------------------------------
# TEA_ENABLE_THREADS --
#
#	Specify if thread support should be enabled.  If "yes" is specified
#	as an arg (optional), threads are enabled by default, "no" means
................................................................................
#
#	Note that it is legal to have a thread enabled extension run in a
#	threaded or non-threaded Tcl core, but a non-threaded extension may
#	only run in a non-threaded Tcl core.
#
# Arguments:
#	none
#
# Results:
#
#	Adds the following arguments to configure:
#		--enable-threads
#
#	Sets the following vars:
#		THREADS_LIBS	Thread library(s)
#
#	Defines the following vars:
#		TCL_THREADS
#		_REENTRANT
#		_THREAD_SAFE

#------------------------------------------------------------------------

AC_DEFUN([TEA_ENABLE_THREADS], [
    AC_ARG_ENABLE(threads,
	AC_HELP_STRING([--enable-threads],
	    [build with threads (default: on)]),
	[tcl_ok=$enableval], [tcl_ok=yes])

    if test "${enable_threads+set}" = set; then
	enableval="$enable_threads"
	tcl_ok=$enableval
    else
	tcl_ok=yes
................................................................................
    fi

    if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then
	TCL_THREADS=1

	if test "${TEA_PLATFORM}" != "windows" ; then
	    # We are always OK on Windows, so check what this platform wants:

	    # USE_THREAD_ALLOC tells us to try the special thread-based
	    # allocator that significantly reduces lock contention
	    AC_DEFINE(USE_THREAD_ALLOC, 1,
		[Do we want to use the threaded memory allocator?])
	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
	    if test "`uname -s`" = "SunOS" ; then
		AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
................................................................................
# TEA_ENABLE_SYMBOLS --
#
#	Specify if debugging symbols should be used.
#	Memory (TCL_MEM_DEBUG) debugging can also be enabled.
#
# Arguments:
#	none
#
#	TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives
#	the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted.
#	Requires the following vars to be set in the Makefile:
#		CFLAGS_DEFAULT
#		LDFLAGS_DEFAULT
#
# Results:
#
#	Adds the following arguments to configure:
#		--enable-symbols
#
#	Defines the following vars:
#		CFLAGS_DEFAULT	Sets to $(CFLAGS_DEBUG) if true
#				Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false
#		LDFLAGS_DEFAULT	Sets to $(LDFLAGS_DEBUG) if true
#				Sets to $(LDFLAGS_OPTIMIZE) if false
#		DBGX		Formerly used as debug library extension;
#				always blank now.

#------------------------------------------------------------------------

AC_DEFUN([TEA_ENABLE_SYMBOLS], [
    dnl TEA specific: Make sure we are initialized
    AC_REQUIRE([TEA_CONFIG_CFLAGS])
    AC_MSG_CHECKING([for build with symbols])
    AC_ARG_ENABLE(symbols,
	AC_HELP_STRING([--enable-symbols],
	    [build with debugging symbols (default: off)]),
	[tcl_ok=$enableval], [tcl_ok=no])
    DBGX=""
    if test "$tcl_ok" = "no"; then
	CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG"
	LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}"
	AC_MSG_RESULT([no])
    else
	CFLAGS_DEFAULT="${CFLAGS_DEBUG}"
	LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}"
	if test "$tcl_ok" = "yes"; then
	    AC_MSG_RESULT([yes (standard debugging)])
	fi
    fi
    # TEA specific:
    if test "${TEA_PLATFORM}" != "windows" ; then
	LDFLAGS_DEFAULT="${LDFLAGS}"
    fi


    AC_SUBST(CFLAGS_DEFAULT)
    AC_SUBST(LDFLAGS_DEFAULT)
    AC_SUBST(TCL_DBGX)

    if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
	AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
    fi

    if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
	if test "$tcl_ok" = "all"; then
................................................................................
# TEA_ENABLE_LANGINFO --
#
#	Allows use of modern nl_langinfo check for better l10n.
#	This is only relevant for Unix.
#
# Arguments:
#	none
#
# Results:
#
#	Adds the following arguments to configure:
#		--enable-langinfo=yes|no (default is yes)
#
#	Defines the following vars:
#		HAVE_LANGINFO	Triggers use of nl_langinfo if defined.

#------------------------------------------------------------------------

AC_DEFUN([TEA_ENABLE_LANGINFO], [
    AC_ARG_ENABLE(langinfo,
	AC_HELP_STRING([--enable-langinfo],
	    [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]),
	[langinfo_ok=$enableval], [langinfo_ok=yes])
................................................................................
	AC_CACHE_VAL(tcl_cv_langinfo_h, [
	    AC_TRY_COMPILE([#include <langinfo.h>], [nl_langinfo(CODESET);],
		    [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])])
	AC_MSG_RESULT([$tcl_cv_langinfo_h])
	if test $tcl_cv_langinfo_h = yes; then
	    AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?])
	fi
    else
	AC_MSG_RESULT([$langinfo_ok])
    fi
])

#--------------------------------------------------------------------
# TEA_CONFIG_SYSTEM
#
#	Determine what the system is (some things cannot be easily checked
#	on a feature-driven basis, alas). This can usually be done via the
#	"uname" command.

#
# Arguments:
#	none
#
# Results:
#	Defines the following var:
#
#	system -	System/platform/version identification code.

#--------------------------------------------------------------------

AC_DEFUN([TEA_CONFIG_SYSTEM], [
    AC_CACHE_CHECK([system version], tcl_cv_sys_version, [
	# TEA specific:
	if test "${TEA_PLATFORM}" = "windows" ; then
	    tcl_cv_sys_version=windows


	else
	    tcl_cv_sys_version=`uname -s`-`uname -r`
	    if test "$?" -ne 0 ; then
		AC_MSG_WARN([can't find uname command])
		tcl_cv_sys_version=unknown
	    else






		if test "`uname -s`" = "AIX" ; then
		    tcl_cv_sys_version=AIX-`uname -v`.`uname -r`
		fi
	    fi
	fi
    ])
    system=$tcl_cv_sys_version
................................................................................
# Arguments:
#	none
#
# Results:
#
#	Defines and substitutes the following vars:
#
#	DL_OBJS, DL_LIBS - removed for TEA, only needed by core.



#       LDFLAGS -      Flags to pass to the compiler when linking object
#                       files into an executable application binary such
#                       as tclsh.
#       LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib",
#                       that tell the run-time dynamic linker where to look
#                       for shared libraries such as libtcl.so.  Depends on
#                       the variable LIB_RUNTIME_DIR in the Makefile. Could
................................................................................
#                       of a shared library (may request position-independent
#                       code, among other things).
#       SHLIB_LD -      Base command to use for combining object files
#                       into a shared library.
#       SHLIB_LD_LIBS - Dependent libraries for the linker to scan when
#                       creating shared libraries.  This symbol typically
#                       goes at the end of the "ld" commands that build
#                       shared libraries. The value of the symbol defaults to
#                       "${LIBS}" if all of the dependent libraries should
#                       be specified when creating a shared library.  If
#                       dependent libraries should not be specified (as on
#                       SunOS 4.x, where they cause the link to fail, or in
#                       general if Tcl and Tk aren't themselves shared
#                       libraries), then this symbol has an empty string
#                       as its value.
#       SHLIB_SUFFIX -  Suffix to use for the names of dynamically loadable
#                       extensions.  An empty string means we don't know how
#                       to use shared libraries on this platform.
#       LIB_SUFFIX -    Specifies everything that comes after the "libfoo"
#                       in a static or shared library name, using the $PACKAGE_VERSION variable
#                       to put the version in the right place.  This is used
#                       by platforms that need non-standard library names.
#                       Examples:  ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs
#                       to have a version after the .so, and ${PACKAGE_VERSION}.a
#                       on AIX, since a shared library needs to have
#                       a .a extension whereas shared objects for loadable
#                       extensions have a .so extension.  Defaults to



#                       ${PACKAGE_VERSION}${SHLIB_SUFFIX}.







#	CFLAGS_DEBUG -
#			Flags used when running the compiler in debug mode
#	CFLAGS_OPTIMIZE -
#			Flags used when running the compiler in optimize mode
#	CFLAGS -	Additional CFLAGS added as necessary (usually 64-bit)

#--------------------------------------------------------------------

AC_DEFUN([TEA_CONFIG_CFLAGS], [
    dnl TEA specific: Make sure we are initialized
    AC_REQUIRE([TEA_INIT])

    # Step 0.a: Enable 64 bit support?

    AC_MSG_CHECKING([if 64bit support is requested])
    AC_ARG_ENABLE(64bit,
	AC_HELP_STRING([--enable-64bit],
................................................................................

    AC_MSG_CHECKING([if 64bit Sparc VIS support is requested])
    AC_ARG_ENABLE(64bit-vis,
	AC_HELP_STRING([--enable-64bit-vis],
	    [enable 64bit Sparc VIS support (default: off)]),
	[do64bitVIS=$enableval], [do64bitVIS=no])
    AC_MSG_RESULT([$do64bitVIS])


    # Force 64bit on with VIS
    AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes])

    # Step 0.c: Check if visibility support is available. Do this here so
    # that platform specific alternatives can be used below if this fails.

    AC_CACHE_CHECK([if compiler supports visibility "hidden"],
	tcl_cv_cc_visibility_hidden, [
	hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
	AC_TRY_LINK([
	    extern __attribute__((__visibility__("hidden"))) void f(void);
	    void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes,
	    tcl_cv_cc_visibility_hidden=no)
	CFLAGS=$hold_cflags])
    AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [
	AC_DEFINE(MODULE_SCOPE,
	    [extern __attribute__((__visibility__("hidden")))],
	    [Compiler support for module scope symbols])
	AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols])
    ])

    # Step 0.d: Disable -rpath support?

    AC_MSG_CHECKING([if rpath support is requested])
    AC_ARG_ENABLE(rpath,
	AC_HELP_STRING([--disable-rpath],
	    [disable rpath support (default: on)]),
	[doRpath=$enableval], [doRpath=yes])
    AC_MSG_RESULT([$doRpath])

    # TEA specific: Cross-compiling options for Windows/CE builds?

    AS_IF([test "${TEA_PLATFORM}" = windows], [
	AC_MSG_CHECKING([if Windows/CE build is requested])
	AC_ARG_ENABLE(wince,
	    AC_HELP_STRING([--enable-wince],
		[enable Win/CE support (where applicable)]),
	    [doWince=$enableval], [doWince=no])
	AC_MSG_RESULT([$doWince])

    ])

    # Set the variable "system" to hold the name and version number
    # for the system.

    TEA_CONFIG_SYSTEM






    # Require ranlib early so we can override it in special cases below.

    AC_REQUIRE([AC_PROG_RANLIB])

    # Set configuration options based on system name and version.
    # This is similar to Tcl's unix/tcl.m4 except that we've added a
    # "windows" case and removed some core-only vars.

    do64bit_ok=no
    # default to '{$LIBS}' and set to "" on per-platform necessary basis
    SHLIB_LD_LIBS='${LIBS}'
    # When ld needs options to work in 64-bit mode, put them in
    # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load]
    # is disabled by the user. [Bug 1016796]
    LDFLAGS_ARCH=""

    UNSHARED_LIB_SUFFIX=""
    # TEA specific: use PACKAGE_VERSION instead of VERSION
    TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`'
    ECHO_VERSION='`echo ${PACKAGE_VERSION}`'
    TCL_LIB_VERSIONS_OK=ok
    CFLAGS_DEBUG=-g

    AS_IF([test "$GCC" = yes], [
	CFLAGS_OPTIMIZE=-O2
	CFLAGS_WARNING="-Wall"

    ], [
	CFLAGS_OPTIMIZE=-O
	CFLAGS_WARNING=""





    ])
    AC_CHECK_TOOL(AR, ar)

    STLIB_LD='${AR} cr'
    LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
    AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"])
    case $system in
	# TEA specific:
	windows)
	    # This is a 2-stage check to make sure we have the 64-bit SDK
	    # We have to know where the SDK is installed.
	    # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs
	    # MACHINE is IX86 for LINK, but this is used by the manifest,
	    # which requires x86|amd64|ia64.
	    MACHINE="X86"
................................................................................
			PATH64="${MSSDK}/Bin/Win64/x86/AMD64"
			;;
		    ia64)
			MACHINE="IA64"
			PATH64="${MSSDK}/Bin/Win64"
			;;
		esac
		if test "$GCC" != "yes" -a ! -d "${PATH64}" ; then
		    AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode])
		    AC_MSG_WARN([Ensure latest Platform SDK is installed])
		    do64bit="no"
		else
		    AC_MSG_RESULT([   Using 64-bit $MACHINE mode])
		    do64bit_ok="yes"
		fi
................................................................................

	    if test "$GCC" != "yes" ; then
	        if test "${SHARED_BUILD}" = "0" ; then
		    runtime=-MT
	        else
		    runtime=-MD
	        fi
	        case "x`echo \${VisualStudioVersion}`" in
	            x1[[4-9]]*)
		        lflags="${lflags} -nodefaultlib:libucrt.lib"
		        TEA_ADD_LIBS([ucrt.lib])
	            ;;
	            *)
	            ;;
	        esac

                if test "$do64bit" != "no" ; then
		    # All this magic is necessary for the Win64 SDK RC1 - hobbs
		    CC="\"${PATH64}/cl.exe\""
		    CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\""
		    RC="\"${MSSDK}/bin/rc.exe\""
		    lflags="${lflags} -nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\""
		    LINKBIN="\"${PATH64}/link.exe\""
		    CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d"
		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
		    # Avoid 'unresolved external symbol __security_cookie'
		    # errors, c.f. http://support.microsoft.com/?id=894573
		    TEA_ADD_LIBS([bufferoverflowU.lib])
		elif test "$doWince" != "no" ; then
................................................................................
			AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i)
		    done
		    AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version])
		    AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version])
		    CFLAGS_DEBUG="-nologo -Zi -Od"
		    CFLAGS_OPTIMIZE="-nologo -Ox"
		    lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'`
		    lflags="${lflags} -MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo"
		    LINKBIN="\"${CEBINROOT}/link.exe\""
		    AC_SUBST(CELIB_DIR)
		else
		    RC="rc"
		    lflags="${lflags} -nologo"
		    LINKBIN="link"
		    CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d"
		    CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}"
		fi
	    fi

	    if test "$GCC" = "yes"; then
		# mingw gcc mode
		AC_CHECK_TOOL(RC, windres)
		CFLAGS_DEBUG="-g"
		CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"
		SHLIB_LD='${CC} -shared'
		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
		LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}"
		LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}"

		AC_CACHE_CHECK(for cross-compile version of gcc,
			ac_cv_cross,
			AC_TRY_COMPILE([
			    #ifdef _WIN32
				#error cross-compiler
			    #endif
			], [],
			ac_cv_cross=yes,
			ac_cv_cross=no)
		      )
		      if test "$ac_cv_cross" = "yes"; then
			case "$do64bit" in
			    amd64|x64|yes)
				CC="x86_64-w64-mingw32-gcc"
				LD="x86_64-w64-mingw32-ld"
				AR="x86_64-w64-mingw32-ar"
				RANLIB="x86_64-w64-mingw32-ranlib"
				RC="x86_64-w64-mingw32-windres"
			    ;;
			    *)
				CC="i686-w64-mingw32-gcc"
				LD="i686-w64-mingw32-ld"
				AR="i686-w64-mingw32-ar"
				RANLIB="i686-w64-mingw32-ranlib"
				RC="i686-w64-mingw32-windres"
			    ;;
			esac
		fi

	    else
		SHLIB_LD="${LINKBIN} -dll ${lflags}"
		# link -lib only works when -lib is the first arg
		STLIB_LD="${LINKBIN} -lib ${lflags}"
		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib'
		PATHTYPE=-w
		# For information on what debugtype is most useful, see:
		# http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
		# and also
		# http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx
		# This essentially turns it all on.
		LDFLAGS_DEBUG="-debug -debugtype:cv"
		LDFLAGS_OPTIMIZE="-release"
		if test "$doWince" != "no" ; then
		    LDFLAGS_CONSOLE="-link ${lflags}"
		    LDFLAGS_WINDOW=${LDFLAGS_CONSOLE}
		else
		    LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}"
		    LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}"
		fi
	    fi


	    SHLIB_SUFFIX=".dll"
	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll'

	    TCL_LIB_VERSIONS_OK=nodots


    	    ;;
	AIX-*)
	    AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [
		# AIX requires the _r compiler when gcc isn't being used
		case "${CC}" in
		    *_r|*_r\ *)
			# ok ...
			;;
		    *)
			# Make sure only first arg gets _r
		    	CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'`
			;;
		esac
		AC_MSG_RESULT([Using $CC for compiling with threads])

	    ])
	    LIBS="$LIBS -lc"
	    SHLIB_CFLAGS=""

	    SHLIB_SUFFIX=".so"


	    LD_LIBRARY_PATH_VAR="LIBPATH"

	    # Check to enable 64-bit flags for compiler/linker
	    AS_IF([test "$do64bit" = yes], [
		AS_IF([test "$GCC" = yes], [
		    AC_MSG_WARN([64bit mode not supported with GCC on $system])

		], [
		    do64bit_ok=yes
		    CFLAGS="$CFLAGS -q64"
		    LDFLAGS_ARCH="-q64"
		    RANLIB="${RANLIB} -X64"
		    AR="${AR} -X64"
		    SHLIB_LD_FLAGS="-b64"


		])
	    ])

	    AS_IF([test "`uname -m`" = ia64], [
		# AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
		SHLIB_LD="/usr/ccs/bin/ld -G -z text"


		AS_IF([test "$GCC" = yes], [
		    CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'

		], [
		    CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'

		])
		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'

	    ], [
		AS_IF([test "$GCC" = yes], [


		    SHLIB_LD='${CC} -shared -Wl,-bexpall'
		], [
		    SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry"

		    LDFLAGS="$LDFLAGS -brtl"
		])
		SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"

		CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}



























	    ])
	    ;;
	BeOS*)
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD='${CC} -nostart'

	    SHLIB_SUFFIX=".so"



	    #-----------------------------------------------------------
	    # Check for inet_ntoa in -lbind, for BeOS (which also needs
	    # -lsocket, even if the network functions are in -lnet which
	    # is always linked to, for compatibility.
	    #-----------------------------------------------------------
	    AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"])
	    ;;










	BSD/OS-4.*)
	    SHLIB_CFLAGS="-export-dynamic -fPIC"
	    SHLIB_LD='${CC} -shared'

	    SHLIB_SUFFIX=".so"


	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	CYGWIN_*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD='${CC} -shared'
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$[@].a"
	    SHLIB_SUFFIX=".dll"
	    EXEEXT=".exe"
	    do64bit_ok=yes
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	Haiku*)
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_SUFFIX=".so"
	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
	    AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
	    ;;
	HP-UX-*.11.*)
	    # Use updated header definitions where possible
	    AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
	    # TEA specific: Needed by Tcl, but not most extensions
	    #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?])
	    #LIBS="$LIBS -lxnet"               # Use the XOPEN network library

	    AS_IF([test "`uname -m`" = ia64], [
		SHLIB_SUFFIX=".so"
		# Use newer C++ library for C++ extensions
		#if test "$GCC" != "yes" ; then
		#   CPPFLAGS="-AA"
		#fi
	    ], [
		SHLIB_SUFFIX=".sl"
	    ])
	    AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no)
	    AS_IF([test "$tcl_ok" = yes], [

		LDFLAGS="$LDFLAGS -Wl,-E"
		CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.'
		LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
		LD_LIBRARY_PATH_VAR="SHLIB_PATH"
	    ])
	    AS_IF([test "$GCC" = yes], [
		SHLIB_LD='${CC} -shared'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    ], [
		CFLAGS="$CFLAGS -z"
		# Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
		#CFLAGS="$CFLAGS +DAportable"
		SHLIB_CFLAGS="+z"
		SHLIB_LD="ld -b"
	    ])

	    # Check to enable 64-bit flags for compiler/linker
	    AS_IF([test "$do64bit" = "yes"], [
		AS_IF([test "$GCC" = yes], [
		    case `${CC} -dumpmachine` in
			hppa64*)
			    # 64-bit gcc in use.  Fix flags for GNU ld.
			    do64bit_ok=yes
			    SHLIB_LD='${CC} -shared'
			    AS_IF([test $doRpath = yes], [
				CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
			    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
			    ;;
			*)
			    AC_MSG_WARN([64bit mode not supported with GCC on $system])
			    ;;
		    esac

		], [
		    do64bit_ok=yes
		    CFLAGS="$CFLAGS +DD64"
		    LDFLAGS_ARCH="+DD64"


		])
	    ]) ;;

























	IRIX-6.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"

	    SHLIB_SUFFIX=".so"


	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])
	    AS_IF([test "$GCC" = yes], [
		CFLAGS="$CFLAGS -mabi=n32"
		LDFLAGS="$LDFLAGS -mabi=n32"

	    ], [
		case $system in
		    IRIX-6.3)
			# Use to build 6.2 compatible binaries on 6.3.
			CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS"
			;;
		    *)
			CFLAGS="$CFLAGS -n32"
			;;
		esac
		LDFLAGS="$LDFLAGS -n32"
	    ])
	    ;;
	IRIX64-6.*)
	    SHLIB_CFLAGS=""
	    SHLIB_LD="ld -n32 -shared -rdata_shared"

	    SHLIB_SUFFIX=".so"


	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])

	    # Check to enable 64-bit flags for compiler/linker

	    AS_IF([test "$do64bit" = yes], [
	        AS_IF([test "$GCC" = yes], [
	            AC_MSG_WARN([64bit mode not supported by gcc])

	        ], [
	            do64bit_ok=yes
	            SHLIB_LD="ld -64 -shared -rdata_shared"
	            CFLAGS="$CFLAGS -64"
	            LDFLAGS_ARCH="-64"


	        ])
	    ])
	    ;;
	Linux*|GNU*|NetBSD-Debian)
	    SHLIB_CFLAGS="-fPIC"

	    SHLIB_SUFFIX=".so"

	    # TEA specific:
	    CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer"





	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS_DEFAULT} -shared'


	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])


	    AS_IF([test $do64bit = yes], [
		AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [
		    hold_cflags=$CFLAGS
		    CFLAGS="$CFLAGS -m64"
		    AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no)
		    CFLAGS=$hold_cflags])
		AS_IF([test $tcl_cv_cc_m64 = yes], [
		    CFLAGS="$CFLAGS -m64"
		    do64bit_ok=yes


		])
	   ])

	    # The combo of gcc + glibc has a bug related to inlining of

	    # functions like strtod(). The -fno-builtin flag should address
	    # this problem but it does not work. The -fno-inline flag is kind

	    # of overkill but it works. Disable inlining only when one of the
	    # files in compat/*.c is being linked in.

















	    AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"])

	    ;;
	Lynx*)
	    SHLIB_CFLAGS="-fPIC"

	    SHLIB_SUFFIX=".so"
	    CFLAGS_OPTIMIZE=-02
	    SHLIB_LD='${CC} -shared'


	    LD_FLAGS="-Wl,--export-dynamic"
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    ;;
















































	OpenBSD-*)


	    arch=`arch -s`
	    case "$arch" in
	    alpha|sparc64)
		SHLIB_CFLAGS="-fPIC"
		;;
	    *)
		SHLIB_CFLAGS="-fpic"
		;;
	    esac
	    SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'

	    SHLIB_SUFFIX=".so"


	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'







	    LDFLAGS="-Wl,-export-dynamic"

	    CFLAGS_OPTIMIZE="-O2"
	    AS_IF([test "${TCL_THREADS}" = "1"], [
		# On OpenBSD:	Compile with -pthread
		#		Don't link with -lpthread
		LIBS=`echo $LIBS | sed s/-lpthread//`
		CFLAGS="$CFLAGS -pthread"


	    ])
	    # OpenBSD doesn't do version numbers with dots.
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	NetBSD-*)
	    # NetBSD has ELF and can use 'cc -shared' to build shared libs
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'

	    SHLIB_SUFFIX=".so"


	    LDFLAGS="$LDFLAGS -export-dynamic"
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    AS_IF([test "${TCL_THREADS}" = "1"], [
		# The -pthread needs to go in the CFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS -pthread"
	    	LDFLAGS="$LDFLAGS -pthread"

	    ])
	    ;;
	FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$[@]"
	    SHLIB_SUFFIX=".so"
	    LDFLAGS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    AS_IF([test "${TCL_THREADS}" = "1"], [
		# The -pthread needs to go in the LDFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
		LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
	    case $system in
	    FreeBSD-3.*)

		# Version numbers are dot-stripped by system policy.
		TCL_TRIM_DOTS=`echo ${PACKAGE_VERSION} | tr -d .`
		UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1'
		TCL_LIB_VERSIONS_OK=nodots
		;;
	    esac
	    ;;
	Darwin-*)
	    CFLAGS_OPTIMIZE="-Os"
	    SHLIB_CFLAGS="-fno-common"
	    # To avoid discrepancies between what headers configure sees during
................................................................................
	    # -mmacosx-version-min flags from CFLAGS to CPPFLAGS:
	    CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`"
	    CFLAGS="`echo " ${CFLAGS}" | \
		awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
		if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`"
	    AS_IF([test $do64bit = yes], [
		case `arch` in
		    ppc)
			AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag],
				tcl_cv_cc_arch_ppc64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes,
				    tcl_cv_cc_arch_ppc64=no)
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [
			    CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
			    do64bit_ok=yes
			]);;
		    i386)
			AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag],
				tcl_cv_cc_arch_x86_64, [
			    hold_cflags=$CFLAGS
			    CFLAGS="$CFLAGS -arch x86_64"
			    AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes,
				    tcl_cv_cc_arch_x86_64=no)
			    CFLAGS=$hold_cflags])
			AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [
			    CFLAGS="$CFLAGS -arch x86_64"
			    do64bit_ok=yes
			]);;
		    *)
			AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);;
		esac
	    ], [
		# Check for combined 32-bit and 64-bit fat build
		AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
		    && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
		    fat_32_64=yes])
	    ])
	    # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
	    SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}'
	    AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
		AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no)
		LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_single_module = yes], [
		SHLIB_LD="${SHLIB_LD} -Wl,-single_module"


	    ])
	    # TEA specific: link shlib with current and compatibility version flags
	    vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d`
	    SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}"
	    SHLIB_SUFFIX=".dylib"


	    # Don't use -prebind when building for Mac OS X 10.4 or later only:
	    AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \
		"`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [
		LDFLAGS="$LDFLAGS -prebind"])
	    LDFLAGS="$LDFLAGS -headerpad_max_install_names"
	    AC_CACHE_CHECK([if ld accepts -search_paths_first flag],
		    tcl_cv_ld_search_paths_first, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
		AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes,
			tcl_cv_ld_search_paths_first=no)
		LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_search_paths_first = yes], [
		LDFLAGS="$LDFLAGS -Wl,-search_paths_first"

	    ])
	    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
		AC_DEFINE(MODULE_SCOPE, [__private_extern__],
		    [Compiler support for module scope symbols])
		tcl_cv_cc_visibility_hidden=yes
	    ])
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"


	    # TEA specific: for combined 32 & 64 bit fat builds of Tk

	    # extensions, verify that 64-bit build is possible.
	    AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [
		AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [
		    AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
			done
			CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include"
			LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
			AC_TRY_LINK([#include <X11/Xlib.h>], [XrmInitialize();],
			    tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no)
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
			done])
		])
		AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [
		    AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
			done
			CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}"
			LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}"
			AC_TRY_LINK([#include <tk.h>], [Tk_InitStubs(NULL, "", 0);],
			    tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no)
			for v in CFLAGS CPPFLAGS LDFLAGS; do
			    eval $v'="$hold_'$v'"'
			done])
		])
		# remove 64-bit arch flags from CFLAGS et al. if configuration
		# does not support 64-bit.
		AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [
		    AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags])
		    for v in CFLAGS CPPFLAGS LDFLAGS; do
			eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
		    done])
	    ])
	    ;;










	OS/390-*)
	    CFLAGS_OPTIMIZE=""		# Optimizer is buggy
	    AC_DEFINE(_OE_SOCKETS, 1,	# needed in sys/socket.h
		[Should OS/390 do the right thing with sockets?])



























	    ;;
	OSF1-V*)
	    # Digital OSF/1
	    SHLIB_CFLAGS=""
	    AS_IF([test "$SHARED_BUILD" = 1], [
	        SHLIB_LD='ld -shared -expect_unresolved "*"'

	    ], [
	        SHLIB_LD='ld -non_shared -expect_unresolved "*"'


	    ])
	    SHLIB_SUFFIX=".so"


	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'])

	    AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [

		CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"])

	    # see pthread_intro(3) for pthread support on osf1, k.furukawa
	    AS_IF([test "${TCL_THREADS}" = 1], [
		CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
		CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
		LIBS=`echo $LIBS | sed s/-lpthreads//`
		AS_IF([test "$GCC" = yes], [
		    LIBS="$LIBS -lpthread -lmach -lexc"

		], [
		    CFLAGS="$CFLAGS -pthread"
		    LDFLAGS="$LDFLAGS -pthread"



		])
	    ])
	    ;;
	QNX-6*)
	    # QNX RTP
	    # This may work for all QNX, but it was only reported for v6.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"



	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	SCO_SV-3.2*)



	    AS_IF([test "$GCC" = yes], [
		SHLIB_CFLAGS="-fPIC -melf"
		LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"

	    ], [
		SHLIB_CFLAGS="-Kpic -belf"
		LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"

	    ])
	    SHLIB_LD="ld -G"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"


	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;





























	SunOS-5.[[0-6]])
	    # Careful to not let 5.10+ fall into this case

	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.

	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
		[Do we really want to follow the standard? Yes we do!])

	    SHLIB_CFLAGS="-KPIC"





	    SHLIB_SUFFIX=".so"


	    AS_IF([test "$GCC" = yes], [
		SHLIB_LD='${CC} -shared'
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}

	    ], [
		SHLIB_LD="/usr/ccs/bin/ld -G -z text"
		CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    ])
	    ;;
	SunOS-5*)
	    # Note: If _REENTRANT isn't defined, then Solaris
	    # won't define thread-safe library routines.

	    AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?])
	    AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1,
		[Do we really want to follow the standard? Yes we do!])

	    SHLIB_CFLAGS="-KPIC"

	    # Check to enable 64-bit flags for compiler/linker
	    AS_IF([test "$do64bit" = yes], [
		arch=`isainfo`
		AS_IF([test "$arch" = "sparcv9 sparc"], [
		    AS_IF([test "$GCC" = yes], [
			AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [
			    AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system])

			], [
			    do64bit_ok=yes
			    CFLAGS="$CFLAGS -m64 -mcpu=v9"
			    LDFLAGS="$LDFLAGS -m64 -mcpu=v9"
			    SHLIB_CFLAGS="-fPIC"


			])
		    ], [
			do64bit_ok=yes
			AS_IF([test "$do64bitVIS" = yes], [
			    CFLAGS="$CFLAGS -xarch=v9a"
			    LDFLAGS_ARCH="-xarch=v9a"

			], [
			    CFLAGS="$CFLAGS -xarch=v9"
			    LDFLAGS_ARCH="-xarch=v9"

			])
			# Solaris 64 uses this as well
			#LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"

		    ])
		], [AS_IF([test "$arch" = "amd64 i386"], [
		    AS_IF([test "$GCC" = yes], [
			case $system in
			    SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
				do64bit_ok=yes
				CFLAGS="$CFLAGS -m64"
				LDFLAGS="$LDFLAGS -m64";;
			    *)
				AC_MSG_WARN([64bit mode not supported with GCC on $system]);;

			esac
		    ], [
			do64bit_ok=yes
			case $system in
			    SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*)
				CFLAGS="$CFLAGS -m64"
				LDFLAGS="$LDFLAGS -m64";;
			    *)
				CFLAGS="$CFLAGS -xarch=amd64"
				LDFLAGS="$LDFLAGS -xarch=amd64";;


			esac
		    ])
		], [AC_MSG_WARN([64bit mode not supported for $arch])])])


	    ])





	    SHLIB_SUFFIX=".so"


	    AS_IF([test "$GCC" = yes], [
		SHLIB_LD='${CC} -shared'
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
		AS_IF([test "$do64bit_ok" = yes], [
		    AS_IF([test "$arch" = "sparcv9 sparc"], [
			# We need to specify -static-libgcc or we need to
			# add the path to the sparv9 libgcc.
			# JH: static-libgcc is necessary for core Tcl, but may
			# not be necessary for extensions.
			SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc"
			# for finding sparcv9 libgcc, get the regular libgcc
			# path, remove so name and append 'sparcv9'
			#v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..."
			#CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"


		    ], [AS_IF([test "$arch" = "amd64 i386"], [
			# JH: static-libgcc is necessary for core Tcl, but may
			# not be necessary for extensions.
			SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
		    ])])
		])
	    ], [
		case $system in
		    SunOS-5.[[1-9]][[0-9]]*)
			# TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS
			SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';;
		    *)
			SHLIB_LD='/usr/ccs/bin/ld -G -z text';;
		esac
		CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'

	    ])
	    ;;
	UNIX_SV* | UnixWare-5*)
	    SHLIB_CFLAGS="-KPIC"
	    SHLIB_LD='${CC} -G'
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"


	    # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
	    # that don't grok the -Bexport option.  Test that it does.
	    AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [
		hold_ldflags=$LDFLAGS
		LDFLAGS="$LDFLAGS -Wl,-Bexport"
		AC_TRY_LINK(, [int i;], tcl_cv_ld_Bexport=yes, tcl_cv_ld_Bexport=no)
	        LDFLAGS=$hold_ldflags])
	    AS_IF([test $tcl_cv_ld_Bexport = yes], [
		LDFLAGS="$LDFLAGS -Wl,-Bexport"

	    ])
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
    esac

    AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [
	AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform])

    ])

dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so
dnl # until the end of configure, as configure's compile and link tests use
dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's
dnl # preprocessing tests use only CPPFLAGS.
    AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""])

    # Add in the arch flags late to ensure it wasn't removed.
























    # Not necessary in TEA, but this is aligned with core
    LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"

    # If we're running gcc, then change the C flags for compiling shared
    # libraries to the right flags for gcc, instead of those for the
    # standard manufacturer compiler.


    AS_IF([test "$GCC" = yes], [
	case $system in
	    AIX-*) ;;

	    BSD/OS*) ;;

	    CYGWIN_*|MINGW32_*|MINGW64_*) ;;
	    IRIX*) ;;

	    NetBSD-*|FreeBSD-*|OpenBSD-*) ;;

	    Darwin-*) ;;

	    SCO_SV-3.2*) ;;

	    windows) ;;


	    *) SHLIB_CFLAGS="-fPIC" ;;

	esac])



    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
	AC_DEFINE(MODULE_SCOPE, [extern],
	    [No Compiler support for module scope symbols])
    ])

    AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [
    # TEA specific: use PACKAGE_VERSION instead of VERSION
    SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}'])

    AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [
    # TEA specific: use PACKAGE_VERSION instead of VERSION
    UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a'])

    if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then
	AC_CACHE_CHECK(for SEH support in compiler,
	    tcl_cv_seh,
	AC_TRY_RUN([
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN

	    int main(int argc, char** argv) {
		int a, b = 0;
		__try {
		    a = 666 / b;
		}
		__except (EXCEPTION_EXECUTE_HANDLER) {
		    return 0;
		}
		return 1;
	    }
	],
	    tcl_cv_seh=yes,
	    tcl_cv_seh=no,
	    tcl_cv_seh=no)
	)
	if test "$tcl_cv_seh" = "no" ; then
	    AC_DEFINE(HAVE_NO_SEH, 1,
		    [Defined when mingw does not support SEH])
	fi

	#
	# Check to see if the excpt.h include file provided contains the
	# definition for EXCEPTION_DISPOSITION; if not, which is the case
	# with Cygwin's version as of 2002-04-10, define it to be int,
	# sufficient for getting the current code to work.
	#
	AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files,
	    tcl_cv_eh_disposition,
	    AC_TRY_COMPILE([
#	    define WIN32_LEAN_AND_MEAN
#	    include <windows.h>
#	    undef WIN32_LEAN_AND_MEAN
	    ],[
		EXCEPTION_DISPOSITION x;
	    ],
		tcl_cv_eh_disposition=yes,
		tcl_cv_eh_disposition=no)
	)
	if test "$tcl_cv_eh_disposition" = "no" ; then
	AC_DEFINE(EXCEPTION_DISPOSITION, int,
		[Defined when cygwin/mingw does not support EXCEPTION DISPOSITION])
	fi

	# Check to see if winnt.h defines CHAR, SHORT, and LONG
	# even if VOID has already been #defined. The win32api
	# used by mingw and cygwin is known to do this.

	AC_CACHE_CHECK(for winnt.h that ignores VOID define,
	    tcl_cv_winnt_ignore_void,
	    AC_TRY_COMPILE([
#define VOID void
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
	    ], [
		CHAR c;
		SHORT s;
		LONG l;
	    ],
        tcl_cv_winnt_ignore_void=yes,
        tcl_cv_winnt_ignore_void=no)
	)
	if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
	    AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
		    [Defined when cygwin/mingw ignores VOID define in winnt.h])
	fi
    fi

	# See if the compiler supports casting to a union type.
	# This is used to stop gcc from printing a compiler
	# warning when initializing a union member.

	AC_CACHE_CHECK(for cast to union support,
	    tcl_cv_cast_to_union,
	    AC_TRY_COMPILE([],
	    [
		  union foo { int i; double d; };
		  union foo f = (union foo) (int) 0;
	    ],
	    tcl_cv_cast_to_union=yes,
	    tcl_cv_cast_to_union=no)
	)
	if test "$tcl_cv_cast_to_union" = "yes"; then
	    AC_DEFINE(HAVE_CAST_TO_UNION, 1,
		    [Defined when compiler supports casting to union type.])
	fi

    AC_SUBST(CFLAGS_DEBUG)
    AC_SUBST(CFLAGS_OPTIMIZE)
    AC_SUBST(CFLAGS_WARNING)

    AC_SUBST(STLIB_LD)
    AC_SUBST(SHLIB_LD)
................................................................................
#	Note that #include lines must begin in leftmost column for
#	some compilers to recognize them as preprocessor directives,
#	and some build environments have stdin not pointing at a
#	pseudo-terminal (usually /dev/null instead.)
#
# Arguments:
#	none
#
# Results:
#
#	Defines only one of the following vars:
#		HAVE_SYS_MODEM_H
#		USE_TERMIOS
#		USE_TERMIO
#		USE_SGTTY

#--------------------------------------------------------------------

AC_DEFUN([TEA_SERIAL_PORT], [
    AC_CHECK_HEADERS(sys/modem.h)
    AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [
    AC_TRY_RUN([
#include <termios.h>
................................................................................
    case $tcl_cv_api_serial in
	termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);;
	termio)  AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);;
	sgtty)   AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);;
    esac
])



























































































#--------------------------------------------------------------------
# TEA_PATH_X
#
#	Locate the X11 header files and the X11 library archive.  Try
#	the ac_path_x macro first, but if it doesn't find the X stuff
#	(e.g. because there's no xmkmf program) then check through
#	a list of possible directories.  Under some conditions the
................................................................................
#	no include files, so double-check its result just to be safe.
#
#	This should be called after TEA_CONFIG_CFLAGS as setting the
#	LIBS line can confuse some configure macro magic.
#
# Arguments:
#	none
#
# Results:
#
#	Sets the following vars:
#		XINCLUDES
#		XLIBSW
#		PKG_LIBS (appends to)

#--------------------------------------------------------------------

AC_DEFUN([TEA_PATH_X], [
    if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then
	TEA_PATH_UNIX_X
    fi
])

AC_DEFUN([TEA_PATH_UNIX_X], [
    AC_PATH_X
    not_really_there=""
    if test "$no_x" = ""; then
	if test "$x_includes" = ""; then
	    AC_TRY_CPP([#include <X11/Xlib.h>], , not_really_there="yes")
	else
	    if test ! -r $x_includes/X11/Xlib.h; then
		not_really_there="yes"
	    fi
	fi
    fi
    if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then
	AC_MSG_CHECKING([for X11 header files])
	found_xincludes="no"
	AC_TRY_CPP([#include <X11/Xlib.h>], found_xincludes="yes", found_xincludes="no")
	if test "$found_xincludes" = "no"; then
	    dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include"
	    for i in $dirs ; do
		if test -r $i/X11/Xlib.h; then
		    AC_MSG_RESULT([$i])
		    XINCLUDES=" -I$i"
		    found_xincludes="yes"
		    break
		fi
	    done
	fi
    else
	if test "$x_includes" != ""; then
	    XINCLUDES="-I$x_includes"
	    found_xincludes="yes"
	fi
    fi
    if test "$found_xincludes" = "no"; then
	AC_MSG_RESULT([couldn't find any!])
    fi

    if test "$no_x" = yes; then
	AC_MSG_CHECKING([for X11 libraries])
	XLIBSW=nope
	dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib"
	for i in $dirs ; do
	    if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then
		AC_MSG_RESULT([$i])
		XLIBSW="-L$i -lX11"
		x_libraries="$i"
		break
	    fi
	done
    else
................................................................................
    if test "$XLIBSW" = nope ; then
	AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow)
    fi
    if test "$XLIBSW" = nope ; then
	AC_MSG_RESULT([could not find any!  Using -lX11.])
	XLIBSW=-lX11
    fi
    # TEA specific:
    if test x"${XLIBSW}" != x ; then
	PKG_LIBS="${PKG_LIBS} ${XLIBSW}"
    fi
])

#--------------------------------------------------------------------
# TEA_BLOCKING_STYLE
#
#	The statements below check for systems where POSIX-style
#	non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
#	On these systems (mostly older ones), use the old BSD-style
#	FIONBIO approach instead.
#
# Arguments:
#	none
#
# Results:
#
#	Defines some of the following vars:
#		HAVE_SYS_IOCTL_H
#		HAVE_SYS_FILIO_H
#		USE_FIONBIO
#		O_NONBLOCK

#--------------------------------------------------------------------

AC_DEFUN([TEA_BLOCKING_STYLE], [
    AC_CHECK_HEADERS(sys/ioctl.h)
    AC_CHECK_HEADERS(sys/filio.h)
    TEA_CONFIG_SYSTEM
    AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O])
    case $system in





	OSF*)




	    AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?])
	    AC_MSG_RESULT([FIONBIO])
	    ;;
	*)
	    AC_MSG_RESULT([O_NONBLOCK])
	    ;;
    esac
])

#--------------------------------------------------------------------
# TEA_TIME_HANDLER
#
#	Checks how the system deals with time.h, what time structures
#	are used on the system, and what fields the structures have.
#
# Arguments:
#	none
#
# Results:
#
#	Defines some of the following vars:
#		USE_DELTA_FOR_TZ
#		HAVE_TM_GMTOFF
#		HAVE_TM_TZADJ
#		HAVE_TIMEZONE_VAR

#--------------------------------------------------------------------

AC_DEFUN([TEA_TIME_HANDLER], [
    AC_CHECK_HEADERS(sys/time.h)
    AC_HEADER_TIME
    AC_STRUCT_TIMEZONE

................................................................................
#	and if the problem exists use a substitute procedure
#	"fixstrtod" (provided by Tcl) that corrects the error.
#	Also, on Compaq's Tru64 Unix 5.0,
#	strtod(" ") returns 0.0 instead of a failure to convert.
#
# Arguments:
#	none
#
# Results:
#
#	Might defines some of the following vars:
#		strtod (=fixstrtod)

#--------------------------------------------------------------------

AC_DEFUN([TEA_BUGGY_STRTOD], [
    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
    if test "$tcl_strtod" = 1; then
	AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
	    AC_TRY_RUN([
................................................................................
	    AC_LIBOBJ([fixstrtod])
	    USE_COMPAT=1
	    AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
	fi
    fi
])

#--------------------------------------------------------------------























































































# TEA_TCL_EARLY_FLAGS
#
#	Check for what flags are needed to be passed so the correct OS
#	features are available.
#
# Arguments:
#	None
#
# Results:
#
#	Might define the following vars:
#		_ISOC99_SOURCE
#		_LARGEFILE64_SOURCE
#		_LARGEFILE_SOURCE64

#--------------------------------------------------------------------

AC_DEFUN([TEA_TCL_EARLY_FLAG],[
    AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
	AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,
	    AC_TRY_COMPILE([[#define ]$1[ 1
]$2], $3,
................................................................................
#--------------------------------------------------------------------
# TEA_TCL_64BIT_FLAGS
#
#	Check for what is defined in the way of 64-bit features.
#
# Arguments:
#	None
#
# Results:
#
#	Might define the following vars:
#		TCL_WIDE_INT_IS_LONG
#		TCL_WIDE_INT_TYPE
#		HAVE_STRUCT_DIRENT64
#		HAVE_STRUCT_STAT64
#		HAVE_TYPE_OFF64_T

#--------------------------------------------------------------------

AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
    AC_MSG_CHECKING([for 64-bit integer type])
    AC_CACHE_VAL(tcl_cv_type_64bit,[
	tcl_cv_type_64bit=none
	# See if the compiler knows natively about __int64
	AC_TRY_COMPILE(,[__int64 value = (__int64) 0;],
	    tcl_type_64bit=__int64, tcl_type_64bit="long long")
	# See if we should use long anyway  Note that we substitute in the
	# type that is our current guess for a 64-bit type inside this check
	# program, so it should be modified only carefully...
        AC_TRY_COMPILE(,[switch (0) {
            case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ;
        }],tcl_cv_type_64bit=${tcl_type_64bit})])
    if test "${tcl_cv_type_64bit}" = none ; then
	AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?])
	AC_MSG_RESULT([using long])
    elif test "${tcl_cv_type_64bit}" = "__int64" \
		-a "${TEA_PLATFORM}" = "windows" ; then
	# TEA specific: We actually want to use the default tcl.h checks in
	# this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER*
	AC_MSG_RESULT([using Tcl header defaults])
    else
	AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit},
	    [What type should be used to define wide integers?])
	AC_MSG_RESULT([${tcl_cv_type_64bit}])

	# Now check for auxiliary declarations
	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
	    AC_TRY_COMPILE([#include <sys/types.h>
#include <dirent.h>],[struct dirent64 p;],
		tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
	fi

	AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
	    AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
................................................................................
# EXEEXT
#	Select the executable extension based on the host type.  This
#	is a lightweight replacement for AC_EXEEXT that doesn't require
#	a compiler.
#------------------------------------------------------------------------

AC_DEFUN([TEA_INIT], [


    TEA_VERSION="3.13"

    AC_MSG_CHECKING([TEA configuration])
    if test x"${PACKAGE_NAME}" = x ; then
	AC_MSG_ERROR([
The PACKAGE_NAME variable must be defined by your TEA configure.ac])
    fi






    AC_MSG_RESULT([ok (TEA ${TEA_VERSION})])

    # If the user did not set CFLAGS, set it now to keep macros
    # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2".
    if test "${CFLAGS+set}" != "set" ; then
	CFLAGS=""
    fi

    case "`uname -s`" in

	*win32*|*WIN32*|*MINGW32_*|*MINGW64_*)
	    AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo)
	    EXEEXT=".exe"
	    TEA_PLATFORM="windows"
	    ;;
	*CYGWIN_*)
	    EXEEXT=".exe"
	    # CYGPATH and TEA_PLATFORM are determined later in LOAD_TCLCONFIG
	    ;;
	*)
	    CYGPATH=echo
	    # Maybe we are cross-compiling....
	    case ${host_alias} in
		*mingw32*)
		EXEEXT=".exe"
		TEA_PLATFORM="windows"
		;;
	    *)
		EXEEXT=""
		TEA_PLATFORM="unix"
		;;
	    esac
	    ;;
    esac

    # Check if exec_prefix is set. If not use fall back to prefix.
    # Note when adjusted, so that TEA_PREFIX can correct for this.
    # This is needed for recursive configures, since autoconf propagates
    # $prefix, but not $exec_prefix (doh!).
    if test x$exec_prefix = xNONE ; then
	exec_prefix_default=yes
	exec_prefix=$prefix
    fi

    AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}])

    AC_SUBST(EXEEXT)
    AC_SUBST(CYGPATH)

    # This package name must be replaced statically for AC_SUBST to work
    AC_SUBST(PKG_LIB_FILE)
    # Substitute STUB_LIB_FILE in case package creates a stub library too.
................................................................................
    AC_SUBST(PKG_STUB_SOURCES)
    AC_SUBST(PKG_STUB_OBJECTS)
    AC_SUBST(PKG_TCL_SOURCES)
    AC_SUBST(PKG_HEADERS)
    AC_SUBST(PKG_INCLUDES)
    AC_SUBST(PKG_LIBS)
    AC_SUBST(PKG_CFLAGS)

    # Configure the installer.
    TEA_INSTALLER
])

#------------------------------------------------------------------------
# TEA_ADD_SOURCES --
#
#	Specify one or more source files.  Users should check for
#	the right platform before adding to their list.
................................................................................
	    [\$]*)
		# allow $-var names
		PKG_SOURCES="$PKG_SOURCES $i"
		PKG_OBJECTS="$PKG_OBJECTS $i"
		;;
	    *)
		# check for existence - allows for generic/win/unix VPATH
		# To add more dirs here (like 'src'), you have to update VPATH
		# in Makefile.in as well
		if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
		    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
		    -a ! -f "${srcdir}/macosx/$i" \
		    ; then
		    AC_MSG_ERROR([could not find source file '$i'])
		fi
		PKG_SOURCES="$PKG_SOURCES $i"
		# this assumes it is in a VPATH dir
		i=`basename $i`
		# handle user calling this before or after TEA_SETUP_COMPILER
................................................................................
#------------------------------------------------------------------------
AC_DEFUN([TEA_ADD_STUB_SOURCES], [
    vars="$@"
    for i in $vars; do
	# check for existence - allows for generic/win/unix VPATH
	if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \
	    -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \
	    -a ! -f "${srcdir}/macosx/$i" \
	    ; then
	    AC_MSG_ERROR([could not find stub source file '$i'])
	fi
	PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i"
	# this assumes it is in a VPATH dir
	i=`basename $i`
	# handle user calling this before or after TEA_SETUP_COMPILER
................................................................................
#	Defines and substs the following vars:
#		PKG_CFLAGS
#------------------------------------------------------------------------
AC_DEFUN([TEA_ADD_CFLAGS], [
    PKG_CFLAGS="$PKG_CFLAGS $@"
    AC_SUBST(PKG_CFLAGS)
])

#------------------------------------------------------------------------
# TEA_ADD_CLEANFILES --
#
#	Specify one or more CLEANFILES.
#
# Arguments:
#	one or more file names to clean target
#
# Results:
#
#	Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG
#------------------------------------------------------------------------
AC_DEFUN([TEA_ADD_CLEANFILES], [
    CLEANFILES="$CLEANFILES $@"
])

#------------------------------------------------------------------------
# TEA_PREFIX --
#
#	Handle the --prefix=... option by defaulting to what Tcl gave
#
# Arguments:
................................................................................
    fi
])

#------------------------------------------------------------------------
# TEA_SETUP_COMPILER_CC --
#
#	Do compiler checks the way we want.  This is just a replacement
#	for AC_PROG_CC in TEA configure.ac files to make them cleaner.
#
# Arguments:
#	none
#
# Results:
#
#	Sets up CC var and other standard bits we need to make executables.
#------------------------------------------------------------------------
AC_DEFUN([TEA_SETUP_COMPILER_CC], [
    # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE)
    # in this macro, they need to go into TEA_SETUP_COMPILER instead.







    AC_PROG_CC
    AC_PROG_CPP



    #--------------------------------------------------------------------
    # Checks to see if the make program sets the $MAKE variable.
    #--------------------------------------------------------------------

    AC_PROG_MAKE_SET

    #--------------------------------------------------------------------
    # Find ranlib
    #--------------------------------------------------------------------

    AC_CHECK_TOOL(RANLIB, ranlib)

    #--------------------------------------------------------------------
    # Determines the correct binary file extension (.o, .obj, .exe etc.)
    #--------------------------------------------------------------------

    AC_OBJEXT
    AC_EXEEXT
................................................................................
    fi

    #--------------------------------------------------------------------
    # Common compiler flag setup
    #--------------------------------------------------------------------

    AC_C_BIGENDIAN








])

#------------------------------------------------------------------------
# TEA_MAKE_LIB --
#
#	Generate a line that can be used to build a shared/unshared library
#	in a platform independent manner.
................................................................................
#	CFLAGS -	Done late here to note disturb other AC macros
#       MAKE_LIB -      Command to execute to build the Tcl library;
#                       differs depending on whether or not Tcl is being
#                       compiled as a shared library.
#	MAKE_SHARED_LIB	Makefile rule for building a shared library
#	MAKE_STATIC_LIB	Makefile rule for building a static library
#	MAKE_STUB_LIB	Makefile rule for building a stub library
#	VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL
#	VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE
#------------------------------------------------------------------------

AC_DEFUN([TEA_MAKE_LIB], [
    if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then
	MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)"
	MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)"
	AC_EGREP_CPP([manifest needed], [
#if defined(_MSC_VER) && _MSC_VER >= 1400
print("manifest needed")
#endif
	], [
	# Could do a CHECK_PROG for mt, but should always be with MSVC8+
	VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;2 ; fi"
	VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;1 ; fi"
	MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}"
	TEA_ADD_CLEANFILES([*.manifest])
	])
	MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -out:\[$]@ \$(PKG_STUB_OBJECTS)"
    else
	MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)"
	MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}"
	MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)"
    fi

    if test "${SHARED_BUILD}" = "1" ; then
................................................................................
    # substituted. (@@@ Might not be necessary anymore)
    #--------------------------------------------------------------------

    if test "${TEA_PLATFORM}" = "windows" ; then
	if test "${SHARED_BUILD}" = "1" ; then
	    # We force the unresolved linking of symbols that are really in
	    # the private libraries of Tcl and Tk.

	    if test x"${TK_BIN_DIR}" != x ; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\""
	    fi
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\""
	    if test "$GCC" = "yes"; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc"
	    fi
	    eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
	else
	    eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
	    if test "$GCC" = "yes"; then
		PKG_LIB_FILE=lib${PKG_LIB_FILE}
	    fi
	fi
	# Some packages build their own stubs libraries
	eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
	if test "$GCC" = "yes"; then
	    PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
	fi
	# These aren't needed on Windows (either MSVC or gcc)
	RANLIB=:
	RANLIB_STUB=:
    else
	RANLIB_STUB="${RANLIB}"
	if test "${SHARED_BUILD}" = "1" ; then
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}"
	    if test x"${TK_BIN_DIR}" != x ; then
		SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}"
	    fi
	    eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
	    RANLIB=:
	else
	    eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
	fi
	# Some packages build their own stubs libraries
	eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
    fi

    # These are escaped so that only CFLAGS is picked up at configure time.
    # The other values will be substituted at make time.
    CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}"
    if test "${SHARED_BUILD}" = "1" ; then
	CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}"
................................................................................
    fi

    AC_SUBST(MAKE_LIB)
    AC_SUBST(MAKE_SHARED_LIB)
    AC_SUBST(MAKE_STATIC_LIB)
    AC_SUBST(MAKE_STUB_LIB)
    AC_SUBST(RANLIB_STUB)
    AC_SUBST(VC_MANIFEST_EMBED_DLL)
    AC_SUBST(VC_MANIFEST_EMBED_EXE)
])

#------------------------------------------------------------------------
# TEA_LIB_SPEC --
#
#	Compute the name of an existing object library located in libdir
#	from the given base name and produce the appropriate linker flags.
................................................................................
    for i in \
	    `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
	    `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \
	    `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \
	    `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \
	    `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \
	    `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \
	    `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \
	    `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \
	    `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \
	    `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do
	if test -f "$i" ; then
	    tea_lib_name_dir=`dirname $i`
	    $1_LIB_NAME=`basename $i`
	    $1_LIB_PATH_NAME=$i
	    break
................................................................................
#
#	Locate the private Tcl include files
#
# Arguments:
#
#	Requires:
#		TCL_SRC_DIR	Assumes that TEA_LOAD_TCLCONFIG has
#				already been called.
#
# Results:
#
#	Substitutes the following vars:
#		TCL_TOP_DIR_NATIVE







#		TCL_INCLUDES
#------------------------------------------------------------------------

AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
    # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh}
    AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS])
    AC_MSG_CHECKING([for Tcl private include files])

    TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}`
    TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\"







    # Check to see if tcl<Plat>Port.h isn't already with the public headers
    # Don't look for tclInt.h because that resides with tcl.h in the core
    # sources, but the <plat>Port headers are in a different directory
    if test "${TEA_PLATFORM}" = "windows" -a \
	-f "${ac_cv_c_tclh}/tclWinPort.h"; then
	result="private headers found with public headers"
    elif test "${TEA_PLATFORM}" = "unix" -a \
	-f "${ac_cv_c_tclh}/tclUnixPort.h"; then
	result="private headers found with public headers"
    else
	TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\"
	if test "${TEA_PLATFORM}" = "windows"; then
	    TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\"
	else
	    TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\"
	fi
	# Overwrite the previous TCL_INCLUDES as this should capture both
	# public and private headers in the same set.
	# We want to ensure these are substituted so as not to require
	# any *_NATIVE vars be defined in the Makefile
	TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
	if test "`uname -s`" = "Darwin"; then
            # If Tcl was built as a framework, attempt to use
            # the framework's Headers and PrivateHeaders directories
            case ${TCL_DEFS} in
	    	*TCL_FRAMEWORK*)
		    if test -d "${TCL_BIN_DIR}/Headers" -a \
			    -d "${TCL_BIN_DIR}/PrivateHeaders"; then
			TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}"
		    else
			TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
		    fi
	            ;;
	    esac
	    result="Using ${TCL_INCLUDES}"
	else
	    if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then
		AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}])
	    fi
	    result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}"
	fi
    fi


    AC_SUBST(TCL_TOP_DIR_NATIVE)







    AC_SUBST(TCL_INCLUDES)

    AC_MSG_RESULT([${result}])
])

#------------------------------------------------------------------------
# TEA_PUBLIC_TCL_HEADERS --
#
#	Locate the installed public Tcl header files
#
................................................................................
#	CYGPATH must be set
#
# Results:
#
#	Adds a --with-tclinclude switch to configure.
#	Result is cached.
#
#	Substitutes the following vars:
#		TCL_INCLUDES
#------------------------------------------------------------------------

AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [
    AC_MSG_CHECKING([for Tcl public headers])

    AC_ARG_WITH(tclinclude, [  --with-tclinclude       directory containing the public Tcl header files], with_tclinclude=${withval})
................................................................................
	if test x"${with_tclinclude}" != x ; then
	    if test -f "${with_tclinclude}/tcl.h" ; then
		ac_cv_c_tclh=${with_tclinclude}
	    else
		AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h])
	    fi
	else
	    list=""
	    if test "`uname -s`" = "Darwin"; then
		# If Tcl was built as a framework, attempt to use
		# the framework's Headers directory
		case ${TCL_DEFS} in
		    *TCL_FRAMEWORK*)
			list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`"
			;;
................................................................................
#
#	Requires:
#		TK_SRC_DIR	Assumes that TEA_LOAD_TKCONFIG has
#				 already been called.
#
# Results:
#
#	Substitutes the following vars:
#		TK_INCLUDES
#------------------------------------------------------------------------

AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [
    # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh}
    AC_REQUIRE([TEA_PUBLIC_TK_HEADERS])
    AC_MSG_CHECKING([for Tk private include files])

    TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}`
    TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\"


    # Check to see if tk<Plat>Port.h isn't already with the public headers
    # Don't look for tkInt.h because that resides with tk.h in the core
    # sources, but the <plat>Port headers are in a different directory
    if test "${TEA_PLATFORM}" = "windows" -a \
	-f "${ac_cv_c_tkh}/tkWinPort.h"; then
	result="private headers found with public headers"
    elif test "${TEA_PLATFORM}" = "unix" -a \
	-f "${ac_cv_c_tkh}/tkUnixPort.h"; then
	result="private headers found with public headers"
    else
	TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\"
	TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\"
	if test "${TEA_PLATFORM}" = "windows"; then
	    TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\"
	else
	    TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\"
	fi
	# Overwrite the previous TK_INCLUDES as this should capture both
	# public and private headers in the same set.
	# We want to ensure these are substituted so as not to require
	# any *_NATIVE vars be defined in the Makefile
	TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}"
	# Detect and add ttk subdir
	if test -d "${TK_SRC_DIR}/generic/ttk"; then
	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\""
	fi
	if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then

	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\""
	fi
	if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then
	   TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\""
	fi
	if test "`uname -s`" = "Darwin"; then
	    # If Tk was built as a framework, attempt to use
	    # the framework's Headers and PrivateHeaders directories
	    case ${TK_DEFS} in
		*TK_FRAMEWORK*)
			if test -d "${TK_BIN_DIR}/Headers" -a \
				-d "${TK_BIN_DIR}/PrivateHeaders"; then
			    TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}"
			else
			    TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
			fi
			;;
	    esac
	    result="Using ${TK_INCLUDES}"
	else
	    if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then
	       AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}])
	    fi
	    result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}"
	fi
    fi

    AC_SUBST(TK_TOP_DIR_NATIVE)



    AC_SUBST(TK_XLIB_DIR_NATIVE)


    AC_SUBST(TK_INCLUDES)

    AC_MSG_RESULT([${result}])
])

#------------------------------------------------------------------------
# TEA_PUBLIC_TK_HEADERS --
#
#	Locate the installed public Tk header files
#
................................................................................
#	CYGPATH must be set
#
# Results:
#
#	Adds a --with-tkinclude switch to configure.
#	Result is cached.
#
#	Substitutes the following vars:
#		TK_INCLUDES
#------------------------------------------------------------------------

AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [
    AC_MSG_CHECKING([for Tk public headers])

    AC_ARG_WITH(tkinclude, [  --with-tkinclude        directory containing the public Tk header files], with_tkinclude=${withval})
................................................................................
	if test x"${with_tkinclude}" != x ; then
	    if test -f "${with_tkinclude}/tk.h" ; then
		ac_cv_c_tkh=${with_tkinclude}
	    else
		AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h])
	    fi
	else
	    list=""
	    if test "`uname -s`" = "Darwin"; then
		# If Tk was built as a framework, attempt to use
		# the framework's Headers directory.
		case ${TK_DEFS} in
		    *TK_FRAMEWORK*)
			list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`"
			;;
................................................................................
	    # Look in the source dir only if Tk is not installed,
	    # and in that situation, look there before installed locations.
	    if test -f "${TK_BIN_DIR}/Makefile" ; then
		list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`"
	    fi

	    # Check order: pkg --prefix location, Tk's --prefix location,
	    # relative to directory of tkConfig.sh, Tcl's --prefix location,
	    # relative to directory of tclConfig.sh.

	    eval "temp_includedir=${includedir}"
	    list="$list \
		`ls -d ${temp_includedir}        2>/dev/null` \
		`ls -d ${TK_PREFIX}/include      2>/dev/null` \
		`ls -d ${TK_BIN_DIR}/../include  2>/dev/null` \
		`ls -d ${TCL_PREFIX}/include     2>/dev/null` \
		`ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`"
	    if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then
		list="$list /usr/local/include /usr/include"
		if test x"${TK_INCLUDE_SPEC}" != x ; then
		    d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'`
		    list="$list `ls -d ${d} 2>/dev/null`"
		fi
	    fi
	    for i in $list ; do
		if test -f "$i/tk.h" ; then
		    ac_cv_c_tkh=$i
		    break
		fi
	    done
................................................................................

    INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}`

    TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"

    AC_SUBST(TK_INCLUDES)

    if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then

	# On Windows and Aqua, we need the X compat headers
	AC_MSG_CHECKING([for X11 header files])
	if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then
	    INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`"
	    TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\"
	    AC_SUBST(TK_XINCLUDES)
	fi
	AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}])
    fi
])





































































































#------------------------------------------------------------------------
# TEA_PATH_CONFIG --
#
#	Locate the ${1}Config.sh file and perform a sanity check on
#	the ${1} compile flags.  These are used by packages like
#	[incr Tk] that load *Config.sh files from more than Tcl and Tk.
#
................................................................................
	    # check in a few common install locations
	    if test x"${ac_cv_c_$1config}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			; do
		    if test -f "$i/$1Config.sh" ; then
			ac_cv_c_$1config=`(cd $i; pwd)`
			break
		    fi
		done
	    fi
................................................................................

#------------------------------------------------------------------------
# TEA_LOAD_CONFIG --
#
#	Load the $1Config.sh file
#
# Arguments:
#
#	Requires the following vars to be set:
#		$1_BIN_DIR
#
# Results:
#
#	Substitutes the following vars:
#		$1_SRC_DIR
#		$1_LIB_FILE
#		$1_LIB_SPEC

#------------------------------------------------------------------------

AC_DEFUN([TEA_LOAD_CONFIG], [
    AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])

    if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
        AC_MSG_RESULT([loading])
................................................................................
    #

    if test -f "${$1_BIN_DIR}/Makefile" ; then
	AC_MSG_WARN([Found Makefile - using build library specs for $1])
        $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
        $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
        $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
        $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
        $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
    fi

    AC_SUBST($1_VERSION)
    AC_SUBST($1_BIN_DIR)
    AC_SUBST($1_SRC_DIR)

    AC_SUBST($1_LIB_FILE)
    AC_SUBST($1_LIB_SPEC)

    AC_SUBST($1_STUB_LIB_FILE)
    AC_SUBST($1_STUB_LIB_SPEC)
    AC_SUBST($1_STUB_LIB_PATH)

    # Allow the caller to prevent this auto-check by specifying any 2nd arg
    AS_IF([test "x$2" = x], [
	# Check both upper and lower-case variants
	# If a dev wanted non-stubs libs, this function could take an option
	# to not use _STUB in the paths below
	AS_IF([test "x${$1_STUB_LIB_SPEC}" = x],
	    [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)],
	    [TEA_LOAD_CONFIG_LIB($1_STUB)])
    ])
])

#------------------------------------------------------------------------
# TEA_LOAD_CONFIG_LIB --
#
#	Helper function to load correct library from another extension's
#	${PACKAGE}Config.sh.
#
# Results:
#	Adds to LIBS the appropriate extension library
#------------------------------------------------------------------------
AC_DEFUN([TEA_LOAD_CONFIG_LIB], [
    AC_MSG_CHECKING([For $1 library for LIBS])
    # This simplifies the use of stub libraries by automatically adding
    # the stub lib to your path.  Normally this would add to SHLIB_LD_LIBS,
    # but this is called before CONFIG_CFLAGS.  More importantly, this adds
    # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD.
    if test "x${$1_LIB_SPEC}" != "x" ; then
	if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then
	    TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"])
	    AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}])
	else
	    TEA_ADD_LIBS([${$1_LIB_SPEC}])
	    AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}])
	fi
    else
	AC_MSG_RESULT([file not found])
    fi
])

#------------------------------------------------------------------------
# TEA_EXPORT_CONFIG --
#
#	Define the data to insert into the ${PACKAGE}Config.sh file
#
# Arguments:
#
#	Requires the following vars to be set:
#		$1
#
# Results:
#	Substitutes the following vars:
#------------------------------------------------------------------------

AC_DEFUN([TEA_EXPORT_CONFIG], [
    #--------------------------------------------------------------------
    # These are for $1Config.sh
    #--------------------------------------------------------------------

    # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib)
    eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}"
    if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then
	eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}"
	eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}"
    else
	eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
	eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}"
    fi
    $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}"
    $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}"
    $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}"
    $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}"
    $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}"
    $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}"

    AC_SUBST($1_BUILD_LIB_SPEC)
    AC_SUBST($1_LIB_SPEC)
    AC_SUBST($1_BUILD_STUB_LIB_SPEC)
    AC_SUBST($1_STUB_LIB_SPEC)
    AC_SUBST($1_BUILD_STUB_LIB_PATH)
    AC_SUBST($1_STUB_LIB_PATH)

    AC_SUBST(MAJOR_VERSION)
    AC_SUBST(MINOR_VERSION)
    AC_SUBST(PATCHLEVEL)
])


#------------------------------------------------------------------------
# TEA_PATH_CELIB --
#
#	Locate Keuchel's celib emulation layer for targeting Win/CE
#
# Arguments:
................................................................................
	    CELIB_DIR=${ac_cv_c_celibconfig}
	    CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'`
	    AC_MSG_RESULT([found $CELIB_DIR])
	fi
    fi
])

#------------------------------------------------------------------------
# TEA_INSTALLER --
#
#	Configure the installer.
#
# Arguments:
#	none
#
# Results:
#	Substitutes the following vars:
#		INSTALL
#		INSTALL_DATA_DIR
#		INSTALL_DATA
#		INSTALL_PROGRAM
#		INSTALL_SCRIPT
#		INSTALL_LIBRARY
#------------------------------------------------------------------------

AC_DEFUN([TEA_INSTALLER], [
    INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c'
    INSTALL_DATA_DIR='${INSTALL} -d -m 755'
    INSTALL_DATA='${INSTALL} -m 644'
    INSTALL_PROGRAM='${INSTALL} -m 755'
    INSTALL_SCRIPT='${INSTALL} -m 755'

    TEA_CONFIG_SYSTEM
    case $system in
	HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;;
	      *) INSTALL_LIBRARY='${INSTALL} -m 644' ;;
    esac

    AC_SUBST(INSTALL)
    AC_SUBST(INSTALL_DATA_DIR)
    AC_SUBST(INSTALL_DATA)
    AC_SUBST(INSTALL_PROGRAM)
    AC_SUBST(INSTALL_SCRIPT)
    AC_SUBST(INSTALL_LIBRARY)
])

###
# Tip 430 - ZipFS Modifications
###
#------------------------------------------------------------------------
# SC_ZIPFS_SUPPORT
#	Locate a zip encoder installed on the system path, or none.
#
# Arguments:
#	none
#
# Results:
#	Substitutes the following vars:
#		TCL_ZIP_FILE
#		TCL_ZIPFS_SUPPORT
#		TCL_ZIPFS_FLAG
#		ZIP_PROG
#------------------------------------------------------------------------

#------------------------------------------------------------------------
# SC_PROG_ZIP
#	Locate a zip encoder installed on the system path, or none.
#
# Arguments:
#	none
#
# Results:
#	Substitutes the following vars:
#		ZIP_PROG
#       ZIP_PROG_OPTIONS
#       ZIP_PROG_VFSSEARCH
#       ZIP_INSTALL_OBJS
#------------------------------------------------------------------------
AC_DEFUN([TEA_ZIPFS_SUPPORT], [
    AC_MSG_CHECKING([for zipfs support])
    ZIP_PROG=""
    ZIP_PROG_OPTIONS=""
    ZIP_PROG_VFSSEARCH=""
    INSTALL_MSGS=""
    # If our native tclsh processes the "install" command line option
    # we can use it to mint zip files
    AS_IF([$TCLSH_PROG install],[
      ZIP_PROG=${TCLSH_PROG}
      ZIP_PROG_OPTIONS="install mkzip"
      ZIP_PROG_VFSSEARCH="."
      AC_MSG_RESULT([Can use Native Tclsh for Zip encoding])
    ])
    if test "x$ZIP_PROG" = "x" ; then
        AC_CACHE_VAL(ac_cv_path_zip, [
        search_path=`echo ${PATH} | sed -e 's/:/ /g'`
        for dir in $search_path ; do
            for j in `ls -r $dir/zip 2> /dev/null` \
                `ls -r $dir/zip 2> /dev/null` ; do
            if test x"$ac_cv_path_zip" = x ; then
                if test -f "$j" ; then
                ac_cv_path_zip=$j
                break
                fi
            fi
            done
        done
        ])
        if test -f "$ac_cv_path_zip" ; then
            ZIP_PROG="$ac_cv_path_zip "
            AC_MSG_RESULT([$ZIP_PROG])
            ZIP_PROG_OPTIONS="-rq"
            ZIP_PROG_VFSSEARCH="."
            AC_MSG_RESULT([Found INFO Zip in environment])
            # Use standard arguments for zip
        fi
    fi
    if test "x$ZIP_PROG" = "x" ; then
	    # It is not an error if an installed version of Zip can't be located.
        ZIP_PROG=""
        ZIP_PROG_OPTIONS=""
        ZIP_PROG_VFSSEARCH=""
        TCL_ZIPFS_SUPPORT=0
        TCL_ZIPFS_FLAG=
    else
        # ZIPFS Support
       eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\""
       if test ${TCL_ZIP_FILE} = "" ; then
          TCL_ZIPFS_SUPPORT=0
          TCL_ZIPFS_FLAG=
          INSTALL_LIBRARIES=install-libraries
          INSTALL_MSGS=install-msgs
       else
           if test ${SHARED_BUILD} = 1 ; then
              TCL_ZIPFS_SUPPORT=1
              INSTALL_LIBRARIES=install-libraries-zipfs-shared
           else
              TCL_ZIPFS_SUPPORT=2
              INSTALL_LIBRARIES=install-libraries-zipfs-static
           fi
          TCL_ZIPFS_FLAG=-DTCL_ZIPFS_SUPPORT
       fi
    fi

    AC_SUBST(TCL_ZIP_FILE)
    AC_SUBST(TCL_ZIPFS_SUPPORT)
    AC_SUBST(TCL_ZIPFS_FLAG)
    AC_SUBST(ZIP_PROG)
    AC_SUBST(ZIP_PROG_OPTIONS)
    AC_SUBST(ZIP_PROG_VFSSEARCH)
    AC_SUBST(INSTALL_LIBRARIES)
    AC_SUBST(INSTALL_MSGS)
])

# Local Variables:
# mode: autoconf
# End:

Changes to tdom.m4.

158
159
160
161
162
163
164








































































































165
166
167
168
169
170
171
...
211
212
213
214
215
216
217








































































































































































































218
219
220
221
222
223
224
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
        AC_MSG_RESULT([yes])
        TEA_ADD_SOURCES([generic/domalloc.c])
    else
        AC_MSG_RESULT([no])
        AC_DEFINE(USE_NORMAL_ALLOCATOR)
    fi
])








































































































 
#------------------------------------------------------------------------
# TDOM_PATH_AOLSERVER
#
#   Allows the building with support for AOLserver 
#
# Arguments:
................................................................................
            fi
        fi
        AC_MSG_RESULT([found AOLserver in $AOL_DIR])
        AC_DEFINE(NS_AOLSERVER)
        AC_DEFINE(USE_NORMAL_ALLOCATOR)
    fi
])









































































































































































































#------------------------------------------------------------------------
# TDOM_PATH_CONFIG --
#
#	Locate the tdomConfig.sh file
#
# Arguments:
................................................................................
#------------------------------------------------------------------------

AC_DEFUN(TDOM_PATH_CONFIG, [
    if test x"${no_tdom}" = x ; then
	    AC_MSG_CHECKING([for tDOM configuration])
	    AC_ARG_WITH(tdom, 
                AC_HELP_STRING([--with-tdom],
                    [directory containig tDOM configuration (tdomConfig.sh)]),
                with_tdomconfig=${withval})

	    no_tdom=true
        if test "${TEA_PLATFORM}" = "windows" ; then
            tdom_bindir=win
        else
            tdom_bindir=unix







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
...
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
...
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
        AC_MSG_RESULT([yes])
        TEA_ADD_SOURCES([generic/domalloc.c])
    else
        AC_MSG_RESULT([no])
        AC_DEFINE(USE_NORMAL_ALLOCATOR)
    fi
])
 
#------------------------------------------------------------------------
# TDOM_ENABLE_LESS_NS --
#
#   Building with lower limit of different XML namespace declarations
#   per document.
#
# Arguments:
#   None
#   
# Results:
#
#   Adds the following arguments to configure:
#       --enable-lessns=yes|no
#
#   Defines the following vars:
#
#   Sets the following vars:
#
#------------------------------------------------------------------------

AC_DEFUN(TDOM_ENABLE_LESS_NS, [
    AC_MSG_CHECKING([whether to enable lower limit for XML ns declarations per document])
    AC_ARG_ENABLE(lessns,
        AC_HELP_STRING([--enable-lessns],
            [build with lower limit for XML ns declarations (default: off)]),
        [tcl_ok=$enableval], [tcl_ok=no])

    if test "${enable_lessns+set}" = set; then
        enableval="$enable_lessns"
        tcl_ok=$enableval
    else
        tcl_ok=no
    fi

    if test "$tcl_ok" = "yes" ; then
        AC_MSG_RESULT([yes])
        AC_DEFINE(TDOM_LESS_NS)
    else
        AC_MSG_RESULT([no])
    fi
])
 
#------------------------------------------------------------------------
# TDOM_ENABLE_HTML5 --
#
#   Building with gumbo support for HTML5 parsing (dom parse -html5)
#
# Arguments:
#   None
#   
# Results:
#
#   Adds the following arguments to configure:
#       --enable-html5=yes|no
#
#   Defines the following vars:
#
#   Sets the following vars:
#
#------------------------------------------------------------------------

AC_DEFUN(TDOM_ENABLE_HTML5, [
    AC_MSG_CHECKING([whether to enable support for HTML5 parsing (using gumbo)])
    AC_ARG_ENABLE(html5,
        AC_HELP_STRING([--enable-html5],
            [build with HTML5 parsing support (default: off)]),
        [tcl_ok=$enableval], [tcl_ok=no])

    if test "${enable_html5+set}" = set; then
        enableval="$enable_html5"
        tcl_ok=$enableval
    else
        tcl_ok=no
    fi
    HTML5_LIBS=""
    HTML5_INCLUDES=""
    if test "$tcl_ok" = "yes" ; then
        # Check if pkg-config is available
        PKGCONFIG=no
        pkg-config --version > /dev/null 2>&1 && PKGCONFIG=yes
        if test "$PKGCONFIG" = no; then
            tcl_ok=no
	    AC_MSG_ERROR([cannot find pkg-config needed for --enable-html5.])
        fi
    fi
    if test "$tcl_ok" = "yes" ; then
        HAVEGUMBO=`pkg-config --exists gumbo && echo "1"`
        if test "$HAVEGUMBO" = "1" ; then
            AC_MSG_RESULT([yes])
            AC_DEFINE(TDOM_HAVE_GUMBO)
            if test "${TEA_PLATFORM}" = "windows" ; then
                HTML5_LIBS="-Wl,-Bstatic `pkg-config --static --libs gumbo` -Wl,-Bdynamic"
            else
                HTML5_LIBS="`pkg-config --libs gumbo`"
            fi
            HTML5_INCLUDES="`pkg-config --cflags gumbo`"
        else
            AC_MSG_ERROR([The required lib gumbo not found])
        fi
    else    
        AC_MSG_RESULT([no])
    fi
])
 
#------------------------------------------------------------------------
# TDOM_PATH_AOLSERVER
#
#   Allows the building with support for AOLserver 
#
# Arguments:
................................................................................
            fi
        fi
        AC_MSG_RESULT([found AOLserver in $AOL_DIR])
        AC_DEFINE(NS_AOLSERVER)
        AC_DEFINE(USE_NORMAL_ALLOCATOR)
    fi
])

#------------------------------------------------------------------------
# TDOM_PATH_EXPAT
#
#   Allows the building against a shared, system-wide expat library In
#   doubt, it falls back to the bundled expat copy
#
# Arguments:
#   none
#
# Results:
#
#   Adds the following arguments to configure:
#       --with-expat=...
#
#   Defines the following vars:
#
#   Sets the following vars:
#
#------------------------------------------------------------------------

AC_DEFUN(TDOM_PATH_EXPAT, [
    AC_MSG_CHECKING([for expat])
    AC_ARG_WITH(expat,
        AC_HELP_STRING([--with-expat],
            [directory with expat installation]), , [with_expat=no])

    AC_CACHE_VAL(ac_cv_c_expat,[
        case $with_expat in
            no) ;;
            yes)
                for f in /usr/local /usr; do
                    if test -f "$f/include/expat.h" ; then
                        ac_cv_c_expat=`(cd $f; pwd)`
                        break
                    fi
                done
                ;;
            *)                
                if test -f "$with_expat/include/expat.h"; then
                    ac_cv_c_expat=`(cd $with_expat; pwd)`
                else                  
                     AC_MSG_ERROR([${with_expat} directory doesn't contain expat.h])
                fi
        esac             
    ])
    if test x"${ac_cv_c_expat}" = x ; then
        AC_MSG_RESULT([Using bundled expat distribution])
        TEA_ADD_SOURCES([expat/xmlrole.c \
                         expat/xmltok.c \
                         expat/xmlparse.c \
                         expat/loadlibrary.c])
        TEA_ADD_INCLUDES([-I${srcdir}/expat])
        AC_DEFINE([XML_POOR_ENTROPY], 1,
          [Define to use poor entropy in lack of better source.])
    else
        AC_MSG_RESULT([Using shared expat found in ${ac_cv_c_expat}])
        TEA_ADD_INCLUDES(-I${ac_cv_c_expat}/include)
        TEA_ADD_LIBS([-lexpat])
    fi
])

#------------------------------------------------------------------------
# TDOM_EXPAT_ENTROPY
#
#   Only useful if building with the included expat. Allows to
#   determine the source of entropy used by the lib. If the argument
#   is something else then the default "auto", this argument value
#   will be a #define. Use XML_POOR_ENTROPY to fall back to the old
#   expat hash table salting. The default is to determine the best
#   available source and to use this.
#
# Arguments:
#   none
#
# Results:
#
#   Adds the following arguments to configure:
#       --with-entropy=...
#
#   Defines the following vars:
#
#   Sets the following vars:
#
#------------------------------------------------------------------------

AC_DEFUN(TDOM_EXPAT_ENTROPY, [
    AC_MSG_NOTICE([checking which source of entropy to use])
    AC_ARG_WITH(entropy,
        AC_HELP_STRING([--with-entropy],
            [source of entropy to use]), , [with_entropy=auto])

        case $with_entropy in
            no) 
                AC_DEFINE([XML_POOR_ENTROPY], 1,
                          [Define to use poor entropy.])
            ;;
            auto)
                AC_MSG_CHECKING([for arc4random_buf (BSD or libbsd)])
                AC_LINK_IFELSE([AC_LANG_SOURCE([
                  #include <stdlib.h>  /* for arc4random_buf on BSD, for NULL */
                  #if defined(HAVE_LIBBSD)
                  # include <bsd/stdlib.h>
                  #endif
                  int main() {
                    arc4random_buf(NULL, 0U);
                    return 0;
                  }
                ])], [
                    AC_DEFINE([HAVE_ARC4RANDOM_BUF], [1],
                        [`arc4random_buf' function.])
                    AC_MSG_RESULT([yes])
                ], [
                    AC_MSG_RESULT([no])

                    AC_MSG_CHECKING([for arc4random (BSD, macOS or libbsd)])
                    AC_LINK_IFELSE([AC_LANG_SOURCE([
                      #if defined(HAVE_LIBBSD)
                      # include <bsd/stdlib.h>
                      #else
                      # include <stdlib.h>
                      #endif
                      int main() {
                          arc4random();
                          return 0;
                      }
                    ])], [
                        AC_DEFINE([HAVE_ARC4RANDOM], [1],
                            [`arc4random' function.])
                        AC_MSG_RESULT([yes])
                    ], [
                        AC_MSG_RESULT([no])
                    ])
                ])


                AC_MSG_CHECKING([for getrandom (Linux 3.17+, glibc 2.25+)])
                AC_LINK_IFELSE([AC_LANG_SOURCE([
                  #include <stdlib.h>  /* for NULL */
                  #include <sys/random.h>
                  int main() {
                    return getrandom(NULL, 0U, 0U);
                  }
                ])], [
                    AC_DEFINE([HAVE_GETRANDOM], [1],
                        [`getrandom' function.])
                    AC_MSG_RESULT([yes])
                ], [
                    AC_MSG_RESULT([no])

                    AC_MSG_CHECKING([for syscall SYS_getrandom (Linux 3.17+)])
                    AC_LINK_IFELSE([AC_LANG_SOURCE([
                      #include <stdlib.h>  /* for NULL */
                      #include <unistd.h>  /* for syscall */
                      #include <sys/syscall.h>  /* for SYS_getrandom */
                      int main() {
                        syscall(SYS_getrandom, NULL, 0, 0);
                        return 0;
                      }
                    ])], [
                        AC_DEFINE([HAVE_SYSCALL_GETRANDOM], [1],
                            [`syscall' and `SYS_getrandom'.])
                        AC_MSG_RESULT([yes])
                    ], [
                        AC_MSG_RESULT([no])
                    ])
                ])
                AC_DEFINE([XML_DEV_URANDOM], 1,
                          [include code reading entropy from `/dev/urandom'.])
                AC_DEFINE([XML_POOR_ENTROPY], 1,
                          [Define to use poor entropy in lack of better source.])
            ;;
            HAVE_GETRANDOM)
                AC_DEFINE([HAVE_GETRANDOM], 1,
                          [Linux + glibc >=2.25])
            ;;
            HAVE_SYSCALL_GETRANDOM)
                AC_DEFINE([HAVE_SYSCALL_GETRANDOM], 1,
                          [Linux + glibc <2.25])
            ;;
            HAVE_ARC4RANDOM_BUF)
                AC_DEFINE([HAVE_ARC4RANDOM_BUF], 1,
                          [BSD / macOS >=10.7])
            ;;
            HAVE_ARC4RANDOM)
                AC_DEFINE([HAVE_ARC4RANDOM], 1,
                          [BSD / macOS <10.7])
            ;;
            XML_DEV_URANDOM)
                AC_DEFINE([XML_DEV_URANDOM], 1,
                          [Linux / BSD / macOS (/dev/urandom).])
            ;;
            XML_POOR_ENTROPY)
                AC_DEFINE([XML_POOR_ENTROPY], 1,
                          [Define to use poor entropy in lack of better source.])
            ;;
            *)
                AC_MSG_ERROR([${with_entropy} not known.])
        esac             
])

#------------------------------------------------------------------------
# TDOM_PATH_CONFIG --
#
#	Locate the tdomConfig.sh file
#
# Arguments:
................................................................................
#------------------------------------------------------------------------

AC_DEFUN(TDOM_PATH_CONFIG, [
    if test x"${no_tdom}" = x ; then
	    AC_MSG_CHECKING([for tDOM configuration])
	    AC_ARG_WITH(tdom, 
                AC_HELP_STRING([--with-tdom],
                    [directory containing tDOM configuration (tdomConfig.sh)]),
                with_tdomconfig=${withval})

	    no_tdom=true
        if test "${TEA_PLATFORM}" = "windows" ; then
            tdom_bindir=win
        else
            tdom_bindir=unix

Added tests/JSONTestSuite.tcl.

































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# The code in this file refers to the work done by:
#
# Parsing JSON is a Minefield
# http://seriot.ch/parsing_json.php
# https://github.com/nst/JSONTestSuite
#
# The dir argument should point to the test_parsing directory of that
# repository

package require tdom

if {$argc > 1} {
    error "usage: $argv0 ?testdir?"
}

if {$argc} {
    set path [lindex $argv 0]
    if {[file isdirectory $path]} {
        set dir $path
    } else {
        set file $path
    }
} else {
    set path ""
    set dir [pwd]
}

set skipfile [list]
# Not all chars allowed in JSON strings are allowed as element names
# or in XML char data.
foreach file {
    y_string_escaped_control_character.json
    y_string_null_escape.json
    y_string_allowed_escapes.json
    y_object_empty_key.json
    y_object_escaped_null_in_key.json
} {
    lappend skipfile $file
}
# UTF-8 edge cases and outside of BMP chars, for which tcl IO already
# did the wrong thing. Or misuse of tcl internal string rep as if it
# would be canonical UTF-8 (which it is not).
foreach file {
    y_string_nonCharacterInUTF-8_U+FFFF.json
    y_string_nonCharacterInUTF-8_U+1FFFF.json
    n_string_unescaped_crtl_char.json    
} {
    lappend skipfile $file
}

foreach test [glob -directory $path "n_*"] {
    if {[file tail $test] in $skipfile} continue
    set fd [open $test]
    set input [read $fd]
    close $fd
    set result [catch {dom parse -json -jsonroot json -- $input}]
    if {!$result} {
        puts $test
    }
}

foreach test [glob -directory $path "y_*"] {
    if {[file tail $test] in $skipfile} continue
    set fd [open $test]
    set input [read $fd]
    close $fd
    set result [catch {dom parse -json -jsonroot json -- $input} errMsg]
    if {$result} {
        puts "$test $errMsg"
    }
}

# The 'some say so, some so' cases. Ignore result, just ensure no seg
# fault */
foreach test [glob -directory $path "i_*"] {
    set fd [open $test]
    set input [read $fd]
    close $fd
    catch {dom parse -json -jsonroot json -- $input}
}

Added tests/OASIS-suite.tcl.













































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
# Helper script to run xslt 1.0 conformance test suite created by the
# OASIS XSLT / XPath Conformance Technical Committee. 

catch {source uri.tcl}
package require uri
package require tdom

# The following is not needed, given, that tDOM is correctly
# installed. This code only ensures, that the tDOM script library gets
# sourced, if the script is called with a tcldomsh out of the build
# dir of a complete tDOM source installation.
if {[info commands ::tdom::xmlReadFile] == ""} {
    # tcldomsh without the script library. Source the lib.
    source [file join [file dir [info script]] ../lib tdom.tcl]
}

# Import the tDOM helper procs
namespace import tdom::*

set catalogfile ""
set loglevel 0
set skip [list]
set match [list]
set matchgroup [list]
set matchfile [list]
set matchcatalog [list]
set verbose 0

proc putsUsage {{channel stderr}} {
    puts $channel "usage: $::argv0 ?options? path/to/catalog.xml"
    puts $channel "where options can be:"
    puts $channel "-loglevel <int>"
    puts $channel "-skip patternlist"
    puts $channel "-match patternlist"
    puts $channel "-matchgroup patternlist"
    puts $channel "-matchfile patternlist"
    puts $channel "-matchcatalog patternlist"
    puts $channel "-verbose <boolean>"
}

proc processArgs {argc argv} {
    variable catalogfile
    variable skip
    variable match
    variable matchgroup
    variable matchfile
    variable matchcatalog
    variable loglevel
    variable verbose
    
    if {$argc == 0 || $argc % 2 == 0} {
        putsUsage
        exit 1
    }
    
    foreach {option value} $argv {
        if {$value eq ""} {
            break
        }
        switch $option {
            "-match" {
                set match $value
            }
            "-matchgroup" {
                set matchgroup $value
            }
            "-matchfile" {
                set matchfile $value
            }
            "-skip" {
                set skip $value
            }
            "-matchcatalog" {
                set matchcatalog $value
            }
            "-loglevel" {
                if {[string is integer -strict $value]} {
                    set loglevel $value
                } else {
                    putsUsage
                    exit 1
                }
            }
            "-verbose" {
                if {[string is boolean -strict $value]} {
                    set verbose $value
                } else {
                    putsUsage
                    exit 1
                }
            }
            default {
                puts stderr "Unknown option \"$option\""
                putsUsage
                exit 1
            }
        }
    }
    set catalogfile [lindex $argv end]
}

set compareOK 0
set compareDIFF 0
set compareFAILED 0
set failedOK 0
set failedXML 0
set failedXSLT 0
set failedProcessing 0
set notFailed 0

proc extRefHandler {base systemId publicId} {
    variable usageCounter

    set absolutURI [uri::resolve $base $systemId]
    incr usageCounter($absolutURI)
    if {$usageCounter($absolutURI) > 10} {
        error "Cirular import/include?"
    }
    switch $systemId {
        "notfound.xml" {
            return [list string $absolutURI "<notfound/>"]
        }
    }
    array set uriData [uri::split $absolutURI]
    switch $uriData(scheme) {
        file {
            if {[catch {
                set xmlstr [xmlReadFile $uriData(path)]
            }]} {
                set pathlist [file split $uriData(path)]
                set file [findFile [lindex $pathlist end] [lrange $pathlist 0 end-1]]
                if {$file ne ""} {
                    set xmlstr [xmlReadFile $file]
                }
                error "not resolved external entity. Base: $base SystemID: $systemId"
            }
            return [list string $absolutURI [xmlReadFile $uriData(path)]]
        }
        default {
            error "can only handle file URI's"
        }
    }
}


# This is the callback proc for xslt:message elements. This proc is
# called once every time an xslt:message element is encountered during
# processing the stylesheet. The callback proc simply sends the text
# message to stderr.
proc xsltmsgcmd {msg terminate} {
    variable loglevel
    if {$loglevel >= 0} {
        puts stderr "xslt message: '$msg'"
    }
}

proc readCatalog {catalogPath} {
    variable catalogDir
    variable infoset

    set fd [open $catalogPath]
    set doc [dom parse -channel $fd]
    close $fd
    set catalogDir [file dirname $catalogPath]
    set infosetxsl [file join $catalogDir .. TOOLS infoset.xsl]
    set infosetdoc [dom parse -keepEmpties [xmlReadFile $infosetxsl]]
    set infoset [$infosetdoc toXSLTcmd]
    return $doc
}

proc checkAgainstPattern {patternlist text} {
    if {![llength $patternlist]} {
        return 1
    }
    foreach pattern $patternlist {
        if {[string match $pattern $text]} {
            return 1
        }
    }
    return 0
}

proc skip {id} {
    variable skip

    if {![llength $skip]} {
        return 0
    }
    return [checkAgainstPattern $skip $id]
}

proc matchcatalog {testcatalog} {
    variable matchcatalog

    if {![llength $matchcatalog]} {
        return 1
    }
    return [checkAgainstPattern $matchcatalog $testcatalog]
}

proc log {level text {detail ""}} {
    variable loglevel

    if {$level <= $loglevel} {
        puts $text
    }
    if {$detail ne "" && $level < $loglevel} {
        puts $detail
    }
}

proc findFile {filename path} {
    # The Microsoft testcatalog includes tests for which the physical
    # file name differ in case from the file name given by the test
    # definition. This proc tries to identify the correct file name in
    # such a case.

    log 3 "findFile called with $filename $path"
    set filelist [glob -nocomplain -tails -directory $path *]
    set nocasequal [lsearch -exact -nocase $filelist $filename]
    if {[llength $nocasequal] == 1} {
        if {$nocasequal >= 0} {
            return [file join $path [lindex $filelist $nocasequal]]
        }
    }
    return ""
}

proc runTest {testcase} {
    variable catalogDir
    variable majorpath
    variable matchgroup
    variable matchfile
    variable match
    variable infoset
    variable compareOK
    variable compareDIFF
    variable compareFAILED
    variable failedOK
    variable failedXML
    variable failedXSLT
    variable failedProcessing
    variable notFailed
    variable verbose
    variable usageCounter
    
    set filepath [$testcase selectNodes string(file-path)]
    if {![checkAgainstPattern $matchgroup $filepath]} {
        return
    }
    set scenario [$testcase selectNodes scenario]
    if {[llength $scenario] != 1 } {
        log 0 "Non-standard scenario!"
        log 0 [$testcase asXML]
        return
    }
    set operation [$scenario @operation]
    switch $operation {
        "standard" -
        "execution-error" {}
        default {
            log 0 "Non-standard scenario!"
            log 0 [$testcase asXML]
            return
        }
    }
    set xmlfile [$scenario selectNodes \
                     {string(input-file[@role="principal-data"])}]
    set xslfile [$scenario selectNodes \
                     {string(input-file[@role="principal-stylesheet"])}]
    set testid [$testcase @id "<no-id>"]
    if {![checkAgainstPattern $match $testid]} {
        return
    }
    if {[skip $testid]} {
        log 1 "Skipping test id $testid (filepath: $filepath)"
        return
    }

    if {![checkAgainstPattern $matchfile $xslfile]} {
        log 1 "Skipping xslfile $xslfile"
        return
    }
    if {$verbose} {
        puts [$testcase @id "<no-id>!!"]
    }
    set xmlfile [file join $catalogDir $majorpath $filepath $xmlfile]
    if {![file readable $xmlfile]} {
        set xmlfile [findFile $xmlfile \
                         [file join $catalogDir $majorpath $filepath]]
        if {$xmlfile eq ""} {
            log 0 "Couldn't find xmlfile \
                  [$scenario selectNodes \
                     {string(input-file[@role="principal-data"])}]"
            return
        }
    }
    if {![file readable $xslfile]} {
        set xslfile [findFile $xslfile \
                         [file join $catalogDir $majorpath $filepath]]
        if {$xslfile eq ""} {
            log 0 "Couldn't find xslfile \
                  [$scenario selectNodes \
                     {string(input-file[@role="principal-stylesheet"])}]"
            return
        }
    }
    set xslfile [file join $catalogDir $majorpath $filepath $xslfile]
    set xmlout [$scenario selectNodes \
                    {string(output-file[@role="principal" and @compare="XML"])}]
    set xmloutfile ""
    if {$xmlout ne ""} {
        set xmloutfile [file join $catalogDir $majorpath "REF_OUT" $filepath \
                            $xmlout]
    }
    array unset usageCounter
    if {[catch {
        set xmldoc [dom parse -baseurl [baseURL $xmlfile] \
                        -externalentitycommand extRefHandler \
                        -keepEmpties \
                        [xmlReadFile $xmlfile] ]
    } errMsg]} {
        incr failedXML
        log 0 "Unable to parse xml file '$xmlfile'. Reason:\n$errMsg"
        return
    }
    dom setStoreLineColumn 1
    if {[catch {
        set xsltdoc [dom parse -baseurl [baseURL $xslfile] \
                         -externalentitycommand extRefHandler \
                         -keepEmpties \
                         [xmlReadFile $xslfile] ]
    } errMsg]} {
        dom setStoreLineColumn 0
        incr failedXSLT
        log 0 "Unable to parse xsl file '$xslfile'. Reason:\n$errMsg"
        return
    }
    dom setStoreLineColumn 0
    set resultDoc ""
    if {[catch {$xmldoc xslt -xsltmessagecmd xsltmsgcmd $xsltdoc resultDoc} \
             errMsg]} {
        if {$operation eq "execution-error"} {
            incr failedOK
            log 2 $errMsg
        } else {
            incr failedProcessing
            log 0 $errMsg
        }
    } else {
        if {$operation eq "execution-error"} {
            incr notFailed
            log 0 "$xslfile - test should have failed, but didn't."
        }
    }
    if {$xmloutfile ne "" && [llength [info commands $resultDoc]]} {
        if {![catch {
            set refdoc [dom parse -keepEmpties [xmlReadFile $xmloutfile]]
        } errMsg]} {
            set refinfosetdoc [$infoset $refdoc]
            set resultinfosetdoc [$infoset $resultDoc]
            if {[$refinfosetdoc asXML -indent none] 
                ne [$resultinfosetdoc asXML -indent none]} {
                incr compareDIFF
                log 1 "Result and ref differ."
                log 2 "Ref:"
                log 2 [$refinfosetdoc asXML]
                log 2 "Result:"
                log 2 [$resultinfosetdoc asXML]
            } else {
                incr compareOK
            }
            $refinfosetdoc delete
            $resultinfosetdoc delete
        } else {
            incr compareFAILED
            log 3 "Unable to parse REF doc. Reason:\n$errMsg"
        }
    }
    $xmldoc delete
    $xsltdoc delete
    catch {$resultDoc delete}
}

proc runTests {catalogRoot} {
    variable majorpath
    variable compareOK
    variable compareDIFF
    variable compareFAILED
    variable failedOK
    variable failedXML
    variable failedXSLT
    variable failedProcessing
    variable notFailed
    
    foreach testcatalog [$catalogRoot selectNodes test-catalog] {
        if {![matchcatalog [$testcatalog @submitter]]} {
            continue
        }
        set majorpath [$testcatalog selectNodes string(major-path)]
        foreach testcase [$testcatalog selectNodes test-case] {
            runTest $testcase
        }
    }
    # Always output the summary
    variable loglevel 0
    log 0 "Finished."
    log 0 "XML parse failed: $failedXML"
    log 0 "XSLT parse failed: $failedXSLT"
    log 0 "Processing failed: $failedProcessing"
    log 0 "Compare OK: $compareOK"
    log 0 "Compare FAIL: $compareDIFF"
    log 0 "Compare BROKEN: $compareFAILED"
    log 0 "Not found errors: $notFailed"
    log 0 "Failed OK: $failedOK"
}

processArgs $argc $argv
set catalogDoc [readCatalog $catalogfile]
runTests [$catalogDoc documentElement]

proc exit args {}

Changes to tests/all-bench.tcl.

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
...
119
120
121
122
123
124
125


126
127
128

129
130
131
132
        }
    }
}


if {[llength $interpPaths] == 0} {
    lappend interpPaths [file dirname [info nameofexecutable]]
    puts $interpPaths
}

puts [bench::locate $interpPattern $interpPaths]

set interps [bench::versions [bench::locate $interpPattern $interpPaths]]

if {![llength $interps]} {
    puts stderr "No interpreters found"
    exit 1
}

if {[llength $benchFlags]} {
................................................................................
set benchfiles [glob -nocomplain [file join [file dir [info script]] \
                                      $benchFilePattern]]
if {![llength $benchfiles]} {
    puts stderr "No benchmark files found."
    exit 1
}



set run $cmd
lappend run $interps $benchfiles
set results [eval $run]

if {$norm ne ""} {
    set results [::bench::norm $results $norm]
}
puts [::bench::out::text $results]







<


|
<
<







 







>
>
|
|
|
>




94
95
96
97
98
99
100

101
102
103


104
105
106
107
108
109
110
...
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
        }
    }
}


if {[llength $interpPaths] == 0} {
    lappend interpPaths [file dirname [info nameofexecutable]]

}

set interps [bench::locate $interpPattern $interpPaths]



if {![llength $interps]} {
    puts stderr "No interpreters found"
    exit 1
}

if {[llength $benchFlags]} {
................................................................................
set benchfiles [glob -nocomplain [file join [file dir [info script]] \
                                      $benchFilePattern]]
if {![llength $benchfiles]} {
    puts stderr "No benchmark files found."
    exit 1
}

set results ""
foreach interp $interps {
    set run $cmd
    lappend run $interp $benchfiles
    set results [::bench::merge $results [eval $run]]
}
if {$norm ne ""} {
    set results [::bench::norm $results $norm]
}
puts [::bench::out::text $results]

Changes to tests/all.tcl.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30





31
32
33
34
35
36
37
source [file join [file dir [info script]] loadtdom.tcl]

if {$tcl_version >= 8.1} {
    if {[lsearch [info proc ::tcltest::testConstraint] \
            ::tcltest::testConstraint] == -1} {
        set ::tcltest::testConfig(need_i18n) 1
        set ::tcltest::testConstraints(need_i18n) 1
        if {[info procs ::tDOM::extRefHandler] != ""} {
            set ::tcltest::testConfig(need_uri) 1
            set ::tcltest::testConstraints(need_uri) 1
        }
   } else {
        ::tcltest::testConstraint need_i18n 1
       if {[info procs ::tDOM::extRefHandler] != ""} {
           ::tcltest::testConstraint need_uri 1
       }
    }
}






set timeCmd {clock format [clock seconds]}

set ::tcltest::testSingleFile false

puts stdout "Tcl $tcl_patchLevel tests running in interp:  [info nameofexecutable]"

if {$tcl_version < 8.2} {







|



|

|
|
|



>
>
>
>
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
source [file join [file dir [info script]] loadtdom.tcl]

if {$tcl_version >= 8.1} {
    if {[lsearch [info proc ::tcltest::testConstraint] \
            ::tcltest::testConstraint] == -1} {
        set ::tcltest::testConfig(need_i18n) 1
        set ::tcltest::testConstraints(need_i18n) 1
        if {[info procs ::tdom::extRefHandler] != ""} {
            set ::tcltest::testConfig(need_uri) 1
            set ::tcltest::testConstraints(need_uri) 1
        }
    } else {
        ::tcltest::testConstraint need_i18n 1
        if {[info procs ::tdom::extRefHandler] != ""} {
            ::tcltest::testConstraint need_uri 1
        }
    }
}

::tcltest::testConstraint needExpand 1
if {$tcl_version < 8.5} {
    ::tcltest::testConstraint needExpand 0
}
    
set timeCmd {clock format [clock seconds]}

set ::tcltest::testSingleFile false

puts stdout "Tcl $tcl_patchLevel tests running in interp:  [info nameofexecutable]"

if {$tcl_version < 8.2} {

Changes to tests/comment.test.

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
..
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    $parser parse {<?xml version="1.0"?>
<!DOCTYPE Test>
<Test>surrounding <!--This is a comment--> PCDATA</Test>
}
    list $::comment $::result $::element
} {{This is a comment} {surrounding  PCDATA} 0}

test comment-1.3 {Simple comment, no white space} {
    set ::result {}
    set ::comment {}
    set ::element 0

    catch {rename xml::comment-1.3 {}}
    set parser [xml::parser comment-1.3 \
	-elementstartcommand Estart \
................................................................................
    $parser parse {<?xml version="1.0"?>
<!DOCTYPE Test>
<Test><!--comment--></Test>
}
    list $::comment $::result $::element
} {comment {} 0}

test comment-1.4 {comment, with nested element} {
    set ::result {}
    set ::comment {}
    set ::element 0

    catch {rename xml::comment-1.4 {}}
    set parser [xml::parser comment-1.4 \
	-elementstartcommand Estart \







|







 







|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
..
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    $parser parse {<?xml version="1.0"?>
<!DOCTYPE Test>
<Test>surrounding <!--This is a comment--> PCDATA</Test>
}
    list $::comment $::result $::element
} {{This is a comment} {surrounding  PCDATA} 0}

test comment-1.4 {Simple comment, no white space} {
    set ::result {}
    set ::comment {}
    set ::element 0

    catch {rename xml::comment-1.3 {}}
    set parser [xml::parser comment-1.3 \
	-elementstartcommand Estart \
................................................................................
    $parser parse {<?xml version="1.0"?>
<!DOCTYPE Test>
<Test><!--comment--></Test>
}
    list $::comment $::result $::element
} {comment {} 0}

test comment-1.5 {comment, with nested element} {
    set ::result {}
    set ::comment {}
    set ::element 0

    catch {rename xml::comment-1.4 {}}
    set parser [xml::parser comment-1.4 \
	-elementstartcommand Estart \

Added tests/data/xmlspec-v20.dtd.



































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
<!-- ............................................................... -->
<!-- XML specification DTD ......................................... -->
<!-- ............................................................... -->

<!--
TYPICAL INVOCATION:
#  <!DOCTYPE spec PUBLIC
#       "-//W3C//DTD Specification V2.0//EN"
#       "http://www.w3.org/XML/1998/06/xmlspec-v20.dtd">

PURPOSE:
  This DTD was developed for use with the XML family of W3C
  specifications.  It is an XML-compliant DTD based in part on
  the TEI Lite and Sweb DTDs.

DEPENDENCIES:
  None.

CHANGE HISTORY:
  The list of changes is at the end of the DTD.

  For all details, see the design report at:

#   <http://www.w3.org/XML/1998/06/NOTE-xmlspec-v20.htm>

  The "typical invocation" FPI always gets updated to reflect the date
  of the most recent changes.

  Search this file for "#" in the first column to see change history
  comments.

MAINTAINER:
  Eve Maler
  Arbortext, Inc.
  elm@arbortext.com
  voice: +1 781 529 1012
  fax:   +1 781 529 1099
-->

<!-- ............................................................... -->
<!-- Entities for characters and symbols ........................... -->
<!-- ............................................................... -->

<!--
#1998-03-10: maler: Added &ldquo; and &rdquo;.
#                   Used 8879:1986-compatible decimal character
#                   references.
#                   Merged charent.mod file back into main file.
#1998-05-14: maler: Fixed ldquo and rdquo.  Gave mdash a real number.
#1998-12-03: maler: Escaped the leading ampersands.
-->

<!ENTITY lt     "&#38;#60;">
<!ENTITY gt     "&#62;">
<!ENTITY amp    "&#38;#38;">
<!ENTITY apos   "&#39;">
<!ENTITY quot   "&#34;">
<!ENTITY nbsp   "&#160;">
<!ENTITY mdash  "&#38;#x2014;">
<!ENTITY ldquo  "&#38;#x201C;">
<!ENTITY rdquo  "&#38;#x201D;">

<!-- ............................................................... -->
<!-- Entities for classes of standalone elements ................... -->
<!-- ............................................................... -->

<!--
#1997-10-16: maler: Added table to %illus.class;.
#1997-11-28: maler: Added htable to %illus.class;.
#1997-12-29: maler: IGNOREd table.
#1998-03-10: maler: Removed SGML Open-specific %illus.class;.
#                   Added "local" entities for customization.
#1998-05-14: maler: Added issue to %note.class;.
#                   Removed %[local.]statusp.class;.
#1998-05-21: maler: Added constraintnote to %note.class;.
#1998-08-22: maler: Changed htable to table in %illus.class;.
#                   Added definitions to %illus.class;.
-->

<!ENTITY % local.p.class        "">
<!ENTITY % p.class              "p
                                %local.p.class;">

<!ENTITY % local.list.class     "">
<!ENTITY % list.class           "ulist|olist|slist|glist
                                %local.list.class;">

<!ENTITY % local.speclist.class "">
<!ENTITY % speclist.class       "orglist|blist
                                %local.speclist.class;">

<!ENTITY % local.note.class     "">
<!ENTITY % note.class           "note|issue|wfcnote|vcnote
                                |constraintnote %local.note.class;">

<!ENTITY % local.illus.class    "">
<!ENTITY % illus.class          "eg|graphic|scrap|table|definitions
                                %local.illus.class;">

<!-- ............................................................... -->
<!-- Entities for classes of phrase-level elements ................. -->
<!-- ............................................................... -->

<!--
#1997-12-29: maler: Added xspecref to %ref.class;.
#1998-03-10: maler: Added %ednote.class;.
#                   Added "local" entities for customization.
-->

<!ENTITY % local.annot.class    "">
<!ENTITY % annot.class          "footnote
                                %local.annot.class;">

<!ENTITY % local.termdef.class  "">
<!ENTITY % termdef.class        "termdef|term
                                %local.termdef.class;">

<!ENTITY % local.emph.class     "">
<!ENTITY % emph.class           "emph|quote
                                %local.emph.class;">

<!ENTITY % local.ref.class      "">
<!ENTITY % ref.class            "bibref|specref|termref|titleref
                                |xspecref|xtermref
                                %local.ref.class;">

<!ENTITY % local.loc.class      "">
<!ENTITY % loc.class            "loc
                                %local.loc.class;">

<!ENTITY % local.tech.class     "">
<!ENTITY % tech.class           "kw|nt|xnt|code
                                %local.tech.class;">

<!ENTITY % local.ednote.class   "">
<!ENTITY % ednote.class         "ednote
                                %local.ednote.class;">

<!-- ............................................................... -->
<!-- Entities for mixtures of standalone elements .................. -->
<!-- ............................................................... -->

<!--
#1997-09-30: maler: Created %p.mix; to eliminate p from self.
#1997-09-30: maler: Added %speclist.class; to %obj.mix; and %p.mix;.
#1997-09-30: maler: Added %note.class; to %obj.mix; and %p.mix;.
#1997-10-16: maler: Created %entry.mix;.  Note that some elements
#                   left out here are still allowed in termdef,
#                   which entry can contain through %p.pcd.mix;.
#1997-11-28: maler: Added %p.class; to %statusobj.mix;.
#1998-03-10: maler: Added %ednote.class; to all mixtures, except
#                   %p.mix; and %statusobj.mix;, because paragraphs
#                   and status paragraphs will contain ednote
#                   through %p.pcd.mix;.
#1998-03-23: maler: Added %termdef.mix; (broken out from
#                    %termdef.pcd.mix;).
#1998-05-14: maler: Removed %statusobj.mix; and all mentions of
#                   %statusp.mix;.
-->

<!ENTITY % div.mix
        "%p.class;|%list.class;|%speclist.class;|%note.class;
        |%illus.class;|%ednote.class;">
<!ENTITY % obj.mix
        "%p.class;|%list.class;|%speclist.class;|%note.class;
        |%illus.class;|%ednote.class;">
<!ENTITY % p.mix
        "%list.class;|%speclist.class;|%note.class;|%illus.class;">
<!ENTITY % entry.mix
        "%list.class;|note|eg|graphic|%ednote.class;">
<!ENTITY % hdr.mix
        "%p.class;|%list.class;|%ednote.class;">
<!ENTITY % termdef.mix
        "%note.class;|%illus.class;">

<!-- ............................................................... -->
<!-- Entities for mixtures of #PCDATA and phrase-level elements .... -->
<!-- ............................................................... -->

<!--    Note that %termdef.pcd.mix contains %note.class;
        and %illus.class;, considered standalone elements. -->

<!--
#1997-09-30: maler: Added scrap and %note.class; to %termdef.pcd.mix;.
#1997-11-28: maler: Added %loc.class; to %p.pcd.mix;.
#1998-03-10: maler: Added %ednote.class; to all mixtures.
#1998-03-23: maler: Moved some %termdef.pcd.mix; stuff out to
#                   %termdef.mix;.
#1998-05-14: maler: Removed %statusp.pcd.mix;.
#1998-05-21: maler: Added constraint element to %eg.pcd.mix;.
#1999-07-02: maler: Added %loc.class; to %head.pcd.mix;,
#                   %label.pcd.mix;, %eg.pcd.mix;, %termdef.pcd.mix;,
#                   %tech.pcd.mix; (net: all PCD mixes have it).
#                   Removed unused %loc.pcd.mix;.
-->

<!ENTITY % p.pcd.mix
        "#PCDATA|%annot.class;|%termdef.class;|%emph.class;
        |%ref.class;|%tech.class;|%loc.class;|%ednote.class;">
<!ENTITY % head.pcd.mix
        "#PCDATA|%annot.class;|%emph.class;|%tech.class;
        |%loc.class;|%ednote.class;">
<!ENTITY % label.pcd.mix
        "#PCDATA|%annot.class;|%termdef.class;|%emph.class;
        |%tech.class;|%loc.class;|%ednote.class;">
<!ENTITY % eg.pcd.mix
        "#PCDATA|%annot.class;|%emph.class;|%loc.class;
        |%ednote.class;|constraint">
<!ENTITY % termdef.pcd.mix
        "#PCDATA|term|%emph.class;|%ref.class;|%tech.class;
        |%loc.class;|%ednote.class;">
<!ENTITY % bibl.pcd.mix
        "#PCDATA|%emph.class;|%ref.class;|%loc.class;|%ednote.class;">
<!ENTITY % tech.pcd.mix
        "#PCDATA|%loc.class;|%ednote.class;">

<!-- ............................................................... -->
<!-- Entities for customizable content models ...................... -->
<!-- ............................................................... -->

<!--
#1998-03-10: maler: Added customization entities.
#1998-05-14: maler: Allowed prevlocs and latestloc in either order.
#1999-07-02: maler: Made version optional; added copyright element.
-->

<!ENTITY % spec.mdl
        "header, front?, body, back?">

<!ENTITY % header.mdl
        "title, subtitle?, version?, w3c-designation, w3c-doctype,
        pubdate, notice*, publoc, ((prevlocs, latestloc?) |
        (latestloc, prevlocs?))?, authlist, copyright?, status,
        abstract, pubstmt?, sourcedesc?, langusage, revisiondesc">

<!ENTITY % pubdate.mdl
        "day?, month, year">

<!-- ............................................................... -->
<!-- Entities for common attributes ................................ -->
<!-- ............................................................... -->

<!--    key attribute:
        Optionally provides a sorting or indexing key, for cases when
        the element content is inappropriate for this purpose. -->
<!ENTITY % key.att
        'key                    CDATA           #IMPLIED'>

<!--    def attribute:
        Points to the element where the relevant definition can be
        found, using the IDREF mechanism.  %def.att; is for optional
        def attributes, and %def-req.att; is for required def
        attributes. -->
<!ENTITY % def.att
        'def                    IDREF           #IMPLIED'>
<!ENTITY % def-req.att
        'def                    IDREF           #REQUIRED'>

<!--    ref attribute:
        Points to the element where more information can be found,
        using the IDREF mechanism.  %ref.att; is for optional
        ref attributes, and %ref-req.att; is for required ref
        attributes. -->
<!ENTITY % ref.att
        'ref                    IDREF           #IMPLIED'>
<!ENTITY % ref-req.att
        'ref                    IDREF           #REQUIRED'>

<!--
#1998-03-23: maler: Added show and actuate attributes to href.
#                   Added semi-common xml:space attribute.
#1998-08-22: maler: Used new xlink:form and #IMPLIED features.
#1999-07-02: maler: Reorganized XLink-related entities completely;
#                   added xmlns:xlink attribute to the mix.
-->

<!--    xmlns:xlink and xlink:form attributes:
        xmlns:xlink declares the association of the xlink prefix
        with the namespace created by the XLink specification.
        xlink:form potentially identifies an element as an XLink
        "simple" linking element.  When a value for href is supplied,
        xlink:form should be understood to have the value "simple".
        When a value for href is not supplied, xlink:form should be
        understood to have the value "none". -->
<!ENTITY % simple-xlink.att
        'xmlns:xlink            CDATA           #FIXED
                                                "http://www.w3.org/TR/WD-xlink"
        xlink:form              CDATA           #IMPLIED '>

<!--    href attributes:
        The href attribute is required to have a value when xlink:form
        has the (implicit or explicit) value "simple".  Some elements
        are links only if the authors chooses to make them so. -->
<!ENTITY % href.att
        'href                   CDATA           #IMPLIED '>
<!ENTITY % href-req.att
        'href                    CDATA           #REQUIRED '>

<!--    show and actuate attributes:
        These attributes offer hints to the display engine about how to
        handle traversal to a link end indicated by an href locator.  The
        auto-embed combination should have the effect of an HTML IMG SRC=.
        The user-replace combination should have the effect of an HTML
        A HREF=.  The user-new combination should have the effect of an
        HTML A HREF= TARGET=NEW.
        -->
<!ENTITY % auto-embed.att
        'show                   CDATA           #FIXED "embed"
        actuate                 CDATA           #FIXED "auto" '>
<!ENTITY % user-replace.att
        'show                   CDATA           #FIXED "replace"
        actuate                 CDATA           #FIXED "user" '>
<!ENTITY % user-new.att
        'show                   CDATA           #FIXED "new"
        actuate                 CDATA           #FIXED "user" '>

<!--    xml:space attribute:
        Indicates that the element contains white space
        that the formatter or other application should retain,
        as appropriate to its function. -->
<!ENTITY % xmlspace.att
        'xml:space              (default
                                |preserve)      #FIXED "preserve" '>

<!--    Common attributes:
        Every element has an ID attribute (sometimes required,
        but usually optional) for links, and a Role attribute
        for extending the useful life of the DTD by allowing
        authors to make subclasses for any element. %common.att;
        is for common attributes where the ID is optional, and
        %common-idreq.att; is for common attributes where the
        ID is required. -->
<!ENTITY % common.att
        'id                     ID              #IMPLIED
        role                    NMTOKEN         #IMPLIED'>
<!ENTITY % common-idreq.att
        'id                     ID              #REQUIRED
        role                    NMTOKEN         #IMPLIED'>

<!-- ............................................................... -->
<!-- Common elements ............................................... -->
<!-- ............................................................... -->

<!--    head: Title on divisions, productions, and the like -->
<!ELEMENT head (%head.pcd.mix;)*>
<!ATTLIST head %common.att;>

<!-- ............................................................... -->
<!-- Major specification structure ................................. -->
<!-- ............................................................... -->

<!--
#1998-03-10: maler: Made spec content model easily customizable.
#1999-07-02: maler: Added doctype atts and status att.
-->

<!ELEMENT spec (%spec.mdl;)>
<!--    doctype attributes:
        Indicates the type of document, so that the appropriate
        stylesheet or workflow routing can be applied.  Should
        *not* generate any text (such as the "REC-" or "NOTE-"
        prefix on the W3C designation content).  No default.  If
        w3c-doctype is "other", other-doctype should be filled in.
        status attribute:
        Indicates the stage of review of the document.  May affect
        the stylesheet's treatment of ednotes (e.g., whether to
        output them).  No default. -->

<!ATTLIST spec
        %common.att;
        w3c-doctype     (rec
                        |pr
                        |wd
                        |note
                        |other)                 #IMPLIED
        other-doctype   CDATA                   #IMPLIED
        status          (int-review
                        |ext-review
                        |final)                 #IMPLIED
>

<!ELEMENT front (div1+)>
<!ATTLIST front %common.att;>

<!ELEMENT body (div1+)>
<!ATTLIST body %common.att;>

<!--
#1997-09-30: maler: Added inform-div1 to back content.
-->

<!ELEMENT back ((div1+, inform-div1*) | inform-div1+)>
<!ATTLIST back %common.att;>

<!ELEMENT div1 (head, (%div.mix;)*, div2*)>
<!ATTLIST div1 %common.att;>

<!--
#1997-09-30: maler: Added inform-div1 declarations.
-->

<!--    inform-div1: Non-normative division in back matter -->
<!ELEMENT inform-div1 (head, (%div.mix;)*, div2*)>
<!ATTLIST inform-div1 %common.att;>

<!ELEMENT div2 (head, (%div.mix;)*, div3*)>
<!ATTLIST div2 %common.att;>

<!ELEMENT div3 (head, (%div.mix;)*, div4*)>
<!ATTLIST div3 %common.att;>

<!ELEMENT div4 (head, (%div.mix;)*)>
<!ATTLIST div4 %common.att;>

<!-- ............................................................... -->
<!-- Specification header .......................................... -->
<!-- ............................................................... -->

<!--
#1998-03-10: maler: Made header content model easily customizable.
-->

<!ELEMENT header (%header.mdl;)>
<!ATTLIST header %common.att;>

<!--    Example of title: "Extensible Cheese Language (XCL)" -->
<!ELEMENT title (#PCDATA)>
<!ATTLIST title %common.att;>

<!--    Example of subtitle: "A Cheesy Specification" -->
<!ELEMENT subtitle (#PCDATA)>
<!ATTLIST subtitle %common.att;>

<!--    Example of version: "Version 666.0" -->
<!ELEMENT version (#PCDATA)>
<!ATTLIST version %common.att;>

<!--    Example of w3c-designation: "WD-xcl-19991231" -->
<!ELEMENT w3c-designation (#PCDATA)>
<!ATTLIST w3c-designation %common.att;>

<!--    Example of w3c-doctype: "World Wide Web Consortium Working
        Draft" -->
<!ELEMENT w3c-doctype (#PCDATA)>
<!ATTLIST w3c-doctype %common.att;>

<!--
#1998-03-10: maler: Made pubdate content model easily customizable.
-->

<!ELEMENT pubdate (%pubdate.mdl;)>
<!ATTLIST pubdate %common.att;>

<!ELEMENT day (#PCDATA)>
<!ATTLIST day %common.att;>

<!ELEMENT month (#PCDATA)>
<!ATTLIST month %common.att;>

<!ELEMENT year (#PCDATA)>
<!ATTLIST year %common.att;>

<!--
#1999-07-02: maler: Declared copyright element.
-->

<!ELEMENT copyright (%hdr.mix;)+>
<!ATTLIST copyright %common.att;>

<!--    Example of notice: "This draft is for public comment..." -->
<!ELEMENT notice (%hdr.mix;)+>
<!ATTLIST notice %common.att;>

<!ELEMENT publoc (loc+)>
<!ATTLIST publoc %common.att;>

<!ELEMENT prevlocs (loc+)>
<!ATTLIST prevlocs %common.att;>

<!ELEMENT latestloc (loc+)>
<!ATTLIST latestloc %common.att;>

<!--      loc (defined in "Phrase-level elements" below) -->

<!ELEMENT authlist (author+)>
<!ATTLIST authlist %common.att;>

<!--
#1997-09-30: maler: Made affiliation optional.
#1998-03-10: maler: Made email optional.
-->

<!ELEMENT author (name, affiliation?, email?)>
<!ATTLIST author %common.att;>

<!ELEMENT name (#PCDATA)>
<!ATTLIST name
        %common.att;
        %key.att;>

<!ELEMENT affiliation (#PCDATA)>
<!ATTLIST affiliation %common.att;>

<!--
#1999-07-02: maler: Added show/actuate attributes and default values.
-->


<!ELEMENT email (#PCDATA)>
<!--    href attribute:
        email functions as a hypertext reference through this
        required attribute.  Typically the reference would use
        the mailto: scheme.  E.g.:

<email href="mailto:elm@arbortext.com">elm@arbortext.com</email>
        -->

<!ATTLIST email
        %common.att;
        %simple-xlink.att;
        %href-req.att;
        %user-new.att;>

<!--
#1998-05-15: maler: Changed status content from %statusobj.mix;
#                   to plain %obj.mix;.  statusp is obsolete.
-->

<!ELEMENT status (%obj.mix;)+>
<!ATTLIST status %common.att;>

<!ELEMENT abstract (%hdr.mix;)*>
<!ATTLIST abstract %common.att;>

<!ELEMENT pubstmt (%hdr.mix;)+>
<!ATTLIST pubstmt %common.att;>

<!ELEMENT sourcedesc (%hdr.mix;)+>
<!ATTLIST sourcedesc %common.att;>

<!ELEMENT langusage (language+)>
<!ATTLIST langusage %common.att;>

<!ELEMENT language (#PCDATA)>
<!ATTLIST language %common.att;>

<!ELEMENT revisiondesc (%hdr.mix;)+>
<!ATTLIST revisiondesc %common.att;>

<!-- ............................................................... -->
<!-- Paragraph ..................................................... -->
<!-- ............................................................... -->

<!--
#1997-09-30: maler: Changed from %obj.mix; to %p.mix;.
#1997-12-29: maler: Changed order of %p.mix; and %p.pcd.mix;
#                   references.
#1997-12-29: maler: Changed order of %statusobj.mix; and
#                   %statusp.pcd.mix; references.
#1998-05-14: maler: Removed statusp declarations.
-->

<!ELEMENT p (%p.pcd.mix;|%p.mix;)*>
<!ATTLIST p %common.att;>

<!-- ............................................................... -->
<!-- Regular lists ................................................. -->
<!-- ............................................................... -->

<!--    ulist: Unordered list, typically bulleted. -->
<!ELEMENT ulist (item+)>
<!--    spacing attribute:
        Use "normal" to get normal vertical spacing for items;
        use "compact" to get less spacing.  The default is dependent
        on the stylesheet. -->
<!ATTLIST ulist
        %common.att;
        spacing         (normal|compact)        #IMPLIED>

<!--    olist: Ordered list, typically numbered. -->
<!ELEMENT olist (item+)>
<!--    spacing attribute:
        Use "normal" to get normal vertical spacing for items;
        use "compact" to get less spacing.  The default is dependent
        on the stylesheet. -->
<!ATTLIST olist
        %common.att;
        spacing         (normal|compact)        #IMPLIED>

<!ELEMENT item (%obj.mix;)+>
<!ATTLIST item %common.att;>

<!--    slist: Simple list, typically with no mark. -->
<!ELEMENT slist (sitem+)>
<!ATTLIST slist %common.att;>

<!ELEMENT sitem (%p.pcd.mix;)*>
<!ATTLIST sitem %common.att;>

<!--    glist: Glossary list, typically two-column. -->
<!ELEMENT glist (gitem+)>
<!ATTLIST glist %common.att;>

<!ELEMENT gitem (label, def)>
<!ATTLIST gitem %common.att;>

<!ELEMENT label (%label.pcd.mix;)*>
<!ATTLIST label %common.att;>

<!ELEMENT def (%obj.mix;)*>
<!ATTLIST def %common.att;>

<!-- ............................................................... -->
<!-- Special lists ................................................. -->
<!-- ............................................................... -->

<!--    blist: Bibliography list. -->
<!ELEMENT blist (bibl+)>
<!ATTLIST blist %common.att;>

<!--
#1999-07-02: maler: Added show/actuate attributes and default values.
-->

<!ELEMENT bibl (%bibl.pcd.mix;)*>
<!--    href attribute:
        bibl optionally functions as a hypertext reference to the
        referred-to resource through this attribute.  E.g.:

        <bibl href="http://www.my.com/doc.htm">My Document</bibl>
        -->
<!ATTLIST bibl
        %common.att;
        %simple-xlink.att;
        %href.att;
        %user-replace.att;
        %key.att;>

<!--    orglist: Organization member list. -->
<!ELEMENT orglist (member+)>
<!ATTLIST orglist %common.att;>

<!--
#1997-09-30: maler: Added optional affiliation.
-->

<!ELEMENT member (name, affiliation?, role?)>
<!ATTLIST member %common.att;>

<!--      name (defined in "Specification header" above) -->
<!--      affiliation (defined in "Specification header" above) -->

<!ELEMENT role (#PCDATA)>
<!ATTLIST role %common.att;>

<!-- ............................................................... -->
<!-- Notes ......................................................... -->
<!-- ............................................................... -->

<!ELEMENT note (%obj.mix;)+>
<!ATTLIST note %common.att;>

<!--
#1998-05-14: maler: Declared issue element.
-->

<!ELEMENT issue (%obj.mix;)+>
<!ATTLIST issue %common-idreq.att;>

<!--    wfcnote: Well-formedness constraint note. -->
<!ELEMENT wfcnote (head, (%obj.mix;)+)>
<!--    ID attribute:
        wfcnote must have an ID so that it can be pointed to
        from a wfc element in a production. -->
<!ATTLIST wfcnote
        %common-idreq.att;>

<!--    vcnote: Validity constraint note. -->
<!ELEMENT vcnote (head, (%obj.mix;)+)>
<!--    ID attribute:
        vcnote must have an ID so that it can be pointed to
        from a vc element in a production. -->
<!ATTLIST vcnote
        %common-idreq.att;>

<!--
#1998-05-21: maler: Declared generic constraintnote element.
-->

<!--    constraintnote: Generic constraint note. -->
<!ELEMENT constraintnote (head, (%obj.mix;)+)>
<!--    ID attribute:
        constraintnote must have an ID so that it can be
        pointed to from a constraint element in a production. -->
<!--    type attribute:
        constraintnote must have a type value keyword so that
        it can be correctly characterized in the specification. -->
<!ATTLIST constraintnote
        %common-idreq.att;
        type            NMTOKEN         #REQUIRED>

<!-- ............................................................... -->
<!-- Basic display elements ........................................ -->
<!-- ............................................................... -->

<!--
#1998-03-23: maler: Added xml:space attribute.
-->

<!--    eg: Example element, with whitespace respected. -->
<!ELEMENT eg (%eg.pcd.mix;)*>
<!ATTLIST eg
        %common.att;
        %xmlspace.att;>

<!--    graphic: Displayed graphic.  Graphic data should be
        displayed at the point where it is referenced. -->
<!ELEMENT graphic EMPTY>
<!--    source attribute:
        The graphic data must reside at the location pointed to.
        This is a hypertext reference, but for practical purposes,
        for now it should just be a pathname. -->
<!ATTLIST graphic
        %common.att;
        %simple-xlink.att;
        xml:attributes          NMTOKENS        #FIXED "href source"
        source                  CDATA           #REQUIRED
        %auto-embed.att;
        alt                     CDATA           #IMPLIED>

<!-- ............................................................... -->
<!-- EBNF .......................................................... -->
<!-- ............................................................... -->

<!--
#1997-11-28: maler: Added prodgroup to scrap and defined it.
#1998-05-21: maler: Added constraint to prod.
#1999-07-02: maler: Added prodrecap to scrap; broadened scrap model.
#                   Added headstyle attribute to scrap.
-->

<!--    scrap: Collection of EBNF language productions. -->
<!ELEMENT scrap (head, (prodgroup | prod | bnf | prodrecap)+)>
<!--    lang attribute:
        The scrap can link to a description of the language used,
        found in a language element in the header.
        headstyle attribute:
        Allows a scrap title to be suppressed from output.  To be
        used only when a scrap title directly next to a section
        title is distracting or repetetive. -->
<!ATTLIST scrap
        %common.att;
        lang            IDREF           #IMPLIED
        headstyle       (show|suppress) "show"
>

<!--    prodgroup: Sub-collection of productions, needed for
        formatting reasons. -->
<!ELEMENT prodgroup (prod+)>
<!--    pcw<n> attributes:
        Presentational attributes to control the width
        of the "pseudo-table" columns used to output
        groups of productions. -->
<!ATTLIST prodgroup
        %common.att;
        pcw1            CDATA           #IMPLIED
        pcw2            CDATA           #IMPLIED
        pcw3            CDATA           #IMPLIED
        pcw4            CDATA           #IMPLIED
        pcw5            CDATA           #IMPLIED
>

<!--    prod: EBNF language production. -->
<!ELEMENT prod (lhs, (rhs, (com|wfc|vc|constraint)*)+)>
<!--    ID attribute:
        The production must have an ID so that cross-references
        (specref) and mentions of nonterminals (nt) can link to
        it. -->
<!ATTLIST prod
        %common-idreq.att;>

<!--    lhs: Left-hand side of production. -->
<!ELEMENT lhs (#PCDATA)>
<!ATTLIST lhs %common.att;>

<!--    rhs: Right-hand side of production; may have many
        "right-hand sides," one to a line. -->
<!ELEMENT rhs (#PCDATA|nt|xnt|com)*>
<!ATTLIST rhs %common.att;>

<!--      nt and xnt (defined in "Phrase-level elements" below) -->

<!--
#1997-11-28: maler: Added loc and bibref to com content.
-->

<!--    com: Production comment. -->
<!ELEMENT com (#PCDATA|loc|bibref)*>
<!ATTLIST com %common.att;>

<!--    wfc: Reference to a well-formedness constraint; should
        generate the head of the wfcnote pointed to. -->
<!ELEMENT wfc EMPTY>
<!--    def attribute:
        Each well formedness tagline in a production must link to the
        wfcnote that defines it. -->
<!ATTLIST wfc
        %def-req.att;
        %common.att;>

<!--    vc: Reference to a validity constraint; should generate
        the head of the vcnote pointed to. -->
<!ELEMENT vc EMPTY>
<!--    def attribute:
        Each validity tagline in a production must link to the vcnote
        that defines it. -->
<!ATTLIST vc
        %def-req.att;
        %common.att;>

<!--
#1998-05-21: maler: Declared generic constraint element.
-->

<!--    constraint: Reference to a generic constraint; should
        generate the head of the constraintnote pointed to. -->
<!ELEMENT constraint EMPTY>
<!--    def attribute:
        Each constraint tagline in a production must link to the
        constraint note that defines it. -->
<!ATTLIST constraint
        %def-req.att;
        %common.att;>

<!--
#1998-03-23: maler: Added xml:space attribute.
-->

<!--    bnf: Un-marked-up EBNF production, with whitespace
        respected. -->
<!ELEMENT bnf (%eg.pcd.mix;)*>
<!ATTLIST bnf
        %common.att;
        %xmlspace.att;>

<!--
#1999-07-02: maler: Declared prodrecap.
-->

<!--    prodrecap: Reference to production or bnf that appears
        in its "normative" form elsewhere in the spec; should
        generate a copy of the original production, without
        a production number next to it. -->
<!ELEMENT prodrecap EMPTY>
<!ATTLIST prodrecap
        %common.att;
        %ref-req.att;>

<!-- ............................................................... -->
<!-- Table ......................................................... -->
<!-- ............................................................... -->

<!--
#1997-10-16: maler: Added table mechanism.
#1997-11-28: maler: Added non-null system ID to entity declaration.
#                   Added HTML table module.
#1997-12-29: maler: IGNOREd SGML Open table model.
#1998-03-10: maler: Removed SGML Open table model.
#                   Merged html-tbl.mod file into main file.
#                   Added %common.att; to all HTML table elements.
#1998-05-14: maler: Replaced table model with full HTML 4.0 model.
#                   Removed htable in favor of table.
#                   Removed htbody in favor of tbody.
-->

<!ENTITY % cellhalign.att
        'align          (left|center
                        |right|justify
                        |char)          #IMPLIED
        char            CDATA           #IMPLIED
        charoff         CDATA           #IMPLIED'>

<!ENTITY % cellvalign.att
        'valign         (top|middle
                        |bottom
                        |baseline)      #IMPLIED'>

<!ENTITY % thtd.att
        'abbr           CDATA           #IMPLIED
        axis            CDATA           #IMPLIED
        headers         IDREFS          #IMPLIED
        scope           (row
                        |col
                        |rowgroup
                        |colgroup)      #IMPLIED
        rowspan         NMTOKEN         "1"
        colspan         NMTOKEN         "1"'>

<!ENTITY % width.att
        'width          CDATA           #IMPLIED'>

<!ENTITY % span.att
        'span           NMTOKEN         "1"'>

<!--    table: HTML-based geometric table model. -->
<!ELEMENT table
        (caption?, (col*|colgroup*), thead?, tfoot?, tbody+)>
<!ATTLIST table
        %common.att;
        %width.att;
        summary         CDATA           #IMPLIED
        border          CDATA           #IMPLIED
        frame           (void|above
                        |below|hsides
                        |lhs|rhs
                        |vsides|box
                        |border)        #IMPLIED
        rules           (none|groups
                        |rows|cols
                        |all)           #IMPLIED
        cellspacing     CDATA           #IMPLIED
        cellpadding     CDATA           #IMPLIED>

<!ELEMENT caption (%p.pcd.mix;)*>
<!ATTLIST caption %common.att;>

<!ELEMENT col EMPTY>
<!ATTLIST col
        %common.att;
        %span.att;
        %width.att;
        %cellhalign.att;
        %cellvalign.att;>

<!ELEMENT colgroup (col)*>
<!ATTLIST colgroup
        %common.att;
        %span.att;
        %width.att;
        %cellhalign.att;
        %cellvalign.att;>

<!ELEMENT thead (tr)+>
<!ATTLIST thead
        %common.att;
        %cellhalign.att;
        %cellvalign.att;>

<!ELEMENT tfoot (tr)+>
<!ATTLIST tfoot
        %common.att;
        %cellhalign.att;
        %cellvalign.att;>

<!ELEMENT tbody (tr)+>
<!ATTLIST tbody
        %common.att;
        %cellhalign.att;
        %cellvalign.att;>

<!ELEMENT tr (th|td)+>
<!ATTLIST tr
        %common.att;
        %cellhalign.att;
        %cellvalign.att;>

<!ELEMENT th (%p.pcd.mix;|%p.mix;)*>
<!ATTLIST th
        %common.att;
        %thtd.att;
        %cellhalign.att;
        %cellvalign.att;>

<!ELEMENT td (%p.pcd.mix;|%p.mix;)*>
<!ATTLIST td
        %common.att;
        %thtd.att;
        %cellhalign.att;
        %cellvalign.att;>

<!-- ............................................................... -->
<!-- IDL structures for DOM specifications ......................... -->
<!-- ............................................................... -->

<!-- ............................................................... -->
<!-- Specialized entities for classes .............................. -->

<!ENTITY % idl-desc.class
        "p|note">

<!ENTITY % idl-tdef.class
        "typedef|constant|exception|reference|group">

<!ENTITY % idl-mod.class
        "module|interface">

<!ENTITY % idl-struct.class
        "struct|enum|sequence|union|typename">

<!ENTITY % idl-meth.class
        "method|attribute">

<!-- ............................................................... -->
<!-- Specialized entities for mixtures ............................. -->

<!--    Quick reference to content model mixtures:

                        desc tdef mod struct meth
group                     x    x   x    x      x
definitions, module       x    x   x
interface                 x    x               x
typedef, case, component                x
-->

<!ENTITY % idl-grp.mix
        "%idl-desc.class;|%idl-tdef.class;|%idl-mod.class;
        |%idl-struct.class;|%idl-meth.class;">

<!ENTITY % idl-defn.mix
        "%idl-desc.class;|%idl-tdef.class;|%idl-mod.class;">

<!ENTITY % idl-intfc.mix
        "%idl-desc.class;|%idl-tdef.class;|%idl-meth.class;">

<!ENTITY % idl-type.mix
        "%idl-struct.class;">

<!-- ............................................................... -->
<!-- Specialized entities for common attributes .................... -->

<!--    name attribute:
        Provides a name.  Required. -->
<!ENTITY % idl-name.att
        'name                   CDATA           #REQUIRED'>

<!--    type attribute:
        Provides a type.  Required. -->
<!ENTITY % idl-type.att
        'type                   CDATA           #REQUIRED'>

<!-- ............................................................... -->
<!-- Common IDL element ............................................ -->

<!ELEMENT descr ((%obj.mix;)*)>
<!ATTLIST descr %common.att;>

<!-- ............................................................... -->
<!-- IDL definition elements ....................................... -->

<!--    definitions: Top-level element for definitions. -->
<!ELEMENT definitions (%idl-defn.mix;)+>
<!ATTLIST definitions %common.att;>

<!--    group: Element used to group a set of definitions. -->

<!ELEMENT group (descr, (%idl-grp.mix;)*)>
<!ATTLIST group
        %common.att;
        %idl-name.att;>

<!--    interface: Definition of an interface. -->
<!ELEMENT interface (descr, (%idl-intfc.mix;)*)>
<!ATTLIST interface
        %common.att;
        %idl-name.att;
        inherits        CDATA           #IMPLIED>

<!--    module: Definition of a module. -->
<!ELEMENT module (descr, (%idl-defn.mix;)*)>
<!ATTLIST module
        %common.att;
        %idl-name.att;>

<!--    reference: Reference to some other declaration. -->
<!ELEMENT reference EMPTY>
<!ATTLIST reference
        %common.att;
        declaration     IDREF           #REQUIRED>

<!--    typedef: Definition of a named type. -->
<!ELEMENT typedef (descr, (%idl-type.mix;))>
<!ATTLIST typedef
        %common.att;
        %idl-name.att;
        array.size      NMTOKEN         #IMPLIED>

<!--    struct: Declaration of a struct type. -->
<!ELEMENT struct (descr, component+)>
<!ATTLIST struct
        %common.att;
        %idl-name.att;>

<!--    component: Declaration of a structural member. -->
<!ELEMENT component (%idl-type.mix;)>
<!ATTLIST component
        %common.att;
        %idl-name.att;>

<!--    union: Declaration of a union type. -->
<!ELEMENT union (descr, case+)>
<!ATTLIST union
        %common.att;
        %idl-name.att;
        switch.type     CDATA           #REQUIRED>

<!ELEMENT case (descr, (%idl-type.mix;))>
<!ATTLIST case
        %common.att;
        labels          CDATA           #REQUIRED>

<!--    enum: Declaration of an enum type. -->
<!ELEMENT enum (descr, enumerator+)>
<!ATTLIST enum
        %common.att;
        %idl-name.att;>

<!ELEMENT enumerator (descr)>
<!ATTLIST enumerator
        %common.att;
        %idl-name.att;>

<!--    sequence: Declaration of a sequence type (not named). -->
<!ELEMENT sequence (sequence*)>
<!ATTLIST sequence
        %common.att;
        %idl-type.att;
        size            NMTOKEN         #IMPLIED>

<!--    constant: Declaration of a named constant. -->
<!ELEMENT constant (descr)>
<!ATTLIST constant
        %common.att;
        %idl-name.att;
        %idl-type.att;
        value           CDATA           #REQUIRED>

<!--    exception: Declaration of an exception. -->
<!ELEMENT exception (descr, component*)>
<!ATTLIST exception
        %common.att;
        %idl-name.att;>
<!-- component (defined under struct, above)-->

<!--    attribute: Declaration of an attribute (data member). -->
<!ELEMENT attribute (descr)>
<!ATTLIST attribute
        %common.att;
        %idl-name.att;
        %idl-type.att;
        readonly        (yes
                        |no)            "no">

<!--    method: Declaration of a method. -->
<!ELEMENT method (descr, parameters, returns, raises)>
<!ATTLIST method
        %common.att;
        %idl-name.att;>

<!ELEMENT parameters (param*)>
<!ATTLIST parameters %common.att;>

<!ELEMENT param (descr)>
<!ATTLIST param
        %common.att;
        %idl-name.att;
        %idl-type.att;
        attr            (in
                        |out
                        |inout)         "inout">

<!ELEMENT returns (descr)>
<!ATTLIST returns
        %common.att;
        %idl-type.att;>

<!ELEMENT raises (exception*)>
<!-- exception (defined under constant, above)-->

<!ELEMENT typename (#PCDATA)>
<!ATTLIST typename %common.att;>

<!-- ............................................................... -->
<!-- Phrase-level elements ......................................... -->
<!-- ............................................................... -->

<!--    bibref: Reference to a bibliography list entry; should
        generate, in square brackets, "key" on bibl. -->
<!ELEMENT bibref EMPTY>
<!--    ref attribute:
        A bibliography reference must link to the bibl element that
        describes the resource. -->
<!ATTLIST bibref
        %common.att;
        %ref-req.att;>

<!ELEMENT code (%tech.pcd.mix;)*>
<!ATTLIST code %common.att;>

<!--
#1998-03-10: maler: Declared ednote and related elements.
#1999-07-02: maler: Changed edtext content from #PCDATA to %p.pcd.mix;.
-->

<!--    ednote: Editorial note for communication among editors. -->
<!ELEMENT ednote (name?, date?, edtext)>
<!ATTLIST ednote %common.att;>

<!ELEMENT date (#PCDATA)>
<!ATTLIST date %common.att;>

<!ELEMENT edtext (%p.pcd.mix;)*>
<!ATTLIST edtext %common.att;>

<!ELEMENT emph (#PCDATA)>
<!ATTLIST emph %common.att;>

<!--    footnote: Both footnote content and call to footnote. -->
<!ELEMENT footnote (%obj.mix;)+>
<!ATTLIST footnote %common.att;>

<!ELEMENT kw (%tech.pcd.mix;)*>
<!ATTLIST kw %common.att;>

<!--
#1999-07-02: maler: Added show/actuate attributes and default values.
-->

<!--    loc: Generic link to a Web resource, similar to HTML's A. -->
<!ELEMENT loc (#PCDATA)>
<!--    href attribute:
        The purpose of a loc element is to function as a A-like
        hypertext link to a resource.  (Ideally, the content of loc
        will also mention the URI of the resource, so that readers of
        the printed version will be able to locate the resource.) E.g.:

<loc href="http://www.my.com/doc.htm">http://www.my.com/doc.htm</loc>
        -->
<!ATTLIST loc
        %common.att;
        %simple-xlink.att;
        %href-req.att;
        %user-replace.att;>

<!--    nt: Mention of a nonterminal in text, along with a link to
        the production in the current document that defines it. -->
<!ELEMENT nt (#PCDATA)>
<!--    def attribute:
        The nonterminal must link to the production that defines
        it. -->
<!ATTLIST nt
        %common.att;
        %def-req.att;>

<!--
#1998-03-10: maler: Declared quote.
-->

<!--    quote: Scare quotes and other purely presentational quotes. -->
<!ELEMENT quote (%p.pcd.mix;)*>
<!ATTLIST quote %common.att;>

<!--    specref: Reference to a div, olist item, prod, or issue
        in the current document; should generate italic "[n.n],
        Section Title" for div, "n" for numbered item, "[n]" for
        production, or "Issue n" for issue. -->
<!ELEMENT specref EMPTY>
<!--    ref attribute:
        The purpose of a specref element is to link to a div, item
        in an olist, or production in the current spec. -->
<!ATTLIST specref
        %common.att;
        %ref-req.att;>

<!--    term: The term in text that is being defined in text. -->
<!ELEMENT term (#PCDATA)>
<!ATTLIST term %common.att;>

<!--    termdef: Definition of a term in text. -->
<!ELEMENT termdef (%termdef.pcd.mix;|%termdef.mix;)*>
<!--    ID attribute:
        A term definition must have an ID so that it can be linked
        to from termref elements. -->
<!--    term attribute:
        The canonical form of the term or phrase being defined must
        appear in this attribute, even if the term or phrase also
        appears in the element content in identical form (e.g., in
        the term element). -->
<!ATTLIST termdef
        %common-idreq.att;
        term            CDATA           #REQUIRED>

<!--    termref: Mention of a term, along with a link to the
        definition in the current document. -->
<!ELEMENT termref (#PCDATA)>
<!--    ref attribute:
        A term reference must link to the termdef element that
        defines the term. -->
<!ATTLIST termref
        %common.att;
        %def-req.att;>

<!--
#1999-07-02: maler: Added show/actuate attributes and default values.
-->

<!--    titleref: Citation of another document, which can also
        link to that document if it is a Web resource. -->
<!ELEMENT titleref (#PCDATA)>
<!--    href attribute:
        A title reference can optionally function as a hypertext
        link to the resource with this title.  E.g.:

<loc href="http://www.my.com/doc.htm">http://www.my.com/doc.htm</loc>
        -->

<!ATTLIST titleref
        %common.att;
        %simple-xlink.att;
        %href.att;
        %user-new.att;>

<!--
#1999-07-02: maler: Added show/actuate attributes and default values.
-->

<!--    nt: Mention of a nonterminal in text, along with a link to
        the production in another document that defines it. -->
<!ELEMENT xnt (#PCDATA)>
<!--    href attribute:
        The nonterminal must hyperlink to a resource that serves
        to define it (e.g., a production in a related XML
        specification).  E.g.:

<xnt href="http://www.w3.org/TR/spec.htm#prod3">Name</xnt>
        -->

<!ATTLIST xnt
        %common.att;
        %simple-xlink.att;
        %href-req.att;
        %user-new.att;>

<!--
#1997-12-29: maler: Declared xspecref.
#1999-07-02: maler: Added show/actuate attributes and default values.
-->

<!--    specref: Reference to a div, olist item, prod, or issue
        in a related specification document; should generate
        no special text. -->
<!ELEMENT xspecref (#PCDATA)>
<!--    href attribute:
        The spec reference must hyperlink to the resource to
        cross-refer to (e.g., a section in a related XML
        specification).  E.g.:

<xspecref href="http://www.w3.org/TR/spec.htm#sec2">
the section on constraints</xspecref>
        -->

<!ATTLIST xspecref
        %common.att;
        %simple-xlink.att;
        %href-req.att;
        %user-new.att;>

<!--
#1999-07-02: maler: Added show/actuate attributes and default values.
-->

<!--    termref: Mention of a term, along with a link to the
        definition in a related document. -->
<!ELEMENT xtermref (#PCDATA)>
<!--    href attribute:
        The term reference must hyperlink to the resource that
        serves to define the term (e.g., a term definition in
        a related XML specification).  E.g.:

<xtermref href="http://www.w3.org/TR/spec.htm#term5">
entity
</xtermref>
        -->

<!ATTLIST xtermref
        %common.att;
        %simple-xlink.att;
        %href-req.att;
        %user-new.att;>

<!-- ............................................................... -->
<!-- Unused elements for ADEPT ..................................... -->
<!-- ............................................................... -->

<!--
#1997-09-30: maler: Added unusued elements.
#1997-10-14: maler: Fixed div to move nested div to the mixture.
#1998-05-14: maler: Added key-term, htable, and htbody.
#1998-11-30: maler: Added para, listitem, itemizedlist, and orderedlist.
-->

<!--    The following elements are purposely declared but never
        referenced.  Declaring them allows them to be pasted from
        an HTML document, an earlier version of an XMLspec document,
        or a DocBook document into a document using this DTD in ADEPT.
        The ATD Context Transformation mechanism will try to convert
        them to the appropriate element for this DTD.  While this
        conversion will not work for all fragments, it does allow many
        cases to work reasonably well. -->

<!ELEMENT div
        (head?, (%div.mix;|ul|ol|h1|h2|h3|h4|h5|h6|div)*)>
<!ELEMENT h1 (%head.pcd.mix;|em|a)*>
<!ELEMENT h2 (%head.pcd.mix;|em|a)*>
<!ELEMENT h3 (%head.pcd.mix;|em|a)*>
<!ELEMENT h4 (%head.pcd.mix;|em|a)*>
<!ELEMENT h5 (%head.pcd.mix;|em|a)*>
<!ELEMENT h6 (%head.pcd.mix;|em|a)*>
<!ELEMENT pre (%eg.pcd.mix;|em)*>
<!ELEMENT ul (item|li)*>
<!ELEMENT ol (item|li)*>
<!ELEMENT li (#PCDATA|%obj.mix;)*>
<!ELEMENT em (#PCDATA)>
<!ELEMENT a (#PCDATA)>

<!ELEMENT key-term (#PCDATA)>
<!ELEMENT htable
        (caption?, (col*|colgroup*), thead?, tfoot?, tbody+)>
<!ELEMENT htbody (tr)+>
<!ELEMENT statusp (%p.pcd.mix;|%p.mix;)*>

<!ELEMENT itemizedlist (listitem*)>
<!ELEMENT orderedlist (listitem*)>
<!ELEMENT listitem (para*)>
<!ELEMENT para (#PCDATA)>

<!-- ............................................................... -->
<!-- Change history ................................................ -->
<!-- ............................................................... -->

<!--
#1997-08-18: maler
#- Did a major revision.
#1997-09-10: maler
#- Updated FPI.
#- Removed namekey element and put key attribute on name element.
#- Made statusp element and supporting entities.
#- Added slist element with sitem+ content.
#- Required head on scrap and added new bnf subelement.
#- Added an xnt element and allowed it and nt in regular text and rhs.
#- Removed the ntref element.
#- Added back the com element to the content of rhs.
#- Added a key attribute to bibl.
#- Removed the ident element.
#- Added a term element to be used inside termdef.
#- Added an xtermref element parallel to termref.
#- Beefed up DTD comments.
#1997-09-12: maler
#- Allowed term element in general text.
#- Changed bibref to EMPTY.
#- Added ref.class to termdef.pcd.mix.
#1997-09-14: maler
#- Changed main attribute of xtermref from def to href.
#- Added termdef.class to label contents.
#1997-09-30: maler
#- Added character entity module and added new entities.
#- Removed p from appearing directly in self; created %p.mix;.
#- Added inform-div (non-normative division) element.
#- Fixed xtermref comment to mention href, not ref.
#- Extended orglist model to allow optional affiliation.
#- Modified author to make affiliation optional.
#- Added %speclist.class; and %note.class; to %obj.mix; and %p.mix;.
#- Added %note.class; and %illus.class; to %termdef.pcd.mix;.
#- Added unused HTML elements.
#- Put empty system ID next to public ID in entity declarations.
#1997-10-14: maler
#- Fixed "unused" div content model to move nested div to mixture.
#1997-10-16: maler
#- Added SGML Open Exchange tables.
#1997-11-28: maler
#- Added support for prodgroup and its attributes.
#- Added support for HTML tables.
#- Added loc and bibref to content of com.
#- Added loc to general p content models.
#- Allowed p as alternative to statusp in status.
#- Added non-null system IDs to external parameter entity declarations.
#- (Modified the SGML Open table module to make it XML-compliant.)
#- (Modified the character entity module.)
#1997-12-29: maler
#- Moved #PCDATA occurrences to come before GIs in content models.
#- Removed use of the SGML Open table module.
#- Added xspecref element.
#- Ensured that all FPIs contain 4-digit year.
#- (Modified the character entity module.)
#1998-03-10: maler
#- Merged the character entity and table modules into the main file.
#- Added ldquo and rdquo entities.
#- Added common attributes to prodgroup.
#- Made the email element in header optional.
#- Removed reference to the SGML Open table model.
#- Added ednote element.
#- Added quote element.
#- Updated XLink usage to reflect 3 March 1998 WD.
#- Added "local" entities to the class entities for customization.
#- Parameterized several content models to allow for customization.
#1998-03-23: maler
#- Cleaned up some comments and removed some others.
#- Added xml:space semi-common attribute to eg and bnf elements.
#- Added show and embed attributes on all the uses of href.
#- Added %common.att; to all HTML table elements.
#- Added a real URI to the "typical invocation" comment.
#1998-05-14: maler
#- Fixed mdash, ldquo, and rdquo character entities.
#- Switched to the full HTML 4.0 table model.
#- Removed htable/htbody elements and replaced them with table/tbody.
#- Added issue element to %note.class; and declared it.
#- Allowed prevlocs and latestloc in either order.
#- Added key-term, htable, htbody, and statusp as unused elements.
#- Removed real statusp element in favor of plain p.
#1998-05-21: maler
#- Declared generic constraint and constraintnote elements.
#- Added constraintnote to %note.class;.
#- Added constraint to %eg.pcd.mix; and prod content model.
#1998-08-22: maler
#- Fixed %illus.class; to mention table instead of htable.
#- Added definitions to %illus.class; for DOM model.
#- Added DOM definitions element and its substructure.
#- Updated XLink usage in %href.att; to use xlink:form and #IMPLIED.
#- Added clarifying comments to href-using elements.
#1998-11-30: maler
#- Added new unused elements to support DocBook translation.
#- Updated maler phone numbers.
#1998-12-3: maler
#- Fixed character entities with respect to escaping of ampersands.
#- Added many more explanatory comments.
#1999-07-02: maler
#- Added %loc.class; to all PCD mixes that didn't already have it.
#- Removed unused %loc.pcd.mix;.
#- Made version in spec header optional.
#- Added three new attributes to spec.
#- Broadened content of edtext.
#- Added optional copyright element to header.
#- Reorganized XLink-related parameter entities; added xmlns:xlink.
#- Changed edtext content from #PCDATA to %p.pcd.mix;.
#- Added show/actuate atts and default values to all href elements.
#- Changed versioning scheme from 8-digit dates to version numbers.
#- Added w3c-doctype, other-doctype, status atts to spec element.
#- Added prodrecap element inside scrap.
#- Added headstyle attribute to scrap.
-->

<!-- ............................................................... -->
<!-- End of XML specification DTD .................................. -->
<!-- ............................................................... -->

Deleted tests/defs.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
# defs.tcl --
#
#	This file contains support code for the Tcl/Tk test suite.It is
#	It is normally sourced by the individual files in the test suite
#	before they run their tests.  This improved approach to testing
#	was designed and initially implemented by Mary Ann May-Pumphrey
#	of Sun Microsystems.
#
# Copyright (c) 1990-1994 The Regents of the University of California.
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.
# 
# RCS: @(#) $Id$

# Initialize wish shell

if {[info exists tk_version]} {
    tk appname tktest
    wm title . tktest
} else {

    # Ensure that we have a minimal auto_path so we don't pick up extra junk.

    set auto_path [list [info library]]
}

# create the "tcltest" namespace for all testing variables and procedures

namespace eval tcltest {
    set procList [list test cleanupTests dotests saveState restoreState \
	    normalizeMsg makeFile removeFile makeDirectory removeDirectory \
	    viewFile bytestring set_iso8859_1_locale restore_locale \
	    safeFetch threadReap]
    if {[info exists tk_version]} {
	lappend procList setupbg dobg bgReady cleanupbg fixfocus
    }
    foreach proc $procList {
	namespace export $proc
    }

    # ::tcltest::verbose defaults to "b"

    variable verbose "b"

    # match defaults to the empty list

    variable match {}

    # skip defaults to the empty list

    variable skip {}

    # Tests should not rely on the current working directory.
    # Files that are part of the test suite should be accessed relative to
    # ::tcltest::testsDir.

    set originalDir [pwd]
    set tDir [file join $originalDir [file dirname [info script]]]
    cd $tDir
    variable testsDir [pwd]
    cd $originalDir

    # Count the number of files tested (0 if all.tcl wasn't called).
    # The all.tcl file will set testSingleFile to false, so stats will
    # not be printed until all.tcl calls the cleanupTests proc.
    # The currentFailure var stores the boolean value of whether the
    # current test file has had any failures.  The failFiles list
    # stores the names of test files that had failures.

    variable numTestFiles 0
    variable testSingleFile true
    variable currentFailure false
    variable failFiles {}

    # Tests should remove all files they create.  The test suite will
    # check the current working dir for files created by the tests.
    # ::tcltest::filesMade keeps track of such files created using the
    # ::tcltest::makeFile and ::tcltest::makeDirectory procedures.
    # ::tcltest::filesExisted stores the names of pre-existing files.

    variable filesMade {}
    variable filesExisted {}

    # ::tcltest::numTests will store test files as indices and the list
    # of files (that should not have been) left behind by the test files.

    array set ::tcltest::createdNewFiles {}

    # initialize ::tcltest::numTests array to keep track fo the number of
    # tests that pass, fial, and are skipped.

    array set numTests [list Total 0 Passed 0 Skipped 0 Failed 0]

    # initialize ::tcltest::skippedBecause array to keep track of
    # constraints that kept tests from running

    array set ::tcltest::skippedBecause {}

    # tests that use thread need to know which is the main thread

    variable ::tcltest::mainThread 1
    if {[info commands testthread] != {}} {
	set ::tcltest::mainThread [testthread names]
    }
}

# If there is no "memory" command (because memory debugging isn't
# enabled), generate a dummy command that does nothing.

if {[info commands memory] == ""} {
    proc memory args {}
}

# ::tcltest::initConfig --
#
# Check configuration information that will determine which tests
# to run.  To do this, create an array ::tcltest::testConfig.  Each
# element has a 0 or 1 value.  If the element is "true" then tests
# with that constraint will be run, otherwise tests with that constraint
# will be skipped.  See the README file for the list of built-in
# constraints defined in this procedure.
#
# Arguments:
#	none
#
# Results:
#	The ::tcltest::testConfig array is reset to have an index for
#	each built-in test constraint.

proc ::tcltest::initConfig {} {

    global tcl_platform tcl_interactive tk_version

    catch {unset ::tcltest::testConfig}

    # The following trace procedure makes it so that we can safely refer to
    # non-existent members of the ::tcltest::testConfig array without causing an
    # error.  Instead, reading a non-existent member will return 0.  This is
    # necessary because tests are allowed to use constraint "X" without ensuring
    # that ::tcltest::testConfig("X") is defined.

    trace variable ::tcltest::testConfig r ::tcltest::safeFetch

    proc ::tcltest::safeFetch {n1 n2 op} {
	if {($n2 != {}) && ([info exists ::tcltest::testConfig($n2)] == 0)} {
	    set ::tcltest::testConfig($n2) 0
	}
    }

    set ::tcltest::testConfig(unixOnly) \
	    [expr {$tcl_platform(platform) == "unix"}]
    set ::tcltest::testConfig(macOnly) \
	    [expr {$tcl_platform(platform) == "macintosh"}]
    set ::tcltest::testConfig(pcOnly) \
	    [expr {$tcl_platform(platform) == "windows"}]

    set ::tcltest::testConfig(unix) $::tcltest::testConfig(unixOnly)
    set ::tcltest::testConfig(mac) $::tcltest::testConfig(macOnly)
    set ::tcltest::testConfig(pc) $::tcltest::testConfig(pcOnly)

    set ::tcltest::testConfig(unixOrPc) \
	    [expr {$::tcltest::testConfig(unix) || $::tcltest::testConfig(pc)}]
    set ::tcltest::testConfig(macOrPc) \
	    [expr {$::tcltest::testConfig(mac) || $::tcltest::testConfig(pc)}]
    set ::tcltest::testConfig(macOrUnix) \
	    [expr {$::tcltest::testConfig(mac) || $::tcltest::testConfig(unix)}]

    set ::tcltest::testConfig(nt) [expr {$tcl_platform(os) == "Windows NT"}]
    set ::tcltest::testConfig(95) [expr {$tcl_platform(os) == "Windows 95"}]

    # The following config switches are used to mark tests that should work,
    # but have been temporarily disabled on certain platforms because they don't
    # and we haven't gotten around to fixing the underlying problem.

    set ::tcltest::testConfig(tempNotPc) [expr {!$::tcltest::testConfig(pc)}]
    set ::tcltest::testConfig(tempNotMac) [expr {!$::tcltest::testConfig(mac)}]
    set ::tcltest::testConfig(tempNotUnix) [expr {!$::tcltest::testConfig(unix)}]

    # The following config switches are used to mark tests that crash on
    # certain platforms, so that they can be reactivated again when the
    # underlying problem is fixed.

    set ::tcltest::testConfig(pcCrash) [expr {!$::tcltest::testConfig(pc)}]
    set ::tcltest::testConfig(macCrash) [expr {!$::tcltest::testConfig(mac)}]
    set ::tcltest::testConfig(unixCrash) [expr {!$::tcltest::testConfig(unix)}]

    # Set the "fonts" constraint for wish apps

    if {[info exists tk_version]} {
	set ::tcltest::testConfig(fonts) 1
	catch {destroy .e}
	entry .e -width 0 -font {Helvetica -12} -bd 1
	.e insert end "a.bcd"
	if {([winfo reqwidth .e] != 37) || ([winfo reqheight .e] != 20)} {
	    set ::tcltest::testConfig(fonts) 0
	}
	destroy .e
	catch {destroy .t}
	text .t -width 80 -height 20 -font {Times -14} -bd 1
	pack .t
	.t insert end "This is\na dot."
	update
	set x [list [.t bbox 1.3] [.t bbox 2.5]]
	destroy .t
	if {[string match {{22 3 6 15} {31 18 [34] 15}} $x] == 0} {
	    set ::tcltest::testConfig(fonts) 0
	}
    }

    # Skip empty tests

    set ::tcltest::testConfig(emptyTest) 0

    # By default, tests that expost known bugs are skipped.

    set ::tcltest::testConfig(knownBug) 0

    # By default, non-portable tests are skipped.

    set ::tcltest::testConfig(nonPortable) 0

    # Some tests require user interaction.

    set ::tcltest::testConfig(userInteraction) 0

    # Some tests must be skipped if the interpreter is not in interactive mode

    set ::tcltest::testConfig(interactive) $tcl_interactive

    # Some tests must be skipped if you are running as root on Unix.
    # Other tests can only be run if you are running as root on Unix.

    set ::tcltest::testConfig(root) 0
    set ::tcltest::testConfig(notRoot) 1
    set user {}
    if {$tcl_platform(platform) == "unix"} {
	catch {set user [exec whoami]}
	if {$user == ""} {
	    catch {regexp {^[^(]*\(([^)]*)\)} [exec id] dummy user}
	}
	if {($user == "root") || ($user == "")} {
	    set ::tcltest::testConfig(root) 1
	    set ::tcltest::testConfig(notRoot) 0
	}
    }

    # Set nonBlockFiles constraint: 1 means this platform supports
    # setting files into nonblocking mode.

    if {[catch {set f [open defs r]}]} {
	set ::tcltest::testConfig(nonBlockFiles) 1
    } else {
	if {[catch {fconfigure $f -blocking off}] == 0} {
	    set ::tcltest::testConfig(nonBlockFiles) 1
	} else {
	    set ::tcltest::testConfig(nonBlockFiles) 0
	}
	close $f
    }

    # Set asyncPipeClose constraint: 1 means this platform supports
    # async flush and async close on a pipe.
    #
    # Test for SCO Unix - cannot run async flushing tests because a
    # potential problem with select is apparently interfering.
    # (Mark Diekhans).

    if {$tcl_platform(platform) == "unix"} {
	if {[catch {exec uname -X | fgrep {Release = 3.2v}}] == 0} {
	    set ::tcltest::testConfig(asyncPipeClose) 0
	} else {
	    set ::tcltest::testConfig(asyncPipeClose) 1
	}
    } else {
	set ::tcltest::testConfig(asyncPipeClose) 1
    }

    # Test to see if we have a broken version of sprintf with respect
    # to the "e" format of floating-point numbers.

    set ::tcltest::testConfig(eformat) 1
    if {[string compare "[format %g 5e-5]" "5e-05"] != 0} {
	set ::tcltest::testConfig(eformat) 0
    }

    # Test to see if execed commands such as cat, echo, rm and so forth are
    # present on this machine.

    set ::tcltest::testConfig(unixExecs) 1
    if {$tcl_platform(platform) == "macintosh"} {
	set ::tcltest::testConfig(unixExecs) 0
    }
    if {($::tcltest::testConfig(unixExecs) == 1) && \
	    ($tcl_platform(platform) == "windows")} {
	if {[catch {exec cat defs}] == 1} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec echo hello}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec sh -c echo hello}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec wc defs}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {$::tcltest::testConfig(unixExecs) == 1} {
	    exec echo hello > removeMe
	    if {[catch {exec rm removeMe}] == 1} {
		set ::tcltest::testConfig(unixExecs) 0
	    }
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec sleep 1}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec fgrep unixExecs defs}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec ps}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec echo abc > removeMe}] == 0) && \
		([catch {exec chmod 644 removeMe}] == 1) && \
		([catch {exec rm removeMe}] == 0)} {
	    set ::tcltest::testConfig(unixExecs) 0
	} else {
	    catch {exec rm -f removeMe}
	}
	if {($::tcltest::testConfig(unixExecs) == 1) && \
		([catch {exec mkdir removeMe}] == 1)} {
	    set ::tcltest::testConfig(unixExecs) 0
	} else {
	    catch {exec rm -r removeMe}
	}
    }
}

::tcltest::initConfig


# ::tcltest::processCmdLineArgs --
#
#	Use command line args to set the verbose, skip, and
#	match variables.  This procedure must be run after
#	constraints are initialized, because some constraints can be
#	overridden.
#
# Arguments:
#	none
#
# Results:
#	::tcltest::verbose is set to <value>

proc ::tcltest::processCmdLineArgs {} {
    global argv

    # The "argv" var doesn't exist in some cases, so use {}
    # The "argv" var doesn't exist in some cases.

    if {(![info exists argv]) || ([llength $argv] < 2)} {
	set flagArray {}
    } else {
	set flagArray $argv
    }

    if {[catch {array set flag $flagArray}]} {
	puts stderr "Error:  odd number of command line args specified:"
	puts stderr "        $argv"
	exit
    }
    
    # Allow for 1-char abbreviations, where applicable (e.g., -match == -m).
    # Note that -verbose cannot be abbreviated to -v in wish because it
    # conflicts with the wish option -visual.

    foreach arg {-verbose -match -skip -constraints} {
	set abbrev [string range $arg 0 1]
	if {([info exists flag($abbrev)]) && \
		([lsearch -exact $flagArray $arg] < \
		[lsearch -exact $flagArray $abbrev])} {
	    set flag($arg) $flag($abbrev)
	}
    }

    # Set ::tcltest::workingDir to [pwd].
    # Save the names of files that already exist in ::tcltest::workingDir.

    set ::tcltest::workingDir [pwd]
    foreach file [glob -nocomplain [file join $::tcltest::workingDir *]] {
	lappend ::tcltest::filesExisted [file tail $file]
    }

    # Set ::tcltest::verbose to the arg of the -verbose flag, if given

    if {[info exists flag(-verbose)]} {
	set ::tcltest::verbose $flag(-verbose)
    }

    # Set ::tcltest::match to the arg of the -match flag, if given

    if {[info exists flag(-match)]} {
	set ::tcltest::match $flag(-match)
    }

    # Set ::tcltest::skip to the arg of the -skip flag, if given

    if {[info exists flag(-skip)]} {
	set ::tcltest::skip $flag(-skip)
    }

    # Use the -constraints flag, if given, to turn on constraints that are
    # turned off by default: userInteractive knownBug nonPortable.  This
    # code fragment must be run after constraints are initialized.

    if {[info exists flag(-constraints)]} {
	foreach elt $flag(-constraints) {
	    set ::tcltest::testConfig($elt) 1
	}
    }
}

::tcltest::processCmdLineArgs


# ::tcltest::cleanupTests --
#
# Remove files and dirs created using the makeFile and makeDirectory
# commands since the last time this proc was invoked.
#
# Print the names of the files created without the makeFile command
# since the tests were invoked.
#
# Print the number tests (total, passed, failed, and skipped) since the
# tests were invoked.
#

proc ::tcltest::cleanupTests {{calledFromAllFile 0}} {
    set tail [file tail [info script]]

    # Remove files and directories created by the :tcltest::makeFile and
    # ::tcltest::makeDirectory procedures.
    # Record the names of files in ::tcltest::workingDir that were not
    # pre-existing, and associate them with the test file that created them.

    if {!$calledFromAllFile} {

	foreach file $::tcltest::filesMade {
	    if {[file exists $file]} {
		catch {file delete -force $file}
	    }
	}
	set currentFiles {}
	foreach file [glob -nocomplain [file join $::tcltest::workingDir *]] {
	    lappend currentFiles [file tail $file]
	}
	set newFiles {}
	foreach file $currentFiles {
	    if {[lsearch -exact $::tcltest::filesExisted $file] == -1} {
		lappend newFiles $file
	    }
	}
	set ::tcltest::filesExisted $currentFiles
	if {[llength $newFiles] > 0} {
	    set ::tcltest::createdNewFiles($tail) $newFiles
	}
    }

    if {$calledFromAllFile || $::tcltest::testSingleFile} {

	# print stats

	puts -nonewline stdout "$tail:"
	foreach index [list "Total" "Passed" "Skipped" "Failed"] {
	    puts -nonewline stdout "\t$index\t$::tcltest::numTests($index)"
	}
	puts stdout ""

	# print number test files sourced
	# print names of files that ran tests which failed

	if {$calledFromAllFile} {
	    puts stdout "Sourced $::tcltest::numTestFiles Test Files."
	    set ::tcltest::numTestFiles 0
	    if {[llength $::tcltest::failFiles] > 0} {
		puts stdout "Files with failing tests: $::tcltest::failFiles"
		set ::tcltest::failFiles {}
	    }
	}

	# if any tests were skipped, print the constraints that kept them
	# from running.

	set constraintList [array names ::tcltest::skippedBecause]
	if {[llength $constraintList] > 0} {
	    puts stdout "Number of tests skipped for each constraint:"
	    foreach constraint [lsort $constraintList] {
		puts stdout \
			"\t$::tcltest::skippedBecause($constraint)\t$constraint"
		unset ::tcltest::skippedBecause($constraint)
	    }
	}

	# report the names of test files in ::tcltest::createdNewFiles, and
	# reset the array to be empty.

	set testFilesThatTurded [lsort [array names ::tcltest::createdNewFiles]]
	if {[llength $testFilesThatTurded] > 0} {
	    puts stdout "Warning: test files left files behind:"
	    foreach testFile $testFilesThatTurded {
		puts "\t$testFile:\t$::tcltest::createdNewFiles($testFile)"
		unset ::tcltest::createdNewFiles($testFile)
	    }
	}

	# reset filesMade, filesExisted, and numTests

	set ::tcltest::filesMade {}
	foreach index [list "Total" "Passed" "Skipped" "Failed"] {
	    set ::tcltest::numTests($index) 0
	}

	# exit only if running Tk in non-interactive mode

	global tk_version tcl_interactive
	if {[info exists tk_version] && !$tcl_interactive} {
	    exit
	}
    } else {

	# if we're deferring stat-reporting until all files are sourced,
	# then add current file to failFile list if any tests in this file
	# failed

	incr ::tcltest::numTestFiles
	if {($::tcltest::currentFailure) && \
		([lsearch -exact $::tcltest::failFiles $tail] == -1)} {
	    lappend ::tcltest::failFiles $tail
	}
	set ::tcltest::currentFailure false
    }
}


# test --
#
# This procedure runs a test and prints an error message if the test fails.
# If ::tcltest::verbose has been set, it also prints a message even if the
# test succeeds.  The test will be skipped if it doesn't match the
# ::tcltest::match variable, if it matches an element in
# ::tcltest::skip, or if one of the elements of "constraints" turns
# out not to be true.
#
# Arguments:
# name -		Name of test, in the form foo-1.2.
# description -		Short textual description of the test, to
#			help humans understand what it does.
# constraints -		A list of one or more keywords, each of
#			which must be the name of an element in
#			the array "::tcltest::testConfig".  If any of these
#			elements is zero, the test is skipped.
#			This argument may be omitted.
# script -		Script to run to carry out the test.  It must
#			return a result that can be checked for
#			correctness.
# expectedAnswer -	Expected result from script.

proc ::tcltest::test {name description script expectedAnswer args} {
    incr ::tcltest::numTests(Total)

    # skip the test if it's name matches an element of skip

    foreach pattern $::tcltest::skip {
	if {[string match $pattern $name]} {
	    incr ::tcltest::numTests(Skipped)
	    return
	}
    }
    # skip the test if it's name doesn't match any element of match

    if {[llength $::tcltest::match] > 0} {
	set ok 0
	foreach pattern $::tcltest::match {
	    if {[string match $pattern $name]} {
		set ok 1
		break
	    }
        }
	if {!$ok} {
	    incr ::tcltest::numTests(Skipped)
	    return
	}
    }
    set i [llength $args]
    if {$i == 0} {
	set constraints {}
    } elseif {$i == 1} {

	# "constraints" argument exists;  shuffle arguments down, then
	# make sure that the constraints are satisfied.

	set constraints $script
	set script $expectedAnswer
	set expectedAnswer [lindex $args 0]
	set doTest 0
	if {[string match {*[$\[]*} $constraints] != 0} {

	    # full expression, e.g. {$foo > [info tclversion]}

	    catch {set doTest [uplevel #0 expr $constraints]}

	} elseif {[regexp {[^.a-zA-Z0-9 ]+} $constraints] != 0} {

	    # something like {a || b} should be turned into 
	    # $::tcltest::testConfig(a) || $::tcltest::testConfig(b).

 	    regsub -all {[.a-zA-Z0-9]+} $constraints \
		    {$::tcltest::testConfig(&)} c
	    catch {set doTest [eval expr $c]}
	} else {

	    # just simple constraints such as {unixOnly fonts}.

	    set doTest 1
	    foreach constraint $constraints {
		if {![info exists ::tcltest::testConfig($constraint)]
			|| !$::tcltest::testConfig($constraint)} {
		    set doTest 0

		    # store the constraint that kept the test from running

		    set constraints $constraint
		    break
		}
	    }
	}
	if {$doTest == 0} {
	    incr ::tcltest::numTests(Skipped)
	    if {[string first s $::tcltest::verbose] != -1} {
		puts stdout "++++ $name SKIPPED: $constraints"
	    }

	    # add the constraint to the list of constraints the kept tests
	    # from running

	    if {[info exists ::tcltest::skippedBecause($constraints)]} {
		incr ::tcltest::skippedBecause($constraints)
	    } else {
		set ::tcltest::skippedBecause($constraints) 1
	    }
	    return	
	}
    } else {
	error "wrong # args: must be \"test name description ?constraints? script expectedAnswer\""
    }
    memory tag $name
    set code [catch {uplevel $script} actualAnswer]
    if {$code != 0 || [string compare $actualAnswer $expectedAnswer] != 0} {
	incr ::tcltest::numTests(Failed)
	set ::tcltest::currentFailure true
	if {[string first b $::tcltest::verbose] == -1} {
	    set script ""
	}
	puts stdout "\n==== $name $description FAILED"
	if {$script != ""} {
	    puts stdout "==== Contents of test case:"
	    puts stdout $script
	}
	if {$code != 0} {
	    if {$code == 1} {
		puts stdout "==== Test generated error:"
		puts stdout $actualAnswer
	    } elseif {$code == 2} {
		puts stdout "==== Test generated return exception;  result was:"
		puts stdout $actualAnswer
	    } elseif {$code == 3} {
		puts stdout "==== Test generated break exception"
	    } elseif {$code == 4} {
		puts stdout "==== Test generated continue exception"
	    } else {
		puts stdout "==== Test generated exception $code;  message was:"
		puts stdout $actualAnswer
	    }
	} else {
	    puts stdout "---- Result was:\n$actualAnswer"
	}
	puts stdout "---- Result should have been:\n$expectedAnswer"
	puts stdout "==== $name FAILED\n" 
    } else { 
	incr ::tcltest::numTests(Passed)
	if {[string first p $::tcltest::verbose] != -1} {
	    puts stdout "++++ $name PASSED"
	}
    }
}

# ::tcltest::dotests --
#
#	takes two arguments--the name of the test file (such
#	as "parse.test"), and a pattern selecting the tests you want to
#	execute.  It sets ::tcltest::matching to the second argument, calls
#	"source" on the file specified in the first argument, and restores
#	::tcltest::matching to its pre-call value at the end.
#
# Arguments:
#	file    name of tests file to source
#	args    pattern selecting the tests you want to execute
#
# Results:
#	none

proc ::tcltest::dotests {file args} {
    set savedTests $::tcltest::match
    set ::tcltest::match $args
    source $file
    set ::tcltest::match $savedTests
}

proc ::tcltest::openfiles {} {
    if {[catch {testchannel open} result]} {
	return {}
    }
    return $result
}

proc ::tcltest::leakfiles {old} {
    if {[catch {testchannel open} new]} {
        return {}
    }
    set leak {}
    foreach p $new {
    	if {[lsearch $old $p] < 0} {
	    lappend leak $p
	}
    }
    return $leak
}

set ::tcltest::saveState {}

proc ::tcltest::saveState {} {
    uplevel #0 {set ::tcltest::saveState [list [info procs] [info vars]]}
}

proc ::tcltest::restoreState {} {
    foreach p [info procs] {
	if {[lsearch [lindex $::tcltest::saveState 0] $p] < 0} {
	    rename $p {}
	}
    }
    foreach p [uplevel #0 {info vars}] {
	if {[lsearch [lindex $::tcltest::saveState 1] $p] < 0} {
	    uplevel #0 "unset $p"
	}
    }
}

proc ::tcltest::normalizeMsg {msg} {
    regsub "\n$" [string tolower $msg] "" msg
    regsub -all "\n\n" $msg "\n" msg
    regsub -all "\n\}" $msg "\}" msg
    return $msg
}

# makeFile --
#
# Create a new file with the name <name>, and write <contents> to it.
#
# If this file hasn't been created via makeFile since the last time
# cleanupTests was called, add it to the $filesMade list, so it will
# be removed by the next call to cleanupTests.
#
proc ::tcltest::makeFile {contents name} {
    set fd [open $name w]
    fconfigure $fd -translation lf
    if {[string index $contents [expr {[string length $contents] - 1}]] == "\n"} {
	puts -nonewline $fd $contents
    } else {
	puts $fd $contents
    }
    close $fd

    set fullName [file join [pwd] $name]
    if {[lsearch -exact $::tcltest::filesMade $fullName] == -1} {
	lappend ::tcltest::filesMade $fullName
    }
}

proc ::tcltest::removeFile {name} {
    file delete $name
}

# makeDirectory --
#
# Create a new dir with the name <name>.
#
# If this dir hasn't been created via makeDirectory since the last time
# cleanupTests was called, add it to the $directoriesMade list, so it will
# be removed by the next call to cleanupTests.
#
proc ::tcltest::makeDirectory {name} {
    file mkdir $name

    set fullName [file join [pwd] $name]
    if {[lsearch -exact $::tcltest::filesMade $fullName] == -1} {
	lappend ::tcltest::filesMade $fullName
    }
}

proc ::tcltest::removeDirectory {name} {
    file delete -force $name
}

proc ::tcltest::viewFile {name} {
    global tcl_platform
    if {($tcl_platform(platform) == "macintosh") || \
		($::tcltest::testConfig(unixExecs) == 0)} {
	set f [open $name]
	set data [read -nonewline $f]
	close $f
	return $data
    } else {
	exec cat $name
    }
}

#
# Construct a string that consists of the requested sequence of bytes,
# as opposed to a string of properly formed UTF-8 characters.  
# This allows the tester to 
# 1. Create denormalized or improperly formed strings to pass to C procedures 
#    that are supposed to accept strings with embedded NULL bytes.
# 2. Confirm that a string result has a certain pattern of bytes, for instance
#    to confirm that "\xe0\0" in a Tcl script is stored internally in 
#    UTF-8 as the sequence of bytes "\xc3\xa0\xc0\x80".
#
# Generally, it's a bad idea to examine the bytes in a Tcl string or to
# construct improperly formed strings in this manner, because it involves
# exposing that Tcl uses UTF-8 internally.

proc ::tcltest::bytestring {string} {
    encoding convertfrom identity $string
}

# Locate tcltest executable

if {![info exists tk_version]} {
    set tcltest [info nameofexecutable]

    if {$tcltest == "{}"} {
	set tcltest {}
    }
}

set ::tcltest::testConfig(stdio) 0
catch {
    catch {file delete -force tmp}
    set f [open tmp w]
    puts $f {
	exit
    }
    close $f

    set f [open "|[list $tcltest tmp]" r]
    close $f
    
    set ::tcltest::testConfig(stdio) 1
}
catch {file delete -force tmp}

# Deliberately call the socket with the wrong number of arguments.  The error
# message you get will indicate whether sockets are available on this system.

catch {socket} msg
set ::tcltest::testConfig(socket) \
	[expr {$msg != "sockets are not available on this system"}]

#
# Internationalization / ISO support procs     -- dl
#

if {[info commands testlocale]==""} {

    # No testlocale command, no tests...
    # (it could be that we are a sub interp and we could just load
    # the Tcltest package but that would interfere with tests
    # that tests packages/loading in slaves...)

    set ::tcltest::testConfig(hasIsoLocale) 0
} else {
    proc ::tcltest::set_iso8859_1_locale {} {
	set ::tcltest::previousLocale [testlocale ctype]
	testlocale ctype $::tcltest::isoLocale
    }

    proc ::tcltest::restore_locale {} {
	testlocale ctype $::tcltest::previousLocale
    }

    if {![info exists ::tcltest::isoLocale]} {
	set ::tcltest::isoLocale fr
        switch $tcl_platform(platform) {
	    "unix" {

		# Try some 'known' values for some platforms:

		switch -exact -- $tcl_platform(os) {
		    "FreeBSD" {
			set ::tcltest::isoLocale fr_FR.ISO_8859-1
		    }
		    HP-UX {
			set ::tcltest::isoLocale fr_FR.iso88591
		    }
		    Linux -
		    IRIX {
			set ::tcltest::isoLocale fr
		    }
		    default {

			# Works on SunOS 4 and Solaris, and maybe others...
			# define it to something else on your system
			#if you want to test those.

			set ::tcltest::isoLocale iso_8859_1
		    }
		}
	    }
	    "windows" {
		set ::tcltest::isoLocale French
	    }
	}
    }

    set ::tcltest::testConfig(hasIsoLocale) \
	    [string length [::tcltest::set_iso8859_1_locale]]
    ::tcltest::restore_locale
} 

#
# procedures that are Tk specific
#

if {[info exists tk_version]} {

    # If the main window isn't already mapped (e.g. because the tests are
    # being run automatically) , specify a precise size for it so that the
    # user won't have to position it manually.

    if {![winfo ismapped .]} {
	wm geometry . +0+0
	update
    }

    # The following code can be used to perform tests involving a second
    # process running in the background.
    
    # Locate the tktest executable

    set ::tcltest::tktest [info nameofexecutable]
    if {$::tcltest::tktest == "{}"} {
	set ::tcltest::tktest {}
	puts stdout \
		"Unable to find tktest executable, skipping multiple process tests."
    }

    # Create background process
    
    proc ::tcltest::setupbg args {
	if {$::tcltest::tktest == ""} {
	    error "you're not running tktest so setupbg should not have been called"
	}
	if {[info exists ::tcltest::fd] && ($::tcltest::fd != "")} {
	    cleanupbg
	}
	
	# The following code segment cannot be run on Windows in Tk8.1b2
	# This bug is logged as a pipe bug (bugID 1495).

	global tcl_platform
	if {$tcl_platform(platform) != "windows"} {
	    set ::tcltest::fd [open "|[list $::tcltest::tktest -geometry +0+0 -name tktest] $args" r+]
	    puts $::tcltest::fd "puts foo; flush stdout"
	    flush $::tcltest::fd
	    if {[gets $::tcltest::fd data] < 0} {
		error "unexpected EOF from \"$::tcltest::tktest\""
	    }
	    if {[string compare $data foo]} {
		error "unexpected output from background process \"$data\""
	    }
	    fileevent $::tcltest::fd readable bgReady
	}
    }
    
    # Send a command to the background process, catching errors and
    # flushing I/O channels

    proc ::tcltest::dobg {command} {
	puts $::tcltest::fd "catch [list $command] msg; update; puts \$msg; puts **DONE**; flush stdout"
	flush $::tcltest::fd
	set ::tcltest::bgDone 0
	set ::tcltest::bgData {}
	tkwait variable ::tcltest::bgDone
	set ::tcltest::bgData
    }

    # Data arrived from background process.  Check for special marker
    # indicating end of data for this command, and make data available
    # to dobg procedure.

    proc ::tcltest::bgReady {} {
	set x [gets $::tcltest::fd]
	if {[eof $::tcltest::fd]} {
	    fileevent $::tcltest::fd readable {}
	    set ::tcltest::bgDone 1
	} elseif {$x == "**DONE**"} {
	    set ::tcltest::bgDone 1
	} else {
	    append ::tcltest::bgData $x
	}
    }

    # Exit the background process, and close the pipes

    proc ::tcltest::cleanupbg {} {
	catch {
	    puts $::tcltest::fd "exit"
	    close $::tcltest::fd
	}
	set ::tcltest::fd ""
    }

    # Clean up focus after using generate event, which
    # can leave the window manager with the wrong impression
    # about who thinks they have the focus. (BW)
    
    proc ::tcltest::fixfocus {} {
	catch {destroy .focus}
	toplevel .focus
	wm geometry .focus +0+0
	entry .focus.e
	.focus.e insert 0 "fixfocus"
	pack .focus.e
	update
	focus -force .focus.e
	destroy .focus
    }
}

# threadReap --
#
#	Kill all threads except for the main thread.
#	Do nothing if testthread is not defined.
#
# Arguments:
#	none.
#
# Results:
#	Returns the number of existing threads.

if {[info commands testthread] != {}} {
    proc ::tcltest::threadReap {} {
	testthread errorproc ThreadNullError
	while {[llength [testthread names]] > 1} {
	    foreach tid [testthread names] {
		if {$tid != $::tcltest::mainThread} {
		    catch {testthread send -async $tid {testthread exit}}
		    update
		}
	    }
	}
	testthread errorproc ThreadError
	return [llength [testthread names]]
    }
} else {
    proc ::tcltest::threadReap {} {
	return 1
    }   
}

# Need to catch the import because it fails if defs.tcl is sourced
# more than once.

catch {namespace import ::tcltest::*}
return
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Added tests/dom.bench.























































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# -*- tcl -*-
# Tcl Benchmark File
#
# This file contains a number of benchmarks for the dom methods.
# This allow developers to monitor/gauge/track package performance.
#
# (c) 2013 Rolf Ade <rolf@pointsman.de>


# ### ### ### ######### ######### ######### ###########################
## Setting up the environment ...

package require tdom 

# ### ### ### ######### ######### ######### ###########################
## Benchmarks.

dom createNodeCmd elementNode e1

foreach nrOf {1 10 100 1000} {

    bench -desc "getElementsByTagName: $nrOf returned nodes" -pre {
        dom createDocument root doc
        $doc documentElement root
        $root appendFromScript {
            for {set x 0} {$x < $nrOf} {incr x} {
                e1
            }
        }
    } -body {
        $doc getElementsByTagName e1
    } -post {
        $doc delete
    }

}

foreach nrOf {1 10 100 1000} {

    bench -desc "getElementsByTagName: $nrOf returned node tokens" -pre {
        dom createDocument root doc
        $doc documentElement root
        $root appendFromScript {
            for {set x 0} {$x < $nrOf} {incr x} {
                e1
            }
        }
        dom setObjectCommands token
    } -body {
        $doc getElementsByTagName e1
    } -post {
        dom setObjectCommands automatic
        $doc delete
    }

}

proc cloneImitated {source target} {
    foreach att [$source attributes] {
        $target setAttribute $att [$source @$att]
    }
    set targetDoc [$target ownerDocument]
    foreach child [$source childNodes] {
        switch [$child nodeType] {
            "ELEMENT_NODE" {
                set targetChild [$targetDoc createElement [$child nodeName]]
            }
            "TEXT_NODE" {
                set targetChild [$targetDoc createTextNode [$child nodeValue]]
            }
            "CDATA_SECTION_NODE" {
                set targetChild [$targetDoc createCDATASection \
                                     [$child nodeValue]]
            }
            "PROCESSING_INSTRUCTION_NODE" {
                set targetChild [$targetDoc createProcessingInstruction \
                                     [$child nodeName] [$child nodeValue]]
            }
            "COMMENT_NODE" {
                set targetChild [$targetDoc createComment [$child nodeValue]]
            }
            default {
                error "Unexpected node type [$child nodeType]"
            }
        }
        $target appendChild $targetChild
        cloneImitated $child $targetChild
    }
}

proc cloneImitated2 {source target} {
    foreach att [$source attributes] {
        $target setAttribute $att [$source @$att]
    }
    set targetDoc [$target ownerDocument]
    foreach child [$source childNodes] {
        switch [$child nodeType] {
            "ELEMENT_NODE" {
                $targetDoc createElement [$child nodeName] targetChild
            }
            "TEXT_NODE" {
                $targetDoc createTextNode [$child nodeValue] targetChild
            }
            "CDATA_SECTION_NODE" {
                $targetDoc createCDATASection [$child nodeValue] targetChild
            }
            "PROCESSING_INSTRUCTION_NODE" {
                $targetDoc createProcessingInstruction [$child nodeName] \
                    targetChild
            }
            "COMMENT_NODE" {
                $targetDoc createComment [$child nodeValue] targetChild
            }
            default {
                error "Unexpected node type [$child nodeType]"
            }
        }
        $target appendChild $targetChild
        cloneImitated2 $child $targetChild
    }
}

proc cloneImitatedToken {source target} {
    foreach att [domNode $source attributes] {
        domNode $target setAttribute $att [domNode $source @$att]
    }
    set targetDoc [domNode $target ownerDocument]
    foreach child [domNode $source childNodes] {
        switch [domNode $child nodeType] {
            "ELEMENT_NODE" {
                set targetChild [$targetDoc createElement \
                                     [domNode $child nodeName]]
            }
            "TEXT_NODE" {
                set targetChild [$targetDoc createTextNode \
                                     [domNode $child nodeValue]]
            }
            "CDATA_SECTION_NODE" {
                set targetChild [$targetDoc createCDATASection \
                                     [domNode $child nodeValue]]
            }
            "PROCESSING_INSTRUCTION_NODE" {
                set targetChild [$targetDoc createProcessingInstruction \
                                     [domNode $child nodeName] \
                                     [domNode $child nodeValue]]
            }
            "COMMENT_NODE" {
                set targetChild [$targetDoc createComment \
                                     [domNode $child nodeValue]]
            }
            default {
                error "Unexpected node type [domNode $child nodeType]"
            }
        }
        domNode $target appendChild $targetChild
        cloneImitatedToken $child $targetChild
    }
}

bench -desc "clone dom tree without clone method - cmds" -pre {
    set fd [open [file join [file dir [info script]] ../tests/data/mondial-europe.xml]]
    fconfigure $fd -encoding utf-8
    set doc [dom parse -channel $fd]
    close $fd
    set root [$doc documentElement]
    set clone [dom createDocument [$root nodeName]]
    set cloneRoot [$clone documentElement]
} -iters 5 -body {
    cloneImitated $root $cloneRoot
} -post {
    $doc delete
    $clone delete
}

bench -desc "clone dom tree without clone method - cmds 2" -pre {
    set fd [open [file join [file dir [info script]] ../tests/data/mondial-europe.xml]]
    fconfigure $fd -encoding utf-8
    set doc [dom parse -channel $fd]
    close $fd
    set root [$doc documentElement]
    set clone [dom createDocument [$root nodeName]]
    set cloneRoot [$clone documentElement]
} -iters 5 -body {
    cloneImitated2 $root $cloneRoot
} -post {
    $doc delete
    $clone delete
}

bench -desc "clone dom tree without clone method - token" -pre {
    set fd [open [file join [file dir [info script]] ../tests/data/mondial-europe.xml]]
    fconfigure $fd -encoding utf-8
    set doc [dom parse -channel $fd]
    close $fd
    set root [$doc documentElement]
    set clone [dom createDocument [$root nodeName]]
    set cloneRoot [$clone documentElement]
    dom setObjectCommands token
} -iters 5 -body {
    cloneImitatedToken $root $cloneRoot
} -post {
    $doc delete
    $clone delete
    dom setObjectCommands automatic
}

foreach nrOf {1 10 100 1000} {

    bench -desc "Create document node: $nrOf"  -pre {
        set doclist [list]
    } -body {
        lappend doclist [dom createDocumentNode]
    } -post {
        foreach doc $doclist {
            $doc delete
        }
    }

}

Changes to tests/dom.test.

9
10
11
12
13
14
15


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
..
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
...
111
112
113
114
115
116
117































































118
119
120
121
122
123
124
...
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
...
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
...
452
453
454
455
456
457
458
















































































































































459
460
461
462
463
464
465
...
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
...
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
...
936
937
938
939
940
941
942

































































































































































































943
944
945
946
947
948
949
....
1125
1126
1127
1128
1129
1130
1131










1132
1133
1134
1135
1136
1137
1138
....
1179
1180
1181
1182
1183
1184
1185




































1186
1187
1188
1189
1190
1191
1192
....
1220
1221
1222
1223
1224
1225
1226

1227
1228
1229
























1230
1231
1232
1233
1234
1235
1236
1237
1238
1239

1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253

1254
1255
1256
1257
1258
1259
1260
....
1291
1292
1293
1294
1295
1296
1297
1298













1299
1300













































































































































































































































1301
1302
1303
#    dom-4.*:  parse -useForeignDTD
#    dom-5.*:  external entities
#    dom-6.*:  use in slave interpreter
#    dom-7.*:  setNameCheck, setTextCheck
#    dom-8.*:  createDocumentNode, documentNodes
#    dom-9.*:  setObjectCommands
#    dom-10.*: createNodeCmd


#
# Copyright (c) 2002, 2003, 2004 Rolf Ade.

source [file join [file dir [info script]] loadtdom.tcl]

test dom-1.1 {createDocument with root node name not a XML Name} {
    list [catch {dom createDocument "root node"} msg] $msg
} "1 {invalid root element name}"

test dom-1.2 {createDocument with root node name not a XML Name} {
    list [catch {dom createDocument "1root"} msg] $msg
} "1 {invalid root element name}"

test dom-1.3 {createDocument - root name us-ascii} {
    dom createDocument "root" doc 
    set root [$doc documentElement]
    set result [$root nodeName]
    $doc delete
    set result
................................................................................
    set result [$root namespaceURI]
    $doc delete
    set result
} "http://foo.bar"    

test dom-1.9 {createDocumentNS with root name not a NCName} {
    list [catch {dom createDocumentNS "http://foo.bar" "foo bar" doc} msg] $msg
} "1 {invalid local name}"

test dom-1.10 {createDocumentNS with root name not a NCName} {
    list [catch {dom createDocumentNS "http://foo.bar" "a:b:c" doc} msg] $msg
} "1 {invalid local name}"

test dom-1.11 {createDocumentNS with root name not a NCName} {
    list [catch {dom createDocumentNS "http://foo.bar" "a b:b" doc} msg] $msg
} "1 {invalid prefix name}"

test dom-1.12 {createDocumentNS with root name not a NCName} {
    list [catch {dom createDocumentNS "http://foo.bar" "a:a b" doc} msg] $msg
} "1 {invalid local name}"

test dom-1.13 {createDocumentNS - check root name} {
    set doc [dom createDocumentNS "http://foo.bar" foo:root]
    set root [$doc documentElement]
    set result [$root nodeName]
    $doc delete
    set result
................................................................................
    }
    set nrOfCommands [llength [info commands]]
    set doc [dom createDocument root]
    rename $doc fooCmd
    fooCmd delete
    expr {[llength [info commands]] == $nrOfCommands}
} {1}
































































test dom-2.1 {Don't quash white space at start or end of non white space content} {
    set doc [dom parse {<root>
    some content
    </root>}]
    set root [$doc documentElement]
    $root text
................................................................................
    close $fd
    $doc delete
    info exists -keepEmpties
} -cleanup {
    removeFile dom.xml
} -result 0

test dom-2.8 {parse method: bogus option} {
    set result [catch {set doc [dom parse -bogusOption foo <root/>]} errMsg]
    lappend result $errMsg
} {1 {bad option "-bogusOption": must be -keepEmpties, -simple, -html, -feedbackAfter, -channel, -baseurl, -externalentitycommand, -useForeignDTD, or -paramentityparsing}}

test dom-2.9 {parse method: bogus option} -setup {
    set xmlFile [makeFile {<root>    </root>} dom.xml]
} -body {
    catch {unset -keepEmpties}
    set fd [open $xmlFile]
    set result [catch {set doc [dom parse -channel $fd -bogusOption]} errMsg]
    close $fd
    lappend result $errMsg
} -cleanup {
    removeFile dom.xml
} -result {1 {bad option "-bogusOption": must be -keepEmpties, -simple, -html, -feedbackAfter, -channel, -baseurl, -externalentitycommand, -useForeignDTD, or -paramentityparsing}}

set dom_dtd "
    <!ELEMENT root EMPTY>
    <!ATTLIST root lang CDATA #FIXED \"en\">"

proc extRefResolver {base systemId publicId} {
    global dom_dtd

    if {$publicId == "DOMCMDTEST"} {
        return [list string $base $dom_dtd]
    } else {
        return [::tDOM::extRefHandler $base $systemId $publicId]
    }
}

test dom-2.10 {parse method: -paramentityparsing default is 'always'} {
    set doc [dom parse -externalentitycommand extRefResolver {
        <!DOCTYPE root PUBLIC "DOMCMDTEST" "dummysystemID">
        <root/>
................................................................................
    set result [catch {set doc [dom parse \
            -externalentitycommand extRefResolver {
        <!DOCTYPE root PUBLIC "DOMCMDTEST" "dummysystemID">
        <root/>
    }]} errMsg]
    lappend result $errMsg
} {1 {error "syntax error" in entity "dummysystemID" at line 1 character 20
"<!ATTLIST root lang # <--Error-- FIXED "en">"}}

test dom-2.18 {parse document with nodes before and after the documentElement} {
    set doc [dom parse {<!-- First comment -->
<doc>
  <!-- Front comment -->
  <inner/>
  <!-- Back comment -->
................................................................................
</doc><!-- Last comment -->}

test dom-2.26 {Not well-formed input} {
    catch {dom parse {<xsl:transform       
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform        
                   <http://www.w3.org/1999/XSL/Transform> "/>}}
} 1

















































































































































test dom-3.1 {isName} {
    dom isName ":foo"
} {1}

test dom-3.2 {isName} {
    dom isName "_foo"
................................................................................

test dom-4.1 {-useForeignDTD 0} {
    set doc [dom parse -useForeignDTD 0 {<root/>}]
    $doc delete
} {}

test dom-4.2 {-useForeignDTD 1 with document with internal subset} {need_uri} {
    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
    set ::tDOM::useForeignDTD "data/domCmd1.dtd"
    set doc [dom parse \
            -useForeignDTD 1 \
            -baseurl $baseURI \
            -externalentitycommand ::tDOM::extRefHandler {
<!DOCTYPE root [
    <!ATTLIST root fixed CDATA #FIXED "toThat">
]>
<root/>}]
    set root [$doc documentElement]
    set result [$root @fixed]
    $doc delete
    set result
} {toThat}

test dom-4.3 {-useForeignDTD 1 with document with internal subset} {need_uri} {
    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
    set ::tDOM::useForeignDTD "data/domCmd1.dtd"
    set doc [dom parse \
            -useForeignDTD 1 \
            -baseurl $baseURI \
            -externalentitycommand ::tDOM::extRefHandler {
<!DOCTYPE root [
    <!ATTLIST root fixed2 CDATA #FIXED "toThat">
]>
<root/>}]
    set root [$doc documentElement]
    set result [$root @fixed]
    lappend result [$root @fixed2]
    $doc delete
    set result
} {toThis toThat}

test dom-4.4 {-useForeignDTD 1 with document without document declaration} {need_uri} {
    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
    set ::tDOM::useForeignDTD "data/domCmd1.dtd"
    set doc [dom parse \
            -useForeignDTD 1 \
            -baseurl $baseURI \
            -externalentitycommand ::tDOM::extRefHandler <root/>]
    set root [$doc documentElement]
    set result [$root @fixed]
    $doc delete
    set result
} {toThis}

test dom-4.5 {-useForeignDTD 1 does not overwrite a given external subset} {need_uri} {
    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
    set ::tDOM::useForeignDTD "data/domCmd1.dtd"
    set doc [dom parse \
            -useForeignDTD 1 \
            -baseurl $baseURI \
            -externalentitycommand ::tDOM::extRefHandler {
<!DOCTYPE root SYSTEM "data/domCmd2.dtd">
<root/>}]
    set root [$doc documentElement]
    set result [$root @fixed]
    $doc delete
    set result
} {toThat}
................................................................................

test dom-4.6 {-useForeignDTD with nonboolean arg} {need_uri} {
    set result [catch {set doc [dom parse -useForeignDTD foo <root/>]} errMsg]
    lappend result $errMsg
} {1 {expected boolean value but got "foo"}}

test dom-5.1 {document with external subset} {need_uri} {
    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
    set doc [dom parse \
            -baseurl $baseURI \
            -externalentitycommand ::tDOM::extRefHandler {
<!DOCTYPE root SYSTEM "data/domCmd2.dtd">
<root/>}]
    set root [$doc documentElement]
    set result [$root @fixed]
    $doc delete
    set result
} {toThat}
................................................................................
                 -baseurl "dummy" \
                 -externalentitycommand [list dom-5.2 thisDoc] {
                     <!DOCTYPE root SYSTEM "">
                     <root/>}]
    $doc delete
    set ::dom-5_2
} {thisDoc}


































































































































































































test dom-6.1 {use in slave interpreter} {
    set slave [interp create]
    load {} tdom $slave
    interp eval $slave {
        dom parse <root>foo</root> doc
        $doc documentElement root
................................................................................
            nodeCmds::t "foo\u0003bar"
        }
    }} errMsg]
    dom setTextCheck 1
    $doc delete
    lappend result $errMsg
} [list 1 "Invalid text value 'foo\u0003bar'"]











test dom-8.1 {createDocumentNode} {
    set result [catch {dom createDocumentNode foo bar}]
} {1}

test dom-8.2 {createDocumentNode} {
    set docNode [dom createDocumentNode]
................................................................................
    $doc delete
    $docNode appendFromList $listRep
    set result [$docNode asXML -indent none]
    $docNode delete
    set result
} {<root><child1/><child2/>some text<child3/></root>}





































test dom-9.1 {setObjectCommands} {
    dom setObjectCommands
} {automatic}

test dom-9.2 {setObjectCommands} {
    dom setObjectCommands automatic
} {automatic}
................................................................................
    set doc [dom parse <root><child1/><child2/></root>]
    set root [domDoc $doc documentElement]
    set result [expr {$nrOfCmds == [llength [info commands]]}]
    dom setObjectCommands command
    set docCmd [domNode $root ownerDocument]
    lappend result [expr {$nrOfCmds + 1 == [llength [info commands]]}]
    $docCmd delete

    set result
} {1 1}

























catch {namespace delete nodeCmds}

namespace eval nodeCmds {
    dom createNodeCmd elementNode e1
    dom createNodeCmd elementNode e2
    dom createNodeCmd commentNode c
    dom createNodeCmd textNode    t
    dom createNodeCmd cdataNode   cdata
    dom createNodeCmd piNode      pi
    dom createNodeCmd parserNode  parser

}

test dom-10.1 {createNodeCmd} {
    llength [info commands nodeCmds::*]
} {7}

namespace eval nodeCmds {
    rename e1 {}
    rename e2 {}
    rename c {}
    rename t {}
    rename cdata {}
    rename pi {}
    rename parser {}

}

test dom-10.2 {createNodeCmd} {
    llength [info commands nodeCmds::*]
} {0}

namespace eval nodeCmds {
................................................................................
    $doc delete
    lappend result [catch {
        nodeCmds::e1 {
            nodeCmds::t "Some text"
        }} errMsg]
    lappend result $errMsg
} {{<docRoot><e1>Some text</e1></docRoot>} 1 {called outside domNode context}}














namespace delete nodeCmds














































































































































































































































# cleanup
::tcltest::cleanupTests
return







>
>







|



|







 







|



|



|



|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|


|











|











|







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|



|











|
|



|












|
|



|







|
|



|







 







|


|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>



>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










>




|









>







 








>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
..
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
...
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
...
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
...
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
....
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
....
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
....
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
....
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
....
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
....
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
....
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
#    dom-4.*:  parse -useForeignDTD
#    dom-5.*:  external entities
#    dom-6.*:  use in slave interpreter
#    dom-7.*:  setNameCheck, setTextCheck
#    dom-8.*:  createDocumentNode, documentNodes
#    dom-9.*:  setObjectCommands
#    dom-10.*: createNodeCmd
#    dom-11.*: featureinfo
#    dom-12.*: -feedbackAfter
#
# Copyright (c) 2002, 2003, 2004 Rolf Ade.

source [file join [file dir [info script]] loadtdom.tcl]

test dom-1.1 {createDocument with root node name not a XML Name} {
    list [catch {dom createDocument "root node"} msg] $msg
} "1 {Invalid root element name 'root node'}"

test dom-1.2 {createDocument with root node name not a XML Name} {
    list [catch {dom createDocument "1root"} msg] $msg
} "1 {Invalid root element name '1root'}"

test dom-1.3 {createDocument - root name us-ascii} {
    dom createDocument "root" doc 
    set root [$doc documentElement]
    set result [$root nodeName]
    $doc delete
    set result
................................................................................
    set result [$root namespaceURI]
    $doc delete
    set result
} "http://foo.bar"    

test dom-1.9 {createDocumentNS with root name not a NCName} {
    list [catch {dom createDocumentNS "http://foo.bar" "foo bar" doc} msg] $msg
} "1 {Invalid root element name 'foo bar'}"

test dom-1.10 {createDocumentNS with root name not a NCName} {
    list [catch {dom createDocumentNS "http://foo.bar" "a:b:c" doc} msg] $msg
} "1 {Invalid root element name 'a:b:c'}"

test dom-1.11 {createDocumentNS with root name not a NCName} {
    list [catch {dom createDocumentNS "http://foo.bar" "a b:b" doc} msg] $msg
} "1 {Invalid root element name 'a b:b'}"

test dom-1.12 {createDocumentNS with root name not a NCName} {
    list [catch {dom createDocumentNS "http://foo.bar" "a:a b" doc} msg] $msg
} "1 {Invalid root element name 'a:a b'}"

test dom-1.13 {createDocumentNS - check root name} {
    set doc [dom createDocumentNS "http://foo.bar" foo:root]
    set root [$doc documentElement]
    set result [$root nodeName]
    $doc delete
    set result
................................................................................
    }
    set nrOfCommands [llength [info commands]]
    set doc [dom createDocument root]
    rename $doc fooCmd
    fooCmd delete
    expr {[llength [info commands]] == $nrOfCommands}
} {1}

test dom-1.16 {createDocumentNS - empty namespace, no prefix} {
    dom createDocumentNS "" doc doc
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc/>}

test dom-1.17 {createDocumentNS -  namespace, no prefix} {
    dom createDocumentNS "uri" doc doc
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc xmlns="uri"/>}

test dom-1.18 {createDocumentNS -  namespace, no prefix} {
    dom createDocumentNS "uri" doc doc
    set result [$doc selectNodes -namespaces {ns uri} count(/ns:doc)]
    $doc delete
    set result
} 1

test dom-1.19 {createDocumentNS - namespace, prefix} {
    dom createDocumentNS "uri" n1:doc doc
    set result [$doc selectNodes -namespaces {ns uri} count(/ns:doc)]
    $doc delete
    set result
} 1

test dom-1.20 {createDocumentNS - empty namespace, prefix} {
    catch {dom createDocumentNS "" n1:doc doc} errMsg
    set errMsg
} {Missing URI in Namespace declaration}

test dom-1.21 {Explicit delete of scoped doc with domDoc cmd} {} {
    dom createDocument test doc
    domDoc $doc delete
    unset doc
} {}    

proc dom-1.22 {doc} {
    $doc delete
}
test dom-1.22 {Explicit delete of scoped doc in proc call from scope} {} {
    dom createDocument test doc
    dom-1.22 $doc
    unset doc
} {}    

test dom-1.23 {Explicit delete of scoped doc} {
    dom createDocument test doc
    $doc delete
    unset doc
} {}    

test dom-1.24 {Explicit delete of scoped doc} {
    dom createDocument test doc
    set result [catch {set doc foo} errMsg]
    lappend result $errMsg
    $doc delete
    unset doc
    set result
} {1 {can't set "doc": var is read-only}}

test dom-2.1 {Don't quash white space at start or end of non white space content} {
    set doc [dom parse {<root>
    some content
    </root>}]
    set root [$doc documentElement]
    $root text
................................................................................
    close $fd
    $doc delete
    info exists -keepEmpties
} -cleanup {
    removeFile dom.xml
} -result 0

test dom-2.8 {parse method: bogus option} -body {
    set result [catch {set doc [dom parse -bogusOption foo <root/>]} errMsg]
    lappend result $errMsg
} -match regexp -result {1 {bad option "-bogusOption": must be .*}}

test dom-2.9 {parse method: bogus option} -setup {
    set xmlFile [makeFile {<root>    </root>} dom.xml]
} -body {
    catch {unset -keepEmpties}
    set fd [open $xmlFile]
    set result [catch {set doc [dom parse -channel $fd -bogusOption]} errMsg]
    close $fd
    lappend result $errMsg
} -cleanup {
    removeFile dom.xml
} -match regexp -result {1 {bad option "-bogusOption": must be .*}}

set dom_dtd "
    <!ELEMENT root EMPTY>
    <!ATTLIST root lang CDATA #FIXED \"en\">"

proc extRefResolver {base systemId publicId} {
    global dom_dtd

    if {$publicId == "DOMCMDTEST"} {
        return [list string $base $dom_dtd]
    } else {
        return [::tdom::extRefHandler $base $systemId $publicId]
    }
}

test dom-2.10 {parse method: -paramentityparsing default is 'always'} {
    set doc [dom parse -externalentitycommand extRefResolver {
        <!DOCTYPE root PUBLIC "DOMCMDTEST" "dummysystemID">
        <root/>
................................................................................
    set result [catch {set doc [dom parse \
            -externalentitycommand extRefResolver {
        <!DOCTYPE root PUBLIC "DOMCMDTEST" "dummysystemID">
        <root/>
    }]} errMsg]
    lappend result $errMsg
} {1 {error "syntax error" in entity "dummysystemID" at line 1 character 20
"<!ATTLIST root lang # <--Error-- FIXED "en">", referenced at line 2 character 58}}

test dom-2.18 {parse document with nodes before and after the documentElement} {
    set doc [dom parse {<!-- First comment -->
<doc>
  <!-- Front comment -->
  <inner/>
  <!-- Back comment -->
................................................................................
</doc><!-- Last comment -->}

test dom-2.26 {Not well-formed input} {
    catch {dom parse {<xsl:transform       
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform        
                   <http://www.w3.org/1999/XSL/Transform> "/>}}
} 1

test dom-2.27 {parse -ignorexmlns} {
    set result [list]
    set doc [dom parse {<doc xmlns="foo.bar"><child/></doc>}]
    set root [$doc documentElement]
    lappend result [$root localName]
    lappend result [$root namespaceURI]
    set child [$root firstChild]
    lappend result [$child localName]
    lappend result [$child namespaceURI]
    lappend result [$doc selectNodes count(/doc/child)]
    $doc delete
    set doc [dom parse -ignorexmlns {<doc xmlns="foo.bar"><child/></doc>}]
    set root [$doc documentElement]
    lappend result [$root nodeName]
    lappend result [$root namespaceURI]
    set child [$root firstChild]
    lappend result [$child nodeName]
    lappend result [$child namespaceURI]
    lappend result [$doc selectNodes count(/doc/child)]
    $doc delete
    set result
} {doc foo.bar child foo.bar 0 doc {} child {} 1}

test dom-2.28 {parse document with undeclared xml prefix} {
    catch {dom parse {<doc><foo:e/></doc>}} errMsg
    string range $errMsg 0 30
} {Namespace prefix is not defined}

test dom-2.29 {parse not well-formed document with undeclared xml prefix} {
    catch {dom parse {<foo:e/>}} errMsg
    string range $errMsg 0 30
} {Namespace prefix is not defined}

test dom-2.30 {parse document with undeclared xml prefix} {
    catch {dom parse {<foo:e><a/></foo:e>}} errMsg
    string range $errMsg 0 30
} {Namespace prefix is not defined}

proc dom-2.31 {base systemId publicId} {
    switch $publicId {
        "e1" {
            # Not well-formed
            set data "<foo:e/>"
        }
        default {
            error "unknown public ID"
        }
    }
    return [list "string" $base $data]
}
test dom-2.31 {parse document with undeclared xml prefix} {
    catch {dom parse -externalentitycommand dom-2.31 \
                {<!DOCTYPE doc [<!ENTITY e1 PUBLIC "e1" "e1.xml">]>
                    <doc>&e1;</doc>}
    } errMsg
    string range $errMsg 0 30
} {Namespace prefix is not defined}
    
test dom-2.32 {parse document with undeclared xml prefix and -ignorexmlns} {
    set doc [dom parse -ignorexmlns {<foo:e><a/></foo:e>}]
    set result [[$doc documentElement] nodeName]
    $doc delete
    set result
} {foo:e}

test dom-2.33 {end of options option} {
    set doc [dom parse -json -- -0.123]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} -0.123

test dom-2.34 {XML prefix declaration with empty namespace} {
    catch {dom parse {<foo:doc xmlns:foo=""><e1/></foo:doc>}} errMsg
    set errMsg
} {Missing URI in Namespace declaration, referenced at line 1 character 22}

test dom-2.35 {-keepCDATA} {
    set doc [dom parse -keepCDATA {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}

test dom-2.36 {-keepCDATA} {
    set doc [dom parse -keepCDATA {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}]
    set root [$doc documentElement]
    set result [list]
    foreach child [$root childNodes] {
        lappend result [$child nodeType]
    }
    $doc delete
    set result
} {TEXT_NODE CDATA_SECTION_NODE TEXT_NODE}

test dom-2.37 {-keepCDATA} {
    set doc [dom parse -keepCDATA {<doc><e><![CDATA[one]]></e></doc>}]
    set result [list]
    foreach child [$doc selectNodes doc/e/node()] {
        lappend result [$child nodeType]
    }
    $doc delete
    set result
} {CDATA_SECTION_NODE}

test dom-2.38 {-keepCDATA} {
    set doc [dom parse -keepCDATA {<doc><e><![CDATA[one]]><![CDATA[two]]></e></doc>}]
    set result [list]
    foreach child [$doc selectNodes doc/e/node()] {
        lappend result [$child nodeType]
    }
    $doc delete
    set result
} {CDATA_SECTION_NODE CDATA_SECTION_NODE}

test dom-2.39 {-keepCDATA} {
    set doc [dom parse -keepCDATA {<doc><e><![CDATA[]]></e></doc>}]
    set result [$doc selectNodes count(doc/e/node())]
    $doc delete
    set result
} 0

test dom-2.40 {-keepCDATA white space only CDATA section} {
    set doc [dom parse -keepCDATA {<doc><e><![CDATA[
    ]]></e></doc>}]
    set result [$doc selectNodes count(doc/e/node())]
    $doc delete
    set result
} 0

test dom-2.41 {-keepCDATA and -keepEmpties} {
    set doc [dom parse -keepCDATA -keepEmpties {<doc><e><![CDATA[]]></e></doc>}]
    set result [$doc selectNodes count(doc/e/node())]
    $doc delete
    set result
} 1

test dom-2.42 {namespaces} {
    set doc [dom parse {
        <help><br xmlns:xsi="a"/><em xmlns:xsi="a">notes</em></help>
    }]
    $doc delete
} {}

test dom-3.1 {isName} {
    dom isName ":foo"
} {1}

test dom-3.2 {isName} {
    dom isName "_foo"
................................................................................

test dom-4.1 {-useForeignDTD 0} {
    set doc [dom parse -useForeignDTD 0 {<root/>}]
    $doc delete
} {}

test dom-4.2 {-useForeignDTD 1 with document with internal subset} {need_uri} {
    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
    set ::tdom::useForeignDTD "data/domCmd1.dtd"
    set doc [dom parse \
            -useForeignDTD 1 \
            -baseurl $baseURI \
            -externalentitycommand ::tdom::extRefHandler {
<!DOCTYPE root [
    <!ATTLIST root fixed CDATA #FIXED "toThat">
]>
<root/>}]
    set root [$doc documentElement]
    set result [$root @fixed]
    $doc delete
    set result
} {toThat}

test dom-4.3 {-useForeignDTD 1 with document with internal subset} {need_uri} {
    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
    set ::tdom::useForeignDTD "data/domCmd1.dtd"
    set doc [dom parse \
            -useForeignDTD 1 \
            -baseurl $baseURI \
            -externalentitycommand ::tdom::extRefHandler {
<!DOCTYPE root [
    <!ATTLIST root fixed2 CDATA #FIXED "toThat">
]>
<root/>}]
    set root [$doc documentElement]
    set result [$root @fixed]
    lappend result [$root @fixed2]
    $doc delete
    set result
} {toThis toThat}

test dom-4.4 {-useForeignDTD 1 with document without document declaration} {need_uri} {
    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
    set ::tdom::useForeignDTD "data/domCmd1.dtd"
    set doc [dom parse \
            -useForeignDTD 1 \
            -baseurl $baseURI \
            -externalentitycommand ::tdom::extRefHandler <root/>]
    set root [$doc documentElement]
    set result [$root @fixed]
    $doc delete
    set result
} {toThis}

test dom-4.5 {-useForeignDTD 1 does not overwrite a given external subset} {need_uri} {
    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
    set ::tdom::useForeignDTD "data/domCmd1.dtd"
    set doc [dom parse \
            -useForeignDTD 1 \
            -baseurl $baseURI \
            -externalentitycommand ::tdom::extRefHandler {
<!DOCTYPE root SYSTEM "data/domCmd2.dtd">
<root/>}]
    set root [$doc documentElement]
    set result [$root @fixed]
    $doc delete
    set result
} {toThat}
................................................................................

test dom-4.6 {-useForeignDTD with nonboolean arg} {need_uri} {
    set result [catch {set doc [dom parse -useForeignDTD foo <root/>]} errMsg]
    lappend result $errMsg
} {1 {expected boolean value but got "foo"}}

test dom-5.1 {document with external subset} {need_uri} {
    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
    set doc [dom parse \
            -baseurl $baseURI \
            -externalentitycommand ::tdom::extRefHandler {
<!DOCTYPE root SYSTEM "data/domCmd2.dtd">
<root/>}]
    set root [$doc documentElement]
    set result [$root @fixed]
    $doc delete
    set result
} {toThat}
................................................................................
                 -baseurl "dummy" \
                 -externalentitycommand [list dom-5.2 thisDoc] {
                     <!DOCTYPE root SYSTEM "">
                     <root/>}]
    $doc delete
    set ::dom-5_2
} {thisDoc}

proc dom-5.3 {base systemId publicId} {
    switch $publicId {
        "e1" {
            # Not well-formed
            set data "<e,1/>"
        }
        default {
            error "unknown public ID"
        }
    }
    return [list "string" $base $data]
}
test dom-5.3 {-externalentitycommand - nested external entities} -body {
    set result [catch {
        dom parse -externalentitycommand dom-5.3 \
            {<!DOCTYPE doc [
                            <!ENTITY e1 PUBLIC "e1" "e1.xml">
                            ]>
                <doc>&e1;</doc>}
    } msg]
    list $result $msg
} -result [list 1 {error "not well-formed (invalid token)" in entity "e1.xml" at line 1 character 2
"<e, <--Error-- 1/>", referenced at line 4 character 21}]

proc dom-5.4 {base systemId publicId} {
    switch $publicId {
        "e1" {
            set data "<e1>&e2;</e1>"
        }
        "e2" {
            set data "<e,2/>"
        }
        default {
            error "unknown public ID"
        }
    }
    return [list "string" $base $data]
}
test dom-5.4 {-externalentitycommand - nested external entities} -body {
    set result [catch {
        dom parse -externalentitycommand dom-5.4 \
            {<!DOCTYPE doc [
                            <!ENTITY e1 PUBLIC "e1" "e1.xml">
                            <!ENTITY e2 PUBLIC "e2" "e2.xml">
                            ]>
                <doc>&e1;</doc>}
    } msg]
    list $result $msg
} -result [list 1 {error "not well-formed (invalid token)" in entity "e2.xml" at line 1 character 2
"<e, <--Error-- 2/>", referenced in entity "e1.xml" at line 1 character 4, referenced at line 5 character 21}]

proc dom-5.5 {base systemId publicId} {
    switch $publicId {
        "e1" {
            set data "<e1>&e2;</e1>"
        }
        "e2" {
            set data "<e2>&e3;</e2>"
        }
        "e3" {
            # Not well-formed
            set data "<e,3/>"
        }
        default {
            error "unknown public ID"
        }
    }
    return [list "string" $base $data]
}
test dom-5.5 {-externalentitycommand - nested external entities} -body {
    set result [catch {
        dom parse -externalentitycommand dom-5.5 \
            {<!DOCTYPE doc [
                            <!ENTITY e1 PUBLIC "e1" "e1.xml">
                            <!ENTITY e2 PUBLIC "e2" "e2.xml">
                            <!ENTITY e3 PUBLIC "e3" "e3.xml">
                            ]>
                <doc>&e1;</doc>}
    } msg]
    list $result $msg
} -result [list 1 {error "not well-formed (invalid token)" in entity "e3.xml" at line 1 character 2
"<e, <--Error-- 3/>", referenced in entity "e2.xml" at line 1 character 4, referenced in entity "e1.xml" at line 1 character 4, referenced at line 6 character 21}]

proc dom-5.6 {base systemId publicId} {
    switch $publicId {
        "e1" {
            set data [open $::e1]
        }
        default {
            error "unknown public ID"
        }
    }
    lappend ::openChannels $data
    return [list "channel" $base $data]
}
test dom-5.6 {-externalentitycommand - nested external entities} -setup {
    set e1 [makeFile "<e,1/>" e1.xml]
    set openChannels [list]
} -body {
    set result [catch {
        dom parse -externalentitycommand dom-5.6 \
            {<!DOCTYPE doc [
                            <!ENTITY e1 PUBLIC "e1" "e1.xml">
                            ]>
                <doc>&e1;</doc>}
    } msg]
    list $result $msg
} -cleanup {
    foreach channel $openChannels {close $channel}
    removeFile e1.xml
} -result [list 1 {error "not well-formed (invalid token)" in entity "e1.xml" at line 1 character 2, referenced at line 4 character 21}]

proc dom-5.7 {base systemId publicId} {
    switch $publicId {
        "e1" {
            set data [open $::e1]
        }
        "e2" {
            set data [open $::e2]
        }
        default {
            error "unknown public ID"
        }
    }
    lappend ::openChannels $data
    return [list "channel" $base $data]
}
test dom-5.7 {-externalentitycommand - nested external entities} -setup {
    set e1 [makeFile "<e1>&e2;</e1>" e1.xml]
    set e2 [makeFile "<e,2/>" e2.xml]
    set openChannels [list]
} -body {
    set result [catch {
        dom parse -externalentitycommand dom-5.7 \
            {<!DOCTYPE doc [
                            <!ENTITY e1 PUBLIC "e1" "e1.xml">
                            <!ENTITY e2 PUBLIC "e2" "e2.xml">
                            ]>
                <doc>&e1;</doc>}
    } msg]
    list $result $msg
} -cleanup {
    foreach channel $openChannels {close $channel}
    removeFile e1.xml
    removeFile e2.xml
} -result [list 1 {error "not well-formed (invalid token)" in entity "e2.xml" at line 1 character 2, referenced in entity "e1.xml" at line 1 character 4, referenced at line 5 character 21}]

proc dom-5.8 {base systemId publicId} {
    switch $publicId {
        "e1" {
            set data [open $::e1]
        }
        "e2" {
            set data [open $::e2]
        }
        "e3" {
            set data [open $::e3]
        }
        default {
            error "unknown public ID"
        }
    }
    lappend ::openChannels $data
    return [list "channel" $base $data]
}
test dom-5.8 {-externalentitycommand - nested external entities} -setup {
    set e1 [makeFile "<e1>&e2;</e1>" e1.xml]
    set e2 [makeFile "<e2>&e3;</e2>" e2.xml]
    set e3 [makeFile "<e,3/>" e3.xml]
    set openChannels [list]
} -body {
    set result [catch {
        dom parse -externalentitycommand dom-5.8 \
            {<!DOCTYPE doc [
                            <!ENTITY e1 PUBLIC "e1" "e1.xml">
                            <!ENTITY e2 PUBLIC "e2" "e2.xml">
                            <!ENTITY e3 PUBLIC "e3" "e3.xml">
                            ]>
                <doc>&e1;</doc>}
    } msg]
    list $result $msg
} -cleanup {
    foreach channel $openChannels {close $channel}
    removeFile e1.xml
    removeFile e2.xml
    removeFile e3.xml
} -result [list 1 {error "not well-formed (invalid token)" in entity "e3.xml" at line 1 character 2, referenced in entity "e2.xml" at line 1 character 4, referenced in entity "e1.xml" at line 1 character 4, referenced at line 6 character 21}]

test dom-5.9 {Wrong option after -externalentitycommand} -body {
    set result [catch {dom parse -externalentitycommand ::tdom::extRefHandler \
                           -useForeignDTD foo}]
} -result 1

test dom-6.1 {use in slave interpreter} {
    set slave [interp create]
    load {} tdom $slave
    interp eval $slave {
        dom parse <root>foo</root> doc
        $doc documentElement root
................................................................................
            nodeCmds::t "foo\u0003bar"
        }
    }} errMsg]
    dom setTextCheck 1
    $doc delete
    lappend result $errMsg
} [list 1 "Invalid text value 'foo\u0003bar'"]

test dom-7.19 {setNameCheck / createDocument} {
    dom setNameCheck 0
    dom createDocument "foo bar" doc
    set result [$doc asXML -indent none]
    $doc delete
    dom setNameCheck 1
    set result
} {<foo bar/>}
    

test dom-8.1 {createDocumentNode} {
    set result [catch {dom createDocumentNode foo bar}]
} {1}

test dom-8.2 {createDocumentNode} {
    set docNode [dom createDocumentNode]
................................................................................
    $doc delete
    $docNode appendFromList $listRep
    set result [$docNode asXML -indent none]
    $docNode delete
    set result
} {<root><child1/><child2/>some text<child3/></root>}

test dom-8.7 {createDocumentNode} {
    dom createDocumentNode docNode
    dom createDocumentNode docNode
    $docNode delete
    set result ""
} ""

test dom-8.8 {createDocumentNode} {
    dom createDocumentNode -jsonType ARRAY docNode
    set result [$docNode jsonType]
    $docNode delete
    set result
} ARRAY

test dom-8.9 {createDocumentNode} {
    set docNode [dom createDocumentNode -jsonType NUMBER]
    set result [$docNode jsonType]
    $docNode delete
    set result
} NUMBER

test dom-8.10 {createDocumentNode} {
    catch {dom createDocumentNode -foo NULL docNode} errMsg
    set errMsg
} {bad option "-foo": must be -jsonType}

test dom-8.10 {createDocumentNode} {
    catch {dom createDocumentNode -foo NULL docNode} errMsg
    set errMsg
} {bad option "-foo": must be -jsonType}

test dom-8.11 {createDocumentNode} {
    catch {dom createDocumentNode -jsonType FOO docNode} errMsg
    set errMsg
} {bad jsonType "FOO": must be NONE, ARRAY, OBJECT, NULL, TRUE, FALSE, STRING, or NUMBER}

test dom-9.1 {setObjectCommands} {
    dom setObjectCommands
} {automatic}

test dom-9.2 {setObjectCommands} {
    dom setObjectCommands automatic
} {automatic}
................................................................................
    set doc [dom parse <root><child1/><child2/></root>]
    set root [domDoc $doc documentElement]
    set result [expr {$nrOfCmds == [llength [info commands]]}]
    dom setObjectCommands command
    set docCmd [domNode $root ownerDocument]
    lappend result [expr {$nrOfCmds + 1 == [llength [info commands]]}]
    $docCmd delete
    dom setObjectCommands automatic
    set result
} {1 1}

test dom-9.6 {node token with result var argument} {
    dom setObjectCommands token
    set doc [dom parse <root><child1/><child2/></root>]
    domDoc $doc documentElement var
    domNode $var firstChild var
    domNode $var nextSibling var
    domDoc $doc delete
    dom setObjectCommands automatic
} {automatic}


test dom-9.7 {Attempt to use the token to an already freed node} {
    dom setObjectCommands token
    set doc [dom createDocument one]
    set top [domDoc $doc documentElement]
    set elem [domDoc $doc createElement one]
    domNode $elem delete
    set result [catch {domNode $elem asList} errMsg]
    lappend result $errMsg
    domDoc $doc delete
    dom setObjectCommands automatic
    set result
} {1 {Parameter "" is not a domNode.}}
    
catch {namespace delete nodeCmds}

namespace eval nodeCmds {
    dom createNodeCmd elementNode e1
    dom createNodeCmd elementNode e2
    dom createNodeCmd commentNode c
    dom createNodeCmd textNode    t
    dom createNodeCmd cdataNode   cdata
    dom createNodeCmd piNode      pi
    dom createNodeCmd parserNode  parser
    dom createNodeCmd -tagName foo elementNode bar
}

test dom-10.1 {createNodeCmd} {
    llength [info commands nodeCmds::*]
} {8}

namespace eval nodeCmds {
    rename e1 {}
    rename e2 {}
    rename c {}
    rename t {}
    rename cdata {}
    rename pi {}
    rename parser {}
    rename bar {}
}

test dom-10.2 {createNodeCmd} {
    llength [info commands nodeCmds::*]
} {0}

namespace eval nodeCmds {
................................................................................
    $doc delete
    lappend result [catch {
        nodeCmds::e1 {
            nodeCmds::t "Some text"
        }} errMsg]
    lappend result $errMsg
} {{<docRoot><e1>Some text</e1></docRoot>} 1 {called outside domNode context}}

namespace eval nodeCmds {
    dom createNodeCmd -tagName foo elementNode bar
}
test dom-10.6 {createNodeCmd - option -tagName} {
    set doc [dom createDocumentNode]
    $doc appendFromScript {
        nodeCmds::bar {}
    }
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<foo/>}

namespace delete nodeCmds

test dom-11.1 {featureinfo - expatversion} -body {
    dom featureinfo expatversion
} -match regexp -result {expat_.*}

test dom-11.2 {featureinfo - invalid arg} -body {
    catch {dom featureinfo foo} errMsg
} -result 1

test dom-11.3 {featureinfo - expatmajorversion} -body {
    dom featureinfo expatmajorversion
} -match regexp -result {(1|2)}

test dom-11.4 {featureinfo - dtd} -body {
    dom featureinfo dtd
} -match regexp -result {(0|1)}

test dom-11.5 {featureinfo - jsonmaxnesting} {
    dom featureinfo jsonmaxnesting
} 2000

test dom-11.6 {featureinfo - versionhash} {
    regexp {^[0-9a-fA-F]+$} [dom featureinfo versionhash]
} 1

proc ::dom::domParseFeedback {} {
    return -code break
}
test dom-12.1 {-feedbackAfter -- cmd returns TCL_BREAK} -body {
    dom parse -feedbackAfter 1 {<doc><e1/><e1/><e1/></doc>}
} -result ""

proc ::dom::domParseFeedback {} {
    error "Error in feedback cmd."
}
test dom-12.2 {-feedbackAfter -- cmd returns TCL_ERROR} -body {
    set result [catch {
        dom parse -feedbackAfter 1 {<doc><e1/><e1/><e1/></doc>}
    } msg]
    list $result $msg
} -result [list 1 "Error in feedback cmd."]

proc ::dom::domParseFeedback {} {
    # Update progess dialog, check for cancel etc.
    return
}
test dom-12.3 {-feedbackAfter} -body {
    set doc [dom parse -feedbackAfter 1 {<doc><e1/><e1/><e1/></doc>}]
    $doc selectNodes count(//*)
} -result 4
test dom-12.4 {-feedbackAfter and -channel} -setup {
    set xmlFile [makeFile {<doc><e1/><e1/><e1/></doc>} dom.xml]
} -body {
    set fd [open $xmlFile]
    set doc [dom parse -channel $fd -feedbackAfter 1]
    close $fd
    $doc selectNodes count(//*)
} -cleanup {
    removeFile dom.xml
} -result 4
proc extRefResolver-12.5 {base systemId publicId} {
    switch $publicId {
        "a" {
            set data "<e1/>"
        }
        "b" {
            set data "<e1/><e1/>"
        }
        default {
            error "unknown public ID"
        }
    }
    return [list "string" $base $data]
}
test dom-12.5 {-feedbackAfter and external entities} -body {
    set doc [dom parse -externalentitycommand extRefResolver-12.5 \
                 -feedbackAfter 1 {
                     <!DOCTYPE doc [
                                    <!ENTITY a PUBLIC "a" "a.xml">
                                    <!ENTITY b PUBLIC "b" "b.xml">
                                    ]>
                     <doc>&a;&b;</doc>}]
    $doc selectNodes count(//*)
} -result 4

set cancel 0
proc extRefResolver-12.6 {base systemId publicId} {
    global cancel
    switch $publicId {
        "a" {
            set cancel 1
            set data "<e1/><e1/>"
        }
        "b" {
            set data "<e1/>"
        }
        default {
            error "unknown public ID"
        }
    }
    return [list "string" $base $data]
}
proc ::dom::domParseFeedback {} {
    global cancel
    if {$cancel} {
        return -code break
    }
}
test dom-12.6 {-feedbackAfter and external entities, with cancel} -body {
    dom parse -externalentitycommand extRefResolver-12.6 \
        -feedbackAfter 1 {
            <!DOCTYPE doc [
                           <!ENTITY a PUBLIC "a" "a.xml">
                           <!ENTITY b PUBLIC "b" "b.xml">
                          ]>
            <doc>&a;&b;</doc>}
} -result ""
proc ::dom::domParseFeedback {} {
    global cancel
    if {$cancel} {
        error "Error in feedback cmd."
    }
}
test dom-12.7 {-feedbackAfter and external entities, with error} -body {
    set result [catch {dom parse -externalentitycommand extRefResolver-12.6 \
                           -feedbackAfter 1 {
                               <!DOCTYPE doc [
                                              <!ENTITY a PUBLIC "a" "a.xml">
                                              <!ENTITY b PUBLIC "b" "b.xml">
                                             ]>
                               <doc>&a;&b;</doc>}} msg]
    list $result $msg
} -result [list 1 "Error in feedback cmd."]

test dom-12.8 {-feedbackAfter without -feedbackcmd} -setup {
    catch {rename ::dom::domParseFeedback ""}
} -body {
    set result [catch {dom parse -feedbackAfter 100 <doc/>} msg]
    list $result $msg
} -result {1 {If -feedbackAfter is used, -feedbackcmd must also be used.}}

proc feedbackcmd-12.9 {} {
    return -code break
}
test dom-12.9 {-feedbackAfter with -feedbackcmd -- cmd returns TCL_BREAK} -body {
    dom parse -feedbackAfter 1 -feedbackcmd feedbackcmd-12.9 \
        {<doc><e1/><e1/><e1/></doc>}
} -result ""

proc feedbackcmd-12.10 {} {
    error "Error in feedback cmd."
}
test dom-12.10 {-feedbackAfter with -feedbackcmd -- cmd returns TCL_ERROR} -body {
    set result [catch {
        dom parse -feedbackAfter 1 -feedbackcmd feedbackcmd-12.10 \
            {<doc><e1/><e1/><e1/></doc>}
    } msg]
    list $result $msg
} -result [list 1 "Error in feedback cmd."]

proc feedbackcmd-12.11 {} {
    # Update progess dialog, check for cancel etc.
    return
}
test dom-12.11 {-feedbackAfter with -feedbackcmd} -body {
    set doc [dom parse -feedbackAfter 1 -feedbackcmd feedbackcmd-12.11 \
                 {<doc><e1/><e1/><e1/></doc>}]
    $doc selectNodes count(//*)
} -result 4
test dom-12.12 {-feedbackAfter with -feedbackcmd and -channel} -setup {
    set xmlFile [makeFile {<doc><e1/><e1/><e1/></doc>} dom.xml]
} -body {
    set fd [open $xmlFile]
    set doc [dom parse -channel $fd -feedbackAfter 1 \
                 -feedbackcmd feedbackcmd-12.11]
    close $fd
    $doc selectNodes count(//*)
} -cleanup {
    removeFile dom.xml
} -result 4
test dom-12.13 {-feedbackAfter with -feedbackcmd and external entities} -body {
    set doc [dom parse -externalentitycommand extRefResolver-12.5 \
                 -feedbackcmd feedbackcmd-12.11 \
                 -feedbackAfter 1 {
                     <!DOCTYPE doc [
                                    <!ENTITY a PUBLIC "a" "a.xml">
                                    <!ENTITY b PUBLIC "b" "b.xml">
                                    ]>
                     <doc>&a;&b;</doc>}]
    $doc selectNodes count(//*)
} -result 4

set cancel 0
proc feedbackcmd-12.14 {} {
    global cancel
    if {$cancel} {
        return -code break
    }
}
test dom-12.14 {-feedbackAfter with -feedbackcmd and external entities, with cancel} -body {
    dom parse -externalentitycommand extRefResolver-12.6 \
        -feedbackcmd feedbackcmd-12.14 \
        -feedbackAfter 1 {
            <!DOCTYPE doc [
                           <!ENTITY a PUBLIC "a" "a.xml">
                           <!ENTITY b PUBLIC "b" "b.xml">
                          ]>
            <doc>&a;&b;</doc>}
} -result ""
set cancel 0
proc feedbackcmd-12.15 {} {
    global cancel
    if {$cancel} {
        error "Error in feedback cmd."
    }
}
test dom-12.15 {-feedbackAfter with -feedbackcmd and external entities, with error} -body {
    set result [catch {dom parse -externalentitycommand extRefResolver-12.6 \
                           -feedbackcmd feedbackcmd-12.15 \
                           -feedbackAfter 1 {
                               <!DOCTYPE doc [
                                              <!ENTITY a PUBLIC "a" "a.xml">
                                              <!ENTITY b PUBLIC "b" "b.xml">
                                             ]>
                               <doc>&a;&b;</doc>}} msg]
    list $result $msg
} -result [list 1 "Error in feedback cmd."]
proc feedbackcmd-12.16 {} {
    incr ::feedbackcmd-12.16
}
test dom-12.16 {-feedbackcmd setting interp result w/ invalid XML} -body {
    set ::feedbackcmd-12.16 0
    set result [catch {dom parse -feedbackcmd feedbackcmd-12.16 \
                           -feedbackAfter 1 {<doc><e1/><e1/><e1></doc}} msg]
    list $result $msg
} -result [list 1 {error "unclosed token" at line 1 character 19
"<doc><e1/><e1/><e1>< <--Error-- /doc"}]

# cleanup
::tcltest::cleanupTests
return

Changes to tests/domDoc.test.

27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
...
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
...
207
208
209
210
211
212
213










































































































214
215
216
217
218
219
220
...
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
...
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
....
1001
1002
1003
1004
1005
1006
1007





























1008
1009
1010
1011
1012
1013
1014
....
1037
1038
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049






1050
1051
1052
1053
1054
1055
1056
....
1221
1222
1223
1224
1225
1226
1227









1228
1229
1230
1231
1232
1233
1234
....
1295
1296
1297
1298
1299
1300
1301


















1302
1303
1304
1305
1306
1307
1308
....
1358
1359
1360
1361
1362
1363
1364





























1365
1366
1367
1368
#    domDoc-21.*: baseURI
#    domDoc-22.*: appendFromScript
#    domDoc-23.*: getElementsByTagNameNS
#    domDoc-24.*: cdataSectionElements
#    domDoc-25.*: selectNodesNamespaces
#    domDoc-26.*: fragments list
#    domDoc-27.*: deleteXPathCache

#
# Copyright (c) 2004 - 2007 Rolf Ade.

source [file join [file dir [info script]] loadtdom.tcl]

test domDoc-1.1 {asXML -escapeNonASCII} {need_i18n} {
    set doc [dom parse [tDOM::xmlReadFile \
            [file join [file dir [info script]] data/i18n_1.xml]]]
    set result [$doc asXML -escapeNonASCII]
    $doc delete
    set result
} {<test>&#1072;&#1073;&#1074;&#1075;&#1076;&#1077;&#1078;&#1079;&#1080;&#1081;</test>
}

test domDoc-1.2 {asXML -escapeNonASCII; comments and PI's are not altered} {need_i18n} {
    set doc [dom parse [tDOM::xmlReadFile \
            [file join [file dir [info script]] data/i18n_2.xml]]]
    set result [$doc asXML -indent none -escapeNonASCII]
    $doc delete
    set result
} "<root withUmlauts=\"&#228;&#246;&#252;&#223;\"><!-- A comment with german umlauts: \u00E4\u00F6\u00FC\u00DF --><?\u00E4\u00F6\u00FC\u00DF A processing node with german umlauts?>
german umlauts: &#228;&#246;&#252;&#223;
</root>"
................................................................................

test domDoc-1.10 {asXML - unknown option} {
    set doc [dom parse {<!DOCTYPE root SYSTEM "file:///boo.baz"><root/>}]
    set errMsg ""
    catch {$doc asXML -fooOption 1} errMsg
    $doc delete
    set errMsg
} {bad option "-fooOption": must be -indent, -channel, -escapeNonASCII, -doctypeDeclaration, or -escapeAllQuot}

test domDoc-1.11 {asXML - non boolean value to -doctypeDeclaration} {
    set doc [dom parse {<!DOCTYPE root SYSTEM "file:///boo.baz"><root/>}]
    set errMsg ""
    catch {$doc asXML -doctypeDeclaration foo} errMsg
    $doc delete
    set errMsg
................................................................................
    set result
} {<doc>
    <!--Comment 1-->
    <e1/>
    <!--Comment 2-->
</doc>
}











































































































set doc [dom parse <root/>]

test domDoc-2.1 {publicId - no publicId there} {
    $doc publicId
} {}

................................................................................
    set result [catch {$xsltCmd -bogusOption foo $doc resultDoc} errMsg]
    lappend result $errMsg
    lappend result [catch {$xsltCmd $doc resultDoc}]
    lappend result [$resultDoc asXML -indent none]
    $resultDoc delete
    rename $xsltCmd {}
    set result
} {1 {bad option "-bogusOption": must be -parameters, -ignoreUndeclaredParameters, or -xsltmessagecmd} 0 {param1Default param2Default param3Default }}

test domDoc-3.4 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd -xsltmessagecmd msgCmd1} errMsg]
    rename $xsltCmd {}
    lappend result $errMsg
} {1 {wrong # args: should be "?-parameters parameterList? ?-ignoreUndeclaredParameters? ?-xsltmessagecmd cmd? <xmlDocObj> ?objVar?"}}

test domDoc-3.5 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd $doc resultDoc bogus} errMsg]
    rename $xsltCmd {}
    lappend result $errMsg
} {1 {wrong # args: should be "?-parameters parameterList? ?-ignoreUndeclaredParameters? ?-xsltmessagecmd cmd? <xmlDocObj> ?objVar?"}}

test domDoc-3.6 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd -parameters {param1 foo} -parameters {param2 foo} $doc resultDoc} errMsg]
    rename $xsltCmd {}
................................................................................
    }
    $elemNode setAttribute id "new"
    [$doc getElementById "new"] getAttribute name
} -cleanup {
    $doc delete
} -result that

test domDoc-10.3 {getElementById} -setup $getElementByIdSetup -body {
    set root [$doc documentElement]
    set elemNode [$root selectNodes {elem[2]}]
    if {![$elemNode hasAttribute id]} {
        error "error in the test code"
    }
    $elemNode setAttribute id "new"
    [$doc getElementById "new"] getAttribute name
} -cleanup {
    $doc delete
} -result that

test domDoc-10.4 {getElementById} -setup $getElementByIdSetup -body {
    set root [$doc documentElement]
    set elemNode [$root selectNodes {elem[2]}]
    if {![$elemNode hasAttribute id]} {
        error "error in the test code"
    }
    $root removeChild $elemNode
................................................................................
    lappend result [$node nodeName]
    lappend result [$doc selectNodes -namespaces {} doc typeVar]
    lappend result $typeVar
    $doc delete
    set result
} [list tdom:doc tdom:doc "" empty]






























test domDoc-21.1 {baseURI} {
    set doc [dom createDocumentNode]
    set result [$doc baseURI]
    $doc delete
    set result
} {}

................................................................................
    lappend result [[$doc documentElement] nodeName]
    $doc delete
    set result
} {<e1/> e1}

test domDoc-22.2 {appendFromScript} {
    set doc [dom parse <root/>]
    namespace eval nodeCmds {
        $doc appendFromScript {

            e1
            e2
        }
    }






    set result [$doc asXML -indent none]
    foreach node [$doc selectNodes *] {
        lappend result [$node parentNode]
        lappend result [expr {$doc == [$node ownerDocument]}]
    }
    $doc delete
    set result
................................................................................
    $doc documentElement root
    set node [$root firstChild]
    $doc cdataSectionElements child 1
    set result [$node asXML -indent none]
    $doc delete
    set result
} {<child><![CDATA[some text]]></child>}










test domDoc-25.1 {selectNodesNamespaces} {
    set doc [dom createDocument foo]
    set result [$doc selectNodesNamespaces]
    $doc delete
    set result
} {}
................................................................................
    set node [$doc selectNodes default1:root/default2:elem1]
    set result [list [$node prefix] [$node localName]]
    set node [$doc selectNodes default1:root/default2:elem1/elem11]
    lappend result [$node nodeName] [$node namespaceURI]
    $doc delete
    set result
} {{} elem1 elem11 {}}



















test domDoc-25.8 {selectNodesNamespaces} {
    set doc [dom parse {<root xmlns="rootdefaultNS">
        <elem1 xmlns="elem1NS"><elem11 xmlns=""/></elem1>
        <elem2 xmlns="elem2NS"/>
        </root>}]
    $doc selectNodesNamespaces {default2 elem1NS default1 rootdefaultNS}
................................................................................
    lappend result [$doc deleteXPathCache foo/bar]
    lappend result [$doc deleteXPathCache 2+2]
    lappend result [$doc deleteXPathCache]
    $doc selectNodes -cache 1 2+2
    $doc delete
    set result
} {{} {} {} {}}






























# cleanup
::tcltest::cleanupTests
return







>






|








|







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|








|








|







 







<
<
<
<
<
<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<
|
>
|
<
|
<
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
...
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
...
826
827
828
829
830
831
832












833
834
835
836
837
838
839
....
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
....
1161
1162
1163
1164
1165
1166
1167

1168
1169
1170

1171

1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
....
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
....
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
....
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
#    domDoc-21.*: baseURI
#    domDoc-22.*: appendFromScript
#    domDoc-23.*: getElementsByTagNameNS
#    domDoc-24.*: cdataSectionElements
#    domDoc-25.*: selectNodesNamespaces
#    domDoc-26.*: fragments list
#    domDoc-27.*: deleteXPathCache
#    domDoc-28.*: createElementNS
#
# Copyright (c) 2004 - 2007 Rolf Ade.

source [file join [file dir [info script]] loadtdom.tcl]

test domDoc-1.1 {asXML -escapeNonASCII} {need_i18n} {
    set doc [dom parse [tdom::xmlReadFile \
            [file join [file dir [info script]] data/i18n_1.xml]]]
    set result [$doc asXML -escapeNonASCII]
    $doc delete
    set result
} {<test>&#1072;&#1073;&#1074;&#1075;&#1076;&#1077;&#1078;&#1079;&#1080;&#1081;</test>
}

test domDoc-1.2 {asXML -escapeNonASCII; comments and PI's are not altered} {need_i18n} {
    set doc [dom parse [tdom::xmlReadFile \
            [file join [file dir [info script]] data/i18n_2.xml]]]
    set result [$doc asXML -indent none -escapeNonASCII]
    $doc delete
    set result
} "<root withUmlauts=\"&#228;&#246;&#252;&#223;\"><!-- A comment with german umlauts: \u00E4\u00F6\u00FC\u00DF --><?\u00E4\u00F6\u00FC\u00DF A processing node with german umlauts?>
german umlauts: &#228;&#246;&#252;&#223;
</root>"
................................................................................

test domDoc-1.10 {asXML - unknown option} {
    set doc [dom parse {<!DOCTYPE root SYSTEM "file:///boo.baz"><root/>}]
    set errMsg ""
    catch {$doc asXML -fooOption 1} errMsg
    $doc delete
    set errMsg
} {bad option "-fooOption": must be -indent, -channel, -escapeNonASCII, -doctypeDeclaration, -xmlDeclaration, -encString, -escapeAllQuot, -indentAttrs, -nogtescape, or -noEmptyElementTag}

test domDoc-1.11 {asXML - non boolean value to -doctypeDeclaration} {
    set doc [dom parse {<!DOCTYPE root SYSTEM "file:///boo.baz"><root/>}]
    set errMsg ""
    catch {$doc asXML -doctypeDeclaration foo} errMsg
    $doc delete
    set errMsg
................................................................................
    set result
} {<doc>
    <!--Comment 1-->
    <e1/>
    <!--Comment 2-->
</doc>
}

test domDoc-1.21 {asXML -indentAttrs} {
    set doc [dom parse {<Element attr1="val1" attr2="val2"/>}]
    set result [$doc asXML -indentAttrs 4]
    $doc delete
    set result
} {<Element
    attr1="val1"
    attr2="val2"/>
}

test domDoc-1.22 {asXML} {
    set doc [dom createDocument doc]
    set result [$doc asXML]
    $doc delete
    set result
} {<doc/>
}

test domDoc-1.23 {asXML -xmlDeclaration} {
    set doc [dom createDocument doc]
    set result [$doc asXML -xmlDeclaration 1]
    $doc delete
    set result
} {<?xml version="1.0"?>
<doc/>
}

test domDoc-1.23 {asXML -xmlDeclaration} {
    set doc [dom createDocument doc]
    set result [$doc asXML -xmlDeclaration 1]
    $doc delete
    set result
} {<?xml version="1.0"?>
<doc/>
}

test domDoc-1.24 {asXML just -encString without -xmlDeclaration} {
    set doc [dom createDocument doc]
    set result [$doc asXML -encString foo]
    $doc delete
    set result
} {<doc/>
}

test domDoc-1.25 {asXML -xmlDeclaration -encString} {
    set doc [dom createDocument doc]
    set result [$doc asXML -xmlDeclaration 1 -encString foo]
    $doc delete
    set result
} {<?xml version="1.0" encoding="foo"?>
<doc/>
} 

test domDoc-1.26 {asXML -xmlDeclaration, encoding set by encoding method} {
    set doc [dom createDocument doc]
    $doc encoding "foo"
    set result [$doc asXML -xmlDeclaration 1]
    $doc delete
    set result
} {<?xml version="1.0" encoding="foo"?>
<doc/>
}    

test domDoc-1.27 {asXML -xmlDeclaration -encString} {
    set doc [dom createDocument doc]
    set result [catch {
        [$doc asXML -xmlDeclaration 1 -encString foo \
             -encString bar -wrongOption]
    }]
    $doc delete
    set result
} 1 

test domDoc-1.28 {asXML -xmlDeclaration not xml compliant -encString} {
    set doc [dom createDocument doc]
    set result [$doc asXML -xmlDeclaration 1 -encString 1\u2345]
    $doc delete
    set result
} [subst -nocommands -novariables {<?xml version="1.0" encoding="1\u2345"?>
<doc/>
}]

test domDoc-1.29 {asXML -nogtescape} {
    set doc [dom parse {<doc attr="foo>bar">></doc>}]
    set result [$doc asXML -nogtescape -indent none]
    $doc delete
    set result
} {<doc attr="foo>bar">></doc>}

test domDoc-1.30 {asXML -noEmptyElementTag} {
    set doc [dom parse {<doc><elm/></doc>}]
    set result [$doc asXML -noEmptyElementTag -indent none]
    $doc delete
    set result
} {<doc><elm></elm></doc>}

test domDoc-1.31 {asXML '"' in attribute value} {
    # emacs: "
    set doc [dom createDocument doc]
    set root [$doc documentElement]
    $root setAttribute attr "foo\"bar"
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc attr="foo&quot;bar"/>}

set doc [dom parse <root/>]

test domDoc-2.1 {publicId - no publicId there} {
    $doc publicId
} {}

................................................................................
    set result [catch {$xsltCmd -bogusOption foo $doc resultDoc} errMsg]
    lappend result $errMsg
    lappend result [catch {$xsltCmd $doc resultDoc}]
    lappend result [$resultDoc asXML -indent none]
    $resultDoc delete
    rename $xsltCmd {}
    set result
} {1 {bad option "-bogusOption": must be -parameters, -ignoreUndeclaredParameters, -maxApplyDepth, or -xsltmessagecmd} 0 {param1Default param2Default param3Default }}

test domDoc-3.4 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd -xsltmessagecmd msgCmd1} errMsg]
    rename $xsltCmd {}
    lappend result $errMsg
} {1 {wrong # args: should be "?-parameters parameterList? ?-ignoreUndeclaredParameters? ?-maxApplyDepth int? ?-xsltmessagecmd cmd? <xmlDocObj> ?objVar?"}}

test domDoc-3.5 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd $doc resultDoc bogus} errMsg]
    rename $xsltCmd {}
    lappend result $errMsg
} {1 {wrong # args: should be "?-parameters parameterList? ?-ignoreUndeclaredParameters? ?-maxApplyDepth int? ?-xsltmessagecmd cmd? <xmlDocObj> ?objVar?"}}

test domDoc-3.6 {toXSLTcmd} {
    set xslt [dom parse -keepEmpties $xslt1]
    set xsltCmd [$xslt toXSLTcmd]

    set result [catch {$xsltCmd -parameters {param1 foo} -parameters {param2 foo} $doc resultDoc} errMsg]
    rename $xsltCmd {}
................................................................................
    }
    $elemNode setAttribute id "new"
    [$doc getElementById "new"] getAttribute name
} -cleanup {
    $doc delete
} -result that













test domDoc-10.4 {getElementById} -setup $getElementByIdSetup -body {
    set root [$doc documentElement]
    set elemNode [$root selectNodes {elem[2]}]
    if {![$elemNode hasAttribute id]} {
        error "error in the test code"
    }
    $root removeChild $elemNode
................................................................................
    lappend result [$node nodeName]
    lappend result [$doc selectNodes -namespaces {} doc typeVar]
    lappend result $typeVar
    $doc delete
    set result
} [list tdom:doc tdom:doc "" empty]

test domDoc-20.6 {selectNodes with -namespaces option} {
    set doc [dom createDocumentNS "http://tdom.org" tdom:doc]
    set node [$doc selectNodes \
                  -namespaces {foo bar} \
                  -namespaces {a b c d} \
                  -namespaces {tdom http://tdom.org} \
                  tdom:doc]
    set result [$node nodeName]
    set node [$doc selectNodes \
                  -namespaces {myPrefix http://tdom.org} \
                  myPrefix:doc]
    lappend result [$node nodeName]
    lappend result [$doc selectNodes -namespaces {} doc typeVar]
    lappend result $typeVar
    $doc delete
    set result
} [list tdom:doc tdom:doc "" empty]

test domDoc-20.7 {selectNodes with -namespaces option} {
    set doc [dom createDocumentNS "http://tdom.org" tdom:doc]
    catch {set node [$doc selectNodes \
                         -namespaces {foo bar} \
                         -namespaces {a b c d} \
                         -namespaces {wrong_not_pair} \
                         tdom:doc]} errMsg
    $doc delete
    set errMsg
} {The "-namespaces" option requires a 'prefix namespace' pairs list as argument}

test domDoc-21.1 {baseURI} {
    set doc [dom createDocumentNode]
    set result [$doc baseURI]
    $doc delete
    set result
} {}

................................................................................
    lappend result [[$doc documentElement] nodeName]
    $doc delete
    set result
} {<e1/> e1}

test domDoc-22.2 {appendFromScript} {
    set doc [dom parse <root/>]

    $doc appendFromScript {
        nodeCmds::e1
        nodeCmds::e2

    }

    # namespace eval nodeCmds {
    #     $doc appendFromScript {
    #         e1
    #         e2
    #     }
    # }
    set result [$doc asXML -indent none]
    foreach node [$doc selectNodes *] {
        lappend result [$node parentNode]
        lappend result [expr {$doc == [$node ownerDocument]}]
    }
    $doc delete
    set result
................................................................................
    $doc documentElement root
    set node [$root firstChild]
    $doc cdataSectionElements child 1
    set result [$node asXML -indent none]
    $doc delete
    set result
} {<child><![CDATA[some text]]></child>}

test domDoc-24.17 {cdataSectionElements} {
    set doc [dom parse {<doc><child>some text <b>more text</b> text again</child></doc>}]
    $doc cdataSectionElements child 1
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc><child><![CDATA[some text ]]><b>more text</b><![CDATA[ text again]]></child></doc>}


test domDoc-25.1 {selectNodesNamespaces} {
    set doc [dom createDocument foo]
    set result [$doc selectNodesNamespaces]
    $doc delete
    set result
} {}
................................................................................
    set node [$doc selectNodes default1:root/default2:elem1]
    set result [list [$node prefix] [$node localName]]
    set node [$doc selectNodes default1:root/default2:elem1/elem11]
    lappend result [$node nodeName] [$node namespaceURI]
    $doc delete
    set result
} {{} elem1 elem11 {}}

test domDoc-25.7.1 {selectNodesNamespaces} {
    set doc [dom parse {<root xmlns="rootdefaultNS">
        <elem1 xmlns="elem1NS"/>
        <elem2 xmlns="elem2NS"/>
        </root>}]
    $doc documentElement root
    $root firstChild elem1
    $doc createElement elem11 elem11
    $elem1 appendChild $elem11
    $doc selectNodesNamespaces {default2 elem1NS default1 rootdefaultNS}
    set node [$doc selectNodes default1:root/default2:elem1]
    set result [list [$node prefix] [$node localName]]
    set node [$doc selectNodes default1:root/default2:elem1/elem11]
    lappend result [$node nodeName] [$node namespaceURI]
    $doc delete
    set result
} {{} elem1 elem11 {}}

test domDoc-25.8 {selectNodesNamespaces} {
    set doc [dom parse {<root xmlns="rootdefaultNS">
        <elem1 xmlns="elem1NS"><elem11 xmlns=""/></elem1>
        <elem2 xmlns="elem2NS"/>
        </root>}]
    $doc selectNodesNamespaces {default2 elem1NS default1 rootdefaultNS}
................................................................................
    lappend result [$doc deleteXPathCache foo/bar]
    lappend result [$doc deleteXPathCache 2+2]
    lappend result [$doc deleteXPathCache]
    $doc selectNodes -cache 1 2+2
    $doc delete
    set result
} {{} {} {} {}}

test domDoc-28.1 {createElementNS} {
    set doc [dom createDocument doc]
    set newElem [$doc createElementNS uri ns:e]
    $doc documentElement root
    $root appendChild $newElem
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc><ns:e xmlns:ns="uri"/></doc>}

test domDoc-28.2 {createElementNS} {
    set doc [dom createDocument doc]
    set newElem [$doc createElementNS uri ns:e]
    $newElem setAttributeNS uri ns:att value
    $doc documentElement root
    $root appendChild $newElem
    set result [$doc selectNodes -namespaces {ns uri} string(/doc/ns:e/@ns:att)]
    $doc delete
    set result
} {value}

test domDoc-28.3 {createElementNS} {
    set doc [dom createDocument doc]
    catch {$doc createElementNS "" e} errMsg
    $doc delete
    set errMsg
} {Missing URI in Namespace declaration}


# cleanup
::tcltest::cleanupTests
return

Changes to tests/domNode.bench.

202
203
204
205
206
207
208






































































209
210
211
212
213
214
215
    } -body {
        $doc selectNodes -cache 1 count(/root/e1)
    } -post {
        $doc delete
    }

}







































































dom parse <root/> doc
$doc documentElement root

bench -desc "Check for text-only element - xpath - empty"  -body {
    for {set x 0} {$x < 100} {incr x} {
        $doc selectNodes -cache 1 {count(node()) = 1 and node() = text()}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
    } -body {
        $doc selectNodes -cache 1 count(/root/e1)
    } -post {
        $doc delete
    }

}

foreach nrOf {1 10 100 1000} {

    bench -desc "getElementsByTagName: $nrOf returned nodes" -pre {
        dom createDocument root doc
        $doc documentElement root
        $root appendFromScript {
            for {set x 0} {$x < $nrOf} {incr x} {
                e1
            }
        }
    } -body {
        $doc getElementsByTagName e1
    } -post {
        $doc delete
    }

}

foreach nrOf {1 10 100 1000} {

    bench -desc "getElementsByTagName: $nrOf returned node tokens" -pre {
        dom createDocument root doc
        $doc documentElement root
        $root appendFromScript {
            for {set x 0} {$x < $nrOf} {incr x} {
                e1
            }
        }
        dom setObjectCommands token
    } -body {
        $doc getElementsByTagName e1
    } -post {
        dom setObjectCommands automatic
        $doc delete
    }

}


bench -desc "firstChild node cmd" -pre {
    dom parse <root><e/></root> doc
    $doc documentElement root
} -body {
    $root firstChild
} -post {
    $doc delete
}

bench -desc "firstChild node token" -pre {
    dom parse <root><e/></root> doc
    $doc documentElement root
    dom setObjectCommands token
} -body {
    $root firstChild
} -post {
    $doc delete
    dom setObjectCommands automatic
}

bench -desc "firstChild node token from node token" -pre {
    dom parse <root><e/></root> doc
    dom setObjectCommands token
    $doc documentElement root
} -body {
    domNode $root firstChild
} -post {
    $doc delete
    dom setObjectCommands automatic
}

dom parse <root/> doc
$doc documentElement root

bench -desc "Check for text-only element - xpath - empty"  -body {
    for {set x 0} {$x < 100} {incr x} {
        $doc selectNodes -cache 1 {count(node()) = 1 and node() = text()}

Changes to tests/domNode.test.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
..
47
48
49
50
51
52
53


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
..
78
79
80
81
82
83
84









































85
86
87
88
89
90
91
...
168
169
170
171
172
173
174







175
176
177
178
179
180
181
...
349
350
351
352
353
354
355



















356
357
358
359
360
361
362
...
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
....
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
....
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
....
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
....
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
....
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
....
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
....
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
....
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
....
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
....
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
....
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
....
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
....
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
....
1752
1753
1754
1755
1756
1757
1758













































1759
1760
1761
1762
1763
1764
1765
....
1803
1804
1805
1806
1807
1808
1809

1810












1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
....
1871
1872
1873
1874
1875
1876
1877




























1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893























1894
1895
1896
1897
1898











1899
1900
1901
1902
1903
1904
1905
....
1913
1914
1915
1916
1917
1918
1919




1920
1921
1922
1923
1924
1925
1926
....
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
....
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
....
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
....
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
....
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
....
3182
3183
3184
3185
3186
3187
3188






























































































































3189
3190
3191
3192
3193
3194
3195
#    domNode-11.*: disableOutputEscaping 
#    domNode-12.*: cloneNode
#    domNode-13.*: appendFromScript
#    domNode-14.*: appendFromList  
#    domNode-15.*: delete
#    domNode-16.*: getAttribute
#    domNode-17.*: nodeType
#    domNode-18.*: attributes
#    domNode-19.*: removeAttribute, removeAttributeNS
#    domNode-20.*: parentNode
#    domNode-21.*: hasChildNodes
#    domNode-22.*: localName, prefix
#    domNode-23.*: replaceChild
#    domNode-24.*: getLine, getColumn
#    domNode-25.*: hasAttribute, hasAttributeNS
................................................................................
#
# Copyright (c) 2002 - 2005 Rolf Ade.
#
# RCS: @(#) $Id$

source [file join [file dir [info script]] loadtdom.tcl]



test domNode-1.1 {to less arguments to domNode command} {
    set doc [dom createDocument "root"]
    set root [$doc documentElement]
    set result [catch {$root}]
    $doc delete
    set result
} {1}

test domNode-1.2 {to less arguments to domNode command} {
    set doc [dom createDocument "root"]
    set root [$doc documentElement]
    set result [catch {domNode $root}]
    $doc delete
    set result
} {1}

test domNode-1.3 {to less arguments to domNode command} {
    catch {domNode}
} {1}

test domNode-1.4 {rename of domNodeObj cmd} {knownBug} {
    set doc [dom createDocument "root"]
    set root [$doc documentElement]
    rename $root my_domNode
................................................................................
    set result [llength [info commands my_domNode]]
    $doc delete
    lappend result [llength [info commands my_domNode]]
    catch {my_domNode nodeName} errMsg
    lappend result $errMsg
} {1 0}    










































set doc [dom parse {<root xmlns="rootdefaultNS">
    <elem1 xmlns="elem1NS"><elem11/></elem1>
    <elem2 xmlns="elem2NS"/>
    </root>}]
set root [$doc documentElement]

test domNode-2.1 {selectNodes - -namespace option: syntax} {
................................................................................
    set r2 [catch {$root selectNodes -cache 1}]
    set r3 [catch {$root selectNodes -cache 0}]
    set r4 [catch {$root selectNodes ""}]
    set r5 [catch {$root selectNodes -cache 1 ""}]
    set r6 [catch {$root selectNodes -cache 0 ""}]
    list $r1 $r2 $r3 $r4 $r5 $r6
} {1 1 1 1 1 1}








$doc delete

test domNode-3.1 {repetitived documentElement with objVar, then delete} {
    dom createDocument "root" doc 
    $doc documentElement root
    $doc delete
................................................................................
    $root setAttributeNS uri1 p1:a1 1 uri1 p1:a2 2 uri2 p2:a3 3 "" a4 4
    set result [$root asXML]
    $doc delete
    set result
} {<p1:root xmlns:p1="uri1" xmlns:p2="uri2" p1:a1="1" p1:a2="2" p2:a3="3" a4="4"/>
}




















test domNode-5.1 {removeChild} {
    dom parse {<root><child/></root>} doc
    $doc documentElement root
    $root removeChild [$root firstChild]
    set result [$doc asXML -indent none]
    $doc delete
    set result
................................................................................
        b "<existing_report_two>...</existing_report_two>"
    } {
        lappend fileList [makeFile $content $name]
    }
} -body {
    set docs {}
    foreach rf $fileList {
        set doc [dom parse -baseurl [tDOM::baseURL $rf] \
                     -externalentitycommand ::tDOM::extRefHandler \
                     -keepEmpties \
                     [tDOM::xmlReadFile $rf] ]
        lappend docs $doc
    }
    set resultDoc [dom createDocument new_report]
    set root [$resultDoc documentElement]
    foreach doc $docs {
        $root appendChild [$doc documentElement]
    }
................................................................................
    set result
} {<root><e1/></root>}

test domNode-13.2 {appendFromScript - elementNode} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $root appendFromScript {
            e1
            e2
        }
    }
    set result [$root asXML -indent none]
    $doc delete
    set result
} {<root><e1/><e2/></root>}

test domNode-13.3 {appendFromScript - elementNode} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $root appendFromScript {
            e1 {
                e2 {
                    e1
                }
            }
            e2
        }
................................................................................
    set result
} {<root><e1><e2><e1/></e2></e1><e2/></root>}

test domNode-13.4 {appendFromScript - elementNode with attributes as options} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $root appendFromScript {
            e1 -attr1 attr1Value -attr2 "attr 2 Value"
        }
    }
    set result [$root asXML -indent none]
    $doc delete
    set result
} {<root><e1 attr1="attr1Value" attr2="attr 2 Value"/></root>}

test domNode-13.5 {appendFromScript - elementNode with attributes as list} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set attlist [list -a1 "some & value" -a2 "another attvalue"]
    namespace eval nodeCmds {
        $root appendFromScript {
            e1 $attlist {}
        }
    }
    set result [$root asXML -indent none]
    $doc delete
    set result
} {<root><e1 a1="some &amp; value" a2="another attvalue"/></root>}

test domNode-13.6 {appendFromScript - textnode, commentnode, cdatanode, pinode} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $root appendFromScript {
            t foo
            c "my comment"
            cdata {&"<>;} ;# emacs: "
            pi mypi "some pi data"
        }
    }
    set result [$root asXML -indent none]
................................................................................

# emacs: "

test domNode-13.7 {appendFromScript - textnode} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $root appendFromScript {
            t "<p>Some <b>important</b> stuff</p>"
        }
    }
    set result [$root asXML -indent none]
    $doc delete
    set result
} {<root>&lt;p&gt;Some &lt;b&gt;important&lt;/b&gt; stuff&lt;/p&gt;</root>}

test domNode-13.8 {appendFromScript - textnode with -disableOutputEscaping} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $root appendFromScript {
            t -disableOutputEscaping "<p>Some <b>important</b> stuff</p>"
        }
    }
    set result [$root asXML -indent none]
    $doc delete
    set result
} {<root><p>Some <b>important</b> stuff</p></root>}
................................................................................
        dom createNodeCmd elementNode thisCmds::thisE
    }
    set result [llength [info commands nodeCmds::thisE]]
    lappend result [llength [info commands nodeCmds::thisCmds::thisE]]
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $root appendFromScript {
            thisCmds::thisE
        }
    }
    lappend result [$doc asXML -indent none]
    $doc delete
    set result
} {0 1 <root><thisE/></root>}

set nsname "tricky nsname"
namespace eval nodeCmds::$nsname { }

test domNode-13.15 {qualified nodeCmds name} {
    namespace eval nodeCmds {
        dom createNodeCmd elementNode ${nsname}::thisE
    }
    set result [llength [info commands nodeCmds::thisE]]
    lappend result [llength [info commands nodeCmds::${nsname}::thisE]]
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $root appendFromScript {
            ${nsname}::thisE
        }
    }
    lappend result [$doc asXML -indent none]
    $doc delete
    set result
} {0 1 <root><thisE/></root>}

test domNode-13.16 {Invalid attribute name} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $root appendFromScript {
                e1 att1 att1Value "invalid attname" value {}
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
................................................................................
} {1 {Invalid attribute name 'invalid attname'}}

test domNode-13.17 {Invalid attribute value} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $root appendFromScript {
                e1 att1 att1Value att2 "invalid \u0003 value" {}
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
................................................................................
dom setNameCheck 1

test domNode-13.18 {Invalid attribute name - check disabled} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $root appendFromScript {
                e1 att1 att1Value "invalid attname" value {}
            }
        }
    }]
    $doc delete
    set result
} {0}
................................................................................
dom setTextCheck 1

test domNode-13.19 {Invalid attribute value - check disabled} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $root appendFromScript {
                e1 att1 att1Value att2 "invalid \u0003 value" {}
            }
        }
    }]
    $doc delete
    set result
} 0
................................................................................
dom setNameCheck 1

test domNode-13.20 {Invalid att name, invalid att value, checks disabled} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $root appendFromScript {
                e1 att1 att1Value "invalid attName" "invalid \u0003 value" {}
            }
        }
    }]
    $doc delete
    set result
} 0
................................................................................
}

test domNode-13.21 {Invalid comment value} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $root appendFromScript {
                c "invalid -- comment"
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
................................................................................
} {1 {Invalid comment value 'invalid -- comment'}}

test domNode-13.22 {Invalid CDATA section value} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $root appendFromScript {
                cdata "invalid comment ]]>"
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
................................................................................
} {1 {Invalid CDATA section value 'invalid comment ]]>'}}

test domNode-13.23 {Invalid text node} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $root appendFromScript {
                t "invalid text \u0004"
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
................................................................................
} [list 1 "Invalid text value 'invalid text \u0004'"]

test domNode-13.24 {Invalid processing instruction} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $root appendFromScript {
                pi  Xml "data"
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
................................................................................
} [list 1 "Invalid processing instruction name 'Xml'"]

test domNode-13.25 {Invalid processing instruction} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $root appendFromScript {
                pi  Xmll "data ?>"
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
} [list 1 "Invalid processing instruction value 'data ?>'"]

test domNode-13.26 {appendFromScript with default namespace in scope} {
    set doc [dom parse {<doc xmlns="http://www.stock.org/stock"/>}]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $root appendFromScript {
            e1
        }
    }
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc xmlns="http://www.stock.org/stock"><e1 xmlns=""/></doc>}
................................................................................
    foreach node [$root selectNodes node()] {
        $node delete
    }
    set result [llength [$root childNodes]]
    $doc delete
    set result
} {0}














































set doc [dom parse {<root attr1="bingbaz" attr2="ab &amp; zu" attr3=""/>}]
set root [$doc documentElement]

test domNode-16.1 {getAttribute} {
    $root getAttribute attr1
} {bingbaz}
................................................................................
test domNode-16.11 {getAttribute shortcut with default} {
    $root @notPresent "expect this given default value"
} {expect this given default value}

test domNode-16.12 {getAttribute shortcut - attr dosen't exists and no default} {
    catch {$root @notPresent}
} {1}














$doc delete

# Yea, it's the same string as above. I just love to have the
# data near by the tests, to reduce confusion and silly errors
set xml {
<root>
  text node <b>text</b><!-- comment1 -->
  <elem1>text<?pi data?><empty/>
     <child>text</child>
 </elem1><!-- comment2 --><?pi data?>text
</root>}
................................................................................
test domNode-18.6 {attributes} {
    $root attributes *brab*
} {}

test domNode-18.7 {attributes} {
    [$root firstChild] attributes
} {}





























# Hmmm. This two following tests are mostly there to document the
# behavior of the method, as it is.  It may debatable if they should
# behave this way. The optional attribute name pattern is a tDOM
# DOM extension there is nothing in the rec, which could help to argue.
# Therefore, it's the way, it is.

test domNode-18.7 {attributes} {
    $root attributes *tdom*
} {}

test domNode-18.8 {attributes} {
    $root attributes foo*
} {{attr1 foo http://tdom.org/ns}}

# still the doc from befor 18.1























test domNode-19.1 {removeAttribute} {
    $root removeAttribute attr1
    $root attributes attr1
} {}












test domNode-19.2 {removeAttribute} {
    catch {$root removeAttribute attr1} errMsg
    set errMsg
} {can't remove attribute 'attr1'}

test domNode-19.3 {removeAttribute} {
    catch {$root removeAttribute} 
................................................................................
    $root removeAttributeNS http://tdom.org/ns attr1
    $root hasAttributeNS http://tdom.org/ns attr1
} {0}

test domNode-19.6 {removeAttributeNS} {
    catch {$root removeAttributeNS http://tdom.org attr1}
} {1}





$doc delete

set doc [dom parse <root><firstL><secondL1/><secondL2/></firstL></root>]
set root [$doc documentElement]

test domNode-20.1 {parentNode} {
................................................................................
    set firstChild [$root firstChild]
    catch {$root start $firstChild foo}
} {1}

test domNode-30.3 {precedes} {
    set result [catch {$root precedes notaNode} errMsg]
    lappend result $errMsg
} {1 {parameter not a domNode!}}

test domNode-30.4 {precedes} {
    set firstChild [$root firstChild]
    $root precedes $firstChild
} {1}

test domNode-30.5 {precedes} {
................................................................................
    set result
} {1 <root><child/></root>}

test domNode-33.4 {insertBeforeFromScript - insert more then one node} {
    set doc [dom parse {<doc><foo/><bar/><grill/></doc>}]
    $doc documentElement root
    namespace eval nodeCmds {
        $root insertBeforeFromScript {
            e1
            e2 {
                t new
            }
            e1
        } [lindex [$root childNodes] 1]
    }
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc><foo/><e1/><e2>new</e2><e1/><bar/><grill/></doc>}

test domNode-33.5 {insertBeforeFromScript - insert more then one node} {
    set doc [dom parse {<doc><foo/><bar/><grill/></doc>}]
    $doc documentElement root
    namespace eval nodeCmds {
        $root insertBeforeFromScript {
            e1
            e2 {
                t new
            }
            e1
        } [lindex [$root childNodes] 1]
    }
    set result ""
    foreach node [$root childNodes] {
        append result "[$node nodeName] "
    }
    $doc delete
    set result
} {foo e1 e2 e1 bar grill }

test domNode-33.6 {insertBeforeFromScript - insert more then one node} {
    set doc [dom parse {<doc><foo/><bar/><grill/></doc>}]
    $doc documentElement root
    namespace eval nodeCmds {
        $root insertBeforeFromScript {
            e1
            e2 {
                t new
            }
            e1
        } [lindex [$root childNodes] 1]
    }
    set result ""
    set node [$root lastChild]
    while {$node != ""} {
        append result "[$node nodeName] "
        set node [$node previousSibling]
    }
................................................................................
    set result
} {grill bar e1 e2 e1 foo }

test domNode-33.7 {insertBeforeFromScript - error in script} {
    set doc [dom parse {<doc><foo/><bar/><grill/></doc>}]
    $doc documentElement root
    catch {namespace eval nodeCmds {
        $root insertBeforeFromScript {
            e1
            e2 {
                t new
            }
            e1
            this is wrong
        } [lindex [$root childNodes] 2]
    }}
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc><foo/><bar/><grill/></doc>}

test domNode-33.8 {insertBeforeFromScript - wrong reference node} {
................................................................................
    set result
} {1 NOT_FOUND_ERR}

test domNode-34.1 {getBaseURI} {need_uri} {
    makeFile <y/> domNode-34.1-e1.xml [file join [file dir [info script]] data]
    makeFile <y/> domNode-34.1-e2.xml [file join [file dir [info script]] data]

    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
    set doc [dom parse \
                 -baseurl $baseURI \
                 -externalentitycommand ::tDOM::extRefHandler {
                     <!DOCTYPE x [
                                  <!ENTITY a SYSTEM "data/domNode-34.1-e1.xml">
                                  <!ENTITY b SYSTEM "data/domNode-34.1-e2.xml">
                                 ]>
                     <x>
                     &a;
                     &b;
................................................................................
    set result
} {1}

test domNode-34.2 {getBaseURI} {need_uri} {
    makeFile <y/> domNode-34.1-e1.xml [file join [file dir [info script]] data]
    makeFile <y/> domNode-34.1-e2.xml [file join [file dir [info script]] data]

    set baseURI file://[file join [pwd] [file dir [info script]] dom.test]
    set doc [dom parse \
                 -baseurl $baseURI \
                 -externalentitycommand ::tDOM::extRefHandler {
                     <!DOCTYPE x [
                                  <!ENTITY a SYSTEM "data/domNode-34.1-e1.xml">
                                  <!ENTITY b SYSTEM "data/domNode-34.1-e2.xml">
                                 ]>
                     <x>
                     &a;
                     &b;
                     <y/>
                     </x>}]
    $doc delete
    set doc [dom parse \
                 -baseurl $baseURI \
                 -externalentitycommand ::tDOM::extRefHandler {
                     <!DOCTYPE x [
                                  <!ENTITY a SYSTEM "data/domNode-34.1-e1.xml">
                                  <!ENTITY b SYSTEM "data/domNode-34.1-e2.xml">
                                 ]>
                     <x>
                     &a;
                     &b;
................................................................................
    set result {}
    foreach toplevelcomment [$doc selectNodes /comment()] {
        lappend result [$toplevelcomment toXPath]
    }
    $doc delete
    set result
} [list {/comment()[1]} {/comment()[2]} {/comment()[3]}]































































































































test domNode-39.1 {text} {
     set doc [dom parse {<root>text <b>bold</b> more text</root>}]
     $doc documentElement root
     set result [$root text]
     $doc delete
     set result







|







 







>
>
|







|







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|

|







 







|













|







 







|













|
|











|







 







|












|







 







|













|






|
|












|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|













|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>

>
>
>
>
>
>
>
>
>
>
>
>


<
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







|



|



|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>







 







|







 







|





|










|





|













|





|







 







|






|







 







|


|







 







|


|












|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
..
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
...
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
...
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
...
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
....
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
....
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
....
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
....
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
....
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
....
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
....
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
....
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
....
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
....
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
....
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
....
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
....
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
....
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
....
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939


1940
1941
1942
1943
1944
1945
1946
....
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
....
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
....
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
....
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
....
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
....
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
....
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
....
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
#    domNode-11.*: disableOutputEscaping 
#    domNode-12.*: cloneNode
#    domNode-13.*: appendFromScript
#    domNode-14.*: appendFromList  
#    domNode-15.*: delete
#    domNode-16.*: getAttribute
#    domNode-17.*: nodeType
#    domNode-18.*: attributes, attributeNames
#    domNode-19.*: removeAttribute, removeAttributeNS
#    domNode-20.*: parentNode
#    domNode-21.*: hasChildNodes
#    domNode-22.*: localName, prefix
#    domNode-23.*: replaceChild
#    domNode-24.*: getLine, getColumn
#    domNode-25.*: hasAttribute, hasAttributeNS
................................................................................
#
# Copyright (c) 2002 - 2005 Rolf Ade.
#
# RCS: @(#) $Id$

source [file join [file dir [info script]] loadtdom.tcl]

testConstraint threaded [info exists tcl_platform(threaded)]

test domNode-1.1 {too less arguments to nodecmd} {
    set doc [dom createDocument "root"]
    set root [$doc documentElement]
    set result [catch {$root}]
    $doc delete
    set result
} {1}

test domNode-1.2 {too less arguments to domNode token} {
    set doc [dom createDocument "root"]
    set root [$doc documentElement]
    set result [catch {domNode $root}]
    $doc delete
    set result
} {1}

test domNode-1.3 {too less arguments to domNode command} {
    catch {domNode}
} {1}

test domNode-1.4 {rename of domNodeObj cmd} {knownBug} {
    set doc [dom createDocument "root"]
    set root [$doc documentElement]
    rename $root my_domNode
................................................................................
    set result [llength [info commands my_domNode]]
    $doc delete
    lappend result [llength [info commands my_domNode]]
    catch {my_domNode nodeName} errMsg
    lappend result $errMsg
} {1 0}    

test domNode-1.5 {domNode command: invalid token} {
    set xml {<doc><e>1</e><e>2</e></doc>}

    set doc [dom parse $xml]
    set root [domDoc $doc documentElement]
    set invalidToken [domNode $root firstChild]
    lappend invalidToken foo
    set result [catch {domNode $invalidToken selectNodes string(.)}]
    $doc delete
    set result
} {1}

test domNode-1.6 {domNode command: invalid token} {
    set xml {<doc><e>1</e><e>2</e></doc>}

    set doc [dom parse $xml]
    set root [domDoc $doc documentElement]
    set invalidToken [domNode $root firstChild]
    append invalidToken "\n"
    set result [catch {domNode $invalidToken selectNodes string(.)}]
    $doc delete
    set result
} {1}

proc domNode-1.7-traceproc {args} {
    error "error in nodeObjVar trace"
}

test domNode-1.7 {error in trace on nodeObjVar} {
    set xml {<doc><e>1</e><e>2</e></doc>}

    set doc [dom parse $xml]
    set root [$doc documentElement]
    trace add variable resultVar write domNode-1.7-traceproc
    set result [catch {$root firstChild resultVar} errMsg]
    lappend result $errMsg
    trace remove variable resultVar write domNode-1.7-traceproc
    $doc delete
    set result
} {1 {can't set "resultVar": error in nodeObjVar trace}}

set doc [dom parse {<root xmlns="rootdefaultNS">
    <elem1 xmlns="elem1NS"><elem11/></elem1>
    <elem2 xmlns="elem2NS"/>
    </root>}]
set root [$doc documentElement]

test domNode-2.1 {selectNodes - -namespace option: syntax} {
................................................................................
    set r2 [catch {$root selectNodes -cache 1}]
    set r3 [catch {$root selectNodes -cache 0}]
    set r4 [catch {$root selectNodes ""}]
    set r5 [catch {$root selectNodes -cache 1 ""}]
    set r6 [catch {$root selectNodes -cache 0 ""}]
    list $r1 $r2 $r3 $r4 $r5 $r6
} {1 1 1 1 1 1}

test domNode-2.12 {selectNodes - -cache option} {
     # Second usage of an invalid XPath expr with -cache 1
     # See 97c0994ae4
     catch {$root selectNodes -cache 1 "/foo bar"}
     catch {$root selectNodes -cache 1 "/foo bar"}
} 1

$doc delete

test domNode-3.1 {repetitived documentElement with objVar, then delete} {
    dom createDocument "root" doc 
    $doc documentElement root
    $doc delete
................................................................................
    $root setAttributeNS uri1 p1:a1 1 uri1 p1:a2 2 uri2 p2:a3 3 "" a4 4
    set result [$root asXML]
    $doc delete
    set result
} {<p1:root xmlns:p1="uri1" xmlns:p2="uri2" p1:a1="1" p1:a2="2" p2:a3="3" a4="4"/>
}

test domNode-4.17 {setAttributeNS - set multiple Attribute with NS atts undermixed at once} {
    set doc [dom createDocumentNS uri1 "p1:root"]
    set root [$doc documentElement]
    $root setAttributeNS "" xmlns:p2 uri2
    $root setAttributeNS uri1 p1:a1 1 "" xmlns uri3 uri1 p1:a2 2 "" xmlns:p4 uri4 uri4 p4:a1 a1 uri2 p2:a3 3 "" a4 4
    set result [$root asXML]
    $doc delete
    set result
} {<p1:root xmlns:p1="uri1" xmlns:p2="uri2" xmlns="uri3" xmlns:p4="uri4" p1:a1="1" p1:a2="2" p4:a1="a1" p2:a3="3" a4="4"/>
}

test domNode-4.18 {setAttributeNS - prefixed attribute name with empty namespace} {
    set doc [dom createDocument "root"]
    set root [$doc documentElement]
    catch {$root setAttributeNS "" ns:att attvalue} errMsg
    $doc delete
    set errMsg
} {For all prefixed attributes with prefixes other than 'xml' or 'xmlns' you have to provide a namespace URI}

test domNode-5.1 {removeChild} {
    dom parse {<root><child/></root>} doc
    $doc documentElement root
    $root removeChild [$root firstChild]
    set result [$doc asXML -indent none]
    $doc delete
    set result
................................................................................
        b "<existing_report_two>...</existing_report_two>"
    } {
        lappend fileList [makeFile $content $name]
    }
} -body {
    set docs {}
    foreach rf $fileList {
        set doc [dom parse -baseurl [tdom::baseURL $rf] \
                     -externalentitycommand ::tdom::extRefHandler \
                     -keepEmpties \
                     [tdom::xmlReadFile $rf] ]
        lappend docs $doc
    }
    set resultDoc [dom createDocument new_report]
    set root [$resultDoc documentElement]
    foreach doc $docs {
        $root appendChild [$doc documentElement]
    }
................................................................................
    set result
} {<root><e1/></root>}

test domNode-13.2 {appendFromScript - elementNode} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $::root appendFromScript {
            e1
            e2
        }
    }
    set result [$root asXML -indent none]
    $doc delete
    set result
} {<root><e1/><e2/></root>}

test domNode-13.3 {appendFromScript - elementNode} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $::root appendFromScript {
            e1 {
                e2 {
                    e1
                }
            }
            e2
        }
................................................................................
    set result
} {<root><e1><e2><e1/></e2></e1><e2/></root>}

test domNode-13.4 {appendFromScript - elementNode with attributes as options} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $::root appendFromScript {
            e1 -attr1 attr1Value -attr2 "attr 2 Value"
        }
    }
    set result [$root asXML -indent none]
    $doc delete
    set result
} {<root><e1 attr1="attr1Value" attr2="attr 2 Value"/></root>}

test domNode-13.5 {appendFromScript - elementNode with attributes as list} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set attlist [list -a1 "some & value" -a2 "another attvalue"]
    namespace eval nodeCmds {
        $::root appendFromScript {
            e1 $::attlist {}
        }
    }
    set result [$root asXML -indent none]
    $doc delete
    set result
} {<root><e1 a1="some &amp; value" a2="another attvalue"/></root>}

test domNode-13.6 {appendFromScript - textnode, commentnode, cdatanode, pinode} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $::root appendFromScript {
            t foo
            c "my comment"
            cdata {&"<>;} ;# emacs: "
            pi mypi "some pi data"
        }
    }
    set result [$root asXML -indent none]
................................................................................

# emacs: "

test domNode-13.7 {appendFromScript - textnode} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $::root appendFromScript {
            t "<p>Some <b>important</b> stuff</p>"
        }
    }
    set result [$root asXML -indent none]
    $doc delete
    set result
} {<root>&lt;p&gt;Some &lt;b&gt;important&lt;/b&gt; stuff&lt;/p&gt;</root>}

test domNode-13.8 {appendFromScript - textnode with -disableOutputEscaping} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $::root appendFromScript {
            t -disableOutputEscaping "<p>Some <b>important</b> stuff</p>"
        }
    }
    set result [$root asXML -indent none]
    $doc delete
    set result
} {<root><p>Some <b>important</b> stuff</p></root>}
................................................................................
        dom createNodeCmd elementNode thisCmds::thisE
    }
    set result [llength [info commands nodeCmds::thisE]]
    lappend result [llength [info commands nodeCmds::thisCmds::thisE]]
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $::root appendFromScript {
            thisCmds::thisE
        }
    }
    lappend result [$doc asXML -indent none]
    $doc delete
    set result
} {0 1 <root><thisE/></root>}

set nsname "tricky nsname"
namespace eval nodeCmds::$nsname { }

test domNode-13.15 {qualified nodeCmds name} {
    namespace eval nodeCmds {
        dom createNodeCmd elementNode ${::nsname}::thisE
    }
    set result [llength [info commands nodeCmds::thisE]]
    lappend result [llength [info commands nodeCmds::${nsname}::thisE]]
    set doc [dom createDocument root]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $::root appendFromScript {
            ${::nsname}::thisE
        }
    }
    lappend result [$doc asXML -indent none]
    $doc delete
    set result
} {0 1 <root><thisE/></root>}

test domNode-13.16 {Invalid attribute name} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $::root appendFromScript {
                e1 att1 att1Value "invalid attname" value {}
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
................................................................................
} {1 {Invalid attribute name 'invalid attname'}}

test domNode-13.17 {Invalid attribute value} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $::root appendFromScript {
                e1 att1 att1Value att2 "invalid \u0003 value" {}
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
................................................................................
dom setNameCheck 1

test domNode-13.18 {Invalid attribute name - check disabled} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $::root appendFromScript {
                e1 att1 att1Value "invalid attname" value {}
            }
        }
    }]
    $doc delete
    set result
} {0}
................................................................................
dom setTextCheck 1

test domNode-13.19 {Invalid attribute value - check disabled} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $::root appendFromScript {
                e1 att1 att1Value att2 "invalid \u0003 value" {}
            }
        }
    }]
    $doc delete
    set result
} 0
................................................................................
dom setNameCheck 1

test domNode-13.20 {Invalid att name, invalid att value, checks disabled} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $::root appendFromScript {
                e1 att1 att1Value "invalid attName" "invalid \u0003 value" {}
            }
        }
    }]
    $doc delete
    set result
} 0
................................................................................
}

test domNode-13.21 {Invalid comment value} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $::root appendFromScript {
                c "invalid -- comment"
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
................................................................................
} {1 {Invalid comment value 'invalid -- comment'}}

test domNode-13.22 {Invalid CDATA section value} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $::root appendFromScript {
                cdata "invalid comment ]]>"
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
................................................................................
} {1 {Invalid CDATA section value 'invalid comment ]]>'}}

test domNode-13.23 {Invalid text node} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $::root appendFromScript {
                t "invalid text \u0004"
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
................................................................................
} [list 1 "Invalid text value 'invalid text \u0004'"]

test domNode-13.24 {Invalid processing instruction} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $::root appendFromScript {
                pi  Xml "data"
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
................................................................................
} [list 1 "Invalid processing instruction name 'Xml'"]

test domNode-13.25 {Invalid processing instruction} {
    set doc [dom createDocument root]
    set root [$doc documentElement]
    set result [catch {
        namespace eval nodeCmds {
            $::root appendFromScript {
                pi  Xmll "data ?>"
            }
        }
    } errMsg]
    lappend result $errMsg
    $doc delete
    set result
} [list 1 "Invalid processing instruction value 'data ?>'"]

test domNode-13.26 {appendFromScript with default namespace in scope} {
    set doc [dom parse {<doc xmlns="http://www.stock.org/stock"/>}]
    set root [$doc documentElement]
    namespace eval nodeCmds {
        $::root appendFromScript {
            e1
        }
    }
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc xmlns="http://www.stock.org/stock"><e1 xmlns=""/></doc>}
................................................................................
    foreach node [$root selectNodes node()] {
        $node delete
    }
    set result [llength [$root childNodes]]
    $doc delete
    set result
} {0}

test domNode-15.5 {delete - threaded} -constraints {
    threaded
} -setup {
    set xml {
        <root>
        <child>
        <attr1>one</attr1>
        <attr2>two</attr2>
        <attr3>three</attr3>
        </child>
        </root>
    }
    set doc [dom parse $xml]
    dom attachDocument $doc doc_
    $doc documentElement root
} -body {
    foreach node [$root selectNodes {//attr1 | //attr2}] {
        [$node firstChild] delete
    }
    set result ""
} -cleanup {
    dom detachDocument $doc
    dom detachDocument $doc_
} -result ""

test domNode-15.6 {delete - threaded} -constraints {
    threaded
} -setup {
    set xml {
        <root><a/><a/><a/><a/><a/><a/><a/>
        <a/><a/><a/><a/><a/><a/><a/><a/></root>
    }
    set doc [dom parse $xml]
    dom attachDocument $doc doc_
    $doc documentElement root
} -body {
    foreach node [$root selectNodes a] {
        $node delete
    }
    set result ""
} -cleanup {
    dom detachDocument $doc
    dom detachDocument $doc_
} -result ""

set doc [dom parse {<root attr1="bingbaz" attr2="ab &amp; zu" attr3=""/>}]
set root [$doc documentElement]

test domNode-16.1 {getAttribute} {
    $root getAttribute attr1
} {bingbaz}
................................................................................
test domNode-16.11 {getAttribute shortcut with default} {
    $root @notPresent "expect this given default value"
} {expect this given default value}

test domNode-16.12 {getAttribute shortcut - attr dosen't exists and no default} {
    catch {$root @notPresent}
} {1}
$doc delete

set doc [dom parse {<root attr1="bingbaz"
    foo:attr1="ns attr"
    xmlns:foo="http://tdom.org/ns1"
    worble2="second attr with 2 in it's name"
    xmlns="uri2"/>}]
set root [$doc documentElement]
test domNode-16.13 {getAttribute} {
    $root getAttribute xmlns
} {uri2}
test domNode-16.14 {getAttribute} {
    $root getAttribute xmlns:foo
} {http://tdom.org/ns1}
$doc delete



set xml {
<root>
  text node <b>text</b><!-- comment1 -->
  <elem1>text<?pi data?><empty/>
     <child>text</child>
 </elem1><!-- comment2 --><?pi data?>text
</root>}
................................................................................
test domNode-18.6 {attributes} {
    $root attributes *brab*
} {}

test domNode-18.7 {attributes} {
    [$root firstChild] attributes
} {}

test domNode-18.1.1 {attributeNames} {
    $root attributeNames
} {xmlns:foo attr1 attr2 attr3 foo:attr1 worble2}

test domNode-18.2.1 {attributeNames} {
    $root attributeNames *
} {xmlns:foo attr1 attr2 attr3 foo:attr1 worble2}

test domNode-18.3.1 {attributeNames} {
    $root attributeNames attr*
} {attr1 attr2 attr3}

test domNode-18.4.1 {attributeNames} {
    $root attributeNames *2*
} {attr2 worble2}

test domNode-18.5.1 {attributeNames} {
    $root attributeNames worble2
} {worble2}

test domNode-18.6.1 {attributeNames} {
    $root attributeNames *brab*
} {}

test domNode-18.7.1 {attributeNames} {
    [$root firstChild] attributeNames
} {}

# Hmmm. This two following tests are mostly there to document the
# behavior of the method, as it is.  It may debatable if they should
# behave this way. The optional attribute name pattern is a tDOM
# DOM extension there is nothing in the rec, which could help to argue.
# Therefore, it's the way, it is.

test domNode-18.8 {attributes} {
    $root attributes *tdom*
} {}

test domNode-18.9 {attributes} {
    $root attributes foo*
} {{attr1 foo http://tdom.org/ns}}

test domNode-18.9.1 {attributeNames} {
    $root attributeNames foo:*
} {foo:attr1}

$doc delete
set doc [dom parse {<root attr1="bingbaz"
    foo:attr1="ns attr"
    xmlns:foo="http://tdom.org/ns1"
    worble2="second attr with 2 in it's name"
    xmlns="uri2"/>}]
set root [$doc documentElement]
test domNode-18.10 {attributes} {
    $root attributes
} {{foo foo {}} {xmlns {} {}} attr1 {attr1 foo http://tdom.org/ns1} worble2}
$doc delete

set doc [dom parse {<root attr1="bingbaz"
                          attr2="ab &amp; zu"
                          attr3=""
                          foo:attr1="ns attr"
                          xmlns:foo="http://tdom.org/ns"
                          worble2="second attr with 2 in it's name">
text child</root>}]
set root [$doc documentElement]
test domNode-19.1 {removeAttribute} {
    $root removeAttribute attr1
    $root attributes attr1
} {}

$doc delete
set doc [dom parse {<root attr2="ab &amp; zu"
                          attr3=""
                          foo:attr1="ns attr"
                          xmlns:foo="http://tdom.org/ns"
                          worble2="second attr with 2 in it's name"
                          xmlns:bar="http://tdom.org/bar"
                          thisatt="thisatt value no ns"
                          bar:thisatt="thisatt value">
text child</root>}]
set root [$doc documentElement]
test domNode-19.2 {removeAttribute} {
    catch {$root removeAttribute attr1} errMsg
    set errMsg
} {can't remove attribute 'attr1'}

test domNode-19.3 {removeAttribute} {
    catch {$root removeAttribute} 
................................................................................
    $root removeAttributeNS http://tdom.org/ns attr1
    $root hasAttributeNS http://tdom.org/ns attr1
} {0}

test domNode-19.6 {removeAttributeNS} {
    catch {$root removeAttributeNS http://tdom.org attr1}
} {1}

test domNode-19.7 {removeAttributeNS} {
     catch {$root removeAttributeNS http://tdom.org/bar thisatt}
} {0}

$doc delete

set doc [dom parse <root><firstL><secondL1/><secondL2/></firstL></root>]
set root [$doc documentElement]

test domNode-20.1 {parentNode} {
................................................................................
    set firstChild [$root firstChild]
    catch {$root start $firstChild foo}
} {1}

test domNode-30.3 {precedes} {
    set result [catch {$root precedes notaNode} errMsg]
    lappend result $errMsg
} {1 {Parameter "notaNode" is not a domNode.}}

test domNode-30.4 {precedes} {
    set firstChild [$root firstChild]
    $root precedes $firstChild
} {1}

test domNode-30.5 {precedes} {
................................................................................
    set result
} {1 <root><child/></root>}

test domNode-33.4 {insertBeforeFromScript - insert more then one node} {
    set doc [dom parse {<doc><foo/><bar/><grill/></doc>}]
    $doc documentElement root
    namespace eval nodeCmds {
        $::root insertBeforeFromScript {
            e1
            e2 {
                t new
            }
            e1
        } [lindex [$::root childNodes] 1]
    }
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc><foo/><e1/><e2>new</e2><e1/><bar/><grill/></doc>}

test domNode-33.5 {insertBeforeFromScript - insert more then one node} {
    set doc [dom parse {<doc><foo/><bar/><grill/></doc>}]
    $doc documentElement root
    namespace eval nodeCmds {
        $::root insertBeforeFromScript {
            e1
            e2 {
                t new
            }
            e1
        } [lindex [$::root childNodes] 1]
    }
    set result ""
    foreach node [$root childNodes] {
        append result "[$node nodeName] "
    }
    $doc delete
    set result
} {foo e1 e2 e1 bar grill }

test domNode-33.6 {insertBeforeFromScript - insert more then one node} {
    set doc [dom parse {<doc><foo/><bar/><grill/></doc>}]
    $doc documentElement root
    namespace eval nodeCmds {
        $::root insertBeforeFromScript {
            e1
            e2 {
                t new
            }
            e1
        } [lindex [$::root childNodes] 1]
    }
    set result ""
    set node [$root lastChild]
    while {$node != ""} {
        append result "[$node nodeName] "
        set node [$node previousSibling]
    }
................................................................................
    set result
} {grill bar e1 e2 e1 foo }

test domNode-33.7 {insertBeforeFromScript - error in script} {
    set doc [dom parse {<doc><foo/><bar/><grill/></doc>}]
    $doc documentElement root
    catch {namespace eval nodeCmds {
        $::root insertBeforeFromScript {
            e1
            e2 {
                t new
            }
            e1
            this is wrong
        } [lindex [$::root childNodes] 2]
    }}
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc><foo/><bar/><grill/></doc>}

test domNode-33.8 {insertBeforeFromScript - wrong reference node} {
................................................................................
    set result
} {1 NOT_FOUND_ERR}

test domNode-34.1 {getBaseURI} {need_uri} {
    makeFile <y/> domNode-34.1-e1.xml [file join [file dir [info script]] data]
    makeFile <y/> domNode-34.1-e2.xml [file join [file dir [info script]] data]

    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
    set doc [dom parse \
                 -baseurl $baseURI \
                 -externalentitycommand ::tdom::extRefHandler {
                     <!DOCTYPE x [
                                  <!ENTITY a SYSTEM "data/domNode-34.1-e1.xml">
                                  <!ENTITY b SYSTEM "data/domNode-34.1-e2.xml">
                                 ]>
                     <x>
                     &a;
                     &b;
................................................................................
    set result
} {1}

test domNode-34.2 {getBaseURI} {need_uri} {
    makeFile <y/> domNode-34.1-e1.xml [file join [file dir [info script]] data]
    makeFile <y/> domNode-34.1-e2.xml [file join [file dir [info script]] data]

    set baseURI [tdom::baseURL [file join [pwd] [file dir [info script]] dom.test]]
    set doc [dom parse \
                 -baseurl $baseURI \
                 -externalentitycommand ::tdom::extRefHandler {
                     <!DOCTYPE x [
                                  <!ENTITY a SYSTEM "data/domNode-34.1-e1.xml">
                                  <!ENTITY b SYSTEM "data/domNode-34.1-e2.xml">
                                 ]>
                     <x>
                     &a;
                     &b;
                     <y/>
                     </x>}]
    $doc delete
    set doc [dom parse \
                 -baseurl $baseURI \
                 -externalentitycommand ::tdom::extRefHandler {
                     <!DOCTYPE x [
                                  <!ENTITY a SYSTEM "data/domNode-34.1-e1.xml">
                                  <!ENTITY b SYSTEM "data/domNode-34.1-e2.xml">
                                 ]>
                     <x>
                     &a;
                     &b;
................................................................................
    set result {}
    foreach toplevelcomment [$doc selectNodes /comment()] {
        lappend result [$toplevelcomment toXPath]
    }
    $doc delete
    set result
} [list {/comment()[1]} {/comment()[2]} {/comment()[3]}]

test domNode-38.3 {toXPath - syntax} -setup {
    set doc [dom parse <doc/>]
    set root [$doc documentElement]
} -body {
    catch {$root toXPath foo bar} errMsg
    set errMsg
} -cleanup {
    $doc delete
} -match regexp -result {wrong # args: should be "domNode(0x)?[[:xdigit:]]+ toXPath \?-legacy\?"}

test domNode-38.4 {toXPath - default xml namespace} -setup {
    set doc [dom parse {<root><foo xmlns="foo"/><foo/></root>}]
    $doc selectNodesNamespaces {foo foo}
    set root [$doc documentElement]
    set foo1 [$root selectNodes foo:foo]
    set xfo1 [$foo1 toXPath]
} -body {
    expr {$foo1 == [[$foo1 ownerDocument] selectNodes [$foo1 toXPath]]}
} -cleanup {
    $doc delete
} -result 1

test domNode-38.5 {toXPath - default xml namespace} -setup {
    set doc [dom parse {
<root xmlns="foo">
    <!-- comment -->
    <foo/>
    some text    
    <foo/>
    <?mypi data?>
    <foo/>
</root>}]
    set root [$doc documentElement]
    $doc selectNodesNamespaces {foo foo}
    set foo2 [$root selectNodes {foo:foo[2]}]
} -body {
    expr {$foo2 == [[$foo2 ownerDocument] selectNodes [$foo2 toXPath]]}
} -cleanup {
    $doc delete
} -result 1

test domNode-38.6 {toXPath - xml namespace} -setup {
    set doc [dom parse {
<root xmlns:foo="foo">
    <!-- comment -->
    <foo:foo/>
    some text    
    <foo:foo/>
    <?mypi data?>
    <foo:foo/>
</root>}]
    set root [$doc documentElement]
    $doc selectNodesNamespaces {foo foo}
    set foo2 [$root selectNodes {foo:foo[2]}]
} -body {
    expr {$foo2 == [[$foo2 ownerDocument] selectNodes [$foo2 toXPath]]}
} -cleanup {
    $doc delete
} -result 1

test domNode-38.7 {toXPath - pathological xml namespace} -setup {
    set doc [dom parse {
<root>
    <!-- comment -->
    <foo:foo xmlns:foo="foo"/>
    some text    
    <foo:foo xmlns:foo="bar"/>
    <?mypi data?>
    <foo:foo xmlns:foo="bar"/>
    <foo:foo xmlns:foo="foo"/>
</root>}]
    set root [$doc documentElement]
    $doc selectNodesNamespaces {foo foo}
    set foo2 [$root selectNodes {foo:foo[2]}]
} -body {
    expr {$foo2 == [[$foo2 ownerDocument] selectNodes [$foo2 toXPath]]}
} -cleanup {
    $doc delete
} -result 1

test domNode-38.8 {toXPath - pathological xml namespace} -setup {
    set doc [dom parse {
<root>
    <!-- comment -->
    <foo:foo xmlns:foo="foo">
        <bar/>
        text
        <bar xmlns=""/>
    </foo:foo>
    some text    
    <foo:foo xmlns:foo="bar"/>
    <?mypi data?>
    <foo:foo xmlns:foo="bar"/>
    <foo:foo xmlns:foo="foo">
        <bar/>
        <foo:foo xmlns:foo="bar"/>
        text
        <bar xmlns=""/>
    </foo:foo>
    <foo:foo xmlns:foo="foo"/>
</root>}]
} -body {
    set result ""
    foreach node [$doc selectNodes //node()] {
        if {$node != [[$node ownerDocument] selectNodes [$node toXPath]]} {
            set result [$node toXPath]
            break
        }
    }
    set result
} -cleanup {
    $doc delete
} -result ""

test domNode-38.9 {toXPath - really long element name} -constraints {
    knownBug
} -setup {
    set doc [dom parse "<doc><[string repeat abc 100]/></doc>"]
    set root [$doc documentElement]
    set firstChild [$root firstChild]
} -body {
    $firstChild toXPath
} -cleanup {
    $doc delete
} -result "/doc/[string repeat abc 100]"

test domNode-39.1 {text} {
     set doc [dom parse {<root>text <b>bold</b> more text</root>}]
     $doc documentElement root
     set result [$root text]
     $doc delete
     set result

Added tests/domjson.test.





































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
# Features covered: JSON parser
#
# This file contains a collection of tests for the JSON parser.
# Tested functionalities:
#    json-1.*: JSON syntax tests
#    json-2.*: Valid JSON, that could not parsed into DOM
#    json-3.*: JSON unescaping
#    json-4.*: Unicode
#    json-5.*: Max nesting
#    json-6.*: asJSON
#    json-7.*: jsonType
#    json-8.*: appendFromScript
#    json-9.*: cloneNode
# Copyright (c) 2017 Rolf Ade.

source [file join [file dir [info script]] loadtdom.tcl]


namespace eval nodeCmds {
    dom createNodeCmd elementNode e1
    dom createNodeCmd -jsonType ARRAY elementNode jae1
    dom createNodeCmd elementNode e2
    dom createNodeCmd commentNode c
    dom createNodeCmd textNode    t
    dom createNodeCmd -jsonType TRUE textNode true
    dom createNodeCmd -jsonType FALSE textNode false
    dom createNodeCmd -jsonType NULL textNode null
    dom createNodeCmd -jsonType NUMBER textNode number
    dom createNodeCmd cdataNode   cdata
    dom createNodeCmd piNode      pi
}

test json-1.1 {Parse JSON} {
    set doc [dom parse -json {{"a":"avalue","b":"bvalue","c":0.123}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} "<a>avalue</a><b>bvalue</b><c>0.123</c>"

test json-1.2 {Parse JSON} {
    set doc [dom parse -json { {"a" : [ "avalue" ] } }]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<a>avalue</a>}

test json-1.3 {Parse JSON} {
    set doc [dom parse -json {{"a":"a value","b":"1value"}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} "<a>a value</a><b>1value</b>"

test json-1.4 {Parse JSON - nested object} {
    set doc [dom parse -json {{"a":{"aa":"aavalue","bb":"bbvalue"},"b":"bvalue","c":0.123}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} "<a><aa>aavalue</aa><bb>bbvalue</bb></a><b>bvalue</b><c>0.123</c>"

test json-1.5 {Parse JSON - array} {
    set doc [dom parse -json {{"a": [1,2,3,4,"abc"]}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} "<a>1234abc</a>"

test json-1.6 {Parse JSON - true, false, null} {
    set doc [dom parse -json {{"a":true,"b":false,"c":null,"d":"true","e":""}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<a>true</a><b>false</b><c>null</c><d>true</d><e></e>}

test json-1.7 {Parse JSON - array in nested object} {
    set doc [dom parse -json {{"a":{"aa":[1,2,3,4,"abc"]},"b":"bvalue"}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} "<a><aa>1234abc</aa></a><b>bvalue</b>"

test json-1.8 {Parse JSON - true, false, null} {
    set doc [dom parse -json -jsonroot "JSONObject" {{"a":true,"b":false,"c":null,"d":"true","e":""}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<JSONObject><a>true</a><b>false</b><c>null</c><d>true</d><e></e></JSONObject>}

test json-1.9 {JSON syntax error} {
    set result [catch {dom parse -json {{"a" "a value"}}} errMsg]
    list $result $errMsg
} {1 {error "JSON syntax error" at position 5
"{"a" " <--Error-- a value"}"}}

test json-1.10 {JSON syntax error} {
    set result [catch {dom parse -json {{"a":00.23}}} errMsg]
    list $result $errMsg
} {1 {error "JSON syntax error" at position 6
"{"a":00 <--Error-- .23}"}}

test json-1.11 {JSON syntax error} {
    set result [catch {dom parse -json {{"a":-00.23}}} errMsg]
    list $result $errMsg
} {1 {error "JSON syntax error" at position 7
"{"a":-00 <--Error-- .23}"}}

test json-1.12 {JSON syntax error} {
    set result [catch {dom parse -json {{"a":.23}}} errMsg]
    list $result $errMsg
} {1 {error "JSON syntax error" at position 5
"{"a":. <--Error-- 23}"}}

test json-1.13 {JSON syntax error} {
    set result [catch {dom parse -json {{"a":-.23}}} errMsg]
    list $result $errMsg
} {1 {error "JSON syntax error" at position 6
"{"a":-. <--Error-- 23}"}}

test json-1.14 {JSON syntax error} {
    set result [catch {dom parse -json {{"a":-}}} errMsg]
    list $result $errMsg
} {1 {error "JSON syntax error" at position 5
"{"a":- <--Error-- }"}}

test json-1.15 {Parse JSON - nested object} {
    set doc [dom parse -json {["a",["aa","bb"],"b"]}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} "a<arraycontainer>aabb</arraycontainer>b"

set notJsons {
    {{null}}
    {{1.23}}
    {{"string"}}
    {{"e":}}
}
test json-1.16 {Invalid input} {
    set result ""
    set ind 0
    foreach notJson $notJsons {
        if {![catch {dom parse -json $notJson docNode} errMsg]} {
            lappend result $errMsg
        }
    }
    set result
} ""

test json-1.17 {Literal binary 0 (NUL, '\0') is not allowed in input} {
    catch {dom parse -json "\"a\u0000\""}
} 1

test json-1.18 {Escaped binary 0 (NUL, '\0') is OK} {
    dom parse -json "\"a\\u0000\"" doc
    set result [$doc asJSON]
    $doc delete
    set result
} "\"a\\u0000\""

test json-1.19 {Invalid input - uncompled \u escape} {
    catch {dom parse -json {"ab\u00"}}
} 1

test json-1.20 {Escaped binary 0} {needExpand} {
    dom parse -json "\"a\\u0000\"" doc
    set textvalue [$doc selectNodes string(node())]
    set result [string length $textvalue]
    binary scan $textvalue c2 result2
    lappend result {*}$result2
    $doc delete
    set result
} {2 97 0}

test json-2.1 {invalid xml name} {
    set doc [dom parse -json {{"a":"a value","1b":"1value", "a\nb":"a\nb", "":"empty string"}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<a>a value</a><1b>1value</1b><a
b>a
b</a
b><>empty string</>}

test json-3.1 {Unescaping} {
    set doc [dom parse -json {{"a":"a\nvalue","b":"value\tvalue"}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} "<a>a
value</a><b>value\tvalue</b>"

test json-3.2 {Unescaping} {
    set doc [dom parse -json {{"a":"a\nvalue", "b":"12\u0077\u2221ec"}}]
    set result [$doc asXML -indent none -escapeNonASCII]
    $doc delete
    set result
} "<a>a
value</a><b>12w&#8737;ec</b>"

test json-3.3 {Unescaping} {
    set doc [dom parse -json {{"a":"\u0077\u2221"}}]
    set result [$doc asXML -indent none -escapeNonASCII]
    $doc delete
    set result
} "<a>w&#8737;</a>"

test json-3.4 {unescaping} {
    set doc [dom parse -jsonroot json -json {["\\a"]}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<json>\a</json>}

test json-3.4.1 {unescaping} {
    set doc [dom parse -jsonroot json -json {["\\a","\u0071"]}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<json>\aq</json>}

test json-3.5 {unescaping} {
    set result [catch {dom parse -json {{"this":"a\lb"}}} errMsg]
    list $result $errMsg
} {1 {error "JSON syntax error" at position 11
"{"this":"a\l <--Error-- b"}"}}

test json-3.6 {unescaping} {
    set doc [dom parse -json {{"this":"a\nbc"}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<this>a
bc</this>} 

test json-3.7 {unescaping} {
    set doc [dom parse -json {{"this":"a\u0077\t\u0078bc"}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} "<this>aw\txbc</this>"

test json-3.8 {unescaping} {
    set doc [dom parse -json {{"this":"a\u000b"}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} "<this>a\u000b</this>"

test json-3.9 {unescaping} {
    set doc [dom parse -json {{"this":"a\u0077","that":"\t\u0078bc"}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} "<this>aw</this><that>\txbc</that>"

test json-5.1 {-jsonmaxnesting 0} {
    set result [catch {dom parse -json -jsonmaxnesting 0 {{"this":"that"}}} errMsg]
    list $result $errMsg
} {1 {error "Maximum JSON object/array nesting depth exceeded" at position 0
"{ <--Error-- "this":"that"}"}}

test json-5.2 {-jsonmaxnesting 0} {
    set result [catch {dom parse -json -jsonmaxnesting 0 {["this","that"]}} errMsg]
    list $result $errMsg
} {1 {error "Maximum JSON object/array nesting depth exceeded" at position 0
"[ <--Error-- "this","that"]"}}

test json-5.3 {-jsonmaxnesting 0} {
    set result [catch {dom parse -jsonroot o -json -jsonmaxnesting 0 {["this","that"]}} errMsg]
    list $result $errMsg
} {1 {error "Maximum JSON object/array nesting depth exceeded" at position 0
"[ <--Error-- "this","that"]"}}

test json-5.4 {-jsonmaxnesting} {
    set doc [dom parse -json -jsonmaxnesting 2 {{"this":{"foo":"that"}}}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<this><foo>that</foo></this>}

test json-5.5 {-jsonmaxnesting} {
    set result [catch {dom parse -json -jsonmaxnesting 1 \
                           {{"this":{"foo":"that"}}}} errMsg]
    list $result $errMsg
} {1 {error "Maximum JSON object/array nesting depth exceeded" at position 8
"{"this":{ <--Error-- "foo":"that"}}"}}

test json-5.6 {-jsonmaxnesting} {
    set doc [dom parse -json -jsonmaxnesting 2 {
        {
            "this": {
                "foo":"that",
                "bar":"grill"
            },
            "two": "value",
            "three": {
                "t1":"t1value",
                "t2":"t2value"
            },
            "four": ["a","b","c"]
        }}]
    set result [$doc asXML]
    $doc delete
    set result
} {<this>
    <foo>that</foo>
    <bar>grill</bar>
</this>
<two>value</two>
<three>
    <t1>t1value</t1>
    <t2>t2value</t2>
</three>
<four>abc</four>
}

set jsons {
    {{"a":"avalue","b":"bvalue","c":0.123}}
    {{"a":["avalue"]}}
    {{"a":"a value","b":"1value"}}
    {{"a":{"aa":"aavalue","bb":"bbvalue"},"b":"bvalue","c":0.123}}
    {{"a":[1,2,3,4,"abc"]}}
    {{"a":true,"b":false,"c":null,"d":"true","e":""}}
    {{"a":{"aa":[1,2,3,4,"abc"]},"b":"bvalue"}}
    {{"a":true,"b":false,"c":null,"d":"true","e":""}}
    {["a",["aa","bb"],"b"]}
    {{"a":"a\nvalue","b":"value\tvalue"}}
    {["\\\\a"]}
    {["a\"b"]}
    {{"b":"a \"b c\" d","b":"a \"b c\" d"}}
    {{"this":"a\nbc"}}
    {{"this":{"foo":"that"}}}
    {{"this":{"foo":"that","bar":"grill"},"two":"value","three":{"t1":"t1value","t2":"t2value"},"four":["a","b","c"]}}
    {"only a string"}
    {null}
    {1.23}
    {true}
    {false}
    {{}}
    {[]}
    {[[]]}
    {[["x"]]}
    {""}
    {[[[[["a"]]]]]}
    {{"x":[{"id":"foo"}]}}
    {"http://foo.bar"}
}
test json-6.1 {asJSON} {
    set failedlist [list]
    set ind 0
    foreach json $jsons {
        set doc [dom parse -json $json]
        set out [$doc asJSON]
        if {$json ne $out} {
            lappend failedlist "$ind : '$json' : '$out'"
        }
        incr ind
    }
    set failedlist
} {}

test json-6.2 {asJSON - slash will not be escaped while serializing} {
    set doc [dom parse -json {"http:\/\/foo.bar"}]
    set result [$doc asJSON]
    $doc delete
    set result
} {"http://foo.bar"}

test json-6.3 {asJSON - docNode serialization} {
    dom createDocumentNode docNode
    set result [$docNode asJSON]
    $docNode delete
    set result
} {{}}

test json-6.4 {asJSON - doc serialization} {
    dom createDocument root docNode
    set result [$docNode asJSON]
    $docNode delete
    set result
} {{"root":""}}

test json-6.5 {asJSON - serialization of control characters} {
    set doc [dom parse -json "\"a\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\u0008\\u0009\\u000A\\u000B\\u000C\\u000D\\u000E\\u000F\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F\\u0020b\""]
    set result [$doc asJSON]
    $doc delete
    set result
} {"a\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f b"}

test json-7.1 {jsonType} {
    set doc [dom parse {<j>foo</j>}]
    set root [$doc documentElement]
    set result [list]
    lappend result [$root asJSON]
    lappend result [$root jsonType]
    $root jsonType ARRAY
    lappend result [$root asJSON]
    $doc delete
    set result
} {{"foo"} NONE {["foo"]}}

test json-7.2 {jsonType} {
    set doc [dom createDocumentNode]
    set result [$doc jsonType]
    lappend result [$doc asJSON]
    lappend result [catch {$doc jsonType foo}]
    $doc jsonType ARRAY
    lappend result [$doc asJSON]
    $doc jsonType OBJECT
    lappend result [$doc asJSON]
    $doc delete
    set result
} {NONE {{}} 1 {[]} {{}}}

test json-8.1 {appendFromScript} {
    set doc [dom createDocumentNode]
    $doc appendFromScript {
        nodeCmds::e1
    }
    set result [list]
    lappend result [$doc asJSON]
    set root [$doc documentElement]
    lappend result [$root asJSON]
    $doc removeChild [$doc firstChild]
    $doc appendFromScript {
        nodeCmds::jae1
    }
    lappend result [$doc asJSON]
    set root [$doc documentElement]
    lappend result [$root asJSON]
    lappend result [$root jsonType]
    $doc delete
    set result
} {{{"e1":""}} {{}} {{"jae1":[]}} {[]} ARRAY}

test json-8.2 {appendFromScript} {
    set doc [dom createDocumentNode]
    $doc appendFromScript {
        nodeCmds::t "some string"
    }
    set result [$doc asJSON]
    $doc delete
    set result
} {"some string"}

test json-8.3 {appendFromScript} {
    set doc [dom createDocumentNode]
    $doc appendFromScript {
        nodeCmds::t ""
        nodeCmds::true ""
        nodeCmds::false ""
        nodeCmds::null ""
    }
    set result [$doc asJSON]
    $doc delete
    set result
} {["",true,false,null]}

test json-8.4 {appendFromScript - text node with type NUMBER} {
    set doc [dom createDocumentNode]
    $doc appendFromScript {
        nodeCmds::number ""
        nodeCmds::number "0"
        nodeCmds::number "123456789012345678901234567890.12345679e-0003"
        nodeCmds::number "42 "
        nodeCmds::number " 42"
        nodeCmds::number "-"
    }
    set result [$doc asJSON]
    $doc delete
    set result
} {["",0,123456789012345678901234567890.12345679e-0003,"42 "," 42","-"]}

test json-8.5 {createNodeCmd - wrong jsonType} {
    catch {dom createNodeCmd -jsonType OBJECT textNode textNodeWithJsonTypeObject}
} 1

test json-9.1 {cloneNode -deep} {
    dom parse -json {[["a",1,"b",{"foo":"bar","baz":"boo"},null],"",null]} doc
    dom createDocument some other
    $other documentElement root
    $root appendChild [[$doc firstChild] cloneNode -deep]
    set result [[$root firstChild] asJSON]
    $doc delete
    $other delete
    set result
} {["a",1,"b",{"foo":"bar","baz":"boo"},null]}

test json-9.2 {cloneNode} {
    dom parse -json {[["a",1,"b",{"foo":"bar","baz":"boo"},null],"",null]} doc
    dom createDocument some other
    $other documentElement root
    $root appendChild [[$doc firstChild] cloneNode]
    set result [[$root firstChild] asJSON]
    $doc delete
    $other delete
    set result
} {[]}

test json-9.3 {cloneNode} {
    dom parse -json {{"string":"bar","number":1,"boolean":true,"array":[1,2,3],"object":{"foo":"bar","baz":"boo"}}} doc
    dom createDocument some other
    $other documentElement root
    foreach child [$doc childNodes] {
        $root appendChild [$child cloneNode -deep]
    }
    set result [list]
    foreach child [$root childNodes] {
        lappend result [$child asJSON]
    }
    $doc delete
    $other delete
    set result
} {{"bar"} 1 true {[1,2,3]} {{"foo":"bar","baz":"boo"}}}

Changes to tests/domnamespace.test.

1
2
3
4
5
6
7


8
9
10
11
12
13
14
...
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
...
296
297
298
299
300
301
302































































































303
304
305
# Features covered: Namespace related DOM actions.
#
# This file contains a collection of tests for some namespace related
# actions.
#
#    domnamespace-1.*: misc tests
#    domnamespace-2.*: moving namespaced nodes from one document to another


#
# Copyright (c) 2002 Rolf Ade.
#
# RCS: @(#) $Id$

source [file join [file dir [info script]] loadtdom.tcl]

................................................................................
    $root2 appendChild $node
    set result [$root2 asXML -indent none]
    $doc1 delete
    $doc2 delete
    set result
} {<root xmlns="NS2"><doc1elem xmlns=""><a xmlns:p="foo" p:b="c"/></doc1elem></root>}

test domnamespace-2.11 {moving nodes with namespaced attributes between documents} {
    set doc1 [dom parse {<root xmlns:p="foo"><doc1elem><a p:b="c"/></doc1elem></root>}]
    set root1 [$doc1 documentElement]
    set doc2 [dom parse {<root xmlns="NS2"/>}]
    set root2 [$doc2 documentElement]

    set node [$root1 removeChild [$root1 firstChild]]
    $root2 appendChild $node
    set result [$root2 asXML -indent none]
    $doc1 delete
    $doc2 delete
    set result
} {<root xmlns="NS2"><doc1elem xmlns=""><a xmlns:p="foo" p:b="c"/></doc1elem></root>}

test domnamespace-2.12 {moving nodes with namespaced attributes between documents} {
    set doc1 [dom parse {<root xmlns:p="foo"><doc1elem><a p:b="c"/></doc1elem></root>}]
    set root1 [$doc1 documentElement]
    set doc2 [dom parse {<root xmlns="NS2"/>}]
    set root2 [$doc2 documentElement]
    
    set node [$root1 removeChild [$root1 firstChild]]
................................................................................
    [$root2 firstChild] appendChild $node
    set result [$root2 asXML -indent none]
    $doc1 delete
    $doc2 delete
    set result
} {<root xmlns="NS2"><e xmlns=""><doc1elem xmlns="NS1"><a xmlns:p="foo" p:b="c"/></doc1elem></e></root>}

test domnamespace-2.14 {moving nodes with namespaced attributes between documents} {
    set doc1 [dom parse {<root xmlns="NS1" xmlns:p="foo"><doc1elem><a p:b="c"/></doc1elem></root>}]
    set root1 [$doc1 documentElement]
    set doc2 [dom parse {<root xmlns="NS2"><e xmlns=""/></root>}]
    set root2 [$doc2 documentElement]
    
    set node [$root1 removeChild [$root1 firstChild]]
    [$root2 firstChild] appendChild $node
................................................................................
        lappend result [$node nodeName]
    }
    $doc1 delete
    $doc2 delete
    set result
} {doc1elem a}
































































































# cleanup
::tcltest::cleanupTests
return







>
>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
222
223
224
225
226
227
228














229
230
231
232
233
234
235
...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
# Features covered: Namespace related DOM actions.
#
# This file contains a collection of tests for some namespace related
# actions.
#
#    domnamespace-1.*: misc tests
#    domnamespace-2.*: moving namespaced nodes from one document to another
#    domnamespace-3.*: moving namespaced nodes within a document
#    domnamespace-4.*: createNodeCmd and namespaces
#
# Copyright (c) 2002 Rolf Ade.
#
# RCS: @(#) $Id$

source [file join [file dir [info script]] loadtdom.tcl]

................................................................................
    $root2 appendChild $node
    set result [$root2 asXML -indent none]
    $doc1 delete
    $doc2 delete
    set result
} {<root xmlns="NS2"><doc1elem xmlns=""><a xmlns:p="foo" p:b="c"/></doc1elem></root>}















test domnamespace-2.12 {moving nodes with namespaced attributes between documents} {
    set doc1 [dom parse {<root xmlns:p="foo"><doc1elem><a p:b="c"/></doc1elem></root>}]
    set root1 [$doc1 documentElement]
    set doc2 [dom parse {<root xmlns="NS2"/>}]
    set root2 [$doc2 documentElement]
    
    set node [$root1 removeChild [$root1 firstChild]]
................................................................................
    [$root2 firstChild] appendChild $node
    set result [$root2 asXML -indent none]
    $doc1 delete
    $doc2 delete
    set result
} {<root xmlns="NS2"><e xmlns=""><doc1elem xmlns="NS1"><a xmlns:p="foo" p:b="c"/></doc1elem></e></root>}

test domnamespace-2.15 {moving nodes with namespaced attributes between documents} {
    set doc1 [dom parse {<root xmlns="NS1" xmlns:p="foo"><doc1elem><a p:b="c"/></doc1elem></root>}]
    set root1 [$doc1 documentElement]
    set doc2 [dom parse {<root xmlns="NS2"><e xmlns=""/></root>}]
    set root2 [$doc2 documentElement]
    
    set node [$root1 removeChild [$root1 firstChild]]
    [$root2 firstChild] appendChild $node
................................................................................
        lappend result [$node nodeName]
    }
    $doc1 delete
    $doc2 delete
    set result
} {doc1elem a}

test domnamespace-2.16 {It is not recommended to create attributes that look like namespace declarations} {
    set doc [[dom parse {<test xmlns="foo"/>}] documentElement]
    set child [[dom parse {<item/>}] documentElement]
    $child setAttribute xmlns "foo"
    $doc appendChild $child
    $doc asXML -indent none
} {<test xmlns="foo"><item xmlns="" xmlns="foo"/></test>}

test domnamespace-2.17 {It is not recommended to create xml namespace declarations} {
    set doc [[dom parse {<test xmlns="foo"/>}] documentElement]
    set child [[dom parse {<item/>}] documentElement]
    $child setAttributeNS "" xmlns "foo"
    $doc appendChild $child
    $doc asXML -indent none
} {<test xmlns="foo"><item xmlns="foo" xmlns=""/></test>}

test domnamespace-3.1 {moving namespaced nodes within a document} {
    set doc [dom parse {<doc><e xmlns="foo"><ee/></e><e xmlns="bar"/></doc>}]
    set root [$doc documentElement]
    set nodeToMove [$doc selectNodes {/doc/node()[1]/node()[1]}]
    set newParent [$doc selectNodes {/doc/node()[2]}]
    $newParent appendChild $nodeToMove
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc><e xmlns="foo"/><e xmlns="bar"><ee xmlns="foo"/></e></doc>}


namespace eval nodeCmds {
    dom createNodeCmd -namespace foo.bar elementNode ns1:e1
    dom createNodeCmd -namespace foo.bar elementNode e1
    dom createNodeCmd textNode t
    dom createNodeCmd -tagName e1 elementNode e1NoNS
}

test domnamespace-4.1 {createNodeCmd and namespace} {
    dom createDocument doc doc
    $doc documentElement root
    $root appendFromScript {
        nodeCmds::ns1:e1 {nodeCmds::t "this"}
    }
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc><ns1:e1 xmlns:ns1="foo.bar">this</ns1:e1></doc>}

test domnamespace-4.2 {createNodeCmd and namespace} {
    dom createDocumentNS foo.bar ns1:doc doc
    $doc documentElement root
    $root appendFromScript {
        nodeCmds::ns1:e1 {nodeCmds::t "this"}
    }
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<ns1:doc xmlns:ns1="foo.bar"><ns1:e1>this</ns1:e1></ns1:doc>}

test domnamespace-4.3 {createNodeCmd and namespace} {
    dom createDocumentNS foo.bar doc doc
    $doc documentElement root
    $root appendFromScript {
        nodeCmds::ns1:e1 {nodeCmds::t "this"}
    }
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc xmlns="foo.bar"><ns1:e1 xmlns:ns1="foo.bar">this</ns1:e1></doc>}

test domnamespace-4.4 {createNodeCmd and namespace} {
    dom createDocumentNS foo.bar doc doc
    $doc documentElement root
    $root appendFromScript {
        nodeCmds::e1 {
            nodeCmds::e1NoNS att attValue {nodeCmds::t "this"}
        }
    }
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc xmlns="foo.bar"><e1><e1 xmlns="" att="attValue">this</e1></e1></doc>}

test domnamespace-4.5 {createNodeCmd and namespace} {
    dom createDocumentNS foo.bar doc doc
    $doc documentElement root
    $root appendFromScript {
        nodeCmds::e1 {
            nodeCmds::e1NoNS att attValue {nodeCmds::t "this"}
        }
    }
    set result [$doc selectNodes -namespaces {fb foo.bar} string(/fb:doc/fb:e1/e1/@att)]
    $doc delete
    set result
} {attValue}

    
# cleanup
::tcltest::cleanupTests
return

Changes to tests/entity.test.

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#
# This file contains a collection of tests for the different kinds of 
# entities.
#
#    entity-1.*:  parameter entities, character entities
#    entity-2.*:  predefined entities
#    entity-3.*:  -useForeignDTD
#    entity-4.*:  external parsed entites
#
# Copyright (c) 1999-2000 Zveno Pty Ltd.
# Copyright (c) 2000-2004 Rolf Ade
#
# $Id$

source [file join [file dir [info script]] loadtdom.tcl]







|







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#
# This file contains a collection of tests for the different kinds of 
# entities.
#
#    entity-1.*:  parameter entities, character entities
#    entity-2.*:  predefined entities
#    entity-3.*:  -useForeignDTD
#    entity-4.*:  external parsed entities
#
# Copyright (c) 1999-2000 Zveno Pty Ltd.
# Copyright (c) 2000-2004 Rolf Ade
#
# $Id$

source [file join [file dir [info script]] loadtdom.tcl]

Added tests/html5reader.test.





























































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# Features covered: HTML parser
#
# This file contains a collection of tests for the HTML parser.
# Tested functionalities:
#    html5-1.*: Character encoding
#    html5-2.*: Parsing tests
#    html5-3.*: Bad data
#    html5-4.*: DOM building
#    html5-5.*: Namespaces
#
# Copyright (c) 2017 Rolf Ade.

source [file join [file dir [info script]] loadtdom.tcl]

testConstraint html5 [dom featureinfo html5]

test html5-1.1 {HTML character entities} {need_i18n html5} {
    set doc [dom parse -html5 -ignorexmlns {<html><body>&nbsp;&iexcl;&Auml;&uuml;</body></html>}]
    set root [$doc documentElement]
    set body [$root selectNodes body]
    set result [$body text]
    $doc delete
    set result
} "\u00A0\u00A1\u00c4\u00fc"

test html5-1.2 {character entities} {need_i18n html5} {
    set doc [dom parse -html5 -ignorexmlns {<html><body>&#214;&#xC4;&#xc4;</body></html>}]
    set root [$doc documentElement]
    set body [$root selectNodes body]
    set result [$body text]
    $doc delete
    set result
} "\u00d6\u00c4\u00c4"

test html5-1.3 {character entities} {need_i18n html5} {
    set doc [dom parse -html5 -ignorexmlns {<html>&euro;&ni;</html>}]
    set root [$doc documentElement]
    set body [$root selectNodes body]
    set result [$body text]
    $doc delete
    set result
} "\u20ac\u220b"

test html5-1.4 {invalid characters} {need_i18n html5} {
    set doc [dom parse -html5 -ignorexmlns {<html>&#1;&#2;&#3;&#4;foo;</html>}]
    set root [$doc documentElement]
    set body [$root selectNodes body]
    set result [$body text]
    $doc delete
    set result
} "\u0001\u0002\u0003\u0004foo;"

test html5-2.1 {not closed p tags} {html5} {
    set doc [dom parse -html5 -ignorexmlns {
        <html><body><p>Para 1<p>Para 2<p>Para 3</body></html>
    }]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<html><head/><body><p>Para 1</p><p>Para 2</p><p>Para 3
    </p></body></html>}

test html5-2.2 {HTML parsing} {html5} {
    set doc [dom parse -html5 -ignorexmlns {
        <HTML><HEAD></HEAD>
        <BODY>
        <H1>HTML</H1>
        </BODY>
        </HTML>
    }]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<html><head/><body><h1>HTML</h1></body></html>}

test html5-2.3 {HTML parsing} {html5} {
    set doc [dom parse -html5 -ignorexmlns {
        <!-- comment -->
        <HTML><HEAD></HEAD>
        <BODY>
        <H1>HTML</H1>
        </BODY>
        </HTML>
    }]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<!-- comment --><html><head/><body><h1>HTML</h1></body></html>}

test html5-2.4 {HTML parsing} {html5} {
    set doc [dom parse -html5 -ignorexmlns {
        <!-- comment -->
        <HTML><HEAD></HEAD>
        <BODY>
        <H1>HTML</H1>
        </BODY>
        </HTML>
        <!-- comment -->
    }]
    $doc documentElement root
    set result [$root nodeName]
    $doc delete
    set result
} {html}

test html5-2.5 {HTML parsing} {html5} {
    set doc [dom parse -html5 -ignorexmlns {<html> <head><title></title></head><body>
        <form>
        <select id="L" name="nls_language">
        <option value="">--</option>
        <option value="en_US" selected="on">en_US</option>
        <option value="es_ES">es_ES</option>
        <option value="de_DE">de_DE</option>
        </select>
        </form>
        </body></html>
    }]
    $doc asHTML
} {<html>
<head><title></title></head><body><form><select id="L" name="nls_language">
<option value="">--</option><option value="en_US" selected="on">en_US</option><option value="es_ES">es_ES</option><option value="de_DE">de_DE</option>
</select></form></body>
</html>}

test html5-2.6 {HTML parsing} {html5} {
    set doc [dom parse -html5 -ignorexmlns {<html> <head><title></title></head><body>
        <form>
        <select id="L" name="nls_language">
        <option value="">--
        <option value="en_US" selected="on">en_US
        <option value="es_ES">es_ES
        <option value="de_DE">de_DE
        </select>
        </form>
        </body></html>
    }]
    $doc asHTML
} {<html>
<head><title></title></head><body><form><select id="L" name="nls_language">
<option value="">--
        </option><option value="en_US" selected="on">en_US
        </option><option value="es_ES">es_ES
        </option><option value="de_DE">de_DE
        </option>
</select></form></body>
</html>}

test html5-2.7 {HTML parsing} {html5} {
    set doc [dom parse -html5 -ignorexmlns {<html> <head><title></title></head><body>
        <form>
        <select id="L" name="nls_language">
        <option value="">--
        <option value="en_US" selected>en_US
        <option value="de_DE">de_DE
        </select>
        </form>
        </body></html>
    }]
    $doc asHTML
} {<html>
<head><title></title></head><body><form><select id="L" name="nls_language">
<option value="">--
        </option><option value="en_US" selected="selected">en_US
        </option><option value="de_DE">de_DE
        </option>
</select></form></body>
</html>}

test html5-2.8 {HTML parsing} {html5} {
    set doc [dom parse -html5 -ignorexmlns {<html> <head><title></title></head><body>
        <form>
        <select id="L" name="nls_language">
        <option value="">--
        <option selected value="en_US">en_US
        <option value="de_DE">de_DE
        </select>
        </form>
        </body></html>
    }]
    $doc asHTML
} {<html>
<head><title></title></head><body><form><select id="L" name="nls_language">
<option value="">--
        </option><option selected="selected" value="en_US">en_US
        </option><option value="de_DE">de_DE
        </option>
</select></form></body>
</html>}

test html5-3.1 {Bad data} {html5} {
    set data {line 6 column 17 - Warning: <script> lacks "type" attribute
line 10 column 17 - Warning: <script> lacks "type" attribute
        line 11 column 17 - Warning: <table> lacks "summary" attribute}
    set doc [dom parse -html5 -ignorexmlns $data]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<html><head/><body>line 6 column 17 - Warning: <script> lacks "type" attribute
line 10 column 17 - Warning: &lt;script&gt; lacks "type" attribute
        line 11 column 17 - Warning: &lt;table&gt; lacks "summary" attribute</script></body></html>}

test html5-3.2 {Bad data} {html5} {
     set doc [dom parse -html5 -ignorexmlns {<a>}]
     set result [$doc asXML -indent none]
     $doc delete
     set result
} {<html><head/><body><a/></body></html>}
        
test html5-4.1 {Tag name case normalization} {html5} {
    set doc [dom parse -html5 -ignorexmlns {<HtmL><boDY></BODy></HTml>}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<html><head/><body/></html>}

test html5-4.2 {Tag name case normalization} {html5} {
    set doc [dom parse -html5 -ignorexmlns {<HtmL><NotaHTML_Tag/></HTml>}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<html><head/><body><notahtml_tag/></body></html>}

test html5-4.3 {Attribute normalization} {html5} {
    set doc [dom parse -html5 -ignorexmlns {<HtmL><Body Id='3' FOO="Bar" note=this GriLL></body></html>}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<html><head/><body id="3" foo="Bar" note="note" grill="grill"/></html>}

test html5-4.4 {ID Attribute handling} {html5} {
    set doc [dom parse -html5 -ignorexmlns {<HtmL><p ID="1"/><p id="2"/><p/></html>}]
    set result [[$doc getElementById 1] getAttribute id]
    $doc delete
    set result
} {1}


set xhtml {h "http://www.w3.org/1999/xhtml"}
set svg {svg "http://www.w3.org/2000/svg"}
set mathml {mml "http://www.w3.org/1998/Math/MathML"}
set xlink  {xlink "http://www.w3.org/1999/xlink"}

set html5 {<!doctype html>
<html>
  <body>
    <p>
      <svg xmlns="http://www.w3.org/2000/svg">
      <circle cx="30" cy="30" r="30" fill="green"></circle>
      </svg>
    <p>text</p>
    </body>
</html>}
test html5-5.1 {svg subtrees} {html5} {
    set doc [dom parse -html5 $html5]
    set result [$doc selectNodes -namespaces $xhtml {string(/h:html/h:body/h:p[2])}]
    $doc delete
    set result
} {text}

set html5 {<!DOCTYPE html>
<html>
  <head>
    <title>HTML5 SVG demo</title>
  </head>

  <body>
    <h1>HTML5 SVG Demo</h1>

A nice green circle:
    <svg id="circle" height="200" xmlns="http://www.w3.org/2000/svg">
      <circle id="greencircle" cx="30" cy="30" r="30" fill="green" />
    </svg>

    <hr>
    <address>Created by DKS. This is free code</address>
  </body>
</html>}
test html5-5.2 {svg subtrees} {html5} {
    set doc [dom parse -html5 $html5]
    set svg [$doc selectNodes -namespaces $svg //svg:circle]
    set result [$svg @fill]
    $doc delete
    set result
} {green}

set html5 {<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>
        <title>Binomial Theorem</title>
    </head>
    <body>
        <p>Binomial Theorem:</p>
        <math XMLNS="http://www.w3.org/1998/Math/MathML" FOO="bar">
            <mrow>
                <MSUp>
                    <mfenced BAR="grill">
                        <mrow>
                            <mi>a</mi>
                            <mo>+</mo>
                            <mi>b</mi>
                        </mrow>
                    </mfenced>
                    <mn>2</mn>
                </msup>
                <mo>=</mo>
                <msup>
                    <mrow>
                        <mi>a</mi>
                    </mrow>
                    <mn>2</mn>
                </msup>
                <mo>+</mo>
                <msup>
                    <mrow>
                        <mi>b</mi>
                    </mrow>
                    <mn>2</mn>
                </msup>
                <mo>+</mo>
                <mrow>
                    <mn>2</mn>
                    <mi>a</mi>
                    <mi>b</mi>
                </mrow>
            </mrow>
        </math>
    </body>
</html>}
test html5-5.3 {mathml subtrees} {html5} {
    set doc [dom parse -html5 $html5]
    set mis [$doc selectNodes -namespaces $mathml //mml:mi]
    set result ""
    foreach mi $mis {
        append result [$mi text]
    }
    $doc delete
    set result
} {ababab}

set html5 {<html>
  <body>
    <svg id="circle" height="60" width="60" 
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
      <image id="image" x="0" y="0" height="60" width="60"  xlink:href="huge-red-circle.svg" />
    </svg>
</body>}
test html5-5.4 {xlink attribute} {html5} {
    set doc [dom parse -html5 $html5]
    set node [$doc selectNodes -namespaces $xlink {//*[@xlink:href]}]
    set result [$node getAttributeNS [lindex $xlink 1] href]
    $doc delete
    set result
} {huge-red-circle.svg}

test html5-5.5 {xlink attribute} {html5} {
    set doc [dom parse -html5 -ignorexmlns $html5]
    set node [$doc getElementById "image"]
    set result [$node getAttribute "xlink:href"]
    $doc delete
    set result
} {huge-red-circle.svg}


# cleanup
::tcltest::cleanupTests
return

Changes to tests/htmlreader.test.

34
35
36
37
38
39
40
























41
42
43
44
45
46
47
test html-1.3 {character entities} {need_i18n} {
    set doc [dom parse -html {<html>&euro;&ni;</html>}]
    set root [$doc documentElement]
    set result [$root text]
    $doc delete
    set result
} "\u20ac\u220b"

























test html-2.1 {not closed p tags} {
    set doc [dom parse -html {
        <html><body><p>Para 1<p>Para 2<p>Para 3</body></html>
    }]
    set result [$doc asXML -indent none]
    $doc delete







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
test html-1.3 {character entities} {need_i18n} {
    set doc [dom parse -html {<html>&euro;&ni;</html>}]
    set root [$doc documentElement]
    set result [$root text]
    $doc delete
    set result
} "\u20ac\u220b"

test html-1.4 {Invalid numeric character entity} {
    set doc [dom parse -html {<html>&#39xyz</html>}]
    set root [$doc documentElement]
    set result [$root text]
    $doc delete
    set result
} "&#39xyz"

test html-1.5 {Numeric character entity} {
    set doc [dom parse -html {<html>&#123456789012345678;</html>}]
    set root [$doc documentElement]
    set result [$root text]
    $doc delete
    set result
} "&#123456789012345678;"

test html-1.6 {Numeric character entity} {
    set doc [dom parse -html {<html>&#xabcdef;</html>}]
    set root [$doc documentElement]
    set result [$root text]
    $doc delete
    set result
} "&#xabcdef;"

test html-2.1 {not closed p tags} {
    set doc [dom parse -html {
        <html><body><p>Para 1<p>Para 2<p>Para 3</body></html>
    }]
    set result [$doc asXML -indent none]
    $doc delete

Changes to tests/i18n.test.

2
3
4
5
6
7
8



9
10
11
12
13
14
15
..
23
24
25
26
27
28
29
30
31
32
33
34
35
36






37














































38
39
40
41
#
# Copyright (c) 2002 Rolf Ade.
#
# RCS: @(#) $Id$

source [file join [file dir [info script]] loadtdom.tcl]




test i18n-1.1 {parse utf-8 string} {need_i18n} {
    set russian "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439"
    set doc [dom parse "<test>$russian</test>"]
    set root [$doc documentElement]
    set text [$root text]
    $doc delete
    string compare $text "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439"
................................................................................
    set root [$doc documentElement]
    set text [$root text]
    $doc delete
    string compare $text "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439"
} {0}
    
test i18n-1.3 {parse utf-8 readFile} {need_i18n} {
    set doc [dom parse [::tDOM::xmlReadFile [file join [pwd] [file dir [info script]] data/i18n_1.xml]]]
    set root [$doc documentElement]
    set text [$root text]
    $doc delete
    string compare $text "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439"
} {0}
    





















































# cleanup
::tcltest::cleanupTests
return








>
>
>







 







|






>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
..
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#
# Copyright (c) 2002 Rolf Ade.
#
# RCS: @(#) $Id$

source [file join [file dir [info script]] loadtdom.tcl]

testConstraint beyondBMP [expr {[dom featureinfo TCL_UTF_MAX] > 3}]
testConstraint 8.6 [package vsatisfies [package present Tcl] 8.6]

test i18n-1.1 {parse utf-8 string} {need_i18n} {
    set russian "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439"
    set doc [dom parse "<test>$russian</test>"]
    set root [$doc documentElement]
    set text [$root text]
    $doc delete
    string compare $text "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439"
................................................................................
    set root [$doc documentElement]
    set text [$root text]
    $doc delete
    string compare $text "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439"
} {0}
    
test i18n-1.3 {parse utf-8 readFile} {need_i18n} {
    set doc [dom parse [::tdom::xmlReadFile [file join [pwd] [file dir [info script]] data/i18n_1.xml]]]
    set root [$doc documentElement]
    set text [$root text]
    $doc delete
    string compare $text "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439"
} {0}
    
test i18n-1.4 {pcdata outside BMP} -body {
    set doc [dom parse "<doc>&#x1F46E;&#x1F47E;&#x1F494;</doc>"]
    set result [$doc asXML -indent none -escapeNonASCII]
    $doc delete
    set result
} -result "<doc>&#128110;&#128126;&#128148;</doc>"

test i18n-1.5 {pcdata outside BMP} -body {
    set doc [dom parse "<doc>&#x1F46E;&#x1F47E;&#x1F494;</doc>"]
    set result [$doc selectNodes string-length(/doc)]
    $doc delete
    set result
} -result 3

test i18n-1.6 {pcdata outside BMP} -constraints {
    8.6
    beyondBMP
} -body {
    set doc [dom parse "<doc>\U1F46E\U1F47E\U1F494</doc>"]
    set result [$doc asXML -indent none -escapeNonASCII]
    $doc delete
    set result
} -result "<doc>&#128110;&#128126;&#128148;</doc>"

test i18n-1.7 {pcdata outside BMP} -body {
    set doc [dom parse "<doc>&#x1F46E;&#x1F47E;&#x1F494;</doc>"]
    set result [dom isBMPCharData [$doc selectNodes string(/doc)]]
    $doc delete
    set result
} -result 0

test i18n-1.8 {pcdata outside BMP} -constraints {
    beyondBMP
    8.6
} -body {
    set doc [dom parse "<doc>\U1F46E\U1F47E\U1F494</doc>"]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} -result "<doc>&#128110;&#128126;&#128148;</doc>"

test i18n-1.10 {pcdata outside unicode} -body {
    set doc [dom parse "<doc>&#x10FFFF;</doc>"]
    set result [$doc asXML -indent none -escapeNonASCII]
    $doc delete
    set result
} -result "<doc>&#1114111;</doc>"

test i18n-1.11 {pcdata outside unicode} -body {
    set result [catch {dom parse "<doc>&#x110000;</doc>"} msg]
    set msg
} -match glob -result "*reference to invalid character number*"

# cleanup
::tcltest::cleanupTests
return

Changes to tests/loadtdom.tcl.

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16



17
18
19
20
21
22
23

24
25
26
27
28
#
# This file is [source]d by all.tcl and all test files, to ensure, that
# the tcltest package and the lastest tdom build is present.
#
# RCS: @(#) $Id$
#

if {[lsearch [namespace children] ::tcltest] == -1} {
    if {$tcl_version < 8.2} {
        puts stderr "sourcing def.tcl"
        source [file join [file dir [info script]] defs.tcl]
        set auto_path [pwd]
    } else {
        package require tcltest
        namespace import ::tcltest::*



    }
}

if {[catch {package present -exact tdom 0.8.3}]} {
    package require -exact tdom 0.8.3
} else {
    if {[lsearch [namespace children] ::tDOM] == -1} {

        # tcldomsh without the script library. Source the lib.
        source [file join [file dir [info script]] ../lib tdom.tcl]
    }
}








<
<
<
<
<
<
|
|
>
>
>


<
<
<
<
<
>
|
|
|
|
<
2
3
4
5
6
7
8






9
10
11
12
13
14
15





16
17
18
19
20

#
# This file is [source]d by all.tcl and all test files, to ensure, that
# the tcltest package and the lastest tdom build is present.
#
# RCS: @(#) $Id$
#







package require tcltest
namespace import ::tcltest::*
if {[catch {package require -exact tdom 0.9.1}]} {
    if {[catch {load [file join [file dir [info script]] ../unix/libtdom0.9.1.so]}]} {
        error "Unable to load the appropriate tDOM version!"
    }
}





if {[info commands ::tdom::xmlReadFile] == ""} {
    # tcldomsh without the script library. Source the lib.
    source [file join [file dir [info script]] ../lib tdom.tcl]
}


Changes to tests/parser.test.

7
8
9
10
11
12
13



14
15
16
17
18
19
20
21
22
23
..
53
54
55
56
57
58
59



60
61
62
63
64
65
66
...
171
172
173
174
175
176
177



























178
179
180
181
182
183
184
...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
...
414
415
416
417
418
419
420













421
422
423
424
425
426
427
...
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
...
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507


























































































































































































508
509
510
511
512
513
514



























































515
516
517
#    parser-3.*: return code 'continue' from callback
#    parser-4.*: return code 'error' from callback
#    parser-5.*: parse input from channel
#    parser-6.*: reuse parser 
#    parser-7.*: parser reset
#    parser-8.*: parser free
#    parser-9.*: parser parse



#
# Copyright (c) 1999-2000 Zveno Pty Ltd.
# Copyright (c) 2002-2005 Rolf Ade
#
# $Id$

source [file join [file dir [info script]] loadtdom.tcl]

proc parray arrayName {
    upvar #0 $arrayName arr
................................................................................
	    }
	    break {
		return -code break
	    }
	    error {
		return -code error "error condition in callback"
	    }



	    default {
		return -code $atts(class) 
	    }
	}
    }
}
catch {unset ended}
................................................................................
    set ::esh_1_13_2 0
    catch {rename parser-1.13 {}}
    set p [expat parser-1.13 -elementstartcommand esh_1_13_1]
    $p configure -elementstartcommand esh_1_13_2
    $p parse {<root><a/><b/></root>}
    list $::esh_1_13_1 $::esh_1_13_2
} {0 3}




























# Test break return code from callback

test parser-2.1 {break in callback} {
    catch {unset ::started}

    catch {rename parser-2.1 {}}
................................................................................
    set p [::xml::parser parser-4.1 -elementstartcommand Start]
    set errcode [catch {$p parse {<?xml version="1.0"?>
<Test>
<Element>Should see this data</Element>
<Element class="error"/>
<Element>Should not see this data</Element>
</Test>
}} result]
    list $errcode $::started(Element)
} {1 2}

test parser-4.2 {error in callback} {
    catch {unset ::started}

    catch {rename parser-4.2 {}}
................................................................................
    set result [catch {$parser parsechannel $fd}]
    close $fd
    set result
} -cleanup {
    removeFile parser.xml
} -result 1














test parser-6.1 {reuse parser} {
    catch {rename parser-6.1 {}}
    set parser [expat parser-6.1 -baseurl file:///foo/bar]
    set result [$parser cget -baseurl]
    $parser parse <data/>
    lappend result [$parser cget -baseurl]
    $parser configure -baseurl file:///bar/foo
................................................................................

test parser-8.1 {parser free called from within callback proc} {
    set parser [expat -elementstartcommand elementstart]
    set result [catch {$parser parse <root>foo</root>} errMsg]
    lappend result $errMsg
    $parser free
    set result
} {1 {parser freeing not allowed from within callback}}

proc elementstart {args} {
    global parser

    $parser parse {<root>foo bar</root>}
}

test parser-9.1 {try to use the parser form within one of its callbacks} {
    set parser [expat -elementstartcommand elementstart]
    set result [catch {$parser parse <root>foo</root>} errMsg]
    lappend result $errMsg
    $parser free
    set result
} {1 {Parser already in use.}}

................................................................................
    $parser parse {<root>foo bar</root>}
}

proc elementstart {args} {
    calledFromElementstart
}

test parser-9.2 {try to use the parser form within one of its callbacks} {
    set parser [expat -elementstartcommand elementstart]
    set result [catch {$parser parse <root>foo</root>} errMsg]
    lappend result $errMsg
    $parser free
    set result
} {1 {Parser already in use.}}



























































































































































































foreach parser [info commands xmlparser*] {
    $parser free
}
foreach parser [info commands parser-*] {
    $parser free
}




























































# cleanup
::tcltest::cleanupTests
return







>
>
>


|







 







>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







|







 







|







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
...
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
...
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
...
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
#    parser-3.*: return code 'continue' from callback
#    parser-4.*: return code 'error' from callback
#    parser-5.*: parse input from channel
#    parser-6.*: reuse parser 
#    parser-7.*: parser reset
#    parser-8.*: parser free
#    parser-9.*: parser parse
#    parser-10.*: return code 'return' from callback
#    parser-11.*: parser input from filename
#    parser-12.*: parser currentmarkup
#
# Copyright (c) 1999-2000 Zveno Pty Ltd.
# Copyright (c) 2002-2015 Rolf Ade
#
# $Id$

source [file join [file dir [info script]] loadtdom.tcl]

proc parray arrayName {
    upvar #0 $arrayName arr
................................................................................
	    }
	    break {
		return -code break
	    }
	    error {
		return -code error "error condition in callback"
	    }
            return {
                return -code return
            }
	    default {
		return -code $atts(class) 
	    }
	}
    }
}
catch {unset ended}
................................................................................
    set ::esh_1_13_2 0
    catch {rename parser-1.13 {}}
    set p [expat parser-1.13 -elementstartcommand esh_1_13_1]
    $p configure -elementstartcommand esh_1_13_2
    $p parse {<root><a/><b/></root>}
    list $::esh_1_13_1 $::esh_1_13_2
} {0 3}

test parser-1.14 {parser get} {
    catch {rename parser-1.14 {}}
    set parser [expat parser-1.14]
    set result [catch {$parser get}]
    $parser free
    set result
} {1}
test parser-1.15 {parser get} {
    catch {rename parser-1.15 {}}
    set parser [expat parser-1.15]
    set result [catch {$parser get foo bar}]
    $parser free
    set result
} {1}
test parser-1.16 {parser get} {
    catch {rename parser-1.16 {}}
    set parser [expat parser-1.16]
    set result [$parser get -currentbytecount]
    $parser free
    set result
} {0}

test parser-1.17 {parser delete} {
    expat parser-1.17
    parser-1.17 delete
} {}

# Test break return code from callback

test parser-2.1 {break in callback} {
    catch {unset ::started}

    catch {rename parser-2.1 {}}
................................................................................
    set p [::xml::parser parser-4.1 -elementstartcommand Start]
    set errcode [catch {$p parse {<?xml version="1.0"?>
<Test>
<Element>Should see this data</Element>
<Element class="error"/>
<Element>Should not see this data</Element>
</Test>
    }} result]
    list $errcode $::started(Element)
} {1 2}

test parser-4.2 {error in callback} {
    catch {unset ::started}

    catch {rename parser-4.2 {}}
................................................................................
    set result [catch {$parser parsechannel $fd}]
    close $fd
    set result
} -cleanup {
    removeFile parser.xml
} -result 1

proc elementstart-5.4 {args} {
    error "Error raised by elementstart-5.4"
}

test parser-5.4 {parse channel - error raised in handler} {
    catch {parser-5.4 free}
    ::xml::parser parser-5.4 -elementstartcommand elementstart-5.4
    set file [file join [pwd] [file dir [info script]] data/books.xml]
    catch {parser-5.4 parsefile $file} errMsg
    parser-5.4 free
    set errMsg
} "Error raised by elementstart-5.4"

test parser-6.1 {reuse parser} {
    catch {rename parser-6.1 {}}
    set parser [expat parser-6.1 -baseurl file:///foo/bar]
    set result [$parser cget -baseurl]
    $parser parse <data/>
    lappend result [$parser cget -baseurl]
    $parser configure -baseurl file:///bar/foo
................................................................................

test parser-8.1 {parser free called from within callback proc} {
    set parser [expat -elementstartcommand elementstart]
    set result [catch {$parser parse <root>foo</root>} errMsg]
    lappend result $errMsg
    $parser free
    set result
} {1 {parser delete not allowed from within callback}}

proc elementstart {args} {
    global parser

    $parser parse {<root>foo bar</root>}
}

test parser-9.1 {try to use the parser from within one of its callbacks} {
    set parser [expat -elementstartcommand elementstart]
    set result [catch {$parser parse <root>foo</root>} errMsg]
    lappend result $errMsg
    $parser free
    set result
} {1 {Parser already in use.}}

................................................................................
    $parser parse {<root>foo bar</root>}
}

proc elementstart {args} {
    calledFromElementstart
}

test parser-9.2 {try to use the parser from within one of its callbacks} {
    set parser [expat -elementstartcommand elementstart]
    set result [catch {$parser parse <root>foo</root>} errMsg]
    lappend result $errMsg
    $parser free
    set result
} {1 {Parser already in use.}}


test parser-10.1 {return -code return in callback} {
    catch {unset ::started}

    catch {rename parser-10.1 {}}
    set p [::xml::parser parser-10.1 -elementstartcommand Start]
    set errcode [catch {$p parse {<?xml version="1.0"?>
<Test>
<Element>Should see this data</Element>
<Element class="return"/>
<Element>Should not see this data</Element>
</Test>
}} result]
    list $errcode $::started(Element)
} {0 2}

test parser-10.2 {return -code return in callback} {
    catch {unset ::started}

    catch {rename parser-10.2 {}}
    set p [::xml::parser parser-10.2 -elementstartcommand Start]
    set errcode [catch {$p parse {<?xml version="1.0"?>
<Test>
<Element>Should see this data</Element>
<Element class="return"/>
<Element>Should not see this data</Element>
</Test>}} errMsg]
    set result [list $errcode $::started(Element)]
    $p reset
    catch {unset ::started}
    set errcode [catch {$p parse {<?xml version="1.0"?>
<Test>
<Element>Should see this data</Element>
<Element class="ok"/>
<Element>Should see this data</Element>
</Test>}} errMsg]
    lappend result $errcode $::started(Element)
} {0 2 0 3}

test parser-11.1 {parse parsefile} {
    catch {unset ::count}

    catch {rename parser-11.1 {}}
    set parser [::xml::parser parser-11.1 -elementstartcommand Count]
    set file [file join [pwd] [file dir [info script]] data/books.xml]
    $parser parsefile $file
    set ::count
} {42}

proc elementstart-11.2 {args} {
    error "Error raised by elementstart-11.2"
}

test parser-11.2 {parse parsefile - error raised in handler} {
    catch {parser-11.2 free}
    ::xml::parser parser-11.2 -elementstartcommand elementstart-11.2
    set file [file join [pwd] [file dir [info script]] data/books.xml]
    catch {parser-11.2 parsefile $file} errMsg
    parser-11.2 free
    set errMsg
} "Error raised by elementstart-11.2"

proc elementstart-12.1 {parser args} {
    global result
    append result [$parser currentmarkup]
}

proc elementend-12.1 {parser args} {
    global result
    append result [$parser currentmarkup]
}

test parser-12.1 {currentmarkup method} {
    catch {unset result}
    set result ""
    set p [expat parser-12.1 -noexpand]
    $p configure \
        -elementstartcommand [list elementstart-12.1 $p] \
        -elementendcommand [list elementend-12.1 $p]
    $p parse {<root rootatt="rootatt">text<a
        a_att1="a_att1"
        a_att2 = "a_att2"/><b>more text</b></root>}
    $p free
    set result
} {<root rootatt="rootatt"><a
        a_att1="a_att1"
        a_att2 = "a_att2"/><b></b></root>}

proc characterdata-12.2 {parser data} {
    global result
    append result [$parser currentmarkup]
}
test parser-12.2 {currentmarkup method} {
    catch {unset result}
    set result ""
    set p [expat parser-12.2]
    $p configure \
        -characterdatacommand [list characterdata-12.2 $p] 
    $p parse {<root rootatt="rootatt">text<a
        a_att1="a_att1"
        a_att2 = "a_att2"/><b>more text</b></root>}
    $p free
    set result
} {}

test parser-12.3 {currentmarkup method} {
    set p [expat parser-12.3]
    set result [$p currentmarkup]
    $p free
    set result
} {}

proc elementstart-12.4 {parser handlerset args} {
    global result
    append result "$handlerset: [$parser currentmarkup]\n"
}
proc elementend-12.4 {parser handlerset args} {
    global result
    append result "$handlerset: [$parser currentmarkup]\n"
}
test parser-12.4 {currentmarkup method - multiple handler set} {
    catch {unset result}
    set result ""
    set p [expat parser-12.4]
    $p configure \
        -elementstartcommand [list elementstart-12.4 $p default] \
        -elementendcommand [list elementend-12.4 $p default] \
        -handlerset "additional" \
        -elementstartcommand [list elementstart-12.4 $p "additional"] \
        -elementendcommand [list elementend-12.4 $p "additional"]
    $p parse {<root rootatt="rootatt">text<a
        a_att1="a_att1"
        a_att2 = "a_att2"/><b>more text</b></root>}
    $p free
    set result
} {default: <root rootatt="rootatt">
additional: <root rootatt="rootatt">
default: <a
        a_att1="a_att1"
        a_att2 = "a_att2"/>
additional: <a
        a_att1="a_att1"
        a_att2 = "a_att2"/>
default: 
additional: 
default: <b>
additional: <b>
default: </b>
additional: </b>
default: </root>
additional: </root>
}

proc elementstart-12.5 {parser args} {
    global result
    append result "[$parser currentmarkup]"
}
test parser-12.5 {currentmarkup method - empty element shortcut -elementstartcommand} {
    catch {unset result}
    set result ""
    set p [expat parser-12.5]
    $p configure \
        -elementstartcommand [list elementstart-12.5 $p] 
    $p parse {<root><elem/></root>}
    $p free
    set result
} {<root><elem/>}

proc elementend-12.6 {parser args} {
    global result
    if {[$parser currentmarkup] eq ""} {
        append result "<elementend called, but currentmarkup return empty string>"
    }
    append result "[$parser currentmarkup]"
}
test parser-12.6 {currentmarkup method - empty element shortcut -elementendcommand} {
    catch {unset result}
    set result ""
    set p [expat parser-12.6]
    $p configure \
        -elementendcommand [list elementend-12.6 $p] 
    $p parse {<root><elem/></root>}
    $p free
    set result
} {<elementend called, but currentmarkup return empty string></root>}
    
foreach parser [info commands xmlparser*] {
    $parser free
}
foreach parser [info commands parser-*] {
    $parser free
}

proc elementdeclcommand-12.7 {parser args} {
    global result
    append result "elementdeclcommand: [$parser currentmarkup]"
}

proc entitydeclcommand-12.7 {parser args} {
    global result
    append result "entitydeclcommand: [$parser currentmarkup]"
}

test parser-12.7 {currentmarkup method - not for doctype markup handler} {
    catch {unset result}
    set result ""
    set p [expat parser-12.7]
    $p configure \
        -elementdeclcommand [list elementdeclcommand-12.7 $p] \
        -entitydeclcommand [list entitydeclcommand-12.7 $p]
    $p parse {<!DOCTYPE test [
<!ELEMENT test (#PCDATA) >
<!ENTITY % xx '&#37;zz;'>
<!ENTITY % zz '&#60;!ENTITY tricky "error-prone" >' >
%xx;
]>
<test>This sample shows a &tricky; method.</test>}
    $p free
    set result
} {elementdeclcommand: entitydeclcommand: entitydeclcommand: }

proc pi-12.8 {parser args} {
    global result
    append result "pi: [$parser currentmarkup]"
}
test parser-12.8 {currentmarkup method - processing instruction} {
    catch {unset result}
    set result ""
    set p [expat parser-12.8]
    $p configure \
        -processinginstructioncommand [list pi-12.8 $p]
    $p parse {<doc><?xml-stylesheet type="text/xsl" href="style.xsl"?></doc>}
    $p free
    set result
} {pi: <?xml-stylesheet type="text/xsl" href="style.xsl"?>}

proc comment-12.9 {parser args} {
    global result
    append result "comment: [$parser currentmarkup]"
}
test parser-12.9 {currentmarkup method - comment} {
    catch {unset result}
    set result ""
    set p [expat parser-12.9]
    $p configure \
        -commentcommand [list comment-12.9 $p]
    $p parse {<doc><!-- A comment --></doc>}
    $p free
    set result
} {comment: <!-- A comment -->}


# cleanup
::tcltest::cleanupTests
return

Changes to tests/pcdata.test.

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    $parser parse {<?xml version="1.0"?>
<!DOCTYPE Test>
<Test>This is &lt;PCDATA&gt;</Test>
}
    list $::result $::pcdataCounter
} {{This is <PCDATA>} 1}

test pcdata-1.3 {keep all PCDATA for not white space only PCDATA content} {
    set ::result {}

    catch {rename xml::pcdata-1.4 {}}
    set parser [xml::parser xml::pcdata-1.4 \
                    -characterdatacommand pcdata \
                    -ignorewhitecdata 1]
    $parser parse {<root>







|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    $parser parse {<?xml version="1.0"?>
<!DOCTYPE Test>
<Test>This is &lt;PCDATA&gt;</Test>
}
    list $::result $::pcdataCounter
} {{This is <PCDATA>} 1}

test pcdata-1.4 {keep all PCDATA for not white space only PCDATA content} {
    set ::result {}

    catch {rename xml::pcdata-1.4 {}}
    set parser [xml::parser xml::pcdata-1.4 \
                    -characterdatacommand pcdata \
                    -ignorewhitecdata 1]
    $parser parse {<root>

Changes to tests/pi.test.

14
15
16
17
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62
63
64
proc PI {target data args} {
    lappend ::result $target $data
}

test pi-1.1 {PI} {
    set ::result {}

    catch {rename xml::pi-1.1 {}}
    set parser [xml::parser pi-1.1 \
	-processinginstructioncommand PI]
    $parser parse {<?xml version="1.0"?>
<!DOCTYPE Test>
<Test><?Test This is a processing instruction?></Test>
}

    set ::result
} {Test {This is a processing instruction}}

test pi-1.2 {PI: missing trailing ?} {
    set ::result {}

    catch {rename xml::pi-1.2 {}}
    set parser [xml::parser pi-1.2 \
	-processinginstructioncommand PI]
    set returncode [catch {$parser parse {<?xml version="1.0"?>
<!DOCTYPE Test>
<Test><?Test This is a syntax error></Test>
}} msg]

    list $returncode [regexp {error "unclosed token" at.+} $msg]
} {1 1}

test pi-2.1 {PI with special characters} {
    set ::result {}

    catch {rename xml::pi-2.1 {}}
    set parser [xml::parser pi-2.1 \
	-processinginstructioncommand PI]
    $parser parse {<?xml version="1.0"?>
<!DOCTYPE Test>
<Test><?Test [if !VMLRender]?></Test>
}

    set ::result
} {Test {[if !VMLRender]}}

foreach parser [info commands pi-*] {
    $parser free
}

# cleanup
::tcltest::cleanupTests
return







<






>






<






|






<






>



<
<
<
<



14
15
16
17
18
19
20

21
22
23
24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56




57
58
59
proc PI {target data args} {
    lappend ::result $target $data
}

test pi-1.1 {PI} {
    set ::result {}


    set parser [xml::parser pi-1.1 \
	-processinginstructioncommand PI]
    $parser parse {<?xml version="1.0"?>
<!DOCTYPE Test>
<Test><?Test This is a processing instruction?></Test>
}
    $parser free
    set ::result
} {Test {This is a processing instruction}}

test pi-1.2 {PI: missing trailing ?} {
    set ::result {}


    set parser [xml::parser pi-1.2 \
	-processinginstructioncommand PI]
    set returncode [catch {$parser parse {<?xml version="1.0"?>
<!DOCTYPE Test>
<Test><?Test This is a syntax error></Test>
}} msg]
    $parser free
    list $returncode [regexp {error "unclosed token" at.+} $msg]
} {1 1}

test pi-2.1 {PI with special characters} {
    set ::result {}


    set parser [xml::parser pi-2.1 \
	-processinginstructioncommand PI]
    $parser parse {<?xml version="1.0"?>
<!DOCTYPE Test>
<Test><?Test [if !VMLRender]?></Test>
}
    $parser free
    set ::result
} {Test {[if !VMLRender]}}





# cleanup
::tcltest::cleanupTests
return

Added tests/pullparser.test.







































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
# Features covered: Pull parser
#
# This file contains a collection of tests for the pull parser
# interface.
# Tested functionalities:
#    pp-1.*: Basics, interface
#    pp-2.*: Compare dom / pull parsing
#    pp-3.*: skip method
#    pp-4.*: find-element method
#    pp-5.*: CDATA section handling
#    pp-6.*: line/column methods
#
# Copyright (c) 2017-2018 Rolf Ade.

source [file join [file dir [info script]] loadtdom.tcl]

test pp-1.1 {Create} {
    tdom::pullparser pp
    pp delete
} {}

test pp-1.2 {Invalid create} {
    catch {tdom::pullparser pp foo}
} 1

test pp-1.3 {Reset freshly created parser} {
    tdom::pullparser pp
    pp reset
    pp reset
    pp delete
} {}

test pp-1.4 {State after creation} {
    tdom::pullparser pp
    set result [pp state]
    lappend result [pp state]
    pp delete
    set result
} {READY READY}

proc walkDOM {node} {
    set str ""
    switch [$node nodeType] {
        "ELEMENT_NODE" {
            append str [$node nodeName]
            # Because the dom builder arranges attributes so that the
            # xmlns attributes come first we need to ensure a unify
            # attribute order for comparsion.
            set attpairs [list]
            foreach att [$node attributes] {
                if {[llength $att] == 3} {
                    if {[lindex $att 2] eq ""} {
                        lappend attpairs [list \
                            xmlns:[lindex $att 0] \
                            [$node getAttribute xmlns:[lindex $att 0]]]
                    } else {
                        lappend attpairs [list \
                            [lindex $att 1]:[lindex $att 0] \
                            [$node getAttribute [lindex $att 1]:[lindex $att 0]]]
                    }
                } else {
                    lappend attpairs [list $att [$node getAttribute $att]]
                }
            }
            foreach {name value} [lsort -index 0 $attpairs] {
                append str $name $value
            }
            foreach child [$node childNodes] {
                append str [walkDOM $child]
            }
            append str /[$node nodeName]
        }
        "TEXT_NODE" {
            append str [$node nodeValue]
        }
        default {
            # Ignore anything else
        }
    }
    return $str
}

proc loopPull {} {
    while {[set state [pp next]] ne "END_DOCUMENT"} {
        switch $state {
            "START_TAG" {
                append pullstr [pp tag]
                set attpairs [list]
                foreach {attname attvalue} [pp attributes] {
                    lappend attpairs [list $attname $attvalue]
                }
                foreach {name value} [lsort -index 0 $attpairs] {
                    append pullstr $name $value
                }
            }
            "TEXT" {
                append pullstr [pp text]
            }
            "END_TAG" {
                append pullstr /[pp tag]
            }
        }
    }
    return $pullstr
}

proc comparewithDOM {data {inputMethod input}} {
    if {$inputMethod eq "input"} {
        dom parse $data doc
    } elseif {$inputMethod eq "inputchannel"} {
        dom parse -channel $data doc
    } else {
        dom parse -keepEmpties [::tdom::xmlReadFile $data] doc
    }
    set domstr [walkDOM [$doc documentElement]]
    $doc delete
    tdom::pullparser pp
    pp $inputMethod $data
    set pullstr [loopPull]
    if {$domstr eq $pullstr} {
        return 1
    } else {
        puts "*** DOM str:"
        puts $domstr
        puts "*** Pull str:"
        puts $pullstr
        return 0
    }
    pp delete
}

proc fdata {file} {
    file join [file dir [info script]] data/$file
}

test pp-2.1 {dom/pull comparsion: mondial-europe.xml} {
    comparewithDOM [fdata mondial-europe.xml] inputfile
} 1

test pp-2.2 {dom/pull comparsion: books.xml} {
    comparewithDOM [fdata books.xml] inputfile
} 1

test pp-2.3 {dom/pull comparsion: i18n_1.xml} {
    comparewithDOM [fdata i18n_1.xml] inputfile
} 1

test pp-2.4 {dom/pull comparsion: i18n_2.xml} {
    comparewithDOM [fdata i18n_2.xml] inputfile
} 1

test pp-2.5 {dom/pull comparsion: REC-xslt-19991116.xml} {
    comparewithDOM [fdata REC-xslt-19991116.xml] inputfile
} 1

test pp-2.6 {dom/pull comparsion: xslt_1.xsl} {
    comparewithDOM [fdata xslt_1.xsl] inputfile
} 1

test pp-2.7 {dom/pull comparsion} {
    comparewithDOM {<p>This specification defines the syntax and semantics of XSLT, which
is a language for transforming XML documents into other XML
        documents.</p>}
} 1

test pp-2.8 {dom/pull comparsion} {
    comparewithDOM {<p><termdef> (see <specref/>), which is
referred to in </termdef></p>}
} 1

test pp-2.9 {dom/pull comparsion} {
    comparewithDOM {<p>This specification defines the syntax and semantics of the XSLT
language.  A transformation in the XSLT language is expressed as a
well-formed XML document <bibref/>conforming </p>}
} 1


proc loopPullE {} {
    while {[set state [pullparser next]] ne "END_DOCUMENT"} {
        switch $state {
            "START_TAG" {
                append pullstr [pullparser tag]
                foreach {attname attvalue} [pullparser attributes] {
                    append pullstr $attname $attvalue
                }
            }
            "TEXT" {
                append pullstr [pullparser text]
            }
            "END_TAG" {
                append pullstr /[pullparser tag]
            }
        }
    }
    return $pullstr
}

proc elementstart {name atts} {
    global expatstr

    append expatstr $name
    foreach {attname attvalue} $atts {
        append expatstr $attname $attvalue
    }
}

proc elementend {name} {
    global expatstr

    append expatstr /$name
}

proc cdata {cdata} {
    global expatstr

    append expatstr $cdata
}

proc comparewithExpat {data {inputMethod ""}} {
    global expatstr

    set expatstr ""
    expat pushparser \
        -elementstartcommand elementstart \
        -elementendcommand elementend \
        -characterdatacommand cdata
    pushparser parse$inputMethod $data
    tdom::pullparser pullparser
    pullparser input$inputMethod $data
    set pullstr [loopPullE]
    if {$expatstr eq $pullstr} {
        return 1
    } else {
        puts $expatstr
        puts $pullstr
        return 0
    }
    pushparser free
    pullparser delete
}


test pp-2.10 {expat/pull comparsion: mondial-europe.xml} {
    comparewithExpat [fdata mondial-europe.xml] file
} 1

test pp-2.11 {expat/pull comparsion: books.xml} {
    comparewithExpat [fdata books.xml] file
} 1

test pp-2.12 {expat/pull comparsion: i18n_1.xml} {
    comparewithExpat [fdata i18n_1.xml] file
} 1

test pp-2.13 {expat/pull comparsion: i18n_2.xml} {
    comparewithExpat [fdata i18n_2.xml] file
} 1

test pp-2.14 {expat/pull comparsion: REC-xslt-19991116.xml} {
    comparewithExpat [fdata REC-xslt-19991116.xml] file
} 1

test pp-2.15 {expat/pull comparsion: xslt_1.xsl} {
    comparewithExpat [fdata xslt_1.xsl] file
} 1

test pp-2.16 {expat/pull comparsion} {
    comparewithExpat {<p>This specification defines the syntax and semantics of XSLT, which
is a language for transforming XML documents into other XML
        documents.</p>}
} 1

test pp-2.17 {expat/pull comparsion} {
    comparewithExpat {<p><termdef> (see <specref/>), which is
referred to in </termdef></p>}
} 1

test pp-2.18 {expat/pull comparsion} {
    comparewithExpat {<p>This specification defines the syntax and semantics of the XSLT
language.  A transformation in the XSLT language is expressed as a
well-formed XML document <bibref/>conforming </p>}
} 1

test pp-3.1 {skip} {
    tdom::pullparser pp
    pp input <doc/>
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp skip]
    lappend result [pp tag]
    lappend result [pp next]
    pp delete
    set result
} {START_TAG doc END_TAG doc END_DOCUMENT}

test pp-3.1.1 {skip} {
    tdom::pullparser pp
    pp input {<doc><e/></doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp skip]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    pp delete
    set result
} {START_TAG doc START_TAG e END_TAG e END_TAG doc END_DOCUMENT}

test pp-3.1.2 {skip} {
    tdom::pullparser pp
    pp input {<doc>text<e/>text</doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp skip]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    pp delete
    set result
} {START_TAG doc TEXT text START_TAG e END_TAG e TEXT text END_TAG doc END_DOCUMENT}

test pp-3.1.3 {skip} {
    tdom::pullparser pp
    pp input {<doc>text<e>bar<b><c/><c>baz</c></b><b>text</b></e>text</doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp skip]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    pp delete
    set result
} {START_TAG doc TEXT text START_TAG e END_TAG e TEXT text END_TAG doc END_DOCUMENT}

test pp-3.1.4 {skip} {
    tdom::pullparser pp
    pp input <doc></doc>
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp skip]
    lappend result [pp tag]
    lappend result [pp next]
    pp delete
    set result
} {START_TAG doc END_TAG doc END_DOCUMENT}

test pp-3.1.5 {skip} {
    tdom::pullparser pp
    pp input {<doc> </doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp skip]
    lappend result [pp tag]
    lappend result [pp next]
    pp delete
    set result
} {START_TAG doc END_TAG doc END_DOCUMENT}

test pp-3.1.5 {skip} {
    tdom::pullparser pp -ignorewhitecdata
    pp input {<doc> </doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp skip]
    lappend result [pp tag]
    lappend result [pp next]
    pp delete
    set result
} {START_TAG doc END_TAG doc END_DOCUMENT}

test pp-3.2 {skip} {
    tdom::pullparser pp
    pp input {<doc><e/></doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp skip]
    lappend result [pp tag]
    lappend result [pp next]
    pp delete
    set result
} {START_TAG doc END_TAG doc END_DOCUMENT}

test pp-3.3 {skip} {
    tdom::pullparser pp
    pp input {<doc>foo bar<e/></doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp skip]
    lappend result [pp tag]
    lappend result [pp next]
    pp delete
    set result
} {START_TAG doc END_TAG doc END_DOCUMENT}

test pp-3.4 {skip} {
    tdom::pullparser pp
    pp input {<doc>foo bar<e/><e>bar<e/></e><e></e></doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp skip]
    lappend result [pp tag]
    lappend result [pp next]
    pp delete
    set result
} {START_TAG doc END_TAG doc END_DOCUMENT}

test pp-3.5 {skip} {
    tdom::pullparser pp
    pp input {<doc>foo bar<e/><e>bar<e/></e><e></e></doc>}
    set result [list]
    while {[set state [pp next]] ne "END_DOCUMENT"} {
        lappend result $state
        if {$state eq "START_TAG"} {
            lappend result [pp tag]
            if {[pp tag] eq "e"} {
                pp skip
                continue
            }
        }
        if {[pp state] eq "END_TAG"} {
            lappend result [pp tag]
        }
    }
    pp delete
    set result
} {START_TAG doc TEXT START_TAG e START_TAG e START_TAG e END_TAG doc}

test pp-3.6 {skip} {
    tdom::pullparser pp
    pp input {<doc>foo bar<e/><e>bar<e/></e><e></e>baz</doc>}
    set result [list]
    while {[set state [pp next]] ne "END_DOCUMENT"} {
        lappend result $state
        if {$state eq "START_TAG"} {
            lappend result [pp tag]
            if {[pp tag] eq "e"} {
                pp skip
                continue
            }
        }
        if {[pp state] eq "END_TAG"} {
            lappend result [pp tag]
        }
        if {[pp state] eq "TEXT"} {
            lappend result [pp text]
        }
    }
    pp delete
    set result
} {START_TAG doc TEXT {foo bar} START_TAG e START_TAG e START_TAG e TEXT baz END_TAG doc}

test pp-3.7 {skip} {
    tdom::pullparser pp
    pp input {<doc>foo bar<e/><e>bar</wrong><e></e></doc>}
    set result [pp next]
    lappend result [pp next]; # TEXT "foo bar"
    lappend result [pp next]; # START_TAG
    lappend result [pp tag];  # e
    lappend result [pp next]; # END_TAG
    lappend result [pp tag];  # e
    lappend result [pp next]; # START_TAG
    lappend result [pp tag];  # e
    lappend result [catch {pp skip} errMsg]
    lappend result $errMsg
    pp delete
    set result
} {START_TAG TEXT START_TAG e END_TAG e START_TAG e 1 {error "mismatched tag" at line 1 character 24}}

test pp-3.8 {skip} {
    tdom::pullparser pp
    pp input {<doc>foo bar<e/><e>bar</e></doc>}
    set result [pp next]
    lappend result [pp skip]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [catch {pp next} errMsg]
    lappend result $errMsg
    pp delete
    set result
} {START_TAG END_TAG doc END_DOCUMENT 1 {No next event after END_DOCUMENT}}

test pp-4.1 {find-element} {
    tdom::pullparser pp
    pp input {<doc><a>foo bar</a><b>baz</b><c>grill</c><d>here</d></doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp find-element d]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]    
    while {[pp next] ne "END_DOCUMENT"} {}
    pp delete
    set result
} {START_TAG doc START_TAG a START_TAG d TEXT here END_TAG d}

test pp-4.2 {find-element} {
    tdom::pullparser pp
    pp input {<doc><a>foo bar</a><b>baz</b><c>grill</c><d></d></doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp find-element d]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]    
    while {[pp next] ne "END_DOCUMENT"} {}
    pp delete
    set result
} {START_TAG doc START_TAG a START_TAG d END_TAG d}

test pp-4.3 {find-element} {
    tdom::pullparser pp
    pp input {<doc><a>foo bar</a><b>baz</b><c>grill</c>some<d/></doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp find-element d]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]    
    while {[pp next] ne "END_DOCUMENT"} {}
    pp delete
    set result
} {START_TAG doc START_TAG a START_TAG d END_TAG d}

test pp-4.4 {find-element} {
    tdom::pullparser pp
    pp input {<doc><a><b><c><d>grill</d></c></b></a></doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp find-element d]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]    
    lappend result [pp next]
    lappend result [pp tag]    
    while {[pp next] ne "END_DOCUMENT"} {}
    pp delete
    set result
} {START_TAG doc START_TAG d TEXT grill END_TAG d END_TAG c}

test pp-4.5 {find-element} {
    tdom::pullparser pp
    pp input {<doc><a><b><c><d></d></c></b></a></doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp find-element d]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]    
    lappend result [pp next]
    lappend result [pp tag]    
    while {[pp next] ne "END_DOCUMENT"} {}
    pp delete
    set result
} {START_TAG doc START_TAG d END_TAG d END_TAG c}

test pp-4.6 {find-element} {
    tdom::pullparser pp
    pp input {<doc><a><b><c><d/></c></b></a></doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp find-element d]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]    
    lappend result [pp next]
    lappend result [pp tag]    
    while {[pp next] ne "END_DOCUMENT"} {}
    pp delete
    set result
} {START_TAG doc START_TAG d END_TAG d END_TAG c}


test pp-4.7 {find-element} {
    tdom::pullparser pp
    pp input {<doc><a><b/></a><a><b><c/></b></a><a><b/></a></doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp find-element b]
    lappend result [pp tag]
    lappend result [pp find-element c]
    lappend result [pp tag]
    lappend result [pp find-element a]
    lappend result [pp tag]
    while {[pp next] ne "END_DOCUMENT"} {}
    pp delete
    set result
} {START_TAG doc START_TAG b START_TAG c START_TAG a}

test pp-4.8 {find-element} {
    tdom::pullparser pp
    pp input {<doc/>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp find-element b]
    pp delete
    set result
} {START_TAG doc END_TAG doc END_DOCUMENT}

test pp-4.8.1 {find-element} {
    tdom::pullparser pp
    pp input {<doc></doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp find-element b]
    pp delete
    set result
} {START_TAG doc END_TAG doc END_DOCUMENT}

test pp-4.8.2 {find-element} {
    tdom::pullparser pp
    pp input {<doc> </doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp find-element b]
    pp delete
    set result
} {START_TAG doc TEXT END_TAG doc END_DOCUMENT}

test pp-4.8.3 {find-element} {
    tdom::pullparser pp -ignorewhitecdata
    pp input {<doc> </doc>}
    set result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp find-element b]
    pp delete
    set result
} {START_TAG doc END_TAG doc END_DOCUMENT}

test pp-4.9 {find-element} {
    tdom::pullparser pp
    pp input {<doc><a><b/></a><a><b><c/></b></a><a><b/></a></doc>}
    set result [pp next]; # START_TAG
    lappend result [pp tag]; # doc
    lappend result [pp next]; # START_TAG
    lappend result [pp tag]; # a
    lappend result [pp find-element b]; # START_TAG
    lappend result [pp tag]; #b 
    lappend result [pp find-element c]; # START_TAG
    lappend result [pp tag]; #c
    lappend result [pp next]; # END_TAG
    lappend result [pp tag]; # c
    lappend result [pp find-element a]; # START_TAG
    lappend result [pp tag]; # a
    while {[pp next] ne "END_DOCUMENT"} {}
    pp delete
    set result
} {START_TAG doc START_TAG a START_TAG b START_TAG c END_TAG c START_TAG a}

test pp-4.10 {find-element} {
    tdom::pullparser pp
    pp input {<doc>foo<a/>bar<b>grill<a/>baz</b></doc>}
    set result [pp next]; # START_TAG
    lappend result [pp tag]; # doc
    lappend result [pp find-element a]; # START_TAG
    lappend result [pp tag]; # a
    lappend result [pp next]; # END_TAG
    lappend result [pp tag]; # a
    lappend result [pp find-element a]; # START_TAG
    lappend result [pp tag]; #a 
    lappend result [pp next]; # END_TAG
    lappend result [pp tag]; # a 
    lappend result [pp next]; # TEXT 
    lappend result [pp text]; # baz 
    lappend result [pp next]; # END_TAG 
    lappend result [pp tag]; # b
    while {[pp next] ne "END_DOCUMENT"} {}
    pp delete
    set result
} {START_TAG doc START_TAG a END_TAG a START_TAG a END_TAG a TEXT baz END_TAG b}

test pp-4.11 {find-element} {
    tdom::pullparser pp
    pp input {<doc>foo<a/>bar<b>grill<a/>baz</b></doc>}
    set result [pp state]
    lappend result [pp find-element a]; # START_TAG
    lappend result [pp tag]; # a
    lappend result [pp next]; # END_TAG
    lappend result [pp tag]; # a
    lappend result [pp find-element a]; # START_TAG
    lappend result [pp tag]; #a 
    lappend result [pp next]; # END_TAG
    lappend result [pp tag]; # a 
    lappend result [pp next]; # TEXT 
    lappend result [pp text]; # baz 
    lappend result [pp next]; # END_TAG 
    lappend result [pp tag]; # b
    while {[pp next] ne "END_DOCUMENT"} {}
    pp delete
    set result
} {START_DOCUMENT START_TAG a END_TAG a START_TAG a END_TAG a TEXT baz END_TAG b}

test pp-4.12 {find-element} {
    tdom::pullparser pp
    pp input {<doc>foo<a/>bar<b>grill<a/>baz</b></doc>}
    set result [pp state]
    pp find-element a
    lappend result [pp find-element a]; # START_TAG
    lappend result [pp tag]; #a 
    lappend result [pp next]; # END_TAG
    lappend result [pp tag]; # a 
    lappend result [pp next]; # TEXT 
    lappend result [pp text]; # baz 
    lappend result [pp next]; # END_TAG 
    lappend result [pp tag]; # b
    while {[pp next] ne "END_DOCUMENT"} {}
    pp delete
    set result
} {START_DOCUMENT START_TAG a END_TAG a TEXT baz END_TAG b}

test pp-4.13 {find-element} {
    tdom::pullparser pp
    pp input {<doc/>}
    set result [pp state]
    lappend result [pp find-element a]
    pp delete
    set result
} {START_DOCUMENT END_DOCUMENT}    

test pp-4.14 {find-element} {
    tdom::pullparser pp
    pp input {<doc>foo bar<e/><e>bar</e></doc>}
    set result [pp next]
    lappend result [pp skip]
    lappend result [pp tag]
    lappend result [pp find-element b]
    lappend result [catch {pp next} errMsg]
    lappend result $errMsg
    pp delete
    set result
} {START_TAG END_TAG doc END_DOCUMENT 1 {No next event after END_DOCUMENT}}
    
test pp-5.1 {CDATA section} {
    tdom::pullparser pp
    pp input {<doc><![CDATA[ some text  ]]></doc>}
    set result [pp state]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    
    pp delete
    set result
} {START_DOCUMENT START_TAG doc TEXT { some text  } END_TAG doc END_DOCUMENT}

test pp-5.2 {CDATA section inside of text} {
    tdom::pullparser pp
    pp input {<doc>before<![CDATA[ some text  ]]>after</doc>}
    set result [pp state]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    
    pp delete
    set result
} {START_DOCUMENT START_TAG doc TEXT {before some text  after} END_TAG doc END_DOCUMENT}

test pp-5.3 {CDATA section after text} {
    tdom::pullparser pp
    pp input {<doc>before<![CDATA[ some text  ]]></doc>}
    set result [pp state]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    
    pp delete
    set result
} {START_DOCUMENT START_TAG doc TEXT {before some text  } END_TAG doc END_DOCUMENT}

test pp-5.4 {CDATA section before text} {
    tdom::pullparser pp
    pp input {<doc><![CDATA[ some text  ]]>after</doc>}
    set result [pp state]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    
    pp delete
    set result
} {START_DOCUMENT START_TAG doc TEXT { some text  after} END_TAG doc END_DOCUMENT}

test pp-5.5 {White space only CDATA section inside text} {
    tdom::pullparser pp
    pp input {<doc>before <![CDATA[  ]]> after</doc>}
    set result [pp state]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    
    pp delete
    set result
} {START_DOCUMENT START_TAG doc TEXT {before    after} END_TAG doc END_DOCUMENT}

test pp-5.6 {White space only CDATA section inside text with -ignorewhitecdata} {
    tdom::pullparser pp -ignorewhitecdata
    pp input {<doc>before <![CDATA[  ]]> after</doc>}
    set result [pp state]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    
    pp delete
    set result
} {START_DOCUMENT START_TAG doc TEXT {before    after} END_TAG doc END_DOCUMENT}

test pp-5.6 {White space only CDATA section inside text with -ignorewhitecdata} {
    tdom::pullparser pp -ignorewhitecdata
    pp input {<doc>before <![CDATA[  ]]> after</doc>}
    set result [pp state]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    
    pp delete
    set result
} {START_DOCUMENT START_TAG doc TEXT {before    after} END_TAG doc END_DOCUMENT}

test pp-5.7 {White space only CDATA section inside white space only text w/ -ignorewhitecdata} {
    tdom::pullparser pp -ignorewhitecdata
    pp input {<doc> <![CDATA[  ]]>
        </doc>}
    set result [pp state]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    
    pp delete
    set result
} {START_DOCUMENT START_TAG doc END_TAG doc END_DOCUMENT}

test pp-5.8 {White space only CDATA section before text w/ -ignorewhitecdata} {
    tdom::pullparser pp -ignorewhitecdata
    pp input {<doc> <![CDATA[  ]]> after</doc>}
    set result [pp state]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    
    pp delete
    set result
} {START_DOCUMENT START_TAG doc TEXT {    after} END_TAG doc END_DOCUMENT}

test pp-5.9 {Successive CDATA sections} {
    tdom::pullparser pp
    pp input {<doc> <![CDATA[one]]><![CDATA[two]]><![CDATA[  ]]> after</doc>}
    set result [pp state]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp next]
    
    pp delete
    set result
} {START_DOCUMENT START_TAG doc TEXT { onetwo   after} END_TAG doc END_DOCUMENT}

test pp-6.1 {line} {
    tdom::pullparser pp
    set result [catch {pp line}]
    pp input {<doc> <![CDATA[one]]><![CDATA[two]]><![CDATA[  ]]> after</doc>}
    lappend result [pp line]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp line]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp line]
    lappend result [pp next]
    lappend result [pp line]
    pp delete
    set result
} {1 0 START_TAG doc 1 TEXT { onetwo   after} END_TAG doc 1 END_DOCUMENT 1}

test pp-6.2 {column} {
    tdom::pullparser pp
    set result [catch {pp column}]
    pp input {<doc> <![CDATA[one]]><![CDATA[two]]><![CDATA[  ]]> after</doc>}
    lappend result [pp column]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp column]
    lappend result [pp next]
    lappend result [pp text]
    lappend result [pp next]
    lappend result [pp tag]
    lappend result [pp column]
    lappend result [pp next]
    lappend result [pp column]
    pp delete
    set result
} {1 0 START_TAG doc 5 TEXT { onetwo   after} END_TAG doc 62 END_DOCUMENT 62}

test pp-6.3 {column} {
    tdom::pullparser pp
    pp input {<doc>foo<b>bar</b>grill</doc>}
    set result [list]
    while {[pp next] ne "END_DOCUMENT"} {
        if {[pp state] eq "TEXT"} {
            lappend result [pp text]
        } else {
            lappend result [pp tag]
            lappend result [pp column]
        }
    }
    pp delete
    set result
} {doc 5 foo b 11 bar b 18 grill doc 29}

test pp-6.4 {line/column} {
    tdom::pullparser pp
    pp input {<doc>foo
<b>bar
</b>grill</doc>}
    set result [list]
    while {[pp next] ne "END_DOCUMENT"} {
        if {[pp state] eq "TEXT"} {
            lappend result [pp text]
        } else {
            lappend result [pp tag]
            lappend result [pp line]/[pp column]
        }
    }
    pp delete
    set result
} {doc 1/5 {foo
} b 2/3 {bar
} b 3/4 grill doc 3/15}

test pp-6.5 {column} {
    tdom::pullparser pp
    pp input {<doc att="attvalue">foo<b att="boo">bar</b>grill</doc>}
    set result [list]
    while {[pp next] ne "END_DOCUMENT"} {
        if {[pp state] eq "TEXT"} {
            lappend result [pp text]
        } else {
            lappend result [pp tag]
            lappend result [pp column]
        }
    }
    lappend result [pp column]
    pp delete
    set result
} {doc 20 foo b 36 bar b 43 grill doc 54 54}

test pp-6.6 {line/column after parsing error} {
    tdom::pullparser pp
    pp input {<doc>an
        < xml error </doc>}
    pp next
    set result [catch {pp skip}]
    lappend result [pp line]/[pp column]
    pp delete
    set result
} {1 2/9}

Added tests/pushpull.bench.







































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# -*- tcl -*-
#
# This file contains a number of benchmarks for push (expat) and pull
# (tdom::pullparser) parser.
#
# (c) 2018 Rolf Ade <rolf@pointsman.de>
#


# ### ### ### ######### ######### ######### ###########################
## Setting up the environment ...

package require tdom 

# ### ### ### ######### ######### ######### ###########################
## Benchmarks.


proc loopPullE {} {
    while {[set state [pullparser next]] ne "END_DOCUMENT"} {
        switch $state {
            "START_TAG" {
                append pullstr [pullparser tag]
                foreach {attname attvalue} [pullparser attributes] {
                    append pullstr $attname $attvalue
                }
            }
            "TEXT" {
                append pullstr [pullparser text]
            }
            "END_TAG" {
                append pullstr /[pullparser tag]
            }
        }
    }
    return $pullstr
}

expat pushparserCanonical \
    -elementstartcommand elementstart \
    -elementendcommand elementend \
    -characterdatacommand cdata


proc elementstart {name atts} {
    global expatstr

    append expatstr $name
    foreach {attname attvalue} $atts {
        append expatstr $attname $attvalue
    }
}

proc elementend {name} {
    global expatstr

    append expatstr /$name
}

proc cdata {cdata} {
    global expatstr

    append expatstr $cdata
}

expat pushparserTricky \
    -elementstartcommand elementstart \
    -elementendcommand elementend \
    -characterdatacommand cdata


proc dopull {} {
    while {[set state [pullparser next]] ne "END_DOCUMENT"} {
        switch $state {
            "START_TAG" {
                append pullstr [pullparser tag]
                foreach {attname attvalue} [pullparser attributes] {
                    append pullstr $attname $attvalue
                }
            }
            "TEXT" {
                append pullstr [pullparser text]
            }
            "END_TAG" {
                append pullstr /[pullparser tag]
            }
        }
    }
    return $pullstr
}
bench -desc "push/canonical mondial-europe.xml" -iters 5 -body {
    set expatstr ""
    pushparserCanonical parsefile ../tests/data/mondial-europe.xml
    pushparserCanonical reset
} -post {
    pushparserCanonical free
}

bench -desc "push/tricky mondial-europe.xml" -iters 5 -body {
    set expatstr ""
    pushparserTricky parsefile ../tests/data/mondial-europe.xml
    pushparserTricky reset
} -post {
    pushparserTricky free
}

tdom::pullparser pullparser

bench -desc "pull mondial-europe.xml" -iters 5 -body {
    pullparser inputfile ../tests/data/mondial-europe.xml
    dopull
    pullparser reset
} -post {
    pullparser delete
}

Changes to tests/stackedhdl.test.

29
30
31
32
33
34
35






























36
37
38
39
40
41
42
..
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
170
171
172
173
174
175
176




















































177
178
179
180
181
182
183
proc CDataHandler {data} {
    if {![info exists ::cdata]} {
        set ::cdata [string length $data]
    } else {
        incr ::cdata [string length $data]
    }
}































test stackedhdl-1.1 {two handlers for element start} {
    catch {unset ::count} 
    catch {unset ::charcount}
    set p [expat -elementstartcommand Count \
                 -handlerset charcount -elementstartcommand CharCount]
    $p parse {<root><a/><a></a></root>}
................................................................................
    $p configure -elementstartcommand Count -elementendcommand Count
    $p configure -handlerset charcount -elementstartcommand CharCount \
                 -elementendcommand CharCount
    $p parse {<root><a/><a></a></root>}
    list $::count $::charcount
} {6 12}

test stackedhdl-1.6 {two handlers for element start} {
    catch {unset ::count} 
    catch {unset ::charcount}
    set p [expat]
    $p configure -handlerset charcount -elementstartcommand CharCount \
                 -elementendcommand CharCount
    $p configure -elementstartcommand Count -elementendcommand Count
    $p parse {<root><a/><a></a></root>}
    list $::count $::charcount
} {6 12}

test stackedhdl-1.6 {two handlers for element start} {
    catch {unset ::count} 
    catch {unset ::charcount}
    set p [expat]
    $p configure -handlerset charcount -elementstartcommand CharCount \
                 -elementendcommand CharCount
    $p configure -elementstartcommand Count -elementendcommand Count
................................................................................
    $p free
    set root [$doc documentElement]
    set result [list $::count [llength [$root childNodes]]]
    $doc delete
    set result
} {3 2}





















































test stackedhdl-3.1 {don't request the DOM tree from a tdom enabled parser} {
    set p [expat]
    tdom $p enable
    $p parse {<root><a/><a>boo</a></root>}
    $p free
} {}








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<
<
<
<
<
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
...
110
111
112
113
114
115
116











117
118
119
120
121
122
123
...
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
proc CDataHandler {data} {
    if {![info exists ::cdata]} {
        set ::cdata [string length $data]
    } else {
        incr ::cdata [string length $data]
    }
}

catch {unset started}
proc Start {name atList} {
    array set atts $atList

    if {![info exists ::started($name)]} {
	set ::started($name) 1
    } else {
	incr ::started($name)
    }
    if {[info exists atts(class)]} {
	switch $atts(class) {
	    continue {
		return -code continue
	    }
	    break {
		return -code break
	    }
	    error {
		return -code error "error condition in callback"
	    }
            return {
                return -code return
            }
	    default {
		return -code $atts(class) 
	    }
	}
    }
}

test stackedhdl-1.1 {two handlers for element start} {
    catch {unset ::count} 
    catch {unset ::charcount}
    set p [expat -elementstartcommand Count \
                 -handlerset charcount -elementstartcommand CharCount]
    $p parse {<root><a/><a></a></root>}
................................................................................
    $p configure -elementstartcommand Count -elementendcommand Count
    $p configure -handlerset charcount -elementstartcommand CharCount \
                 -elementendcommand CharCount
    $p parse {<root><a/><a></a></root>}
    list $::count $::charcount
} {6 12}












test stackedhdl-1.6 {two handlers for element start} {
    catch {unset ::count} 
    catch {unset ::charcount}
    set p [expat]
    $p configure -handlerset charcount -elementstartcommand CharCount \
                 -elementendcommand CharCount
    $p configure -elementstartcommand Count -elementendcommand Count
................................................................................
    $p free
    set root [$doc documentElement]
    set result [list $::count [llength [$root childNodes]]]
    $doc delete
    set result
} {3 2}

test stackedhdl-2.3 {return -code return with tcl and C coded handler} -setup {
    catch {unset started}
} -body {
    set p [expat -elementstartcommand Start]
    tdom $p enable
    set resultcode [catch {$p parse {<doc><e/><e class="return"/><e/></doc>}}]
    set result [list $resultcode $::started(e) [[tdom $p getdoc] asXML -indent none]]
    $p free
    set result
} -result {0 2 {<doc><e/><e class="return"/></doc>}}

test stackedhdl-2.4 {return -code error with tcl and C coded handler} -setup {
    catch {unset started}
} -body {
    set p [expat -elementstartcommand Start]
    tdom $p enable
    set resultcode [catch {$p parse {<doc><e/><e class="error"/><e/></doc>}} msg]
    set result [list $resultcode $msg $::started(e) [[tdom $p getdoc] asXML -indent none]]
    $p free
    set result
} -result {1 {error condition in callback} 2 {<doc><e/><e class="error"/></doc>}}

test stackedhdl-2.5 {return -code return with tcl and C coded handler} -setup {
    catch {unset started}
} -body {
    set p [expat -elementstartcommand Start]
    tdom $p enable
    set resultcode [catch {$p parse {<doc><e/><e class="return"/><e/></doc>}}]
    set result [list $resultcode $::started(e) [[tdom $p getdoc] asXML -indent none]]
    $p reset
    catch {unset started}
    set resultcode [catch {$p parse {<doc><e/><e/><e/></doc>}}]
    lappend result $resultcode $::started(e) [[tdom $p getdoc] asXML -indent none]
    $p free
    set result
} -result {0 2 {<doc><e/><e class="return"/></doc>} 0 3 <doc><e/><e/><e/></doc>}

test stackedhdl-2.6 {return -code error with tcl and C coded handler} -setup {
    catch {unset started}
} -body {
    set p [expat -elementstartcommand Start]
    tdom $p enable
    set resultcode [catch {$p parse {<doc><e/><e class="error"/><e/></doc>}} msg]
    set result [list $resultcode $msg $::started(e) [[tdom $p getdoc] asXML -indent none]]
    $p reset
    catch {unset started}
    set resultcode [catch {$p parse {<doc><e/><e/><e/></doc>}}]
    lappend result $resultcode $::started(e) [[tdom $p getdoc] asXML -indent none]
    $p free
    set result
} -result {1 {error condition in callback} 2 {<doc><e/><e class="error"/></doc>} 0 3 <doc><e/><e/><e/></doc>}

test stackedhdl-3.1 {don't request the DOM tree from a tdom enabled parser} {
    set p [expat]
    tdom $p enable
    $p parse {<root><a/><a>boo</a></root>}
    $p free
} {}

Added tests/tdomcmd.bench.







































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# -*- tcl -*-
#
# This file contains benchmarks for DOM doc creation with dom and tdom
#
# (c) 2018 Rolf Ade <rolf@pointsman.de>
#


# ### ### ### ######### ######### ######### ###########################
## Setting up the environment ...

package require tdom 

# ### ### ### ######### ######### ######### ###########################
## Benchmarks.


bench -desc "dom mondial-europe.xml" -iters 20 -ipre {
    set fd [open ../tests/data/mondial-europe.xml]
} -body {
    set doc [dom parse -channel $fd]
} -ipost {
    close $fd
    $doc delete
}

bench -desc "tdom mondial-europe.xml" -iters 20 -ipre {
    set p [expat]
    tdom $p enable
} -body {
    $p parsefile ../tests/data/mondial-europe.xml
    set doc [tdom $p getdoc]
} -ipost {
    $doc delete
    $p free
}

bench -desc "tdom mondial-europe.xml / reuse parser" -iters 20 -pre {
    set p [expat]
    tdom $p enable
} -body {
    $p parsefile ../tests/data/mondial-europe.xml
    set doc [tdom $p getdoc]
} -ipost {
    $doc delete
    $p reset
} -post {
    $p free
}

bench -desc "dom REC-xslt-19991116.xml" -iters 20 -ipre {
    set fd [open ../tests/data/REC-xslt-19991116.xml]
} -body {
    set doc [dom parse -channel $fd]
} -ipost {
    close $fd
    $doc delete
}

bench -desc "tdom REC-xslt-19991116.xml" -iters 20 -ipre {
    set p [expat]
    tdom $p enable
} -body {
    $p parsefile ../tests/data/REC-xslt-19991116.xml
    set doc [tdom $p getdoc]
} -ipost {
    $doc delete
    $p free
}

bench -desc "tdom REC-xslt-19991116.xml / reuse parser" -iters 20 -pre {
    set p [expat]
    tdom $p enable
} -body {
    $p parsefile ../tests/data/REC-xslt-19991116.xml
    set doc [tdom $p getdoc]
} -ipost {
    $doc delete
    $p reset
} -post {
    $p free
}

if {![catch {package require tnc}]} {

    proc extresolver {base systemId publicId} {
        switch $publicId {
            "-//W3C//DTD Specification V2.0//EN" {
                set fd [open [file join [file dir [info script]] \
                                  data/xmlspec-v20.dtd]]
                set xmlspec [read $fd]
                close $fd
                return [list "string" "" $xmlspec]
            }
            default {
                puts stderr "Unexpected systemId '$systemId'"
                return ""
            }
        }
    }
    
    bench -desc "tdom REC-xslt-19991116.xml / tnc " -iters 20 -ipre {
        set p [expat -externalentitycommand extresolver \
                   -paramentityparsing always]
        tdom $p enable
        tnc $p enable
    } -body {
        $p parsefile ../tests/data/REC-xslt-19991116.xml
        set doc [tdom $p getdoc]
    } -ipost {
        $doc delete
        $p free
    }


    bench -desc "tdom REC-xslt-19991116.xml / tnc / reuse parse" -iters 20 -pre {
        set p [expat -externalentitycommand extresolver \
                   -paramentityparsing always]
        tdom $p enable
        tnc $p enable
    } -body {
        $p parsefile ../tests/data/REC-xslt-19991116.xml
        set doc [tdom $p getdoc]
    } -ipost {
        $doc delete
        $p reset
        $p configure -paramentityparsing always
    } -post {
        $p free
    }
}

Changes to tests/tdomcmd.test.

36
37
38
39
40
41
42



43
44
45
46
47
48
49
..
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
122
123
124
125
126
127
128
129



















130
131
132
133
                        incr x
                        set data [lindex $args $x]
                        set haveData 1
                    }
                    "-keepEmpties" {
                        tdom $::_main_parser keepEmpties 1
                    }



                    "-baseurl" {
                        incr x
                        $::_main_parser configure -baseurl [lindex $args $x]
                    }
                    "-externalentitycommand" {
                        incr x
                        $::_main_parser configure -externalentitycommand \
................................................................................
# source [file join [file dir [info script]] xslt.test]

rename dom {}
rename _dom dom

$_main_parser free

test tdomcmd-1.1 {no doc avaliable} {
    set parser [expat]
    tdom $parser enable
    set result [catch {tdom $parser getdoc} errMsg]
    $parser free
    lappend result $errMsg
} {1 {No DOM tree avaliable.}}

test tdomcmd-1.2 {request dom tree in the middle of parsing} {
    set parser [expat -final 0]
    tdom $parser enable
    $parser parse {<root>}
    set result [catch {tdom $parser getdoc} errMsg]
    lappend result $errMsg
................................................................................
    lappend result $errMsg
    $parser configure -final 1
    $parser parse {}
    lappend result [catch {set doc [tdom $parser getdoc]} errMsg]
    $doc delete
    $parser free
    set result
} {1 {No DOM tree avaliable.} 1 {No DOM tree avaliable.} 0}




















# cleanup
::tcltest::cleanupTests
return







>
>
>







 







|





|







 







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
...
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
...
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
                        incr x
                        set data [lindex $args $x]
                        set haveData 1
                    }
                    "-keepEmpties" {
                        tdom $::_main_parser keepEmpties 1
                    }
                    "-keepCDATA" {
                        tdom $::_main_parser keepCDATA 1
                    }
                    "-baseurl" {
                        incr x
                        $::_main_parser configure -baseurl [lindex $args $x]
                    }
                    "-externalentitycommand" {
                        incr x
                        $::_main_parser configure -externalentitycommand \
................................................................................
# source [file join [file dir [info script]] xslt.test]

rename dom {}
rename _dom dom

$_main_parser free

test tdomcmd-1.1 {no doc available} {
    set parser [expat]
    tdom $parser enable
    set result [catch {tdom $parser getdoc} errMsg]
    $parser free
    lappend result $errMsg
} {1 {No DOM tree available.}}

test tdomcmd-1.2 {request dom tree in the middle of parsing} {
    set parser [expat -final 0]
    tdom $parser enable
    $parser parse {<root>}
    set result [catch {tdom $parser getdoc} errMsg]
    lappend result $errMsg
................................................................................
    lappend result $errMsg
    $parser configure -final 1
    $parser parse {}
    lappend result [catch {set doc [tdom $parser getdoc]} errMsg]
    $doc delete
    $parser free
    set result
} {1 {No DOM tree available.} 1 {No DOM tree available.} 0}

proc es-tdomcmd-1.3 {parser name attlist} {
    tdom $parser enable
}

test tdomcmd-1.3 {Try to tdom enable a parser from its parsing callback} {
    set p [expat]
    $p configure -elementstartcommand [list es-tdomcmd-1.3 $p]
    set result [catch {$p parse {<x><y/></x>}}]
    $p free
    set result
} {1}
    
test tdomcmd-1.4 {keepCDATA} {
    set parser [expat]
    set result [catch {tdom $parser keepCDATA 1}]
    $parser free
    set result
} 1

# cleanup
::tcltest::cleanupTests
return

Changes to tests/xmlsimple.test.

84
85
86
87
88
89
90
91





























































































92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
} 1

test simple-1.11 {simple doesn't catch all not wellformed input} {
     catch {dom parse -simple {<xsl:transform 
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform
                    <http://www.w3.org/1999/XSL/Transform> "/>}}
} 0






























































































test simple-2.1 {XML build in entities} {
    set doc [dom parse -simple {<doc>&lt;&gt;&amp;&apos;&quot;</doc>}]
    set root [$doc documentElement]
    set result [$root text]
    $doc delete
    set result
} {<>&'"}

# emacs: "

test simple-2.2 {character entities} {
    set doc [dom parse -simple {<doc>&#65;&#x42;</doc>}]
    set root [$doc documentElement]
    set result [$root text]
    $doc delete








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







<







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
} 1

test simple-1.11 {simple doesn't catch all not wellformed input} {
     catch {dom parse -simple {<xsl:transform 
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform
                    <http://www.w3.org/1999/XSL/Transform> "/>}}
} 0

test simple-1.12 {CDATA section} {
    set doc [dom parse -simple {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}]
    set result [$doc selectNodes count(doc/node())]
    $doc delete
    set result
} 1

test simple-1.13 {CDATA section} {
    set doc [dom parse -simple {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}]
    set root [$doc documentElement]
    set result [list]
    foreach child [$root childNodes] {
        lappend result [$child nodeType]
    }
    $doc delete
    set result
} {TEXT_NODE}

test simple-1.14 {CDATA section} {
    set doc [dom parse -simple {<doc>&lt;foo &amp; &gt;<![CDATA[test of & <bad> format]]>&apos; bar &quot;</doc>}]
    set result [$doc selectNodes string(doc)]
    $doc delete
    set result
} {<foo & >test of & <bad> format' bar "}
# emacs: "

test simple-1.15 {-keepCDATA} {
    set doc [dom parse -simple -keepCDATA {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}]
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}

test simple-1.16 {-keepCDATA} {
    set doc [dom parse -simple -keepCDATA {<doc>foo <![CDATA[test of & <bad> format]]> bar </doc>}]
    set root [$doc documentElement]
    set result [list]
    foreach child [$root childNodes] {
        lappend result [$child nodeType]
    }
    $doc delete
    set result
} {TEXT_NODE CDATA_SECTION_NODE TEXT_NODE}

test simple-1.17 {-keepCDATA} {
    set doc [dom parse -simple -keepCDATA {<doc><e><![CDATA[one]]></e></doc>}]
    set result [list]
    foreach child [$doc selectNodes doc/e/node()] {
        lappend result [$child nodeType]
    }
    $doc delete
    set result
} {CDATA_SECTION_NODE}

test simple-1.18 {-keepCDATA} {
    set doc [dom parse -simple -keepCDATA {<doc><e><![CDATA[one]]><![CDATA[two]]></e></doc>}]
    set result [list]
    foreach child [$doc selectNodes doc/e/node()] {
        lappend result [$child nodeType]
    }
    $doc delete
    set result
} {CDATA_SECTION_NODE CDATA_SECTION_NODE}

test simple-1.19 {-keepCDATA} {
    set doc [dom parse -simple -keepCDATA {<doc><e><![CDATA[]]></e></doc>}]
    set result [$doc selectNodes count(doc/e/node())]
    $doc delete
    set result
} 0

test simple-1.20 {-keepCDATA white space only CDATA section} {
    set doc [dom parse -simple -keepCDATA {<doc><e><![CDATA[
    ]]></e></doc>}]
    set result [$doc selectNodes count(doc/e/node())]
    $doc delete
    set result
} 0

test simple-1.21 {-keepCDATA and -keepEmpties} {
    set doc [dom parse -simple -keepCDATA -keepEmpties {<doc><e><![CDATA[]]></e></doc>}]
    set result [$doc selectNodes count(doc/e/node())]
    $doc delete
    set result
} 1

test simple-1.22 {namespaces} {
    set doc [dom parse -simple {
        <help><br xmlns:xsi="a"/><em xmlns:xsi="a">notes</em></help>
    }]
    $doc delete
} {}

test simple-2.1 {XML build in entities} {
    set doc [dom parse -simple {<doc>&lt;&gt;&amp;&apos;&quot;</doc>}]
    set root [$doc documentElement]
    set result [$root text]
    $doc delete
    set result
} {<>&'"}

# emacs: "

test simple-2.2 {character entities} {
    set doc [dom parse -simple {<doc>&#65;&#x42;</doc>}]
    set root [$doc documentElement]
    set result [$root text]
    $doc delete

Changes to tests/xpath.bench.

50
51
52
53
54
55
56


57











































































































































































bench -desc "path with predicate - cached" -pre {
    set doc [dom parse <root/>]
} -body {
    $doc selectNodes -cache 1 {/foo/bar/baz[not(grill) and @some='foo']}
}























































































































































































>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
bench -desc "path with predicate - cached" -pre {
    set doc [dom parse <root/>]
} -body {
    $doc selectNodes -cache 1 {/foo/bar/baz[not(grill) and @some='foo']}
}


namespace eval ::dom {
    namespace eval  xpathFunc {
    }
}

proc ::dom::xpathFunc::myfunc {args} {
    return "foo"
}

dom createNodeCmd elementNode e1

foreach nrOf {1 10 20 30 40 50 60} {

    bench -desc "Tcl scripted XPath func with $nrOf nodes in the current nodelist" -pre {
        dom createDocument root doc
        $doc documentElement root
        $root appendFromScript {
            for {set x 0} {$x < $nrOf} {incr x} {
                e1
            }
        }
    } -body {
        $root selectNodes {e1[myfunc() = '']}
    } -post {
        $doc delete
    }

}

dom createNodeCmd elementNode e2

dom createDocument root doc
$doc documentElement root
$root appendFromScript {
    e2
    for {set x 1} {$x < 1000} {incr x} {
        e1
    }
}

bench -desc "Select unique element between 1000, at first, with pred" -body {
    $root selectNodes -cache 1 {e2[1]}
} -post {
    $doc delete
}

bench -desc "Select unique element between 1000, at first, without pred" -pre {
    dom createDocument root doc
    $doc documentElement root
    $root appendFromScript {
        e2
        for {set x 1} {$x < 1000} {incr x} {
            e1
        }
    }
} -body {
    $root selectNodes -cache 1 {e2}
} -post {
    $doc delete
}

bench -desc "Select unique element between 1000, at first, with last() pred" -pre {
    dom createDocument root doc
    $doc documentElement root
    $root appendFromScript {
        e2
        for {set x 1} {$x < 1000} {incr x} {
            e1
        }
    }
} -body {
    $root selectNodes -cache 1 {e2[last()]}
} -post {
    $doc delete
}

bench -desc "Select unique element between 1000, at 500, with pred" -pre {
    dom createDocument root doc
    $doc documentElement root
    $root appendFromScript {
        for {set x 1} {$x < 500} {incr x} {
            e1
        }
        e2
        for {set x 501} {$x <= 1000} {incr x} {
            e1
        }
    }
} -body {
    $root selectNodes -cache 1 {e2[1]}
} -post {
    $doc delete
}

bench -desc "Select unique element between 1000, at 500, without pred" -pre {
    dom createDocument root doc
    $doc documentElement root
    $root appendFromScript {
        for {set x 1} {$x < 500} {incr x} {
            e1
        }
        e2
        for {set x 501} {$x <= 1000} {incr x} {
            e1
        }
    }
} -body {
    $root selectNodes -cache 1 {e2}
} -post {
    $doc delete
}

bench -desc "Select unique element between 1000, at 500, with last()" -pre {
    dom createDocument root doc
    $doc documentElement root
    $root appendFromScript {
        for {set x 1} {$x < 500} {incr x} {
            e1
        }
        e2
        for {set x 501} {$x <= 1000} {incr x} {
            e1
        }
    }
} -body {
    $root selectNodes -cache 1 {e2[last()]}
} -post {
    $doc delete
}

bench -desc "Select unique element between 1000, at 1000, with pred" -pre {
    dom createDocument root doc
    $doc documentElement root
    $root appendFromScript {
        for {set x 1} {$x < 1000} {incr x} {
            e1
        }
        e2
    }
} -body {
    $root selectNodes -cache 1 {e2[1]}
} -post {
    $doc delete
}

bench -desc "Select unique element between 1000, at 1000, without pred" -pre {
    dom createDocument root doc
    $doc documentElement root
    $root appendFromScript {
        for {set x 1} {$x < 1000} {incr x} {
            e1
        }
        e2
    }
} -body {
    $root selectNodes -cache 1 {e2}
} -post {
    $doc delete
}

bench -desc "Select unique element between 1000, at 1000, with last()" -pre {
    dom createDocument root doc
    $doc documentElement root
    $root appendFromScript {
        for {set x 1} {$x < 1000} {incr x} {
            e1
        }
        e2
    }
} -body {
    $root selectNodes -cache 1 {e2[last()]}
} -post {
    $doc delete
}

Changes to tests/xpath.test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
...
260
261
262
263
264
265
266


































267
268
269
270
271
272
273
...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
...
444
445
446
447
448
449
450
451
452
453

























































454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
...
715
716
717
718
719
720
721

















































































































































































































































































































































































722
723
724
725
726
727
728
...
798
799
800
801
802
803
804
805














































806
807
808
809
# Features covered: XPath capabilities
#
# This file contains a collection of tests for the XPath engine of
# tDOM.
# Tested commands and object commands:
#    xpath-1.*: Function tests
#    xpath-2.*: i18n
#    xpath-3.*: NaN/Inf
#    xpath-4.*: Tcl coded XPath functions and additional Tcl coded
#               XPath functions
#    xpath-5.*: XPath lexer/parser tests
#    xpath-6.*: Doc order after modifying tree
#    xpath-7.*: Asorted XPath expressions, which are not occur in the xslt 
#               tests outside this tcltest based test suite
#
................................................................................
    $root selectNodes {-2.2 div (-23.7 div 0)}
} {0}

test xpath-3.20 {Infinity divided by Infinity} {
    $root selectNodes {(2 div 0) div (3 div 0)}
} {NaN}

test xpath-3.21 {Infinity divided by postive number} {
    $root selectNodes {(2.7 div 0) div 23}
} {Infinity}

test xpath-3.22 {Infinity divided by negative number} {
    $root selectNodes {(2.7 div 0) div -23}
} {-Infinity}

test xpath-3.23 {-Infinity divided by postive number} {
    $root selectNodes {(-2.7 div 0) div 23}
} {-Infinity}

test xpath-3.24 {-Infinity divided by negative number} {
    $root selectNodes {(-2.7 div 0) div -23}
} {Infinity}

................................................................................
} {NaN}

test xpath-3.35 {Infinity minus -Infinity} {
    $root selectNodes {(1 div 0) - (-1 div 0)}
} {Infinity}

$doc delete



































set doc [dom parse {<root xmlns:myNS="myNS">Foo</root>}]
set root [$doc documentElement]

test xpath-4.1 {function-available} {
    $root selectNodes function-available('count')
} {1}
................................................................................
test xpath-4.5 {tcl coded additional XPath function} {
    $root selectNodes {mycontains(., 'bo')}
} {0}

test xpath-4.6 {tcl coded additional XPath function - error reported} {
    catch {$root selectNodes {mycontains(., 'bo', 'ba')}} errMsg
    set errMsg
} {Tcl error while executing XPATH extension function 'mycontains':
mycontains(): wrong # of args!}

proc ::dom::xpathFunc::wrongreturn {ctxNode pos nodeListNode nodeList args} {
    return [list footype "foo"]
}

test xpath-4.7 {tcl coded additional XPath function - unknown return type} {
    catch {$root selectNodes {wrongreturn('foo')}} errMsg
    set errMsg
} {Unknown type of return value "footype" from tcl coded XPath function "wrongreturn"!}

proc ::dom::xpathFunc::returnnumber {ctxNode pos nodeListNode nodeList args} {
    return [list number "42"]
}

test xpath-4.8 {tcl coded additional XPath function - return number} {
    $root selectNodes {returnnumber()}
................................................................................
    errorStack1
    return [list string "Not reached"]
}

test xpath-4.18 {error stack in tcl coded additional XPath function} {
    set result [catch {$root selectNodes errorStack()} errMsg]
    lappend result $errMsg
} {1 {Tcl error while executing XPATH extension function 'errorStack':
Some error}}


























































test xpath-5.1 {erroneous XPath expr: missing right brace in predicate} {
    set result [catch {$root selectNodes {*[1}} errMsg]
    list $result $errMsg
} {1 {Predicate: Expected "RBRACKET" for '*[1' 

Parsed symbols:
     0 WCARDNAME        0    0.000     0  *
     1 LBRACKET         0    0.000     1  
     2 INTNUMBER        1    1.000     2  }}

test xpath-5.2 {erroneous XPath expr: missing right brace in predicate} {
    set result [catch {$root selectNodes {*[1][@attr}} errMsg]
    list $result $errMsg
} {1 {Predicate: Expected "RBRACKET" for '*[1][@attr' 

Parsed symbols:
     0 WCARDNAME        0    0.000     0  *
     1 LBRACKET         0    0.000     1  
     2 INTNUMBER        1    1.000     2  
     3 RBRACKET         0    0.000     3  
     4 LBRACKET         0    0.000     4  
     5 ATTRIBUTE        0    0.000     9  attr}}

test xpath-5.3 {erroneous XPath expr: missing left brace in predicate} {
    catch {$root selectNodes {*1]}}
} {1}

test xpath-5.4 {erroneous XPath expr} {
    catch {$root selectNodes {myNS: bar}} errMsg
................................................................................

test xpath-5.27 {erroneous XPath expr} {
    set doc [dom parse {<!--yes-->  <doc><e1/></doc><?foo bar?>}]
    set result [catch {$doc selectNodes {/[position()=1]}} errMsg]
    $doc delete
    set result
} {1}


















































































































































































































































































































































































set doc [dom parse {
<root>
  <asub>asub2</asub>
  <asub>asub3</asub>
  <asub>asub4</asub>
  <bsub>bsub1</bsub>
................................................................................
    dom parse {<root/>} doc
    set result [$doc selectNodes {count(parent::*)}]
    lappend result [$doc selectNodes {count(parent::node())}]
    lappend result [$doc selectNodes {count(..)}]
    $doc delete
    set result
} {0 0 0}















































# cleanup
::tcltest::cleanupTests
return








|







 







|







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|









|







 







|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






|
|
|







|
|
|
|
|
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
...
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
...
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
...
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
....
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
# Features covered: XPath capabilities
#
# This file contains a collection of tests for the XPath engine of
# tDOM.
# Tested commands and object commands:
#    xpath-1.*: Function tests
#    xpath-2.*: i18n
#    xpath-3.*: NaN/Inf, number conversion
#    xpath-4.*: Tcl coded XPath functions and additional Tcl coded
#               XPath functions
#    xpath-5.*: XPath lexer/parser tests
#    xpath-6.*: Doc order after modifying tree
#    xpath-7.*: Asorted XPath expressions, which are not occur in the xslt 
#               tests outside this tcltest based test suite
#
................................................................................
    $root selectNodes {-2.2 div (-23.7 div 0)}
} {0}

test xpath-3.20 {Infinity divided by Infinity} {
    $root selectNodes {(2 div 0) div (3 div 0)}
} {NaN}

test xpath-3.21 {Infinity divided by positive number} {
    $root selectNodes {(2.7 div 0) div 23}
} {Infinity}

test xpath-3.22 {Infinity divided by negative number} {
    $root selectNodes {(2.7 div 0) div -23}
} {-Infinity}

test xpath-3.23 {-Infinity divided by positive number} {
    $root selectNodes {(-2.7 div 0) div 23}
} {-Infinity}

test xpath-3.24 {-Infinity divided by negative number} {
    $root selectNodes {(-2.7 div 0) div -23}
} {Infinity}

................................................................................
} {NaN}

test xpath-3.35 {Infinity minus -Infinity} {
    $root selectNodes {(1 div 0) - (-1 div 0)}
} {Infinity}

$doc delete

set doc [dom parse {<a>
    <b>
        <number>1</number>
    </b>
    <b>
        <number>4</number>
    </b>
    <b>
        <number>6</number>
    </b>
    <b>
        <number>7</number>
    </b>
    <b>
        <number>0xA</number>
    </b>
    <b>
        <number>0xB</number>
    </b>
    </a>}]
test xpath-3.36 {number conversion} {
    $doc selectNodes {count(/a/b[number>4])}
} {2}

test xpath-3.37 {number conversion} {
    $doc selectNodes {count(/a/b[4<number])}
} {2}

test xpath-3.38 {mod by a float that casts to integer 0} {
    $doc selectNodes { 2 mod 0.2}
} {NaN}

$doc delete

set doc [dom parse {<root xmlns:myNS="myNS">Foo</root>}]
set root [$doc documentElement]

test xpath-4.1 {function-available} {
    $root selectNodes function-available('count')
} {1}
................................................................................
test xpath-4.5 {tcl coded additional XPath function} {
    $root selectNodes {mycontains(., 'bo')}
} {0}

test xpath-4.6 {tcl coded additional XPath function - error reported} {
    catch {$root selectNodes {mycontains(., 'bo', 'ba')}} errMsg
    set errMsg
} {Tcl error while executing XPath extension function 'mycontains':
mycontains(): wrong # of args!}

proc ::dom::xpathFunc::wrongreturn {ctxNode pos nodeListNode nodeList args} {
    return [list footype "foo"]
}

test xpath-4.7 {tcl coded additional XPath function - unknown return type} {
    catch {$root selectNodes {wrongreturn('foo')}} errMsg
    set errMsg
} {Unknown type of return value "footype" from Tcl coded XPath function "wrongreturn"!}

proc ::dom::xpathFunc::returnnumber {ctxNode pos nodeListNode nodeList args} {
    return [list number "42"]
}

test xpath-4.8 {tcl coded additional XPath function - return number} {
    $root selectNodes {returnnumber()}
................................................................................
    errorStack1
    return [list string "Not reached"]
}

test xpath-4.18 {error stack in tcl coded additional XPath function} {
    set result [catch {$root selectNodes errorStack()} errMsg]
    lappend result $errMsg
} {1 {Tcl error while executing XPath extension function 'errorStack':
Some error}}

proc ::dom::xpathFunc::stringReturn {args} {return x}

test xpath-4.19 {tcl coded additional XPath function - return implicit string result} {
    $root selectNodes stringReturn(.)
} {x}

test xpath-4.20 {tcl coded additional XPath function - return implicit string result} {
    $root selectNodes stringReturn()
} {x}

proc ::dom::xpathFunc::ctxNode {ctxNode args} {
    return [list "nodes" $ctxNode]
}

test xpath-4.21 {tcl coded additional XPath function - return node} {
    $root selectNodes {string(ctxNode()/node())} 
} {Foo}

dom parse {<doc>
<e>1</e>
<e>2</e>
<e>3</e>
<e>4</e>
<e>5</e>
    </doc>} doc1

proc ::dom::xpathFunc::useXPath {ctxNode pos nodeListNode nodeList args} {

    if {[llength $args] != 2} {
        error "useXPath(): wrong # of args!"
    }
    foreach { arg1Typ arg1Value } $args break
    if {$arg1Typ ne "nodes" || [llength $arg1Value] != 1} {
        error "wrong argument: expecting one node"
    }
    set result [list]
    for {set i 5} {$i > 0} {incr i -2} {
        lappend result [$arg1Value selectNodes {*[position()=$i]}]
    }
    for {set i 1} {$i < 6} {incr i 2} {
        lappend result [$arg1Value selectNodes {*[position()=$i]}]
    }
    # Result will be a XPath result set, that means in document order
    # and de-duplicated.
    return [list "nodes" $result]
}

test xpath-4.22 {tcl coded additional XPath function - use XPath on the document in the function} {
    set result [list]
    foreach node [$doc1 selectNodes useXPath(/doc)] {
        lappend result [$node text]
    }
    join $result " "
} {1 3 5}

$doc1 delete

test xpath-5.1 {erroneous XPath expr: missing right brace in predicate} {
    set result [catch {$root selectNodes {*[1}} errMsg]
    list $result $errMsg
} {1 {Predicate: Expected "RBRACKET" for '*[1' 

Parsed symbols:
     0 WCARDNAME        0 00000.000     0  *
     1 LBRACKET         0 00000.000     1  
     2 INTNUMBER        1 00001.000     2  }}

test xpath-5.2 {erroneous XPath expr: missing right brace in predicate} {
    set result [catch {$root selectNodes {*[1][@attr}} errMsg]
    list $result $errMsg
} {1 {Predicate: Expected "RBRACKET" for '*[1][@attr' 

Parsed symbols:
     0 WCARDNAME        0 00000.000     0  *
     1 LBRACKET         0 00000.000     1  
     2 INTNUMBER        1 00001.000     2  
     3 RBRACKET         0 00000.000     3  
     4 LBRACKET         0 00000.000     4  
     5 ATTRIBUTE        0 00000.000     9  attr}}

test xpath-5.3 {erroneous XPath expr: missing left brace in predicate} {
    catch {$root selectNodes {*1]}}
} {1}

test xpath-5.4 {erroneous XPath expr} {
    catch {$root selectNodes {myNS: bar}} errMsg
................................................................................

test xpath-5.27 {erroneous XPath expr} {
    set doc [dom parse {<!--yes-->  <doc><e1/></doc><?foo bar?>}]
    set result [catch {$doc selectNodes {/[position()=1]}} errMsg]
    $doc delete
    set result
} {1}

test xpath-5.28 {afl-fuzz found seg faulting 'xpath expr'} {
    set doc [dom parse <a/>]
    set result [catch {$doc selectNodes {@a//b::*}}]
    $doc delete
    set result
} {1}

test xpath-5.29 {afl-fuzz found seg faulting 'xpath expr'} {
    set doc [dom parse <a/>]
    set result [catch {$doc selectNodes {a[1=a::a]}}]
    $doc delete
    set result
} {1}

test xpath-5.30 {afl-fuzz found seg faulting 'xpath expr'} {
    set doc [dom parse <a/>]
    set result [catch {$doc selectNodes [string repeate 9 239]@d}]
    $doc delete
    set result
} {1}

test xpath-5.31 {Limits} {
    set doc [dom parse <a/>]
    set result [$doc selectNodes {999999999999999 + 999999999999999}]
    $doc delete
    set result
} {1999999999999998.0}

test xpath-5.32 {Limits} {
    set doc [dom parse <a/>]
    set result [$doc selectNodes {9999999999999999999 + 9999999999999999999}]
    $doc delete
    set result
} {2e+19}

test xpath-5.33 {afl-fuzz found seg faulting 'xpath expr'} {
    set doc [dom parse <a/>]
    set result [catch {$doc selectNodes "[string repeat Q 1380](1)"}]
    $doc delete
    set result
} {1}

test xpath-5.34 {tcl var resolution in expr} {
    set doc [dom parse {<doc><e att="1"/><e att="2"/><e att="3"/></doc>}]
    set which 2
    # Tcl var value is always seen as string by the xpath engine. Any
    # non empty string is always true
    set node [$doc selectNodes {/doc/e[$which]}]
    set result [llength $node]
    # If another xpath data type is needed, cast explicitly
    set node [$doc selectNodes {/doc/e[number($which)]}]
    lappend result [llength $node]
    lappend result [$node @att]
    set which ""
    # Empty string is false, by xpath converting rules
    set node [$doc selectNodes {/doc/e[$which]}]
    lappend result [llength $node]
    $doc delete
    set result
} {3 1 2 0}

test xpath-5.35 {tcl var resolution in xpath expr} {
    set doc [dom parse {<doc><e>1</e><e>2</e><e>3</e><e>4</e></doc>}]
    set node [$doc documentElement] 
    set i 2
    set result [list]
    lappend result [$node selectNodes -cache 1 {string(*[position()=$i])}]
    set i 3
    lappend result [$node selectNodes -cache 1 {string(*[position()=$i])}]
    $doc delete
    set result
} {2 2}

test xpath-5.36 {tcl var resolution in xpath expr} {
    set doc [dom parse {<doc><e>1</e><e>2</e><e>3</e><e>4</e></doc>}]
    set node [$doc documentElement] 
    set i 2
    set result [list]
    lappend result [$node selectNodes {string(*[position()=$i])}]
    set i 3
    lappend result [$node selectNodes {string(*[position()=$i])}]
    $doc delete
    set result
} {2 3}

proc xpath-5.37 {node} {
    set i 4
    return [$node selectNodes -cache 1 {string(*[position()=$i])}]
}
test xpath-5.37 {tcl var resolution in xpath expr} {
    set doc [dom parse {<doc><e>1</e><e>2</e><e>3</e><e>4</e></doc>}]
    set node [$doc documentElement] 
    set i 2
    set result [list]
    lappend result [$node selectNodes -cache 1 {string(*[position()=$i])}]
    lappend result [xpath-5.37 $node]
    set i 3
    $doc delete
    set result
} {2 2}

test xpath-5.38 {tcl var resolution in xpath expr} {
    set doc [dom parse <doc/>]
    set xpath "/doc"
    for {set i 1} {$i <= 20} {incr i} {
        set var$i $i
        append xpath "/e\[position()=\$var$i\]"
    }
    set result [$doc selectNodes $xpath]
    $doc delete
} {}

test xpath-5.39 {tcl var resolution in xpath expr} {
    set xml {
        <doc>
        <e att="a" elm="1"/>
        <e att="a" elm="2"/>
        <e att="b" elm="3"/>
        <e att="b" elm="4"/>
        </doc>
    }
    set doc [dom parse $xml]
    set attvalue "b"
    set pos 2
    set result [[$doc selectNodes {/doc/e[@att=$attvalue][position()=$pos]}] asXML -indent none]
    $doc delete
    set result
} {<e att="b" elm="4"/>}

test xpath-5.40 {tcl var resolution in xpath expr} {
    set doc [dom parse {<doc><e>1</e><e>2</e><e>3</e><e>4</e></doc>}]
    # What this test tests depend on NUM_STATIC_TOKENS. Which is 20 in
    # the tcl core distribution at the time, this test was written.
    unset -nocomplain a
    for {set i 0} {$i < 25} {} {
        set a($i) [incr i]
    }
    set a(25) 2
    set xpath "string(/doc/e\[position()="
    for {set i 0} {$i < 26} {incr i} {
        append xpath "\$a("
    }
    append xpath 0
    for {set i 0} {$i < 26} {incr i} {
        append xpath ")"
    }
    append xpath "\])"
    set result [$doc selectNodes $xpath]
    lappend result [$doc selectNodes -cache 1 $xpath]
    $doc delete
    unset a
    set result
} {2 2}

test xpath-5.41 {tcl var resolution in xpath expr} {
    set doc [dom parse {<doc><e>1</e><e>2</e><e>3</e><e>4</e></doc>}]
    # What this test tests depend on NUM_STATIC_TOKENS.
    unset -nocomplain a
    for {set i 0} {$i < 25} {} {
        set a($i) [incr i]
    }
    set a(25) 2
    set xpath "/doc"
    for {set i 1} {$i <= 20} {incr i} {
        set var$i $i
        append xpath "/e\[position()=\$var$i\]"
    }
    append xpath "/e\[position()="
    for {set i 0} {$i < 26} {incr i} {
        append xpath "\$a("
    }
    append xpath 0
    for {set i 0} {$i < 26} {incr i} {
        append xpath ")"
    }
    append xpath "\]"
    set result [$doc selectNodes $xpath]
    append result [$doc selectNodes -cache 1 $xpath]
    $doc delete
    unset a
    set result
} ""

test xpath-5.42 {tcl var resolution in xpath expr} {
    set doc [dom parse {<doc><e>1</e><e>2</e><e>3</e><e>4</e></doc>}]
    # What this test tests depend on NUM_STATIC_TOKENS.
    unset -nocomplain a
    for {set i 0} {$i < 25} {} {
        set a($i) [incr i]
    }
    set a(25) 2
    set xpath "/doc/e\[position()="
    for {set i 0} {$i < 26} {incr i} {
        append xpath "\$a("
    }
    append xpath 0
    for {set i 0} {$i < 26} {incr i} {
        append xpath ")"
    }
    append xpath "\]"
    for {set i 1} {$i <= 20} {incr i} {
        set var$i $i
        append xpath "/e\[position()=\$var$i\]"
    }
    set result [$doc selectNodes $xpath]
    append result [$doc selectNodes -cache 1 $xpath]
    $doc delete
    unset a
    set result
} ""

test xpath-5.43 {XPath is commutative} {
    set xml {
<doc>
  <e>
    <ee>eins</ee>
  </e>
  <e>
    <ee>zwei</ee>
  </e>
</doc>}
    set doc [dom parse $xml]
    set result [expr {[$doc selectNodes {doc/e[ee='zwei']}]
                      == [$doc selectNodes {doc/e['zwei'=ee]}]}]
    lappend result [llength [$doc selectNodes {doc/e[ee='zwei']}]]
    lappend result [$doc selectNodes {string(doc/e[ee='zwei'])}]
    $doc delete
    set result
} {1 1 zwei}

test xpath-5.44 {Element name injected with tcl variable} {
    set doc [dom parse -json {{"member name with spaces":"the value"}}]
    set nodeName "member name with spaces"
    set node [$doc selectNodes %nodeName]
    set result [list]
    lappend result [$node nodeName]
    lappend result [$doc selectNodes string(%nodeName)]
    set node [$doc selectNodes /%nodeName]
    lappend result [$node nodeName]
    $doc delete
    set result
} {{member name with spaces} {the value} {member name with spaces}}

test xpath-5.45 {Element name injected with tcl variable} {
    set doc [dom parse -json {{"a":{"with spaces":"the value"},"a":{"with spaces":"another value"}}}]
    set nodeName "with spaces"
    set node [$doc selectNodes {a[%nodeName='another value']}]
    set result [list]
    lappend result [$node nodeName]
    lappend result [$doc selectNodes {string(a[%nodeName='another value'])}]
    $doc delete
    set result
} {a {another value}}

test xpath-5.46 {Element name injected with tcl variable - wrong xpath syntax} {
    set doc [dom parse -json {{"a":{"with spaces":"the value"},"a":{"with spaces":"another value"}}}]
    set result [catch {$doc selectNodes {a[b %nodeName='another value']}} errMsg]
    lappend result $errMsg
    $doc delete
    set result
} {1 {Predicate: Expected "RBRACKET" for 'a[b %nodeName='another value']' 

Parsed symbols:
     0 WCARDNAME        0 00000.000     0  a
     1 LBRACKET         0 00000.000     1  
     2 WCARDNAME        0 00000.000     2  b
-->  3 WCARDNAME        1 00000.000    12  with spaces
     4 EQUAL            0 00000.000    13  
     5 LITERAL          0 00000.000    28  another value
     6 RBRACKET         0 00000.000    29  }}

test xpath-5.47 {Element name injected with tcl variable} {
    set doc [dom parse -json {{"a":{"":"the value"},"a":{"":"another value"}}}]
    set nodeName ""
    set node [$doc selectNodes {a[%nodeName='another value']}]
    set result [list]
    lappend result [$node nodeName]
    lappend result [$doc selectNodes {string(a[%nodeName='another value'])}]
    $doc delete
    set result
} {a {another value}}

test xpath-5.48 {Element name injected with tcl variable} {
    set doc [dom parse -json {{"a":{"a\u0001b":"the value"},"a":{"a\u0001b":"another value"}}}]
    set nodeName "a\u0001b"
    set node [$doc selectNodes {a[%nodeName='another value']}]
    set result [list]
    lappend result [$node nodeName]
    lappend result [$doc selectNodes {string(a[%nodeName='another value'])}]
    $doc delete
    set result
} {a {another value}}

test xpath-5.49 {Element name injected with tcl variable} {
    set doc [dom parse -json {{"a":{"a\u0000b":"the value"},"a":{"a\u0000b":"another value"}}}]
    set nodeName "a\u0000b"
    set node [$doc selectNodes {a[%nodeName='another value']}]
    set result [list]
    lappend result [$node nodeName]
    lappend result [$doc selectNodes {string(a[%nodeName='another value'])}]
    $doc delete
    set result
} {a {another value}}

test xpath-5.50 {Element name injected with tcl variable} {
    set doc [dom parse -json {{"a":"1","*":"2","c":"3"}}]
    set nodeName "*"
    set result [llength [$doc selectNodes %nodeName]]
    $doc delete
    set result
} {1}

test xpath-5.51 {Element name injected with tcl variable} {
    set doc [dom parse -json {{"member name with spaces":"the value"}}]
    set nodeName "member name with spaces"
    set node [$doc selectNodes %nodeName]
    set result [list]
    lappend result [$node nodeName]
    lappend result [$doc selectNodes string(%nodeName)]
    set node [$doc selectNodes child::%nodeName]
    lappend result [$node nodeName]
    $doc delete
    set result
} {{member name with spaces} {the value} {member name with spaces}}

test xpath-5.52 {Element name injected with tcl variable} {
    set doc [dom parse -json {{"a:b":"value"}}]
    set nodeName "a:b"
    set result [$doc selectNodes string(%nodeName)]
    $doc delete
    set result
} {value}

test xpath-5.53 {Element name injected with tcl variable} {
    set doc [dom parse -json {{"a:b":"value"}}]
    set nodeName "a:b"
    set result [$doc selectNodes string(child::%nodeName)]
    $doc delete
    set result
} {value}

test xpath-5.54 {Element name injected with tcl variable} {
    set doc [dom parse -json {{"a:b":"value"}}]
    set nodeName "a:b"
    set result [$doc selectNodes string(descendant-or-self::%nodeName)]
    $doc delete
    set result
} {value}

test xpath-5.55 {Element name injected with tcl variable} {
    set doc [dom parse <a><b/></a>]
    set nodeName "a/b"
    set result [llength [$doc selectNodes %nodeName]]
    lappend result [llength [$doc selectNodes a/b]]
    $doc delete
    set result
} {0 1}

test xpath-5.56 {Element name injected with tcl variable} {
    set doc [dom parse -json {{"a":{"a/b":"a/b"},"a":{"a":{"b":"b"}}}}]
    set nodeName0 "a"
    set nodeName1 "a/b"
    set result [list]
    lappend result [$doc selectNodes string(%nodeName0/%nodeName1)]
    lappend result [$doc selectNodes string(a/a/b)]
    $doc delete
    set result
} {a/b b}

set doc [dom parse {
<root>
  <asub>asub2</asub>
  <asub>asub3</asub>
  <asub>asub4</asub>
  <bsub>bsub1</bsub>
................................................................................
    dom parse {<root/>} doc
    set result [$doc selectNodes {count(parent::*)}]
    lappend result [$doc selectNodes {count(parent::node())}]
    lappend result [$doc selectNodes {count(..)}]
    $doc delete
    set result
} {0 0 0}

test xpath-7.7 {Document order in complexer // expressions} -setup {
    set doc [dom parse {
    <doc>
    <a>
        <b>1</b>
        <a>
            <b>11</b>
        </a>
        <b>2</b>
    </a>
    <a>
        <a>
            <b>22</b>
        </a>
        <b>3</b>
        <b>4</b>
        <a>
            <b>33</b>
        </a>
    </a>
</doc>}]} -body {
    set result [list]
    foreach node [$doc selectNodes //a/b] {
        lappend result [$node selectNodes string()]
    }
    join $result " - "
} -cleanup {
    $doc delete
} -result {1 - 11 - 2 - 22 - 3 - 4 - 33}

test xpath-7.8 {Attribute node as context node of a lang() call} -setup {
    set doc [dom parse <doc/>]
} -body {
    $doc selectNodes {/namespace::node()[lang('en')]}
} -cleanup {
    $doc delete
} -result ""

test xpath-7.9 {Attribute node as context node of an id() call} -setup {
    set doc [dom parse {<doc foo="bar"/>}]
} -body {
    $doc selectNodes {doc/@foo[id(.)]}
} -cleanup {
    $doc delete
} -result ""

# cleanup
::tcltest::cleanupTests
return

Changes to tests/xslt.test.

12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
543
544
545
546
547
548
549














































































































550
551
552
553
554
555
556
....
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
....
1143
1144
1145
1146
1147
1148
1149
1150












































































































1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
#    xslt-3.*: xslt vars, scope, parameters
#    xslt-4.*: xslt transformations on modified/created from the scratch docs
#    xslt-5.*: External documents: document(), xsl:import, xsl:include
#    xslt-6.*: xsl:output
#    xslt-7.*: tests related to the created result doc
#    xslt-8.*: Additional xslt rec compliance tests (details not covered by
#              by the external xslt compliance test suite).

#
# Copyright (c) 2002 - 2005 Rolf Ade.
#
# RCS: @(#) $Id$

source [file join [file dir [info script]] loadtdom.tcl]

test xslt-1.1 {unicode chars outside of US-ASCII in var name} {need_i18n} {
     set xml [dom parse {<root/>}]
     set xslt [dom parse [tDOM::xmlReadFile [file join [pwd] [file dir [info script]] data/xslt_1.xsl]]]
     set xmlroot [$xml documentElement]
     $xmlroot xslt $xslt resultDoc
     set resultroot [$resultDoc documentElement]
     set result [$resultroot asXML]
     $xml delete
     $xslt delete
     $resultDoc delete
................................................................................
    set result [$resultDoc asXML -indent none]
    $resultDoc delete
    $xml delete
    $xslt delete
    set result
} {<out>the parameter value</out>}















































































































test xslt-3.1 {xslt variable scope} {
    set xml [dom parse {<root/>}]
    set xslt [dom parse {<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <xsl:variable name="main" select="'main'"/>
    <xsl:call-template name="first"/>
  </xsl:template>
................................................................................
    catch {$xmldoc xslt $xsltdoc resultDoc} errMsg
    $xmldoc delete
    $xsltdoc delete
    set errMsg
} {The 'current' function is not allowed in Pattern. for '*[current() != 'notthis']' 

Parsed symbols:
     0 WCARDNAME        0    0.000     0  *
     1 LBRACKET         0    0.000     1  
     2 FUNCTION         0    0.000     8  current
     3 LPAR             0    0.000     9  
     4 RPAR             0    0.000    10  
     5 NOTEQ            0    0.000    13  
     6 LITERAL          0    0.000    23  notthis
     7 RBRACKET         0    0.000    24  }

set xslt-8.2.xml {<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
	<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
	</DocumentProperties>
	<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
	</OfficeDocumentSettings>
................................................................................

    set xsltDoc [dom parse $xslt]
    set result [catch {$xmlDoc xslt $xsltDoc} errMsg]
    $xmlDoc delete
    $xsltDoc delete
    set result
} {1}
    












































































































# Below is code, which replaces the dom cmd with a version, which parses
# the xml into a dom tree, then transformations this dom tree with the
# xslt identity transformation and returns the result tree of that
# transformation. This is used to test, that the result tree of an xslt
# transformation could be used as any 'ordinary' tree created with
# [dom parse]. It is here, because I didn't want to hold it seperated.
# It is commented out, because some of the tests in the sourced test files
# need line/column or baseURI information, to work correctly, and this
# information is not preserved by an xslt identity transformation and
# I was up to now too lazy, to trick around this few tests with some
# test constraints.
# 
# set identityTransformation [dom parse {<xsl:stylesheet version="1.0"







>

|







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|
|
|
|
|
|
|







 







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
....
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
....
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
#    xslt-3.*: xslt vars, scope, parameters
#    xslt-4.*: xslt transformations on modified/created from the scratch docs
#    xslt-5.*: External documents: document(), xsl:import, xsl:include
#    xslt-6.*: xsl:output
#    xslt-7.*: tests related to the created result doc
#    xslt-8.*: Additional xslt rec compliance tests (details not covered by
#              by the external xslt compliance test suite).
#    xslt-9.*: xslt transformations that are using scripted xpath functions
#
# Copyright (c) 2002 - 2005, 2013 Rolf Ade.
#
# RCS: @(#) $Id$

source [file join [file dir [info script]] loadtdom.tcl]

test xslt-1.1 {unicode chars outside of US-ASCII in var name} {need_i18n} {
     set xml [dom parse {<root/>}]
     set xslt [dom parse [tdom::xmlReadFile [file join [pwd] [file dir [info script]] data/xslt_1.xsl]]]
     set xmlroot [$xml documentElement]
     $xmlroot xslt $xslt resultDoc
     set resultroot [$resultDoc documentElement]
     set result [$resultroot asXML]
     $xml delete
     $xslt delete
     $resultDoc delete
................................................................................
    set result [$resultDoc asXML -indent none]
    $resultDoc delete
    $xml delete
    $xslt delete
    set result
} {<out>the parameter value</out>}

proc xslt-2.21-xsltmsgcmd {msg terminate} {
    global result
    if {$msg eq "3"} {
        return -code break
    }
    append result $msg
}

test xslt-2.21 {xslt -xsltmessagecmd return code break} {
    set result ""
    set xml [dom parse {<doc><e/><e/><e/><e/></doc>}]
    set xslt [dom parse {<xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
        <xsl:template match="e">
          <xsl:message><xsl:value-of select="position()"/></xsl:message>
        </xsl:template>
        </xsl:stylesheet>}]
    catch {$xml xslt -xsltmessagecmd xslt-2.21-xsltmsgcmd $xslt resultDoc} errMsg
    append result $resultDoc $errMsg
    $xml delete
    $xslt delete
    set result
} {12}

test xslt-2.22 {xslt -xsltmessagecmd return code break} {
    set result ""
    set xml [dom parse {<doc><e/><e/><e/><e/></doc>}]
    set xslt [dom parse {<xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
        <xsl:template match="e">
          <xsl:message><xsl:value-of select="position()"/></xsl:message>
        </xsl:template>
        </xsl:stylesheet>}]
    set resultDoc "untouched"
    catch {$xml xslt -ignoreUndeclaredParameters -xsltmessagecmd xslt-2.21-xsltmsgcmd $xslt resultDoc} errMsg
    append result $resultDoc
    $xml delete
    $xslt delete
    set result
} {12}

test xslt-2.23 {xslt outputVar} {
    set result ""
    set xml [dom parse {<doc/>}]
    set xslt [dom parse {<xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
        <xsl:template match="/">
        <resultDoc/>
        </xsl:template>
        </xsl:stylesheet>}]
    set resultDoc "untouched"
    catch {$xml xslt -foo $xslt resultDoc} errMsg
    append result $resultDoc
    $xml delete
    $xslt delete
    set result
} {untouched}

test xslt-2.24 {xslt outputVar} {
    set xml [dom parse {<doc/>}]
    set xslt [dom parse {<xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
        <xsl:template match="/">
        <resultDoc/>
        </xsl:template>
        </xsl:stylesheet>}]
    set result [catch {$xml xslt -foo $xslt }]
    $xml delete
    $xslt delete
    set result
} {1}

test xslt-2.25 {xslt outputVar} {
    set xml [dom parse {<doc/>}]
    set xslt [dom parse {<xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
        <xsl:template match="/">
        <xsl:message>Here</xsl:message>
        <resultDoc/>
        </xsl:template>
        </xsl:stylesheet>}]
    $xml xslt $xslt resultDoc
    $xml delete
    $xslt delete
    set result [$resultDoc asXML -indent none]
    $resultDoc delete
    set result
} {<resultDoc/>}

test xslt-2.26 {xslt -maxApplyDepth option} {
    set xml [dom parse {<e><e><e><e></e></e></e></e>}]
    set xslt [dom parse {<xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
        <xsl:template match="e">
        <xsl:text>e</xsl:text>
        <xsl:apply-templates select="e"/>
        </xsl:template>
        </xsl:stylesheet>}]
    catch {$xml xslt -maxApplyDepth 3 $xslt} errMsg
    $xml delete
    $xslt delete
    set errMsg
} "Maximum nested apply templates reached (potential infinite template recursion?)."

test xslt-3.1 {xslt variable scope} {
    set xml [dom parse {<root/>}]
    set xslt [dom parse {<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <xsl:variable name="main" select="'main'"/>
    <xsl:call-template name="first"/>
  </xsl:template>
................................................................................
    catch {$xmldoc xslt $xsltdoc resultDoc} errMsg
    $xmldoc delete
    $xsltdoc delete
    set errMsg
} {The 'current' function is not allowed in Pattern. for '*[current() != 'notthis']' 

Parsed symbols:
     0 WCARDNAME        0 00000.000     0  *
     1 LBRACKET         0 00000.000     1  
     2 FUNCTION         0 00000.000     8  current
     3 LPAR             0 00000.000     9  
     4 RPAR             0 00000.000    10  
     5 NOTEQ            0 00000.000    13  
     6 LITERAL          0 00000.000    23  notthis
     7 RBRACKET         0 00000.000    24  }

set xslt-8.2.xml {<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
	<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
	</DocumentProperties>
	<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
	</OfficeDocumentSettings>
................................................................................

    set xsltDoc [dom parse $xslt]
    set result [catch {$xmlDoc xslt $xsltDoc} errMsg]
    $xmlDoc delete
    $xsltDoc delete
    set result
} {1}

test xslt-8.5 {Minimal xslt 1.0 stylesheet} {
    set xmlDoc {<doc><child/></doc>}
    set xsltDoc {<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"/>}
    dom parse -keepEmpties $xmlDoc xmldoc
    dom parse -keepEmpties $xsltDoc xsltdoc
    $xmldoc xslt $xsltdoc resultDoc
    set result [$resultDoc asXML -indent none]
    $xmldoc delete
    $xsltdoc delete
    $resultDoc delete
    set result
} {}

test xslt-8.6 {Almost minimal xslt 1.0 stylesheet} {
    set xmlDoc {<doc><child/></doc>}
    set xsltDoc {<xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="/"/>
        </xsl:stylesheet>}
    dom parse -keepEmpties $xmlDoc xmldoc
    dom parse -keepEmpties $xsltDoc xsltdoc
    $xmldoc xslt $xsltdoc resultDoc
    set result [$resultDoc asXML -indent none]
    $xmldoc delete
    $xsltdoc delete
    $resultDoc delete
    set result
} {}

test xslt-8.7 {Minimal xslt 1.0 stylesheet returns text content of doc by default} {
    set xmlDoc {<doc><child>text</child></doc>}
    set xsltDoc {<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"/>}
    dom parse -keepEmpties $xmlDoc xmldoc
    dom parse -keepEmpties $xsltDoc xsltdoc
    $xmldoc xslt $xsltdoc resultDoc
    set result [$resultDoc asXML -indent none]
    $xmldoc delete
    $xsltdoc delete
    $resultDoc delete
    set result
} {text}

test xslt-8.8 {Almost minimal xslt 1.0 stylesheet} {
    set xmlDoc {<doc><child>text</child></doc>}
    set xsltDoc {<xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="/"/>
        </xsl:stylesheet>}
    dom parse -keepEmpties $xmlDoc xmldoc
    dom parse -keepEmpties $xsltDoc xsltdoc
    $xmldoc xslt $xsltdoc resultDoc
    set result [$resultDoc asXML -indent none]
    $xmldoc delete
    $xsltdoc delete
    $resultDoc delete
    set result
} {}

test xslt-8.9 {format-number} {knownBug} {
    set xmlDoc [dom parse <doc/>]
    set xsltDoc [dom parse {<xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="/">
        <out><xsl:value-of select="format-number(1.0, '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')"/></out>
        </xsl:template>
        </xsl:stylesheet>}]
    $xmlDoc xslt $xsltDoc resultDoc
    set result [$resultDoc asXML -indent none]
    $xmlDoc delete
    $xsltDoc delete
    $resultDoc delete
    set result <out>001</out>
} {<out>001</out>}

proc ::dom::xpathFunc::xslt-9.1 {ctxNode pos nodeListType nodeList args} {
    if {[llength $ctxNode] != 2} {
        error "::dom::xpathFunc::xslt-9.1: expected parent node / attribute \
               name list as first argument."
    }
    return {string "bar"}
}

test xslt-9.1 {xslt using scripted xpath function} -setup {
    set xml {<a><b start="foo"><c/></b></a>}
    set xsl {<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        version="1.0">
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>         
  <xsl:template match="@start">
    <xsl:attribute name="start">
      <xsl:value-of select="xslt-9.1(.)"/>
    </xsl:attribute>
  </xsl:template>
</xsl:transform>}
    set xsltDoc [dom parse -keepEmpties $xsl]
    set xmlDoc [dom parse $xml]
} -body {
    $xmlDoc xslt $xsltDoc resultDoc
    $resultDoc asXML -indent none
} -cleanup {
    $xsltDoc delete
    $xmlDoc delete
    $resultDoc delete
} -result {<a><b start="bar"><c/></b></a>}

# Below is code, which replaces the dom cmd with a version, which parses
# the xml into a dom tree, then transformations this dom tree with the
# xslt identity transformation and returns the result tree of that
# transformation. This is used to test, that the result tree of an xslt
# transformation could be used as any 'ordinary' tree created with
# [dom parse]. It is here, because I didn't want to hold it separated.
# It is commented out, because some of the tests in the sourced test files
# need line/column or baseURI information, to work correctly, and this
# information is not preserved by an xslt identity transformation and
# I was up to now too lazy, to trick around this few tests with some
# test constraints.
# 
# set identityTransformation [dom parse {<xsl:stylesheet version="1.0"

Changes to unix/CONFIG.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/bin/sh
#
# This is a small collection of example settings you can use to
# compile tdom on different platforms. Just uncomment the line(s)
# you need and run this script with "sh CONFIG".
#
# With the exception of the --enable-tdomalloc option it's best, to
# leave the tDOM specfic configuration options alone (that is: use the
# defaults, do nothing).
# 
# --enable-tdomalloc
# Default: off
# With this option on, a special memory allocator is used, which is
# optimized for low memory allocation overhead. This allocator works
# only on 32-bit plattforms. If you build for a 64-bit OS, you _must_
# disable this (and it's disabled by default).
................................................................................
# 
# --with-aolserver
# If building tDOM as module for AOLserver, this points to the 
# directory with the AOLserver source distribution. See below
# for examples.
# 
# --with-tdom
# Useful (and avaliable) only for building extensions to tDOM (as
# tnc). Use it to point to the tdomConfig.sh file.
#
# 
#
# Comment-out next line if building with GCC compiler.
# CC=gcc; export CC
#
#
# Tcl 8.0.5 on Unix. Uses public Tcl library
# -------------------------------------------
# ../configure-tcl8.0.5
#
#
# Tcl 8.1+ on Unix. Uses public Tcl library
# -------------------------------------------
# ../configure
#
#
# For 64-bit Unix you've to use --disable-tdomalloc
# -------------------------------------------------
# ../configure --disable-tdomalloc
#
#
# AOLserver 3.X. It delivers its own patched Tcl lib.
# Also, this one builds tdom as AOLserver module.
# Please do not use "make install" after doing "make".
# You have to manually adjust AOLserver config file
# to load tdom module. See README.AOL for more info.
# Also, you need to modify the "aolsrc" to point to






|
<
|







 







|







<
<
<
<
<





<
<
<
<
<







1
2
3
4
5
6
7

8
9
10
11
12
13
14
15
..
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56





57
58
59
60
61





62
63
64
65
66
67
68
#!/bin/sh
#
# This is a small collection of example settings you can use to
# compile tdom on different platforms. Just uncomment the line(s)
# you need and run this script with "sh CONFIG".
#
# For typical use it's best, to leave the tDOM specific configuration

# options alone (that is: use the defaults, do nothing).
# 
# --enable-tdomalloc
# Default: off
# With this option on, a special memory allocator is used, which is
# optimized for low memory allocation overhead. This allocator works
# only on 32-bit plattforms. If you build for a 64-bit OS, you _must_
# disable this (and it's disabled by default).
................................................................................
# 
# --with-aolserver
# If building tDOM as module for AOLserver, this points to the 
# directory with the AOLserver source distribution. See below
# for examples.
# 
# --with-tdom
# Useful (and available) only for building extensions to tDOM (as
# tnc). Use it to point to the tdomConfig.sh file.
#
# 
#
# Comment-out next line if building with GCC compiler.
# CC=gcc; export CC
#





#
# Tcl 8.1+ on Unix. Uses public Tcl library
# -------------------------------------------
# ../configure
#





#
# AOLserver 3.X. It delivers its own patched Tcl lib.
# Also, this one builds tdom as AOLserver module.
# Please do not use "make install" after doing "make".
# You have to manually adjust AOLserver config file
# to load tdom module. See README.AOL for more info.
# Also, you need to modify the "aolsrc" to point to

Added unix/speed-check.sh.













































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/bin/bash
#
# This script is used for performance monitoring of tDOM.
#
# Needs valgrind (cachegrind), so best use on linux.
#
if test "$1" = ""
then
  echo "Usage: $0 OUTPUTFILE [OPTIONS]"
  exit
fi
NAME=$1
CACHEGRIND_OPTS=""
TESTSCRIPT="../tests/all.tcl"
TESTRUN_OPTS=""
shift
while test "$1" != ""; do
    case $1 in
        --testscript)
            shift
            TESTSCRIPT=$1
            ;;
        --options)  
            shift
            TESTRUN_OPTS=$1
            ;;                        
    esac
    shift
done
        
echo "NAME           = $NAME" | tee summary-$NAME.txt
echo 'puts [string range [dom featureinfo versionhash] 0 12]' \
    | ./tcldomsh >> summary-$NAME.txt
echo "TESTSCRIPT     = $TESTSCRIPT" | tee -a summary-$NAME.txt
echo "TESTRUN_OPTS   = $TESTRUN_OPTS" | tee -a summary-$NAME.txt
rm -f cachegrind.out.* 
valgrind --tool=cachegrind $CACHEGRIND_OPTS ./tcldomsh $TESTSCRIPT \
         $TESTRUN_OPTS 2>&1 | tee -a summary-$NAME.txt

Changes to unix/tclAppInit.c.

28
29
30
31
32
33
34
35






36
37
38
39
40
41
42
43
44
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
|   written by Rolf Ade
|   August, 2007
|
\---------------------------------------------------------------------------*/

#include "tcl.h"
 






extern int Tdom_Init _ANSI_ARGS_((Tcl_Interp *interp));
extern int Tdom_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));

/*----------------------------------------------------------------------------
|   main
|
\---------------------------------------------------------------------------*/
int
main(
................................................................................
|   Tcl_AppInit
|
\---------------------------------------------------------------------------*/
int
Tcl_AppInit(interp)
    Tcl_Interp *interp;
{
    if (Tcl_Init(interp) == TCL_ERROR) {
        return TCL_ERROR;
    }
    if (Tdom_Init(interp) == TCL_ERROR) {
        return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "tdom", Tdom_Init, Tdom_SafeInit);
    Tcl_SetVar(interp, "tcl_rcFileName", "~/.tcldomshrc", TCL_GLOBAL_ONLY);
    return TCL_OK;
}







|
>
>
>
>
>
>
|
|







 







|









28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
|   written by Rolf Ade
|   August, 2007
|
\---------------------------------------------------------------------------*/

#include "tcl.h"

#ifndef MODULE_SCOPE
#   define MODULE_SCOPE extern
#endif
MODULE_SCOPE int Tcl_AppInit(Tcl_Interp *);
MODULE_SCOPE int main(int, char **);
 
extern int Tdom_Init (Tcl_Interp *interp);
extern int Tdom_SafeInit (Tcl_Interp *interp);

/*----------------------------------------------------------------------------
|   main
|
\---------------------------------------------------------------------------*/
int
main(
................................................................................
|   Tcl_AppInit
|
\---------------------------------------------------------------------------*/
int
Tcl_AppInit(interp)
    Tcl_Interp *interp;
{
    if ((Tcl_Init)(interp) == TCL_ERROR) {
        return TCL_ERROR;
    }
    if (Tdom_Init(interp) == TCL_ERROR) {
        return TCL_ERROR;
    }
    Tcl_StaticPackage(interp, "tdom", Tdom_Init, Tdom_SafeInit);
    Tcl_SetVar(interp, "tcl_rcFileName", "~/.tcldomshrc", TCL_GLOBAL_ONLY);
    return TCL_OK;
}

Added win/README.



























































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
This file contains instructions for building tdom on Windows platforms.

Windows builds may be done with either the MingW-W64 tool chain
comprising of gcc and friends, or with the Microsoft Visual C++ and
nmake tools. Each is described below.

IMPORTANT NOTE:
Building with either tool chain requires that the Tcl libraries that
are linked have also been built with the same tool chain. The resulting
binaries however can be loaded into a Tcl shell compiled with any
tool chain provided the requisite C runtimes are present on the system.

Building With The Mingw-W64 Tool Chain
======================================

Building with the MingW follows a similar process to the autoconf/TEA
based Unix builds.

1. Start a shell using mingw32.exe or mingw64.exe for 32- and 64-bit
fields respectively. Do NOT use msys2.exe directly.

2. Assuming you want to include HTML5 support using the Gumbo libraries,
build the Gumbo libraries by running these commands in the top level
directory where you extracted the Gumbo distribution. Note these
shell commands must be run in the mingw32.exe or mingw64.exe shells
as appropriate.

    ./autogen.sh
    ./configure
    make
    make install

This will install the Gumbo libraries in the mingw32/mingw64 system
directories as appropriate.

3. Change to a build directory and run the configure at the top level
tdom directory. For example, if doing a 64-bit build in the win/build64
directory within a mingw64.exe shell,

    mkdir win/build
    cd win/build
    ../../configure --enable-threads --enable-html5 --enable-64bit --prefix=/c/tcl/mingw/85/x64 --with-tcl=/c/tcl/mingw/85/x64/lib
    make
    make install

In the above sequence, we are building against Tcl 8.5 installed under
c:\tcl\mingw\85\x64 on the system. The Gumbo libraries built in the
previous step are automatically picked up from the mingw64.exe directories.
Note that tdom on Windows binds against the static Gumbo library so
there is no additional DLL to distribute.

The 32-bit build is similar except omitting the --enable-64bit option
(and of course pointing configure to a 32-bit installation of Tcl.

4. Build the tnc and tdomhtml extensions in similar fashion to the above
except that the --enable-html5 option should be left out in both cases,
and an additional option --with-tdom=path/to/tdom/build needs to be
specified for the tnc configure step.

IMPORTANT NOTE:
Because the MinGW-built binaries link to the msvcrt 6.0 runtimes that
is present on all Windows systems, the built tdom is usable on all
Windows systems with a Tcl built with any tool chain without needing
additional runtime libraries to be installed.




Building with Visual Studio 2017 Community Edition (free)
=========================================================

1. Build the Gumbo libraries if HTML5 support is desired.

1a. Check out the git repository from
https://github.com/apnadkarni/gumbo-parser.  Do NOT use the original
Gumbo repository as that does not contain a complete Visual Studio
project file required for tdom.

1b. Switch to the tdom-libs branch.
Open the visualc/gumbo.sln solution file in Visual Studio. Click the
Batch Build... item under the Build menu. In the dialog box, select
the Win32|Release|x86 and x64|Release|x64 project configurations and
then click the Build or Rebuild button. This will build the 32-bit
and 64-bit gumbo.lib libraries under visualc/Win32/Release and
visualc/x64/Release respectively.

2. Next start a Visual Studio build command shell for 64-bit builds,
usually from
    Windows Start menu->Visual Studio 2017 Folder->x64 Native Command shell

3. Change to the tdom\win directory and type the command

     nmake /s /nologo /f makefile.vc INSTALLDIR=c:\tcl\85-vs2017\x64 GUMBODIR=C:\src\gumbo
    nmake /s /nologo /f makefile.vc INSTALLDIR=c:\tcl\85-vs2017\x64 GUMBODIR=C:\src\gumbo install

Here INSTALLDIR is the path to your Tcl installation and GUMBODIR is
the path to the top level of the Gumbo sources. If GUMBODIR is not
specified, tdom will build without HTML5 support.

The 32-bit builds are similar except that

- the commands need to be run from the Visual Studio x86 Native Tools
command shell, and
- the INSTALLDIR needs to point to a 32-bit Tcl installation
- (Note GUMBODIR need not change)

4a. To build the tnc and tdomhtml extensions,

    cd extensions/tnc/win
    nmake /s /nologo /f makefile.vc INSTALLDIR=c:\tcl\85-vs2017\x64
    nmake /s /nologo /f makefile.vc INSTALLDIR=c:\tcl\85-vs2017\x64 install

    cd extensions/tdomhtml/win
    nmake /s /nologo /f makefile.vc INSTALLDIR=c:\tcl\85-vs2017\x64 install

Note no build step necessary for tdomhtml as it is pure Tcl.

Similar steps for 32-bit builds with appropriate changes.

IMPORTANT NOTE:
The Visual Studio 2017 runtimes are not guaranteed to be installed on
all Windows systems. Thus the built tdom package should only be used
with a Tcl that is also built with Visual Studio 2017.



# Building with Visual C++ 6 (32-bit) or Windows 2003 SDK (for 64-bit)
======================================================================

Steps similar to above except that HTML5 support is not available due
to Gumbo needing C99 support. The GUMBODIR option should be left out
on the nmake build commands.

IMPORTANT NOTE:
Because the VC++ 6 and 2003 SDK link to the msvcrt 6.0 runtimes that
is present on all Windows systems, the built tdom is usable on all
Windows systems with a Tcl built with any tool chain without needing
additional runtime libraries to be installed.



Changes to win/makefile.vc.

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143





144

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175
176

177
178
179
180

181
182

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
285




286
287
288
289
290
291
292
293
294

295
296
297

298
299
300
301


302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370
371
372
373
374
375

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397

398
399
400
401



402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
# makefile.vc --                                               -*- Makefile -*-
#
# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
#
# This makefile is based upon the Tcl 8.4 Makefile.vc and modified to 
# make it suitable as a general package makefile. Look for the word EDIT

# which marks sections that may need modification. As a minumum you will
# need to change the PROJECT, DOTVERSION and DLLOBJS variables to values
# relevant to your package.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# 
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 2001 ActiveState Corporation.
# Copyright (c) 2001-2002 David Gravereaux.
# Copyright (c) 2003-2006 Pat Thoyts
#
#-------------------------------------------------------------------------
# RCS: @(#)$Id$
#-------------------------------------------------------------------------

# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
# or with the MS Platform SDK (MSSDK). Visual Studio .NET 2003 and 2005 define
# VCINSTALLDIR instead. The MSVC Toolkit release defines yet another.
!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(MSSDK) && !defined(VCINSTALLDIR) && !defined(VCToolkitInstallDir)
MSG = ^
You need to run vcvars32.bat from Developer Studio or setenv.bat from the^
Platform SDK first to setup the environment.  Jump to this line to read^
the build instructions.
!error $(MSG)
!endif

#------------------------------------------------------------------------------
# HOW TO USE this makefile:
#
# 1)  It is now necessary to have %MSVCDir% set in the environment.  This is
#     used  as a check to see if vcvars32.bat had been run prior to running
#     nmake or during the installation of Microsoft Visual C++, MSVCDir had
#     been set globally and the PATH adjusted.  Either way is valid.
#
#     You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin
#     directory to setup the proper environment, if needed, for your current
#     setup.  This is a needed bootstrap requirement and allows the swapping of
#     different environments to be easier.
#
# 2)  To use the Platform SDK (not expressly needed), run setenv.bat after
#     vcvars32.bat according to the instructions for it.  This can also turn on
#     the 64-bit compiler, if your SDK has it.
#
# 3)  Targets are:
#	all       -- Builds everything.
#       <project> -- Builds the project (eg: nmake sample)
#	test      -- Builds and runs the test suite.
#	install   -- Installs the built binaries and libraries to $(INSTALLDIR)
#		     in an appropriate subdirectory.
#	clean/realclean/distclean -- varying levels of cleaning.
#
# 4)  Macros usable on the commandline:
#	INSTALLDIR=<path>
#		Sets where to install Tcl from the built binaries.
#		C:\Progra~1\Tcl is assumed when not specified.
#
#	OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,none
#		Sets special options for the core.  The default is for none.
#		Any combination of the above may be used (comma separated).
#		'none' will over-ride everything to nothing.
#
#		static  =  Builds a static library of the core instead of a
#			   dll.  The shell will be static (and large), as well.
#		msvcrt  =  Effects the static option only to switch it from
#			   using libcmt(d) as the C runtime [by default] to
#			   msvcrt(d). This is useful for static embedding
#			   support.
#		staticpkg = Effects the static option only to switch
#			   tclshXX.exe to have the dde and reg extension linked
#			   inside it.
#		nothreads = Turns off multithreading support (not recommended)
#		thrdalloc = Use the thread allocator (shared global free pool).
#		symbols =  Adds symbols for step debugging.
#		profile =  Adds profiling hooks.  Map file is assumed.
#		loimpact =  Adds a flag for how NT treats the heap to keep memory
#			   in use, low.  This is said to impact alloc performance.
#
#	STATS=memdbg,compdbg,none
#		Sets optional memory and bytecode compiler debugging code added
#		to the core.  The default is for none.  Any combination of the
#		above may be used (comma separated).  'none' will over-ride
#		everything to nothing.
#
#		memdbg   = Enables the debugging memory allocator.
#		compdbg  = Enables byte compilation logging.
#
#	MACHINE=(IX86|IA64|ALPHA|AMD64)
#		Set the machine type used for the compiler, linker, and
#		resource compiler.  This hook is needed to tell the tools
#		when alternate platforms are requested.  IX86 is the default
#		when not specified. If the CPU environment variable has been
#		set (ie: recent Platform SDK) then MACHINE is set from CPU.
#
#	TMP_DIR=<path>
#	OUT_DIR=<path>
#		Hooks to allow the intermediate and output directories to be
#		changed.  $(OUT_DIR) is assumed to be 
#		$(BINROOT)\(Release|Debug) based on if symbols are requested.
#		$(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
#
#	TESTPAT=<file>
#		Reads the tests requested to be run from this file.
#
#	CFG_ENCODING=encoding
#		name of encoding for configuration information. Defaults
#		to cp1252
#
# 5)  Examples:
#
#	Basic syntax of calling nmake looks like this:
#	nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
#
#                        Standard (no frills)
#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
#       Setting environment for using Microsoft Visual C++ tools.
#       c:\tcl_src\win\>nmake -f makefile.vc all
#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
#
#                         Building for Win64
#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
#       Setting environment for using Microsoft Visual C++ tools.
#       c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
#       Targeting Windows pre64 RETAIL
#       c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64
#
#------------------------------------------------------------------------------
#==============================================================================
###############################################################################
#------------------------------------------------------------------------------

!if !exist("makefile.vc")
MSG = ^
You must run this makefile only from the directory it is in.^
Please `cd` to its location first.
!error $(MSG)





!endif


#-------------------------------------------------------------------------
# Project specific information (EDIT)
#
# You should edit this with the name and version of your project. This
# information is used to generate the name of the package library and
# it's install location.
#
# For example, the sample extension is  going to build sample04.dll and
# would install it into $(INSTALLDIR)\lib\sample04
#
# You need to specify the object files that need to be linked into your
# binary here.
#
#-------------------------------------------------------------------------

PROJECT = tdom
!include "rules.vc"

DOTVERSION      = 0.8.3
VERSION         = $(DOTVERSION:.=)
STUBPREFIX      = $(PROJECT)stub


DLLOBJS = \
	$(TMP_DIR)\xmlrole.obj     \
	$(TMP_DIR)\xmltok.obj      \
	$(TMP_DIR)\xmlparse.obj    \
	$(TMP_DIR)\xmlsimple.obj   \
	$(TMP_DIR)\utf8conv.obj    \
	$(TMP_DIR)\dom.obj         \
	$(TMP_DIR)\domalloc.obj    \
	$(TMP_DIR)\domhtml.obj     \

	$(TMP_DIR)\domxslt.obj     \
	$(TMP_DIR)\nodecmd.obj     \
	$(TMP_DIR)\domxpath.obj    \
	$(TMP_DIR)\domlock.obj     \

	$(TMP_DIR)\tclexpat.obj    \
	$(TMP_DIR)\tcldom.obj      \

	$(TMP_DIR)\tdomStubInit.obj\
	$(TMP_DIR)\tdomStubLib.obj \
	$(TMP_DIR)\tdominit.obj    \
!if !$(STATIC_BUILD)
	$(TMP_DIR)\tdom.res
!endif

PRJSTUBOBJS = \
	$(TMP_DIR)\tdomStubLib.obj

#-------------------------------------------------------------------------
# Target names and paths ( shouldn't need changing )
#-------------------------------------------------------------------------

BINROOT		= .
ROOT            = ..

PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)

PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)

### Make sure we use backslash only.
PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
LIB_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
BIN_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
INCLUDE_INSTALL_DIR	= $(_TCLDIR)\include

### The following paths CANNOT have spaces in them.
GENERICDIR	= $(ROOT)\generic
WINDIR		= $(ROOT)\win
LIBDIR          = $(ROOT)\lib
DOCDIR		= $(ROOT)\doc
TOOLSDIR	= $(ROOT)\tools
COMPATDIR	= $(ROOT)\compat
EXPATDIR        = $(ROOT)\expat

#---------------------------------------------------------------------
# Compile flags
#---------------------------------------------------------------------

!if !$(DEBUG)
!if $(OPTIMIZING)
### This cranks the optimization level to maximize speed
cdebug	= $(OPTIMIZATIONS)
!else
cdebug	=
!endif
!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
### Warnings are too many, can't support warnings into errors.
cdebug	= -Zi -Od $(DEBUGFLAGS)
!else
cdebug	= -Zi -WX $(DEBUGFLAGS)
!endif

### Declarations common to all compiler options

cwarn = -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\

# Warning level
!if $(FULLWARNINGS)
cflags = $(cflags) -W4
!else
cflags = $(cflags) -W3
!endif

!if $(MSVCRT)
!if $(DEBUG) && !$(UNCHECKED)
crt = -MDd
!else
crt = -MD
!endif
!else
!if $(DEBUG) && !$(UNCHECKED)
crt = -MTd
!else
crt = -MT
!endif
!endif

!if !$(STATIC_BUILD)
cflags = $(cflags) -DUSE_TCL_STUBS
!if defined(TKSTUBLIB)
cflags = $(cflags) -DUSE_TK_STUBS
!endif
!endif

DEFS            =-DHAVE_MEMMOVE -DXML_DTD -DXML_NS -DTDOM_NO_UNKNOWN_CMD

DEFS_EXPAT	=-DXMLIMPORT=__declspec(dllexport)
INCLUDES	= -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(EXPATDIR)" $(TCL_INCLUDES) 
BASE_CFLAGS	= $(cflags) $(cdebug) $(crt) $(INCLUDES)
CON_CFLAGS	= $(cflags) $(cdebug) $(crt) -DCONSOLE
TCL_CFLAGS      = -DPACKAGE_NAME="\"$(PROJECT)\"" \
		  -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
		  $(BASE_CFLAGS) $(OPTDEFINES) $(DEFS) $(DEFS_EXPAT)

#---------------------------------------------------------------------
# Link flags
#---------------------------------------------------------------------





!if $(DEBUG)
ldebug	= -debug:full -debugtype:cv
!if $(MSVCRT)
ldebug = $(ldebug) -nodefaultlib:msvcrt
!endif
!else
ldebug	= -release -opt:ref -opt:icf,3
!endif


### Declarations common to all linker options
lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)


!if $(FULLWARNINGS)
lflags = $(lflags) -warn:3
!endif



!if $(PROFILE)
lflags	= $(lflags) -profile
!endif

!if $(ALIGN98_HACK) && !$(STATIC_BUILD)
### Align sections for PE size savings.
lflags	= $(lflags) -opt:nowin98
!else if !$(ALIGN98_HACK) && $(STATIC_BUILD)
### Align sections for speed in loading by choosing the virtual page size.
lflags	= $(lflags) -align:4096
!endif

!if $(LOIMPACT)
lflags	= $(lflags) -ws:aggressive
!endif

dlllflags = $(lflags) -dll
conlflags = $(lflags) -subsystem:console
guilflags = $(lflags) -subsystem:windows
!if !$(STATIC_BUILD)
baselibs  = $(TCLSTUBLIB)
!if defined(TKSTUBLIB)
baselibs  = $(baselibs) $(TKSTUBLIB)
!endif
!endif

# Avoid 'unresolved external symbol __security_cookie' errors.
# c.f. http://support.microsoft.com/?id=894573
!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
baselibs   = $(baselibs) bufferoverflowU.lib
!endif

#---------------------------------------------------------------------
# TclTest flags
#---------------------------------------------------------------------

!IF "$(TESTPAT)" != ""
TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
!ENDIF

#---------------------------------------------------------------------
# Project specific targets (EDIT)
#---------------------------------------------------------------------

all:	    setup $(PROJECT)
$(PROJECT): setup $(PRJLIB) $(PRJSTUBLIB)
install:    install-binaries install-libraries install-docs

# Tests need to ensure we load the right dll file we
# have to handle the output differently on Win9x.
#
!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
test: setup $(PROJECT)
        set TCL_LIBRARY=$(ROOT)/library
        $(TCLSH) <<
load $(PRJLIB:\=/)
source [file join $(LIBDIR:\=/) tdom.tcl]
cd "$(ROOT)/tests"
set argv "$(TESTFLAGS)"
source all.tcl
<<

!else
test: setup $(PROJECT)
        echo Please wait while the test results are collected
        set TCL_LIBRARY=$(ROOT)/library
        $(TCLSH) << >tests.log
load $(PRJLIB:\=/)
source [file join $(LIBDIR:\=/) tdom.tcl]
cd "$(ROOT)/tests"
set argv "$(TESTFLAGS)"
source all.tcl
<<
        type tests.log | more

!endif

setup:
	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)

# See <tcl>/win/coffbase.txt for extension base addresses.
$(PRJLIB): $(DLLOBJS)
!if $(STATIC_BUILD)
	$(lib32) -nologo -out:$@ @<<
$**
<<
!else
	$(link32) $(dlllflags) -base:0x109E0000 -out:$@ $(baselibs) @<<
$**
<<
	$(_VC_MANIFEST_EMBED_DLL)
	-@del $*.exp
!endif

$(PRJSTUBLIB): $(PRJSTUBOBJS)
	$(lib32) -nologo -out:$@ $(PRJSTUBOBJS)


#---------------------------------------------------------------------
# Implicit rules
#---------------------------------------------------------------------




{$(WINDIR)}.c{$(TMP_DIR)}.obj::
    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
$<
<<


{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
$<
<<

{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
$<
<<

{$(EXPATDIR)}.c{$(TMP_DIR)}.obj::
    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<

$<
<<

{$(WINDIR)}.rc{$(TMP_DIR)}.res:
	$(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
                -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
                -DDOTVERSION=\"$(DOTVERSION)\" \
                -DVERSION=\"$(VERSION)$(SUFX)\" \
!if $(DEBUG)
	-d DEBUG \
!endif
!if $(TCL_THREADS)
	-d TCL_THREADS \
!endif
!if $(STATIC_BUILD)
	-d STATIC_BUILD \
!endif
	$<

.SUFFIXES:
.SUFFIXES:.c .rc

#-------------------------------------------------------------------------
# Explicit dependency rules
#
#-------------------------------------------------------------------------


$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
	nmakehlp -s << $** > $@
@PACKAGE_VERSION@    $(DOTVERSION)
@PACKAGE_NAME@       $(PROJECT)
@PKG_LIB_FILE@       $(PRJLIBNAME)
<<

#---------------------------------------------------------------------
# Installation. (EDIT)
#
# You may need to modify this section to reflect the final distribution
# of your files and possibly to generate documentation.
#
#---------------------------------------------------------------------

install-binaries:
	@echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
	@$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
	@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL

install-libraries:
        @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
        @if exist $(LIBDIR)\NUL $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)" >NUL
        @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
        @type << >"$(SCRIPT_INSTALL_DIR)\pkgIndex.tcl"
if {[info exists ::tcl_platform(debug)]} {
    package ifneeded $(PROJECT) $(DOTVERSION) "[list load [file join $$dir $(PROJECT)$(VERSION)g.$(EXT)] tdom]; [list source [file join $$dir tdom.tcl]]"
} else {
    package ifneeded $(PROJECT) $(DOTVERSION) "[list load [file join $$dir $(PROJECT)$(VERSION).$(EXT)] tdom]; [list source [file join $$dir tdom.tcl]]"
}
<<

install-docs:
#	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
#	@if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)"

#---------------------------------------------------------------------
# Clean up
#---------------------------------------------------------------------

clean:
	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
	@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
	@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
	@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
	@if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch

realclean: clean
	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)

distclean: realclean
	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
|

|

|
<
>
|
|
|
|


|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
>
>
>
>

>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

<
<
<
<
>
|




<



>




>


>



<
|
<

<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<

<
<
<
>
>
>
>

<
<
<
<
<
<
<
<
>

<
<
>

<
<
<
>
>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>

<
<
<
<
<
<
<
<
<
<
<
>


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

<
<
>

<
<
<
>
>
>

<
<
<
<
>

<
<
<
<
<
<
<
<
<
<

<
>



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1
2
3
4
5

6
7
8
9
10
11
12
13





















14

15










































































































16
17
18
19
20
21
22
23
















24
25




26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

47

48

49
50


















































51
52































53
54






55



56
57
58
59
60








61
62


63
64



65
66
67




























68
































69
70











71
72
73
















74
75


76
77



78
79
80
81




82
83










84

85
86
87
88
























89
90


























91



92
93





















#------------------------------------------------------------- -*- makefile -*-
#
# Makefile for tdom
#
# For basic build instructions see the README in this directory.

#
# For other build options (debug, static etc.),
# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
# detailed documentation.
# 
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#





















#------------------------------------------------------------------------------












































































































PROJECT = tdom
PRJ_RCFILE = tdom.rc
!if [echo VERSIONHASH = \> nmakehlp.out] \
   || [type ..\manifest.uuid >> nmakehlp.out]
!error *** Could not retrieve VERSIONHASH.
!endif
!include nmakehlp.out

















!include "rules-ext.vc"





EXPATDIR = ..\expat
PRJ_OBJS = \
	$(TMP_DIR)\xmlrole.obj     \
	$(TMP_DIR)\xmltok.obj      \
	$(TMP_DIR)\xmlparse.obj    \
	$(TMP_DIR)\xmlsimple.obj   \

	$(TMP_DIR)\dom.obj         \
	$(TMP_DIR)\domalloc.obj    \
	$(TMP_DIR)\domhtml.obj     \
	$(TMP_DIR)\domhtml5.obj    \
	$(TMP_DIR)\domxslt.obj     \
	$(TMP_DIR)\nodecmd.obj     \
	$(TMP_DIR)\domxpath.obj    \
	$(TMP_DIR)\domlock.obj     \
	$(TMP_DIR)\domjson.obj     \
	$(TMP_DIR)\tclexpat.obj    \
	$(TMP_DIR)\tcldom.obj      \
	$(TMP_DIR)\tclpull.obj     \
	$(TMP_DIR)\tdomStubInit.obj\
	$(TMP_DIR)\tdomStubLib.obj \
	$(TMP_DIR)\tdominit.obj    \

	$(TMP_DIR)\loadlibrary.obj



PRJ_STUBOBJS = $(TMP_DIR)\tdomStubLib.obj



















































PRJ_DEFINES = \
	-D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE \































	-DHAVE_MEMMOVE -DXML_DTD=1 -DXML_NS=1 -DTDOM_NO_UNKNOWN_CMD=1 \
	-DXMLIMPORT=__declspec(dllexport)










# TBD - some of the code, like expat checks for Windows using the
# WIN32 macro. This should really be changed to check _WIN32. For now,
# define WIN32 ourselves
PRJ_DEFINES = $(PRJ_DEFINES) -DWIN32









PRJ_INCLUDES	= -I"$(EXPATDIR)" -I"$(TMP_DIR)"



!if "$(GUMBODIR)" != ""




PRJ_DEFINES     = $(PRJ_DEFINES) -DTDOM_HAVE_GUMBO=1
PRJ_INCLUDES = $(PRJ_INCLUDES) -I"$(GUMBODIR)\src"





























!if "$(MACHINE)" == "AMD64"
































baselibs = $(baselibs) "$(GUMBODIR)\visualc\x64\Release\gumbo.lib"
!else











baselibs = $(baselibs) "$(GUMBODIR)\visualc\Win32\Release\gumbo.lib"
!endif

















!endif # GUMBODIR



!include "$(_RULESDIR)\targets.vc"




$(TMP_DIR)\tcldom.obj: $(TMP_DIR)\versionhash.h
$(TMP_DIR)\versionhash.h: $(ROOT)\manifest.uuid
	echo #define FOSSIL_HASH "$(VERSIONHASH)" > $(TMP_DIR)\versionhash.h





install:    default-install-docs-html default-install-stubs











{$(EXPATDIR)}.c{$(TMP_DIR)}.obj::

    $(CCPKGCMD) @<<
$<
<<

























pkgindex:
        @type << >"$(OUT_DIR)\pkgIndex.tcl"


























    package ifneeded $(PROJECT) $(DOTVERSION) "[list load [file join $$dir $(PRJLIBNAME)] tdom]; [list source [file join $$dir tdom.tcl]]"



<<






















Deleted win/makefile805.vc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#----------------------------------------------------------------------------
#   This is derivated from the tcl8.3 win makefile and surely not
#   perfect. It works for me. 
#   rolf ade, 2001 (rolf@pointsman.de)
#   
#   Changes for 8.0.5 by Sumit Pokhariyal (sumitp@pune.tcs.co.in)
#
#   Project directories
#
#   ROOT   = top of source tree
#
#   TOOLS32 = location of VC++ 32-bit development tools.
#
#   INSTALLDIR = location of the Tcl installation
#
#----------------------------------------------------------------------------

!if "$(MSVCDIR)" == ""
MSG = ^
You'll need to run vcvars32.bat from Developer Studio, first, to setup^
the environment.
!error $(MSG)
!endif
# emacs: '

# Set this to the appropriate value of /MACHINE: for your platform
MACHINE                = IX86
ROOT           = ..
INSTALLDIR     = c:\Progra~1\Tcl

TOOLS32        = $(MSVCDIR)
TOOLS32_rc     = $(MSVCDIR)\..\common\MSDev98

# Uncomment the following line to compile with thread support
#THREADDEFINES = -DTCL_THREADS=1

# Set NODEBUG to 0 to compile with symbols
NODEBUG = 1

# The following defines can be used to control the amount of debugging
# code that is added to the compilation.
#
#      -DTCL_MEM_DEBUG         Enables the debugging memory allocator.
#      -DTCL_COMPILE_DEBUG     Enables byte compilation logging.
#      -DTCL_COMPILE_STATS     Enables byte compilation statistics gathering.
#      -DUSE_TCLALLOC=0        Disables the Tcl memory allocator in favor
#                              of the native malloc implementation.  This is
#
# DEBUGDEFINES = -DTCL_MEM_DEBUG -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
# DEBUGDEFINES = -DUSE_TCLALLOC=0


#-------------------------------------------------------------------------
#
#   Do not modify below this line
#
#-------------------------------------------------------------------------

NAMEPREFIX = libtdom
DOTVERSION = 0.8.3
VERSION = 083

BINROOT         = .
!IF "$(NODEBUG)" == "1"
TMPDIRNAME      =
DBGX            =
!ELSE
TMPDIRNAME      = Debug
DBGX            = d
!ENDIF
TMPDIR          = $(BINROOT)
OUTDIRNAME      = $(TMPDIRNAME)
OUTDIR          = $(TMPDIR)
TOP_DIR         = $(BINROOT)\..

TDOMLIB         = $(OUTDIR)\$(NAMEPREFIX)$(VERSION)$(DBGX).lib
TDOMDLLNAME     = $(NAMEPREFIX)$(VERSION)$(DBGX).dll
TDOMDLL         = $(OUTDIR)\$(TDOMDLLNAME)

MKDIR           = .\mkd.bat
RM              = del

LIB_INSTALL_DIR        = $(INSTALLDIR)\lib
BIN_INSTALL_DIR        = $(INSTALLDIR)\bin
SCRIPT_INSTALL_DIR     = $(INSTALLDIR)\lib\tcl$(DOTVERSION)
INCLUDE_INSTALL_DIR    = $(INSTALLDIR)\include


TDOMOBJS = $(TMPDIR)\xmlrole.obj    \
           $(TMPDIR)\xmltok.obj     \
           $(TMPDIR)\xmlparse.obj   \
           $(TMPDIR)\xmlsimple.obj  \
           $(TMPDIR)\utf8conv.obj   \
           $(TMPDIR)\dom.obj        \
           $(TMPDIR)\domalloc.obj   \
	   $(TMPDIR)\domhtml.obj    \
	   $(TMPDIR)\domxslt.obj    \
	   $(TMPDIR)\nodecmd.obj    \
           $(TMPDIR)\domxpath.obj   \
           $(TMPDIR)\domlock.obj   \
           $(TMPDIR)\tclexpat.obj   \
           $(TMPDIR)\tcldom.obj     \
           $(TMPDIR)\tdominit.obj


cc32           = "$(TOOLS32)\bin\cl.exe"
link32         = "$(TOOLS32)\bin\link.exe"
rc32           = "$(TOOLS32_rc)\bin\rc.exe"
include32      = -I"$(TOOLS32)\include"
libpath32      = /LIBPATH:"$(TOOLS32)\lib"
tcllibpath     = /LIBPATH:"$(INSTALLDIR)\lib"
lib32          = "$(TOOLS32)\bin\lib.exe"

WINDIR         = $(ROOT)\win
GENERICDIR     = $(ROOT)\generic
EXPATDIR       = $(ROOT)\expat
TCLINCDIR      = $(INSTALLDIR)\Include

TCL_INCLUDES   = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(EXPATDIR)" -I"$(TCLINCDIR)"
TCL_DEFINES    = $(DEBUGDEFINES) $(THREADDEFINES)

#-------------------------------------------------------------------------
#
#   Compile flags
#
#-------------------------------------------------------------------------

!IF "$(NODEBUG)" == "1"
# This cranks the optimization level to maximize speed
cdebug = -O2 -Gs -GD
!ELSE
!IF "$(MACHINE)" == "IA64"
cdebug = -Od -Zi
!ELSE
cdebug = -Z7 -Od
!ENDIF
!ENDIF

# declarations common to all compiler options
cflags = -c -W3 -nologo -Fp$(TMPDIR)\ -YX -DHAVE_MEMMOVE -DXML_DTD -DXML_NS -DTDOM_NO_UNKNOWN_CMD -DVERSION="\"$(DOTVERSION)\""
cvarsdll = -MD$(DBGX)

TCL_CFLAGS     = $(cdebug) $(cflags) $(cvarsdll) $(include32) \
                       $(TCL_INCLUDES) $(TCL_DEFINES)
CON_CFLAGS     = $(cdebug) $(cflags) $(include32) -DCONSOLE

#-------------------------------------------------------------------------
#
#   Link flags
#
#-------------------------------------------------------------------------

!IF "$(NODEBUG)" == "1"
ldebug = /RELEASE
!ELSE
ldebug = -debug:full -debugtype:cv
!ENDIF

# declarations common to all linker options
lflags = /NODEFAULTLIB /NOLOGO /MACHINE:$(MACHINE) $(libpath32) $(tcllibpath)

# declarations for use on Intel i386, i486, and Pentium systems
DLLENTRY = @12
dlllflags = $(lflags) -entry:_DllMainCRTStartup$(DLLENTRY) -dll


conlflags = $(lflags) -subsystem:console -entry:mainCRTStartup
guilflags = $(lflags) -subsystem:windows -entry:WinMainCRTStartup

libc = libc$(DBGX).lib oldnames.lib
libcdll = msvcrt$(DBGX).lib oldnames.lib

baselibs   = kernel32.lib $(optlibs) advapi32.lib user32.lib tcl80$(DBGX).lib
#baselibs    = kernel32.lib $(optlibs) advapi32.lib user32.lib tcl83.lib
winlibs     = $(baselibs) gdi32.lib comdlg32.lib winspool.lib


guilibs     = $(libc) $(winlibs)
conlibs     = $(libc) $(baselibs)
guilibsdll  = $(libcdll) $(winlibs)
conlibsdll  = $(libcdll) $(baselibs)

#-------------------------------------------------------------------------
#
#   Project specific targets
#
#-------------------------------------------------------------------------

all:       dlls 
dlls:      $(TDOMDLL)

install:   all
	@echo installing tDOM
	@$(MKDIR) "$(INSTALLDIR)\lib\tDOM"
	@xcopy /y $(TDOMDLL) "$(INSTALLDIR)\lib\tDOM"
	@xcopy /y pkgIndex.tcl "$(INSTALLDIR)\lib\tDOM"
	@xcopy /y ..\lib\tdom.tcl "$(INSTALLDIR)\lib\tDOM"
	@xcopy /y ..\lib\domhtml.tcl "$(INSTALLDIR)\lib\tDOM"

$(TDOMLIB): $(TDOMDLL)

$(TDOMDLL): $(TDOMOBJS)
       $(link32) $(ldebug) $(dlllflags) \
               -out:$@ $(guilibsdll) @<<
$(TDOMOBJS)
<<


	$(cc32) $(cdebug) $(cflags) -Zl -DSTATIC_BUILD $(TCL_INCLUDES) -Fo$@ $?


#---------------------------------------------------------------------
# Dedependency rules
#---------------------------------------------------------------------


#-------------------------------------------------------------------------
#   Implicit rules
#-------------------------------------------------------------------------

{$(EXPATDIR)}.c{$(TMPDIR)}.obj:
    $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<

{$(GENERICDIR)}.c{$(TMPDIR)}.obj:
    $(cc32) -DBUILD_tcl $(TCL_CFLAGS) -Fo$(TMPDIR)\ $<

clean:
       -@$(RM) $(OUTDIR)\*.exp 2>nul
       -@$(RM) $(OUTDIR)\*.lib 2>nul
       -@$(RM) $(OUTDIR)\*.dll 2>nul
       -@$(RM) $(TMPDIR)\*.pch 2>nul
       -@$(RM) $(TMPDIR)\*.obj 2>nul
       -@$(RM) $(TMPDIR)\*.ilk 2>nul
       -@$(RM) $(TMPDIR)\*.pdb 2>nul
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































Changes to win/nmakehlp.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19




20
21

22
23




24

25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41


42
43
44
45
46
47
48
49
50
..
62
63
64
65
66
67
68

69
70
71
72
73
74
75
..
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
...
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
...
153
154
155
156
157
158
159
160


161


162









163




164











165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
...
295
296
297
298
299
300
301
302


303
304
305
306
307

308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323
...
355
356
357
358
359
360
361


362


363
364
365
366
367
368
369
...
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
...
420
421
422
423
424
425
426
427


428
429
430
431
432
433
434
435
436
437
...
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530

531
532
533
534
535
536
537
...
541
542
543
544
545
546
547
548
549
550

551
552
553
554
555
556
557
558
559
560

561
562
563
564
565
566
567
...
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
...
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
...
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
...
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710



















































































































711
712
713
714
715
716
717
718
 *	This is used to fix limitations within nmake and the environment.
 *
 * Copyright (c) 2002 by David Gravereaux.
 * Copyright (c) 2006 by Pat Thoyts
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * ----------------------------------------------------------------------------
 * RCS: @(#) $Id$
 * ----------------------------------------------------------------------------
 */

#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>




#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")

#include <stdio.h>
#include <math.h>




#if defined(_M_IA64) || defined(_M_AMD64)

#pragma comment(lib, "bufferoverflowU")

#endif

/* ISO hack for dumb VC++ */
#ifdef _MSC_VER
#define   snprintf	_snprintf
#endif



/* protos */

int		CheckForCompilerFeature(const char *option);
int		CheckForLinkerFeature(const char *option);
int		IsIn(const char *string, const char *substring);
int		GrepForDefine(const char *file, const char *string);
int		SubstituteFile(const char *substs, const char *filename);


const char *    GetVersionFromFile(const char *filename, const char *match);
DWORD WINAPI	ReadFromPipe(LPVOID args);

/* globals */

#define CHUNK	25
#define STATICBUFFERSIZE    1000
typedef struct {
    HANDLE pipe;
................................................................................
main(
    int argc,
    char *argv[])
{
    char msg[300];
    DWORD dwWritten;
    int chars;


    /*
     * Make sure children (cl.exe and link.exe) are kept quiet.
     */

    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);

................................................................................
			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
			&dwWritten, NULL);
		return 2;
	    }
	    return CheckForCompilerFeature(argv[2]);
	case 'l':
	    if (argc != 3) {
		chars = snprintf(msg, sizeof(msg) - 1,
	       		"usage: %s -l <linker option>\n"
			"Tests for whether link.exe supports an option\n"
			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
			&dwWritten, NULL);
		return 2;
	    }
	    return CheckForLinkerFeature(argv[2]);
	case 'f':
	    if (argc == 2) {
		chars = snprintf(msg, sizeof(msg) - 1,
			"usage: %s -f <string> <substring>\n"
			"Find a substring within another\n"
			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
................................................................................
		 * If the string is blank, there is no match.
		 */

		return 0;
	    } else {
		return IsIn(argv[2], argv[3]);
	    }
	case 'g':
	    if (argc == 2) {
		chars = snprintf(msg, sizeof(msg) - 1,
			"usage: %s -g <file> <string>\n"
			"grep for a #define\n"
			"exitcodes: integer of the found string (no decimals)\n",
			argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
			&dwWritten, NULL);
		return 2;
	    }
	    return GrepForDefine(argv[2], argv[3]);
	case 's':
	    if (argc == 2) {
		chars = snprintf(msg, sizeof(msg) - 1,
			"usage: %s -s <substitutions file> <file>\n"
			"Perform a set of string map type substutitions on a file\n"
			"exitcodes: 0\n",
			argv[0]);
................................................................................
		    "Extract a version from a file:\n"
		    "eg: pkgIndex.tcl \"package ifneeded http\"",
		    argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
		    &dwWritten, NULL);
		return 0;
	    }
	    printf("%s\n", GetVersionFromFile(argv[2], argv[3]));


	    return 0;


	}









    }




    chars = snprintf(msg, sizeof(msg) - 1,











	    "usage: %s -c|-l|-f|-g|-V ...\n"
	    "This is a little helper app to equalize shell differences between WinNT and\n"
	    "Win9x and get nmake.exe to accomplish its job.\n",
	    argv[0]);
    WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
    return 2;
}
 
int
CheckForCompilerFeature(
    const char *option)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
................................................................................
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.
     */

................................................................................
     * Look for the commandline warning code in both streams.
     *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
     */

    return !(strstr(Out.buffer, "D4002") != NULL
             || strstr(Err.buffer, "D4002") != NULL
             || strstr(Out.buffer, "D9002") != NULL
             || strstr(Err.buffer, "D9002") != NULL);


}
 
int
CheckForLinkerFeature(
    const char *option)

{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];

    char cmdline[100];

    hProcess = GetCurrentProcess();

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
................................................................................

    lstrcpy(cmdline, "link.exe -nologo ");

    /*
     * Append our option for testing.
     */



    lstrcat(cmdline, option);



    ok = CreateProcess(
	    NULL,	    /* Module name. */
	    cmdline,	    /* Command line. */
	    NULL,	    /* Process handle not inheritable. */
	    NULL,	    /* Thread handle not inheritable. */
	    TRUE,	    /* yes, inherit handles. */
................................................................................
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.
     */

................................................................................
    /*
     * Look for the commandline warning code in the stderr stream.
     */

    return !(strstr(Out.buffer, "LNK1117") != NULL ||
	    strstr(Err.buffer, "LNK1117") != NULL ||
	    strstr(Out.buffer, "LNK4044") != NULL ||
	    strstr(Err.buffer, "LNK4044") != NULL);


}
 
DWORD WINAPI
ReadFromPipe(
    LPVOID args)
{
    pipeinfo *pi = (pipeinfo *) args;
    char *lastBuf = pi->buffer;
    DWORD dwRead;
    BOOL ok;
................................................................................
    }
    lastBuf += dwRead;
    goto again;

    return 0;  /* makes the compiler happy */
}
 
int
IsIn(
    const char *string,
    const char *substring)
{
    return (strstr(string, substring) != NULL);
}
 
/*
 * Find a specified #define by name.
 *
 * If the line is '#define TCL_VERSION "8.5"', it returns 85 as the result.
 */

int
GrepForDefine(
    const char *file,
    const char *string)
{
    char s1[51], s2[51], s3[51];
    FILE *f = fopen(file, "rt");

    if (f == NULL) {
	return 0;
    }

    do {
	int r = fscanf(f, "%50s", s1);

	if (r == 1 && !strcmp(s1, "#define")) {
	    /*
	     * Get next two words.
	     */

	    r = fscanf(f, "%50s %50s", s2, s3);
	    if (r != 2) {
		continue;
	    }

	    /*
	     * Is the first word what we're looking for?
	     */

	    if (!strcmp(s2, string)) {
		double d1;

		fclose(f);

		/*
		 * Add 1 past first double quote char. "8.5"
		 */

		d1 = atof(s3 + 1);		  /*    8.5  */
		while (floor(d1) != d1) {
		    d1 *= 10.0;
		}
		return ((int) d1);		  /*    85   */
	    }
	}
    } while (!feof(f));

    fclose(f);
    return 0;
}
 
/*
 * GetVersionFromFile --
 * 	Looks for a match string in a file and then returns the version
 * 	following the match where a version is anything acceptable to
 * 	package provide or package ifneeded.
 */

const char *
GetVersionFromFile(
    const char *filename,
    const char *match)

{
    size_t cbBuffer = 100;
    static char szBuffer[100];
    char *szResult = NULL;
    FILE *fp = fopen(filename, "rt");

    if (fp != NULL) {
................................................................................

	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
	    LPSTR p, q;

	    p = strstr(szBuffer, match);
	    if (p != NULL) {
		/*
		 * Skip to first digit.
		 */


		while (*p && !isdigit(*p)) {
		    ++p;
		}

		/*
		 * Find ending whitespace.
		 */

		q = p;
		while (*q && (isalnum(*q) || *q == '.')) {

		    ++q;
		}

		memcpy(szBuffer, p, q - p);
		szBuffer[q-p] = 0;
		szResult = szBuffer;
		break;
................................................................................
 *	Usage is something like:
 *	  nmakehlp -S << $** > $@
 *        @PACKAGE_NAME@ $(PACKAGE_NAME)
 *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
 *        <<
 */

int
SubstituteFile(
    const char *substitutions,
    const char *filename)
{
    size_t cbBuffer = 1024;
    static char szBuffer[1024], szCopy[1024];
    char *szResult = NULL;
................................................................................
	/*
	 * Build a list of substutitions from the first filename
	 */

	sp = fopen(substitutions, "rt");
	if (sp != NULL) {
	    while (fgets(szBuffer, cbBuffer, sp) != NULL) {
		char *ks, *ke, *vs, *ve;
		ks = szBuffer;
		while (ks && *ks && isspace(*ks)) ++ks;
		ke = ks;
		while (ke && *ke && !isspace(*ke)) ++ke;
		vs = ke;
		while (vs && *vs && isspace(*vs)) ++vs;
		ve = vs;
		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
		*ke = 0, *ve = 0;
		list_insert(&substPtr, ks, vs);
	    }
	    fclose(sp);
	}

	/* debug: dump the list */
#ifdef _DEBUG
	{
................................................................................
	    int n = 0;
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
		fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
	    }
	}
#endif
	
	/*
	 * Run the substitutions over each line of the input
	 */
	
	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr) {
		char *m = strstr(szBuffer, p->key);
		if (m) {
		    char *cp, *op, *sp;
		    cp = szCopy;
................................................................................
		    while (*op) *cp++ = *op++;
		    *cp = 0;
		    memcpy(szBuffer, szCopy, sizeof(szCopy));
		}
	    }
	    printf(szBuffer);
	}
	
	list_free(&substPtr);
    }
    fclose(fp);
    return 0;
}

/*



















































































































 * Local variables:
 *   mode: c
 *   c-basic-offset: 4
 *   fill-column: 78
 *   indent-tabs-mode: t
 *   tab-width: 8
 * End:
 */







<
<
<





>
>
>
>


>


>
>
>
>

>

>








<


|
|
|
<
|
>
>
|
|







 







>







 







|

|






|







 







<
<
<
<
<
<
<
<
<
<
<
<







 







|
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|







|







 







|







 







|
>
>


|

|
>








>
|







 







>
>
|
>
>







 







|







 







|
>
>


|







 







|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








|


|
>







 







|


>









|
>







 







|







 







|
|








|







 







|



|







 







|





|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








5
6
7
8
9
10
11



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
..
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
..
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
...
127
128
129
130
131
132
133












134
135
136
137
138
139
140
...
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
...
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
...
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
...
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
...
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
...
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
...
483
484
485
486
487
488
489
490
491
492
493
494
495
496

























































497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
...
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
...
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
...
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
...
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
...
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
 *	This is used to fix limitations within nmake and the environment.
 *
 * Copyright (c) 2002 by David Gravereaux.
 * Copyright (c) 2006 by Pat Thoyts
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.



 * ----------------------------------------------------------------------------
 */

#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#define NO_SHLWAPI_GDI
#define NO_SHLWAPI_STREAM
#define NO_SHLWAPI_REG
#include <shlwapi.h>
#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
#pragma comment (lib, "shlwapi.lib")
#include <stdio.h>
#include <math.h>

/*
 * This library is required for x64 builds with _some_ versions of MSVC
 */
#if defined(_M_IA64) || defined(_M_AMD64)
#if _MSC_VER >= 1400 && _MSC_VER < 1500
#pragma comment(lib, "bufferoverflowU")
#endif
#endif

/* ISO hack for dumb VC++ */
#ifdef _MSC_VER
#define   snprintf	_snprintf
#endif



/* protos */

static int CheckForCompilerFeature(const char *option);
static int CheckForLinkerFeature(const char **options, int count);
static int IsIn(const char *string, const char *substring);

static int SubstituteFile(const char *substs, const char *filename);
static int QualifyPath(const char *path);
static int LocateDependency(const char *keyfile);
static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
static DWORD WINAPI ReadFromPipe(LPVOID args);

/* globals */

#define CHUNK	25
#define STATICBUFFERSIZE    1000
typedef struct {
    HANDLE pipe;
................................................................................
main(
    int argc,
    char *argv[])
{
    char msg[300];
    DWORD dwWritten;
    int chars;
    char *s;

    /*
     * Make sure children (cl.exe and link.exe) are kept quiet.
     */

    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);

................................................................................
			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
			&dwWritten, NULL);
		return 2;
	    }
	    return CheckForCompilerFeature(argv[2]);
	case 'l':
	    if (argc < 3) {
		chars = snprintf(msg, sizeof(msg) - 1,
	       		"usage: %s -l <linker option> ?<mandatory option> ...?\n"
			"Tests for whether link.exe supports an option\n"
			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
			&dwWritten, NULL);
		return 2;
	    }
	    return CheckForLinkerFeature(&argv[2], argc-2);
	case 'f':
	    if (argc == 2) {
		chars = snprintf(msg, sizeof(msg) - 1,
			"usage: %s -f <string> <substring>\n"
			"Find a substring within another\n"
			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
................................................................................
		 * If the string is blank, there is no match.
		 */

		return 0;
	    } else {
		return IsIn(argv[2], argv[3]);
	    }












	case 's':
	    if (argc == 2) {
		chars = snprintf(msg, sizeof(msg) - 1,
			"usage: %s -s <substitutions file> <file>\n"
			"Perform a set of string map type substutitions on a file\n"
			"exitcodes: 0\n",
			argv[0]);
................................................................................
		    "Extract a version from a file:\n"
		    "eg: pkgIndex.tcl \"package ifneeded http\"",
		    argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
		    &dwWritten, NULL);
		return 0;
	    }
	    s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
	    if (s && *s) {
		printf("%s\n", s);
		return 0;
	    } else
		return 1; /* Version not found. Return non-0 exit code */

	case 'Q':
	    if (argc != 3) {
		chars = snprintf(msg, sizeof(msg) - 1,
		    "usage: %s -Q path\n"
		    "Emit the fully qualified path\n"
		    "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
		    &dwWritten, NULL);
		return 2;
	    }
	    return QualifyPath(argv[2]);

	case 'L':
	    if (argc != 3) {
		chars = snprintf(msg, sizeof(msg) - 1,
		    "usage: %s -L keypath\n"
		    "Emit the fully qualified path of directory containing keypath\n"
		    "exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
		    &dwWritten, NULL);
		return 2;
	    }
	    return LocateDependency(argv[2]);
	}
    }
    chars = snprintf(msg, sizeof(msg) - 1,
	    "usage: %s -c|-f|-l|-Q|-s|-V ...\n"
	    "This is a little helper app to equalize shell differences between WinNT and\n"
	    "Win9x and get nmake.exe to accomplish its job.\n",
	    argv[0]);
    WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
    return 2;
}
 
static int
CheckForCompilerFeature(
    const char *option)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
................................................................................
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.
     */

................................................................................
     * Look for the commandline warning code in both streams.
     *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
     */

    return !(strstr(Out.buffer, "D4002") != NULL
             || strstr(Err.buffer, "D4002") != NULL
             || strstr(Out.buffer, "D9002") != NULL
             || strstr(Err.buffer, "D9002") != NULL
             || strstr(Out.buffer, "D2021") != NULL
             || strstr(Err.buffer, "D2021") != NULL);
}
 
static int
CheckForLinkerFeature(
    const char **options,
    int count)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];
    int i;
    char cmdline[255];

    hProcess = GetCurrentProcess();

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
................................................................................

    lstrcpy(cmdline, "link.exe -nologo ");

    /*
     * Append our option for testing.
     */

    for (i = 0; i < count; i++) {
	lstrcat(cmdline, " \"");
	lstrcat(cmdline, options[i]);
	lstrcat(cmdline, "\"");
    }

    ok = CreateProcess(
	    NULL,	    /* Module name. */
	    cmdline,	    /* Command line. */
	    NULL,	    /* Process handle not inheritable. */
	    NULL,	    /* Thread handle not inheritable. */
	    TRUE,	    /* yes, inherit handles. */
................................................................................
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.
     */

................................................................................
    /*
     * Look for the commandline warning code in the stderr stream.
     */

    return !(strstr(Out.buffer, "LNK1117") != NULL ||
	    strstr(Err.buffer, "LNK1117") != NULL ||
	    strstr(Out.buffer, "LNK4044") != NULL ||
	    strstr(Err.buffer, "LNK4044") != NULL ||
	    strstr(Out.buffer, "LNK4224") != NULL ||
	    strstr(Err.buffer, "LNK4224") != NULL);
}
 
static DWORD WINAPI
ReadFromPipe(
    LPVOID args)
{
    pipeinfo *pi = (pipeinfo *) args;
    char *lastBuf = pi->buffer;
    DWORD dwRead;
    BOOL ok;
................................................................................
    }
    lastBuf += dwRead;
    goto again;

    return 0;  /* makes the compiler happy */
}
 
static int
IsIn(
    const char *string,
    const char *substring)
{
    return (strstr(string, substring) != NULL);
}

























































 
/*
 * GetVersionFromFile --
 * 	Looks for a match string in a file and then returns the version
 * 	following the match where a version is anything acceptable to
 * 	package provide or package ifneeded.
 */

static const char *
GetVersionFromFile(
    const char *filename,
    const char *match,
    int numdots)
{
    size_t cbBuffer = 100;
    static char szBuffer[100];
    char *szResult = NULL;
    FILE *fp = fopen(filename, "rt");

    if (fp != NULL) {
................................................................................

	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
	    LPSTR p, q;

	    p = strstr(szBuffer, match);
	    if (p != NULL) {
		/*
		 * Skip to first digit after the match.
		 */

		p += strlen(match);
		while (*p && !isdigit(*p)) {
		    ++p;
		}

		/*
		 * Find ending whitespace.
		 */

		q = p;
		while (*q && (strchr("0123456789.ab", *q)) && ((!strchr(".ab", *q)
			    && (!strchr("ab", q[-1])) || --numdots))) {
		    ++q;
		}

		memcpy(szBuffer, p, q - p);
		szBuffer[q-p] = 0;
		szResult = szBuffer;
		break;
................................................................................
 *	Usage is something like:
 *	  nmakehlp -S << $** > $@
 *        @PACKAGE_NAME@ $(PACKAGE_NAME)
 *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
 *        <<
 */

static int
SubstituteFile(
    const char *substitutions,
    const char *filename)
{
    size_t cbBuffer = 1024;
    static char szBuffer[1024], szCopy[1024];
    char *szResult = NULL;
................................................................................
	/*
	 * Build a list of substutitions from the first filename
	 */

	sp = fopen(substitutions, "rt");
	if (sp != NULL) {
	    while (fgets(szBuffer, cbBuffer, sp) != NULL) {
		unsigned char *ks, *ke, *vs, *ve;
		ks = (unsigned char*)szBuffer;
		while (ks && *ks && isspace(*ks)) ++ks;
		ke = ks;
		while (ke && *ke && !isspace(*ke)) ++ke;
		vs = ke;
		while (vs && *vs && isspace(*vs)) ++vs;
		ve = vs;
		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
		*ke = 0, *ve = 0;
		list_insert(&substPtr, (char*)ks, (char*)vs);
	    }
	    fclose(sp);
	}

	/* debug: dump the list */
#ifdef _DEBUG
	{
................................................................................
	    int n = 0;
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
		fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
	    }
	}
#endif

	/*
	 * Run the substitutions over each line of the input
	 */

	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
	    list_item_t *p = NULL;
	    for (p = substPtr; p != NULL; p = p->nextPtr) {
		char *m = strstr(szBuffer, p->key);
		if (m) {
		    char *cp, *op, *sp;
		    cp = szCopy;
................................................................................
		    while (*op) *cp++ = *op++;
		    *cp = 0;
		    memcpy(szBuffer, szCopy, sizeof(szCopy));
		}
	    }
	    printf(szBuffer);
	}

	list_free(&substPtr);
    }
    fclose(fp);
    return 0;
}
 
/*
 * QualifyPath --
 *
 *	This composes the current working directory with a provided path
 *	and returns the fully qualified and normalized path.
 *	Mostly needed to setup paths for testing.
 */

static int
QualifyPath(
    const char *szPath)
{
    char szCwd[MAX_PATH + 1];
    char szTmp[MAX_PATH + 1];
    char *p;
    GetCurrentDirectory(MAX_PATH, szCwd);
    while ((p = strchr(szPath, '/')) && *p)
	*p = '\\';
    PathCombine(szTmp, szCwd, szPath);
    PathCanonicalize(szCwd, szTmp);
    printf("%s\n", szCwd);
    return 0;
}

/*
 * Implements LocateDependency for a single directory. See that command
 * for an explanation.
 * Returns 0 if found after printing the directory.
 * Returns 1 if not found but no errors.
 * Returns 2 on any kind of error
 * Basically, these are used as exit codes for the process.
 */
static int LocateDependencyHelper(const char *dir, const char *keypath)
{
    HANDLE hSearch;
    char path[MAX_PATH+1];
    int dirlen, keylen, ret;
    WIN32_FIND_DATA finfo;

    if (dir == NULL || keypath == NULL)
	return 2; /* Have no real error reporting mechanism into nmake */
    dirlen = strlen(dir);
    if ((dirlen + 3) > sizeof(path))
	return 2;
    strncpy(path, dir, dirlen);
    strncpy(path+dirlen, "\\*", 3);	/* Including terminating \0 */
    keylen = strlen(keypath);

#if 0 /* This function is not available in Visual C++ 6 */
    /*
     * Use numerics 0 -> FindExInfoStandard,
     * 1 -> FindExSearchLimitToDirectories, 
     * as these are not defined in Visual C++ 6
     */
    hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
#else
    hSearch = FindFirstFile(path, &finfo);
#endif
    if (hSearch == INVALID_HANDLE_VALUE)
	return 1; /* Not found */

    /* Loop through all subdirs checking if the keypath is under there */
    ret = 1; /* Assume not found */
    do {
	int sublen;
	/*
	 * We need to check it is a directory despite the 
	 * FindExSearchLimitToDirectories in the above call. See SDK docs
	 */
	if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
	    continue;
	sublen = strlen(finfo.cFileName);
	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
	    continue;		/* Path does not fit, assume not matched */
	strncpy(path+dirlen+1, finfo.cFileName, sublen);
	path[dirlen+1+sublen] = '\\';
	strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
	if (PathFileExists(path)) {
	    /* Found a match, print to stdout */
	    path[dirlen+1+sublen] = '\0';
	    QualifyPath(path);
	    ret = 0;
	    break;
	}
    } while (FindNextFile(hSearch, &finfo));
    FindClose(hSearch);
    return ret;
}

/*
 * LocateDependency --
 *
 *	Locates a dependency for a package.
 *        keypath - a relative path within the package directory
 *          that is used to confirm it is the correct directory.
 *	The search path for the package directory is currently only
 *      the parent and grandparent of the current working directory.
 *      If found, the command prints 
 *         name_DIRPATH=<full path of located directory>
 *      and returns 0. If not found, does not print anything and returns 1.
 */
static int LocateDependency(const char *keypath)
{
    int i, ret;
    static char *paths[] = {"..", "..\\..", "..\\..\\.."};
    
    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
	ret = LocateDependencyHelper(paths[i], keypath);
	if (ret == 0)
	    return ret;
    }
    return ret;
}


/*
 * Local variables:
 *   mode: c
 *   c-basic-offset: 4
 *   fill-column: 78
 *   indent-tabs-mode: t
 *   tab-width: 8
 * End:
 */

Changes to win/pkgIndex.tcl.

1
2
3
4
5
# tDOM Tcl package index file

package ifneeded tdom 0.8.3 \
    "[list load   [file join $dir tdom083[info sharedlibextension] ] tdom];\
     [list source [file join $dir tdom.tcl]]"


|
|

1
2
3
4
5
# tDOM Tcl package index file

package ifneeded tdom 0.9.1 \
    "[list load   [file join $dir tdom091[info sharedlibextension] ] tdom];\
     [list source [file join $dir tdom.tcl]]"

Added win/rules-ext.vc.













































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# This file should only be included in makefiles for Tcl extensions,
# NOT in the makefile for Tcl itself.

!ifndef _RULES_EXT_VC

# We need to run from the directory the parent makefile is located in.
# nmake does not tell us what makefile was used to invoke it so parent
# makefile has to set the MAKEFILEVC macro or we just make a guess and
# warn if we think that is not the case.
!if "$(MAKEFILEVC)" == ""

!if exist("$(PROJECT).vc")
MAKEFILEVC = $(PROJECT).vc
!elseif exist("makefile.vc")
MAKEFILEVC = makefile.vc
!endif
!endif # "$(MAKEFILEVC)" == ""

!if !exist("$(MAKEFILEVC)")
MSG = ^
You must run nmake from the directory containing the project makefile.^
If you are doing that and getting this message, set the MAKEFILEVC^
macro to the name of the project makefile.
!message WARNING: $(MSG)
!endif

!if "$(PROJECT)" == "tcl"
!error The rules-ext.vc file is not intended for Tcl itself.
!endif

# We extract version numbers using the nmakehlp program. For now use
# the local copy of nmakehlp. Once we locate Tcl, we will use that
# one if it is newer.
!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
!endif

# First locate the Tcl directory that we are working with.
!ifdef TCLDIR

_RULESDIR = $(TCLDIR:/=\)

!else

# If an installation path is specified, that is also the Tcl directory.
# Also Tk never builds against an installed Tcl, it needs Tcl sources
!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
_RULESDIR=$(INSTALLDIR:/=\)
!else
# Locate Tcl sources
!if [echo _RULESDIR = \> nmakehlp.out] \
   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
_RULESDIR = ..\..\tcl
!else
!include nmakehlp.out
!endif

!endif # defined(INSTALLDIR)....

!endif # ifndef TCLDIR

# Now look for the targets.vc file under the Tcl root. Note we check this
# file and not rules.vc because the latter also exists on older systems.
!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
_RULESDIR = $(_RULESDIR)\lib\nmake
!elseif exist("$(_RULESDIR)\win\targets.vc")   # Building against Tcl sources
_RULESDIR = $(_RULESDIR)\win
!else
# If we have not located Tcl's targets file, most likely we are compiling
# against an older version of Tcl and so must use our own support files.
_RULESDIR = .
!endif

!if "$(_RULESDIR)" != "."
# Potentially using Tcl's support files. If this extension has its own
# nmake support files, need to compare the versions and pick newer.

!if exist("rules.vc") # The extension has its own copy

!if [echo TCL_RULES_MAJOR = \> versions.vc] \
   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
!if [echo TCL_RULES_MINOR = \>> versions.vc] \
   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
!endif

!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
   && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
!if [echo OUR_RULES_MINOR = \>> versions.vc] \
   && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
!endif
!include versions.vc
# We have a newer version of the support files, use them
!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
_RULESDIR = .
!endif

!endif # if exist("rules.vc")

!endif # if $(_RULESDIR) != "."

# Let rules.vc know what copy of nmakehlp.c to use.
NMAKEHLPC = $(_RULESDIR)\nmakehlp.c

# Get rid of our internal defines before calling rules.vc
!undef TCL_RULES_MAJOR
!undef TCL_RULES_MINOR
!undef OUR_RULES_MAJOR
!undef OUR_RULES_MINOR

!if exist("$(_RULESDIR)\rules.vc")
!message *** Using $(_RULESDIR)\rules.vc
!include "$(_RULESDIR)\rules.vc"
!else
!error *** Could not locate rules.vc in $(_RULESDIR)
!endif

!endif # _RULES_EXT_VC

Changes to win/rules.vc.

1
2
3
4
5


6
7
8


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221




























































































































































































































































































































































































































































































222
223
224
225
226




227





228
229
230
231



232
233



234
235
236
237
238
239

240
241
242

243
244

245

246
247
248
249
250
251








252
253
254
255
256
257

258
259
260



261
262
263






264
265
266
267
268
269

270
271
272
273
274
275

276
277
278
279
280
281





282
283

284
285
286
287
288
289








290









291







292








































































293

































































294
295
296
297


298
299
300
301
302
303
304
305
306
307
308


















309
310
311
312
313
314
315
316
...
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
...
356
357
358
359
360
361
362










363
364
365
366


367
368
369
370























371
372
373
374


375
376







377
378
379
380











381
382


383






384





385

386
387
388
389

390
391
392
393







394
395
396
397

398
399
400
401
402
403



























































404
405

406
407
408










409
410
411
412











413

































414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437











438
439
440
441

442
443
444
445
446
447
448



449


450
451
452
453












454
455



456
457
458
459








460
461
462
463
464
465
466
467




468
469
470
471

472
473
474
475
476
477
478
479
480


481
482
483
484

485
486
487
488











489
490
491
492













493






494
495
496
497
498
499
500
501


502
503
504
505
506









































507
508
509
510



511
512
513
514
515
516
517



518
519
520
521
522


523
524
525



526
527
528
529
530
531
532
533
534
535
536
537









538
539
540
541
542
543
544
545
546











547
548
549
550






551
552
553
554






















555
556
557
558







559
















































































560



























561
562
563
564
565
566
567
568






569
570
571
572
573





























574
575




































576











577



578





















579
580
581
582
583






584
585

586
587
588
589
590
591
592
#------------------------------------------------------------------------------
# rules.vc --
#
#	Microsoft Visual C++ makefile include for decoding the commandline
#	macros.  This file does not need editing to build Tcl.


#
#	This version is modified from the Tcl source version to support
#	building extensions using nmake.


#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# 
# Copyright (c) 2001-2002 David Gravereaux.
# Copyright (c) 2003-2005 Patrick Thoyts
#
#------------------------------------------------------------------------------
# RCS: @(#) $Id$
#------------------------------------------------------------------------------

!ifndef _RULES_VC
_RULES_VC = 1

cc32		= $(CC)   # built-in default.
link32		= link
lib32		= lib
rc32		= $(RC)   # built-in default.

!ifndef INSTALLDIR
### Assume the normal default.
_INSTALLDIR	= C:\Program Files\Tcl
!else
### Fix the path separators.
_INSTALLDIR	= $(INSTALLDIR:/=\)
!endif

!ifndef MACHINE
!if "$(CPU)" == "" || "$(CPU)" == "i386"
MACHINE         = IX86
!else
MACHINE         = $(CPU)
!endif
!endif

!ifndef CFG_ENCODING
CFG_ENCODING	= \"cp1252\"
!endif

#----------------------------------------------------------
# Set the proper copy method to avoid overwrite questions
# to the user when copying files and selecting the right
# "delete all" method.
#----------------------------------------------------------

!if "$(OS)" == "Windows_NT"
RMDIR	= rmdir /S /Q
ERRNULL  = 2>NUL
!if ![ver | find "4.0" > nul]
CPY	= echo y | xcopy /i >NUL
COPY	= copy >NUL
!else
CPY	= xcopy /i /y >NUL
COPY	= copy /y >NUL
!endif
!else # "$(OS)" != "Windows_NT"
CPY	= xcopy /i >_JUNK.OUT # On Win98 NUL does not work here.
COPY	= copy >_JUNK.OUT # On Win98 NUL does not work here.
RMDIR	= deltree /Y
NULL    = \NUL # Used in testing directory existence
ERRNULL = >NUL # Win9x shell cannot redirect stderr
!endif
MKDIR   = mkdir

!message ===============================================================================

#----------------------------------------------------------
# build the helper app we need to overcome nmake's limiting
# environment.
#----------------------------------------------------------

!if !exist(nmakehlp.exe)
!if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul]
!endif
!endif

#----------------------------------------------------------
# Test for compiler features
#----------------------------------------------------------

### test for optimizations
!if [nmakehlp -c -Ot]
!message *** Compiler has 'Optimizations'
OPTIMIZING	= 1
!else
!message *** Compiler doesn't have 'Optimizations'
OPTIMIZING	= 0
!endif

OPTIMIZATIONS  =

!if [nmakehlp -c -Ot]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -Ot
!endif

!if [nmakehlp -c -Oi]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -Oi
!endif

!if [nmakehlp -c -Op]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -Op
!endif

!if [nmakehlp -c -fp:strict]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -fp:strict
!endif

!if [nmakehlp -c -Gs]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -Gs
!endif

!if [nmakehlp -c -GS]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
!endif

!if [nmakehlp -c -GL]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
!endif

DEBUGFLAGS     =

!if [nmakehlp -c -RTC1]
DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
!elseif [nmakehlp -c -GZ]
DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
!endif

COMPILERFLAGS  =-W3

# In v13 -GL and -YX are incompatible.
!if [nmakehlp -c -YX]
!if ![nmakehlp -c -GL]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
!endif
!endif

!if "$(MACHINE)" == "IX86"
### test for pentium errata
!if [nmakehlp -c -QI0f]
!message *** Compiler has 'Pentium 0x0f fix'
COMPILERFLAGS  = $(COMPILERFLAGSS) -QI0f
!else
!message *** Compiler doesn't have 'Pentium 0x0f fix'
!endif
!endif

!if "$(MACHINE)" == "IA64"
### test for Itanium errata
!if [nmakehlp -c -QIA64_Bx]
!message *** Compiler has 'B-stepping errata workarounds'
COMPILERFLAGS   = $(COMPILERFLAGS) -QIA64_Bx
!else
!message *** Compiler does not have 'B-stepping errata workarounds'
!endif
!endif

!if "$(MACHINE)" == "IX86"
### test for -align:4096, when align:512 will do.
!if [nmakehlp -l -opt:nowin98]
!message *** Linker has 'Win98 alignment problem'
ALIGN98_HACK	= 1
!else
!message *** Linker doesn't have 'Win98 alignment problem'
ALIGN98_HACK	= 0
!endif
!else
ALIGN98_HACK	= 0
!endif

LINKERFLAGS     =

!if [nmakehlp -l -ltcg]
LINKERFLAGS     =-ltcg
!endif

#----------------------------------------------------------
# MSVC8 (ships with Visual Studio 2005) generates a manifest
# file that we should link into the binaries. This is how.
#----------------------------------------------------------

_VC_MANIFEST_EMBED_EXE=
_VC_MANIFEST_EMBED_DLL=
VCVER=0
!if ![echo VCVERSION=_MSC_VER > vercl.x] \
    && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
!include vercl.i
!if $(VCVERSION) >= 1400
VCVER=8
_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
!elseif $(VCVERSION) >= 1300
VCVER=7
!elseif $(VCVERSION) >= 1200
VCVER=6
!endif
!endif

#----------------------------------------------------------
# Decode the options requested.
#----------------------------------------------------------

!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
STATIC_BUILD	= 0
TCL_THREADS	= 1
DEBUG		= 0
PROFILE		= 0
MSVCRT		= 0
LOIMPACT	= 0
TCL_USE_STATIC_PACKAGES	= 0
USE_THREAD_ALLOC = 1
USE_THREAD_STORAGE = 1
UNCHECKED       = 0
!else




























































































































































































































































































































































































































































































!if [nmakehlp -f $(OPTS) "static"]
!message *** Doing static
STATIC_BUILD	= 1
!else
STATIC_BUILD	= 0




!endif





!if [nmakehlp -f $(OPTS) "msvcrt"]
!message *** Doing msvcrt
MSVCRT		= 1
!else



MSVCRT		= 0
!endif



!if [nmakehlp -f $(OPTS) "staticpkg"]
!message *** Doing staticpkg
TCL_USE_STATIC_PACKAGES	= 1
!else
TCL_USE_STATIC_PACKAGES	= 0
!endif

!if [nmakehlp -f $(OPTS) "nothreads"]
!message *** Compile explicitly for non-threaded tcl
TCL_THREADS	= 0

!else
TCL_THREADS     = 1

!endif

!if [nmakehlp -f $(OPTS) "symbols"]
!message *** Doing symbols
DEBUG		= 1
!else
DEBUG		= 0
!endif








!if [nmakehlp -f $(OPTS) "profile"]
!message *** Doing profile
PROFILE		= 1
!else
PROFILE		= 0
!endif

!if [nmakehlp -f $(OPTS) "loimpact"]
!message *** Doing loimpact
LOIMPACT	= 1



!else
LOIMPACT	= 0
!endif






!if [nmakehlp -f $(OPTS) "thrdalloc"]
!message *** Doing thrdalloc
USE_THREAD_ALLOC = 1
!else
USE_THREAD_ALLOC = 0
!endif

!if [nmakehlp -f $(OPTS) "thrdstorage"]
!message *** Doing thrdstorage
USE_THREAD_STORAGE = 1
!else
USE_THREAD_STORAGE = 0
!endif

!if [nmakehlp -f $(OPTS) "unchecked"]
!message *** Doing unchecked
UNCHECKED = 1
!else
UNCHECKED = 0
!endif





!endif



!if !$(STATIC_BUILD)
# Make sure we don't build overly fat DLLs.
MSVCRT		= 1
# We shouldn't statically put the extensions inside the shell when dynamic.
TCL_USE_STATIC_PACKAGES = 0








!endif


























































































#----------------------------------------------------------

































































# Figure-out how to name our intermediate and output directories.
# We wouldn't want different builds to use the same .obj files
# by accident.
#----------------------------------------------------------



#----------------------------------------
# Naming convention:
#   t = full thread support.
#   s = static library (as opposed to an
#	import library)
#   g = linked to the debug enabled C
#	run-time.
#   x = special static build when it
#	links to the dynamic C run-time.
#----------------------------------------


















SUFX	    = sgx

!if $(DEBUG)
BUILDDIRTOP = Debug
!else
BUILDDIRTOP = Release
!endif

................................................................................

TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX

!if !$(STATIC_BUILD)
TMP_DIRFULL = $(TMP_DIRFULL:Static=)
SUFX	    = $(SUFX:s=)
EXT	    = dll
!if $(MSVCRT)
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!endif
!else
TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
EXT	    = lib
!if !$(MSVCRT)
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!endif
................................................................................
!endif
!else
!ifndef OUT_DIR
OUT_DIR	    = $(TMP_DIR)
!endif
!endif












#----------------------------------------------------------
# Decode the statistics requested.
#----------------------------------------------------------



!if "$(STATS)" == "" || [nmakehlp -f "$(STATS)" "none"]
TCL_MEM_DEBUG	    = 0
TCL_COMPILE_DEBUG   = 0























!else
!if [nmakehlp -f $(STATS) "memdbg"]
!message *** Doing memdbg
TCL_MEM_DEBUG	    = 1


!else
TCL_MEM_DEBUG	    = 0







!endif
!if [nmakehlp -f $(STATS) "compdbg"]
!message *** Doing compdbg
TCL_COMPILE_DEBUG   = 1











!else
TCL_COMPILE_DEBUG   = 0


!endif






!endif








#----------------------------------------------------------
# Decode the checks requested.
#----------------------------------------------------------


!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
TCL_NO_DEPRECATED	    = 0
FULLWARNINGS		    = 0







!else
!if [nmakehlp -f $(CHECKS) "nodep"]
!message *** Doing nodep check
TCL_NO_DEPRECATED	    = 1

!else
TCL_NO_DEPRECATED	    = 0
!endif
!if [nmakehlp -f $(CHECKS) "fullwarn"]
!message *** Doing full warnings check
FULLWARNINGS		    = 1



























































!else
FULLWARNINGS		    = 0

!endif
!endif












#----------------------------------------------------------
# Set our defines now armed with our options.
#----------------------------------------------------------













































OPTDEFINES	= -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING)

!if $(TCL_MEM_DEBUG)
OPTDEFINES	= $(OPTDEFINES) -DTCL_MEM_DEBUG
!endif
!if $(TCL_COMPILE_DEBUG)
OPTDEFINES	= $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
!endif
!if $(TCL_THREADS)
OPTDEFINES	= $(OPTDEFINES) -DTCL_THREADS=1
!if $(USE_THREAD_ALLOC)
OPTDEFINES	= $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
!endif
!if $(USE_THREAD_STORAGE)
OPTDEFINES	= $(OPTDEFINES) -DUSE_THREAD_STORAGE=1
!endif
!endif
!if $(STATIC_BUILD)
OPTDEFINES	= $(OPTDEFINES) -DSTATIC_BUILD
!endif
!if $(TCL_NO_DEPRECATED)
OPTDEFINES	= $(OPTDEFINES) -DTCL_NO_DEPRECATED
!endif












!if $(DEBUG)
OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_DEBUG
!elseif $(OPTIMIZING)
OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_OPTIMIZED

!endif
!if $(PROFILE)
OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_PROFILED
!endif
!if "$(MACHINE)" == "IA64"
OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_DO64BIT
!endif







#----------------------------------------------------------
# Get common info used when building extensions.
#----------------------------------------------------------













!if "$(PROJECT)" != "tcl"




# If INSTALLDIR set to tcl root dir then reset to the lib dir.
!if exist("$(_INSTALLDIR)\include\tcl.h")
_INSTALLDIR=$(_INSTALLDIR)\lib








!endif

!if !defined(TCLDIR)
!if exist("$(_INSTALLDIR)\..\include\tcl.h")
TCLINSTALL	= 1
_TCLDIR		= $(_INSTALLDIR)\..
_TCL_H          = $(_INSTALLDIR)\..\include\tcl.h
TCLDIR          = $(_INSTALLDIR)\..




!else
MSG=^
Failed to find tcl.h.  Set the TCLDIR macro.
!error $(MSG)

!endif
!else
_TCLDIR	= $(TCLDIR:/=\)
!if exist("$(_TCLDIR)\include\tcl.h")
TCLINSTALL	= 1
_TCL_H          = $(_TCLDIR)\include\tcl.h
!elseif exist("$(_TCLDIR)\generic\tcl.h")
TCLINSTALL	= 0
_TCL_H          = $(_TCLDIR)\generic\tcl.h


!else
MSG =^
Failed to find tcl.h.  The TCLDIR macro does not appear correct.
!error $(MSG)

!endif
!endif

!if [echo REM = This file is generated from rules.vc > version.vc]











!endif
!if exist("$(_TCL_H)")
!if [echo TCL_DOTVERSION = \>> version.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_VERSION >> version.vc]













!endif






!endif
!include version.vc
TCL_VERSION	= $(TCL_DOTVERSION:.=)

!if $(TCLINSTALL)
TCLSH		= "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
!if !exist($(TCLSH)) && $(TCL_THREADS)
TCLSH           = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe"


!endif
TCLSTUBLIB	= "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
TCLIMPLIB	= "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
TCL_LIBRARY	= $(_TCLDIR)\lib
TCL_INCLUDES    = -I"$(_TCLDIR)\include"









































!else
TCLSH		= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
!if !exist($(TCLSH)) && $(TCL_THREADS)
TCLSH		= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe"



!endif
TCLSTUBLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
TCLIMPLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
TCL_LIBRARY	= $(_TCLDIR)\library
TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
!endif




!endif

#----------------------------------------------------------
# Optionally check for Tk info for building extensions.
#----------------------------------------------------------



!ifdef PROJECT_REQUIRES_TK
!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"




!if !defined(TKDIR)
!if exist("$(_INSTALLDIR)\..\include\tk.h")
TKINSTALL      = 1
_TKDIR         = $(_INSTALLDIR)\..
_TK_H          = $(_TKDIR)\include\tk.h
TKDIR          = $(_TKDIR)
!elseif exist("$(_TCLDIR)\include\tk.h")
TKINSTALL      = 1
_TKDIR         = $(_TCLDIR)
_TK_H          = $(_TKDIR)\include\tk.h
TKDIR          = $(_TKDIR)









!endif
!else
_TKDIR = $(TKDIR:/=\)
!if exist("$(_TKDIR)\include\tk.h")
TKINSTALL      = 1
_TK_H          = $(_TKDIR)\include\tk.h
!elseif exist("$(_TKDIR)\generic\tk.h")
TKINSTALL      = 0
_TK_H          = $(_TKDIR)\generic\tk.h











!else
MSG =^
Failed to find tk.h. The TKDIR macro does not appear correct.
!error $(MSG)






!endif
!endif

!if defined(TKDIR)






















TK_DOTVERSION = 8.4
!if exist("$(_TK_H)")
!if [echo TK_DOTVERSION = \>> version.vc] \
   && [nmakehlp -V "$(_TK_H)" TK_VERSION >> version.vc]







!endif
















































































!endif



























!include version.vc
TK_VERSION = $(TK_DOTVERSION:.=)

!if $(TKINSTALL)
WISH		= "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
TKSTUBLIB	= "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
TKIMPLIB	= "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
TK_INCLUDES     = -I"$(_TKDIR)\include"






!else
WISH		= "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
TKSTUBLIB	= "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
TKIMPLIB	= "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"





























!endif





































!endif











!endif



!endif






















#----------------------------------------------------------
# Display stats being used.
#----------------------------------------------------------







!message *** Intermediate directory will be '$(TMP_DIR)'
!message *** Output directory will be '$(OUT_DIR)'

!message *** Suffix for binaries will be '$(SUFX)'
!message *** Optional defines are '$(OPTDEFINES)'
!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS)'
!message *** Link options '$(LINKERFLAGS)'

!endif
|
|
|
|
|
>
>
|
<
<
>
>



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



|
<
>
>
>
>
|
>
>
>
>
>




>
>
>
|
|
>
>
>
|





>
|
|
|
>
|
|
>
|
>






>
>
>
>
>
>
>
>






>
|
|
|
>
>
>
|
|
|
>
>
>
>
>
>



<
<
|
>
|
<
|
<
<
|
>
|
|
|
|
|
|
>
>
>
>
>
|
|
>
|
<
<
<
|
<
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<
>
>
|
<
|
|
|
<
|
<
|
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







 







<
|
|
<







 







>
>
>
>
>
>
>
>
>
>
|
<
<
<
>
>
|
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<
>
>
|
<
>
>
>
>
>
>
>
|
<
<
<
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
|
>
>
>
>
>
>
|
>
>
>
>
>
|
>
|
<
<
<
>
|
<
<
<
>
>
>
>
>
>
>
|
<
<
<
>
|
<
|
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
|
|
|
>
>
>
>
>
>
>
>
>
>
|
<
<
<
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|












<
<
<








>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
>




|
|
|
>
>
>
|
>
>
|
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>
|
<
<
<
>
>
>
>
>
>
>
>
|
|
<
<
<
<
<
<
>
>
>
>
|
<
<
<
>
|
|
<
<
<
<
<
<
<
>
>
|
<
<
<
>
|
|
|
<
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
<
<
|
|
<
<
<
>
>
|
<
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<
>
>
>
|
<
<
<
<
|
|
>
>
>
|
|
<
<
<
>
>
|
<
<
>
>
>
|
<
<
<
<
<
<
<
<
<
<
<
>
>
>
>
>
>
>
>
>
|
|
<
<
<
<
<
<
<
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<
>
>
>
>
>
>
|
|
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
|
<
<
<
<
<
>
>
>
>
>
>
|
<
<
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
|
|
>
|
<
|
<
<
|
|
1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703

704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780


781
782
783

784


785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801



802

803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968



969
970
971

972
973
974

975

976


977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
....
1013
1014
1015
1016
1017
1018
1019

1020
1021

1022
1023
1024
1025
1026
1027
1028
....
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057



1058
1059
1060



1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084



1085
1086
1087

1088
1089
1090
1091
1092
1093
1094
1095



1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107

1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125



1126
1127



1128
1129
1130
1131
1132
1133
1134
1135



1136
1137

1138



1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198

1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213



1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271



1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309



1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322

1323
1324
1325
1326



1327
1328
1329
1330
1331
1332
1333
1334
1335
1336






1337
1338
1339
1340
1341



1342
1343
1344







1345
1346
1347



1348
1349
1350
1351

1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363



1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384


1385
1386



1387
1388
1389




1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431



1432
1433
1434
1435




1436
1437
1438
1439
1440
1441
1442



1443
1444
1445


1446
1447
1448
1449











1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460







1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472



1473
1474
1475
1476
1477
1478
1479
1480
1481

1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504



1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621

1622





1623
1624
1625
1626
1627
1628
1629




1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749

1750


1751
1752
#------------------------------------------------------------- -*- makefile -*-
# rules.vc --
#
# Part of the nmake based build system for Tcl and its extensions.
# This file does all the hard work in terms of parsing build options,
# compiler switches, defining common targets and macros. The Tcl makefile
# directly includes this. Extensions include it via "rules-ext.vc".
#


# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
# detailed documentation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# Copyright (c) 2001-2003 David Gravereaux.
# Copyright (c) 2003-2008 Patrick Thoyts
# Copyright (c) 2017      Ashok P. Nadkarni
#------------------------------------------------------------------------------

!ifndef _RULES_VC
_RULES_VC = 1

# The following macros define the version of the rules.vc nmake build system
# For modifications that are not backward-compatible, you *must* change
# the major version.
RULES_VERSION_MAJOR = 1
RULES_VERSION_MINOR = 1

# The PROJECT macro must be defined by parent makefile.
!if "$(PROJECT)" == ""
!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
!endif

!if "$(PRJ_PACKAGE_TCLNAME)" == ""
PRJ_PACKAGE_TCLNAME = $(PROJECT)
!endif

# Also special case Tcl and Tk to save some typing later
DOING_TCL = 0
DOING_TK  = 0
!if "$(PROJECT)" == "tcl"
DOING_TCL = 1
!elseif "$(PROJECT)" == "tk"
DOING_TK = 1
!endif

!ifndef NEED_TK
# Backwards compatibility
!ifdef PROJECT_REQUIRES_TK
NEED_TK = $(PROJECT_REQUIRES_TK)
!else
NEED_TK = 0
!endif
!endif

!ifndef NEED_TCL_SOURCE
NEED_TCL_SOURCE = 0
!endif

!ifdef NEED_TK_SOURCE
!if $(NEED_TK_SOURCE)
NEED_TK = 1
!endif
!else
NEED_TK_SOURCE = 0
!endif

################################################################
# Nmake is a pretty weak environment in syntax and capabilities
# so this file is necessarily verbose. It's broken down into
# the following parts.
#
# 0. Sanity check that compiler environment is set up and initialize
#    any built-in settings from the parent makefile
# 1. First define the external tools used for compiling, copying etc.
#    as this is independent of everything else.
# 2. Figure out our build structure in terms of the directory, whether
#    we are building Tcl or an extension, etc.
# 3. Determine the compiler and linker versions
# 4. Build the nmakehlp helper application
# 5. Determine the supported compiler options and features
# 6. Parse the OPTS macro value for user-specified build configuration
# 7. Parse the STATS macro value for statistics instrumentation
# 8. Parse the CHECKS macro for additional compilation checks
# 9. Extract Tcl, and possibly Tk, version numbers from the headers
# 10. Based on this selected configuration, construct the output
#     directory and file paths
# 11. Construct the paths where the package is to be installed
# 12. Set up the actual options passed to compiler and linker based
#     on the information gathered above.
# 13. Define some standard build targets and implicit rules. These may
#     be optionally disabled by the parent makefile.
# 14. (For extensions only.) Compare the configuration of the target
#     Tcl and the extensions and warn against discrepancies.
#
# One final note about the macro names used. They are as they are
# for historical reasons. We would like legacy extensions to
# continue to work with this make include file so be wary of
# changing them for consistency or clarity.

# 0. Sanity check compiler environment

# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)

!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
MSG = ^
Visual C++ compiler environment not initialized.
!error $(MSG)
!endif

# We need to run from the directory the parent makefile is located in.
# nmake does not tell us what makefile was used to invoke it so parent
# makefile has to set the MAKEFILEVC macro or we just make a guess and
# warn if we think that is not the case.
!if "$(MAKEFILEVC)" == ""

!if exist("$(PROJECT).vc")
MAKEFILEVC = $(PROJECT).vc
!elseif exist("makefile.vc")
MAKEFILEVC = makefile.vc
!endif
!endif # "$(MAKEFILEVC)" == ""

!if !exist("$(MAKEFILEVC)")
MSG = ^
You must run nmake from the directory containing the project makefile.^
If you are doing that and getting this message, set the MAKEFILEVC^
macro to the name of the project makefile.
!message WARNING: $(MSG)
!endif


################################################################
# 1. Define external programs being used

#----------------------------------------------------------
# Set the proper copy method to avoid overwrite questions
# to the user when copying files and selecting the right
# "delete all" method.
#----------------------------------------------------------

RMDIR	= rmdir /S /Q
CPY	= xcopy /i /y >NUL
CPYDIR  = xcopy /e /i /y >NUL
COPY	= copy /y >NUL
MKDIR   = mkdir

######################################################################
# 2. Figure out our build environment in terms of what we're building.
#
# (a) Tcl itself
# (b) Tk
# (c) a Tcl extension using libraries/includes from an *installed* Tcl
# (d) a Tcl extension using libraries/includes from Tcl source directory
#
# This last is needed because some extensions still need
# some Tcl interfaces that are not publicly exposed.
#
# The fragment will set the following macros:
# ROOT - root of this module sources
# COMPATDIR - source directory that holds compatibility sources
# DOCDIR - source directory containing documentation files
# GENERICDIR - platform-independent source directory
# WINDIR - Windows-specific source directory
# TESTDIR - directory containing test files
# TOOLSDIR - directory containing build tools
# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
#    when building Tcl itself.
# _INSTALLDIR - native form of the installation path. For Tcl
#    this will be the root of the Tcl installation. For extensions
#    this will be the lib directory under the root.
# TCLINSTALL  - set to 1 if _TCLDIR refers to
#    headers and libraries from an installed Tcl, and 0 if built against
#    Tcl sources. Not set when building Tcl itself. Yes, not very well
#    named.
# _TCL_H - native path to the tcl.h file
#
# If Tk is involved, also sets the following
# _TKDIR - native form Tk installation OR Tk source. Not set if building
#    Tk itself.
# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
# _TK_H - native path to the tk.h file

# Root directory for sources and assumed subdirectories
ROOT = $(MAKEDIR)\..
# The following paths CANNOT have spaces in them as they appear on the
# left side of implicit rules.
!ifndef COMPATDIR
COMPATDIR	= $(ROOT)\compat
!endif
!ifndef DOCDIR
DOCDIR		= $(ROOT)\doc
!endif
!ifndef GENERICDIR
GENERICDIR	= $(ROOT)\generic
!endif
!ifndef TOOLSDIR
TOOLSDIR	= $(ROOT)\tools
!endif
!ifndef TESTDIR
TESTDIR	= $(ROOT)\tests
!endif
!ifndef LIBDIR
!if exist("$(ROOT)\library")
LIBDIR          = $(ROOT)\library
!else
LIBDIR          = $(ROOT)\lib
!endif
!endif
!ifndef DEMODIR
!if exist("$(LIBDIR)\demos")
DEMODIR		= $(LIBDIR)\demos
!else
DEMODIR		= $(ROOT)\demos
!endif
!endif # ifndef DEMODIR
# Do NOT enclose WINDIR in a !ifndef because Windows always defines
# WINDIR env var to point to c:\windows!
# TBD - This is a potentially dangerous conflict, rename WINDIR to
# something else
WINDIR		= $(ROOT)\win

!ifndef RCDIR
!if exist("$(WINDIR)\rc")
RCDIR           = $(WINDIR)\rc
!else
RCDIR           = $(WINDIR)
!endif
!endif
RCDIR = $(RCDIR:/=\)

# The target directory where the built packages and binaries will be installed.
# INSTALLDIR is the (optional) path specified by the user.
# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
!ifdef INSTALLDIR
### Fix the path separators.
_INSTALLDIR	= $(INSTALLDIR:/=\)
!else
### Assume the normal default.
_INSTALLDIR	= $(HOMEDRIVE)\Tcl
!endif

!if $(DOING_TCL)

# BEGIN Case 2(a) - Building Tcl itself

# Only need to define _TCL_H
_TCL_H = ..\generic\tcl.h

# END Case 2(a) - Building Tcl itself

!elseif $(DOING_TK)

# BEGIN Case 2(b) - Building Tk

TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
!if "$(TCLDIR)" == ""
!if [echo TCLDIR = \> nmakehlp.out] \
   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
!error *** Could not locate Tcl source directory.
!endif
!include nmakehlp.out
!endif # TCLDIR == ""

_TCLDIR	= $(TCLDIR:/=\)
_TCL_H  = $(_TCLDIR)\generic\tcl.h
!if !exist("$(_TCL_H)")
!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
!endif

_TK_H = ..\generic\tk.h

# END Case 2(b) - Building Tk

!else

# BEGIN Case 2(c) or (d) - Building an extension other than Tk

# If command line has specified Tcl location through TCLDIR, use it
# else default to the INSTALLDIR setting
!if "$(TCLDIR)" != ""

_TCLDIR	= $(TCLDIR:/=\)
!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
TCLINSTALL	= 1
_TCL_H          = $(_TCLDIR)\include\tcl.h
!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
TCLINSTALL	= 0
_TCL_H          = $(_TCLDIR)\generic\tcl.h
!endif

!else  #  # Case 2(c) for extensions with TCLDIR undefined

# Need to locate Tcl depending on whether it needs Tcl source or not.
# If we don't, check the INSTALLDIR for an installed Tcl first

!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)

TCLINSTALL	= 1
TCLDIR          = $(_INSTALLDIR)\..
# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
# later so the \.. accounts for the /lib
_TCLDIR		= $(_INSTALLDIR)\..
_TCL_H          = $(_TCLDIR)\include\tcl.h

!else # exist(...) && ! $(NEED_TCL_SOURCE)

!if [echo _TCLDIR = \> nmakehlp.out] \
   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
!error *** Could not locate Tcl source directory.
!endif
!include nmakehlp.out
TCLINSTALL      = 0
TCLDIR         = $(_TCLDIR)
_TCL_H          = $(_TCLDIR)\generic\tcl.h

!endif # exist(...) && ! $(NEED_TCL_SOURCE)

!endif # TCLDIR

!ifndef _TCL_H
MSG =^
Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
!error $(MSG)
!endif

# Now do the same to locate Tk headers and libs if project requires Tk
!if $(NEED_TK)

!if "$(TKDIR)" != ""

_TKDIR = $(TKDIR:/=\)
!if exist("$(_TKDIR)\include\tk.h")
TKINSTALL      = 1
_TK_H          = $(_TKDIR)\include\tk.h
!elseif exist("$(_TKDIR)\generic\tk.h")
TKINSTALL      = 0
_TK_H          = $(_TKDIR)\generic\tk.h
!endif

!else # TKDIR not defined

# Need to locate Tcl depending on whether it needs Tcl source or not.
# If we don't, check the INSTALLDIR for an installed Tcl first

!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)

TKINSTALL      = 1
# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
# later so the \.. accounts for the /lib
_TKDIR         = $(_INSTALLDIR)\..
_TK_H          = $(_TKDIR)\include\tk.h
TKDIR          = $(_TKDIR)

!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)

!if [echo _TKDIR = \> nmakehlp.out] \
   || [nmakehlp -L generic\tk.h >> nmakehlp.out]
!error *** Could not locate Tk source directory.
!endif
!include nmakehlp.out
TKINSTALL      = 0
TKDIR          = $(_TKDIR)
_TK_H          = $(_TKDIR)\generic\tk.h

!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)

!endif # TKDIR

!ifndef _TK_H
MSG =^
Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
!error $(MSG)
!endif

!endif # NEED_TK

!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
MSG = ^
*** Warning: This extension requires the source distribution of Tcl.^
*** Please set the TCLDIR macro to point to the Tcl sources.
!error $(MSG)
!endif

!if $(NEED_TK_SOURCE)
!if $(TKINSTALL)
MSG = ^
*** Warning: This extension requires the source distribution of Tk.^
*** Please set the TKDIR macro to point to the Tk sources.
!error $(MSG)
!endif
!endif


# If INSTALLDIR set to Tcl installation root dir then reset to the
# lib dir for installing extensions 
!if exist("$(_INSTALLDIR)\include\tcl.h")
_INSTALLDIR=$(_INSTALLDIR)\lib
!endif

# END Case 2(c) or (d) - Building an extension
!endif # if $(DOING_TCL)

################################################################
# 3. Determine compiler version and architecture
# In this section, we figure out the compiler version and the
# architecture for which we are building. This sets the
# following macros:
# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
#     This is also printed by the compiler in dotted form 19.10 etc.
# VCVER - the "marketing version", for example Visual C++ 6 for internal
#     compiler version 1200. This is kept only for legacy reasons as it
#     does not make sense for recent Microsoft compilers. Only used for
#     output directory names.
# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
# MACHINE - same as $(ARCH) - legacy
# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
# CFG_ENCODING - set to an character encoding.
#   TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
#   see where it is used

cc32		= $(CC)   # built-in default.
link32		= link
lib32		= lib
rc32		= $(RC)   # built-in default.

#----------------------------------------------------------------
# Figure out the compiler architecture and version by writing
# the C macros to a file, preprocessing them with the C
# preprocessor and reading back the created file

_HASH=^#
_VC_MANIFEST_EMBED_EXE=
_VC_MANIFEST_EMBED_DLL=
VCVER=0
!if ![echo VCVERSION=_MSC_VER > vercl.x] \
    && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
    && ![echo ARCH=IX86 >> vercl.x] \
    && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
    && ![echo ARCH=AMD64 >> vercl.x] \
    && ![echo $(_HASH)endif >> vercl.x] \
    && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
!include vercl.i
!if $(VCVERSION) < 1900
!if ![echo VCVER= ^\> vercl.vc] \
    && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
!include vercl.vc
!endif
!else
# The simple calculation above does not apply to new Visual Studio releases
# Keep the compiler version in its native form.
VCVER = $(VCVERSION)
!endif
!endif

!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
!endif

#----------------------------------------------------------------
# The MACHINE macro is used by legacy makefiles so set it as well
!ifdef MACHINE
!if "$(MACHINE)" == "x86"
!undef MACHINE
MACHINE = IX86
!elseif "$(MACHINE)" == "x64"
!undef MACHINE
MACHINE = AMD64
!endif
!if "$(MACHINE)" != "$(ARCH)"
!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
!endif
!else
MACHINE=$(ARCH)
!endif

#------------------------------------------------------------
# Figure out the *host* architecture by reading the registry

!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
NATIVE_ARCH=IX86
!else
NATIVE_ARCH=AMD64
!endif

# Since MSVC8 we must deal with manifest resources.
!if $(VCVERSION) >= 1400
_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
!endif

!ifndef CFG_ENCODING
CFG_ENCODING	= \"cp1252\"
!endif

################################################################
# 4. Build the nmakehlp program
# This is a helper app we need to overcome nmake's limiting
# environment. We will call out to it to get various bits of
# information about supported compiler options etc.
#
# Tcl itself will always use the nmakehlp.c program which is
# in its own source. This is the "master" copy and kept updated.
#
# Extensions built against an installed Tcl will use the installed
# copy of Tcl's nmakehlp.c if there is one and their own version
# otherwise. In the latter case, they would also be using their own
# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
# or rules.vc.
#
# Extensions built against Tcl sources will use the one from the Tcl source.
#
# When building an extension using a sufficiently new version of Tcl,
# rules-ext.vc will define NMAKEHLPC appropriately to point to the
# copy of nmakehlp.c to be used.

!ifndef NMAKEHLPC
# Default to the one in the current directory (the extension's own nmakehlp.c)
NMAKEHLPC = nmakehlp.c

!if !$(DOING_TCL)
!if $(TCLINSTALL)
!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
!endif
!else # ! $(TCLINSTALL)
!if exist("$(_TCLDIR)\win\nmakehlp.c")
NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
!endif
!endif # $(TCLINSTALL)
!endif # !$(DOING_TCL)

!endif # NMAKEHLPC

# We always build nmakehlp even if it exists since we do not know
# what source it was built from.
!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
!endif

################################################################
# 5. Test for compiler features
# Visual C++ compiler options have changed over the years. Check
# which options are supported by the compiler in use.
#
# The following macros are set:
# OPTIMIZATIONS - the compiler flags to be used for optimized builds
# DEBUGFLAGS - the compiler flags to be used for debug builds
# LINKERFLAGS - Flags passed to the linker 
#
# Note that these are the compiler settings *available*, not those
# that will be *used*. The latter depends on the OPTS macro settings
# which we have not yet parsed.
#
# Also note that some of the flags in OPTIMIZATIONS are not really
# related to optimization. They are placed there only for legacy reasons
# as some extensions expect them to be included in that macro.

# -Op improves float consistency. Note only needed for older compilers
# Newer compilers do not need or support this option.
!if [nmakehlp -c -Op]
FPOPTS  = -Op
!endif

# Strict floating point semantics - present in newer compilers in lieu of -Op
!if [nmakehlp -c -fp:strict]
FPOPTS  = $(FPOPTS) -fp:strict
!endif

!if "$(MACHINE)" == "IX86"
### test for pentium errata
!if [nmakehlp -c -QI0f]
!message *** Compiler has 'Pentium 0x0f fix'
FPOPTS  = $(FPOPTS) -QI0f
!else
!message *** Compiler does not have 'Pentium 0x0f fix'
!endif
!endif

### test for optimizations
# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
# documentation. Note we do NOT want /Gs as that inserts a _chkstk
# stack probe at *every* function entry, not just those with more than
# a page of stack allocation resulting in a performance hit.  However,
# /O2 documentation is misleading as its stack probes are simply the
# default page size locals allocation probes and not what is implied
# by an explicit /Gs option.

OPTIMIZATIONS = $(FPOPTS)

!if [nmakehlp -c -O2]
OPTIMIZING = 1
OPTIMIZATIONS   = $(OPTIMIZATIONS) -O2
!else
# Legacy, really. All modern compilers support this
!message *** Compiler does not have 'Optimizations'
OPTIMIZING = 0
!endif

# Checks for buffer overflows in local arrays
!if [nmakehlp -c -GS]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
!endif

# Link time optimization. Note that this option (potentially) makes
# generated libraries only usable by the specific VC++ version that
# created it. Requires /LTCG linker option
!if [nmakehlp -c -GL]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
CC_GL_OPT_ENABLED = 1
!else
# In newer compilers -GL and -YX are incompatible.
!if [nmakehlp -c -YX]
OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
!endif
!endif # [nmakehlp -c -GL]

DEBUGFLAGS     = $(FPOPTS)

# Run time error checks. Not available or valid in a release, non-debug build
# RTC is for modern compilers, -GZ is legacy
!if [nmakehlp -c -RTC1]
DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
!elseif [nmakehlp -c -GZ]
DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
!endif

#----------------------------------------------------------------
# Linker flags

# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
# if the linker supports a specific option. Without these flags link will
# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
# They are not passed through to the actual application / extension
# link rules.
!ifndef LINKER_TESTFLAGS
LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
!endif

LINKERFLAGS     =

# If compiler has enabled link time optimization, linker must too with -ltcg
!ifdef CC_GL_OPT_ENABLED
!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
LINKERFLAGS     = $(LINKERFLAGS) -ltcg
!endif
!endif

########################################################################
# 6. Parse the OPTS macro to work out the requested build configuration.
# Based on this, we will construct the actual switches to be passed to the
# compiler and linker using the macros defined in the previous section.
# The following macros are defined by this section based on OPTS
# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
#                1 -> build as a static library and shell
# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
# DEBUG - 1 -> debug build, 0 -> release builds
# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
# PROFILE - 1 -> generate profiling info, 0 -> no profiling
# PGO     - 1 -> profile based optimization, 0 -> no
# MSVCRT  - 1 -> link to dynamic C runtime even when building static Tcl build
#           0 -> link to static C runtime for static Tcl build.
#           Does not impact shared Tcl builds (STATIC_BUILD == 0)
# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
#           in the Tcl shell. 0 -> keep them as shared libraries
#           Does not impact shared Tcl builds.
# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
#           0 -> Use the non-thread allocator.
# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
#           C runtime, 0 -> use the debug C runtime.
# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
# CONFIG_CHECK - 1 -> check current build configuration against Tcl
#           configuration (ignored for Tcl itself)
# Further, LINKERFLAGS are modified based on above.

# Default values for all the above
STATIC_BUILD	= 0
TCL_THREADS	= 1
DEBUG		= 0
SYMBOLS		= 0
PROFILE		= 0
PGO		= 0
MSVCRT		= 1
TCL_USE_STATIC_PACKAGES	= 0
USE_THREAD_ALLOC = 1
UNCHECKED	= 0
CONFIG_CHECK    = 1
!if $(DOING_TCL)
USE_STUBS       = 0
!else
USE_STUBS       = 1
!endif

# If OPTS is not empty AND does not contain "none" which turns off all OPTS
# set the above macros based on OPTS content
!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]

# OPTS are specified, parse them

!if [nmakehlp -f $(OPTS) "static"]
!message *** Doing static
STATIC_BUILD	= 1
!endif


!if [nmakehlp -f $(OPTS) "nostubs"]
!message *** Not using stubs
USE_STUBS	= 0
!endif

!if [nmakehlp -f $(OPTS) "nomsvcrt"]
!message *** Doing nomsvcrt
MSVCRT		= 0
!else
!if [nmakehlp -f $(OPTS) "msvcrt"]
!message *** Doing msvcrt
MSVCRT		= 1
!else
!if !$(STATIC_BUILD)
MSVCRT		= 1
!else
MSVCRT		= 0
!endif
!endif
!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]

!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
!message *** Doing staticpkg
TCL_USE_STATIC_PACKAGES	= 1
!else
TCL_USE_STATIC_PACKAGES	= 0
!endif

!if [nmakehlp -f $(OPTS) "nothreads"]
!message *** Compile explicitly for non-threaded Tcl
TCL_THREADS	= 0
USE_THREAD_ALLOC= 0
!else
TCL_THREADS	= 1
USE_THREAD_ALLOC= 1
!endif

!if [nmakehlp -f $(OPTS) "symbols"]
!message *** Doing symbols
DEBUG		= 1
!else
DEBUG		= 0
!endif

!if [nmakehlp -f $(OPTS) "pdbs"]
!message *** Doing pdbs
SYMBOLS		= 1
!else
SYMBOLS		= 0
!endif

!if [nmakehlp -f $(OPTS) "profile"]
!message *** Doing profile
PROFILE		= 1
!else
PROFILE		= 0
!endif

!if [nmakehlp -f $(OPTS) "pgi"]
!message *** Doing profile guided optimization instrumentation
PGO		= 1
!elseif [nmakehlp -f $(OPTS) "pgo"]
!message *** Doing profile guided optimization
PGO		= 2
!else
PGO		= 0
!endif

!if [nmakehlp -f $(OPTS) "loimpact"]
!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
!endif

# TBD - should get rid of this option
!if [nmakehlp -f $(OPTS) "thrdalloc"]
!message *** Doing thrdalloc
USE_THREAD_ALLOC = 1


!endif

!if [nmakehlp -f $(OPTS) "tclalloc"]

USE_THREAD_ALLOC = 0


!endif

!if [nmakehlp -f $(OPTS) "unchecked"]
!message *** Doing unchecked
UNCHECKED = 1
!else
UNCHECKED = 0
!endif

!if [nmakehlp -f $(OPTS) "noconfigcheck"]
CONFIG_CHECK = 1
!else
CONFIG_CHECK = 0
!endif

!endif # "$(OPTS)" != ""  && ... parsing of OPTS




# Set linker flags based on above


!if $(PGO) > 1
!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
!else
MSG=^
This compiler does not support profile guided optimization.
!error $(MSG)
!endif
!elseif $(PGO) > 0
!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
!else
MSG=^
This compiler does not support profile guided optimization.
!error $(MSG)
!endif
!endif

################################################################
# 7. Parse the STATS macro to configure code instrumentation
# The following macros are set by this section:
# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
#                 0 -> disables
# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
#                     0 -> disables

# Default both are off
TCL_MEM_DEBUG	    = 0
TCL_COMPILE_DEBUG   = 0

!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]

!if [nmakehlp -f $(STATS) "memdbg"]
!message *** Doing memdbg
TCL_MEM_DEBUG	    = 1
!else
TCL_MEM_DEBUG	    = 0
!endif

!if [nmakehlp -f $(STATS) "compdbg"]
!message *** Doing compdbg
TCL_COMPILE_DEBUG   = 1
!else
TCL_COMPILE_DEBUG   = 0
!endif

!endif

####################################################################
# 8. Parse the CHECKS macro to configure additional compiler checks
# The following macros are set by this section:
# WARNINGS - compiler switches that control the warnings level
# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
#                     0 -> enable deprecated functions

# Defaults - Permit deprecated functions and warning level 3
TCL_NO_DEPRECATED	    = 0
WARNINGS		    = -W3

!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]

!if [nmakehlp -f $(CHECKS) "nodep"]
!message *** Doing nodep check
TCL_NO_DEPRECATED	    = 1
!endif

!if [nmakehlp -f $(CHECKS) "fullwarn"]
!message *** Doing full warnings check
WARNINGS		    = -W4
!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
LINKERFLAGS		    = $(LINKERFLAGS) -warn:3
!endif
!endif

!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
!message *** Doing 64bit portability warnings
WARNINGS		    = $(WARNINGS) -Wp64
!endif

!endif

################################################################
# 9. Extract various version numbers
# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
# respectively. For extensions, versions are extracted from the
# configure.in or configure.ac from the TEA configuration if it
# exists, and unset otherwise.
# Sets the following macros:
# TCL_MAJOR_VERSION
# TCL_MINOR_VERSION
# TCL_PATCH_LEVEL
# TCL_VERSION
# TK_MAJOR_VERSION
# TK_MINOR_VERSION
# TK_PATCH_LEVEL
# TK_VERSION
# DOTVERSION - set as (for example) 2.5
# VERSION - set as (for example 25)
#--------------------------------------------------------------

!if [echo REM = This file is generated from rules.vc > versions.vc]
!endif
!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
!endif
!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
!endif
!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
!endif

!if defined(_TK_H)
!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
!endif
!if [echo TK_MINOR_VERSION = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
!endif
!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
!endif
!endif # _TK_H

!include versions.vc

TCL_VERSION	= $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
TCL_DOTVERSION	= $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
!if defined(_TK_H)
TK_VERSION	= $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
TK_DOTVERSION	= $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
!endif

# Set DOTVERSION and VERSION
!if $(DOING_TCL)

DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
VERSION = $(TCL_VERSION)

!elseif $(DOING_TK)

DOTVERSION = $(TK_DOTVERSION)
VERSION = $(TK_VERSION)

!else # Doing a non-Tk extension

# If parent makefile has not defined DOTVERSION, try to get it from TEA
# first from a configure.in file, and then from configure.ac
!ifndef DOTVERSION
!if [echo DOTVERSION = \> versions.vc] \
   || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
!if [echo DOTVERSION = \> versions.vc] \
   || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
!endif
!endif
!include versions.vc
!endif # DOTVERSION
VERSION         = $(DOTVERSION:.=)

!endif # $(DOING_TCL) ... etc.

################################################################
# 10. Construct output directory and file paths
# Figure-out how to name our intermediate and output directories.



# In order to avoid inadvertent mixing of object files built using
# different compilers, build configurations etc.,
#

# Naming convention (suffixes):
#   t = full thread support.
#   s = static library (as opposed to an import library)

#   g = linked to the debug enabled C run-time.

#   x = special static build when it links to the dynamic C run-time.


#
# The following macros are set in this section:
# SUFX - the suffix to use for binaries based on above naming convention
# BUILDDIRTOP - the toplevel default output directory
#      is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
# TMP_DIR - directory where object files are created
# OUT_DIR - directory where output executables are created
# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
# parent makefile (or command line). The default values are
# based on BUILDDIRTOP.
# STUBPREFIX - name of the stubs library for this project
# PRJIMPLIB - output path of the generated project import library
# PRJLIBNAME - name of generated project library
# PRJLIB     - output path of generated project library
# PRJSTUBLIBNAME - name of the generated project stubs library
# PRJSTUBLIB - output path of the generated project stubs library
# RESFILE - output resource file (only if not static build)

SUFX	    = tsgx

!if $(DEBUG)
BUILDDIRTOP = Debug
!else
BUILDDIRTOP = Release
!endif

................................................................................

TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX

!if !$(STATIC_BUILD)
TMP_DIRFULL = $(TMP_DIRFULL:Static=)
SUFX	    = $(SUFX:s=)
EXT	    = dll

TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)

!else
TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
EXT	    = lib
!if !$(MSVCRT)
TMP_DIRFULL = $(TMP_DIRFULL:X=)
SUFX	    = $(SUFX:x=)
!endif
................................................................................
!endif
!else
!ifndef OUT_DIR
OUT_DIR	    = $(TMP_DIR)
!endif
!endif

# Relative paths -> absolute
!if [echo OUT_DIR = \> nmakehlp.out] \
   || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
!endif
!if [echo TMP_DIR = \>> nmakehlp.out] \
   || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
!endif
!include nmakehlp.out




# The name of the stubs library for the project being built
STUBPREFIX      = $(PROJECT)stub




# Set up paths to various Tcl executables and libraries needed by extensions
!if $(DOING_TCL)

TCLSHNAME       = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
TCLSH		= $(OUT_DIR)\$(TCLSHNAME)
TCLIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
TCLLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
TCLLIB		= $(OUT_DIR)\$(TCLLIBNAME)

TCLSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
TCLSTUBLIB	= $(OUT_DIR)\$(TCLSTUBLIBNAME)
TCL_INCLUDES    = -I"$(WINDIR)" -I"$(GENERICDIR)"

!else # ! $(DOING_TCL)

!if $(TCLINSTALL) # Building against an installed Tcl

# When building extensions, we need to locate tclsh. Depending on version
# of Tcl we are building against, this may or may not have a "t" suffix.
# Try various possibilities in turn.
TCLSH		= $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
!if !exist("$(TCLSH)") && $(TCL_THREADS)
TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
!endif



!if !exist("$(TCLSH)")
TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
!endif


TCLSTUBLIB	= $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
# When building extensions, may be linking against Tcl that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TCLIMPLIB)")
TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
!endif



TCL_LIBRARY	= $(_TCLDIR)\lib
TCLREGLIB	= $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
TCLDDELIB	= $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
TCLTOOLSDIR	= \must\have\tcl\sources\to\build\this\target
TCL_INCLUDES    = -I"$(_TCLDIR)\include"

!else # Building against Tcl sources

TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
!if !exist($(TCLSH)) && $(TCL_THREADS)
TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
!endif

!if !exist($(TCLSH))
TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
!endif
TCLSTUBLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
# When building extensions, may be linking against Tcl that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TCLIMPLIB)")
TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
!endif
TCL_LIBRARY	= $(_TCLDIR)\library
TCLREGLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
TCLDDELIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
TCLTOOLSDIR	= $(_TCLDIR)\tools
TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"

!endif # TCLINSTALL




tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"




!endif # $(DOING_TCL)

# We need a tclsh that will run on the host machine as part of the build.
# IX86 runs on all architectures.
!ifndef TCLSH_NATIVE
!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
TCLSH_NATIVE	= $(TCLSH)
!else



!error You must explicitly set TCLSH_NATIVE for cross-compilation
!endif

!endif




# Do the same for Tk and Tk extensions that require the Tk libraries
!if $(DOING_TK) || $(NEED_TK)
WISHNAMEPREFIX = wish
WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
TKLIBNAME	= $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
TKSTUBLIBNAME	= tkstub$(TK_VERSION).lib
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX).lib

!if $(DOING_TK)
WISH 		= $(OUT_DIR)\$(WISHNAME)
TKSTUBLIB	= $(OUT_DIR)\$(TKSTUBLIBNAME)
TKIMPLIB	= $(OUT_DIR)\$(TKIMPLIBNAME)
TKLIB		= $(OUT_DIR)\$(TKLIBNAME)
TK_INCLUDES    = -I"$(WINDIR)" -I"$(GENERICDIR)"

!else # effectively NEED_TK

!if $(TKINSTALL) # Building against installed Tk
WISH		= $(_TKDIR)\bin\$(WISHNAME)
TKSTUBLIB	= $(_TKDIR)\lib\$(TKSTUBLIBNAME)
TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
# When building extensions, may be linking against Tk that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TKIMPLIB)")
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
!endif
TK_INCLUDES     = -I"$(_TKDIR)\include"
!else # Building against Tk sources
WISH		= $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
TKSTUBLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
# When building extensions, may be linking against Tk that does not add
# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
!if !exist("$(TKIMPLIB)")
TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
!endif
TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
!endif # TKINSTALL
tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"

!endif # $(DOING_TK)
!endif # $(DOING_TK) || $(NEED_TK)

# Various output paths
PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)

PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)

# If extension parent makefile has not defined a resource definition file,
# we will generate one from standard template.
!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
!ifdef RCFILE
RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
!else

RESFILE = $(TMP_DIR)\$(PROJECT).res
!endif
!endif

###################################################################
# 11. Construct the paths for the installation directories
# The following macros get defined in this section:
# LIB_INSTALL_DIR - where libraries should be installed
# BIN_INSTALL_DIR - where the executables should be installed
# DOC_INSTALL_DIR - where documentation should be installed
# SCRIPT_INSTALL_DIR - where scripts should be installed
# INCLUDE_INSTALL_DIR - where C include files should be installed
# DEMO_INSTALL_DIR - where demos should be installed
# PRJ_INSTALL_DIR - where package will be installed (not set for Tcl and Tk)




!if $(DOING_TCL) || $(DOING_TK)
LIB_INSTALL_DIR		= $(_INSTALLDIR)\lib
BIN_INSTALL_DIR		= $(_INSTALLDIR)\bin
DOC_INSTALL_DIR		= $(_INSTALLDIR)\doc
!if $(DOING_TCL)
SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
!else # DOING_TK
SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
!endif
DEMO_INSTALL_DIR	= $(SCRIPT_INSTALL_DIR)\demos
INCLUDE_INSTALL_DIR	= $(_INSTALLDIR)\include

!else # extension other than Tk

PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
LIB_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
BIN_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
DEMO_INSTALL_DIR	= $(PRJ_INSTALL_DIR)\demos
INCLUDE_INSTALL_DIR	= $(_TCLDIR)\include

!endif

###################################################################
# 12. Set up actual options to be passed to the compiler and linker
# Now we have all the information we need, set up the actual flags and
# options that we will pass to the compiler and linker. The main
# makefile should use these in combination with whatever other flags
# and switches are specific to it.
# The following macros are defined, names are for historical compatibility:
# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
# crt - Compiler switch that selects the appropriate C runtime
# cdebug - Compiler switches related to debug AND optimizations
# cwarn - Compiler switches that set warning levels
# cflags - complete compiler switches (subsumes cdebug and cwarn)
# ldebug - Linker switches controlling debug information and optimization
# lflags - complete linker switches (subsumes ldebug) except subsystem type
# dlllflags - complete linker switches to build DLLs (subsumes lflags)
# conlflags - complete linker switches for console program (subsumes lflags)
# guilflags - complete linker switches for GUI program (subsumes lflags)
# baselibs - minimum Windows libraries required. Parent makefile can
#    define PRJ_LIBS before including rules.rc if additional libs are needed

OPTDEFINES	= -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS

!if $(TCL_MEM_DEBUG)
OPTDEFINES	= $(OPTDEFINES) -DTCL_MEM_DEBUG
!endif
!if $(TCL_COMPILE_DEBUG)
OPTDEFINES	= $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
!endif
!if $(TCL_THREADS)
OPTDEFINES	= $(OPTDEFINES) -DTCL_THREADS=1
!if $(USE_THREAD_ALLOC)
OPTDEFINES	= $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
!endif



!endif
!if $(STATIC_BUILD)
OPTDEFINES	= $(OPTDEFINES) -DSTATIC_BUILD
!endif
!if $(TCL_NO_DEPRECATED)
OPTDEFINES	= $(OPTDEFINES) -DTCL_NO_DEPRECATED
!endif

!if $(USE_STUBS)
# Note we do not define USE_TCL_STUBS even when building Tk since some
# test targets in Tk do not use stubs
!if ! $(DOING_TCL)
USE_STUBS_DEFS  = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
!if $(NEED_TK)
USE_STUBS_DEFS  = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
!endif
!endif
!endif # USE_STUBS

!if !$(DEBUG)
OPTDEFINES	= $(OPTDEFINES) -DNDEBUG
!if $(OPTIMIZING)
OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
!endif
!endif
!if $(PROFILE)
OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_PROFILED
!endif
!if "$(MACHINE)" == "AMD64"
OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_DO64BIT
!endif
!if $(VCVERSION) < 1300
OPTDEFINES	= $(OPTDEFINES) -DNO_STRTOI64
!endif

# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
COMPILERFLAGS  = /D_ATL_XP_TARGETING




# Following is primarily for the benefit of extensions. Tcl 8.5 builds
# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
# an extension, it is advisable (but not mandated) to use the same Windows
# API as the Tcl build. This is accordingly defaulted below. A particular
# extension can override this by pre-defining USE_WIDECHAR_API.
!ifndef USE_WIDECHAR_API
!if $(TCL_VERSION) > 85
USE_WIDECHAR_API = 1
!else
USE_WIDECHAR_API = 0
!endif
!endif


!if $(USE_WIDECHAR_API)
COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE 
!endif




# Like the TEA system only set this non empty for non-Tk extensions
# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
# so we pass both
!if !$(DOING_TCL) && !$(DOING_TK)
PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
               -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
               -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
               -DMODULE_SCOPE=extern 
!endif







# crt picks the C run time based on selected OPTS
!if $(MSVCRT)
!if $(DEBUG) && !$(UNCHECKED)
crt = -MDd
!else



crt = -MD
!endif
!else







!if $(DEBUG) && !$(UNCHECKED)
crt = -MTd
!else



crt = -MT
!endif
!endif


# cdebug includes compiler options for debugging as well as optimization.
!if $(DEBUG)

# In debugging mode, optimizations need to be disabled
cdebug = -Zi -Od $(DEBUGFLAGS)

!else

cdebug = $(OPTIMIZATIONS)
!if $(SYMBOLS)
cdebug = $(cdebug) -Zi
!endif




!endif # $(DEBUG)

# cwarn includes default warning levels.
cwarn = $(WARNINGS)

!if "$(MACHINE)" == "AMD64"
# Disable pointer<->int warnings related to cast between different sizes
# There are a gadzillion of these due to use of ClientData and
# clutter up compiler
# output increasing chance of a real warning getting lost. So disable them.
# Eventually some day, Tcl will be 64-bit clean.
cwarn = $(cwarn) -wd4311 -wd4312
!endif

### Common compiler options that are architecture specific
!if "$(MACHINE)" == "ARM"
carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
!else
carch =
!endif



!if $(DEBUG)



# Turn warnings into errors
cwarn = $(cwarn) -WX
!endif





INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
!if !$(DOING_TCL) && !$(DOING_TK)
INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
!endif

# These flags are defined roughly in the order of the pre-reform
# rules.vc/makefile.vc to help visually compare that the pre- and
# post-reform build logs

# cflags contains generic flags used for building practically all object files
cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)

# appcflags contains $(cflags) and flags for building the application
# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
# flags used for building shared object files The two differ in the
# BUILD_$(PROJECT) macro which should be defined only for the shared
# library *implementation* and not for its caller interface

appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)

# stubscflags contains $(cflags) plus flags used for building a stubs
# library for the package.  Note: -DSTATIC_BUILD is defined in
# $(OPTDEFINES) only if the OPTS configuration indicates a static
# library. However the stubs library is ALWAYS static hence included
# here irrespective of the OPTS setting.
#
# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
# without stating why. Tcl itself compiled stubs libs with this flag.
# so we do not remove it from cflags. -GL may prevent extensions
# compiled with one VC version to fail to link against stubs library
# compiled with another VC version. Check for this and fix accordingly.
stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)

# Link flags 

!if $(DEBUG)
ldebug	= -debug -debugtype:cv
!else



ldebug	= -release -opt:ref -opt:icf,3
!if $(SYMBOLS)
ldebug	= $(ldebug) -debug -debugtype:cv
!endif




!endif

# Note: Profiling is currently only possible with the Visual Studio Enterprise
!if $(PROFILE)
ldebug= $(ldebug) -profile
!endif




### Declarations common to all linker versions 
lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)



!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
lflags	= $(lflags) -nodefaultlib:libucrt.lib
!endif












# Old linkers (Visual C++ 6 in particular) will link for fast loading
# on Win98. Since we do not support Win98 any more, we specify nowin98
# as recommended for NT and later. However, this is only required by
# IX86 on older compilers and only needed if we are not doing a static build.

!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
# Align sections for PE size savings.
lflags	= $(lflags) -opt:nowin98
!endif
!endif








dlllflags = $(lflags) -dll
conlflags = $(lflags) -subsystem:console
guilflags = $(lflags) -subsystem:windows

# Libraries that are required for every image.
# Extensions should define any additional libraries with $(PRJ_LIBS)
winlibs   = kernel32.lib advapi32.lib

!if $(NEED_TK)
winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
!endif




# Avoid 'unresolved external symbol __security_cookie' errors.
# c.f. http://support.microsoft.com/?id=894573
!if "$(MACHINE)" == "AMD64"
!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
winlibs   = $(winlibs) bufferoverflowU.lib
!endif
!endif


baselibs = $(winlibs) $(PRJ_LIBS)

!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
baselibs   = $(baselibs) ucrt.lib
!endif

################################################################
# 13. Define standard commands, common make targets and implicit rules

CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\

LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)

CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
RESCMD  = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
	    $(TCL_INCLUDES) \
	    -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
	    -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
	    -DDOTVERSION=\"$(DOTVERSION)\" \



	    -DVERSION=\"$(VERSION)\" \
	    -DSUFX=\"$(SUFX)\" \
            -DPROJECT=\"$(PROJECT)\" \
            -DPRJLIBNAME=\"$(PRJLIBNAME)\" 

!ifndef DEFAULT_BUILD_TARGET
DEFAULT_BUILD_TARGET = $(PROJECT)
!endif

default-target: $(DEFAULT_BUILD_TARGET)

default-pkgindex:
	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
	    [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl

default-pkgindex-tea:
	@if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
@PACKAGE_VERSION@    $(DOTVERSION)
@PACKAGE_NAME@       $(PRJ_PACKAGE_TCLNAME)
@PACKAGE_TCLNAME@    $(PRJ_PACKAGE_TCLNAME)
@PKG_LIB_FILE@       $(PRJLIBNAME)
<<


default-install: default-install-binaries default-install-libraries

default-install-binaries: $(PRJLIB)
	@echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
	@$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL

default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
	@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
	@if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
	@echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
	@$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)

default-install-stubs:
	@echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
	@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL

default-install-docs-html:
	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"

default-install-docs-n:
	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"

default-install-demos:
	@echo Installing demos to '$(DEMO_INSTALL_DIR)'
	@if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
	@if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"

default-clean:
	@echo Cleaning $(TMP_DIR)\* ...
	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
	@echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
	@if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
	@echo Cleaning $(WINDIR)\nmhlp-out.txt ...
	@if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
	@echo Cleaning $(WINDIR)\_junk.pch ...
	@if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
	@echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
	@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
	@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
	@echo Cleaning $(WINDIR)\versions.vc, version.vc ...
	@if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
	@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc

default-hose: default-clean
	@echo Hosing $(OUT_DIR)\* ...
	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)

# Only for backward compatibility
default-distclean: default-hose

default-setup:
	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)

!if "$(TESTPAT)" != ""
TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
!endif

default-test: default-setup $(PROJECT)
	@set TCLLIBPATH=$(OUT_DIR:\=/)
	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
	cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)

default-shell: default-setup $(PROJECT)
	@set TCLLIBPATH=$(OUT_DIR:\=/)
	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
	$(DEBUGGER) $(TCLSH)

# Generation of Windows version resource 
!ifdef RCFILE

# Note: don't use $** in below rule because there may be other dependencies
# and only the "master" rc must be passed to the resource compiler
$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
	$(RESCMD) $(RCDIR)\$(PROJECT).rc

!else

# If parent makefile has not defined a resource definition file,
# we will generate one from standard template.
$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc

$(TMP_DIR)\$(PROJECT).rc:
	@$(COPY) << $(TMP_DIR)\$(PROJECT).rc
#include <winver.h>







VS_VERSION_INFO VERSIONINFO
 FILEVERSION	COMMAVERSION
 PRODUCTVERSION	COMMAVERSION
 FILEFLAGSMASK	0x3fL
#ifdef DEBUG
 FILEFLAGS	VS_FF_DEBUG
#else




 FILEFLAGS	0x0L
#endif
 FILEOS		VOS_NT_WINDOWS32
 FILETYPE	VFT_DLL
 FILESUBTYPE	0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription",  "Tcl extension " PROJECT
            VALUE "OriginalFilename", PRJLIBNAME
            VALUE "FileVersion",      DOTVERSION
            VALUE "ProductName",      "Package " PROJECT " for Tcl"
            VALUE "ProductVersion",   DOTVERSION 
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END

<<

!endif # ifdef RCFILE

!ifndef DISABLE_IMPLICIT_RULES
DISABLE_IMPLICIT_RULES = 0
!endif

!if !$(DISABLE_IMPLICIT_RULES)
# Implicit rule definitions - only for building library objects. For stubs and
# main application, the master makefile should define explicit rules.

{$(ROOT)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(WINDIR)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
	$(CCPKGCMD) @<<
$<
<<

{$(RCDIR)}.rc{$(TMP_DIR)}.res:
	$(RESCMD) $<

{$(WINDIR)}.rc{$(TMP_DIR)}.res:
	$(RESCMD) $<

{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
	$(RESCMD) $<

.SUFFIXES:
.SUFFIXES:.c .rc

!endif

################################################################
# 14. Sanity check selected options against Tcl build options
# When building an extension, certain configuration options should
# match the ones used when Tcl was built. Here we check and
# warn on a mismatch.
!if ! $(DOING_TCL)

!if $(TCLINSTALL) # Building against an installed Tcl
!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
!endif
!else # ! $(TCLINSTALL) - building against Tcl source
!if exist("$(OUT_DIR)\tcl.nmake")
TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
!endif
!endif # TCLINSTALL

!if $(CONFIG_CHECK)
!ifdef TCLNMAKECONFIG
!include $(TCLNMAKECONFIG)

!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
!endif
!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
!endif
!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
!endif
!endif

!endif # TCLNMAKECONFIG

!endif # ! $(DOING_TCL)


#----------------------------------------------------------
# Display stats being used.
#----------------------------------------------------------

!if !$(DOING_TCL)
!message *** Building against Tcl at '$(_TCLDIR)'
!endif
!if !$(DOING_TK) && $(NEED_TK)
!message *** Building against Tk at '$(_TKDIR)'
!endif
!message *** Intermediate directory will be '$(TMP_DIR)'
!message *** Output directory will be '$(OUT_DIR)'
!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
!message *** Suffix for binaries will be '$(SUFX)'

!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).



!endif # ifdef _RULES_VC

Added win/targets.vc.





































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#------------------------------------------------------------- -*- makefile -*-
# targets.vc --
#
# Part of the nmake based build system for Tcl and its extensions.
# This file defines some standard targets for the convenience of extensions
# and can be optionally included by the extension makefile.
# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.

$(PROJECT): setup pkgindex $(PRJLIB)

!ifdef PRJ_STUBOBJS
$(PROJECT): $(PRJSTUBLIB)
$(PRJSTUBLIB): $(PRJ_STUBOBJS)
	$(LIBCMD) $**

$(PRJ_STUBOBJS):
	$(CCSTUBSCMD) %s
!endif # PRJ_STUBOBJS

!ifdef PRJ_MANIFEST
$(PROJECT): $(PRJLIB).manifest
$(PRJLIB).manifest: $(PRJ_MANIFEST)
	@nmakehlp -s << $** >$@
@MACHINE@	  $(MACHINE:IX86=X86)
<<
!endif

!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
!if $(STATIC_BUILD)
       $(LIBCMD) $**
!else
       $(DLLCMD) $**
       $(_VC_MANIFEST_EMBED_DLL)
!endif
       -@del $*.exp
!endif

!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
$(PRJ_OBJS): $(PRJ_HEADERS)
!endif

# If parent makefile has defined stub objects, add their installation
# to the default install
!if "$(PRJ_STUBOBJS)" != ""
default-install: default-install-stubs
!endif

# Unlike the other default targets, these cannot be in rules.vc because
# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
# that the parent makefile will not define until after including rules-ext.vc
!if "$(PRJ_HEADERS_PUBLIC)" != ""
default-install: default-install-headers
default-install-headers:
	@echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
	@for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
!endif

!if "$(DISABLE_STANDARD_TARGETS)" == ""
DISABLE_STANDARD_TARGETS = 0
!endif

!if "$(DISABLE_TARGET_setup)" == ""
DISABLE_TARGET_setup = 0
!endif
!if "$(DISABLE_TARGET_install)" == ""
DISABLE_TARGET_install = 0
!endif
!if "$(DISABLE_TARGET_clean)" == ""
DISABLE_TARGET_clean = 0
!endif
!if "$(DISABLE_TARGET_test)" == ""
DISABLE_TARGET_test = 0
!endif
!if "$(DISABLE_TARGET_shell)" == ""
DISABLE_TARGET_shell = 0
!endif

!if !$(DISABLE_STANDARD_TARGETS)
!if !$(DISABLE_TARGET_setup)
setup: default-setup
!endif
!if !$(DISABLE_TARGET_install)
install: default-install
!endif
!if !$(DISABLE_TARGET_clean)
clean: default-clean
realclean: hose
hose: default-hose
distclean: realclean default-distclean
!endif
!if !$(DISABLE_TARGET_test)
test: default-test
!endif
!if !$(DISABLE_TARGET_shell)
shell: default-shell
!endif
!endif # DISABLE_STANDARD_TARGETS

Changes to win/tdom.rc.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 PRODUCTVERSION	COMMAVERSION
 FILEFLAGSMASK	0x3fL
#ifdef DEBUG
 FILEFLAGS	VS_FF_DEBUG
#else
 FILEFLAGS	0x0L
#endif
 FILEOS		VOS__WINDOWS32
 FILETYPE	VFT_DLL
 FILESUBTYPE	0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription",  "tdom " DOTVERSION " for Windows\0"
            VALUE "OriginalFilename", "tdom" VERSION ".dll\0"
            VALUE "FileVersion",      DOTVERSION "\0"
            VALUE "LegalCopyright",   "Copyright \251 1998-2007 Jochen Loewer, Rolf Ade, et al.\0"
            VALUE "ProductName",      "tdom " DOTVERSION " for Windows\0"
            VALUE "ProductVersion",   DOTVERSION "\0"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END







|








|
|

|
|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 PRODUCTVERSION	COMMAVERSION
 FILEFLAGSMASK	0x3fL
#ifdef DEBUG
 FILEFLAGS	VS_FF_DEBUG
#else
 FILEFLAGS	0x0L
#endif
 FILEOS		VOS_NT_WINDOWS32
 FILETYPE	VFT_DLL
 FILESUBTYPE	0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription",  "tdom " DOTVERSION " for Windows\0"
            VALUE "OriginalFilename", PRJLIBNAME
            VALUE "FileVersion",      DOTVERSION
            VALUE "LegalCopyright",   "Copyright \251 1998-2007 Jochen Loewer, Rolf Ade, et al.\0"
            VALUE "ProductName",      "Package" PROJECT " for Tcl"
            VALUE "ProductVersion",   DOTVERSION
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END

Changes to xe/README.

7
8
9
10
11
12
13
14
15

 1)  cp xe-input ~/.xe-input
     xe

 2)  xe xe-input


Latter should be more appropiate for Wn32 users.








|

7
8
9
10
11
12
13
14
15

 1)  cp xe-input ~/.xe-input
     xe

 2)  xe xe-input


Latter should be more appropriate for Wn32 users.